Changeset 163655 in webkit


Ignore:
Timestamp:
Feb 7, 2014 3:07:29 PM (10 years ago)
Author:
rniwa@webkit.org
Message:

Revert r154384 and r154674 as they broke selection rect computations for text with ligatures.

Source/WebCore:

  • platform/graphics/Font.cpp:

(WebCore::Font::drawText):
(WebCore::Font::drawEmphasisMarks):
(WebCore::Font::selectionRectForText):
(WebCore::Font::offsetForPosition):

  • platform/graphics/FontFastPath.cpp:

(WebCore::Font::getGlyphsAndAdvancesForSimpleText):
(WebCore::Font::selectionRectForSimpleText):
(WebCore::Font::offsetForPositionForSimpleText):

  • platform/graphics/GlyphBuffer.h:
  • platform/graphics/WidthIterator.cpp:

(WebCore::WidthIterator::WidthIterator):
(WebCore::WidthIterator::advanceInternal):
(WebCore::WidthIterator::advanceOneCharacter):

  • platform/graphics/WidthIterator.h:

LayoutTests:

  • fast/text/partial-textruns-expected.html: Removed.
  • fast/text/partial-textruns.html: Removed.
  • fast/text/resources/PTS55F-webfont.ttf: Removed.
Location:
trunk
Files:
3 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r163649 r163655  
     12014-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
    192014-02-07  Brendan Long  <b.long@cablelabs.com>
    210
  • trunk/Source/WebCore/ChangeLog

    r163654 r163655  
     12014-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
    1212014-02-07  Benjamin Poulain  <bpoulain@apple.com>
    222
  • trunk/Source/WebCore/platform/graphics/Font.cpp

    r161589 r163655  
    335335    to = (to == -1 ? run.length() : to);
    336336
    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)
    338343        return drawSimpleText(context, run, point, from, to);
    339344
     
    349354        to = run.length();
    350355
    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)
    352362        drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
    353363    else
     
    421431    to = (to == -1 ? run.length() : to);
    422432
    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)
    424439        return selectionRectForSimpleText(run, point, h, from, to);
    425440
     
    429444int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
    430445{
    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())
    432448        return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
    433449
  • trunk/Source/WebCore/platform/graphics/FontFastPath.cpp

    r163310 r163655  
    128128float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
    129129{
     130    float initialAdvance;
     131
    130132    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.
    131135    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;
    151144
    152145    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())
    153153        glyphBuffer.reverse(0, glyphBuffer.size());
    154         return totalWidth - afterWidth;
    155     }
    156 
    157     return beforeWidth;
     154
     155    return initialAdvance;
    158156}
    159157
     
    302300    GlyphBuffer glyphBuffer;
    303301    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;
    317306
    318307    // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning.
    319308    if (run.rtl()) {
     309        it.advance(run.length(), &glyphBuffer);
     310        float totalWidth = it.m_runWidthSoFar;
    320311        return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
    321312    }
     
    326317int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool includePartialGlyphs) const
    327318{
    328     GlyphBuffer glyphBuffer;
     319    float delta = x;
     320
    329321    WidthIterator it(this, run);
    330     it.advance(run.length(), &glyphBuffer);
    331 
    332     int characterOffset = 0;
     322    GlyphBuffer localGlyphBuffer;
     323    unsigned offset;
    333324    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))
    338330                break;
    339             }
    340             characterOffset = it.m_characterIndexOfGlyph[glyphPosition];
    341             float glyphWidth = glyphBuffer.advanceAt(glyphPosition).width();
     331            delta += w;
    342332            if (includePartialGlyphs) {
    343                 if (currentX - glyphWidth / 2.0f <= x)
     333                if (delta - w / 2 >= 0)
    344334                    break;
    345335            } else {
    346                 if (currentX - glyphWidth <= x)
     336                if (delta >= 0)
    347337                    break;
    348338            }
    349             currentX -= glyphWidth;
    350339        }
    351340    } 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))
    356345                break;
    357             }
    358             characterOffset = it.m_characterIndexOfGlyph[glyphPosition];
    359             float glyphWidth = glyphBuffer.advanceAt(glyphPosition).width();
     346            delta -= w;
    360347            if (includePartialGlyphs) {
    361                 if (currentX + glyphWidth / 2.0f >= x)
     348                if (delta + w / 2 <= 0)
    362349                    break;
    363350            } else {
    364                 if (currentX + glyphWidth >= x)
     351                if (delta <= 0)
    365352                    break;
    366353            }
    367             currentX += glyphWidth;
    368354        }
    369355    }
    370356
    371     return characterOffset;
    372 }
    373 
    374 } // namespace WebCore
     357    return offset;
     358}
     359
     360}
  • trunk/Source/WebCore/platform/graphics/GlyphBuffer.h

    r161680 r163655  
    123123    }
    124124
    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 #endif
    133     }
    134 
    135125    void add(Glyph glyph, const SimpleFontData* font, float width, const FloatSize* offset = 0)
    136126    {
  • trunk/Source/WebCore/platform/graphics/WidthIterator.cpp

    r163440 r163655  
    6767            m_expansionPerOpportunity = m_expansion / expansionOpportunityCount;
    6868    }
    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());
    7169}
    7270
     
    175173    while (textIterator.consume(character, clusterLength)) {
    176174        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);
    179176        Glyph glyph = glyphData.glyph;
    180177        const SimpleFontData* fontData = glyphData.fontData;
     
    242239                                else
    243240                                    glyphBuffer->add(fontData->spaceGlyph(), fontData, expansionAtThisOpportunity);
    244                                 m_characterIndexOfGlyph.append(currentCharacterIndex);
    245241                            } else
    246242                                glyphBuffer->expandLastAdvance(expansionAtThisOpportunity);
     
    309305        }
    310306
    311         if (glyphBuffer) {
     307        if (glyphBuffer)
    312308            glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
    313             m_characterIndexOfGlyph.append(currentCharacterIndex);
    314         }
    315309
    316310        lastRoundingWidth = width - oldWidth;
     
    352346}
    353347
    354 }
     348bool 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  
    4343
    4444    unsigned advance(int to, GlyphBuffer*);
     45    bool advanceOneCharacter(float& width, GlyphBuffer&);
    4546
    4647    float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; }
     
    8081    bool m_isAfterExpansion;
    8182    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;
    8483
    8584#if ENABLE(SVG_FONTS)
Note: See TracChangeset for help on using the changeset viewer.