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 |