OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 ++it) | 91 ++it) |
92 count += it->value->pageCount(); | 92 count += it->value->pageCount(); |
93 | 93 |
94 if (m_systemFallbackChild) | 94 if (m_systemFallbackChild) |
95 ++count; | 95 ++count; |
96 | 96 |
97 return count; | 97 return count; |
98 } | 98 } |
99 | 99 |
100 void GlyphPageTreeNode::pruneTreeCustomFontData(const FontData* fontData) { | 100 void GlyphPageTreeNode::pruneTreeCustomFontData(const FontData* fontData) { |
101 // Enumerate all the roots and prune any tree that contains our custom font da
ta. | 101 // Enumerate all the roots and prune any tree that contains our custom font |
| 102 // data. |
102 if (roots) { | 103 if (roots) { |
103 HashMap<int, GlyphPageTreeNode*>::iterator end = roots->end(); | 104 HashMap<int, GlyphPageTreeNode*>::iterator end = roots->end(); |
104 for (HashMap<int, GlyphPageTreeNode*>::iterator it = roots->begin(); | 105 for (HashMap<int, GlyphPageTreeNode*>::iterator it = roots->begin(); |
105 it != end; ++it) | 106 it != end; ++it) |
106 it->value->pruneCustomFontData(fontData); | 107 it->value->pruneCustomFontData(fontData); |
107 } | 108 } |
108 | 109 |
109 if (pageZeroRoot) | 110 if (pageZeroRoot) |
110 pageZeroRoot->pruneCustomFontData(fontData); | 111 pageZeroRoot->pruneCustomFontData(fontData); |
111 } | 112 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 | 177 |
177 void GlyphPageTreeNode::initializePurePage(const FontData* fontData, | 178 void GlyphPageTreeNode::initializePurePage(const FontData* fontData, |
178 unsigned pageNumber) { | 179 unsigned pageNumber) { |
179 ASSERT(m_level == 1); | 180 ASSERT(m_level == 1); |
180 | 181 |
181 unsigned start = pageNumber * GlyphPage::size; | 182 unsigned start = pageNumber * GlyphPage::size; |
182 UChar buffer[GlyphPage::size * 2 + 2]; | 183 UChar buffer[GlyphPage::size * 2 + 2]; |
183 unsigned bufferLength; | 184 unsigned bufferLength; |
184 unsigned i; | 185 unsigned i; |
185 | 186 |
186 // Fill in a buffer with the entire "page" of characters that we want to look
up glyphs for. | 187 // Fill in a buffer with the entire "page" of characters that we want to look |
| 188 // up glyphs for. |
187 if (start < 0x10000) { | 189 if (start < 0x10000) { |
188 bufferLength = GlyphPage::size; | 190 bufferLength = GlyphPage::size; |
189 for (i = 0; i < GlyphPage::size; i++) | 191 for (i = 0; i < GlyphPage::size; i++) |
190 buffer[i] = start + i; | 192 buffer[i] = start + i; |
191 | 193 |
192 if (start == 0) { | 194 if (start == 0) { |
193 // Control characters must not render at all. | 195 // Control characters must not render at all. |
194 for (i = 0; i < 0x20; ++i) | 196 for (i = 0; i < 0x20; ++i) |
195 buffer[i] = zeroWidthSpaceCharacter; | 197 buffer[i] = zeroWidthSpaceCharacter; |
196 for (i = 0x7F; i < 0xA0; i++) | 198 for (i = 0x7F; i < 0xA0; i++) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 for (i = 0; i < GlyphPage::size; i++) { | 243 for (i = 0; i < GlyphPage::size; i++) { |
242 int c = i + start; | 244 int c = i + start; |
243 buffer[i * 2] = U16_LEAD(c); | 245 buffer[i * 2] = U16_LEAD(c); |
244 buffer[i * 2 + 1] = U16_TRAIL(c); | 246 buffer[i * 2 + 1] = U16_TRAIL(c); |
245 } | 247 } |
246 } | 248 } |
247 | 249 |
248 // Now that we have a buffer full of characters, we want to get back an array | 250 // Now that we have a buffer full of characters, we want to get back an array |
249 // of glyph indices. This part involves calling into the platform-specific | 251 // of glyph indices. This part involves calling into the platform-specific |
250 // routine of our glyph map for actually filling in the page with the glyphs. | 252 // routine of our glyph map for actually filling in the page with the glyphs. |
251 // Success is not guaranteed. For example, Times fails to fill page 260, givin
g glyph data | 253 // Success is not guaranteed. For example, Times fails to fill page 260, |
252 // for only 128 out of 256 characters. | 254 // giving glyph data for only 128 out of 256 characters. |
253 bool haveGlyphs; | 255 bool haveGlyphs; |
254 if (!fontData->isSegmented()) { | 256 if (!fontData->isSegmented()) { |
255 m_page = | 257 m_page = |
256 GlyphPage::createForSingleFontData(this, toSimpleFontData(fontData)); | 258 GlyphPage::createForSingleFontData(this, toSimpleFontData(fontData)); |
257 haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, | 259 haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, |
258 toSimpleFontData(fontData)); | 260 toSimpleFontData(fontData)); |
259 } else { | 261 } else { |
260 m_page = GlyphPage::createForMixedFontData(this); | 262 m_page = GlyphPage::createForMixedFontData(this); |
261 haveGlyphs = false; | 263 haveGlyphs = false; |
262 | 264 |
263 const SegmentedFontData* segmentedFontData = toSegmentedFontData(fontData); | 265 const SegmentedFontData* segmentedFontData = toSegmentedFontData(fontData); |
264 for (int i = segmentedFontData->numFaces() - 1; i >= 0; i--) { | 266 for (int i = segmentedFontData->numFaces() - 1; i >= 0; i--) { |
265 RefPtr<FontDataForRangeSet> fontDataForRangeSet = | 267 RefPtr<FontDataForRangeSet> fontDataForRangeSet = |
266 segmentedFontData->faceAt(i); | 268 segmentedFontData->faceAt(i); |
267 RefPtr<UnicodeRangeSet> ranges = fontDataForRangeSet->ranges(); | 269 RefPtr<UnicodeRangeSet> ranges = fontDataForRangeSet->ranges(); |
268 // If there are no ranges, that means this font should be used for | 270 // If there are no ranges, that means this font should be used for |
269 // the full codepoint range, thus running the loop once over a | 271 // the full codepoint range, thus running the loop once over a |
270 // synthetic full UnicodeRange object. Otherwise we use the ranges | 272 // synthetic full UnicodeRange object. Otherwise we use the ranges |
271 // that come from the segmented font. This needs a locally | 273 // that come from the segmented font. This needs a locally |
272 // initialized size_t variable (or a cast alternatively) as a | 274 // initialized size_t variable (or a cast alternatively) as a |
273 // compile fix for Android since size_t differs between platforms. | 275 // compile fix for Android since size_t differs between platforms. |
274 const size_t oneRoundForZeroRanges = 1u; | 276 const size_t oneRoundForZeroRanges = 1u; |
275 for (size_t i = 0; i < max(ranges->size(), oneRoundForZeroRanges); ++i) { | 277 for (size_t i = 0; i < max(ranges->size(), oneRoundForZeroRanges); ++i) { |
276 UnicodeRange range(0, kMaxCodepoint); | 278 UnicodeRange range(0, kMaxCodepoint); |
277 if (ranges->size()) { | 279 if (ranges->size()) { |
278 range = ranges->rangeAt(i); | 280 range = ranges->rangeAt(i); |
279 } | 281 } |
280 // all this casting is to ensure all the parameters to min and max have
the same type, | 282 // all this casting is to ensure all the parameters to min and max have |
281 // to avoid ambiguous template parameter errors on Windows | 283 // the same type, to avoid ambiguous template parameter errors on |
| 284 // Windows |
282 int from = | 285 int from = |
283 max(0, static_cast<int>(range.from()) - static_cast<int>(start)); | 286 max(0, static_cast<int>(range.from()) - static_cast<int>(start)); |
284 int to = 1 + min(static_cast<int>(range.to()) - static_cast<int>(start), | 287 int to = 1 + min(static_cast<int>(range.to()) - static_cast<int>(start), |
285 static_cast<int>(GlyphPage::size) - 1); | 288 static_cast<int>(GlyphPage::size) - 1); |
286 if (from >= static_cast<int>(GlyphPage::size) || to <= 0) | 289 if (from >= static_cast<int>(GlyphPage::size) || to <= 0) |
287 continue; | 290 continue; |
288 | 291 |
289 // If this is a custom font needs to be loaded, do not fill | 292 // If this is a custom font needs to be loaded, do not fill |
290 // the page so that font fallback is used while loading. | 293 // the page so that font fallback is used while loading. |
291 RefPtr<CustomFontData> customData = | 294 RefPtr<CustomFontData> customData = |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 return; | 409 return; |
407 | 410 |
408 // Prune any branch that contains this FontData. | 411 // Prune any branch that contains this FontData. |
409 if (std::unique_ptr<GlyphPageTreeNode> node = m_children.take(fontData)) { | 412 if (std::unique_ptr<GlyphPageTreeNode> node = m_children.take(fontData)) { |
410 if (unsigned customFontCount = node->m_customFontCount + 1) { | 413 if (unsigned customFontCount = node->m_customFontCount + 1) { |
411 for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent) | 414 for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent) |
412 curr->m_customFontCount -= customFontCount; | 415 curr->m_customFontCount -= customFontCount; |
413 } | 416 } |
414 } | 417 } |
415 | 418 |
416 // Check any branches that remain that still have custom fonts underneath them
. | 419 // Check any branches that remain that still have custom fonts underneath |
| 420 // them. |
417 if (!m_customFontCount) | 421 if (!m_customFontCount) |
418 return; | 422 return; |
419 | 423 |
420 GlyphPageTreeNodeMap::iterator end = m_children.end(); | 424 GlyphPageTreeNodeMap::iterator end = m_children.end(); |
421 for (GlyphPageTreeNodeMap::iterator it = m_children.begin(); it != end; ++it) | 425 for (GlyphPageTreeNodeMap::iterator it = m_children.begin(); it != end; ++it) |
422 it->value->pruneCustomFontData(fontData); | 426 it->value->pruneCustomFontData(fontData); |
423 } | 427 } |
424 | 428 |
425 void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, | 429 void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, |
426 unsigned level) { | 430 unsigned level) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 // System fallback page is initialized with the parent's page, as individual | 476 // System fallback page is initialized with the parent's page, as individual |
473 // entries may use different fonts depending on character. If the Font | 477 // entries may use different fonts depending on character. If the Font |
474 // ever finds it needs a glyph out of the system fallback page, it will | 478 // ever finds it needs a glyph out of the system fallback page, it will |
475 // ask the system for the best font to use and fill that glyph in for us. | 479 // ask the system for the best font to use and fill that glyph in for us. |
476 if (GlyphPage* parentPage = m_parent->page()) | 480 if (GlyphPage* parentPage = m_parent->page()) |
477 return parentPage->createCopiedSystemFallbackPage(this); | 481 return parentPage->createCopiedSystemFallbackPage(this); |
478 return GlyphPage::createForMixedFontData(this); | 482 return GlyphPage::createForMixedFontData(this); |
479 } | 483 } |
480 | 484 |
481 } // namespace blink | 485 } // namespace blink |
OLD | NEW |