Title: [222086] trunk/Source/WebCore
Revision
222086
Author
carlo...@webkit.org
Date
2017-09-15 06:42:34 -0700 (Fri, 15 Sep 2017)

Log Message

[Harfbuzz] Fix incorrect font rendering when selecting texts in pages which specifies text-rendering: optimizeLegibility
https://bugs.webkit.org/show_bug.cgi?id=148220

Reviewed by Michael Catanzaro.

Add support for shaping a range of characters and return the advance to the first glyph in the range.

Covered by existing tests.

* platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText const): Pass "from" and "to" parameters to
HarfBuzzShaper::shape and return the x position of the selection rect.
* platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
(WebCore::HarfBuzzShaper::shape): Forward "from" and "to" parameters to fillGlyphBuffer().
(WebCore::HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun): Only add glyphs for the given character range.
(WebCore::HarfBuzzShaper::fillGlyphBuffer): Only consider runs in the given character range.
* platform/graphics/harfbuzz/HarfBuzzShaper.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (222085 => 222086)


--- trunk/Source/WebCore/ChangeLog	2017-09-15 13:24:46 UTC (rev 222085)
+++ trunk/Source/WebCore/ChangeLog	2017-09-15 13:42:34 UTC (rev 222086)
@@ -1,3 +1,23 @@
+2017-09-15  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [Harfbuzz] Fix incorrect font rendering when selecting texts in pages which specifies text-rendering: optimizeLegibility
+        https://bugs.webkit.org/show_bug.cgi?id=148220
+
+        Reviewed by Michael Catanzaro.
+
+        Add support for shaping a range of characters and return the advance to the first glyph in the range.
+
+        Covered by existing tests.
+
+        * platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText const): Pass "from" and "to" parameters to
+        HarfBuzzShaper::shape and return the x position of the selection rect.
+        * platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
+        (WebCore::HarfBuzzShaper::shape): Forward "from" and "to" parameters to fillGlyphBuffer().
+        (WebCore::HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun): Only add glyphs for the given character range.
+        (WebCore::HarfBuzzShaper::fillGlyphBuffer): Only consider runs in the given character range.
+        * platform/graphics/harfbuzz/HarfBuzzShaper.h:
+
 2017-09-15  Zan Dobersek  <zdober...@igalia.com>
 
         [EME] ClearKey: list 'persistent-license' sessions as supported

Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp (222085 => 222086)


--- trunk/Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp	2017-09-15 13:24:46 UTC (rev 222085)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp	2017-09-15 13:42:34 UTC (rev 222086)
@@ -40,16 +40,18 @@
 
 namespace WebCore {
 
-float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned, unsigned, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot /* forTextEmphasis */) const
+float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot /* forTextEmphasis */) const
 {
     HarfBuzzShaper shaper(this, run);
-    if (!shaper.shape(&glyphBuffer)) {
+    if (!shaper.shape(&glyphBuffer, from, to)) {
         LOG_ERROR("Shaper couldn't shape glyphBuffer.");
         return 0;
     }
 
-    // FIXME: Mac returns an initial advance here.
-    return 0;
+    if (glyphBuffer.isEmpty())
+        return 0;
+
+    return shaper.selectionRect({ }, 0, from, to).x();
 }
 
 bool FontCascade::canReturnFallbackFontsForComplexText()

Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp (222085 => 222086)


--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp	2017-09-15 13:24:46 UTC (rev 222085)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp	2017-09-15 13:42:34 UTC (rev 222086)
@@ -336,7 +336,7 @@
     }
 }
 
-bool HarfBuzzShaper::shape(GlyphBuffer* glyphBuffer)
+bool HarfBuzzShaper::shape(GlyphBuffer* glyphBuffer, std::optional<unsigned> from, std::optional<unsigned> to)
 {
     if (!collectHarfBuzzRuns())
         return false;
@@ -348,7 +348,7 @@
         return false;
     m_totalWidth = roundf(m_totalWidth);
 
-    if (glyphBuffer && !fillGlyphBuffer(glyphBuffer))
+    if (glyphBuffer && !fillGlyphBuffer(glyphBuffer, from.value_or(0), to.value_or(m_run.length())))
         return false;
 
     return true;
@@ -529,7 +529,7 @@
     m_totalWidth += currentRun->width();
 }
 
