| 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 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 { | 450 { |
| 451 ASSERT_WITH_SECURITY_IMPLICATION(from >= 0); | 451 ASSERT_WITH_SECURITY_IMPLICATION(from >= 0); |
| 452 ASSERT_WITH_SECURITY_IMPLICATION(to <= m_run.length()); | 452 ASSERT_WITH_SECURITY_IMPLICATION(to <= m_run.length()); |
| 453 m_fromIndex = from; | 453 m_fromIndex = from; |
| 454 m_toIndex = to; | 454 m_toIndex = to; |
| 455 } | 455 } |
| 456 | 456 |
| 457 void HarfBuzzShaper::setFontFeatures() | 457 void HarfBuzzShaper::setFontFeatures() |
| 458 { | 458 { |
| 459 const FontDescription& description = m_font->fontDescription(); | 459 const FontDescription& description = m_font->fontDescription(); |
| 460 if (description.orientation() == Vertical) { | |
| 461 static hb_feature_t vert = { HarfBuzzFace::vertTag, 1, 0, static_cast<un
signed>(-1) }; | |
| 462 static hb_feature_t vrt2 = { HarfBuzzFace::vrt2Tag, 1, 0, static_cast<un
signed>(-1) }; | |
| 463 m_features.append(vert); | |
| 464 m_features.append(vrt2); | |
| 465 } | |
| 466 | 460 |
| 467 static hb_feature_t noKern = { HB_TAG('k', 'e', 'r', 'n'), 0, 0, static_cast
<unsigned>(-1) }; | 461 static hb_feature_t noKern = { HB_TAG('k', 'e', 'r', 'n'), 0, 0, static_cast
<unsigned>(-1) }; |
| 468 static hb_feature_t noVkrn = { HB_TAG('v', 'k', 'r', 'n'), 0, 0, static_cast
<unsigned>(-1) }; | 462 static hb_feature_t noVkrn = { HB_TAG('v', 'k', 'r', 'n'), 0, 0, static_cast
<unsigned>(-1) }; |
| 469 switch (description.kerning()) { | 463 switch (description.kerning()) { |
| 470 case FontDescription::NormalKerning: | 464 case FontDescription::NormalKerning: |
| 471 // kern/vkrn are enabled by default | 465 // kern/vkrn are enabled by default |
| 472 break; | 466 break; |
| 473 case FontDescription::NoneKerning: | 467 case FontDescription::NoneKerning: |
| 474 m_features.append(description.orientation() == Vertical ? noVkrn : noKer
n); | 468 m_features.append(description.orientation() == Vertical ? noVkrn : noKer
n); |
| 475 break; | 469 break; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 // A port of hb_icu_script_to_script because harfbuzz on CrOS is built | 772 // A port of hb_icu_script_to_script because harfbuzz on CrOS is built |
| 779 // without hb-icu. See http://crbug.com/356929 | 773 // without hb-icu. See http://crbug.com/356929 |
| 780 static inline hb_script_t ICUScriptToHBScript(UScriptCode script) | 774 static inline hb_script_t ICUScriptToHBScript(UScriptCode script) |
| 781 { | 775 { |
| 782 if (UNLIKELY(script == USCRIPT_INVALID_CODE)) | 776 if (UNLIKELY(script == USCRIPT_INVALID_CODE)) |
| 783 return HB_SCRIPT_INVALID; | 777 return HB_SCRIPT_INVALID; |
| 784 | 778 |
| 785 return hb_script_from_string(uscript_getShortName(script), -1); | 779 return hb_script_from_string(uscript_getShortName(script), -1); |
| 786 } | 780 } |
| 787 | 781 |
| 788 static inline hb_direction_t TextDirectionToHBDirection(TextDirection dir) | 782 static inline hb_direction_t TextDirectionToHBDirection(TextDirection dir, FontO
rientation orientation, const SimpleFontData* fontData) |
| 789 { | 783 { |
| 790 return dir == RTL ? HB_DIRECTION_RTL : HB_DIRECTION_LTR; | 784 hb_direction_t harfBuzzDirection = orientation == Vertical && !fontData->isT
extOrientationFallback() ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; |
| 785 return dir == RTL ? HB_DIRECTION_REVERSE(harfBuzzDirection) : harfBuzzDirect
ion; |
| 791 } | 786 } |
| 792 | 787 |
| 793 | 788 |
| 794 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, | 789 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, |
| 795 unsigned endCharacter, const SimpleFontData* fontData, | 790 unsigned endCharacter, const SimpleFontData* fontData, |
| 796 UScriptCode script) | 791 UScriptCode script) |
| 797 { | 792 { |
| 798 ASSERT(endCharacter > startCharacter); | 793 ASSERT(endCharacter > startCharacter); |
| 799 ASSERT(script != USCRIPT_INVALID_CODE); | 794 ASSERT(script != USCRIPT_INVALID_CODE); |
| 800 if (m_fallbackFonts) | 795 if (m_fallbackFonts) |
| 801 m_fallbackFonts->add(fontData); | 796 m_fallbackFonts->add(fontData); |
| 802 return m_harfBuzzRuns.append(HarfBuzzRun::create(fontData, | 797 return m_harfBuzzRuns.append(HarfBuzzRun::create(fontData, |
| 803 startCharacter, endCharacter - startCharacter, | 798 startCharacter, endCharacter - startCharacter, |
| 804 TextDirectionToHBDirection(m_run.direction()), | 799 TextDirectionToHBDirection(m_run.direction(), m_font->fontDescription().
orientation(), fontData), |
| 805 ICUScriptToHBScript(script))); | 800 ICUScriptToHBScript(script))); |
| 806 } | 801 } |
| 807 | 802 |
| 808 static const uint16_t* toUint16(const UChar* src) | 803 static const uint16_t* toUint16(const UChar* src) |
| 809 { | 804 { |
| 810 // FIXME: This relies on undefined behavior however it works on the | 805 // FIXME: This relies on undefined behavior however it works on the |
| 811 // current versions of all compilers we care about and avoids making | 806 // current versions of all compilers we care about and avoids making |
| 812 // a copy of the string. | 807 // a copy of the string. |
| 813 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_
uint16_t); | 808 COMPILE_ASSERT(sizeof(UChar) == sizeof(uint16_t), UChar_is_the_same_size_as_
uint16_t); |
| 814 return reinterpret_cast<const uint16_t*>(src); | 809 return reinterpret_cast<const uint16_t*>(src); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes(); | 896 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes(); |
| 902 float totalAdvance = 0; | 897 float totalAdvance = 0; |
| 903 FloatPoint glyphOrigin; | 898 FloatPoint glyphOrigin; |
| 904 | 899 |
| 905 // HarfBuzz returns the shaping result in visual order. We need not to flip
for RTL. | 900 // HarfBuzz returns the shaping result in visual order. We need not to flip
for RTL. |
| 906 for (size_t i = 0; i < numGlyphs; ++i) { | 901 for (size_t i = 0; i < numGlyphs; ++i) { |
| 907 bool runEnd = i + 1 == numGlyphs; | 902 bool runEnd = i + 1 == numGlyphs; |
| 908 uint16_t glyph = glyphInfos[i].codepoint; | 903 uint16_t glyph = glyphInfos[i].codepoint; |
| 909 float offsetX = harfBuzzPositionToFloat(glyphPositions[i].x_offset); | 904 float offsetX = harfBuzzPositionToFloat(glyphPositions[i].x_offset); |
| 910 float offsetY = -harfBuzzPositionToFloat(glyphPositions[i].y_offset); | 905 float offsetY = -harfBuzzPositionToFloat(glyphPositions[i].y_offset); |
| 911 float advance = harfBuzzPositionToFloat(glyphPositions[i].x_advance); | 906 // One out of x_advance and y_advance is zero, depending on |
| 907 // whether the buffer direction is horizontal or vertical. |
| 908 float advance = harfBuzzPositionToFloat(glyphPositions[i].x_advance + gl
yphPositions[i].y_advance); |
| 912 | 909 |
| 913 unsigned currentCharacterIndex = currentRun->startIndex() + glyphInfos[i
].cluster; | 910 unsigned currentCharacterIndex = currentRun->startIndex() + glyphInfos[i
].cluster; |
| 914 RELEASE_ASSERT(m_normalizedBufferLength > currentCharacterIndex); | 911 RELEASE_ASSERT(m_normalizedBufferLength > currentCharacterIndex); |
| 915 bool isClusterEnd = runEnd || glyphInfos[i].cluster != glyphInfos[i + 1]
.cluster; | 912 bool isClusterEnd = runEnd || glyphInfos[i].cluster != glyphInfos[i + 1]
.cluster; |
| 916 float spacing = 0; | 913 float spacing = 0; |
| 917 | 914 |
| 918 glyphToCharacterIndexes[i] = glyphInfos[i].cluster; | 915 glyphToCharacterIndexes[i] = glyphInfos[i].cluster; |
| 919 | 916 |
| 920 if (isClusterEnd && !Character::treatAsZeroWidthSpace(m_normalizedBuffer
[currentCharacterIndex])) | 917 if (isClusterEnd && !Character::treatAsZeroWidthSpace(m_normalizedBuffer
[currentCharacterIndex])) |
| 921 spacing += m_letterSpacing; | 918 spacing += m_letterSpacing; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 break; | 1135 break; |
| 1139 if (!m_run.rtl()) | 1136 if (!m_run.rtl()) |
| 1140 currentX += m_harfBuzzRuns[i]->width(); | 1137 currentX += m_harfBuzzRuns[i]->width(); |
| 1141 } | 1138 } |
| 1142 | 1139 |
| 1143 // The position in question might be just after the text. | 1140 // The position in question might be just after the text. |
| 1144 if (!foundFromX) | 1141 if (!foundFromX) |
| 1145 fromX = 0; | 1142 fromX = 0; |
| 1146 if (!foundToX) | 1143 if (!foundToX) |
| 1147 toX = m_run.rtl() ? 0 : m_totalWidth; | 1144 toX = m_run.rtl() ? 0 : m_totalWidth; |
| 1145 // None of our HarfBuzzRuns is part of the selection, |
| 1146 // possibly invalid from, to arguments. |
| 1147 if (!foundToX && !foundFromX) |
| 1148 fromX = toX = 0; |
| 1148 | 1149 |
| 1149 if (fromX < toX) | 1150 if (fromX < toX) |
| 1150 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); | 1151 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); |
| 1151 return FloatRect(point.x() + toX, point.y(), fromX - toX, height); | 1152 return FloatRect(point.x() + toX, point.y(), fromX - toX, height); |
| 1152 } | 1153 } |
| 1153 | 1154 |
| 1154 } // namespace blink | 1155 } // namespace blink |
| OLD | NEW |