| 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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 157 |
| 158 void ShapeResult::RunInfo::setGlyphAndPositions(unsigned index, | 158 void ShapeResult::RunInfo::setGlyphAndPositions(unsigned index, |
| 159 uint16_t glyphId, float advance, float offsetX, float offsetY) | 159 uint16_t glyphId, float advance, float offsetX, float offsetY) |
| 160 { | 160 { |
| 161 HarfBuzzRunGlyphData& data = m_glyphData[index]; | 161 HarfBuzzRunGlyphData& data = m_glyphData[index]; |
| 162 data.glyph = glyphId; | 162 data.glyph = glyphId; |
| 163 data.advance = advance; | 163 data.advance = advance; |
| 164 data.offset = FloatSize(offsetX, offsetY); | 164 data.offset = FloatSize(offsetX, offsetY); |
| 165 } | 165 } |
| 166 | 166 |
| 167 ShapeResult::ShapeResult(unsigned numCharacters, TextDirection direction) | 167 ShapeResult::ShapeResult(const Font* font, unsigned numCharacters, TextDirection
direction) |
| 168 : m_width(0) | 168 : m_width(0) |
| 169 , m_primaryFont(const_cast<SimpleFontData*>(font->primaryFont())) |
| 169 , m_numCharacters(numCharacters) | 170 , m_numCharacters(numCharacters) |
| 170 , m_numGlyphs(0) | 171 , m_numGlyphs(0) |
| 171 , m_direction(direction) | 172 , m_direction(direction) |
| 172 { | 173 { |
| 173 } | 174 } |
| 174 | 175 |
| 175 ShapeResult::~ShapeResult() | 176 ShapeResult::~ShapeResult() |
| 176 { | 177 { |
| 177 } | 178 } |
| 178 | 179 |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 return charactersSoFar + index; | 477 return charactersSoFar + index; |
| 477 } | 478 } |
| 478 charactersSoFar += m_runs[i]->m_numCharacters; | 479 charactersSoFar += m_runs[i]->m_numCharacters; |
| 479 currentX = nextX; | 480 currentX = nextX; |
| 480 } | 481 } |
| 481 } | 482 } |
| 482 | 483 |
| 483 return charactersSoFar; | 484 return charactersSoFar; |
| 484 } | 485 } |
| 485 | 486 |
| 487 void ShapeResult::fallbackFonts(HashSet<const SimpleFontData*>* fallback) const |
| 488 { |
| 489 ASSERT(fallback); |
| 490 ASSERT(m_primaryFont); |
| 491 for (unsigned i = 0; i < m_runs.size(); ++i) { |
| 492 if (m_runs[i] && m_runs[i]->m_fontData != m_primaryFont) |
| 493 fallback->add(m_runs[i]->m_fontData.get()); |
| 494 } |
| 495 } |
| 496 |
| 486 unsigned ShapeResult::numberOfRunsForTesting() const | 497 unsigned ShapeResult::numberOfRunsForTesting() const |
| 487 { | 498 { |
| 488 return m_runs.size(); | 499 return m_runs.size(); |
| 489 } | 500 } |
| 490 | 501 |
| 491 bool ShapeResult::runInfoForTesting(unsigned runIndex, unsigned& startIndex, | 502 bool ShapeResult::runInfoForTesting(unsigned runIndex, unsigned& startIndex, |
| 492 unsigned& numGlyphs, hb_script_t& script) | 503 unsigned& numGlyphs, hb_script_t& script) |
| 493 { | 504 { |
| 494 if (runIndex < m_runs.size() && m_runs[runIndex]) { | 505 if (runIndex < m_runs.size() && m_runs[runIndex]) { |
| 495 startIndex = m_runs[runIndex]->m_startIndex; | 506 startIndex = m_runs[runIndex]->m_startIndex; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 else if (Character::treatAsSpace(character) && character != tabulationCh
aracter) | 573 else if (Character::treatAsSpace(character) && character != tabulationCh
aracter) |
| 563 character = spaceCharacter; | 574 character = spaceCharacter; |
| 564 else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) | 575 else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) |
| 565 character = zeroWidthSpaceCharacter; | 576 character = zeroWidthSpaceCharacter; |
| 566 | 577 |
| 567 U16_APPEND(destination, *destinationLength, length, character, error); | 578 U16_APPEND(destination, *destinationLength, length, character, error); |
| 568 ASSERT_UNUSED(error, !error); | 579 ASSERT_UNUSED(error, !error); |
| 569 } | 580 } |
| 570 } | 581 } |
| 571 | 582 |
| 572 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run, | 583 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run) |
| 573 HashSet<const SimpleFontData*>* fallbackFonts) | 584 : Shaper(font, run) |
| 574 : Shaper(font, run, nullptr, fallbackFonts) | |
| 575 , m_normalizedBufferLength(0) | 585 , m_normalizedBufferLength(0) |
| 576 , m_wordSpacingAdjustment(font->fontDescription().wordSpacing()) | 586 , m_wordSpacingAdjustment(font->fontDescription().wordSpacing()) |
| 577 , m_letterSpacing(font->fontDescription().letterSpacing()) | 587 , m_letterSpacing(font->fontDescription().letterSpacing()) |
| 578 , m_expansionOpportunityCount(0) | 588 , m_expansionOpportunityCount(0) |
| 579 { | 589 { |
| 580 // TODO(eae): Once SimpleShaper is gone the ownership of this should shift | |
| 581 // to HarfBuzzShaper. | |
| 582 ASSERT(fallbackFonts); | |
| 583 m_normalizedBuffer = adoptArrayPtr(new UChar[m_textRun.length() + 1]); | 590 m_normalizedBuffer = adoptArrayPtr(new UChar[m_textRun.length() + 1]); |
| 584 normalizeCharacters(m_textRun, m_textRun.length(), m_normalizedBuffer.get(),
&m_normalizedBufferLength); | 591 normalizeCharacters(m_textRun, m_textRun.length(), m_normalizedBuffer.get(),
&m_normalizedBufferLength); |
| 585 setExpansion(m_textRun.expansion()); | 592 setExpansion(m_textRun.expansion()); |
| 586 setFontFeatures(); | 593 setFontFeatures(); |
| 587 } | 594 } |
| 588 | 595 |
| 589 float HarfBuzzShaper::nextExpansionPerOpportunity() | 596 float HarfBuzzShaper::nextExpansionPerOpportunity() |
| 590 { | 597 { |
| 591 if (!m_expansionOpportunityCount) { | 598 if (!m_expansionOpportunityCount) { |
| 592 ASSERT_NOT_REACHED(); // failures indicate that the logic in HarfBuzzSha
per does not match to the one in expansionOpportunityCount() | 599 ASSERT_NOT_REACHED(); // failures indicate that the logic in HarfBuzzSha
per does not match to the one in expansionOpportunityCount() |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 hb_direction_t harfBuzzDirection = isVerticalAnyUpright(orientation) && !fon
tData->isTextOrientationFallback() ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; | 940 hb_direction_t harfBuzzDirection = isVerticalAnyUpright(orientation) && !fon
tData->isTextOrientationFallback() ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; |
| 934 return dir == RTL ? HB_DIRECTION_REVERSE(harfBuzzDirection) : harfBuzzDirect
ion; | 941 return dir == RTL ? HB_DIRECTION_REVERSE(harfBuzzDirection) : harfBuzzDirect
ion; |
| 935 } | 942 } |
| 936 | 943 |
| 937 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, | 944 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, |
| 938 unsigned endCharacter, const SimpleFontData* fontData, | 945 unsigned endCharacter, const SimpleFontData* fontData, |
| 939 UScriptCode script) | 946 UScriptCode script) |
| 940 { | 947 { |
| 941 ASSERT(endCharacter > startCharacter); | 948 ASSERT(endCharacter > startCharacter); |
| 942 ASSERT(script != USCRIPT_INVALID_CODE); | 949 ASSERT(script != USCRIPT_INVALID_CODE); |
| 943 if (m_fallbackFonts) | |
| 944 trackNonPrimaryFallbackFont(fontData); | |
| 945 | 950 |
| 946 hb_direction_t direction = TextDirectionToHBDirection(m_textRun.direction(), | 951 hb_direction_t direction = TextDirectionToHBDirection(m_textRun.direction(), |
| 947 m_font->fontDescription().orientation(), fontData); | 952 m_font->fontDescription().orientation(), fontData); |
| 948 HarfBuzzRun harfBuzzRun = { | 953 HarfBuzzRun harfBuzzRun = { |
| 949 fontData, startCharacter, endCharacter - startCharacter, | 954 fontData, startCharacter, endCharacter - startCharacter, |
| 950 direction, ICUScriptToHBScript(script) | 955 direction, ICUScriptToHBScript(script) |
| 951 }; | 956 }; |
| 952 m_harfBuzzRuns.append(harfBuzzRun); | 957 m_harfBuzzRuns.append(harfBuzzRun); |
| 953 } | 958 } |
| 954 | 959 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 975 hb_buffer_add_utf16(buffer, toUint16(upperText.characters16()), | 980 hb_buffer_add_utf16(buffer, toUint16(upperText.characters16()), |
| 976 numCharacters, 0, numCharacters); | 981 numCharacters, 0, numCharacters); |
| 977 } else { | 982 } else { |
| 978 hb_buffer_add_utf16(buffer, toUint16(normalizedBuffer + startIndex), | 983 hb_buffer_add_utf16(buffer, toUint16(normalizedBuffer + startIndex), |
| 979 numCharacters, 0, numCharacters); | 984 numCharacters, 0, numCharacters); |
| 980 } | 985 } |
| 981 } | 986 } |
| 982 | 987 |
| 983 PassRefPtr<ShapeResult> HarfBuzzShaper::shapeHarfBuzzRuns() | 988 PassRefPtr<ShapeResult> HarfBuzzShaper::shapeHarfBuzzRuns() |
| 984 { | 989 { |
| 985 RefPtr<ShapeResult> result = ShapeResult::create( | 990 RefPtr<ShapeResult> result = ShapeResult::create(m_font, |
| 986 m_normalizedBufferLength, m_textRun.direction()); | 991 m_normalizedBufferLength, m_textRun.direction()); |
| 987 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_
destroy); | 992 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_
destroy); |
| 988 | 993 |
| 989 const FontDescription& fontDescription = m_font->fontDescription(); | 994 const FontDescription& fontDescription = m_font->fontDescription(); |
| 990 const String& localeString = fontDescription.locale(); | 995 const String& localeString = fontDescription.locale(); |
| 991 CString locale = localeString.latin1(); | 996 CString locale = localeString.latin1(); |
| 992 const hb_language_t language = hb_language_from_string(locale.data(), locale
.length()); | 997 const hb_language_t language = hb_language_from_string(locale.data(), locale
.length()); |
| 993 | 998 |
| 994 result->m_runs.resize(m_harfBuzzRuns.size()); | 999 result->m_runs.resize(m_harfBuzzRuns.size()); |
| 995 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { | 1000 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); | 1098 FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); |
| 1094 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); | 1099 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); |
| 1095 result->m_glyphBoundingBox.unite(glyphBounds); | 1100 result->m_glyphBoundingBox.unite(glyphBounds); |
| 1096 glyphOrigin += FloatSize(advance + offsetX, offsetY); | 1101 glyphOrigin += FloatSize(advance + offsetX, offsetY); |
| 1097 } | 1102 } |
| 1098 | 1103 |
| 1099 run->m_width = totalAdvance > 0.0 ? totalAdvance : 0.0; | 1104 run->m_width = totalAdvance > 0.0 ? totalAdvance : 0.0; |
| 1100 result->m_width += run->m_width; | 1105 result->m_width += run->m_width; |
| 1101 result->m_numGlyphs += numGlyphs; | 1106 result->m_numGlyphs += numGlyphs; |
| 1102 result->m_runs[index] = run.release(); | 1107 result->m_runs[index] = run.release(); |
| 1103 for (auto& fallbackFont : *m_fallbackFonts) | |
| 1104 result->m_fallbackFonts.add(const_cast<SimpleFontData*>(fallbackFont)); | |
| 1105 } | 1108 } |
| 1106 | 1109 |
| 1107 float HarfBuzzShaper::adjustSpacing(ShapeResult::RunInfo* run, size_t glyphIndex
, unsigned currentCharacterIndex, float& offset, float& totalAdvance) | 1110 float HarfBuzzShaper::adjustSpacing(ShapeResult::RunInfo* run, size_t glyphIndex
, unsigned currentCharacterIndex, float& offset, float& totalAdvance) |
| 1108 { | 1111 { |
| 1109 float spacing = 0; | 1112 float spacing = 0; |
| 1110 UChar32 character = m_normalizedBuffer[currentCharacterIndex]; | 1113 UChar32 character = m_normalizedBuffer[currentCharacterIndex]; |
| 1111 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character)) | 1114 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character)) |
| 1112 spacing += m_letterSpacing; | 1115 spacing += m_letterSpacing; |
| 1113 | 1116 |
| 1114 bool treatAsSpace = Character::treatAsSpace(character); | 1117 bool treatAsSpace = Character::treatAsSpace(character); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 return spacing; | 1157 return spacing; |
| 1155 } | 1158 } |
| 1156 | 1159 |
| 1157 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere
d by !m_expansionOpportunityCount above | 1160 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere
d by !m_expansionOpportunityCount above |
| 1158 spacing += nextExpansionPerOpportunity(); | 1161 spacing += nextExpansionPerOpportunity(); |
| 1159 m_isAfterExpansion = true; | 1162 m_isAfterExpansion = true; |
| 1160 return spacing; | 1163 return spacing; |
| 1161 } | 1164 } |
| 1162 | 1165 |
| 1163 } // namespace blink | 1166 } // namespace blink |
| OLD | NEW |