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

Side by Side Diff: Source/core/rendering/RenderBoxModelObject.cpp

Issue 550363004: Factor painting code out of RenderBox into a new class called BoxPainter. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: fix 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderBoxModelObject.h ('k') | Source/core/rendering/RenderFieldset.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBoxModelObject.h ('k') | Source/core/rendering/RenderFieldset.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698