+2012-02-23 Levi Weintraub <leviw@chromium.org>
+
+ Switch drawLineForBoxSide to use integers
+ https://bugs.webkit.org/show_bug.cgi?id=78647
+
+ Reviewed by Eric Seidel.
+
+ drawLineForBoxSide handles painting lines for boxes which must be done on pixel boundaries.
+ Its interface doesn't make it possible to pixel snap properly within the function itself --
+ it draws one side of the box at a time, and the logical right and bottom lines can only be
+ properly determined using the logical top and left positions -- so it needs to be treated
+ like a graphics context function, whereby the caller handles the proper pixel snapping before
+ passing the values in.
+
+ No new tests. No change in behavior.
+
+ * rendering/LayoutTypes.h:
+ (WebCore::pixelSnappedIntRectFromEdges): convenience function for returning a pixel snapped
+ int rect from four LayoutUnits that are its edges (as opposed to position and size).
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintColumnRules): Pixel snapping the column rule rect.
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintOneBorderSide): Side rects are now IntRects by the time
+ they get to paintOneBorderSide.
+ (WebCore::calculateSideRect): Properly use RoundedRect as IntRects instead of LayoutRects.
+ (WebCore::RenderBoxModelObject::paintBorderSides): Ditto.
+ (WebCore::RenderBoxModelObject::paintBorder): Ditto.
+ (WebCore::calculateSideRectIncludingInner): Ditto.
+ * rendering/RenderBoxModelObject.h:
+ (RenderBoxModelObject):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::paintOutlineForLine): Outline widths are related to borders and stored
+ as ints. Removing an unnecessary conversion to LayoutUnits. Pixel snapping the edges of the box.
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::drawLineForBoxSide): Moving back to integers and removing an
+ unnecessary pixelSnappedIntRect call.
+ (WebCore::RenderObject::paintOutline): Pixel snapping the column rule rect and using an integer
+ for outlineOffset.
+ * rendering/RenderObject.h:
+ (RenderObject):
+
2012-02-23 Leo Yang <leo.yang@torchmobile.com.cn>
[BlackBerry] Upstream the BlackBerry change to platform/graphics/IntPoint.h
return rect;
}
+inline IntRect pixelSnappedIntRectFromEdges(LayoutUnit left, LayoutUnit top, LayoutUnit right, LayoutUnit bottom)
+{
+ return IntRect(left, top, right - left, bottom - top);
+}
+
inline IntSize roundedIntSize(const LayoutSize& s)
{
return s;
LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
- drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom, boxSide, ruleColor, ruleStyle, 0, 0, antialias);
+ IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
+ drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
}
ruleLogicalLeft = currLogicalLeftOffset;
for (unsigned i = 1; i < colCount; i++) {
ruleRect.move(step);
- drawLineForBoxSide(paintInfo.context, ruleRect.x(), ruleRect.y(), ruleRect.maxX(), ruleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
+ IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
+ drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
}
}
}
}
void RenderBoxModelObject::paintOneBorderSide(GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
- const LayoutRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge edges[], const Path* path,
+ const IntRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge edges[], const Path* path,
BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
{
const BorderEdge& edgeToRender = edges[side];
}
}
-static LayoutRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdge edges[], int side)
+static IntRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdge edges[], int side)
{
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
int width = edges[side].width;
if (side == BSTop)
roundedPath.addRoundedRect(outerBorder);
if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.setHeight(edges[BSTop].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].style) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorder.radii().topRight()));
}
if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom].style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.radii().bottomRight()));
}
if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.setWidth(edges[BSLeft].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.radii().topLeft()));
}
if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight].style) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), innerBorder.radii().topRight()));
for (int i = BSTop; i <= BSLeft; ++i) {
const BorderEdge& currEdge = edges[i];
if (currEdge.shouldRender()) {
- LayoutRect sideRect = calculateSideRect(outerBorder, edges, i);
+ IntRect sideRect = calculateSideRect(outerBorder, edges, i);
path.addRect(sideRect);
}
}
graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches);
}
-static LayoutRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, const BorderEdge edges[], BoxSide side)
+static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, const BorderEdge edges[], BoxSide side)
{
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
int width;
switch (side) {
BoxSide, bool firstEdgeMatches, bool secondEdgeMatches);
void clipBorderSideForComplexInnerPath(GraphicsContext*, const RoundedRect&, const RoundedRect&, BoxSide, const class BorderEdge[]);
void paintOneBorderSide(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
- const LayoutRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[],
+ const IntRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[],
const Path*, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = 0);
void paintTranslucentBorderSides(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
const class BorderEdge[], BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false);
const Color outlineColor)
{
RenderStyle* styleToUse = style();
- LayoutUnit outlineWidth = styleToUse->outlineWidth();
+ int outlineWidth = styleToUse->outlineWidth();
EBorderStyle outlineStyle = styleToUse->outlineStyle();
bool antialias = shouldAntialiasLines(graphicsContext);
- LayoutUnit offset = style()->outlineOffset();
+ int offset = style()->outlineOffset();
- LayoutUnit top = paintOffset.y() + thisline.y() - offset;
- LayoutUnit left = paintOffset.x() + thisline.x() - offset;
- LayoutUnit bottom = paintOffset.y() + thisline.maxY() + offset;
- LayoutUnit right = paintOffset.x() + thisline.maxX() + offset;
+ LayoutRect box(LayoutPoint(paintOffset.x() + thisline.x() - offset, paintOffset.y() + thisline.y() - offset),
+ LayoutSize(thisline.width() + offset, thisline.height() + offset));
+
+ IntRect pixelSnappedBox = pixelSnappedIntRect(box);
// left edge
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- top - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : zeroLayoutUnit),
- left,
- bottom + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX() - 1) <= thisline.x() ? outlineWidth : zeroLayoutUnit),
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.y() - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : 0),
+ pixelSnappedBox.x(),
+ pixelSnappedBox.maxY() + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX() - 1) <= thisline.x() ? outlineWidth : 0),
BSLeft,
outlineColor, outlineStyle,
(lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : -outlineWidth),
// right edge
drawLineForBoxSide(graphicsContext,
- right,
- top - (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : zeroLayoutUnit),
- right + outlineWidth,
- bottom + (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.maxX() - 1) <= nextline.x() ? outlineWidth : zeroLayoutUnit),
+ pixelSnappedBox.maxX(),
+ pixelSnappedBox.y() - (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : 0),
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.maxY() + (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.maxX() - 1) <= nextline.x() ? outlineWidth : 0),
BSRight,
outlineColor, outlineStyle,
(lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : -outlineWidth),
// upper edge
if (thisline.x() < lastline.x())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- top - outlineWidth,
- min(right + outlineWidth, (lastline.isEmpty() ? 1000000 : paintOffset.x() + lastline.x())),
- top,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.y() - outlineWidth,
+ min(pixelSnappedBox.maxX() + outlineWidth, (lastline.isEmpty() ? 1000000 : paintOffset.x() + lastline.x())),
+ pixelSnappedBox.y(),
BSTop, outlineColor, outlineStyle,
outlineWidth,
- (!lastline.isEmpty() && paintOffset.x() + lastline.x() + 1 < right + outlineWidth) ? -outlineWidth : outlineWidth,
+ (!lastline.isEmpty() && paintOffset.x() + lastline.x() + 1 < pixelSnappedBox.maxX() + outlineWidth) ? -outlineWidth : outlineWidth,
antialias);
if (lastline.maxX() < thisline.maxX())
drawLineForBoxSide(graphicsContext,
- max(lastline.isEmpty() ? -1000000 : paintOffset.x() + lastline.maxX(), left - outlineWidth),
- top - outlineWidth,
- right + outlineWidth,
- top,
+ max(lastline.isEmpty() ? -1000000 : paintOffset.x() + lastline.maxX(), pixelSnappedBox.x() - outlineWidth),
+ pixelSnappedBox.y() - outlineWidth,
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.y(),
BSTop, outlineColor, outlineStyle,
- (!lastline.isEmpty() && left - outlineWidth < paintOffset.x() + lastline.maxX()) ? -outlineWidth : outlineWidth,
+ (!lastline.isEmpty() && pixelSnappedBox.x() - outlineWidth < paintOffset.x() + lastline.maxX()) ? -outlineWidth : outlineWidth,
outlineWidth, antialias);
if (thisline.x() == thisline.maxX())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- top - outlineWidth,
- right + outlineWidth,
- top,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.y() - outlineWidth,
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.y(),
BSTop, outlineColor, outlineStyle,
outlineWidth,
outlineWidth,
// lower edge
if (thisline.x() < nextline.x())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- bottom,
- min(right + outlineWidth, !nextline.isEmpty() ? paintOffset.x() + nextline.x() + 1 : 1000000),
- bottom + outlineWidth,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.maxY(),
+ min(pixelSnappedBox.maxX() + outlineWidth, !nextline.isEmpty() ? paintOffset.x() + nextline.x() + 1 : 1000000),
+ pixelSnappedBox.maxY() + outlineWidth,
BSBottom, outlineColor, outlineStyle,
outlineWidth,
- (!nextline.isEmpty() && paintOffset.x() + nextline.x() + 1 < right + outlineWidth) ? -outlineWidth : outlineWidth,
+ (!nextline.isEmpty() && paintOffset.x() + nextline.x() + 1 < pixelSnappedBox.maxX() + outlineWidth) ? -outlineWidth : outlineWidth,
antialias);
if (nextline.maxX() < thisline.maxX())
drawLineForBoxSide(graphicsContext,
- max(!nextline.isEmpty() ? paintOffset.x() + nextline.maxX() : -1000000, left - outlineWidth),
- bottom,
- right + outlineWidth,
- bottom + outlineWidth,
+ max(!nextline.isEmpty() ? paintOffset.x() + nextline.maxX() : -1000000, pixelSnappedBox.x() - outlineWidth),
+ pixelSnappedBox.maxY(),
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.maxY() + outlineWidth,
BSBottom, outlineColor, outlineStyle,
- (!nextline.isEmpty() && left - outlineWidth < paintOffset.x() + nextline.maxX()) ? -outlineWidth : outlineWidth,
+ (!nextline.isEmpty() && pixelSnappedBox.x() - outlineWidth < paintOffset.x() + nextline.maxX()) ? -outlineWidth : outlineWidth,
outlineWidth, antialias);
if (thisline.x() == thisline.maxX())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- bottom,
- right + outlineWidth,
- bottom + outlineWidth,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.maxY(),
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.maxY() + outlineWidth,
BSBottom, outlineColor, outlineStyle,
outlineWidth,
outlineWidth,
return false;
}
-void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, LayoutUnit x1, LayoutUnit y1, LayoutUnit x2, LayoutUnit y2,
+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)
{
// this matters for rects in transformed contexts.
bool wasAntialiased = graphicsContext->shouldAntialias();
graphicsContext->setShouldAntialias(antialias);
- graphicsContext->drawRect(pixelSnappedIntRect(LayoutRect(x1, y1, x2 - x1, y2 - y1)));
+ graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1));
graphicsContext->setShouldAntialias(wasAntialiased);
graphicsContext->setStrokeStyle(oldStrokeStyle);
return;
Color outlineColor = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
- LayoutUnit outlineOffset = styleToUse->outlineOffset();
+ int outlineOffset = styleToUse->outlineOffset();
if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
if (!theme()->supportsFocusRing(styleToUse)) {
if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
return;
- LayoutRect inner = paintRect;
+ IntRect inner = pixelSnappedIntRect(paintRect);
inner.inflate(outlineOffset);
- LayoutRect outer = inner;
+ IntRect outer = pixelSnappedIntRect(inner);
outer.inflate(outlineWidth);
// FIXME: This prevents outlines from painting inside the object. See bug 12042
outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
}
- LayoutUnit leftOuter = outer.x();
- LayoutUnit leftInner = inner.x();
- LayoutUnit rightOuter = outer.maxX();
- LayoutUnit rightInner = inner.maxX();
- LayoutUnit topOuter = outer.y();
- LayoutUnit topInner = inner.y();
- LayoutUnit bottomOuter = outer.maxY();
- LayoutUnit bottomInner = inner.maxY();
+ 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);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void propagateStyleToAnonymousChildren(bool blockChildrenOnly = false);
- void drawLineForBoxSide(GraphicsContext*, LayoutUnit x1, LayoutUnit y1, LayoutUnit x2, LayoutUnit y2, BoxSide,
+ void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false);
void paintFocusRing(GraphicsContext*, const LayoutPoint&, RenderStyle*);