-void HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer, HarfBuzzRun* currentRun, FloatPoint& firstOffsetOfNextRun)
+void HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer, unsigned from, unsigned to, HarfBuzzRun* currentRun, const FloatPoint& firstOffsetOfNextRun)
 {
     FloatPoint* offsets = currentRun->offsets();
     uint16_t* glyphs = currentRun->glyphs();
@@ -539,8 +539,12 @@
 
     for (unsigned i = 0; i < numGlyphs; ++i) {
         uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToCharacterIndexes[i];
-        FloatPoint& currentOffset = offsets[i];
-        FloatPoint& nextOffset = (i == numGlyphs - 1) ? firstOffsetOfNextRun : offsets[i + 1];
+        if (currentCharacterIndex < from)
+            continue;
+        if (currentCharacterIndex >= to)
+            break;
+        const FloatPoint& currentOffset = offsets[i];
+        const FloatPoint& nextOffset = (i == numGlyphs - 1) ? firstOffsetOfNextRun : offsets[i + 1];
         float glyphAdvanceX = advances[i] + nextOffset.x() - currentOffset.x();
         float glyphAdvanceY = nextOffset.y() - currentOffset.y();
         if (m_run.rtl()) {
@@ -555,7 +559,7 @@
     }
 }
 
-bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer)
+bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer, unsigned from, unsigned to)
 {
     unsigned numRuns = m_harfBuzzRuns.size();
     if (m_run.rtl()) {
@@ -562,15 +566,25 @@
         m_startOffset = m_harfBuzzRuns.last()->offsets()[0];
         for (int runIndex = numRuns - 1; runIndex >= 0; --runIndex) {
             HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get();
-            FloatPoint firstOffsetOfNextRun = !runIndex ? FloatPoint() : m_harfBuzzRuns[runIndex - 1]->offsets()[0];
-            fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, firstOffsetOfNextRun);
+            auto runStartIndex = currentRun->startIndex();
+            auto runEndIndex = std::max<unsigned>(0, runStartIndex + currentRun->numCharacters() - 1);
+            if ((from >= runStartIndex && from <= runEndIndex) || (to >= runStartIndex && to <= runEndIndex)
+                || (from < runEndIndex && to > runStartIndex)) {
+                FloatPoint firstOffsetOfNextRun = !runIndex ? FloatPoint() : m_harfBuzzRuns[runIndex - 1]->offsets()[0];
+                fillGlyphBufferFromHarfBuzzRun(glyphBuffer, from, to, currentRun, firstOffsetOfNextRun);
+            }
         }
     } else {
         m_startOffset = m_harfBuzzRuns.first()->offsets()[0];
         for (unsigned runIndex = 0; runIndex < numRuns; ++runIndex) {
             HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get();
-            FloatPoint firstOffsetOfNextRun = runIndex == numRuns - 1 ? FloatPoint() : m_harfBuzzRuns[runIndex + 1]->offsets()[0];
-            fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, firstOffsetOfNextRun);
+            auto runStartIndex = currentRun->startIndex();
+            auto runEndIndex = std::max<unsigned>(0, runStartIndex + currentRun->numCharacters() - 1);
+            if ((from >= runStartIndex && from <= runEndIndex) || (to >= runStartIndex && to <= runEndIndex)
+                || (from < runStartIndex && to > runEndIndex)) {
+                FloatPoint firstOffsetOfNextRun = runIndex == numRuns - 1 ? FloatPoint() : m_harfBuzzRuns[runIndex + 1]->offsets()[0];
+                fillGlyphBufferFromHarfBuzzRun(glyphBuffer, from, to, currentRun, firstOffsetOfNextRun);
+            }
         }
     }
     return glyphBuffer->size();

Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.h (222085 => 222086)


--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.h	2017-09-15 13:24:46 UTC (rev 222085)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.h	2017-09-15 13:42:34 UTC (rev 222086)
@@ -54,7 +54,7 @@
     HarfBuzzShaper(const FontCascade*, const TextRun&);
     virtual ~HarfBuzzShaper();
 
-    bool shape(GlyphBuffer* = 0);
+    bool shape(GlyphBuffer* = nullptr, std::optional<unsigned> from = std::nullopt, std::optional<unsigned> to = std::nullopt);
     FloatPoint adjustStartPoint(const FloatPoint&);
     float totalWidth() { return m_totalWidth; }
     int offsetForPosition(float targetX, bool includePartialGlyphs = true);
@@ -113,8 +113,8 @@
 
     bool collectHarfBuzzRuns();
     bool shapeHarfBuzzRuns(bool shouldSetDirection);
-    bool fillGlyphBuffer(GlyphBuffer*);
-    void fillGlyphBufferFromHarfBuzzRun(GlyphBuffer*, HarfBuzzRun*, FloatPoint& firstOffsetOfNextRun);
+    bool fillGlyphBuffer(GlyphBuffer*, unsigned from, unsigned to);
+    void fillGlyphBufferFromHarfBuzzRun(GlyphBuffer*, unsigned from, unsigned to, HarfBuzzRun*, const FloatPoint& firstOffsetOfNextRun);
     void setGlyphPositionsForHarfBuzzRun(HarfBuzzRun*, hb_buffer_t*);
 
     GlyphBufferAdvance createGlyphBufferAdvance(float, float);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to