Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: Source/platform/fonts/GlyphPage.h

Issue 243453003: Proper unicode-range font loading behavior (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
3 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 3 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 13 matching lines...) Expand all
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30 #ifndef GlyphPage_h 30 #ifndef GlyphPage_h
31 #define GlyphPage_h 31 #define GlyphPage_h
32 32
33 #include "platform/PlatformExport.h" 33 #include "platform/PlatformExport.h"
34 #include "platform/fonts/CustomFontData.h"
34 #include "platform/fonts/Glyph.h" 35 #include "platform/fonts/Glyph.h"
35 #include <string.h> 36 #include <string.h>
36 #include "wtf/PassRefPtr.h" 37 #include "wtf/PassRefPtr.h"
37 #include "wtf/RefCounted.h" 38 #include "wtf/RefCounted.h"
38 #include "wtf/RefPtr.h" 39 #include "wtf/RefPtr.h"
39 #include "wtf/unicode/Unicode.h" 40 #include "wtf/unicode/Unicode.h"
40 41
41 namespace WebCore { 42 namespace WebCore {
42 43
43 class SimpleFontData; 44 class SimpleFontData;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 { 87 {
87 RefPtr<GlyphPage> page = GlyphPage::createForMixedFontData(owner); 88 RefPtr<GlyphPage> page = GlyphPage::createForMixedFontData(owner);
88 memcpy(page->m_glyphs, m_glyphs, sizeof(m_glyphs)); 89 memcpy(page->m_glyphs, m_glyphs, sizeof(m_glyphs));
89 if (hasPerGlyphFontData()) 90 if (hasPerGlyphFontData())
90 memcpy(page->m_perGlyphFontData, m_perGlyphFontData, sizeof(SimpleFo ntData*) * GlyphPage::size); 91 memcpy(page->m_perGlyphFontData, m_perGlyphFontData, sizeof(SimpleFo ntData*) * GlyphPage::size);
91 else { 92 else {
92 for (size_t i = 0; i < GlyphPage::size; ++i) { 93 for (size_t i = 0; i < GlyphPage::size; ++i) {
93 page->m_perGlyphFontData[i] = m_glyphs[i] ? m_fontDataForAllGlyp hs : 0; 94 page->m_perGlyphFontData[i] = m_glyphs[i] ? m_fontDataForAllGlyp hs : 0;
94 } 95 }
95 } 96 }
97 page->m_customFontToLoad = m_customFontToLoad;
96 return page.release(); 98 return page.release();
97 } 99 }
98 100
99 ~GlyphPage() { } 101 ~GlyphPage() { }
100 102
101 static const unsigned char sizeBits = 8; 103 static const unsigned char sizeBits = 8;
102 static const size_t size = (1 << GlyphPage::sizeBits); // Covers Latin-1 in a single page. 104 static const size_t size = (1 << GlyphPage::sizeBits); // Covers Latin-1 in a single page.
103 static unsigned indexForCharacter(UChar32 c) { return c & 0xFF; } 105 static unsigned indexForCharacter(UChar32 c) { return c & 0xFF; }
104 106
105 ALWAYS_INLINE GlyphData glyphDataForCharacter(UChar32 c) const 107 ALWAYS_INLINE GlyphData glyphDataForCharacter(UChar32 c) const
106 { 108 {
107 return glyphDataForIndex(indexForCharacter(c)); 109 unsigned index = indexForCharacter(c);
110 if (const CustomFontData* customData = customFontToLoadAt(index))
111 customData->beginLoadIfNeeded();
112 return glyphDataForIndex(index);
108 } 113 }
109 114
110 ALWAYS_INLINE GlyphData glyphDataForIndex(unsigned index) const 115 ALWAYS_INLINE GlyphData glyphDataForIndex(unsigned index) const
111 { 116 {
112 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 117 ASSERT_WITH_SECURITY_IMPLICATION(index < size);
113 Glyph glyph = m_glyphs[index]; 118 Glyph glyph = m_glyphs[index];
114 if (hasPerGlyphFontData()) 119 if (hasPerGlyphFontData())
115 return GlyphData(glyph, m_perGlyphFontData[index]); 120 return GlyphData(glyph, m_perGlyphFontData[index]);
116 return GlyphData(glyph, glyph ? m_fontDataForAllGlyphs : 0); 121 return GlyphData(glyph, glyph ? m_fontDataForAllGlyphs : 0);
117 } 122 }
118 123
119 ALWAYS_INLINE Glyph glyphForCharacter(UChar32 c) const 124 ALWAYS_INLINE Glyph glyphForCharacter(UChar32 c) const
120 { 125 {
121 return glyphAt(indexForCharacter(c)); 126 return glyphAt(indexForCharacter(c));
122 } 127 }
123 128
124 ALWAYS_INLINE Glyph glyphAt(unsigned index) const 129 ALWAYS_INLINE Glyph glyphAt(unsigned index) const
125 { 130 {
126 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 131 ASSERT_WITH_SECURITY_IMPLICATION(index < size);
127 return m_glyphs[index]; 132 return m_glyphs[index];
128 } 133 }
129 134
130 ALWAYS_INLINE const SimpleFontData* fontDataForCharacter(UChar32 c) const
131 {
132 unsigned index = indexForCharacter(c);
133 if (hasPerGlyphFontData())
134 return m_perGlyphFontData[index];
135 return m_glyphs[index] ? m_fontDataForAllGlyphs : 0;
136 }
137
138 void setGlyphDataForCharacter(UChar32 c, Glyph g, const SimpleFontData* f) 135 void setGlyphDataForCharacter(UChar32 c, Glyph g, const SimpleFontData* f)
139 { 136 {
140 setGlyphDataForIndex(indexForCharacter(c), g, f); 137 setGlyphDataForIndex(indexForCharacter(c), g, f);
141 } 138 }
142 139
143 void setGlyphDataForIndex(unsigned index, Glyph glyph, const SimpleFontData* fontData) 140 void setGlyphDataForIndex(unsigned index, Glyph glyph, const SimpleFontData* fontData)
144 { 141 {
145 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 142 ASSERT_WITH_SECURITY_IMPLICATION(index < size);
146 m_glyphs[index] = glyph; 143 m_glyphs[index] = glyph;
144 setCustomFontToLoad(index, 0);
147 145
148 // GlyphPage getters will always return a null SimpleFontData* for glyph #0 if there's no per-glyph font array. 146 // GlyphPage getters will always return a null SimpleFontData* for glyph #0 if there's no per-glyph font array.
149 if (hasPerGlyphFontData()) { 147 if (hasPerGlyphFontData()) {
150 m_perGlyphFontData[index] = glyph ? fontData : 0; 148 m_perGlyphFontData[index] = glyph ? fontData : 0;
151 return; 149 return;
152 } 150 }
153 151
154 // A single-font GlyphPage already assigned m_fontDataForAllGlyphs in th e constructor. 152 // A single-font GlyphPage already assigned m_fontDataForAllGlyphs in th e constructor.
155 ASSERT(!glyph || fontData == m_fontDataForAllGlyphs); 153 ASSERT(!glyph || fontData == m_fontDataForAllGlyphs);
156 } 154 }
157 155
158 void setGlyphDataForIndex(unsigned index, const GlyphData& glyphData) 156 void setGlyphDataForIndex(unsigned index, const GlyphData& glyphData)
159 { 157 {
160 setGlyphDataForIndex(index, glyphData.glyph, glyphData.fontData); 158 setGlyphDataForIndex(index, glyphData.glyph, glyphData.fontData);
161 } 159 }
162 160
161 const CustomFontData* customFontToLoadAt(unsigned index) const
162 {
163 ASSERT_WITH_SECURITY_IMPLICATION(index < size);
164 return m_customFontToLoad ? m_customFontToLoad->at(index) : 0;
165 }
166
167 void setCustomFontToLoad(unsigned index, const CustomFontData* customFontToL oad)
168 {
169 if (!m_customFontToLoad) {
170 if (!customFontToLoad)
171 return;
172 m_customFontToLoad = CustomDataPage::create();
173 }
174 ASSERT_WITH_SECURITY_IMPLICATION(index < size);
175 m_customFontToLoad->set(index, customFontToLoad);
176 }
177
163 void removeFontDataFromSystemFallbackPage(const SimpleFontData* fontData) 178 void removeFontDataFromSystemFallbackPage(const SimpleFontData* fontData)
164 { 179 {
165 // This method should only be called on the system fallback page, which is never single-font. 180 // This method should only be called on the system fallback page, which is never single-font.
166 ASSERT(hasPerGlyphFontData()); 181 ASSERT(hasPerGlyphFontData());
167 for (size_t i = 0; i < size; ++i) { 182 for (size_t i = 0; i < size; ++i) {
168 if (m_perGlyphFontData[i] == fontData) { 183 if (m_perGlyphFontData[i] == fontData) {
169 m_glyphs[i] = 0; 184 m_glyphs[i] = 0;
170 m_perGlyphFontData[i] = 0; 185 m_perGlyphFontData[i] = 0;
171 } 186 }
172 } 187 }
173 } 188 }
174 189
175 GlyphPageTreeNode* owner() const { return m_owner; } 190 GlyphPageTreeNode* owner() const { return m_owner; }
176 191
177 private: 192 private:
178 explicit GlyphPage(GlyphPageTreeNode* owner, const SimpleFontData* fontDataF orAllGlyphs = 0) 193 explicit GlyphPage(GlyphPageTreeNode* owner, const SimpleFontData* fontDataF orAllGlyphs = 0)
179 : m_fontDataForAllGlyphs(fontDataForAllGlyphs) 194 : m_fontDataForAllGlyphs(fontDataForAllGlyphs)
180 , m_owner(owner) 195 , m_owner(owner)
181 { 196 {
182 memset(m_glyphs, 0, sizeof(m_glyphs)); 197 memset(m_glyphs, 0, sizeof(m_glyphs));
183 if (hasPerGlyphFontData()) 198 if (hasPerGlyphFontData())
184 memset(m_perGlyphFontData, 0, sizeof(SimpleFontData*) * GlyphPage::s ize); 199 memset(m_perGlyphFontData, 0, sizeof(SimpleFontData*) * GlyphPage::s ize);
185 } 200 }
186 201
187 bool hasPerGlyphFontData() const { return !m_fontDataForAllGlyphs; } 202 bool hasPerGlyphFontData() const { return !m_fontDataForAllGlyphs; }
188 203
204 class CustomDataPage : public RefCounted<CustomDataPage> {
205 public:
206 static RefPtr<CustomDataPage> create() { return adoptRef(new CustomDataP age()); }
207 const CustomFontData* at(size_t index) const { return m_customData[index ]; }
208 void set(size_t index, const CustomFontData* data) { m_customData[index] = data; }
209 private:
210 CustomDataPage() { memset(m_customData, 0, sizeof(m_customData)); }
211 const CustomFontData* m_customData[size];
212 };
213
189 const SimpleFontData* m_fontDataForAllGlyphs; 214 const SimpleFontData* m_fontDataForAllGlyphs;
190 GlyphPageTreeNode* m_owner; 215 GlyphPageTreeNode* m_owner;
216 RefPtr<CustomDataPage> m_customFontToLoad;
191 Glyph m_glyphs[size]; 217 Glyph m_glyphs[size];
192 218
193 // NOTE: This array has (GlyphPage::size) elements if m_fontDataForAllGlyphs is null. 219 // NOTE: This array has (GlyphPage::size) elements if m_fontDataForAllGlyphs is null.
194 const SimpleFontData* m_perGlyphFontData[0]; 220 const SimpleFontData* m_perGlyphFontData[0];
195 }; 221 };
196 222
197 #if COMPILER(MSVC) 223 #if COMPILER(MSVC)
198 #pragma warning(pop) 224 #pragma warning(pop)
199 #endif 225 #endif
200 226
201 } // namespace WebCore 227 } // namespace WebCore
202 228
203 #endif // GlyphPage_h 229 #endif // GlyphPage_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698