Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1173)

Unified Diff: Source/core/rendering/RenderObject.cpp

Issue 591613003: Move painting code from RenderObject into a new ObjectPainter class. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Merge again. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/RenderObject.h ('k') | Source/core/rendering/RenderTableCell.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « Source/core/rendering/RenderObject.h ('k') | Source/core/rendering/RenderTableCell.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698