| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/BoxPainter.h" | 6 #include "core/paint/BoxPainter.h" |
| 7 | 7 |
| 8 #include "core/HTMLNames.h" | 8 #include "core/HTMLNames.h" |
| 9 #include "core/frame/Settings.h" | 9 #include "core/frame/Settings.h" |
| 10 #include "core/html/HTMLFrameOwnerElement.h" | 10 #include "core/html/HTMLFrameOwnerElement.h" |
| 11 #include "core/layout/ImageQualityController.h" | 11 #include "core/layout/ImageQualityController.h" |
| 12 #include "core/layout/LayoutBox.h" | 12 #include "core/layout/LayoutBox.h" |
| 13 #include "core/layout/LayoutBoxModelObject.h" | 13 #include "core/layout/LayoutBoxModelObject.h" |
| 14 #include "core/layout/LayoutObject.h" | 14 #include "core/layout/LayoutObject.h" |
| 15 #include "core/layout/LayoutTable.h" | 15 #include "core/layout/LayoutTable.h" |
| 16 #include "core/layout/LayoutTheme.h" | 16 #include "core/layout/LayoutTheme.h" |
| 17 #include "core/layout/LayoutView.h" | 17 #include "core/layout/LayoutView.h" |
| 18 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h" | 18 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h" |
| 19 #include "core/style/BorderEdge.h" | 19 #include "core/style/BorderEdge.h" |
| 20 #include "core/style/ShadowList.h" | 20 #include "core/style/ShadowList.h" |
| 21 #include "core/paint/BackgroundImageGeometry.h" | 21 #include "core/paint/BackgroundImageGeometry.h" |
| 22 #include "core/paint/BoxBorderPainter.h" |
| 22 #include "core/paint/BoxDecorationData.h" | 23 #include "core/paint/BoxDecorationData.h" |
| 23 #include "core/paint/DeprecatedPaintLayer.h" | 24 #include "core/paint/DeprecatedPaintLayer.h" |
| 24 #include "core/paint/LayoutObjectDrawingRecorder.h" | 25 #include "core/paint/LayoutObjectDrawingRecorder.h" |
| 25 #include "core/paint/PaintInfo.h" | 26 #include "core/paint/PaintInfo.h" |
| 26 #include "core/paint/RoundedInnerRectClipper.h" | 27 #include "core/paint/RoundedInnerRectClipper.h" |
| 27 #include "core/paint/ThemePainter.h" | 28 #include "core/paint/ThemePainter.h" |
| 28 #include "platform/LengthFunctions.h" | 29 #include "platform/LengthFunctions.h" |
| 29 #include "platform/geometry/LayoutPoint.h" | 30 #include "platform/geometry/LayoutPoint.h" |
| 30 #include "platform/geometry/LayoutRectOutsets.h" | 31 #include "platform/geometry/LayoutRectOutsets.h" |
| 31 #include "platform/graphics/GraphicsContextStateSaver.h" | 32 #include "platform/graphics/GraphicsContextStateSaver.h" |
| (...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 else if (side == BSBottom) | 1141 else if (side == BSBottom) |
| 1141 sideRect.shiftYEdgeTo(sideRect.maxY() - width); | 1142 sideRect.shiftYEdgeTo(sideRect.maxY() - width); |
| 1142 else if (side == BSLeft) | 1143 else if (side == BSLeft) |
| 1143 sideRect.setWidth(width); | 1144 sideRect.setWidth(width); |
| 1144 else | 1145 else |
| 1145 sideRect.shiftXEdgeTo(sideRect.maxX() - width); | 1146 sideRect.shiftXEdgeTo(sideRect.maxX() - width); |
| 1146 | 1147 |
| 1147 return sideRect; | 1148 return sideRect; |
| 1148 } | 1149 } |
| 1149 | 1150 |
| 1150 enum BorderEdgeFlag { | |
| 1151 TopBorderEdge = 1 << BSTop, | |
| 1152 RightBorderEdge = 1 << BSRight, | |
| 1153 BottomBorderEdge = 1 << BSBottom, | |
| 1154 LeftBorderEdge = 1 << BSLeft, | |
| 1155 AllBorderEdges = TopBorderEdge | BottomBorderEdge | LeftBorderEdge | RightBo
rderEdge | |
| 1156 }; | |
| 1157 | |
| 1158 static inline BorderEdgeFlag edgeFlagForSide(BoxSide side) | 1151 static inline BorderEdgeFlag edgeFlagForSide(BoxSide side) |
| 1159 { | 1152 { |
| 1160 return static_cast<BorderEdgeFlag>(1 << side); | 1153 return static_cast<BorderEdgeFlag>(1 << side); |
| 1161 } | 1154 } |
| 1162 | 1155 |
| 1163 static inline bool includesEdge(BorderEdgeFlags flags, BoxSide side) | 1156 static inline bool includesEdge(BorderEdgeFlags flags, BoxSide side) |
| 1164 { | 1157 { |
| 1165 return flags & edgeFlagForSide(side); | 1158 return flags & edgeFlagForSide(side); |
| 1166 } | 1159 } |
| 1167 | 1160 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 | 1429 |
| 1437 LayoutRect bottomRightRect(boundingRect.location(), LayoutSize(radii.bottomR
ight())); | 1430 LayoutRect bottomRightRect(boundingRect.location(), LayoutSize(radii.bottomR
ight())); |
| 1438 bottomRightRect.setX(boundingRect.maxX() - bottomRightRect.width()); | 1431 bottomRightRect.setX(boundingRect.maxX() - bottomRightRect.width()); |
| 1439 bottomRightRect.setY(boundingRect.maxY() - bottomRightRect.height()); | 1432 bottomRightRect.setY(boundingRect.maxY() - bottomRightRect.height()); |
| 1440 if (clipRect.intersects(bottomRightRect)) | 1433 if (clipRect.intersects(bottomRightRect)) |
| 1441 return false; | 1434 return false; |
| 1442 | 1435 |
| 1443 return true; | 1436 return true; |
| 1444 } | 1437 } |
| 1445 | 1438 |
| 1446 // TODO(fmalita): Border painting is complex enough to warrant a standalone clas
s. Move all related | |
| 1447 // logic out into BoxBorderPainter or such. | |
| 1448 // TODO(fmalita): Move static BoxPainter border methods to anonymous ns and upda
te to use a | |
| 1449 // BoxBorderInfo argument. | |
| 1450 struct BoxBorderInfo { | |
| 1451 STACK_ALLOCATED(); | |
| 1452 public: | |
| 1453 BoxBorderInfo(const ComputedStyle& style, BackgroundBleedAvoidance bleedAvoi
dance, | |
| 1454 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) | |
| 1455 : style(style) | |
| 1456 , bleedAvoidance(bleedAvoidance) | |
| 1457 , includeLogicalLeftEdge(includeLogicalLeftEdge) | |
| 1458 , includeLogicalRightEdge(includeLogicalRightEdge) | |
| 1459 , visibleEdgeCount(0) | |
| 1460 , firstVisibleEdge(0) | |
| 1461 , visibleEdgeSet(0) | |
| 1462 , isUniformStyle(true) | |
| 1463 , isUniformWidth(true) | |
| 1464 , isUniformColor(true) | |
| 1465 , hasAlpha(false) | |
| 1466 { | |
| 1467 | |
| 1468 style.getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRig
htEdge); | |
| 1469 | |
| 1470 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(edges); ++i) { | |
| 1471 const BorderEdge& edge = edges[i]; | |
| 1472 | |
| 1473 if (!edge.shouldRender()) { | |
| 1474 if (edge.presentButInvisible()) { | |
| 1475 isUniformWidth = false; | |
| 1476 isUniformColor = false; | |
| 1477 } | |
| 1478 | |
| 1479 continue; | |
| 1480 } | |
| 1481 | |
| 1482 visibleEdgeCount++; | |
| 1483 visibleEdgeSet |= edgeFlagForSide(static_cast<BoxSide>(i)); | |
| 1484 | |
| 1485 hasAlpha = hasAlpha || edge.color.hasAlpha(); | |
| 1486 | |
| 1487 if (visibleEdgeCount == 1) { | |
| 1488 firstVisibleEdge = i; | |
| 1489 continue; | |
| 1490 } | |
| 1491 | |
| 1492 isUniformStyle = isUniformStyle && (edge.borderStyle() == edges[firs
tVisibleEdge].borderStyle()); | |
| 1493 isUniformWidth = isUniformWidth && (edge.width == edges[firstVisible
Edge].width); | |
| 1494 isUniformColor = isUniformColor && (edge.color == edges[firstVisible
Edge].color); | |
| 1495 } | |
| 1496 } | |
| 1497 | |
| 1498 const ComputedStyle& style; | |
| 1499 const BackgroundBleedAvoidance bleedAvoidance; | |
| 1500 const bool includeLogicalLeftEdge; | |
| 1501 const bool includeLogicalRightEdge; | |
| 1502 | |
| 1503 BorderEdge edges[4]; | |
| 1504 | |
| 1505 unsigned visibleEdgeCount; | |
| 1506 unsigned firstVisibleEdge; | |
| 1507 BorderEdgeFlags visibleEdgeSet; | |
| 1508 | |
| 1509 bool isUniformStyle; | |
| 1510 bool isUniformWidth; | |
| 1511 bool isUniformColor; | |
| 1512 bool hasAlpha; | |
| 1513 }; | |
| 1514 | |
| 1515 LayoutRectOutsets doubleStripeInsets(const BorderEdge edges[], BorderEdge::Doubl
eBorderStripe stripe) | 1439 LayoutRectOutsets doubleStripeInsets(const BorderEdge edges[], BorderEdge::Doubl
eBorderStripe stripe) |
| 1516 { | 1440 { |
| 1517 // Insets are representes as negative outsets. | 1441 // Insets are representes as negative outsets. |
| 1518 return LayoutRectOutsets( | 1442 return LayoutRectOutsets( |
| 1519 -edges[BSTop].getDoubleBorderStripeWidth(stripe), | 1443 -edges[BSTop].getDoubleBorderStripeWidth(stripe), |
| 1520 -edges[BSRight].getDoubleBorderStripeWidth(stripe), | 1444 -edges[BSRight].getDoubleBorderStripeWidth(stripe), |
| 1521 -edges[BSBottom].getDoubleBorderStripeWidth(stripe), | 1445 -edges[BSBottom].getDoubleBorderStripeWidth(stripe), |
| 1522 -edges[BSLeft].getDoubleBorderStripeWidth(stripe)); | 1446 -edges[BSLeft].getDoubleBorderStripeWidth(stripe)); |
| 1523 } | 1447 } |
| 1524 | 1448 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already
applied. | 1616 // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already
applied. |
| 1693 if (!bleedAvoidanceIsClipping(bleedAvoidance)) | 1617 if (!bleedAvoidanceIsClipping(bleedAvoidance)) |
| 1694 graphicsContext->clipRoundedRect(outerBorder); | 1618 graphicsContext->clipRoundedRect(outerBorder); |
| 1695 | 1619 |
| 1696 // For BackgroundBleedBackgroundOverBorder, we're going to draw an opaqu
e background over | 1620 // For BackgroundBleedBackgroundOverBorder, we're going to draw an opaqu
e background over |
| 1697 // the inner rrect - so clipping is not needed (nor desirable due to bac
kdrop bleeding). | 1621 // the inner rrect - so clipping is not needed (nor desirable due to bac
kdrop bleeding). |
| 1698 if (bleedAvoidance != BackgroundBleedBackgroundOverBorder && innerBorder
.isRenderable() && !innerBorder.isEmpty()) | 1622 if (bleedAvoidance != BackgroundBleedBackgroundOverBorder && innerBorder
.isRenderable() && !innerBorder.isEmpty()) |
| 1699 graphicsContext->clipOutRoundedRect(innerBorder); | 1623 graphicsContext->clipOutRoundedRect(innerBorder); |
| 1700 } | 1624 } |
| 1701 | 1625 |
| 1626 if (RuntimeEnabledFeatures::antiAliasBordersEnabled() || RuntimeEnabledFeatu
res::slimmingPaintEnabled()) { |
| 1627 BoxBorderPainter(borderInfo, outerBorder, innerBorder).paint(graphicsCon
text); |
| 1628 return; |
| 1629 } |
| 1630 |
| 1702 // If only one edge visible antialiasing doesn't create seams | 1631 // If only one edge visible antialiasing doesn't create seams |
| 1703 bool antialias = shouldAntialiasLines(graphicsContext) || borderInfo.visible
EdgeCount == 1; | 1632 bool antialias = shouldAntialiasLines(graphicsContext) || borderInfo.visible
EdgeCount == 1; |
| 1704 if (borderInfo.hasAlpha) { | 1633 if (borderInfo.hasAlpha) { |
| 1705 paintTranslucentBorderSides(graphicsContext, style, outerBorder, innerBo
rder, borderInfo.edges, | 1634 paintTranslucentBorderSides(graphicsContext, style, outerBorder, innerBo
rder, borderInfo.edges, |
| 1706 borderInfo.visibleEdgeSet, bleedAvoidance, includeLogicalLeftEdge, inclu
deLogicalRightEdge, antialias); | 1635 borderInfo.visibleEdgeSet, bleedAvoidance, includeLogicalLeftEdge, i
ncludeLogicalRightEdge, antialias); |
| 1707 } else { | 1636 } else { |
| 1708 paintBorderSides(graphicsContext, style, outerBorder, innerBorder, borde
rInfo.edges, | 1637 paintBorderSides(graphicsContext, style, outerBorder, innerBorder, borde
rInfo.edges, |
| 1709 borderInfo.visibleEdgeSet, bleedAvoidance, includeLogicalLeftEdge, inclu
deLogicalRightEdge, antialias); | 1638 borderInfo.visibleEdgeSet, bleedAvoidance, includeLogicalLeftEdge, i
ncludeLogicalRightEdge, antialias); |
| 1710 } | 1639 } |
| 1711 } | 1640 } |
| 1712 | 1641 |
| 1713 static inline bool includesAdjacentEdges(BorderEdgeFlags flags) | 1642 static inline bool includesAdjacentEdges(BorderEdgeFlags flags) |
| 1714 { | 1643 { |
| 1715 // The set includes adjacent edges iff it contains at least one horizontal a
nd one vertical edge. | 1644 // The set includes adjacent edges iff it contains at least one horizontal a
nd one vertical edge. |
| 1716 return (flags & (TopBorderEdge | BottomBorderEdge)) | 1645 return (flags & (TopBorderEdge | BottomBorderEdge)) |
| 1717 && (flags & (LeftBorderEdge | RightBorderEdge)); | 1646 && (flags & (LeftBorderEdge | RightBorderEdge)); |
| 1718 } | 1647 } |
| 1719 | 1648 |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 } | 2047 } |
| 2119 } | 2048 } |
| 2120 | 2049 |
| 2121 void BoxPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, const F
loatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder, BoxSide side,
bool firstEdgeMatches, bool secondEdgeMatches) | 2050 void BoxPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, const F
loatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder, BoxSide side,
bool firstEdgeMatches, bool secondEdgeMatches) |
| 2122 { | 2051 { |
| 2123 FloatPoint quad[4]; | 2052 FloatPoint quad[4]; |
| 2124 | 2053 |
| 2125 const LayoutRect outerRect(outerBorder.rect()); | 2054 const LayoutRect outerRect(outerBorder.rect()); |
| 2126 const LayoutRect innerRect(innerBorder.rect()); | 2055 const LayoutRect innerRect(innerBorder.rect()); |
| 2127 | 2056 |
| 2128 FloatPoint centerPoint(innerRect.location().x().toFloat() + innerRect.width(
).toFloat() / 2, innerRect.location().y().toFloat() + innerRect.height().toFloat
() / 2); | |
| 2129 | |
| 2130 // For each side, create a quad that encompasses all parts of that side that
may draw, | 2057 // For each side, create a quad that encompasses all parts of that side that
may draw, |
| 2131 // including areas inside the innerBorder. | 2058 // including areas inside the innerBorder. |
| 2132 // | 2059 // |
| 2133 // 0----------------3 | 2060 // 0----------------3 |
| 2134 // 0 \ / 0 | 2061 // 0 \ / 0 |
| 2135 // |\ 1----------- 2 /| | 2062 // |\ 1----------- 2 /| |
| 2136 // | 1 1 | | 2063 // | 1 1 | |
| 2137 // | | | | | 2064 // | | | | |
| 2138 // | | | | | 2065 // | | | | |
| 2139 // | 2 2 | | 2066 // | 2 2 | |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2298 | 2225 |
| 2299 FloatPoint secondQuad[4]; | 2226 FloatPoint secondQuad[4]; |
| 2300 secondQuad[0] = quad[0]; | 2227 secondQuad[0] = quad[0]; |
| 2301 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); | 2228 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); |
| 2302 secondQuad[2] = quad[2]; | 2229 secondQuad[2] = quad[2]; |
| 2303 secondQuad[3] = quad[3]; | 2230 secondQuad[3] = quad[3]; |
| 2304 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches); | 2231 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches); |
| 2305 } | 2232 } |
| 2306 | 2233 |
| 2307 } // namespace blink | 2234 } // namespace blink |
| OLD | NEW |