OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 Google Inc. All rights reserved. | 2 * Copyright (c) 2012 Google Inc. All rights reserved. |
3 * Copyright (C) 2013 BlackBerry Limited. All rights reserved. | 3 * Copyright (C) 2013 BlackBerry Limited. 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 are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * 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 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 return charactersSoFar + index; | 477 return charactersSoFar + index; |
478 } | 478 } |
479 charactersSoFar += m_runs[i]->m_numCharacters; | 479 charactersSoFar += m_runs[i]->m_numCharacters; |
480 currentX = nextX; | 480 currentX = nextX; |
481 } | 481 } |
482 } | 482 } |
483 | 483 |
484 return charactersSoFar; | 484 return charactersSoFar; |
485 } | 485 } |
486 | 486 |
| 487 void ShapeResult::fallbackFonts(HashSet<const SimpleFontData*>* fallback) const |
| 488 { |
| 489 ASSERT(fallback); |
| 490 for (unsigned i = 0; i < m_runs.size(); ++i) { |
| 491 if (m_runs[i]->m_fontData != m_primaryFont) |
| 492 fallback->add(m_runs[i]->m_fontData); |
| 493 } |
| 494 } |
| 495 |
487 unsigned ShapeResult::numberOfRunsForTesting() const | 496 unsigned ShapeResult::numberOfRunsForTesting() const |
488 { | 497 { |
489 return m_runs.size(); | 498 return m_runs.size(); |
490 } | 499 } |
491 | 500 |
492 bool ShapeResult::runInfoForTesting(unsigned runIndex, unsigned& startIndex, | 501 bool ShapeResult::runInfoForTesting(unsigned runIndex, unsigned& startIndex, |
493 unsigned& numGlyphs, hb_script_t& script) | 502 unsigned& numGlyphs, hb_script_t& script) |
494 { | 503 { |
495 if (runIndex < m_runs.size() && m_runs[runIndex]) { | 504 if (runIndex < m_runs.size() && m_runs[runIndex]) { |
496 startIndex = m_runs[runIndex]->m_startIndex; | 505 startIndex = m_runs[runIndex]->m_startIndex; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 else if (Character::treatAsSpace(character) && character != tabulationCh
aracter) | 594 else if (Character::treatAsSpace(character) && character != tabulationCh
aracter) |
586 character = spaceCharacter; | 595 character = spaceCharacter; |
587 else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) | 596 else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) |
588 character = zeroWidthSpaceCharacter; | 597 character = zeroWidthSpaceCharacter; |
589 | 598 |
590 U16_APPEND(destination, *destinationLength, length, character, error); | 599 U16_APPEND(destination, *destinationLength, length, character, error); |
591 ASSERT_UNUSED(error, !error); | 600 ASSERT_UNUSED(error, !error); |
592 } | 601 } |
593 } | 602 } |
594 | 603 |
595 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run, | 604 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run) |
596 HashSet<const SimpleFontData*>* fallbackFonts) | 605 : Shaper(font, run) |
597 : Shaper(font, run, nullptr, fallbackFonts) | |
598 , m_normalizedBufferLength(0) | 606 , m_normalizedBufferLength(0) |
599 , m_wordSpacingAdjustment(font->fontDescription().wordSpacing()) | 607 , m_wordSpacingAdjustment(font->fontDescription().wordSpacing()) |
600 , m_letterSpacing(font->fontDescription().letterSpacing()) | 608 , m_letterSpacing(font->fontDescription().letterSpacing()) |
601 , m_expansionOpportunityCount(0) | 609 , m_expansionOpportunityCount(0) |
602 { | 610 { |
603 // TODO(eae): Once SimpleShaper is gone the ownership of this should shift | |
604 // to HarfBuzzShaper. | |
605 ASSERT(fallbackFonts); | |
606 m_normalizedBuffer = adoptArrayPtr(new UChar[m_textRun.length() + 1]); | 611 m_normalizedBuffer = adoptArrayPtr(new UChar[m_textRun.length() + 1]); |
607 normalizeCharacters(m_textRun, m_textRun.length(), m_normalizedBuffer.get(),
&m_normalizedBufferLength); | 612 normalizeCharacters(m_textRun, m_textRun.length(), m_normalizedBuffer.get(),
&m_normalizedBufferLength); |
608 setExpansion(m_textRun.expansion()); | 613 setExpansion(m_textRun.expansion()); |
609 setFontFeatures(); | 614 setFontFeatures(); |
610 } | 615 } |
611 | 616 |
612 float HarfBuzzShaper::nextExpansionPerOpportunity() | 617 float HarfBuzzShaper::nextExpansionPerOpportunity() |
613 { | 618 { |
614 if (!m_expansionOpportunityCount) { | 619 if (!m_expansionOpportunityCount) { |
615 ASSERT_NOT_REACHED(); // failures indicate that the logic in HarfBuzzSha
per does not match to the one in expansionOpportunityCount() | 620 ASSERT_NOT_REACHED(); // failures indicate that the logic in HarfBuzzSha
per does not match to the one in expansionOpportunityCount() |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 } | 750 } |
746 | 751 |
747 PassRefPtr<ShapeResult> HarfBuzzShaper::shapeResult() | 752 PassRefPtr<ShapeResult> HarfBuzzShaper::shapeResult() |
748 { | 753 { |
749 if (!createHarfBuzzRuns()) | 754 if (!createHarfBuzzRuns()) |
750 return nullptr; | 755 return nullptr; |
751 | 756 |
752 ShapeResult* result = new ShapeResult(); | 757 ShapeResult* result = new ShapeResult(); |
753 result->m_numCharacters = m_normalizedBufferLength; | 758 result->m_numCharacters = m_normalizedBufferLength; |
754 result->m_direction = m_textRun.direction(); | 759 result->m_direction = m_textRun.direction(); |
| 760 result->m_primaryFont = m_font->primaryFont(); |
755 | 761 |
756 if (!shapeHarfBuzzRuns(result)) { | 762 if (!shapeHarfBuzzRuns(result)) { |
757 delete result; | 763 delete result; |
758 return nullptr; | 764 return nullptr; |
759 } | 765 } |
760 | 766 |
761 return adoptRef(result); | 767 return adoptRef(result); |
762 } | 768 } |
763 | 769 |
764 struct CandidateRun { | 770 struct CandidateRun { |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 hb_direction_t harfBuzzDirection = isVerticalAnyUpright(orientation) && !fon
tData->isTextOrientationFallback() ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; | 973 hb_direction_t harfBuzzDirection = isVerticalAnyUpright(orientation) && !fon
tData->isTextOrientationFallback() ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; |
968 return dir == RTL ? HB_DIRECTION_REVERSE(harfBuzzDirection) : harfBuzzDirect
ion; | 974 return dir == RTL ? HB_DIRECTION_REVERSE(harfBuzzDirection) : harfBuzzDirect
ion; |
969 } | 975 } |
970 | 976 |
971 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, | 977 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, |
972 unsigned endCharacter, const SimpleFontData* fontData, | 978 unsigned endCharacter, const SimpleFontData* fontData, |
973 UScriptCode script) | 979 UScriptCode script) |
974 { | 980 { |
975 ASSERT(endCharacter > startCharacter); | 981 ASSERT(endCharacter > startCharacter); |
976 ASSERT(script != USCRIPT_INVALID_CODE); | 982 ASSERT(script != USCRIPT_INVALID_CODE); |
977 if (m_fallbackFonts) | |
978 trackNonPrimaryFallbackFont(fontData); | |
979 return m_harfBuzzRuns.append(HarfBuzzRun::create(fontData, | 983 return m_harfBuzzRuns.append(HarfBuzzRun::create(fontData, |
980 startCharacter, endCharacter - startCharacter, | 984 startCharacter, endCharacter - startCharacter, |
981 TextDirectionToHBDirection(m_textRun.direction(), m_font->fontDescriptio
n().orientation(), fontData), | 985 TextDirectionToHBDirection(m_textRun.direction(), m_font->fontDescriptio
n().orientation(), fontData), |
982 ICUScriptToHBScript(script))); | 986 ICUScriptToHBScript(script))); |
983 } | 987 } |
984 | 988 |
985 static const uint16_t* toUint16(const UChar* src) | 989 static const uint16_t* toUint16(const UChar* src) |
986 { | 990 { |
987 // FIXME: This relies on undefined behavior however it works on the | 991 // FIXME: This relies on undefined behavior however it works on the |
988 // current versions of all compilers we care about and avoids making | 992 // current versions of all compilers we care about and avoids making |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 totalAdvance += advance; | 1128 totalAdvance += advance; |
1125 | 1129 |
1126 FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); | 1130 FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); |
1127 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); | 1131 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); |
1128 result->m_glyphBoundingBox.unite(glyphBounds); | 1132 result->m_glyphBoundingBox.unite(glyphBounds); |
1129 glyphOrigin += FloatSize(advance + offsetX, offsetY); | 1133 glyphOrigin += FloatSize(advance + offsetX, offsetY); |
1130 } | 1134 } |
1131 | 1135 |
1132 run->m_width = totalAdvance > 0.0 ? totalAdvance : 0.0; | 1136 run->m_width = totalAdvance > 0.0 ? totalAdvance : 0.0; |
1133 result->m_width += run->m_width; | 1137 result->m_width += run->m_width; |
1134 result->m_fallbackFonts = *m_fallbackFonts; | |
1135 } | 1138 } |
1136 | 1139 |
1137 float HarfBuzzShaper::adjustSpacing(ShapeResult::RunInfo* run, size_t glyphIndex
, unsigned currentCharacterIndex, float& offset, float& totalAdvance) | 1140 float HarfBuzzShaper::adjustSpacing(ShapeResult::RunInfo* run, size_t glyphIndex
, unsigned currentCharacterIndex, float& offset, float& totalAdvance) |
1138 { | 1141 { |
1139 float spacing = 0; | 1142 float spacing = 0; |
1140 UChar32 character = m_normalizedBuffer[currentCharacterIndex]; | 1143 UChar32 character = m_normalizedBuffer[currentCharacterIndex]; |
1141 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character)) | 1144 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character)) |
1142 spacing += m_letterSpacing; | 1145 spacing += m_letterSpacing; |
1143 | 1146 |
1144 bool treatAsSpace = Character::treatAsSpace(character); | 1147 bool treatAsSpace = Character::treatAsSpace(character); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 return spacing; | 1187 return spacing; |
1185 } | 1188 } |
1186 | 1189 |
1187 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere
d by !m_expansionOpportunityCount above | 1190 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere
d by !m_expansionOpportunityCount above |
1188 spacing += nextExpansionPerOpportunity(); | 1191 spacing += nextExpansionPerOpportunity(); |
1189 m_isAfterExpansion = true; | 1192 m_isAfterExpansion = true; |
1190 return spacing; | 1193 return spacing; |
1191 } | 1194 } |
1192 | 1195 |
1193 } // namespace blink | 1196 } // namespace blink |
OLD | NEW |