Changeset 168528 in webkit


Ignore:
Timestamp:
May 9, 2014 7:20:49 AM (10 years ago)
Author:
Alan Bujtas
Message:

REGRESSION (r168095): 1-pixel gap between adjacent selection inlines
https://bugs.webkit.org/show_bug.cgi?id=132474
<rdar://problem/16797394>

Reviewed by David Hyatt.

This patch changes text selection rectangle calculation from integral to device
pixel snapping. It ensures that selection rect painting matches box boundaries for inline elements.
Directional rounding (horizontal only atm) is moved out from Font class and now accessible
to all the painting code. RTL snapping strategy is changed from floor to round to match ltr behavior.
However this patch does not address all the integral snapping across inline elements. There are
a few places where we still calculate enclosing rects where snapping is sufficient.

Source/WebCore:
Test: fast/inline/hidpi-pixel-gap-between-adjacent-selection-inlines.html

  • platform/LayoutUnit.h:

(WebCore::roundToDevicePixel): added fudge factor to change rounding direction as directed.

  • platform/graphics/Font.cpp:

(WebCore::Font::adjustSelectionRectForText):
(WebCore::Font::selectionRectForText): Deleted.

  • platform/graphics/Font.h:
  • platform/graphics/FontFastPath.cpp:

(WebCore::Font::adjustSelectionRectForSimpleText): removed directional rounding.
(WebCore::Font::selectionRectForSimpleText): Deleted.

  • platform/graphics/GraphicsContext.cpp:

(WebCore::GraphicsContext::drawHighlightForText): Deleted.

  • platform/graphics/GraphicsContext.h:
  • platform/graphics/LayoutPoint.h:

(WebCore::roundedForPainting):

  • platform/graphics/LayoutRect.h:

(WebCore::directionalPixelSnappedForPainting): Snap top right corner for rtl direction.

  • platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:

(WebCore::Font::adjustSelectionRectForComplexText):
(WebCore::Font::selectionRectForComplexText): Deleted.

  • platform/graphics/mac/FontComplexTextMac.cpp:

(WebCore::Font::adjustSelectionRectForComplexText): removed directional rounding.
(WebCore::Font::selectionRectForComplexText): Deleted.

  • platform/graphics/win/FontWin.cpp:

(WebCore::Font::adjustSelectionRectForComplexText):
(WebCore::Font::selectionRectForComplexText): Deleted.

  • rendering/EllipsisBox.cpp:

(WebCore::EllipsisBox::selectionRect):
(WebCore::EllipsisBox::paintSelection):

  • rendering/InlineTextBox.cpp:

(WebCore::integralEnclosingRectForSelection): helper to address enclosing empty rect problem.
(WebCore::InlineTextBox::localSelectionRect):
(WebCore::InlineTextBox::paintSelection):
(WebCore::InlineTextBox::paintCompositionBackground):
(WebCore::InlineTextBox::paintDocumentMarker):
(WebCore::InlineTextBox::paintTextMatchMarker):
(WebCore::InlineTextBox::computeRectForReplacementMarker):
(WebCore::InlineTextBox::positionForOffset):

  • rendering/svg/SVGInlineTextBox.cpp:

(WebCore::SVGInlineTextBox::selectionRectForTextFragment):

LayoutTests:

  • fast/inline/hidpi-pixel-gap-between-adjacent-selection-inlines-expected.html: Added.
  • fast/inline/hidpi-pixel-gap-between-adjacent-selection-inlines.html: Added.
  • platform/mac/editing/selection/mixed-editability-10-expected.txt: progression.
  • platform/mac/fast/forms/cursor-at-editable-content-boundary-expected.txt: progression.
  • platform/mac/platform/mac/editing/input/caret-primary-bidi-expected.txt: Added. change in rounding strategy.
  • platform/mac/svg/text/caret-in-svg-text-expected.txt: Added. progression + change in rounding strategy.
