diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-08-27 13:34:22 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-27 15:23:57 +0200 |
commit | 3a342484c4e35b7c9f10131dee8c39d2f62e9c6a (patch) | |
tree | 1e865bee61acc226f1128369560aff869fedd70f | |
parent | a978cfb2e4c0fc3dd7551aaff16f1eee60ab1b1b (diff) | |
download | qtwebkit-3a342484c4e35b7c9f10131dee8c39d2f62e9c6a.tar.gz |
Font's fast code path doesn't handle partial runs correctly when kerning or ligatures are enabled
https://bugs.webkit.org/show_bug.cgi?id=100050
Reviewed by Darin Adler.
Renamed m_characterIndex to m_characterIndexOfGlyph and gave it an inline size of 10,
which covers around 66% of all cases. The rest of the cases are now preallocated to the
upper limit which is length of the original TextRun.
* platform/graphics/FontFastPath.cpp:
(WebCore::Font::getGlyphsAndAdvancesForSimpleText):
(WebCore::Font::selectionRectForSimpleText):
(WebCore::Font::offsetForPositionForSimpleText):
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::WidthIterator):
(WebCore::WidthIterator::advanceInternal):
* platform/graphics/WidthIterator.h:
Change-Id: I253195dc5fc07b4c9d0bb4947cd07d86f054a265
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154674 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r-- | Source/WebCore/platform/graphics/FontFastPath.cpp | 12 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/WidthIterator.cpp | 6 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/WidthIterator.h | 3 |
3 files changed, 12 insertions, 9 deletions
diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp index 22ce7f57e..d1553ea3f 100644 --- a/Source/WebCore/platform/graphics/FontFastPath.cpp +++ b/Source/WebCore/platform/graphics/FontFastPath.cpp @@ -335,13 +335,13 @@ float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int float totalWidth = it.m_runWidthSoFar; float beforeWidth = 0; int glyphPos = 0; - for (; glyphPos < localGlyphBuffer.size() && it.m_characterIndex[glyphPos] < from; ++glyphPos) + for (; glyphPos < localGlyphBuffer.size() && it.m_characterIndexOfGlyph[glyphPos] < from; ++glyphPos) beforeWidth += localGlyphBuffer.advanceAt(glyphPos); int glyphFrom = glyphPos; float afterWidth = totalWidth; glyphPos = localGlyphBuffer.size() - 1; - for (; glyphPos >= glyphFrom && it.m_characterIndex[glyphPos] >= to; --glyphPos) + for (; glyphPos >= glyphFrom && it.m_characterIndexOfGlyph[glyphPos] >= to; --glyphPos) afterWidth -= localGlyphBuffer.advanceAt(glyphPos); int glyphTo = glyphPos + 1; @@ -494,13 +494,13 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& float totalWidth = it.m_runWidthSoFar; float beforeWidth = 0; int glyphPos = 0; - for (; glyphPos < glyphBuffer.size() && it.m_characterIndex[glyphPos] < from; ++glyphPos) + for (; glyphPos < glyphBuffer.size() && it.m_characterIndexOfGlyph[glyphPos] < from; ++glyphPos) beforeWidth += glyphBuffer.advanceAt(glyphPos); int glyphFrom = glyphPos; float afterWidth = totalWidth; glyphPos = glyphBuffer.size() - 1; - for (; glyphPos >= glyphFrom && it.m_characterIndex[glyphPos] >= to; --glyphPos) + for (; glyphPos >= glyphFrom && it.m_characterIndexOfGlyph[glyphPos] >= to; --glyphPos) afterWidth -= glyphBuffer.advanceAt(glyphPos); // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning. @@ -525,7 +525,7 @@ int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool inclu characterOffset = run.length(); break; } - characterOffset = it.m_characterIndex[glyphPosition]; + characterOffset = it.m_characterIndexOfGlyph[glyphPosition]; float glyphWidth = glyphBuffer.advanceAt(glyphPosition); if (includePartialGlyphs) { if (currentX - glyphWidth / 2.0f <= x) @@ -543,7 +543,7 @@ int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool inclu characterOffset = run.length(); break; } - characterOffset = it.m_characterIndex[glyphPosition]; + characterOffset = it.m_characterIndexOfGlyph[glyphPosition]; float glyphWidth = glyphBuffer.advanceAt(glyphPosition); if (includePartialGlyphs) { if (currentX + glyphWidth / 2.0f >= x) diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp index 1fb1d9b40..7a1698d19 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.cpp +++ b/Source/WebCore/platform/graphics/WidthIterator.cpp @@ -67,6 +67,8 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const else m_expansionPerOpportunity = m_expansion / expansionOpportunityCount; } + // 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. + m_characterIndexOfGlyph.reserveInitialCapacity(m_run.length()); } GlyphData WidthIterator::glyphDataForCharacter(UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) @@ -226,7 +228,7 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph if (glyphBuffer) { if (glyphBuffer->isEmpty()) { glyphBuffer->add(fontData->spaceGlyph(), fontData, expansionAtThisOpportunity); - m_characterIndex.append(currentCharacterIndex); + m_characterIndexOfGlyph.append(currentCharacterIndex); } else glyphBuffer->expandLastAdvance(expansionAtThisOpportunity); } @@ -295,7 +297,7 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph if (glyphBuffer) { glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); - m_characterIndex.append(currentCharacterIndex); + m_characterIndexOfGlyph.append(currentCharacterIndex); } lastRoundingWidth = width - oldWidth; diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h index 43007e80d..8aa26782c 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.h +++ b/Source/WebCore/platform/graphics/WidthIterator.h @@ -82,7 +82,8 @@ public: float m_expansionPerOpportunity; bool m_isAfterExpansion; float m_finalRoundingWidth; - Vector<int> m_characterIndex; + // An inline capacity of 10 catches around 2/3 of the cases. To catch 90% we would need 32. + Vector<int, 10> m_characterIndexOfGlyph; #if ENABLE(SVG_FONTS) String m_lastGlyphName; |