Title: [154674] trunk/Source/WebCore
Revision
154674
Author
[email protected]
Date
2013-08-27 03:22:20 -0700 (Tue, 27 Aug 2013)

Log Message

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:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (154673 => 154674)


--- trunk/Source/WebCore/ChangeLog	2013-08-27 10:09:06 UTC (rev 154673)
+++ trunk/Source/WebCore/ChangeLog	2013-08-27 10:22:20 UTC (rev 154674)
@@ -1,3 +1,23 @@
+2013-08-27  Allan Sandfeld Jensen  <[email protected]>
+
+        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:
+
 2013-08-27  Christophe Dumez  <[email protected]>
 
         Implement DOM3 wheel event

Modified: trunk/Source/WebCore/platform/graphics/FontFastPath.cpp (154673 => 154674)


--- trunk/Source/WebCore/platform/graphics/FontFastPath.cpp	2013-08-27 10:09:06 UTC (rev 154673)
+++ trunk/Source/WebCore/platform/graphics/FontFastPath.cpp	2013-08-27 10:22:20 UTC (rev 154674)
@@ -139,13 +139,13 @@
     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).width();
     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).width();
     int glyphTo = glyphPos + 1;
 
@@ -303,13 +303,13 @@
     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).width();
     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).width();
 
     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning.
@@ -334,7 +334,7 @@
                 characterOffset = run.length();
                 break;
             }
-            characterOffset = it.m_characterIndex[glyphPosition];
+            characterOffset = it.m_characterIndexOfGlyph[glyphPosition];
             float glyphWidth = glyphBuffer.advanceAt(glyphPosition).width();
             if (includePartialGlyphs) {
                 if (currentX - glyphWidth / 2.0f <= x)
@@ -352,7 +352,7 @@
                 characterOffset = run.length();
                 break;
             }
-            characterOffset = it.m_characterIndex[glyphPosition];
+            characterOffset = it.m_characterIndexOfGlyph[glyphPosition];
             float glyphWidth = glyphBuffer.advanceAt(glyphPosition).width();
             if (includePartialGlyphs) {
                 if (currentX + glyphWidth / 2.0f >= x)

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (154673 => 154674)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2013-08-27 10:09:06 UTC (rev 154673)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2013-08-27 10:22:20 UTC (rev 154674)
@@ -67,6 +67,8 @@
         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)
@@ -231,7 +233,7 @@
                                     glyphBuffer->add(fontData->zeroWidthSpaceGlyph(), fontData, m_expansionPerOpportunity);
                                 else
                                     glyphBuffer->add(fontData->spaceGlyph(), fontData, expansionAtThisOpportunity);
-                                m_characterIndex.append(currentCharacterIndex);
+                                m_characterIndexOfGlyph.append(currentCharacterIndex);
                             } else
                                 glyphBuffer->expandLastAdvance(expansionAtThisOpportunity);
                         }
@@ -300,7 +302,7 @@
 
         if (glyphBuffer) {
             glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
-            m_characterIndex.append(currentCharacterIndex);
+            m_characterIndexOfGlyph.append(currentCharacterIndex);
         }
 
         lastRoundingWidth = width - oldWidth;

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.h (154673 => 154674)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.h	2013-08-27 10:09:06 UTC (rev 154673)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.h	2013-08-27 10:22:20 UTC (rev 154674)
@@ -82,7 +82,8 @@
     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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to