Location:
trunk
Files:
5 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r168524 r168528  
     12014-05-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        REGRESSION (r168095): 1-pixel gap between adjacent selection inlines
     4        https://bugs.webkit.org/show_bug.cgi?id=132474
     5        <rdar://problem/16797394>
     6
     7        Reviewed by David Hyatt.
     8
     9        This patch changes text selection rectangle calculation from integral to device
     10        pixel snapping. It ensures that selection rect painting matches box boundaries for inline elements.
     11        Directional rounding (horizontal only atm) is moved out from Font class and now accessible
     12        to all the painting code. RTL snapping strategy is changed from floor to round to match ltr behavior.
     13        However this patch does not address all the integral snapping across inline elements. There are
     14        a few places where we still calculate enclosing rects where snapping is sufficient.
     15
     16        * fast/inline/hidpi-pixel-gap-between-adjacent-selection-inlines-expected.html: Added.
     17        * fast/inline/hidpi-pixel-gap-between-adjacent-selection-inlines.html: Added.
     18        * platform/mac/editing/selection/mixed-editability-10-expected.txt: progression.
     19        * platform/mac/fast/forms/cursor-at-editable-content-boundary-expected.txt: progression.
     20        * platform/mac/platform/mac/editing/input/caret-primary-bidi-expected.txt: Added. change in rounding strategy.
     21        * platform/mac/svg/text/caret-in-svg-text-expected.txt: Added. progression + change in rounding strategy.
     22
    1232014-05-09  Martin Hodovan  <mhodovan@inf.u-szeged.hu>
    224
  • trunk/LayoutTests/platform/mac/editing/selection/mixed-editability-10-expected.txt

    r161884 r168528  
    1616
    1717Hello: 
    18 Anchor ([object HTMLDivElement], 0 caret[40,540] refpos=41) is incorrect.
    19 Anchor ([object HTMLDivElement], 3 caret[75,540] refpos=77) is incorrect.
     18Anchor ([object HTMLDivElement], 0 caret[41,540] refpos=41) is correct.
     19Anchor ([object HTMLDivElement], 3 caret[76,540] refpos=77) is incorrect.
    2020Anchor ([object HTMLDivElement], 1 caret[43,472] refpos=43) is correct.
    2121Anchor ([object HTMLDivElement], 0 caret[8,472] refpos=8) is correct.
  • trunk/LayoutTests/platform/mac/fast/forms/cursor-at-editable-content-boundary-expected.txt

    r84659 r168528  
    77vertical text.
    88
     9FAIL test id: textarea_rtl (text width: 108 != caretRange: 107), which means moving caret in the text, caret might be invisible or overlap with element.
    910FAIL test id: textarea_rtl_no_wrap (text width: 108 != caretRange: 107), which means moving caret in the text, caret might be invisible or overlap with element.
    1011
  • trunk/Source/WebCore/ChangeLog

    r168524 r168528  
     12014-05-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        REGRESSION (r168095): 1-pixel gap between adjacent selection inlines
     4        https://bugs.webkit.org/show_bug.cgi?id=132474
     5        <rdar://problem/16797394>
     6
     7        Reviewed by David Hyatt.
     8
     9        This patch changes text selection rectangle calculation from integral to device
     10        pixel snapping. It ensures that selection rect painting matches box boundaries for inline elements.
     11        Directional rounding (horizontal only atm) is moved out from Font class and now accessible
     12        to all the painting code. RTL snapping strategy is changed from floor to round to match ltr behavior.
     13        However this patch does not address all the integral snapping across inline elements. There are
     14        a few places where we still calculate enclosing rects where snapping is sufficient.
     15
     16        Test: fast/inline/hidpi-pixel-gap-between-adjacent-selection-inlines.html
     17
     18        * platform/LayoutUnit.h:
     19        (WebCore::roundToDevicePixel): added fudge factor to change rounding direction as directed.
     20        * platform/graphics/Font.cpp:
     21        (WebCore::Font::adjustSelectionRectForText):
     22        (WebCore::Font::selectionRectForText): Deleted.
     23        * platform/graphics/Font.h:
     24        * platform/graphics/FontFastPath.cpp:
     25        (WebCore::Font::adjustSelectionRectForSimpleText): removed directional rounding.
     26        (WebCore::Font::selectionRectForSimpleText): Deleted.
     27        * platform/graphics/GraphicsContext.cpp:
     28        (WebCore::GraphicsContext::drawHighlightForText): Deleted.
     29        * platform/graphics/GraphicsContext.h:
     30        * platform/graphics/LayoutPoint.h:
     31        (WebCore::roundedForPainting):
     32        * platform/graphics/LayoutRect.h:
     33        (WebCore::directionalPixelSnappedForPainting): Snap top right corner for rtl direction.
     34        * platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
     35        (WebCore::Font::adjustSelectionRectForComplexText):
     36        (WebCore::Font::selectionRectForComplexText): Deleted.
     37        * platform/graphics/mac/FontComplexTextMac.cpp:
     38        (WebCore::Font::adjustSelectionRectForComplexText): removed directional rounding.
     39        (WebCore::Font::selectionRectForComplexText): Deleted.
     40        * platform/graphics/win/FontWin.cpp:
     41        (WebCore::Font::adjustSelectionRectForComplexText):
     42        (WebCore::Font::selectionRectForComplexText): Deleted.
     43        * rendering/EllipsisBox.cpp:
     44        (WebCore::EllipsisBox::selectionRect):
     45        (WebCore::EllipsisBox::paintSelection):
     46        * rendering/InlineTextBox.cpp:
     47        (WebCore::integralEnclosingRectForSelection): helper to address enclosing empty rect problem.
     48        (WebCore::InlineTextBox::localSelectionRect):
     49        (WebCore::InlineTextBox::paintSelection):
     50        (WebCore::InlineTextBox::paintCompositionBackground):
     51        (WebCore::InlineTextBox::paintDocumentMarker):
     52        (WebCore::InlineTextBox::paintTextMatchMarker):
     53        (WebCore::InlineTextBox::computeRectForReplacementMarker):
     54        (WebCore::InlineTextBox::positionForOffset):
     55        * rendering/svg/SVGInlineTextBox.cpp:
     56        (WebCore::SVGInlineTextBox::selectionRectForTextFragment):
     57
    1582014-05-09  Martin Hodovan  <mhodovan@inf.u-szeged.hu>
    259
  • trunk/Source/WebCore/platform/LayoutUnit.h

    r164449 r168528  
    936936}
    937937
    938 inline float roundToDevicePixel(LayoutUnit value, float pixelSnappingFactor)
    939 {
    940     return roundf((value.rawValue() * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;
     938inline float roundToDevicePixel(LayoutUnit value, float pixelSnappingFactor, bool needsDirectionalRounding = false)
     939{
     940    return roundf(((value.rawValue() - (needsDirectionalRounding ? LayoutUnit::epsilon() / 2.0f : 0)) * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;
    941941}
    942942
  • trunk/Source/WebCore/platform/graphics/Font.cpp

    r167724 r168528  
    2727#include "FloatRect.h"
    2828#include "FontCache.h"
    29 #include "IntPoint.h"
    3029#include "GlyphBuffer.h"
     30#include "LayoutRect.h"
    3131#include "TextRun.h"
    3232#include "WidthIterator.h"
     
    508508}
    509509
    510 FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
     510void Font::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
    511511{
    512512    to = (to == -1 ? run.length() : to);
     
    518518
    519519    if (codePathToUse != Complex)
    520         return selectionRectForSimpleText(run, point, h, from, to);
    521 
    522     return selectionRectForComplexText(run, point, h, from, to);
     520        return adjustSelectionRectForSimpleText(run, selectionRect, from, to);
     521
     522    return adjustSelectionRectForComplexText(run, selectionRect, from, to);
    523523}
    524524
  • trunk/Source/WebCore/platform/graphics/Font.h

    r167724 r168528  
    5353class GlyphBuffer;
    5454class GraphicsContext;
     55class LayoutRect;
    5556class RenderText;
    5657class TextLayout;
     
    124125
    125126    int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
    126     FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const;
     127    void adjustSelectionRectForText(const TextRun&, LayoutRect& selectionRect, int from = 0, int to = -1) const;
    127128
    128129    bool isSmallCaps() const { return m_fontDescription.smallCaps(); }
     
    203204    float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    204205    int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
    205     FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
     206    void adjustSelectionRectForSimpleText(const TextRun&, LayoutRect& selectionRect, int from, int to) const;
    206207
    207208    bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
     
    216217    float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    217218    int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
    218     FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
     219    void adjustSelectionRectForComplexText(const TextRun&, LayoutRect& selectionRect, int from, int to) const;
    219220
    220221    friend struct WidthIterator;
  • trunk/Source/WebCore/platform/graphics/FontFastPath.cpp

    r163655 r168528  
    2929#include "GlyphBuffer.h"
    3030#include "GlyphPageTreeNode.h"
     31#include "LayoutRect.h"
    3132#include "SimpleFontData.h"
    3233#include "TextRun.h"
     
    296297}
    297298
    298 FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
     299void Font::adjustSelectionRectForSimpleText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
    299300{
    300301    GlyphBuffer glyphBuffer;
     
    304305    it.advance(to, &glyphBuffer);
    305306    float afterWidth = it.m_runWidthSoFar;
    306 
    307     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning.
     307    float totalWidth = -1;
     308
    308309    if (run.rtl()) {
    309310        it.advance(run.length(), &glyphBuffer);
    310         float totalWidth = it.m_runWidthSoFar;
    311         return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
    312     }
    313 
    314     return FloatRect(floorf(point.x() + beforeWidth), point.y(), roundf(point.x() + afterWidth) - floorf(point.x() + beforeWidth), h);
     311        totalWidth = it.m_runWidthSoFar;
     312        selectionRect.move(totalWidth - afterWidth, 0);
     313    } else
     314        selectionRect.move(beforeWidth, 0);
     315    selectionRect.setWidth(afterWidth - beforeWidth);
    315316}
    316317
  • trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp

    r166902 r168528  
    548548}
    549549
    550 void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to)
    551 {
    552     if (paintingDisabled())
    553         return;
    554 
    555     fillRect(font.selectionRectForText(run, point, h, from, to), backgroundColor, colorSpace);
    556 }
    557 
    558550void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const FloatPoint& p, CompositeOperator op, ImageOrientationDescription description)
    559551{
  • trunk/Source/WebCore/platform/graphics/GraphicsContext.h

    r168397 r168528  
    355355        float drawBidiText(const Font&, const TextRun&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady, BidiStatus* = 0, int length = -1);
    356356#endif
    357         void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
    358 
    359357        enum RoundingMode {
    360358            RoundAllSides,
  • trunk/Source/WebCore/platform/graphics/LayoutPoint.h

    r167473 r168528  
    185185}
    186186
    187 inline FloatPoint roundedForPainting(const LayoutPoint& point, float pixelSnappingFactor)
    188 {
    189 #if ENABLE(SUBPIXEL_LAYOUT)
    190     return FloatPoint(roundToDevicePixel(point.x(), pixelSnappingFactor), roundToDevicePixel(point.y(), pixelSnappingFactor));
     187inline FloatPoint roundedForPainting(const LayoutPoint& point, float pixelSnappingFactor, bool directionalRoundingToRight = true, bool directionalRoundingToBottom = true)
     188{
     189#if ENABLE(SUBPIXEL_LAYOUT)
     190    return FloatPoint(roundToDevicePixel(point.x(), pixelSnappingFactor, !directionalRoundingToRight), roundToDevicePixel(point.y(), pixelSnappingFactor, !directionalRoundingToBottom));
     191#else
     192    UNUSED_PARAM(pixelSnappingFactor);
     193    UNUSED_PARAM(directionalRoundingToRight);
     194    UNUSED_PARAM(directionalRoundingToBottom);
     195    return FloatPoint(point);
     196#endif
     197}
     198
     199inline FloatPoint flooredForPainting(const LayoutPoint& point, float pixelSnappingFactor)
     200{
     201#if ENABLE(SUBPIXEL_LAYOUT)
     202    return FloatPoint(floorToDevicePixel(point.x(), pixelSnappingFactor), floorToDevicePixel(point.y(), pixelSnappingFactor));
    191203#else
    192204    UNUSED_PARAM(pixelSnappingFactor);
     
    195207}
    196208
    197 inline FloatPoint flooredForPainting(const LayoutPoint& point, float pixelSnappingFactor)
    198 {
    199 #if ENABLE(SUBPIXEL_LAYOUT)
    200     return FloatPoint(floorToDevicePixel(point.x(), pixelSnappingFactor), floorToDevicePixel(point.y(), pixelSnappingFactor));
     209inline FloatPoint ceiledForPainting(const LayoutPoint& point, float pixelSnappingFactor)
     210{
     211#if ENABLE(SUBPIXEL_LAYOUT)
     212    return FloatPoint(ceilToDevicePixel(point.x(), pixelSnappingFactor), ceilToDevicePixel(point.y(), pixelSnappingFactor));
    201213#else
    202214    UNUSED_PARAM(pixelSnappingFactor);
     
    205217}
    206218
    207 inline FloatPoint ceiledForPainting(const LayoutPoint& point, float pixelSnappingFactor)
    208 {
    209 #if ENABLE(SUBPIXEL_LAYOUT)
    210     return FloatPoint(ceilToDevicePixel(point.x(), pixelSnappingFactor), ceilToDevicePixel(point.y(), pixelSnappingFactor));
    211 #else
    212     UNUSED_PARAM(pixelSnappingFactor);
    213     return FloatPoint(point);
    214 #endif
    215 }
    216 
    217219inline LayoutPoint roundedLayoutPoint(const FloatPoint& p)
    218220{
  • trunk/Source/WebCore/platform/graphics/LayoutRect.h

    r164449 r168528  
    248248}
    249249
     250// FIXME: This needs to take vertical centering into account too.
     251inline FloatRect directionalPixelSnappedForPainting(const LayoutRect& rect, float deviceScaleFactor, bool ltr)
     252{
     253    if (!ltr) {
     254        FloatPoint snappedTopRight = roundedForPainting(rect.maxXMinYCorner(), deviceScaleFactor, ltr);
     255        float snappedWidth = snapSizeToDevicePixel(rect.width(), rect.maxX(), deviceScaleFactor);
     256        float snappedHeight = snapSizeToDevicePixel(rect.height(), rect.y(), deviceScaleFactor);
     257        return FloatRect(snappedTopRight.x() - snappedWidth, snappedTopRight.y(), snappedWidth, snappedHeight);
     258    }
     259    return pixelSnappedForPainting(rect, deviceScaleFactor);
     260}
     261
    250262} // namespace WebCore
    251263
  • trunk/Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp

    r165676 r168528  
    3030#include "GraphicsContext.h"
    3131#include "HarfBuzzShaper.h"
     32#include "LayoutRect.h"
    3233#include "Logging.h"
    3334#include "NotImplemented.h"
     
    8586}
    8687
    87 FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
     88void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
    8889{
    8990    HarfBuzzShaper shaper(this, run);
    90     if (shaper.shape())
    91         return shaper.selectionRect(point, h, from, to);
     91    if (shaper.shape()) {
     92        // FIXME: This should mimic Mac port.
     93        FloatRect rect = shaper.selectionRect(FloatPoint(selectionRect.location()), selectionRect.height().toInt(), from, to);
     94        selectionRect = LayoutRect(rect);
     95        return;
     96    }
    9297    LOG_ERROR("Shaper couldn't shape text run.");
    93     return FloatRect();
    9498}
    9599
  • trunk/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp

    r161589 r168528  
    3131#include "GraphicsContext.h"
    3232#include "IntRect.h"
     33#include "LayoutRect.h"
    3334#include "SimpleFontData.h"
    3435#include "TextRun.h"
     
    3738namespace WebCore {
    3839
    39 FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h,
    40                                             int from, int to) const
     40void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
    4141{
    4242    ComplexTextController controller(this, run);
     
    4646    float afterWidth = controller.runWidthSoFar();
    4747
    48     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
    49     if (run.rtl()) {
    50         float totalWidth = controller.totalWidth();
    51         return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
    52     }
    53 
    54     return FloatRect(floorf(point.x() + beforeWidth), point.y(), roundf(point.x() + afterWidth) - floorf(point.x() + beforeWidth), h);
     48    if (run.rtl())
     49        selectionRect.move(controller.totalWidth() - afterWidth, 0);
     50    else
     51        selectionRect.move(beforeWidth, 0);
     52    selectionRect.setWidth(afterWidth - beforeWidth);
    5553}
    5654
  • trunk/Source/WebCore/platform/graphics/win/FontWin.cpp

    r165676 r168528  
    3131#include "GraphicsContext.h"
    3232#include "IntRect.h"
     33#include "LayoutRect.h"
    3334#include "Logging.h"
    3435#include "SimpleFontData.h"
     
    5152}
    5253
    53 FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h,
    54                                             int from, int to) const
     54void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
    5555{
    5656    UniscribeController it(this, run);
     
    6060    float afterWidth = it.runWidthSoFar();
    6161
    62     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
    63     if (run.rtl()) {
    64         it.advance(run.length());
    65         float totalWidth = it.runWidthSoFar();
    66         return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h);
    67     }
    68    
    69     return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
     62    if (run.rtl())
     63        selectionRect.move(controller.totalWidth() - afterWidth, 0);
     64    else
     65        selectionRect.move(beforeWidth, 0);
     66    selectionRect.setWidth(afterWidth - beforeWidth);
    7067}
    7168
  • trunk/Source/WebCore/rendering/EllipsisBox.cpp

    r168095 r168528  
    114114    const RootInlineBox& rootBox = root();
    115115    // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
    116     return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(&blockFlow(), font, m_str, lineStyle, TextRun::AllowTrailingExpansion), IntPoint(x(), y() + rootBox.selectionTopAdjustedForPrecedingBlock()), rootBox.selectionHeightAdjustedForPrecedingBlock()));
     116    LayoutRect selectionRect = LayoutRect(x(), y() + rootBox.selectionTopAdjustedForPrecedingBlock(), 0, rootBox.selectionHeightAdjustedForPrecedingBlock());
     117    font.adjustSelectionRectForText(RenderBlock::constructTextRun(&blockFlow(), font, m_str, lineStyle, TextRun::AllowTrailingExpansion), selectionRect);
     118    // FIXME: use directional pixel snapping instead.
     119    return enclosingIntRect(selectionRect);
    117120}
    118121
     
    130133
    131134    const RootInlineBox& rootBox = root();
    132     LayoutUnit top = rootBox.selectionTop();
    133     LayoutUnit h = rootBox.selectionHeight();
    134 
    135135    GraphicsContextStateSaver stateSaver(*context);
    136     float deviceScaleFactor = renderer().document().deviceScaleFactor();
    137     context->clip(pixelSnappedForPainting(x() + paintOffset.x(), top + paintOffset.y(), m_logicalWidth, h, renderer().document().deviceScaleFactor()));
    138136    // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
    139     FloatPoint localOrigin = roundedForPainting(LayoutPoint(x() + paintOffset.x(), y() + paintOffset.y() + top), deviceScaleFactor);
    140     context->drawHighlightForText(font, RenderBlock::constructTextRun(&blockFlow(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c, style.colorSpace());
     137    LayoutRect selectionRect = LayoutRect(x() + paintOffset.x(), y() + paintOffset.y() + rootBox.selectionTop(), 0, rootBox.selectionHeight());
     138    TextRun run = RenderBlock::constructTextRun(&blockFlow(), font, m_str, style, TextRun::AllowTrailingExpansion);
     139    font.adjustSelectionRectForText(run, selectionRect, 0, -1);
     140    context->fillRect(directionalPixelSnappedForPainting(selectionRect, renderer().document().deviceScaleFactor(), run.ltr()), c, style.colorSpace());
    141141}
    142142
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r168095 r168528  
    266266}
    267267
     268// FIXME: remove this function, when switching to directional pixel snapping.
     269static IntRect integralEnclosingRectForSelection(const LayoutRect& rect)
     270{
     271    // Empty rects with fractional x, y values turn into non-empty rects when converting to enclosing.
     272    // We need to ensure that empty rects stay empty after the conversion, because the selection code expects them to be empty.
     273    IntPoint location = flooredIntPoint(rect.minXMinYCorner());
     274    IntPoint maxPoint = IntPoint(rect.width() ? rect.maxX().ceil() : location.x(), rect.height() ? rect.maxY().ceil() : location.y());
     275    return IntRect(location, maxPoint - location);
     276}
     277
    268278LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const
    269279{
     
    276286    FontCachePurgePreventer fontCachePurgePreventer;
    277287
    278     LayoutUnit selTop = selectionTop();
    279     LayoutUnit selHeight = selectionHeight();
     288    LayoutUnit selectionTop = this->selectionTop();
     289    LayoutUnit selectionHeight = this->selectionHeight();
    280290    const RenderStyle& lineStyle = this->lineStyle();
    281291    const Font& font = fontToUse(lineStyle, renderer());
     
    287297        endPos = textRun.length();
    288298
    289     FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop);
    290     LayoutRect r;
     299    LayoutRect selectionRect = LayoutRect(LayoutPoint(logicalLeft(), selectionTop), LayoutSize(m_logicalWidth, selectionHeight));
     300    // Avoid computing the font width when the entire line box is selected as an optimization.
    291301    if (sPos || ePos != static_cast<int>(m_len))
    292         r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, selHeight, sPos, ePos));
    293     else // Avoid computing the font width when the entire line box is selected as an optimization.
    294         r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight)));
    295 
    296     LayoutUnit logicalWidth = r.width();
    297     if (r.x() > logicalRight())
     302        font.adjustSelectionRectForText(textRun, selectionRect, sPos, ePos);
     303    IntRect snappedSelectionRect = integralEnclosingRectForSelection(selectionRect);
     304    LayoutUnit logicalWidth = snappedSelectionRect.width();
     305    if (snappedSelectionRect.x() > logicalRight())
    298306        logicalWidth  = 0;
    299     else if (r.maxX() > logicalRight())
    300         logicalWidth = logicalRight() - r.x();
    301 
    302     LayoutPoint topPoint = isHorizontal() ? LayoutPoint(r.x(), selTop) : LayoutPoint(selTop, r.x());
    303     LayoutUnit width = isHorizontal() ? logicalWidth : selHeight;
    304     LayoutUnit height = isHorizontal() ? selHeight : logicalWidth;
     307    else if (snappedSelectionRect.maxX() > logicalRight())
     308        logicalWidth = logicalRight() - snappedSelectionRect.x();
     309
     310    LayoutPoint topPoint = isHorizontal() ? LayoutPoint(snappedSelectionRect.x(), selectionTop) : LayoutPoint(selectionTop, snappedSelectionRect.x());
     311    LayoutUnit width = isHorizontal() ? logicalWidth : selectionHeight;
     312    LayoutUnit height = isHorizontal() ? selectionHeight : logicalWidth;
    305313
    306314    return LayoutRect(topPoint, LayoutSize(width, height));
     
    760768    LayoutUnit selectionHeight = std::max<LayoutUnit>(0, selectionBottom - selectionTop);
    761769
    762     float deviceScaleFactor = renderer().document().deviceScaleFactor();
    763     FloatPoint localOrigin = roundedForPainting(LayoutPoint(boxOrigin.x(), boxOrigin.y() - deltaY), deviceScaleFactor);
    764     context->clip(pixelSnappedForPainting(LayoutRect(LayoutPoint(localOrigin), LayoutSize(m_logicalWidth, selectionHeight)), deviceScaleFactor));
    765     context->drawHighlightForText(font, textRun, localOrigin, selectionHeight, c, style.colorSpace(), sPos, ePos);
     770    LayoutRect selectionRect = LayoutRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selectionHeight);
     771    font.adjustSelectionRectForText(textRun, selectionRect, sPos, ePos);
     772    context->fillRect(directionalPixelSnappedForPainting(selectionRect, renderer().document().deviceScaleFactor(), textRun.ltr()), c, style.colorSpace());
    766773#else
    767774    UNUSED_PARAM(context);
     
    794801    updateGraphicsContext(*context, TextPaintStyle(c, style.colorSpace())); // Don't draw text at all!
    795802
    796     int deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
    797     int selHeight = selectionHeight();
    798     FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
    799     context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, c, style.colorSpace(), sPos, ePos);
     803    LayoutUnit deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     804    LayoutRect selectionRect = LayoutRect(boxOrigin.x(), boxOrigin.y() - deltaY, 0, selectionHeight());
     805    TextRun textRun = constructTextRun(style, font);
     806    font.adjustSelectionRectForText(textRun, selectionRect, sPos, ePos);
     807    context->fillRect(directionalPixelSnappedForPainting(selectionRect, renderer().document().deviceScaleFactor(), textRun.ltr()), c, style.colorSpace());
    800808}
    801809
     
    11791187        TextRun run = constructTextRun(style, font);
    11801188
    1181         // FIXME: Convert the document markers to float rects.
    1182         IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
     1189        LayoutRect selectionRect = LayoutRect(startPoint, FloatSize(0, selHeight));
     1190        font.adjustSelectionRectForText(run, selectionRect, startPosition, endPosition);
     1191        IntRect markerRect = integralEnclosingRectForSelection(selectionRect);
    11831192        start = markerRect.x() - startPoint.x();
    11841193        width = markerRect.width();
     
    12131222}
    12141223
    1215 void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, const RenderStyle& style, const Font& font)
    1216 {
    1217     // Use same y positioning and height as for selection, so that when the selection and this highlight are on
    1218     // the same word there are no pieces sticking out.
    1219     int deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
    1220     int selHeight = selectionHeight();
     1224void InlineTextBox::paintTextMatchMarker(GraphicsContext* context, const FloatPoint& boxOrigin, DocumentMarker* marker, const RenderStyle& style, const Font& font)
     1225{
     1226    LayoutUnit selectionHeight = this->selectionHeight();
    12211227
    12221228    int sPos = std::max(marker->startOffset() - m_start, (unsigned)0);
     
    12251231
    12261232    // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
    1227     IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(x(), selectionTop()), selHeight, sPos, ePos));
    1228     markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
     1233    // FIXME: figure out how renderedRect and selectionRect are different.
     1234    LayoutRect renderedRect = LayoutRect(LayoutPoint(x(), selectionTop()), FloatSize(0, selectionHeight));
     1235    font.adjustSelectionRectForText(run, renderedRect, sPos, ePos);
     1236    IntRect markerRect = integralEnclosingRectForSelection(renderedRect);
     1237    markerRect = renderer().localToAbsoluteQuad(FloatQuad(markerRect)).enclosingBoundingBox();
    12291238    toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
    12301239   
     
    12321241    if (renderer().frame().editor().markedTextMatchesAreHighlighted()) {
    12331242        Color color = marker->activeMatch() ? renderer().theme().platformActiveTextSearchHighlightColor() : renderer().theme().platformInactiveTextSearchHighlightColor();
    1234         GraphicsContextStateSaver stateSaver(*pt);
    1235         updateGraphicsContext(*pt, TextPaintStyle(color, style.colorSpace())); // Don't draw text at all!
    1236         pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
    1237         pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style.colorSpace(), sPos, ePos);
     1243        GraphicsContextStateSaver stateSaver(*context);
     1244        updateGraphicsContext(*context, TextPaintStyle(color, style.colorSpace())); // Don't draw text at all!
     1245
     1246        // Use same y positioning and height as for selection, so that when the selection and this highlight are on
     1247        // the same word there are no pieces sticking out.
     1248        LayoutUnit deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     1249        LayoutRect selectionRect = LayoutRect(boxOrigin.x(), boxOrigin.y() - deltaY, 0, selectionHeight);
     1250        font.adjustSelectionRectForText(run, selectionRect, sPos, ePos);
     1251        context->fillRect(directionalPixelSnappedForPainting(selectionRect, renderer().document().deviceScaleFactor(), run.ltr()), color, style.colorSpace());
    12381252    }
    12391253}
     
    12421256{
    12431257    // Replacement markers are not actually drawn, but their rects need to be computed for hit testing.
    1244     int top = selectionTop();
    1245     int h = selectionHeight();
     1258    LayoutUnit top = selectionTop();
     1259    LayoutUnit h = selectionHeight();
    12461260   
    12471261    int sPos = std::max(marker->startOffset() - m_start, (unsigned)0);
    12481262    int ePos = std::min(marker->endOffset() - m_start, (unsigned)m_len);
    12491263    TextRun run = constructTextRun(style, font);
    1250     IntPoint startPoint = IntPoint(x(), top);
    1251    
     1264
    12521265    // Compute and store the rect associated with this marker.
    1253     IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
     1266    LayoutRect selectionRect = LayoutRect(LayoutPoint(x(), top), LayoutSize(0, h));
     1267    font.adjustSelectionRectForText(run, selectionRect, sPos, ePos);
     1268    IntRect markerRect = integralEnclosingRectForSelection(selectionRect);
    12541269    markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
    12551270    toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
     
    14321447    int to = !isLeftToRightDirection() ? m_len : offset - m_start;
    14331448    // FIXME: Do we need to add rightBearing here?
    1434     return font.selectionRectForText(constructTextRun(lineStyle, font), IntPoint(logicalLeft(), 0), 0, from, to).maxX();
     1449    LayoutRect selectionRect = LayoutRect(logicalLeft(), 0, 0, 0);
     1450    TextRun run = constructTextRun(lineStyle, font);
     1451    font.adjustSelectionRectForText(run, selectionRect, from, to);
     1452    return directionalPixelSnappedForPainting(selectionRect, renderer().document().deviceScaleFactor(), run.ltr()).maxX();
    14351453}
    14361454
  • trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp

    r166420 r168528  
    126126    textOrigin.move(0, -scaledFontMetrics.floatAscent());
    127127
    128     FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height * scalingFactor, startPosition, endPosition);
     128    LayoutRect selectionRect = LayoutRect(textOrigin, LayoutSize(0, fragment.height * scalingFactor));
     129    TextRun run = constructTextRun(style, fragment);
     130    scaledFont.adjustSelectionRectForText(run, selectionRect, startPosition, endPosition);
     131    FloatRect snappedSelectionRect = directionalPixelSnappedForPainting(selectionRect, renderer().document().deviceScaleFactor(), run.ltr());
    129132    if (scalingFactor == 1)
    130         return selectionRect;
     133        return snappedSelectionRect;
    131134
    132135    selectionRect.scale(1 / scalingFactor);
    133     return selectionRect;
     136    return snappedSelectionRect;
    134137}
    135138
Note: See TracChangeset for help on using the changeset viewer.