Changeset 163655 in webkit
- Timestamp:
- Feb 7, 2014 3:07:29 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 3 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r163649 r163655 1 2014-02-07 Ryosuke Niwa <rniwa@webkit.org> 2 3 Revert r154384 and r154674 as they broke selection rect computations for text with ligatures. 4 5 * fast/text/partial-textruns-expected.html: Removed. 6 * fast/text/partial-textruns.html: Removed. 7 * fast/text/resources/PTS55F-webfont.ttf: Removed. 8 1 9 2014-02-07 Brendan Long <b.long@cablelabs.com> 2 10 -
trunk/Source/WebCore/ChangeLog
r163654 r163655 1 2014-02-07 Ryosuke Niwa <rniwa@webkit.org> 2 3 Revert r154384 and r154674 as they broke selection rect computations for text with ligatures. 4 5 * platform/graphics/Font.cpp: 6 (WebCore::Font::drawText): 7 (WebCore::Font::drawEmphasisMarks): 8 (WebCore::Font::selectionRectForText): 9 (WebCore::Font::offsetForPosition): 10 * platform/graphics/FontFastPath.cpp: 11 (WebCore::Font::getGlyphsAndAdvancesForSimpleText): 12 (WebCore::Font::selectionRectForSimpleText): 13 (WebCore::Font::offsetForPositionForSimpleText): 14 * platform/graphics/GlyphBuffer.h: 15 * platform/graphics/WidthIterator.cpp: 16 (WebCore::WidthIterator::WidthIterator): 17 (WebCore::WidthIterator::advanceInternal): 18 (WebCore::WidthIterator::advanceOneCharacter): 19 * platform/graphics/WidthIterator.h: 20 1 21 2014-02-07 Benjamin Poulain <bpoulain@apple.com> 2 22 -
trunk/Source/WebCore/platform/graphics/Font.cpp
r161589 r163655 335 335 to = (to == -1 ? run.length() : to); 336 336 337 if (codePath(run) != Complex) 337 CodePath codePathToUse = codePath(run); 338 // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 339 if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !run.renderingContext()) 340 codePathToUse = Complex; 341 342 if (codePathToUse != Complex) 338 343 return drawSimpleText(context, run, point, from, to); 339 344 … … 349 354 to = run.length(); 350 355 351 if (codePath(run) != Complex) 356 CodePath codePathToUse = codePath(run); 357 // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 358 if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !run.renderingContext()) 359 codePathToUse = Complex; 360 361 if (codePathToUse != Complex) 352 362 drawEmphasisMarksForSimpleText(context, run, mark, point, from, to); 353 363 else … … 421 431 to = (to == -1 ? run.length() : to); 422 432 423 if (codePath(run) != Complex) 433 CodePath codePathToUse = codePath(run); 434 // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 435 if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !run.renderingContext()) 436 codePathToUse = Complex; 437 438 if (codePathToUse != Complex) 424 439 return selectionRectForSimpleText(run, point, h, from, to); 425 440 … … 429 444 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const 430 445 { 431 if (codePath(run) != Complex) 446 // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050 447 if (codePath(run) != Complex && !typesettingFeatures()) 432 448 return offsetForPositionForSimpleText(run, x, includePartialGlyphs); 433 449 -
trunk/Source/WebCore/platform/graphics/FontFastPath.cpp
r163310 r163655 128 128 float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const 129 129 { 130 float initialAdvance; 131 130 132 WidthIterator it(this, run, 0, false, forTextEmphasis); 133 // FIXME: Using separate glyph buffers for the prefix and the suffix is incorrect when kerning or 134 // ligatures are enabled. 131 135 GlyphBuffer localGlyphBuffer; 132 it.advance(run.length(), &localGlyphBuffer); 133 134 if (localGlyphBuffer.isEmpty()) 135 return 0; 136 137 float totalWidth = it.m_runWidthSoFar; 138 float beforeWidth = 0; 139 int glyphPos = 0; 140 for (; glyphPos < localGlyphBuffer.size() && it.m_characterIndexOfGlyph[glyphPos] < from; ++glyphPos) 141 beforeWidth += localGlyphBuffer.advanceAt(glyphPos).width(); 142 int glyphFrom = glyphPos; 143 144 float afterWidth = totalWidth; 145 glyphPos = localGlyphBuffer.size() - 1; 146 for (; glyphPos >= glyphFrom && it.m_characterIndexOfGlyph[glyphPos] >= to; --glyphPos) 147 afterWidth -= localGlyphBuffer.advanceAt(glyphPos).width(); 148 int glyphTo = glyphPos + 1; 149 150 glyphBuffer.add(&localGlyphBuffer, glyphFrom, glyphTo - glyphFrom); 136 it.advance(from, &localGlyphBuffer); 137 float beforeWidth = it.m_runWidthSoFar; 138 it.advance(to, &glyphBuffer); 139 140 if (glyphBuffer.isEmpty()) 141 return 0; 142 143 float afterWidth = it.m_runWidthSoFar; 151 144 152 145 if (run.rtl()) { 146 float finalRoundingWidth = it.m_finalRoundingWidth; 147 it.advance(run.length(), &localGlyphBuffer); 148 initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth; 149 } else 150 initialAdvance = beforeWidth; 151 152 if (run.rtl()) 153 153 glyphBuffer.reverse(0, glyphBuffer.size()); 154 return totalWidth - afterWidth; 155 } 156 157 return beforeWidth; 154 155 return initialAdvance; 158 156 } 159 157 … … 302 300 GlyphBuffer glyphBuffer; 303 301 WidthIterator it(this, run); 304 it.advance(run.length(), &glyphBuffer); 305 306 float totalWidth = it.m_runWidthSoFar; 307 float beforeWidth = 0; 308 int glyphPos = 0; 309 for (; glyphPos < glyphBuffer.size() && it.m_characterIndexOfGlyph[glyphPos] < from; ++glyphPos) 310 beforeWidth += glyphBuffer.advanceAt(glyphPos).width(); 311 int glyphFrom = glyphPos; 312 313 float afterWidth = totalWidth; 314 glyphPos = glyphBuffer.size() - 1; 315 for (; glyphPos >= glyphFrom && it.m_characterIndexOfGlyph[glyphPos] >= to; --glyphPos) 316 afterWidth -= glyphBuffer.advanceAt(glyphPos).width(); 302 it.advance(from, &glyphBuffer); 303 float beforeWidth = it.m_runWidthSoFar; 304 it.advance(to, &glyphBuffer); 305 float afterWidth = it.m_runWidthSoFar; 317 306 318 307 // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning. 319 308 if (run.rtl()) { 309 it.advance(run.length(), &glyphBuffer); 310 float totalWidth = it.m_runWidthSoFar; 320 311 return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h); 321 312 } … … 326 317 int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool includePartialGlyphs) const 327 318 { 328 GlyphBuffer glyphBuffer; 319 float delta = x; 320 329 321 WidthIterator it(this, run); 330 it.advance(run.length(), &glyphBuffer); 331 332 int characterOffset = 0; 322 GlyphBuffer localGlyphBuffer; 323 unsigned offset; 333 324 if (run.rtl()) { 334 float currentX = it.m_runWidthSoFar; 335 for (int glyphPosition = 0; glyphPosition <= glyphBuffer.size(); ++glyphPosition) { 336 if (glyphPosition == glyphBuffer.size()) { 337 characterOffset = run.length(); 325 delta -= floatWidthForSimpleText(run); 326 while (1) { 327 offset = it.m_currentCharacter; 328 float w; 329 if (!it.advanceOneCharacter(w, localGlyphBuffer)) 338 330 break; 339 } 340 characterOffset = it.m_characterIndexOfGlyph[glyphPosition]; 341 float glyphWidth = glyphBuffer.advanceAt(glyphPosition).width(); 331 delta += w; 342 332 if (includePartialGlyphs) { 343 if ( currentX - glyphWidth / 2.0f <= x)333 if (delta - w / 2 >= 0) 344 334 break; 345 335 } else { 346 if ( currentX - glyphWidth <= x)336 if (delta >= 0) 347 337 break; 348 338 } 349 currentX -= glyphWidth;350 339 } 351 340 } else { 352 float currentX = 0;353 for (int glyphPosition = 0; glyphPosition <= glyphBuffer.size(); ++glyphPosition) {354 if (glyphPosition == glyphBuffer.size()) {355 characterOffset = run.length();341 while (1) { 342 offset = it.m_currentCharacter; 343 float w; 344 if (!it.advanceOneCharacter(w, localGlyphBuffer)) 356 345 break; 357 } 358 characterOffset = it.m_characterIndexOfGlyph[glyphPosition]; 359 float glyphWidth = glyphBuffer.advanceAt(glyphPosition).width(); 346 delta -= w; 360 347 if (includePartialGlyphs) { 361 if ( currentX + glyphWidth / 2.0f >= x)348 if (delta + w / 2 <= 0) 362 349 break; 363 350 } else { 364 if ( currentX + glyphWidth >= x)351 if (delta <= 0) 365 352 break; 366 353 } 367 currentX += glyphWidth;368 354 } 369 355 } 370 356 371 return characterOffset;372 } 373 374 } // namespace WebCore357 return offset; 358 } 359 360 } -
trunk/Source/WebCore/platform/graphics/GlyphBuffer.h
r161680 r163655 123 123 } 124 124 125 void add(const GlyphBuffer* glyphBuffer, int from, int len)126 {127 m_glyphs.append(glyphBuffer->glyphs(from), len);128 m_advances.append(glyphBuffer->advances(from), len);129 m_fontData.append(glyphBuffer->m_fontData.data() + from, len);130 #if PLATFORM(WIN)131 m_offsets.append(glyphBuffer->m_offsets.data() + from, len);132 #endif133 }134 135 125 void add(Glyph glyph, const SimpleFontData* font, float width, const FloatSize* offset = 0) 136 126 { -
trunk/Source/WebCore/platform/graphics/WidthIterator.cpp
r163440 r163655 67 67 m_expansionPerOpportunity = m_expansion / expansionOpportunityCount; 68 68 } 69 // Character-index will end up the same or slightly shorter than m_run, so if we reserve that much it will never need to resize.70 m_characterIndexOfGlyph.reserveInitialCapacity(m_run.length());71 69 } 72 70 … … 175 173 while (textIterator.consume(character, clusterLength)) { 176 174 unsigned advanceLength = clusterLength; 177 int currentCharacterIndex = textIterator.currentCharacter(); 178 const GlyphData& glyphData = glyphDataForCharacter(character, rtl, currentCharacterIndex, advanceLength); 175 const GlyphData& glyphData = glyphDataForCharacter(character, rtl, textIterator.currentCharacter(), advanceLength); 179 176 Glyph glyph = glyphData.glyph; 180 177 const SimpleFontData* fontData = glyphData.fontData; … … 242 239 else 243 240 glyphBuffer->add(fontData->spaceGlyph(), fontData, expansionAtThisOpportunity); 244 m_characterIndexOfGlyph.append(currentCharacterIndex);245 241 } else 246 242 glyphBuffer->expandLastAdvance(expansionAtThisOpportunity); … … 309 305 } 310 306 311 if (glyphBuffer) {307 if (glyphBuffer) 312 308 glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); 313 m_characterIndexOfGlyph.append(currentCharacterIndex);314 }315 309 316 310 lastRoundingWidth = width - oldWidth; … … 352 346 } 353 347 354 } 348 bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer& glyphBuffer) 349 { 350 int oldSize = glyphBuffer.size(); 351 advance(m_currentCharacter + 1, &glyphBuffer); 352 float w = 0; 353 for (int i = oldSize; i < glyphBuffer.size(); ++i) 354 w += glyphBuffer.advanceAt(i).width(); 355 width = w; 356 return glyphBuffer.size() > oldSize; 357 } 358 359 } -
trunk/Source/WebCore/platform/graphics/WidthIterator.h
r163310 r163655 43 43 44 44 unsigned advance(int to, GlyphBuffer*); 45 bool advanceOneCharacter(float& width, GlyphBuffer&); 45 46 46 47 float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; } … … 80 81 bool m_isAfterExpansion; 81 82 float m_finalRoundingWidth; 82 // An inline capacity of 10 catches around 2/3 of the cases. To catch 90% we would need 32.83 Vector<int, 10> m_characterIndexOfGlyph;84 83 85 84 #if ENABLE(SVG_FONTS)
Note: See TracChangeset
for help on using the changeset viewer.