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