Chromium Code Reviews| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 struct ShapeResult::RunInfo { | 68 struct ShapeResult::RunInfo { |
| 69 RunInfo(const SimpleFontData* font, hb_direction_t dir, hb_script_t script, | 69 RunInfo(const SimpleFontData* font, hb_direction_t dir, hb_script_t script, |
| 70 unsigned startIndex, unsigned numGlyphs, unsigned numCharacters) | 70 unsigned startIndex, unsigned numGlyphs, unsigned numCharacters) |
| 71 : m_fontData(const_cast<SimpleFontData*>(font)), m_direction(dir), m_scr ipt(script) | 71 : m_fontData(const_cast<SimpleFontData*>(font)), m_direction(dir), m_scr ipt(script) |
| 72 , m_startIndex(startIndex), m_numCharacters(numCharacters) | 72 , m_startIndex(startIndex), m_numCharacters(numCharacters) |
| 73 , m_numGlyphs(numGlyphs), m_width(0.0f) | 73 , m_numGlyphs(numGlyphs), m_width(0.0f) |
| 74 { | 74 { |
| 75 m_glyphData.resize(m_numGlyphs); | 75 m_glyphData.resize(m_numGlyphs); |
| 76 } | 76 } |
| 77 | 77 |
| 78 bool rtl() const { return HB_DIRECTION_IS_BACKWARD(m_direction); } | |
| 79 float xPositionForVisualOffset(unsigned) const; | |
| 78 float xPositionForOffset(unsigned) const; | 80 float xPositionForOffset(unsigned) const; |
| 79 int characterIndexForXPosition(float) const; | 81 int characterIndexForXPosition(float) const; |
| 80 void setGlyphAndPositions(unsigned index, uint16_t glyphId, float advance, | 82 void setGlyphAndPositions(unsigned index, uint16_t glyphId, float advance, |
| 81 float offsetX, float offsetY); | 83 float offsetX, float offsetY); |
| 82 | 84 |
| 83 void addAdvance(unsigned index, float advance) | 85 void addAdvance(unsigned index, float advance) |
| 84 { | 86 { |
| 85 m_glyphData[index].advance += advance; | 87 m_glyphData[index].advance += advance; |
| 86 } | 88 } |
| 87 | 89 |
| 88 size_t glyphToCharacterIndex(size_t i) const | 90 size_t glyphToCharacterIndex(size_t i) const |
| 89 { | 91 { |
| 90 return m_startIndex + m_glyphData[i].characterIndex; | 92 return m_startIndex + m_glyphData[i].characterIndex; |
| 91 } | 93 } |
| 92 | 94 |
| 93 RefPtr<SimpleFontData> m_fontData; | 95 RefPtr<SimpleFontData> m_fontData; |
| 94 hb_direction_t m_direction; | 96 hb_direction_t m_direction; |
| 95 hb_script_t m_script; | 97 hb_script_t m_script; |
| 96 Vector<HarfBuzzRunGlyphData> m_glyphData; | 98 Vector<HarfBuzzRunGlyphData> m_glyphData; |
| 97 unsigned m_startIndex; | 99 unsigned m_startIndex; |
| 98 unsigned m_numCharacters; | 100 unsigned m_numCharacters; |
| 99 unsigned m_numGlyphs; | 101 unsigned m_numGlyphs; |
| 100 float m_width; | 102 float m_width; |
| 101 }; | 103 }; |
| 102 | 104 |
| 105 float ShapeResult::RunInfo::xPositionForVisualOffset(unsigned offset) const | |
| 106 { | |
| 107 ASSERT(offset < m_numCharacters); | |
| 108 if (rtl()) | |
| 109 offset = m_numCharacters - offset - 1; | |
| 110 return xPositionForOffset(offset); | |
| 111 } | |
| 112 | |
| 103 float ShapeResult::RunInfo::xPositionForOffset(unsigned offset) const | 113 float ShapeResult::RunInfo::xPositionForOffset(unsigned offset) const |
| 104 { | 114 { |
| 105 ASSERT(offset <= m_numCharacters); | 115 ASSERT(offset <= m_numCharacters); |
| 106 unsigned glyphIndex = 0; | 116 unsigned glyphIndex = 0; |
| 107 float position = 0; | 117 float position = 0; |
| 108 if (m_direction == HB_DIRECTION_RTL) { | 118 if (rtl()) { |
| 109 while (glyphIndex < m_numGlyphs && m_glyphData[glyphIndex].characterInde x > offset) { | 119 while (glyphIndex < m_numGlyphs && m_glyphData[glyphIndex].characterInde x > offset) { |
| 110 position += m_glyphData[glyphIndex].advance; | 120 position += m_glyphData[glyphIndex].advance; |
| 111 ++glyphIndex; | 121 ++glyphIndex; |
| 112 } | 122 } |
| 113 // For RTL, we need to return the right side boundary of the character. | 123 // For RTL, we need to return the right side boundary of the character. |
| 114 // Add advance of glyphs which are part of the character. | 124 // Add advance of glyphs which are part of the character. |
| 115 while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].character Index == m_glyphData[glyphIndex + 1].characterIndex) { | 125 while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].character Index == m_glyphData[glyphIndex + 1].characterIndex) { |
| 116 position += m_glyphData[glyphIndex].advance; | 126 position += m_glyphData[glyphIndex].advance; |
| 117 ++glyphIndex; | 127 ++glyphIndex; |
| 118 } | 128 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 131 ASSERT(targetX <= m_width); | 141 ASSERT(targetX <= m_width); |
| 132 float currentX = 0; | 142 float currentX = 0; |
| 133 float currentAdvance = m_glyphData[0].advance; | 143 float currentAdvance = m_glyphData[0].advance; |
| 134 unsigned glyphIndex = 0; | 144 unsigned glyphIndex = 0; |
| 135 | 145 |
| 136 // Sum up advances that belong to the first character. | 146 // Sum up advances that belong to the first character. |
| 137 while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].characterInde x == m_glyphData[glyphIndex + 1].characterIndex) | 147 while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].characterInde x == m_glyphData[glyphIndex + 1].characterIndex) |
| 138 currentAdvance += m_glyphData[++glyphIndex].advance; | 148 currentAdvance += m_glyphData[++glyphIndex].advance; |
| 139 currentAdvance = currentAdvance / 2.0; | 149 currentAdvance = currentAdvance / 2.0; |
| 140 if (targetX <= currentAdvance) | 150 if (targetX <= currentAdvance) |
| 141 return m_direction == HB_DIRECTION_RTL ? m_numCharacters : 0; | 151 return rtl() ? m_numCharacters : 0; |
| 142 | 152 |
| 143 currentX = currentAdvance; | 153 currentX = currentAdvance; |
| 144 ++glyphIndex; | 154 ++glyphIndex; |
| 145 while (glyphIndex < m_numGlyphs) { | 155 while (glyphIndex < m_numGlyphs) { |
| 146 unsigned prevCharacterIndex = m_glyphData[glyphIndex - 1].characterIndex ; | 156 unsigned prevCharacterIndex = m_glyphData[glyphIndex - 1].characterIndex ; |
| 147 float prevAdvance = currentAdvance; | 157 float prevAdvance = currentAdvance; |
| 148 currentAdvance = m_glyphData[glyphIndex].advance; | 158 currentAdvance = m_glyphData[glyphIndex].advance; |
| 149 while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].character Index == m_glyphData[glyphIndex + 1].characterIndex) | 159 while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].character Index == m_glyphData[glyphIndex + 1].characterIndex) |
| 150 currentAdvance += m_glyphData[++glyphIndex].advance; | 160 currentAdvance += m_glyphData[++glyphIndex].advance; |
| 151 currentAdvance = currentAdvance / 2.0; | 161 currentAdvance = currentAdvance / 2.0; |
| 152 float nextX = currentX + prevAdvance + currentAdvance; | 162 float nextX = currentX + prevAdvance + currentAdvance; |
| 153 if (currentX <= targetX && targetX <= nextX) | 163 if (currentX <= targetX && targetX <= nextX) |
| 154 return m_direction == HB_DIRECTION_RTL ? prevCharacterIndex : m_glyp hData[glyphIndex].characterIndex; | 164 return rtl() ? prevCharacterIndex : m_glyphData[glyphIndex].characte rIndex; |
| 155 currentX = nextX; | 165 currentX = nextX; |
| 156 ++glyphIndex; | 166 ++glyphIndex; |
| 157 } | 167 } |
| 158 | 168 |
| 159 return m_direction == HB_DIRECTION_RTL ? 0 : m_numCharacters; | 169 return rtl() ? 0 : m_numCharacters; |
| 160 } | 170 } |
| 161 | 171 |
| 162 void ShapeResult::RunInfo::setGlyphAndPositions(unsigned index, | 172 void ShapeResult::RunInfo::setGlyphAndPositions(unsigned index, |
| 163 uint16_t glyphId, float advance, float offsetX, float offsetY) | 173 uint16_t glyphId, float advance, float offsetX, float offsetY) |
| 164 { | 174 { |
| 165 HarfBuzzRunGlyphData& data = m_glyphData[index]; | 175 HarfBuzzRunGlyphData& data = m_glyphData[index]; |
| 166 data.glyph = glyphId; | 176 data.glyph = glyphId; |
| 167 data.advance = advance; | 177 data.advance = advance; |
| 168 data.offset = FloatSize(offsetX, offsetY); | 178 data.offset = FloatSize(offsetX, offsetY); |
| 169 } | 179 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 | 413 |
| 404 // The absoluteFrom and absoluteTo arguments represent the start/end offset | 414 // The absoluteFrom and absoluteTo arguments represent the start/end offset |
| 405 // for the entire run, from/to are continuously updated to be relative to | 415 // for the entire run, from/to are continuously updated to be relative to |
| 406 // the current word (ShapeResult instance). | 416 // the current word (ShapeResult instance). |
| 407 int from = absoluteFrom; | 417 int from = absoluteFrom; |
| 408 int to = absoluteTo; | 418 int to = absoluteTo; |
| 409 | 419 |
| 410 unsigned totalNumCharacters = 0; | 420 unsigned totalNumCharacters = 0; |
| 411 for (unsigned j = 0; j < results.size(); j++) { | 421 for (unsigned j = 0; j < results.size(); j++) { |
| 412 RefPtr<ShapeResult> result = results[j]; | 422 RefPtr<ShapeResult> result = results[j]; |
| 423 if (direction == RTL) { | |
| 424 // Convert logical offsets to visual offsets, because results are in | |
|
wkorman
2015/11/02 04:29:20
Is visual the same as physical? Which name is pref
kojii
2015/11/02 05:19:44
IIUC Unicode bidi reordering uses logical/visual w
| |
| 425 // logical order while runs are in visual order. | |
| 426 if (!foundFromX && from >= 0 && static_cast<unsigned>(from) < result ->numCharacters()) | |
| 427 from = result->numCharacters() - from - 1; | |
| 428 if (!foundToX && to >= 0 && static_cast<unsigned>(to) < result->numC haracters()) | |
| 429 to = result->numCharacters() - to - 1; | |
| 430 currentX -= result->width(); | |
| 431 } | |
| 413 for (unsigned i = 0; i < result->m_runs.size(); i++) { | 432 for (unsigned i = 0; i < result->m_runs.size(); i++) { |
| 414 if (!result->m_runs[i]) | 433 if (!result->m_runs[i]) |
| 415 continue; | 434 continue; |
| 416 if (direction == RTL) | 435 ASSERT((direction == RTL) == result->m_runs[i]->rtl()); |
| 417 currentX -= result->m_runs[i]->m_width; | |
| 418 int numCharacters = result->m_runs[i]->m_numCharacters; | 436 int numCharacters = result->m_runs[i]->m_numCharacters; |
| 419 if (!foundFromX && from >= 0 && from < numCharacters) { | 437 if (!foundFromX && from >= 0 && from < numCharacters) { |
| 420 fromX = result->m_runs[i]->xPositionForOffset(from) + currentX; | 438 fromX = result->m_runs[i]->xPositionForVisualOffset(from) + curr entX; |
| 421 foundFromX = true; | 439 foundFromX = true; |
| 422 } else { | 440 } else { |
| 423 from -= numCharacters; | 441 from -= numCharacters; |
| 424 } | 442 } |
| 425 | 443 |
| 426 if (!foundToX && to >= 0 && to < numCharacters) { | 444 if (!foundToX && to >= 0 && to < numCharacters) { |
| 427 toX = result->m_runs[i]->xPositionForOffset(to) + currentX; | 445 toX = result->m_runs[i]->xPositionForVisualOffset(to) + currentX ; |
| 428 foundToX = true; | 446 foundToX = true; |
| 429 } else { | 447 } else { |
| 430 to -= numCharacters; | 448 to -= numCharacters; |
| 431 } | 449 } |
| 432 | 450 |
| 433 if (foundFromX && foundToX) | 451 if (foundFromX && foundToX) |
| 434 break; | 452 break; |
| 435 if (direction != RTL) | 453 currentX += result->m_runs[i]->m_width; |
| 436 currentX += result->m_runs[i]->m_width; | |
| 437 } | 454 } |
| 455 if (direction == RTL) | |
| 456 currentX -= result->width(); | |
| 438 totalNumCharacters += result->numCharacters(); | 457 totalNumCharacters += result->numCharacters(); |
| 439 } | 458 } |
| 440 | 459 |
| 441 // The position in question might be just after the text. | 460 // The position in question might be just after the text. |
| 442 if (!foundFromX && absoluteFrom == totalNumCharacters) { | 461 if (!foundFromX && absoluteFrom == totalNumCharacters) { |
| 443 fromX = direction == RTL ? 0 : totalWidth; | 462 fromX = direction == RTL ? 0 : totalWidth; |
| 444 foundFromX = true; | 463 foundFromX = true; |
| 445 } | 464 } |
| 446 if (!foundToX && absoluteTo == totalNumCharacters) { | 465 if (!foundToX && absoluteTo == totalNumCharacters) { |
| 447 toX = direction == RTL ? 0 : totalWidth; | 466 toX = direction == RTL ? 0 : totalWidth; |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1316 } | 1335 } |
| 1317 | 1336 |
| 1318 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere d by !m_expansionOpportunityCount above | 1337 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere d by !m_expansionOpportunityCount above |
| 1319 spacing += nextExpansionPerOpportunity(); | 1338 spacing += nextExpansionPerOpportunity(); |
| 1320 m_isAfterExpansion = true; | 1339 m_isAfterExpansion = true; |
| 1321 return spacing; | 1340 return spacing; |
| 1322 } | 1341 } |
| 1323 | 1342 |
| 1324 | 1343 |
| 1325 } // namespace blink | 1344 } // namespace blink |
| OLD | NEW |