Title: [265415] trunk/Source/WebCore
Revision
265415
Author
[email protected]
Date
2020-08-09 00:36:19 -0700 (Sun, 09 Aug 2020)

Log Message

Update OriginalAdvancesForCharacterTreatedAsSpace to work correctly in the presence of inserted or removed glyphs
https://bugs.webkit.org/show_bug.cgi?id=215302

Reviewed by Darin Adler.

OriginalAdvancesForCharacterTreatedAsSpace is trying to make sure that shaping doesn't cause
spaces to get wider or thinner. However, the way it was doing that is, for all the space
characters, overwrite that glyph index's advance after shaping to be what it was before shaping.
However, this is wrong, because shaping can insert or delete glyphs. Instead, now that we have
explicit string indices for each glyph, we can use those to determine which glyphs come from
space characters. These glyphs are the ones which should be overwritten.

* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::applyFontTransforms):
(WebCore::WidthIterator::advanceInternal):
* platform/graphics/WidthIterator.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (265414 => 265415)


--- trunk/Source/WebCore/ChangeLog	2020-08-09 06:40:00 UTC (rev 265414)
+++ trunk/Source/WebCore/ChangeLog	2020-08-09 07:36:19 UTC (rev 265415)
@@ -1,5 +1,24 @@
 2020-08-08  Myles C. Maxfield  <[email protected]>
 
+        Update OriginalAdvancesForCharacterTreatedAsSpace to work correctly in the presence of inserted or removed glyphs
+        https://bugs.webkit.org/show_bug.cgi?id=215302
+
+        Reviewed by Darin Adler.
+
+        OriginalAdvancesForCharacterTreatedAsSpace is trying to make sure that shaping doesn't cause
+        spaces to get wider or thinner. However, the way it was doing that is, for all the space
+        characters, overwrite that glyph index's advance after shaping to be what it was before shaping.
+        However, this is wrong, because shaping can insert or delete glyphs. Instead, now that we have
+        explicit string indices for each glyph, we can use those to determine which glyphs come from
+        space characters. These glyphs are the ones which should be overwritten.
+
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::applyFontTransforms):
+        (WebCore::WidthIterator::advanceInternal):
+        * platform/graphics/WidthIterator.h:
+
+2020-08-08  Myles C. Maxfield  <[email protected]>
+
         Fix bad merge in r265241
         https://bugs.webkit.org/show_bug.cgi?id=215051
 

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (265414 => 265415)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2020-08-09 06:40:00 UTC (rev 265414)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2020-08-09 07:36:19 UTC (rev 265415)
@@ -28,6 +28,7 @@
 #include "GlyphBuffer.h"
 #include "Latin1TextIterator.h"
 #include "SurrogatePairAwareTextIterator.h"
+#include <algorithm>
 #include <wtf/MathExtras.h>
 
 namespace WebCore {
@@ -58,14 +59,15 @@
 }
 
 struct OriginalAdvancesForCharacterTreatedAsSpace {
-public:
-    explicit OriginalAdvancesForCharacterTreatedAsSpace(bool isSpace, float advanceBefore, float advanceAt)
-        : characterIsSpace(isSpace)
+    explicit OriginalAdvancesForCharacterTreatedAsSpace(GlyphBufferStringOffset stringOffset, bool isSpace, float advanceBefore, float advanceAt)
+        : stringOffset(stringOffset)
+        , characterIsSpace(isSpace)
         , advanceBeforeCharacter(advanceBefore)
         , advanceAtCharacter(advanceAt)
     {
     }
 
+    GlyphBufferStringOffset stringOffset;
     bool characterIsSpace;
     float advanceBeforeCharacter;
     float advanceAtCharacter;
@@ -113,18 +115,17 @@
     if (!ltr)
         glyphBuffer.reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
 
-    // https://bugs.webkit.org/show_bug.cgi?id=206208: This is totally, 100%, furiously, utterly, frustratingly bogus.
-    // There is absolutely no guarantee that glyph indices before shaping have any relation at all with glyph indices after shaping.
-    // One of the fundamental things that shaping does is insert glyph all over the place.
-    for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) {
-        auto spaceOffset = charactersTreatedAsSpace[i].first;
-        // Shaping may have deleted the glyph.
-        if (spaceOffset >= glyphBufferSize)
+    for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i) {
+        auto characterIndex = glyphBuffer.stringOffsetAt(i);
+        auto iterator = std::lower_bound(charactersTreatedAsSpace.begin(), charactersTreatedAsSpace.end(), characterIndex, [](const OriginalAdvancesForCharacterTreatedAsSpace& l, GlyphBufferStringOffset r) -> bool {
+            return l.stringOffset < r;
+        });
+        if (iterator == charactersTreatedAsSpace.end() || iterator->stringOffset != characterIndex)
             continue;
-        const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second;
-        if (spaceOffset && !originalAdvances.characterIsSpace)
-            glyphBuffer.advances(spaceOffset - 1)->setWidth(originalAdvances.advanceBeforeCharacter);
-        glyphBuffer.advances(spaceOffset)->setWidth(originalAdvances.advanceAtCharacter);
+        const auto& originalAdvances = *iterator;
+        if (i && !originalAdvances.characterIsSpace)
+            glyphBuffer.advances(i - 1)->setWidth(originalAdvances.advanceBeforeCharacter);
+        glyphBuffer.advances(i)->setWidth(originalAdvances.advanceAtCharacter);
     }
     charactersTreatedAsSpace.clear();
 
@@ -308,8 +309,11 @@
 
         auto transformsType = shouldApplyFontTransforms(glyphBuffer, lastGlyphCount, previousCharacter);
         if (transformsType != TransformsType::None && FontCascade::treatAsSpace(character)) {
-            charactersTreatedAsSpace.append(std::make_pair(glyphBuffer.size(),
-                OriginalAdvancesForCharacterTreatedAsSpace(character == ' ', glyphBuffer.size() ? glyphBuffer.advanceAt(glyphBuffer.size() - 1).width() : 0, width)));
+            charactersTreatedAsSpace.constructAndAppend(
+                currentCharacterIndex,
+                character == ' ',
+                glyphBuffer.size() ? glyphBuffer.advanceAt(glyphBuffer.size() - 1).width() : 0,
+                width);
         }
 
         if (m_accountForGlyphBounds) {

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.h (265414 => 265415)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.h	2020-08-09 06:40:00 UTC (rev 265414)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.h	2020-08-09 07:36:19 UTC (rev 265415)
@@ -35,7 +35,7 @@
 struct GlyphData;
 struct OriginalAdvancesForCharacterTreatedAsSpace;
 
-typedef Vector<std::pair<unsigned, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace;
+using CharactersTreatedAsSpace = Vector<OriginalAdvancesForCharacterTreatedAsSpace, 64>;
 
 struct WidthIterator {
     WTF_MAKE_FAST_ALLOCATED;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to