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