| Index: Source/core/rendering/RenderObject.cpp | 
| diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp | 
| index 4a385c0510141c1153eab7c5d86cd15e952860c8..96a28d4392bcdb5cd41f7d77e5274e5d91ee2bc2 100644 | 
| --- a/Source/core/rendering/RenderObject.cpp | 
| +++ b/Source/core/rendering/RenderObject.cpp | 
| @@ -41,6 +41,8 @@ | 
| #include "core/frame/EventHandlerRegistry.h" | 
| #include "core/frame/FrameView.h" | 
| #include "core/frame/LocalFrame.h" | 
| +#include "core/frame/Settings.h" | 
| +#include "core/frame/UseCounter.h" | 
| #include "core/html/HTMLAnchorElement.h" | 
| #include "core/html/HTMLElement.h" | 
| #include "core/html/HTMLHtmlElement.h" | 
| @@ -49,8 +51,7 @@ | 
| #include "core/page/AutoscrollController.h" | 
| #include "core/page/EventHandler.h" | 
| #include "core/page/Page.h" | 
| -#include "core/frame/Settings.h" | 
| -#include "core/frame/UseCounter.h" | 
| +#include "core/paint/ObjectPainter.h" | 
| #include "core/rendering/FlowThreadController.h" | 
| #include "core/rendering/HitTestResult.h" | 
| #include "core/rendering/RenderCounter.h" | 
| @@ -977,336 +978,9 @@ bool RenderObject::mustInvalidateBackgroundOrBorderPaintOnHeightChange() const | 
| return false; | 
| } | 
|  | 
| -void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, | 
| -                                      BoxSide side, Color color, EBorderStyle style, | 
| -                                      int adjacentWidth1, int adjacentWidth2, bool antialias) | 
| -{ | 
| -    int thickness; | 
| -    int length; | 
| -    if (side == BSTop || side == BSBottom) { | 
| -        thickness = y2 - y1; | 
| -        length = x2 - x1; | 
| -    } else { | 
| -        thickness = x2 - x1; | 
| -        length = y2 - y1; | 
| -    } | 
| - | 
| -    // FIXME: We really would like this check to be an ASSERT as we don't want to draw empty borders. However | 
| -    // nothing guarantees that the following recursive calls to drawLineForBoxSide will have non-null dimensions. | 
| -    if (!thickness || !length) | 
| -        return; | 
| - | 
| -    if (style == DOUBLE && thickness < 3) | 
| -        style = SOLID; | 
| - | 
| -    switch (style) { | 
| -    case BNONE: | 
| -    case BHIDDEN: | 
| -        return; | 
| -    case DOTTED: | 
| -    case DASHED: | 
| -        drawDashedOrDottedBoxSide(graphicsContext, x1, y1, x2, y2, side, | 
| -            color, thickness, style, antialias); | 
| -        break; | 
| -    case DOUBLE: | 
| -        drawDoubleBoxSide(graphicsContext, x1, y1, x2, y2, length, side, color, | 
| -            thickness, adjacentWidth1, adjacentWidth2, antialias); | 
| -        break; | 
| -    case RIDGE: | 
| -    case GROOVE: | 
| -        drawRidgeOrGrooveBoxSide(graphicsContext, x1, y1, x2, y2, side, color, | 
| -            style, adjacentWidth1, adjacentWidth2, antialias); | 
| -        break; | 
| -    case INSET: | 
| -        // FIXME: Maybe we should lighten the colors on one side like Firefox. | 
| -        // https://bugs.webkit.org/show_bug.cgi?id=58608 | 
| -        if (side == BSTop || side == BSLeft) | 
| -            color = color.dark(); | 
| -        // fall through | 
| -    case OUTSET: | 
| -        if (style == OUTSET && (side == BSBottom || side == BSRight)) | 
| -            color = color.dark(); | 
| -        // fall through | 
| -    case SOLID: | 
| -        drawSolidBoxSide(graphicsContext, x1, y1, x2, y2, side, color, adjacentWidth1, adjacentWidth2, antialias); | 
| -        break; | 
| -    } | 
| -} | 
| - | 
| -void RenderObject::drawDashedOrDottedBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, | 
| -    BoxSide side, Color color, int thickness, EBorderStyle style, bool antialias) | 
| -{ | 
| -    if (thickness <= 0) | 
| -        return; | 
| - | 
| -    bool wasAntialiased = graphicsContext->shouldAntialias(); | 
| -    StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle(); | 
| -    graphicsContext->setShouldAntialias(antialias); | 
| -    graphicsContext->setStrokeColor(color); | 
| -    graphicsContext->setStrokeThickness(thickness); | 
| -    graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke); | 
| - | 
| -    switch (side) { | 
| -    case BSBottom: | 
| -    case BSTop: | 
| -        graphicsContext->drawLine(IntPoint(x1, (y1 + y2) / 2), IntPoint(x2, (y1 + y2) / 2)); | 
| -        break; | 
| -    case BSRight: | 
| -    case BSLeft: | 
| -        graphicsContext->drawLine(IntPoint((x1 + x2) / 2, y1), IntPoint((x1 + x2) / 2, y2)); | 
| -        break; | 
| -    } | 
| -    graphicsContext->setShouldAntialias(wasAntialiased); | 
| -    graphicsContext->setStrokeStyle(oldStrokeStyle); | 
| -} | 
| - | 
| -void RenderObject::drawDoubleBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, | 
| -    int length, BoxSide side, Color color, int thickness, int adjacentWidth1, int adjacentWidth2, bool antialias) | 
| -{ | 
| -    int thirdOfThickness = (thickness + 1) / 3; | 
| -    ASSERT(thirdOfThickness); | 
| - | 
| -    if (!adjacentWidth1 && !adjacentWidth2) { | 
| -        StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle(); | 
| -        graphicsContext->setStrokeStyle(NoStroke); | 
| -        graphicsContext->setFillColor(color); | 
| - | 
| -        bool wasAntialiased = graphicsContext->shouldAntialias(); | 
| -        graphicsContext->setShouldAntialias(antialias); | 
| - | 
| -        switch (side) { | 
| -        case BSTop: | 
| -        case BSBottom: | 
| -            graphicsContext->drawRect(IntRect(x1, y1, length, thirdOfThickness)); | 
| -            graphicsContext->drawRect(IntRect(x1, y2 - thirdOfThickness, length, thirdOfThickness)); | 
| -            break; | 
| -        case BSLeft: | 
| -        case BSRight: | 
| -            // FIXME: Why do we offset the border by 1 in this case but not the other one? | 
| -            if (length > 1) { | 
| -                graphicsContext->drawRect(IntRect(x1, y1 + 1, thirdOfThickness, length - 1)); | 
| -                graphicsContext->drawRect(IntRect(x2 - thirdOfThickness, y1 + 1, thirdOfThickness, length - 1)); | 
| -            } | 
| -            break; | 
| -        } | 
| - | 
| -        graphicsContext->setShouldAntialias(wasAntialiased); | 
| -        graphicsContext->setStrokeStyle(oldStrokeStyle); | 
| -        return; | 
| -    } | 
| - | 
| -    int adjacent1BigThird = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 3; | 
| -    int adjacent2BigThird = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 3; | 
| - | 
| -    switch (side) { | 
| -    case BSTop: | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            y1, x2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), y1 + thirdOfThickness, | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            y2 - thirdOfThickness, x2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), y2, | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        break; | 
| -    case BSLeft: | 
| -        drawLineForBoxSide(graphicsContext, x1, y1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            x1 + thirdOfThickness, y2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, y1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            x2, y2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        break; | 
| -    case BSBottom: | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            y1, x2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), y1 + thirdOfThickness, | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            y2 - thirdOfThickness, x2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), y2, | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        break; | 
| -    case BSRight: | 
| -        drawLineForBoxSide(graphicsContext, x1, y1 + std::max((adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            x1 + thirdOfThickness, y2 - std::max((adjacentWidth2 * 2 + 1) / 3, 0), | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, y1 + std::max((-adjacentWidth1 * 2 + 1) / 3, 0), | 
| -            x2, y2 - std::max((-adjacentWidth2 * 2 + 1) / 3, 0), | 
| -            side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias); | 
| -        break; | 
| -    default: | 
| -        break; | 
| -    } | 
| -} | 
| - | 
| -void RenderObject::drawRidgeOrGrooveBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, | 
| -    BoxSide side, Color color, EBorderStyle style, int adjacentWidth1, int adjacentWidth2, bool antialias) | 
| -{ | 
| -    EBorderStyle s1; | 
| -    EBorderStyle s2; | 
| -    if (style == GROOVE) { | 
| -        s1 = INSET; | 
| -        s2 = OUTSET; | 
| -    } else { | 
| -        s1 = OUTSET; | 
| -        s2 = INSET; | 
| -    } | 
| - | 
| -    int adjacent1BigHalf = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 2; | 
| -    int adjacent2BigHalf = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 2; | 
| - | 
| -    switch (side) { | 
| -    case BSTop: | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max(-adjacentWidth1, 0) / 2, y1, x2 - std::max(-adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2, | 
| -            side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias); | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max(adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - std::max(adjacentWidth2 + 1, 0) / 2, y2, | 
| -            side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); | 
| -        break; | 
| -    case BSLeft: | 
| -        drawLineForBoxSide(graphicsContext, x1, y1 + std::max(-adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - std::max(-adjacentWidth2, 0) / 2, | 
| -            side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias); | 
| -        drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + std::max(adjacentWidth1 + 1, 0) / 2, x2, y2 - std::max(adjacentWidth2 + 1, 0) / 2, | 
| -            side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); | 
| -        break; | 
| -    case BSBottom: | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max(adjacentWidth1, 0) / 2, y1, x2 - std::max(adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2, | 
| -            side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias); | 
| -        drawLineForBoxSide(graphicsContext, x1 + std::max(-adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - std::max(-adjacentWidth2 + 1, 0) / 2, y2, | 
| -            side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); | 
| -        break; | 
| -    case BSRight: | 
| -        drawLineForBoxSide(graphicsContext, x1, y1 + std::max(adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - std::max(adjacentWidth2, 0) / 2, | 
| -            side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias); | 
| -        drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + std::max(-adjacentWidth1 + 1, 0) / 2, x2, y2 - std::max(-adjacentWidth2 + 1, 0) / 2, | 
| -            side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias); | 
| -        break; | 
| -    } | 
| -} | 
| - | 
| -void RenderObject::drawSolidBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, | 
| -    BoxSide side, Color color, int adjacentWidth1, int adjacentWidth2, bool antialias) | 
| -{ | 
| -    StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle(); | 
| -    graphicsContext->setStrokeStyle(NoStroke); | 
| -    graphicsContext->setFillColor(color); | 
| -    ASSERT(x2 >= x1); | 
| -    ASSERT(y2 >= y1); | 
| -    if (!adjacentWidth1 && !adjacentWidth2) { | 
| -        // Turn off antialiasing to match the behavior of drawConvexPolygon(); | 
| -        // this matters for rects in transformed contexts. | 
| -        bool wasAntialiased = graphicsContext->shouldAntialias(); | 
| -        graphicsContext->setShouldAntialias(antialias); | 
| -        graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1)); | 
| -        graphicsContext->setShouldAntialias(wasAntialiased); | 
| -        graphicsContext->setStrokeStyle(oldStrokeStyle); | 
| -        return; | 
| -    } | 
| -    FloatPoint quad[4]; | 
| -    switch (side) { | 
| -    case BSTop: | 
| -        quad[0] = FloatPoint(x1 + std::max(-adjacentWidth1, 0), y1); | 
| -        quad[1] = FloatPoint(x1 + std::max(adjacentWidth1, 0), y2); | 
| -        quad[2] = FloatPoint(x2 - std::max(adjacentWidth2, 0), y2); | 
| -        quad[3] = FloatPoint(x2 - std::max(-adjacentWidth2, 0), y1); | 
| -        break; | 
| -    case BSBottom: | 
| -        quad[0] = FloatPoint(x1 + std::max(adjacentWidth1, 0), y1); | 
| -        quad[1] = FloatPoint(x1 + std::max(-adjacentWidth1, 0), y2); | 
| -        quad[2] = FloatPoint(x2 - std::max(-adjacentWidth2, 0), y2); | 
| -        quad[3] = FloatPoint(x2 - std::max(adjacentWidth2, 0), y1); | 
| -        break; | 
| -    case BSLeft: | 
| -        quad[0] = FloatPoint(x1, y1 + std::max(-adjacentWidth1, 0)); | 
| -        quad[1] = FloatPoint(x1, y2 - std::max(-adjacentWidth2, 0)); | 
| -        quad[2] = FloatPoint(x2, y2 - std::max(adjacentWidth2, 0)); | 
| -        quad[3] = FloatPoint(x2, y1 + std::max(adjacentWidth1, 0)); | 
| -        break; | 
| -    case BSRight: | 
| -        quad[0] = FloatPoint(x1, y1 + std::max(adjacentWidth1, 0)); | 
| -        quad[1] = FloatPoint(x1, y2 - std::max(adjacentWidth2, 0)); | 
| -        quad[2] = FloatPoint(x2, y2 - std::max(-adjacentWidth2, 0)); | 
| -        quad[3] = FloatPoint(x2, y1 + std::max(-adjacentWidth1, 0)); | 
| -        break; | 
| -    } | 
| - | 
| -    graphicsContext->drawConvexPolygon(4, quad, antialias); | 
| -    graphicsContext->setStrokeStyle(oldStrokeStyle); | 
| -} | 
| - | 
| -void RenderObject::paintFocusRing(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderStyle* style) | 
| -{ | 
| -    Vector<LayoutRect> focusRingRects; | 
| -    addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer()); | 
| -    ASSERT(style->outlineStyleIsAuto()); | 
| -    Vector<IntRect> focusRingIntRects; | 
| -    for (size_t i = 0; i < focusRingRects.size(); ++i) | 
| -        focusRingIntRects.append(pixelSnappedIntRect(focusRingRects[i])); | 
| -    paintInfo.context->drawFocusRing(focusRingIntRects, style->outlineWidth(), style->outlineOffset(), resolveColor(style, CSSPropertyOutlineColor)); | 
| -} | 
| - | 
| void RenderObject::paintOutline(PaintInfo& paintInfo, const LayoutRect& paintRect) | 
| { | 
| -    RenderStyle* styleToUse = style(); | 
| -    if (!styleToUse->hasOutline()) | 
| -        return; | 
| - | 
| -    LayoutUnit outlineWidth = styleToUse->outlineWidth(); | 
| - | 
| -    int outlineOffset = styleToUse->outlineOffset(); | 
| - | 
| -    if (styleToUse->outlineStyleIsAuto()) { | 
| -        if (RenderTheme::theme().shouldDrawDefaultFocusRing(this)) { | 
| -            // Only paint the focus ring by hand if the theme isn't able to draw the focus ring. | 
| -            paintFocusRing(paintInfo, paintRect.location(), styleToUse); | 
| -        } | 
| -        return; | 
| -    } | 
| - | 
| -    if (styleToUse->outlineStyle() == BNONE) | 
| -        return; | 
| - | 
| -    IntRect inner = pixelSnappedIntRect(paintRect); | 
| -    inner.inflate(outlineOffset); | 
| - | 
| -    IntRect outer = pixelSnappedIntRect(inner); | 
| -    outer.inflate(outlineWidth); | 
| - | 
| -    // FIXME: This prevents outlines from painting inside the object. See bug 12042 | 
| -    if (outer.isEmpty()) | 
| -        return; | 
| - | 
| -    EBorderStyle outlineStyle = styleToUse->outlineStyle(); | 
| -    Color outlineColor = resolveColor(styleToUse, CSSPropertyOutlineColor); | 
| - | 
| -    GraphicsContext* graphicsContext = paintInfo.context; | 
| -    bool useTransparencyLayer = outlineColor.hasAlpha(); | 
| -    if (useTransparencyLayer) { | 
| -        if (outlineStyle == SOLID) { | 
| -            Path path; | 
| -            path.addRect(outer); | 
| -            path.addRect(inner); | 
| -            graphicsContext->setFillRule(RULE_EVENODD); | 
| -            graphicsContext->setFillColor(outlineColor); | 
| -            graphicsContext->fillPath(path); | 
| -            return; | 
| -        } | 
| -        graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.alpha()) / 255); | 
| -        outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue()); | 
| -    } | 
| - | 
| -    int leftOuter = outer.x(); | 
| -    int leftInner = inner.x(); | 
| -    int rightOuter = outer.maxX(); | 
| -    int rightInner = inner.maxX(); | 
| -    int topOuter = outer.y(); | 
| -    int topInner = inner.y(); | 
| -    int bottomOuter = outer.maxY(); | 
| -    int bottomInner = inner.maxY(); | 
| - | 
| -    drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth); | 
| -    drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth); | 
| -    drawLineForBoxSide(graphicsContext, rightInner, topOuter, rightOuter, bottomOuter, BSRight, outlineColor, outlineStyle, outlineWidth, outlineWidth); | 
| -    drawLineForBoxSide(graphicsContext, leftOuter, bottomInner, rightOuter, bottomOuter, BSBottom, outlineColor, outlineStyle, outlineWidth, outlineWidth); | 
| - | 
| -    if (useTransparencyLayer) | 
| -        graphicsContext->endLayer(); | 
| +    ObjectPainter(*this).paintOutline(paintInfo, paintRect); | 
| } | 
|  | 
| void RenderObject::addChildFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer) const | 
|  |