OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "core/rendering/RenderFlowThread.h" | 35 #include "core/rendering/RenderFlowThread.h" |
36 #include "core/rendering/RenderGeometryMap.h" | 36 #include "core/rendering/RenderGeometryMap.h" |
37 #include "core/rendering/RenderInline.h" | 37 #include "core/rendering/RenderInline.h" |
38 #include "core/rendering/RenderLayer.h" | 38 #include "core/rendering/RenderLayer.h" |
39 #include "core/rendering/RenderObjectInlines.h" | 39 #include "core/rendering/RenderObjectInlines.h" |
40 #include "core/rendering/RenderRegion.h" | 40 #include "core/rendering/RenderRegion.h" |
41 #include "core/rendering/RenderTextFragment.h" | 41 #include "core/rendering/RenderTextFragment.h" |
42 #include "core/rendering/RenderView.h" | 42 #include "core/rendering/RenderView.h" |
43 #include "core/rendering/compositing/CompositedLayerMapping.h" | 43 #include "core/rendering/compositing/CompositedLayerMapping.h" |
44 #include "core/rendering/compositing/RenderLayerCompositor.h" | 44 #include "core/rendering/compositing/RenderLayerCompositor.h" |
| 45 #include "core/rendering/style/BorderEdge.h" |
45 #include "core/rendering/style/ShadowList.h" | 46 #include "core/rendering/style/ShadowList.h" |
46 #include "platform/LengthFunctions.h" | 47 #include "platform/LengthFunctions.h" |
47 #include "platform/geometry/TransformState.h" | 48 #include "platform/geometry/TransformState.h" |
48 #include "platform/graphics/DrawLooperBuilder.h" | 49 #include "platform/graphics/DrawLooperBuilder.h" |
49 #include "platform/graphics/GraphicsContextStateSaver.h" | 50 #include "platform/graphics/GraphicsContextStateSaver.h" |
50 #include "platform/graphics/Path.h" | 51 #include "platform/graphics/Path.h" |
51 #include "wtf/CurrentTime.h" | 52 #include "wtf/CurrentTime.h" |
52 | 53 |
53 namespace blink { | 54 namespace blink { |
54 | 55 |
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 | 1225 |
1225 graphicsContext->drawTiledImage(image.get(), | 1226 graphicsContext->drawTiledImage(image.get(), |
1226 IntRect(borderImageRect.x() + leftWidth, borderImageRect.y() + topWi
dth, destinationWidth, destinationHeight), | 1227 IntRect(borderImageRect.x() + leftWidth, borderImageRect.y() + topWi
dth, destinationWidth, destinationHeight), |
1227 IntRect(leftSlice, topSlice, sourceWidth, sourceHeight), | 1228 IntRect(leftSlice, topSlice, sourceWidth, sourceHeight), |
1228 middleScaleFactor, (Image::TileRule)hRule, (Image::TileRule)vRule, o
p); | 1229 middleScaleFactor, (Image::TileRule)hRule, (Image::TileRule)vRule, o
p); |
1229 } | 1230 } |
1230 | 1231 |
1231 return true; | 1232 return true; |
1232 } | 1233 } |
1233 | 1234 |
1234 class BorderEdge { | |
1235 public: | |
1236 BorderEdge(int edgeWidth, const Color& edgeColor, EBorderStyle edgeStyle, bo
ol edgeIsTransparent, bool edgeIsPresent = true) | |
1237 : width(edgeWidth) | |
1238 , color(edgeColor) | |
1239 , style(edgeStyle) | |
1240 , isTransparent(edgeIsTransparent) | |
1241 , isPresent(edgeIsPresent) | |
1242 { | |
1243 if (style == DOUBLE && edgeWidth < 3) | |
1244 style = SOLID; | |
1245 } | |
1246 | |
1247 BorderEdge() | |
1248 : width(0) | |
1249 , style(BHIDDEN) | |
1250 , isTransparent(false) | |
1251 , isPresent(false) | |
1252 { | |
1253 } | |
1254 | |
1255 bool hasVisibleColorAndStyle() const { return style > BHIDDEN && !isTranspar
ent; } | |
1256 bool shouldRender() const { return isPresent && width && hasVisibleColorAndS
tyle(); } | |
1257 bool presentButInvisible() const { return usedWidth() && !hasVisibleColorAnd
Style(); } | |
1258 bool obscuresBackgroundEdge(float scale) const | |
1259 { | |
1260 if (!isPresent || isTransparent || (width * scale) < 2 || color.hasAlpha
() || style == BHIDDEN) | |
1261 return false; | |
1262 | |
1263 if (style == DOTTED || style == DASHED) | |
1264 return false; | |
1265 | |
1266 if (style == DOUBLE) | |
1267 return width >= 5 * scale; // The outer band needs to be >= 2px wide
at unit scale. | |
1268 | |
1269 return true; | |
1270 } | |
1271 bool obscuresBackground() const | |
1272 { | |
1273 if (!isPresent || isTransparent || color.hasAlpha() || style == BHIDDEN) | |
1274 return false; | |
1275 | |
1276 if (style == DOTTED || style == DASHED || style == DOUBLE) | |
1277 return false; | |
1278 | |
1279 return true; | |
1280 } | |
1281 | |
1282 int usedWidth() const { return isPresent ? width : 0; } | |
1283 | |
1284 void getDoubleBorderStripeWidths(int& outerWidth, int& innerWidth) const | |
1285 { | |
1286 int fullWidth = usedWidth(); | |
1287 outerWidth = fullWidth / 3; | |
1288 innerWidth = fullWidth * 2 / 3; | |
1289 | |
1290 // We need certain integer rounding results | |
1291 if (fullWidth % 3 == 2) | |
1292 outerWidth += 1; | |
1293 | |
1294 if (fullWidth % 3 == 1) | |
1295 innerWidth += 1; | |
1296 } | |
1297 | |
1298 int width; | |
1299 Color color; | |
1300 EBorderStyle style; | |
1301 bool isTransparent; | |
1302 bool isPresent; | |
1303 }; | |
1304 | |
1305 static bool allCornersClippedOut(const RoundedRect& border, const LayoutRect& cl
ipRect) | 1235 static bool allCornersClippedOut(const RoundedRect& border, const LayoutRect& cl
ipRect) |
1306 { | 1236 { |
1307 LayoutRect boundingRect = border.rect(); | 1237 LayoutRect boundingRect = border.rect(); |
1308 if (clipRect.contains(boundingRect)) | 1238 if (clipRect.contains(boundingRect)) |
1309 return false; | 1239 return false; |
1310 | 1240 |
1311 RoundedRect::Radii radii = border.radii(); | 1241 RoundedRect::Radii radii = border.radii(); |
1312 | 1242 |
1313 LayoutRect topLeftRect(boundingRect.location(), radii.topLeft()); | 1243 LayoutRect topLeftRect(boundingRect.location(), radii.topLeft()); |
1314 if (clipRect.intersects(topLeftRect)) | 1244 if (clipRect.intersects(topLeftRect)) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 } | 1287 } |
1358 | 1288 |
1359 static inline bool includesAdjacentEdges(BorderEdgeFlags flags) | 1289 static inline bool includesAdjacentEdges(BorderEdgeFlags flags) |
1360 { | 1290 { |
1361 return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | Right
BorderEdge) | 1291 return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | Right
BorderEdge) |
1362 || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge |
BottomBorderEdge) | 1292 || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge |
BottomBorderEdge) |
1363 || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge |
LeftBorderEdge) | 1293 || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge |
LeftBorderEdge) |
1364 || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBo
rderEdge); | 1294 || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBo
rderEdge); |
1365 } | 1295 } |
1366 | 1296 |
1367 inline bool edgesShareColor(const BorderEdge& firstEdge, const BorderEdge& secon
dEdge) | |
1368 { | |
1369 return firstEdge.color == secondEdge.color; | |
1370 } | |
1371 | |
1372 inline bool styleRequiresClipPolygon(EBorderStyle style) | 1297 inline bool styleRequiresClipPolygon(EBorderStyle style) |
1373 { | 1298 { |
1374 return style == DOTTED || style == DASHED; // These are drawn with a stroke,
so we have to clip to get corner miters. | 1299 return style == DOTTED || style == DASHED; // These are drawn with a stroke,
so we have to clip to get corner miters. |
1375 } | 1300 } |
1376 | 1301 |
1377 static bool borderStyleFillsBorderArea(EBorderStyle style) | 1302 static bool borderStyleFillsBorderArea(EBorderStyle style) |
1378 { | 1303 { |
1379 return !(style == DOTTED || style == DASHED || style == DOUBLE); | 1304 return !(style == DOTTED || style == DASHED || style == DOUBLE); |
1380 } | 1305 } |
1381 | 1306 |
(...skipping 20 matching lines...) Expand all Loading... |
1402 return flags == topRightFlags || flags == bottomLeftFlags; | 1327 return flags == topRightFlags || flags == bottomLeftFlags; |
1403 } | 1328 } |
1404 return false; | 1329 return false; |
1405 } | 1330 } |
1406 | 1331 |
1407 static inline bool colorsMatchAtCorner(BoxSide side, BoxSide adjacentSide, const
BorderEdge edges[]) | 1332 static inline bool colorsMatchAtCorner(BoxSide side, BoxSide adjacentSide, const
BorderEdge edges[]) |
1408 { | 1333 { |
1409 if (edges[side].shouldRender() != edges[adjacentSide].shouldRender()) | 1334 if (edges[side].shouldRender() != edges[adjacentSide].shouldRender()) |
1410 return false; | 1335 return false; |
1411 | 1336 |
1412 if (!edgesShareColor(edges[side], edges[adjacentSide])) | 1337 if (!edges[side].sharesColorWith(edges[adjacentSide])) |
1413 return false; | 1338 return false; |
1414 | 1339 |
1415 return !borderStyleHasUnmatchedColorsAtCorner(edges[side].style, side, adjac
entSide); | 1340 return !borderStyleHasUnmatchedColorsAtCorner(edges[side].borderStyle(), sid
e, adjacentSide); |
1416 } | 1341 } |
1417 | 1342 |
1418 | 1343 |
1419 static inline bool colorNeedsAntiAliasAtCorner(BoxSide side, BoxSide adjacentSid
e, const BorderEdge edges[]) | 1344 static inline bool colorNeedsAntiAliasAtCorner(BoxSide side, BoxSide adjacentSid
e, const BorderEdge edges[]) |
1420 { | 1345 { |
1421 if (!edges[side].color.hasAlpha()) | 1346 if (!edges[side].color.hasAlpha()) |
1422 return false; | 1347 return false; |
1423 | 1348 |
1424 if (edges[side].shouldRender() != edges[adjacentSide].shouldRender()) | 1349 if (edges[side].shouldRender() != edges[adjacentSide].shouldRender()) |
1425 return false; | 1350 return false; |
1426 | 1351 |
1427 if (!edgesShareColor(edges[side], edges[adjacentSide])) | 1352 if (!edges[side].sharesColorWith(edges[adjacentSide])) |
1428 return true; | 1353 return true; |
1429 | 1354 |
1430 return borderStyleHasUnmatchedColorsAtCorner(edges[side].style, side, adjace
ntSide); | 1355 return borderStyleHasUnmatchedColorsAtCorner(edges[side].borderStyle(), side
, adjacentSide); |
1431 } | 1356 } |
1432 | 1357 |
1433 // This assumes that we draw in order: top, bottom, left, right. | 1358 // This assumes that we draw in order: top, bottom, left, right. |
1434 static inline bool willBeOverdrawn(BoxSide side, BoxSide adjacentSide, const Bor
derEdge edges[]) | 1359 static inline bool willBeOverdrawn(BoxSide side, BoxSide adjacentSide, const Bor
derEdge edges[]) |
1435 { | 1360 { |
1436 switch (side) { | 1361 switch (side) { |
1437 case BSTop: | 1362 case BSTop: |
1438 case BSBottom: | 1363 case BSBottom: |
1439 if (edges[adjacentSide].presentButInvisible()) | 1364 if (edges[adjacentSide].presentButInvisible()) |
1440 return false; | 1365 return false; |
1441 | 1366 |
1442 if (!edgesShareColor(edges[side], edges[adjacentSide]) && edges[adjacent
Side].color.hasAlpha()) | 1367 if (!edges[side].sharesColorWith(edges[adjacentSide]) && edges[adjacentS
ide].color.hasAlpha()) |
1443 return false; | 1368 return false; |
1444 | 1369 |
1445 if (!borderStyleFillsBorderArea(edges[adjacentSide].style)) | 1370 if (!borderStyleFillsBorderArea(edges[adjacentSide].borderStyle())) |
1446 return false; | 1371 return false; |
1447 | 1372 |
1448 return true; | 1373 return true; |
1449 | 1374 |
1450 case BSLeft: | 1375 case BSLeft: |
1451 case BSRight: | 1376 case BSRight: |
1452 // These draw last, so are never overdrawn. | 1377 // These draw last, so are never overdrawn. |
1453 return false; | 1378 return false; |
1454 } | 1379 } |
1455 return false; | 1380 return false; |
(...skipping 14 matching lines...) Expand all Loading... |
1470 } | 1395 } |
1471 | 1396 |
1472 static bool joinRequiresMitre(BoxSide side, BoxSide adjacentSide, const BorderEd
ge edges[], bool allowOverdraw) | 1397 static bool joinRequiresMitre(BoxSide side, BoxSide adjacentSide, const BorderEd
ge edges[], bool allowOverdraw) |
1473 { | 1398 { |
1474 if ((edges[side].isTransparent && edges[adjacentSide].isTransparent) || !edg
es[adjacentSide].isPresent) | 1399 if ((edges[side].isTransparent && edges[adjacentSide].isTransparent) || !edg
es[adjacentSide].isPresent) |
1475 return false; | 1400 return false; |
1476 | 1401 |
1477 if (allowOverdraw && willBeOverdrawn(side, adjacentSide, edges)) | 1402 if (allowOverdraw && willBeOverdrawn(side, adjacentSide, edges)) |
1478 return false; | 1403 return false; |
1479 | 1404 |
1480 if (!edgesShareColor(edges[side], edges[adjacentSide])) | 1405 if (!edges[side].sharesColorWith(edges[adjacentSide])) |
1481 return true; | 1406 return true; |
1482 | 1407 |
1483 if (borderStylesRequireMitre(side, adjacentSide, edges[side].style, edges[ad
jacentSide].style)) | 1408 if (borderStylesRequireMitre(side, adjacentSide, edges[side].borderStyle(),
edges[adjacentSide].borderStyle())) |
1484 return true; | 1409 return true; |
1485 | 1410 |
1486 return false; | 1411 return false; |
1487 } | 1412 } |
1488 | 1413 |
1489 void RenderBoxModelObject::paintOneBorderSide(GraphicsContext* graphicsContext,
const RenderStyle* style, const RoundedRect& outerBorder, const RoundedRect& inn
erBorder, | 1414 void RenderBoxModelObject::paintOneBorderSide(GraphicsContext* graphicsContext,
const RenderStyle* style, const RoundedRect& outerBorder, const RoundedRect& inn
erBorder, |
1490 const IntRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjace
ntSide2, const BorderEdge edges[], const Path* path, | 1415 const IntRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjace
ntSide2, const BorderEdge edges[], const Path* path, |
1491 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool i
ncludeLogicalRightEdge, bool antialias, const Color* overrideColor) | 1416 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool i
ncludeLogicalRightEdge, bool antialias, const Color* overrideColor) |
1492 { | 1417 { |
1493 const BorderEdge& edgeToRender = edges[side]; | 1418 const BorderEdge& edgeToRender = edges[side]; |
(...skipping 10 matching lines...) Expand all Loading... |
1504 const Color& colorToPaint = overrideColor ? *overrideColor : edgeToRender.co
lor; | 1429 const Color& colorToPaint = overrideColor ? *overrideColor : edgeToRender.co
lor; |
1505 | 1430 |
1506 if (path) { | 1431 if (path) { |
1507 GraphicsContextStateSaver stateSaver(*graphicsContext); | 1432 GraphicsContextStateSaver stateSaver(*graphicsContext); |
1508 if (innerBorder.isRenderable()) | 1433 if (innerBorder.isRenderable()) |
1509 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid
e, adjacentSide1StylesMatch, adjacentSide2StylesMatch); | 1434 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid
e, adjacentSide1StylesMatch, adjacentSide2StylesMatch); |
1510 else | 1435 else |
1511 clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, inne
rBorder, side, edges); | 1436 clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, inne
rBorder, side, edges); |
1512 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi
dth), adjacentEdge2.width); | 1437 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi
dth), adjacentEdge2.width); |
1513 drawBoxSideFromPath(graphicsContext, outerBorder.rect(), *path, edges, e
dgeToRender.width, thickness, side, style, | 1438 drawBoxSideFromPath(graphicsContext, outerBorder.rect(), *path, edges, e
dgeToRender.width, thickness, side, style, |
1514 colorToPaint, edgeToRender.style, bleedAvoidance, includeLogicalLeft
Edge, includeLogicalRightEdge); | 1439 colorToPaint, edgeToRender.borderStyle(), bleedAvoidance, includeLog
icalLeftEdge, includeLogicalRightEdge); |
1515 } else { | 1440 } else { |
1516 bool clipForStyle = styleRequiresClipPolygon(edgeToRender.style) && (mit
reAdjacentSide1 || mitreAdjacentSide2); | 1441 bool clipForStyle = styleRequiresClipPolygon(edgeToRender.borderStyle())
&& (mitreAdjacentSide1 || mitreAdjacentSide2); |
1517 bool clipAdjacentSide1 = colorNeedsAntiAliasAtCorner(side, adjacentSide1
, edges) && mitreAdjacentSide1; | 1442 bool clipAdjacentSide1 = colorNeedsAntiAliasAtCorner(side, adjacentSide1
, edges) && mitreAdjacentSide1; |
1518 bool clipAdjacentSide2 = colorNeedsAntiAliasAtCorner(side, adjacentSide2
, edges) && mitreAdjacentSide2; | 1443 bool clipAdjacentSide2 = colorNeedsAntiAliasAtCorner(side, adjacentSide2
, edges) && mitreAdjacentSide2; |
1519 bool shouldClip = clipForStyle || clipAdjacentSide1 || clipAdjacentSide2
; | 1444 bool shouldClip = clipForStyle || clipAdjacentSide1 || clipAdjacentSide2
; |
1520 | 1445 |
1521 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip); | 1446 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip); |
1522 if (shouldClip) { | 1447 if (shouldClip) { |
1523 bool aliasAdjacentSide1 = clipAdjacentSide1 || (clipForStyle && mitr
eAdjacentSide1); | 1448 bool aliasAdjacentSide1 = clipAdjacentSide1 || (clipForStyle && mitr
eAdjacentSide1); |
1524 bool aliasAdjacentSide2 = clipAdjacentSide2 || (clipForStyle && mitr
eAdjacentSide2); | 1449 bool aliasAdjacentSide2 = clipAdjacentSide2 || (clipForStyle && mitr
eAdjacentSide2); |
1525 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid
e, !aliasAdjacentSide1, !aliasAdjacentSide2); | 1450 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid
e, !aliasAdjacentSide1, !aliasAdjacentSide2); |
1526 // Since we clipped, no need to draw with a mitre. | 1451 // Since we clipped, no need to draw with a mitre. |
1527 mitreAdjacentSide1 = false; | 1452 mitreAdjacentSide1 = false; |
1528 mitreAdjacentSide2 = false; | 1453 mitreAdjacentSide2 = false; |
1529 } | 1454 } |
1530 | 1455 |
1531 drawLineForBoxSide(graphicsContext, sideRect.x(), sideRect.y(), sideRect
.maxX(), sideRect.maxY(), side, colorToPaint, edgeToRender.style, | 1456 drawLineForBoxSide(graphicsContext, sideRect.x(), sideRect.y(), sideRect
.maxX(), sideRect.maxY(), side, colorToPaint, edgeToRender.borderStyle(), |
1532 mitreAdjacentSide1 ? adjacentEdge1.width : 0, mitreAdjacentSide2
? adjacentEdge2.width : 0, antialias); | 1457 mitreAdjacentSide1 ? adjacentEdge1.width : 0, mitreAdjacentSide2
? adjacentEdge2.width : 0, antialias); |
1533 } | 1458 } |
1534 } | 1459 } |
1535 | 1460 |
1536 static IntRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdg
e edges[], int side) | 1461 static IntRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdg
e edges[], int side) |
1537 { | 1462 { |
1538 IntRect sideRect = outerBorder.rect(); | 1463 IntRect sideRect = outerBorder.rect(); |
1539 int width = edges[side].width; | 1464 int width = edges[side].width; |
1540 | 1465 |
1541 if (side == BSTop) | 1466 if (side == BSTop) |
(...skipping 20 matching lines...) Expand all Loading... |
1562 | 1487 |
1563 // The inner border adjustment for bleed avoidance mode BackgroundBleedBackg
roundOverBorder | 1488 // The inner border adjustment for bleed avoidance mode BackgroundBleedBackg
roundOverBorder |
1564 // is only applied to sideRect, which is okay since BackgroundBleedBackgroun
dOverBorder | 1489 // is only applied to sideRect, which is okay since BackgroundBleedBackgroun
dOverBorder |
1565 // is only to be used for solid borders and the shape of the border painted
by drawBoxSideFromPath | 1490 // is only to be used for solid borders and the shape of the border painted
by drawBoxSideFromPath |
1566 // only depends on sideRect when painting solid borders. | 1491 // only depends on sideRect when painting solid borders. |
1567 | 1492 |
1568 if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) { | 1493 if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) { |
1569 IntRect sideRect = outerBorder.rect(); | 1494 IntRect sideRect = outerBorder.rect(); |
1570 sideRect.setHeight(edges[BSTop].width + innerBorderAdjustment.y()); | 1495 sideRect.setHeight(edges[BSTop].width + innerBorderAdjustment.y()); |
1571 | 1496 |
1572 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].st
yle) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorder.radii(
).topRight())); | 1497 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].bo
rderStyle()) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorde
r.radii().topRight())); |
1573 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoidance
, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); | 1498 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoidance
, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); |
1574 } | 1499 } |
1575 | 1500 |
1576 if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) { | 1501 if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) { |
1577 IntRect sideRect = outerBorder.rect(); | 1502 IntRect sideRect = outerBorder.rect(); |
1578 sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width - innerBor
derAdjustment.y()); | 1503 sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width - innerBor
derAdjustment.y()); |
1579 | 1504 |
1580 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom]
.style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.
radii().bottomRight())); | 1505 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom]
.borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), inne
rBorder.radii().bottomRight())); |
1581 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoida
nce, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); | 1506 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoida
nce, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); |
1582 } | 1507 } |
1583 | 1508 |
1584 if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) { | 1509 if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) { |
1585 IntRect sideRect = outerBorder.rect(); | 1510 IntRect sideRect = outerBorder.rect(); |
1586 sideRect.setWidth(edges[BSLeft].width + innerBorderAdjustment.x()); | 1511 sideRect.setWidth(edges[BSLeft].width + innerBorderAdjustment.x()); |
1587 | 1512 |
1588 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].s
tyle) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.ra
dii().topLeft())); | 1513 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].b
orderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerB
order.radii().topLeft())); |
1589 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvoidanc
e, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); | 1514 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvoidanc
e, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); |
1590 } | 1515 } |
1591 | 1516 |
1592 if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) { | 1517 if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) { |
1593 IntRect sideRect = outerBorder.rect(); | 1518 IntRect sideRect = outerBorder.rect(); |
1594 sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width - innerBord
erAdjustment.x()); | 1519 sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width - innerBord
erAdjustment.x()); |
1595 | 1520 |
1596 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight].
style) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), innerBorder.
radii().topRight())); | 1521 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight].
borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), inne
rBorder.radii().topRight())); |
1597 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvoidan
ce, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); | 1522 paintOneBorderSide(graphicsContext, style, outerBorder, innerBorder, sid
eRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvoidan
ce, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor); |
1598 } | 1523 } |
1599 } | 1524 } |
1600 | 1525 |
1601 void RenderBoxModelObject::paintTranslucentBorderSides(GraphicsContext* graphics
Context, const RenderStyle* style, const RoundedRect& outerBorder, const Rounded
Rect& innerBorder, const IntPoint& innerBorderAdjustment, | 1526 void RenderBoxModelObject::paintTranslucentBorderSides(GraphicsContext* graphics
Context, const RenderStyle* style, const RoundedRect& outerBorder, const Rounded
Rect& innerBorder, const IntPoint& innerBorderAdjustment, |
1602 const BorderEdge edges[], BorderEdgeFlags edgesToDraw, BackgroundBleedAvoida
nce bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, b
ool antialias) | 1527 const BorderEdge edges[], BorderEdgeFlags edgesToDraw, BackgroundBleedAvoida
nce bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, b
ool antialias) |
1603 { | 1528 { |
1604 // willBeOverdrawn assumes that we draw in order: top, bottom, left, right. | 1529 // willBeOverdrawn assumes that we draw in order: top, bottom, left, right. |
1605 // This is different from BoxSide enum order. | 1530 // This is different from BoxSide enum order. |
1606 static const BoxSide paintOrder[] = { BSTop, BSBottom, BSLeft, BSRight }; | 1531 static const BoxSide paintOrder[] = { BSTop, BSBottom, BSLeft, BSRight }; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 | 1568 |
1644 void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
rect, const RenderStyle* style, | 1569 void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
rect, const RenderStyle* style, |
1645 BackgroundBleedAvoidance bleedAvoidance,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) | 1570 BackgroundBleedAvoidance bleedAvoidance,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) |
1646 { | 1571 { |
1647 GraphicsContext* graphicsContext = info.context; | 1572 GraphicsContext* graphicsContext = info.context; |
1648 // border-image is not affected by border-radius. | 1573 // border-image is not affected by border-radius. |
1649 if (paintNinePieceImage(graphicsContext, rect, style, style->borderImage())) | 1574 if (paintNinePieceImage(graphicsContext, rect, style, style->borderImage())) |
1650 return; | 1575 return; |
1651 | 1576 |
1652 BorderEdge edges[4]; | 1577 BorderEdge edges[4]; |
1653 getBorderEdgeInfo(edges, style, includeLogicalLeftEdge, includeLogicalRightE
dge); | 1578 style->getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightE
dge); |
1654 RoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogicalLef
tEdge, includeLogicalRightEdge); | 1579 RoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogicalLef
tEdge, includeLogicalRightEdge); |
1655 RoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRectAdj
ustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogicalLef
tEdge, includeLogicalRightEdge); | 1580 RoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRectAdj
ustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogicalLef
tEdge, includeLogicalRightEdge); |
1656 | 1581 |
1657 if (outerBorder.rect().isEmpty()) | 1582 if (outerBorder.rect().isEmpty()) |
1658 return; | 1583 return; |
1659 | 1584 |
1660 bool haveAlphaColor = false; | 1585 bool haveAlphaColor = false; |
1661 bool haveAllSolidEdges = true; | 1586 bool haveAllSolidEdges = true; |
1662 bool haveAllDoubleEdges = true; | 1587 bool haveAllDoubleEdges = true; |
1663 int numEdgesVisible = 4; | 1588 int numEdgesVisible = 4; |
(...skipping 25 matching lines...) Expand all Loading... |
1689 } else { | 1614 } else { |
1690 if (currEdge.color != edges[firstVisibleEdge].color) | 1615 if (currEdge.color != edges[firstVisibleEdge].color) |
1691 allEdgesShareColor = false; | 1616 allEdgesShareColor = false; |
1692 if (currEdge.width != edges[firstVisibleEdge].width) | 1617 if (currEdge.width != edges[firstVisibleEdge].width) |
1693 allEdgesShareWidth = false; | 1618 allEdgesShareWidth = false; |
1694 } | 1619 } |
1695 | 1620 |
1696 if (currEdge.color.hasAlpha()) | 1621 if (currEdge.color.hasAlpha()) |
1697 haveAlphaColor = true; | 1622 haveAlphaColor = true; |
1698 | 1623 |
1699 if (currEdge.style != SOLID) | 1624 if (currEdge.borderStyle() != SOLID) |
1700 haveAllSolidEdges = false; | 1625 haveAllSolidEdges = false; |
1701 | 1626 |
1702 if (currEdge.style != DOUBLE) | 1627 if (currEdge.borderStyle() != DOUBLE) |
1703 haveAllDoubleEdges = false; | 1628 haveAllDoubleEdges = false; |
1704 } | 1629 } |
1705 | 1630 |
1706 // If no corner intersects the clip region, we can pretend outerBorder is | 1631 // If no corner intersects the clip region, we can pretend outerBorder is |
1707 // rectangular to improve performance. | 1632 // rectangular to improve performance. |
1708 if (haveAllSolidEdges && outerBorder.isRounded() && allCornersClippedOut(out
erBorder, info.rect)) | 1633 if (haveAllSolidEdges && outerBorder.isRounded() && allCornersClippedOut(out
erBorder, info.rect)) |
1709 outerBorder.setRadii(RoundedRect::Radii()); | 1634 outerBorder.setRadii(RoundedRect::Radii()); |
1710 | 1635 |
1711 // isRenderable() check avoids issue described in https://bugs.webkit.org/sh
ow_bug.cgi?id=38787 | 1636 // isRenderable() check avoids issue described in https://bugs.webkit.org/sh
ow_bug.cgi?id=38787 |
1712 if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && inner
Border.isRenderable()) { | 1637 if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && inner
Border.isRenderable()) { |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2258 newRect.move(newRect.width() - maxRadii, 0); | 2183 newRect.move(newRect.width() - maxRadii, 0); |
2259 newRect.setWidth(maxRadii); | 2184 newRect.setWidth(maxRadii); |
2260 } | 2185 } |
2261 break; | 2186 break; |
2262 } | 2187 } |
2263 | 2188 |
2264 return RoundedRect(newRect, newRadii); | 2189 return RoundedRect(newRect, newRadii); |
2265 } | 2190 } |
2266 | 2191 |
2267 void RenderBoxModelObject::clipBorderSideForComplexInnerPath(GraphicsContext* gr
aphicsContext, const RoundedRect& outerBorder, const RoundedRect& innerBorder, | 2192 void RenderBoxModelObject::clipBorderSideForComplexInnerPath(GraphicsContext* gr
aphicsContext, const RoundedRect& outerBorder, const RoundedRect& innerBorder, |
2268 BoxSide side, const class BorderEdge edges[]) | 2193 BoxSide side, const BorderEdge edges[]) |
2269 { | 2194 { |
2270 graphicsContext->clip(calculateSideRectIncludingInner(outerBorder, edges, si
de)); | 2195 graphicsContext->clip(calculateSideRectIncludingInner(outerBorder, edges, si
de)); |
2271 RoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(innerBorder, si
de); | 2196 RoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(innerBorder, si
de); |
2272 if (!adjustedInnerRect.isEmpty()) | 2197 if (!adjustedInnerRect.isEmpty()) |
2273 graphicsContext->clipOutRoundedRect(adjustedInnerRect); | 2198 graphicsContext->clipOutRoundedRect(adjustedInnerRect); |
2274 } | 2199 } |
2275 | 2200 |
2276 void RenderBoxModelObject::getBorderEdgeInfo(BorderEdge edges[], const RenderSty
le* style, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const | |
2277 { | |
2278 bool horizontal = style->isHorizontalWritingMode(); | |
2279 | |
2280 edges[BSTop] = BorderEdge(style->borderTopWidth(), | |
2281 resolveColor(style, CSSPropertyBorderTopColor), | |
2282 style->borderTopStyle(), | |
2283 style->borderTopIsTransparent(), | |
2284 horizontal || includeLogicalLeftEdge); | |
2285 | |
2286 edges[BSRight] = BorderEdge(style->borderRightWidth(), | |
2287 resolveColor(style, CSSPropertyBorderRightColor), | |
2288 style->borderRightStyle(), | |
2289 style->borderRightIsTransparent(), | |
2290 !horizontal || includeLogicalRightEdge); | |
2291 | |
2292 edges[BSBottom] = BorderEdge(style->borderBottomWidth(), | |
2293 resolveColor(style, CSSPropertyBorderBottomColor), | |
2294 style->borderBottomStyle(), | |
2295 style->borderBottomIsTransparent(), | |
2296 horizontal || includeLogicalRightEdge); | |
2297 | |
2298 edges[BSLeft] = BorderEdge(style->borderLeftWidth(), | |
2299 resolveColor(style, CSSPropertyBorderLeftColor), | |
2300 style->borderLeftStyle(), | |
2301 style->borderLeftIsTransparent(), | |
2302 !horizontal || includeLogicalLeftEdge); | |
2303 } | |
2304 | |
2305 bool RenderBoxModelObject::borderObscuresBackgroundEdge(const FloatSize& context
Scale) const | |
2306 { | |
2307 BorderEdge edges[4]; | |
2308 getBorderEdgeInfo(edges, style()); | |
2309 | |
2310 for (int i = BSTop; i <= BSLeft; ++i) { | |
2311 const BorderEdge& currEdge = edges[i]; | |
2312 // FIXME: for vertical text | |
2313 float axisScale = (i == BSTop || i == BSBottom) ? contextScale.height()
: contextScale.width(); | |
2314 if (!currEdge.obscuresBackgroundEdge(axisScale)) | |
2315 return false; | |
2316 } | |
2317 | |
2318 return true; | |
2319 } | |
2320 | |
2321 bool RenderBoxModelObject::borderObscuresBackground() const | |
2322 { | |
2323 if (!style()->hasBorder()) | |
2324 return false; | |
2325 | |
2326 // Bail if we have any border-image for now. We could look at the image alph
a to improve this. | |
2327 if (style()->borderImage().image()) | |
2328 return false; | |
2329 | |
2330 BorderEdge edges[4]; | |
2331 getBorderEdgeInfo(edges, style()); | |
2332 | |
2333 for (int i = BSTop; i <= BSLeft; ++i) { | |
2334 const BorderEdge& currEdge = edges[i]; | |
2335 if (!currEdge.obscuresBackground()) | |
2336 return false; | |
2337 } | |
2338 | |
2339 return true; | |
2340 } | |
2341 | |
2342 bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedA
voidance bleedAvoidance, InlineFlowBox* inlineFlowBox) const | 2201 bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedA
voidance bleedAvoidance, InlineFlowBox* inlineFlowBox) const |
2343 { | 2202 { |
2344 if (bleedAvoidance != BackgroundBleedNone) | 2203 if (bleedAvoidance != BackgroundBleedNone) |
2345 return false; | 2204 return false; |
2346 | 2205 |
2347 if (style()->hasAppearance()) | 2206 if (style()->hasAppearance()) |
2348 return false; | 2207 return false; |
2349 | 2208 |
2350 const ShadowList* shadowList = style()->boxShadow(); | 2209 const ShadowList* shadowList = style()->boxShadow(); |
2351 if (!shadowList) | 2210 if (!shadowList) |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2745 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 2604 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
2746 for (RenderObject* child = startChild; child && child != endChild; ) { | 2605 for (RenderObject* child = startChild; child && child != endChild; ) { |
2747 // Save our next sibling as moveChildTo will clear it. | 2606 // Save our next sibling as moveChildTo will clear it. |
2748 RenderObject* nextSibling = child->nextSibling(); | 2607 RenderObject* nextSibling = child->nextSibling(); |
2749 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 2608 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
2750 child = nextSibling; | 2609 child = nextSibling; |
2751 } | 2610 } |
2752 } | 2611 } |
2753 | 2612 |
2754 } // namespace blink | 2613 } // namespace blink |
OLD | NEW |