OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. | 5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 24 matching lines...) Expand all Loading... | |
35 #include "platform/fonts/WidthIterator.h" | 35 #include "platform/fonts/WidthIterator.h" |
36 #include "platform/geometry/FloatRect.h" | 36 #include "platform/geometry/FloatRect.h" |
37 #include "platform/text/TextRun.h" | 37 #include "platform/text/TextRun.h" |
38 #include "wtf/MainThread.h" | 38 #include "wtf/MainThread.h" |
39 #include "wtf/StdLibExtras.h" | 39 #include "wtf/StdLibExtras.h" |
40 #include "wtf/unicode/CharacterNames.h" | 40 #include "wtf/unicode/CharacterNames.h" |
41 #include "wtf/unicode/Unicode.h" | 41 #include "wtf/unicode/Unicode.h" |
42 | 42 |
43 using namespace WTF; | 43 using namespace WTF; |
44 using namespace Unicode; | 44 using namespace Unicode; |
45 using namespace std; | |
46 | 45 |
47 namespace blink { | 46 namespace blink { |
48 | 47 |
49 CodePath Font::s_codePath = AutoPath; | 48 CodePath Font::s_codePath = AutoPath; |
50 | 49 |
51 // ============================================================================= =============== | 50 // ============================================================================= =============== |
52 // Font Implementation (Cross-Platform Portion) | 51 // Font Implementation (Cross-Platform Portion) |
53 // ============================================================================= =============== | 52 // ============================================================================= =============== |
54 | 53 |
55 Font::Font() | 54 Font::Font() |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 | 133 |
135 if (codePathToUse != ComplexPath) | 134 if (codePathToUse != ComplexPath) |
136 drawEmphasisMarksForSimpleText(context, runInfo, mark, point); | 135 drawEmphasisMarksForSimpleText(context, runInfo, mark, point); |
137 else | 136 else |
138 drawEmphasisMarksForComplexText(context, runInfo, mark, point); | 137 drawEmphasisMarksForComplexText(context, runInfo, mark, point); |
139 } | 138 } |
140 | 139 |
141 static inline void updateGlyphOverflowFromBounds(const IntRectExtent& glyphBound s, | 140 static inline void updateGlyphOverflowFromBounds(const IntRectExtent& glyphBound s, |
142 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow) | 141 const FontMetrics& fontMetrics, GlyphOverflow* glyphOverflow) |
143 { | 142 { |
144 glyphOverflow->top = max<int>(glyphOverflow->top, | 143 glyphOverflow->top = std::max<int>(glyphOverflow->top, |
145 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce nt())); | 144 glyphBounds.top() - (glyphOverflow->computeBounds ? 0 : fontMetrics.asce nt())); |
146 glyphOverflow->bottom = max<int>(glyphOverflow->bottom, | 145 glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, |
147 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d escent())); | 146 glyphBounds.bottom() - (glyphOverflow->computeBounds ? 0 : fontMetrics.d escent())); |
148 glyphOverflow->left = glyphBounds.left(); | 147 glyphOverflow->left = glyphBounds.left(); |
149 glyphOverflow->right = glyphBounds.right(); | 148 glyphOverflow->right = glyphBounds.right(); |
150 } | 149 } |
151 | 150 |
152 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo nts, GlyphOverflow* glyphOverflow) const | 151 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo nts, GlyphOverflow* glyphOverflow) const |
153 { | 152 { |
154 CodePath codePathToUse = codePath(run); | 153 CodePath codePathToUse = codePath(run); |
155 if (codePathToUse != ComplexPath) { | 154 if (codePathToUse != ComplexPath) { |
156 // The complex path is more restrictive about returning fallback fonts t han the simple path, so we need an explicit test to make their behaviors match. | 155 // The complex path is more restrictive about returning fallback fonts t han the simple path, so we need an explicit test to make their behaviors match. |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForNonCJKCharacte rWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, Gly phData& data, GlyphPage* page, unsigned pageNumber) | 362 static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForNonCJKCharacte rWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, Gly phData& data, GlyphPage* page, unsigned pageNumber) |
364 { | 363 { |
365 if (orientation == NonCJKGlyphOrientationUpright || shouldIgnoreRotation(cha racter)) { | 364 if (orientation == NonCJKGlyphOrientationUpright || shouldIgnoreRotation(cha racter)) { |
366 RefPtr<SimpleFontData> uprightFontData = data.fontData->uprightOrientati onFontData(); | 365 RefPtr<SimpleFontData> uprightFontData = data.fontData->uprightOrientati onFontData(); |
367 GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(upright FontData.get(), pageNumber); | 366 GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(upright FontData.get(), pageNumber); |
368 GlyphPage* uprightPage = uprightNode->page(); | 367 GlyphPage* uprightPage = uprightNode->page(); |
369 if (uprightPage) { | 368 if (uprightPage) { |
370 GlyphData uprightData = uprightPage->glyphDataForCharacter(character ); | 369 GlyphData uprightData = uprightPage->glyphDataForCharacter(character ); |
371 // If the glyphs are the same, then we know we can just use the hori zontal glyph rotated vertically to be upright. | 370 // If the glyphs are the same, then we know we can just use the hori zontal glyph rotated vertically to be upright. |
372 if (data.glyph == uprightData.glyph) | 371 if (data.glyph == uprightData.glyph) |
373 return make_pair(data, page); | 372 return std::make_pair(data, page); |
jamesr
2014/08/28 19:57:21
given the number of make_pair calls i think adding
| |
374 // The glyphs are distinct, meaning that the font has a vertical-rig ht glyph baked into it. We can't use that | 373 // The glyphs are distinct, meaning that the font has a vertical-rig ht glyph baked into it. We can't use that |
375 // glyph, so we fall back to the upright data and use the horizontal glyph. | 374 // glyph, so we fall back to the upright data and use the horizontal glyph. |
376 if (uprightData.fontData) | 375 if (uprightData.fontData) |
377 return make_pair(uprightData, uprightPage); | 376 return std::make_pair(uprightData, uprightPage); |
378 } | 377 } |
379 } else if (orientation == NonCJKGlyphOrientationVerticalRight) { | 378 } else if (orientation == NonCJKGlyphOrientationVerticalRight) { |
380 RefPtr<SimpleFontData> verticalRightFontData = data.fontData->verticalRi ghtOrientationFontData(); | 379 RefPtr<SimpleFontData> verticalRightFontData = data.fontData->verticalRi ghtOrientationFontData(); |
381 GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(v erticalRightFontData.get(), pageNumber); | 380 GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(v erticalRightFontData.get(), pageNumber); |
382 GlyphPage* verticalRightPage = verticalRightNode->page(); | 381 GlyphPage* verticalRightPage = verticalRightNode->page(); |
383 if (verticalRightPage) { | 382 if (verticalRightPage) { |
384 GlyphData verticalRightData = verticalRightPage->glyphDataForCharact er(character); | 383 GlyphData verticalRightData = verticalRightPage->glyphDataForCharact er(character); |
385 // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked | 384 // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked |
386 // into it. | 385 // into it. |
387 if (data.glyph != verticalRightData.glyph) | 386 if (data.glyph != verticalRightData.glyph) |
388 return make_pair(data, page); | 387 return std::make_pair(data, page); |
389 // The glyphs are identical, meaning that we should just use the hor izontal glyph. | 388 // The glyphs are identical, meaning that we should just use the hor izontal glyph. |
390 if (verticalRightData.fontData) | 389 if (verticalRightData.fontData) |
391 return make_pair(verticalRightData, verticalRightPage); | 390 return std::make_pair(verticalRightData, verticalRightPage); |
392 } | 391 } |
393 } | 392 } |
394 return make_pair(data, page); | 393 return std::make_pair(data, page); |
395 } | 394 } |
396 | 395 |
397 std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b ool mirror, FontDataVariant variant) const | 396 std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b ool mirror, FontDataVariant variant) const |
398 { | 397 { |
399 ASSERT(isMainThread()); | 398 ASSERT(isMainThread()); |
400 | 399 |
401 if (variant == AutoVariant) { | 400 if (variant == AutoVariant) { |
402 if (m_fontDescription.variant() == FontVariantSmallCaps && !primaryFont( )->isSVGFont()) { | 401 if (m_fontDescription.variant() == FontVariantSmallCaps && !primaryFont( )->isSVGFont()) { |
403 UChar32 upperC = toUpper(c); | 402 UChar32 upperC = toUpper(c); |
404 if (upperC != c) { | 403 if (upperC != c) { |
(...skipping 19 matching lines...) Expand all Loading... | |
424 } | 423 } |
425 | 424 |
426 GlyphPage* page = 0; | 425 GlyphPage* page = 0; |
427 if (variant == NormalVariant) { | 426 if (variant == NormalVariant) { |
428 // Fastest loop, for the common case (normal variant). | 427 // Fastest loop, for the common case (normal variant). |
429 while (true) { | 428 while (true) { |
430 page = node->page(); | 429 page = node->page(); |
431 if (page) { | 430 if (page) { |
432 GlyphData data = page->glyphDataForCharacter(c); | 431 GlyphData data = page->glyphDataForCharacter(c); |
433 if (data.fontData && (data.fontData->platformData().orientation( ) == Horizontal || data.fontData->isTextOrientationFallback())) | 432 if (data.fontData && (data.fontData->platformData().orientation( ) == Horizontal || data.fontData->isTextOrientationFallback())) |
434 return make_pair(data, page); | 433 return std::make_pair(data, page); |
435 | 434 |
436 if (data.fontData) { | 435 if (data.fontData) { |
437 if (Character::isCJKIdeographOrSymbol(c)) { | 436 if (Character::isCJKIdeographOrSymbol(c)) { |
438 if (!data.fontData->hasVerticalGlyphs()) { | 437 if (!data.fontData->hasVerticalGlyphs()) { |
439 // Use the broken ideograph font data. The broken id eograph font will use the horizontal width of glyphs | 438 // Use the broken ideograph font data. The broken id eograph font will use the horizontal width of glyphs |
440 // to make sure you get a square (even for broken gl yphs like symbols used for punctuation). | 439 // to make sure you get a square (even for broken gl yphs like symbols used for punctuation). |
441 variant = BrokenIdeographVariant; | 440 variant = BrokenIdeographVariant; |
442 break; | 441 break; |
443 } | 442 } |
444 } else { | 443 } else { |
445 return glyphDataAndPageForNonCJKCharacterWithGlyphOrient ation(c, m_fontDescription.nonCJKGlyphOrientation(), data, page, pageNumber); | 444 return glyphDataAndPageForNonCJKCharacterWithGlyphOrient ation(c, m_fontDescription.nonCJKGlyphOrientation(), data, page, pageNumber); |
446 } | 445 } |
447 | 446 |
448 return make_pair(data, page); | 447 return std::make_pair(data, page); |
449 } | 448 } |
450 | 449 |
451 if (node->isSystemFallback()) | 450 if (node->isSystemFallback()) |
452 break; | 451 break; |
453 } | 452 } |
454 | 453 |
455 // Proceed with the fallback list. | 454 // Proceed with the fallback list. |
456 node = node->getChild(fontDataAt(node->level()), pageNumber); | 455 node = node->getChild(fontDataAt(node->level()), pageNumber); |
457 m_fontFallbackList->setPageNode(pageNumber, node); | 456 m_fontFallbackList->setPageNode(pageNumber, node); |
458 } | 457 } |
459 } | 458 } |
460 if (variant != NormalVariant) { | 459 if (variant != NormalVariant) { |
461 while (true) { | 460 while (true) { |
462 page = node->page(); | 461 page = node->page(); |
463 if (page) { | 462 if (page) { |
464 GlyphData data = page->glyphDataForCharacter(c); | 463 GlyphData data = page->glyphDataForCharacter(c); |
465 if (data.fontData) { | 464 if (data.fontData) { |
466 // The variantFontData function should not normally return 0 . | 465 // The variantFontData function should not normally return 0 . |
467 // But if it does, we will just render the capital letter bi g. | 466 // But if it does, we will just render the capital letter bi g. |
468 RefPtr<SimpleFontData> variantFontData = data.fontData->vari antFontData(m_fontDescription, variant); | 467 RefPtr<SimpleFontData> variantFontData = data.fontData->vari antFontData(m_fontDescription, variant); |
469 if (!variantFontData) | 468 if (!variantFontData) |
470 return make_pair(data, page); | 469 return std::make_pair(data, page); |
471 | 470 |
472 GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootC hild(variantFontData.get(), pageNumber); | 471 GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootC hild(variantFontData.get(), pageNumber); |
473 GlyphPage* variantPage = variantNode->page(); | 472 GlyphPage* variantPage = variantNode->page(); |
474 if (variantPage) { | 473 if (variantPage) { |
475 GlyphData data = variantPage->glyphDataForCharacter(c); | 474 GlyphData data = variantPage->glyphDataForCharacter(c); |
476 if (data.fontData) | 475 if (data.fontData) |
477 return make_pair(data, variantPage); | 476 return std::make_pair(data, variantPage); |
478 } | 477 } |
479 | 478 |
480 // Do not attempt system fallback off the variantFontData. T his is the very unlikely case that | 479 // Do not attempt system fallback off the variantFontData. T his is the very unlikely case that |
481 // a font has the lowercase character but the small caps fon t does not have its uppercase version. | 480 // a font has the lowercase character but the small caps fon t does not have its uppercase version. |
482 return make_pair(variantFontData->missingGlyphData(), page); | 481 return std::make_pair(variantFontData->missingGlyphData(), p age); |
483 } | 482 } |
484 | 483 |
485 if (node->isSystemFallback()) | 484 if (node->isSystemFallback()) |
486 break; | 485 break; |
487 } | 486 } |
488 | 487 |
489 // Proceed with the fallback list. | 488 // Proceed with the fallback list. |
490 node = node->getChild(fontDataAt(node->level()), pageNumber); | 489 node = node->getChild(fontDataAt(node->level()), pageNumber); |
491 m_fontFallbackList->setPageNode(pageNumber, node); | 490 m_fontFallbackList->setPageNode(pageNumber, node); |
492 } | 491 } |
(...skipping 19 matching lines...) Expand all Loading... | |
512 if (variant != NormalVariant) | 511 if (variant != NormalVariant) |
513 characterFontData = characterFontData->variantFontData(m_fontDescrip tion, variant); | 512 characterFontData = characterFontData->variantFontData(m_fontDescrip tion, variant); |
514 } | 513 } |
515 if (characterFontData) { | 514 if (characterFontData) { |
516 // Got the fallback glyph and font. | 515 // Got the fallback glyph and font. |
517 GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontD ata.get(), pageNumber)->page(); | 516 GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontD ata.get(), pageNumber)->page(); |
518 GlyphData data = fallbackPage && fallbackPage->glyphForCharacter(c) ? fa llbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData(); | 517 GlyphData data = fallbackPage && fallbackPage->glyphForCharacter(c) ? fa llbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData(); |
519 // Cache it so we don't have to do system fallback again next time. | 518 // Cache it so we don't have to do system fallback again next time. |
520 if (variant == NormalVariant) { | 519 if (variant == NormalVariant) { |
521 page->setGlyphDataForCharacter(c, data.glyph, data.fontData); | 520 page->setGlyphDataForCharacter(c, data.glyph, data.fontData); |
522 data.fontData->setMaxGlyphPageTreeLevel(max(data.fontData->maxGlyphP ageTreeLevel(), node->level())); | 521 data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxG lyphPageTreeLevel(), node->level())); |
523 if (!Character::isCJKIdeographOrSymbol(c) && data.fontData->platform Data().orientation() != Horizontal && !data.fontData->isTextOrientationFallback( )) | 522 if (!Character::isCJKIdeographOrSymbol(c) && data.fontData->platform Data().orientation() != Horizontal && !data.fontData->isTextOrientationFallback( )) |
524 return glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(c, m_fontDescription.nonCJKGlyphOrientation(), data, page, pageNumber); | 523 return glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(c, m_fontDescription.nonCJKGlyphOrientation(), data, page, pageNumber); |
525 } | 524 } |
526 return make_pair(data, page); | 525 return std::make_pair(data, page); |
527 } | 526 } |
528 | 527 |
529 // Even system fallback can fail; use the missing glyph in that case. | 528 // Even system fallback can fail; use the missing glyph in that case. |
530 // FIXME: It would be nicer to use the missing glyph from the last resort fo nt instead. | 529 // FIXME: It would be nicer to use the missing glyph from the last resort fo nt instead. |
531 GlyphData data = primaryFont()->missingGlyphData(); | 530 GlyphData data = primaryFont()->missingGlyphData(); |
532 if (variant == NormalVariant) { | 531 if (variant == NormalVariant) { |
533 page->setGlyphDataForCharacter(c, data.glyph, data.fontData); | 532 page->setGlyphDataForCharacter(c, data.glyph, data.fontData); |
534 data.fontData->setMaxGlyphPageTreeLevel(max(data.fontData->maxGlyphPageT reeLevel(), node->level())); | 533 data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyph PageTreeLevel(), node->level())); |
535 } | 534 } |
536 return make_pair(data, page); | 535 return std::make_pair(data, page); |
537 } | 536 } |
538 | 537 |
539 bool Font::primaryFontHasGlyphForCharacter(UChar32 character) const | 538 bool Font::primaryFontHasGlyphForCharacter(UChar32 character) const |
540 { | 539 { |
541 unsigned pageNumber = (character / GlyphPage::size); | 540 unsigned pageNumber = (character / GlyphPage::size); |
542 | 541 |
543 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(primaryFont(), pag eNumber); | 542 GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(primaryFont(), pag eNumber); |
544 GlyphPage* page = node->page(); | 543 GlyphPage* page = node->page(); |
545 | 544 |
546 return page && page->glyphForCharacter(character); | 545 return page && page->glyphForCharacter(character); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
836 if (delta <= 0) | 835 if (delta <= 0) |
837 break; | 836 break; |
838 } | 837 } |
839 } | 838 } |
840 } | 839 } |
841 | 840 |
842 return offset; | 841 return offset; |
843 } | 842 } |
844 | 843 |
845 } // namespace blink | 844 } // namespace blink |
OLD | NEW |