OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |