| 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 |