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

Side by Side Diff: Source/core/paint/BoxPainter.cpp

Issue 815933006: Change all uses of the RoundedRect class to use FloatRoundedRect instead. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 12 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/paint/BoxPainter.h ('k') | Source/core/paint/LayerClipRecorder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 BoxDecorationData boxDecorationData(*style, m_renderBox.canRenderBorderImage (), m_renderBox.backgroundHasOpaqueTopLayer(), m_renderBox.backgroundShouldAlway sBeClipped(), paintInfo.context); 77 BoxDecorationData boxDecorationData(*style, m_renderBox.canRenderBorderImage (), m_renderBox.backgroundHasOpaqueTopLayer(), m_renderBox.backgroundShouldAlway sBeClipped(), paintInfo.context);
78 78
79 // FIXME: Should eventually give the theme control over whether the box shad ow should paint, since controls could have 79 // FIXME: Should eventually give the theme control over whether the box shad ow should paint, since controls could have
80 // custom shadows of their own. 80 // custom shadows of their own.
81 if (!m_renderBox.boxShadowShouldBeAppliedToBackground(boxDecorationData.blee dAvoidance())) 81 if (!m_renderBox.boxShadowShouldBeAppliedToBackground(boxDecorationData.blee dAvoidance()))
82 paintBoxShadow(paintInfo, paintRect, style, Normal); 82 paintBoxShadow(paintInfo, paintRect, style, Normal);
83 83
84 GraphicsContextStateSaver stateSaver(*paintInfo.context, false); 84 GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
85 if (boxDecorationData.bleedAvoidance() == BackgroundBleedClipBackground) { 85 if (boxDecorationData.bleedAvoidance() == BackgroundBleedClipBackground) {
86 stateSaver.save(); 86 stateSaver.save();
87 RoundedRect border = style->getRoundedBorderFor(paintRect); 87 FloatRoundedRect border = style->getRoundedBorderFor(paintRect);
88 paintInfo.context->clipRoundedRect(border); 88 paintInfo.context->clipRoundedRect(border);
89 } 89 }
90 90
91 // If we have a native theme appearance, paint that before painting our back ground. 91 // If we have a native theme appearance, paint that before painting our back ground.
92 // The theme will tell us whether or not we should also paint the CSS backgr ound. 92 // The theme will tell us whether or not we should also paint the CSS backgr ound.
93 IntRect snappedPaintRect(pixelSnappedIntRect(paintRect)); 93 IntRect snappedPaintRect(pixelSnappedIntRect(paintRect));
94 bool themePainted = boxDecorationData.hasAppearance && !RenderTheme::theme() .paint(&m_renderBox, paintInfo, snappedPaintRect); 94 bool themePainted = boxDecorationData.hasAppearance && !RenderTheme::theme() .paint(&m_renderBox, paintInfo, snappedPaintRect);
95 if (!themePainted) { 95 if (!themePainted) {
96 if (boxDecorationData.bleedAvoidance() == BackgroundBleedBackgroundOverB order) 96 if (boxDecorationData.bleedAvoidance() == BackgroundBleedBackgroundOverB order)
97 paintBorder(m_renderBox, paintInfo, paintRect, style, boxDecorationD ata.bleedAvoidance()); 97 paintBorder(m_renderBox, paintInfo, paintRect, style, boxDecorationD ata.bleedAvoidance());
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 // include scales applied at raster time, such as the device zoom. 231 // include scales applied at raster time, such as the device zoom.
232 static LayoutRect shrinkRectByOnePixel(GraphicsContext* context, const LayoutRec t& rect) 232 static LayoutRect shrinkRectByOnePixel(GraphicsContext* context, const LayoutRec t& rect)
233 { 233 {
234 LayoutRect shrunkRect = rect; 234 LayoutRect shrunkRect = rect;
235 AffineTransform transform = context->getCTM(); 235 AffineTransform transform = context->getCTM();
236 shrunkRect.inflateX(-static_cast<LayoutUnit>(ceil(1 / transform.xScale()))); 236 shrunkRect.inflateX(-static_cast<LayoutUnit>(ceil(1 / transform.xScale())));
237 shrunkRect.inflateY(-static_cast<LayoutUnit>(ceil(1 / transform.yScale()))); 237 shrunkRect.inflateY(-static_cast<LayoutUnit>(ceil(1 / transform.yScale())));
238 return shrunkRect; 238 return shrunkRect;
239 } 239 }
240 240
241 RoundedRect BoxPainter::getBackgroundRoundedRect(RenderObject& obj, const Layout Rect& borderRect, InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inli neBoxHeight, 241 FloatRoundedRect BoxPainter::getBackgroundRoundedRect(RenderObject& obj, const L ayoutRect& borderRect, InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
242 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 242 bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
243 { 243 {
244 RoundedRect border = obj.style()->getRoundedBorderFor(borderRect, includeLog icalLeftEdge, includeLogicalRightEdge); 244 FloatRoundedRect border = obj.style()->getRoundedBorderFor(borderRect, inclu deLogicalLeftEdge, includeLogicalRightEdge);
245 if (box && (box->nextLineBox() || box->prevLineBox())) { 245 if (box && (box->nextLineBox() || box->prevLineBox())) {
246 RoundedRect segmentBorder = obj.style()->getRoundedBorderFor(LayoutRect( 0, 0, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogicalRi ghtEdge); 246 FloatRoundedRect segmentBorder = obj.style()->getRoundedBorderFor(Layout Rect(0, 0, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogi calRightEdge);
247 border.setRadii(segmentBorder.radii()); 247 border.setRadii(segmentBorder.radii());
248 } 248 }
249 249
250 return border; 250 return border;
251 } 251 }
252 252
253 RoundedRect BoxPainter::backgroundRoundedRectAdjustedForBleedAvoidance(RenderObj ect& obj, GraphicsContext* context, const LayoutRect& borderRect, BackgroundBlee dAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, bool i ncludeLogicalLeftEdge, bool includeLogicalRightEdge) 253 FloatRoundedRect BoxPainter::backgroundRoundedRectAdjustedForBleedAvoidance(Rend erObject& obj, GraphicsContext* context, const LayoutRect& borderRect, Backgroun dBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, b ool includeLogicalLeftEdge, bool includeLogicalRightEdge)
254 { 254 {
255 if (bleedAvoidance == BackgroundBleedShrinkBackground) { 255 if (bleedAvoidance == BackgroundBleedShrinkBackground) {
256 // We shrink the rectangle by one pixel on each side because the bleed i s one pixel maximum. 256 // We shrink the rectangle by one pixel on each side because the bleed i s one pixel maximum.
257 return BoxPainter::getBackgroundRoundedRect(obj, shrinkRectByOnePixel(co ntext, borderRect), box, boxSize.width(), boxSize.height(), includeLogicalLeftEd ge, includeLogicalRightEdge); 257 return BoxPainter::getBackgroundRoundedRect(obj, shrinkRectByOnePixel(co ntext, borderRect), box, boxSize.width(), boxSize.height(), includeLogicalLeftEd ge, includeLogicalRightEdge);
258 } 258 }
259 if (bleedAvoidance == BackgroundBleedBackgroundOverBorder) 259 if (bleedAvoidance == BackgroundBleedBackgroundOverBorder)
260 return obj.style()->getRoundedInnerBorderFor(borderRect, includeLogicalL eftEdge, includeLogicalRightEdge); 260 return obj.style()->getRoundedInnerBorderFor(borderRect, includeLogicalL eftEdge, includeLogicalRightEdge);
261 261
262 return BoxPainter::getBackgroundRoundedRect(obj, borderRect, box, boxSize.wi dth(), boxSize.height(), includeLogicalLeftEdge, includeLogicalRightEdge); 262 return BoxPainter::getBackgroundRoundedRect(obj, borderRect, box, boxSize.wi dth(), boxSize.height(), includeLogicalLeftEdge, includeLogicalRightEdge);
263 } 263 }
264 264
265 void BoxPainter::clipRoundedInnerRect(GraphicsContext * context, const LayoutRec t& rect, const RoundedRect& clipRect) 265 void BoxPainter::clipRoundedInnerRect(GraphicsContext * context, const LayoutRec t& rect, const FloatRoundedRect& clipRect)
266 { 266 {
267 if (clipRect.isRenderable()) { 267 if (clipRect.isRenderable()) {
268 context->clipRoundedRect(clipRect); 268 context->clipRoundedRect(clipRect);
269 } else { 269 } else {
270 // We create a rounded rect for each of the corners and clip it, while m aking sure we clip opposing corners together. 270 // We create a rounded rect for each of the corners and clip it, while m aking sure we clip opposing corners together.
271 if (!clipRect.radii().topLeft().isEmpty() || !clipRect.radii().bottomRig ht().isEmpty()) { 271 if (!clipRect.radii().topLeft().isEmpty() || !clipRect.radii().bottomRig ht().isEmpty()) {
272 IntRect topCorner(clipRect.rect().x(), clipRect.rect().y(), rect.max X() - clipRect.rect().x(), rect.maxY() - clipRect.rect().y()); 272 FloatRect topCorner(clipRect.rect().x(), clipRect.rect().y(), rect.m axX() - clipRect.rect().x(), rect.maxY() - clipRect.rect().y());
273 RoundedRect::Radii topCornerRadii; 273 FloatRoundedRect::Radii topCornerRadii;
274 topCornerRadii.setTopLeft(clipRect.radii().topLeft()); 274 topCornerRadii.setTopLeft(clipRect.radii().topLeft());
275 context->clipRoundedRect(RoundedRect(topCorner, topCornerRadii)); 275 context->clipRoundedRect(FloatRoundedRect(topCorner, topCornerRadii) );
276 276
277 IntRect bottomCorner(rect.x(), rect.y(), clipRect.rect().maxX() - re ct.x(), clipRect.rect().maxY() - rect.y()); 277 FloatRect bottomCorner(rect.x().toFloat(), rect.y().toFloat(), clipR ect.rect().maxX() - rect.x().toFloat(), clipRect.rect().maxY() - rect.y().toFloa t());
278 RoundedRect::Radii bottomCornerRadii; 278 FloatRoundedRect::Radii bottomCornerRadii;
279 bottomCornerRadii.setBottomRight(clipRect.radii().bottomRight()); 279 bottomCornerRadii.setBottomRight(clipRect.radii().bottomRight());
280 context->clipRoundedRect(RoundedRect(bottomCorner, bottomCornerRadii )); 280 context->clipRoundedRect(FloatRoundedRect(bottomCorner, bottomCorner Radii));
281 } 281 }
282 282
283 if (!clipRect.radii().topRight().isEmpty() || !clipRect.radii().bottomLe ft().isEmpty()) { 283 if (!clipRect.radii().topRight().isEmpty() || !clipRect.radii().bottomLe ft().isEmpty()) {
284 IntRect topCorner(rect.x(), clipRect.rect().y(), clipRect.rect().max X() - rect.x(), rect.maxY() - clipRect.rect().y()); 284 FloatRect topCorner(rect.x().toFloat(), clipRect.rect().y(), clipRec t.rect().maxX() - rect.x().toFloat(), rect.maxY() - clipRect.rect().y());
285 RoundedRect::Radii topCornerRadii; 285 FloatRoundedRect::Radii topCornerRadii;
286 topCornerRadii.setTopRight(clipRect.radii().topRight()); 286 topCornerRadii.setTopRight(clipRect.radii().topRight());
287 context->clipRoundedRect(RoundedRect(topCorner, topCornerRadii)); 287 context->clipRoundedRect(FloatRoundedRect(topCorner, topCornerRadii) );
288 288
289 IntRect bottomCorner(clipRect.rect().x(), rect.y(), rect.maxX() - cl ipRect.rect().x(), clipRect.rect().maxY() - rect.y()); 289 FloatRect bottomCorner(clipRect.rect().x(), rect.y().toFloat(), rect .maxX() - clipRect.rect().x(), clipRect.rect().maxY() - rect.y().toFloat());
290 RoundedRect::Radii bottomCornerRadii; 290 FloatRoundedRect::Radii bottomCornerRadii;
291 bottomCornerRadii.setBottomLeft(clipRect.radii().bottomLeft()); 291 bottomCornerRadii.setBottomLeft(clipRect.radii().bottomLeft());
292 context->clipRoundedRect(RoundedRect(bottomCorner, bottomCornerRadii )); 292 context->clipRoundedRect(FloatRoundedRect(bottomCorner, bottomCorner Radii));
293 } 293 }
294 } 294 }
295 } 295 }
296 296
297 void BoxPainter::paintFillLayerExtended(RenderBoxModelObject& obj, const PaintIn fo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& r ect, 297 void BoxPainter::paintFillLayerExtended(RenderBoxModelObject& obj, const PaintIn fo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& r ect,
298 BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSiz e& boxSize, CompositeOperator op, RenderObject* backgroundObject, bool skipBaseC olor) 298 BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSiz e& boxSize, CompositeOperator op, RenderObject* backgroundObject, bool skipBaseC olor)
299 { 299 {
300 GraphicsContext* context = paintInfo.context; 300 GraphicsContext* context = paintInfo.context;
301 if (rect.isEmpty()) 301 if (rect.isEmpty())
302 return; 302 return;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 if (!isDocumentElementRenderer && !clippedWithLocalScrolling && !shouldPaint BackgroundImage && isBorderFill && isBottomLayer) { 344 if (!isDocumentElementRenderer && !clippedWithLocalScrolling && !shouldPaint BackgroundImage && isBorderFill && isBottomLayer) {
345 if (!colorVisible) 345 if (!colorVisible)
346 return; 346 return;
347 347
348 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box); 348 bool boxShadowShouldBeAppliedToBackground = obj.boxShadowShouldBeApplied ToBackground(bleedAvoidance, box);
349 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp pliedToBackground); 349 GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAp pliedToBackground);
350 if (boxShadowShouldBeAppliedToBackground) 350 if (boxShadowShouldBeAppliedToBackground)
351 BoxPainter::applyBoxShadowForBackground(context, obj); 351 BoxPainter::applyBoxShadowForBackground(context, obj);
352 352
353 if (hasRoundedBorder && bleedAvoidance != BackgroundBleedClipBackground) { 353 if (hasRoundedBorder && bleedAvoidance != BackgroundBleedClipBackground) {
354 RoundedRect border = backgroundRoundedRectAdjustedForBleedAvoidance( obj, context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightE dge); 354 FloatRoundedRect border = backgroundRoundedRectAdjustedForBleedAvoid ance(obj, context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeR ightEdge);
355 if (border.isRenderable()) { 355 if (border.isRenderable()) {
356 context->fillRoundedRect(border, bgColor); 356 context->fillRoundedRect(border, bgColor);
357 } else { 357 } else {
358 context->save(); 358 context->save();
359 clipRoundedInnerRect(context, rect, border); 359 clipRoundedInnerRect(context, rect, border);
360 context->fillRect(border.rect(), bgColor); 360 context->fillRect(border.rect(), bgColor);
361 context->restore(); 361 context->restore();
362 } 362 }
363 } else { 363 } else {
364 context->fillRect(pixelSnappedIntRect(rect), bgColor); 364 context->fillRect(pixelSnappedIntRect(rect), bgColor);
365 } 365 }
366 366
367 return; 367 return;
368 } 368 }
369 369
370 // BorderFillBox radius clipping is taken care of by BackgroundBleedClipBack ground 370 // BorderFillBox radius clipping is taken care of by BackgroundBleedClipBack ground
371 bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidan ce == BackgroundBleedClipBackground); 371 bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidan ce == BackgroundBleedClipBackground);
372 GraphicsContextStateSaver clipToBorderStateSaver(*context, clipToBorderRadiu s); 372 GraphicsContextStateSaver clipToBorderStateSaver(*context, clipToBorderRadiu s);
373 if (clipToBorderRadius) { 373 if (clipToBorderRadius) {
374 RoundedRect border = isBorderFill ? backgroundRoundedRectAdjustedForBlee dAvoidance(obj, context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, in cludeRightEdge) : getBackgroundRoundedRect(obj, rect, box, boxSize.width(), boxS ize.height(), includeLeftEdge, includeRightEdge); 374 FloatRoundedRect border = isBorderFill ? backgroundRoundedRectAdjustedFo rBleedAvoidance(obj, context, rect, bleedAvoidance, box, boxSize, includeLeftEdg e, includeRightEdge) : getBackgroundRoundedRect(obj, rect, box, boxSize.width(), boxSize.height(), includeLeftEdge, includeRightEdge);
375 375
376 // Clip to the padding or content boxes as necessary. 376 // Clip to the padding or content boxes as necessary.
377 if (bgLayer.clip() == ContentFillBox) { 377 if (bgLayer.clip() == ContentFillBox) {
378 border = obj.style()->getRoundedInnerBorderFor(border.rect(), 378 border = obj.style()->getRoundedInnerBorderFor(LayoutRect(border.rec t()),
379 obj.paddingTop() + obj.borderTop(), obj.paddingBottom() + obj.bo rderBottom(), 379 obj.paddingTop() + obj.borderTop(), obj.paddingBottom() + obj.bo rderBottom(),
380 obj.paddingLeft() + obj.borderLeft(), obj.paddingRight() + obj.b orderRight(), includeLeftEdge, includeRightEdge); 380 obj.paddingLeft() + obj.borderLeft(), obj.paddingRight() + obj.b orderRight(), includeLeftEdge, includeRightEdge);
381 } else if (bgLayer.clip() == PaddingFillBox) { 381 } else if (bgLayer.clip() == PaddingFillBox) {
382 border = obj.style()->getRoundedInnerBorderFor(border.rect(), includ eLeftEdge, includeRightEdge); 382 border = obj.style()->getRoundedInnerBorderFor(LayoutRect(border.rec t()), includeLeftEdge, includeRightEdge);
383 } 383 }
384 384
385 clipRoundedInnerRect(context, rect, border); 385 clipRoundedInnerRect(context, rect, border);
386 } 386 }
387 387
388 int bLeft = includeLeftEdge ? obj.borderLeft() : 0; 388 int bLeft = includeLeftEdge ? obj.borderLeft() : 0;
389 int bRight = includeRightEdge ? obj.borderRight() : 0; 389 int bRight = includeRightEdge ? obj.borderRight() : 0;
390 LayoutUnit pLeft = includeLeftEdge ? obj.paddingLeft() : LayoutUnit(); 390 LayoutUnit pLeft = includeLeftEdge ? obj.paddingLeft() : LayoutUnit();
391 LayoutUnit pRight = includeRightEdge ? obj.paddingRight() : LayoutUnit(); 391 LayoutUnit pRight = includeRightEdge ? obj.paddingRight() : LayoutUnit();
392 392
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 middleScaleFactor.setHeight(destinationHeight / sourceHeight); 1069 middleScaleFactor.setHeight(destinationHeight / sourceHeight);
1070 1070
1071 graphicsContext->drawTiledImage(image.get(), 1071 graphicsContext->drawTiledImage(image.get(),
1072 IntRect(borderImageRect.x() + leftWidth, borderImageRect.y() + topWi dth, destinationWidth, destinationHeight), 1072 IntRect(borderImageRect.x() + leftWidth, borderImageRect.y() + topWi dth, destinationWidth, destinationHeight),
1073 IntRect(leftSlice, topSlice, sourceWidth, sourceHeight), 1073 IntRect(leftSlice, topSlice, sourceWidth, sourceHeight),
1074 middleScaleFactor, (Image::TileRule)hRule, (Image::TileRule)vRule, o p); 1074 middleScaleFactor, (Image::TileRule)hRule, (Image::TileRule)vRule, o p);
1075 } 1075 }
1076 return true; 1076 return true;
1077 } 1077 }
1078 1078
1079 static IntRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdg e edges[], int side) 1079 static FloatRect calculateSideRect(const FloatRoundedRect& outerBorder, const Bo rderEdge edges[], int side)
1080 { 1080 {
1081 IntRect sideRect = outerBorder.rect(); 1081 FloatRect sideRect = outerBorder.rect();
1082 int width = edges[side].width; 1082 int width = edges[side].width;
1083 1083
1084 if (side == BSTop) 1084 if (side == BSTop)
1085 sideRect.setHeight(width); 1085 sideRect.setHeight(width);
1086 else if (side == BSBottom) 1086 else if (side == BSBottom)
1087 sideRect.shiftYEdgeTo(sideRect.maxY() - width); 1087 sideRect.shiftYEdgeTo(sideRect.maxY() - width);
1088 else if (side == BSLeft) 1088 else if (side == BSLeft)
1089 sideRect.setWidth(width); 1089 sideRect.setWidth(width);
1090 else 1090 else
1091 sideRect.shiftXEdgeTo(sideRect.maxX() - width); 1091 sideRect.shiftXEdgeTo(sideRect.maxX() - width);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 1173
1174 bool BoxPainter::shouldAntialiasLines(GraphicsContext* context) 1174 bool BoxPainter::shouldAntialiasLines(GraphicsContext* context)
1175 { 1175 {
1176 // FIXME: We may want to not antialias when scaled by an integral value, 1176 // FIXME: We may want to not antialias when scaled by an integral value,
1177 // and we may want to antialias when translated by a non-integral value. 1177 // and we may want to antialias when translated by a non-integral value.
1178 // FIXME: See crbug.com/382491. getCTM does not include scale factors applie d at raster time, such 1178 // FIXME: See crbug.com/382491. getCTM does not include scale factors applie d at raster time, such
1179 // as device zoom. 1179 // as device zoom.
1180 return !context->getCTM().isIdentityOrTranslationOrFlipped(); 1180 return !context->getCTM().isIdentityOrTranslationOrFlipped();
1181 } 1181 }
1182 1182
1183 static bool borderWillArcInnerEdge(const IntSize& firstRadius, const FloatSize& secondRadius) 1183 static bool borderWillArcInnerEdge(const FloatSize& firstRadius, const FloatSize & secondRadius)
1184 { 1184 {
1185 return !firstRadius.isZero() || !secondRadius.isZero(); 1185 return !firstRadius.isZero() || !secondRadius.isZero();
1186 } 1186 }
1187 1187
1188 // This assumes that we draw in order: top, bottom, left, right. 1188 // This assumes that we draw in order: top, bottom, left, right.
1189 static inline bool willBeOverdrawn(BoxSide side, BoxSide adjacentSide, const Bor derEdge edges[]) 1189 static inline bool willBeOverdrawn(BoxSide side, BoxSide adjacentSide, const Bor derEdge edges[])
1190 { 1190 {
1191 switch (side) { 1191 switch (side) {
1192 case BSTop: 1192 case BSTop:
1193 case BSBottom: 1193 case BSBottom:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 1234
1235 if (!edges[side].sharesColorWith(edges[adjacentSide])) 1235 if (!edges[side].sharesColorWith(edges[adjacentSide]))
1236 return true; 1236 return true;
1237 1237
1238 if (borderStylesRequireMitre(side, adjacentSide, edges[side].borderStyle(), edges[adjacentSide].borderStyle())) 1238 if (borderStylesRequireMitre(side, adjacentSide, edges[side].borderStyle(), edges[adjacentSide].borderStyle()))
1239 return true; 1239 return true;
1240 1240
1241 return false; 1241 return false;
1242 } 1242 }
1243 1243
1244 static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, c onst BorderEdge edges[], BoxSide side) 1244 static FloatRect calculateSideRectIncludingInner(const FloatRoundedRect& outerBo rder, const BorderEdge edges[], BoxSide side)
1245 { 1245 {
1246 IntRect sideRect = outerBorder.rect(); 1246 FloatRect sideRect = outerBorder.rect();
1247 int width; 1247 int width;
1248 1248
1249 switch (side) { 1249 switch (side) {
1250 case BSTop: 1250 case BSTop:
1251 width = sideRect.height() - edges[BSBottom].width; 1251 width = sideRect.height() - edges[BSBottom].width;
1252 sideRect.setHeight(width); 1252 sideRect.setHeight(width);
1253 break; 1253 break;
1254 case BSBottom: 1254 case BSBottom:
1255 width = sideRect.height() - edges[BSTop].width; 1255 width = sideRect.height() - edges[BSTop].width;
1256 sideRect.shiftYEdgeTo(sideRect.maxY() - width); 1256 sideRect.shiftYEdgeTo(sideRect.maxY() - width);
1257 break; 1257 break;
1258 case BSLeft: 1258 case BSLeft:
1259 width = sideRect.width() - edges[BSRight].width; 1259 width = sideRect.width() - edges[BSRight].width;
1260 sideRect.setWidth(width); 1260 sideRect.setWidth(width);
1261 break; 1261 break;
1262 case BSRight: 1262 case BSRight:
1263 width = sideRect.width() - edges[BSLeft].width; 1263 width = sideRect.width() - edges[BSLeft].width;
1264 sideRect.shiftXEdgeTo(sideRect.maxX() - width); 1264 sideRect.shiftXEdgeTo(sideRect.maxX() - width);
1265 break; 1265 break;
1266 } 1266 }
1267 1267
1268 return sideRect; 1268 return sideRect;
1269 } 1269 }
1270 1270
1271 static RoundedRect calculateAdjustedInnerBorder(const RoundedRect&innerBorder, B oxSide side) 1271 static FloatRoundedRect calculateAdjustedInnerBorder(const FloatRoundedRect& inn erBorder, BoxSide side)
1272 { 1272 {
1273 // Expand the inner border as necessary to make it a rounded rect (i.e. radi i contained within each edge). 1273 // Expand the inner border as necessary to make it a rounded rect (i.e. radi i contained within each edge).
1274 // This function relies on the fact we only get radii not contained within e ach edge if one of the radii 1274 // This function relies on the fact we only get radii not contained within e ach edge if one of the radii
1275 // for an edge is zero, so we can shift the arc towards the zero radius corn er. 1275 // for an edge is zero, so we can shift the arc towards the zero radius corn er.
1276 RoundedRect::Radii newRadii = innerBorder.radii(); 1276 FloatRoundedRect::Radii newRadii = innerBorder.radii();
1277 IntRect newRect = innerBorder.rect(); 1277 FloatRect newRect = innerBorder.rect();
1278 1278
1279 float overshoot; 1279 float overshoot;
1280 float maxRadii; 1280 float maxRadii;
1281 1281
1282 switch (side) { 1282 switch (side) {
1283 case BSTop: 1283 case BSTop:
1284 overshoot = newRadii.topLeft().width() + newRadii.topRight().width() - n ewRect.width(); 1284 overshoot = newRadii.topLeft().width() + newRadii.topRight().width() - n ewRect.width();
1285 if (overshoot > 0) { 1285 // FIXME: once we start pixel-snapping rounded rects after this point, t he overshoot concept
1286 // should disappear.
1287 if (overshoot > 0.1) {
1286 ASSERT(!(newRadii.topLeft().width() && newRadii.topRight().width())) ; 1288 ASSERT(!(newRadii.topLeft().width() && newRadii.topRight().width())) ;
1287 newRect.setWidth(newRect.width() + overshoot); 1289 newRect.setWidth(newRect.width() + overshoot);
1288 if (!newRadii.topLeft().width()) 1290 if (!newRadii.topLeft().width())
1289 newRect.move(-overshoot, 0); 1291 newRect.move(-overshoot, 0);
1290 } 1292 }
1291 newRadii.setBottomLeft(IntSize(0, 0)); 1293 newRadii.setBottomLeft(IntSize(0, 0));
1292 newRadii.setBottomRight(IntSize(0, 0)); 1294 newRadii.setBottomRight(IntSize(0, 0));
1293 maxRadii = std::max(newRadii.topLeft().height(), newRadii.topRight().hei ght()); 1295 maxRadii = std::max(newRadii.topLeft().height(), newRadii.topRight().hei ght());
1294 if (maxRadii > newRect.height()) 1296 if (maxRadii > newRect.height())
1295 newRect.setHeight(maxRadii); 1297 newRect.setHeight(maxRadii);
1296 break; 1298 break;
1297 1299
1298 case BSBottom: 1300 case BSBottom:
1299 overshoot = newRadii.bottomLeft().width() + newRadii.bottomRight().width () - newRect.width(); 1301 overshoot = newRadii.bottomLeft().width() + newRadii.bottomRight().width () - newRect.width();
1300 if (overshoot > 0) { 1302 if (overshoot > 0.1) {
1301 ASSERT(!(newRadii.bottomLeft().width() && newRadii.bottomRight().wid th())); 1303 ASSERT(!(newRadii.bottomLeft().width() && newRadii.bottomRight().wid th()));
1302 newRect.setWidth(newRect.width() + overshoot); 1304 newRect.setWidth(newRect.width() + overshoot);
1303 if (!newRadii.bottomLeft().width()) 1305 if (!newRadii.bottomLeft().width())
1304 newRect.move(-overshoot, 0); 1306 newRect.move(-overshoot, 0);
1305 } 1307 }
1306 newRadii.setTopLeft(IntSize(0, 0)); 1308 newRadii.setTopLeft(IntSize(0, 0));
1307 newRadii.setTopRight(IntSize(0, 0)); 1309 newRadii.setTopRight(IntSize(0, 0));
1308 maxRadii = std::max(newRadii.bottomLeft().height(), newRadii.bottomRight ().height()); 1310 maxRadii = std::max(newRadii.bottomLeft().height(), newRadii.bottomRight ().height());
1309 if (maxRadii > newRect.height()) { 1311 if (maxRadii > newRect.height()) {
1310 newRect.move(0, newRect.height() - maxRadii); 1312 newRect.move(0, newRect.height() - maxRadii);
1311 newRect.setHeight(maxRadii); 1313 newRect.setHeight(maxRadii);
1312 } 1314 }
1313 break; 1315 break;
1314 1316
1315 case BSLeft: 1317 case BSLeft:
1316 overshoot = newRadii.topLeft().height() + newRadii.bottomLeft().height() - newRect.height(); 1318 overshoot = newRadii.topLeft().height() + newRadii.bottomLeft().height() - newRect.height();
1317 if (overshoot > 0) { 1319 if (overshoot > 0.1) {
1318 ASSERT(!(newRadii.topLeft().height() && newRadii.bottomLeft().height ())); 1320 ASSERT(!(newRadii.topLeft().height() && newRadii.bottomLeft().height ()));
1319 newRect.setHeight(newRect.height() + overshoot); 1321 newRect.setHeight(newRect.height() + overshoot);
1320 if (!newRadii.topLeft().height()) 1322 if (!newRadii.topLeft().height())
1321 newRect.move(0, -overshoot); 1323 newRect.move(0, -overshoot);
1322 } 1324 }
1323 newRadii.setTopRight(IntSize(0, 0)); 1325 newRadii.setTopRight(IntSize(0, 0));
1324 newRadii.setBottomRight(IntSize(0, 0)); 1326 newRadii.setBottomRight(IntSize(0, 0));
1325 maxRadii = std::max(newRadii.topLeft().width(), newRadii.bottomLeft().wi dth()); 1327 maxRadii = std::max(newRadii.topLeft().width(), newRadii.bottomLeft().wi dth());
1326 if (maxRadii > newRect.width()) 1328 if (maxRadii > newRect.width())
1327 newRect.setWidth(maxRadii); 1329 newRect.setWidth(maxRadii);
1328 break; 1330 break;
1329 1331
1330 case BSRight: 1332 case BSRight:
1331 overshoot = newRadii.topRight().height() + newRadii.bottomRight().height () - newRect.height(); 1333 overshoot = newRadii.topRight().height() + newRadii.bottomRight().height () - newRect.height();
1332 if (overshoot > 0) { 1334 if (overshoot > 0.1) {
1333 ASSERT(!(newRadii.topRight().height() && newRadii.bottomRight().heig ht())); 1335 ASSERT(!(newRadii.topRight().height() && newRadii.bottomRight().heig ht()));
1334 newRect.setHeight(newRect.height() + overshoot); 1336 newRect.setHeight(newRect.height() + overshoot);
1335 if (!newRadii.topRight().height()) 1337 if (!newRadii.topRight().height())
1336 newRect.move(0, -overshoot); 1338 newRect.move(0, -overshoot);
1337 } 1339 }
1338 newRadii.setTopLeft(IntSize(0, 0)); 1340 newRadii.setTopLeft(IntSize(0, 0));
1339 newRadii.setBottomLeft(IntSize(0, 0)); 1341 newRadii.setBottomLeft(IntSize(0, 0));
1340 maxRadii = std::max(newRadii.topRight().width(), newRadii.bottomRight(). width()); 1342 maxRadii = std::max(newRadii.topRight().width(), newRadii.bottomRight(). width());
1341 if (maxRadii > newRect.width()) { 1343 if (maxRadii > newRect.width()) {
1342 newRect.move(newRect.width() - maxRadii, 0); 1344 newRect.move(newRect.width() - maxRadii, 0);
1343 newRect.setWidth(maxRadii); 1345 newRect.setWidth(maxRadii);
1344 } 1346 }
1345 break; 1347 break;
1346 } 1348 }
1347 1349
1348 return RoundedRect(newRect, newRadii); 1350 return FloatRoundedRect(newRect, newRadii);
1349 } 1351 }
1350 1352
1351 void BoxPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphicsCont ext, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 1353 void BoxPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphicsCont ext, const FloatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder,
1352 BoxSide side, const BorderEdge edges[]) 1354 BoxSide side, const BorderEdge edges[])
1353 { 1355 {
1354 graphicsContext->clip(calculateSideRectIncludingInner(outerBorder, edges, si de)); 1356 graphicsContext->clip(calculateSideRectIncludingInner(outerBorder, edges, si de));
1355 RoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(innerBorder, si de); 1357 FloatRoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(innerBorde r, side);
1356 if (!adjustedInnerRect.isEmpty()) 1358 if (!adjustedInnerRect.isEmpty())
1357 graphicsContext->clipOutRoundedRect(adjustedInnerRect); 1359 graphicsContext->clipOutRoundedRect(adjustedInnerRect);
1358 } 1360 }
1359 1361
1360 static bool allCornersClippedOut(const RoundedRect& border, const LayoutRect& cl ipRect) 1362 static bool allCornersClippedOut(const FloatRoundedRect& border, const LayoutRec t& clipRect)
1361 { 1363 {
1362 LayoutRect boundingRect = border.rect(); 1364 LayoutRect boundingRect(border.rect());
1363 if (clipRect.contains(boundingRect)) 1365 if (clipRect.contains(boundingRect))
1364 return false; 1366 return false;
1365 1367
1366 RoundedRect::Radii radii = border.radii(); 1368 FloatRoundedRect::Radii radii = border.radii();
1367 1369
1368 LayoutRect topLeftRect(boundingRect.location(), LayoutSize(radii.topLeft())) ; 1370 LayoutRect topLeftRect(boundingRect.location(), LayoutSize(radii.topLeft())) ;
1369 if (clipRect.intersects(topLeftRect)) 1371 if (clipRect.intersects(topLeftRect))
1370 return false; 1372 return false;
1371 1373
1372 LayoutRect topRightRect(boundingRect.location(), LayoutSize(radii.topRight() )); 1374 LayoutRect topRightRect(boundingRect.location(), LayoutSize(radii.topRight() ));
1373 topRightRect.setX(boundingRect.maxX() - topRightRect.width()); 1375 topRightRect.setX(boundingRect.maxX() - topRightRect.width());
1374 if (clipRect.intersects(topRightRect)) 1376 if (clipRect.intersects(topRightRect))
1375 return false; 1377 return false;
1376 1378
(...skipping 13 matching lines...) Expand all
1390 1392
1391 void BoxPainter::paintBorder(RenderBoxModelObject& obj, const PaintInfo& info, c onst LayoutRect& rect, const RenderStyle* style, BackgroundBleedAvoidance bleedA voidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 1393 void BoxPainter::paintBorder(RenderBoxModelObject& obj, const PaintInfo& info, c onst LayoutRect& rect, const RenderStyle* style, BackgroundBleedAvoidance bleedA voidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
1392 { 1394 {
1393 GraphicsContext* graphicsContext = info.context; 1395 GraphicsContext* graphicsContext = info.context;
1394 // border-image is not affected by border-radius. 1396 // border-image is not affected by border-radius.
1395 if (paintNinePieceImage(obj, graphicsContext, rect, style, style->borderImag e())) 1397 if (paintNinePieceImage(obj, graphicsContext, rect, style, style->borderImag e()))
1396 return; 1398 return;
1397 1399
1398 BorderEdge edges[4]; 1400 BorderEdge edges[4];
1399 style->getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightE dge); 1401 style->getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightE dge);
1400 RoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogicalLef tEdge, includeLogicalRightEdge); 1402 FloatRoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogic alLeftEdge, includeLogicalRightEdge);
1401 RoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRectAdj ustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogicalLef tEdge, includeLogicalRightEdge); 1403 FloatRoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRe ctAdjustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogic alLeftEdge, includeLogicalRightEdge);
1402 1404
1403 if (outerBorder.rect().isEmpty()) 1405 if (outerBorder.rect().isEmpty())
1404 return; 1406 return;
1405 1407
1406 bool haveAlphaColor = false; 1408 bool haveAlphaColor = false;
1407 bool haveAllSolidEdges = true; 1409 bool haveAllSolidEdges = true;
1408 bool haveAllDoubleEdges = true; 1410 bool haveAllDoubleEdges = true;
1409 int numEdgesVisible = 4; 1411 int numEdgesVisible = 4;
1410 bool allEdgesShareColor = true; 1412 bool allEdgesShareColor = true;
1411 bool allEdgesShareWidth = true; 1413 bool allEdgesShareWidth = true;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 if (currEdge.borderStyle() != SOLID) 1447 if (currEdge.borderStyle() != SOLID)
1446 haveAllSolidEdges = false; 1448 haveAllSolidEdges = false;
1447 1449
1448 if (currEdge.borderStyle() != DOUBLE) 1450 if (currEdge.borderStyle() != DOUBLE)
1449 haveAllDoubleEdges = false; 1451 haveAllDoubleEdges = false;
1450 } 1452 }
1451 1453
1452 // If no corner intersects the clip region, we can pretend outerBorder is 1454 // If no corner intersects the clip region, we can pretend outerBorder is
1453 // rectangular to improve performance. 1455 // rectangular to improve performance.
1454 if (haveAllSolidEdges && outerBorder.isRounded() && allCornersClippedOut(out erBorder, info.rect)) 1456 if (haveAllSolidEdges && outerBorder.isRounded() && allCornersClippedOut(out erBorder, info.rect))
1455 outerBorder.setRadii(RoundedRect::Radii()); 1457 outerBorder.setRadii(FloatRoundedRect::Radii());
1456 1458
1457 // isRenderable() check avoids issue described in https://bugs.webkit.org/sh ow_bug.cgi?id=38787 1459 // isRenderable() check avoids issue described in https://bugs.webkit.org/sh ow_bug.cgi?id=38787
1458 if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && inner Border.isRenderable()) { 1460 if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && inner Border.isRenderable()) {
1459 // Fast path for drawing all solid edges and all unrounded double edges 1461 // Fast path for drawing all solid edges and all unrounded double edges
1460 1462
1461 if (numEdgesVisible == 4 && (outerBorder.isRounded() || haveAlphaColor) 1463 if (numEdgesVisible == 4 && (outerBorder.isRounded() || haveAlphaColor)
1462 && (haveAllSolidEdges || (!outerBorder.isRounded() && !innerBorder.i sRounded()))) { 1464 && (haveAllSolidEdges || (!outerBorder.isRounded() && !innerBorder.i sRounded()))) {
1463 Path path; 1465 Path path;
1464 1466
1465 if (outerBorder.isRounded() && allEdgesShareWidth) { 1467 if (outerBorder.isRounded() && allEdgesShareWidth) {
1466 1468
1467 // Very fast path for single stroked round rect with circular co rners 1469 // Very fast path for single stroked round rect with circular co rners
1468 1470
1469 graphicsContext->fillBetweenRoundedRects(outerBorder, innerBorde r, edges[firstVisibleEdge].color); 1471 graphicsContext->fillBetweenRoundedRects(outerBorder, innerBorde r, edges[firstVisibleEdge].color);
1470 return; 1472 return;
1471 } 1473 }
1472 if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedClip Background) 1474 if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedClip Background)
1473 path.addRoundedRect(outerBorder); 1475 path.addRoundedRect(outerBorder);
1474 else 1476 else
1475 path.addRect(outerBorder.rect()); 1477 path.addRect(outerBorder.rect());
1476 1478
1477 if (haveAllDoubleEdges) { 1479 if (haveAllDoubleEdges) {
1478 IntRect innerThirdRect = outerBorder.rect(); 1480 FloatRect innerThirdRect = outerBorder.rect();
1479 IntRect outerThirdRect = outerBorder.rect(); 1481 FloatRect outerThirdRect = outerBorder.rect();
1480 for (int side = BSTop; side <= BSLeft; ++side) { 1482 for (int side = BSTop; side <= BSLeft; ++side) {
1481 int outerWidth; 1483 int outerWidth;
1482 int innerWidth; 1484 int innerWidth;
1483 edges[side].getDoubleBorderStripeWidths(outerWidth, innerWid th); 1485 edges[side].getDoubleBorderStripeWidths(outerWidth, innerWid th);
1484 1486
1485 if (side == BSTop) { 1487 if (side == BSTop) {
1486 innerThirdRect.shiftYEdgeTo(innerThirdRect.y() + innerWi dth); 1488 innerThirdRect.shiftYEdgeTo(innerThirdRect.y() + innerWi dth);
1487 outerThirdRect.shiftYEdgeTo(outerThirdRect.y() + outerWi dth); 1489 outerThirdRect.shiftYEdgeTo(outerThirdRect.y() + outerWi dth);
1488 } else if (side == BSBottom) { 1490 } else if (side == BSBottom) {
1489 innerThirdRect.setHeight(innerThirdRect.height() - inner Width); 1491 innerThirdRect.setHeight(innerThirdRect.height() - inner Width);
1490 outerThirdRect.setHeight(outerThirdRect.height() - outer Width); 1492 outerThirdRect.setHeight(outerThirdRect.height() - outer Width);
1491 } else if (side == BSLeft) { 1493 } else if (side == BSLeft) {
1492 innerThirdRect.shiftXEdgeTo(innerThirdRect.x() + innerWi dth); 1494 innerThirdRect.shiftXEdgeTo(innerThirdRect.x() + innerWi dth);
1493 outerThirdRect.shiftXEdgeTo(outerThirdRect.x() + outerWi dth); 1495 outerThirdRect.shiftXEdgeTo(outerThirdRect.x() + outerWi dth);
1494 } else { 1496 } else {
1495 innerThirdRect.setWidth(innerThirdRect.width() - innerWi dth); 1497 innerThirdRect.setWidth(innerThirdRect.width() - innerWi dth);
1496 outerThirdRect.setWidth(outerThirdRect.width() - outerWi dth); 1498 outerThirdRect.setWidth(outerThirdRect.width() - outerWi dth);
1497 } 1499 }
1498 } 1500 }
1499 1501
1500 RoundedRect outerThird = outerBorder; 1502 FloatRoundedRect outerThird = outerBorder;
1501 RoundedRect innerThird = innerBorder; 1503 FloatRoundedRect innerThird = innerBorder;
1502 innerThird.setRect(innerThirdRect); 1504 innerThird.setRect(innerThirdRect);
1503 outerThird.setRect(outerThirdRect); 1505 outerThird.setRect(outerThirdRect);
1504 1506
1505 if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground) 1507 if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground)
1506 path.addRoundedRect(outerThird); 1508 path.addRoundedRect(outerThird);
1507 else 1509 else
1508 path.addRect(outerThird.rect()); 1510 path.addRect(outerThird.rect());
1509 1511
1510 if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground) 1512 if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground)
1511 path.addRoundedRect(innerThird); 1513 path.addRoundedRect(innerThird);
(...skipping 11 matching lines...) Expand all
1523 graphicsContext->fillPath(path); 1525 graphicsContext->fillPath(path);
1524 return; 1526 return;
1525 } 1527 }
1526 // Avoid creating transparent layers 1528 // Avoid creating transparent layers
1527 if (haveAllSolidEdges && numEdgesVisible != 4 && !outerBorder.isRounded( ) && haveAlphaColor) { 1529 if (haveAllSolidEdges && numEdgesVisible != 4 && !outerBorder.isRounded( ) && haveAlphaColor) {
1528 Path path; 1530 Path path;
1529 1531
1530 for (int i = BSTop; i <= BSLeft; ++i) { 1532 for (int i = BSTop; i <= BSLeft; ++i) {
1531 const BorderEdge& currEdge = edges[i]; 1533 const BorderEdge& currEdge = edges[i];
1532 if (currEdge.shouldRender()) { 1534 if (currEdge.shouldRender()) {
1533 IntRect sideRect = calculateSideRect(outerBorder, edges, i); 1535 FloatRect sideRect = calculateSideRect(outerBorder, edges, i );
1534 path.addRect(sideRect); 1536 path.addRect(sideRect);
1535 } 1537 }
1536 } 1538 }
1537 1539
1538 graphicsContext->setFillRule(RULE_NONZERO); 1540 graphicsContext->setFillRule(RULE_NONZERO);
1539 graphicsContext->setFillColor(edges[firstVisibleEdge].color); 1541 graphicsContext->setFillColor(edges[firstVisibleEdge].color);
1540 graphicsContext->fillPath(path); 1542 graphicsContext->fillPath(path);
1541 return; 1543 return;
1542 } 1544 }
1543 } 1545 }
1544 1546
1545 bool clipToOuterBorder = outerBorder.isRounded(); 1547 bool clipToOuterBorder = outerBorder.isRounded();
1546 GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder); 1548 GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder);
1547 if (clipToOuterBorder) { 1549 if (clipToOuterBorder) {
1548 // Clip to the inner and outer radii rects. 1550 // Clip to the inner and outer radii rects.
1549 if (bleedAvoidance != BackgroundBleedClipBackground) 1551 if (bleedAvoidance != BackgroundBleedClipBackground)
1550 graphicsContext->clipRoundedRect(outerBorder); 1552 graphicsContext->clipRoundedRect(outerBorder);
1551 // isRenderable() check avoids issue described in https://bugs.webkit.or g/show_bug.cgi?id=38787 1553 // isRenderable() check avoids issue described in https://bugs.webkit.or g/show_bug.cgi?id=38787
1552 // The inside will be clipped out later (in clipBorderSideForComplexInne rPath) 1554 // The inside will be clipped out later (in clipBorderSideForComplexInne rPath)
1553 if (innerBorder.isRenderable() && !innerBorder.isEmpty()) 1555 if (innerBorder.isRenderable() && !innerBorder.isEmpty())
1554 graphicsContext->clipOutRoundedRect(innerBorder); 1556 graphicsContext->clipOutRoundedRect(innerBorder);
1555 } 1557 }
1556 1558
1557 // If only one edge visible antialiasing doesn't create seams 1559 // If only one edge visible antialiasing doesn't create seams
1558 bool antialias = shouldAntialiasLines(graphicsContext) || numEdgesVisible == 1; 1560 bool antialias = shouldAntialiasLines(graphicsContext) || numEdgesVisible == 1;
1559 RoundedRect unadjustedInnerBorder = (bleedAvoidance == BackgroundBleedBackgr oundOverBorder) ? style->getRoundedInnerBorderFor(rect, includeLogicalLeftEdge, includeLogicalRightEdge) : innerBorder; 1561 FloatRoundedRect unadjustedInnerBorder = (bleedAvoidance == BackgroundBleedB ackgroundOverBorder) ? style->getRoundedInnerBorderFor(rect, includeLogicalLeftE dge, includeLogicalRightEdge) : innerBorder;
1560 IntPoint innerBorderAdjustment(innerBorder.rect().x() - unadjustedInnerBorde r.rect().x(), innerBorder.rect().y() - unadjustedInnerBorder.rect().y()); 1562 IntPoint innerBorderAdjustment(innerBorder.rect().x() - unadjustedInnerBorde r.rect().x(), innerBorder.rect().y() - unadjustedInnerBorder.rect().y());
1561 if (haveAlphaColor) 1563 if (haveAlphaColor)
1562 paintTranslucentBorderSides(obj, graphicsContext, style, outerBorder, un adjustedInnerBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias); 1564 paintTranslucentBorderSides(obj, graphicsContext, style, outerBorder, un adjustedInnerBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
1563 else 1565 else
1564 paintBorderSides(obj, graphicsContext, style, outerBorder, unadjustedInn erBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge, antialias); 1566 paintBorderSides(obj, graphicsContext, style, outerBorder, unadjustedInn erBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge, antialias);
1565 } 1567 }
1566 1568
1567 static inline bool includesAdjacentEdges(BorderEdgeFlags flags) 1569 static inline bool includesAdjacentEdges(BorderEdgeFlags flags)
1568 { 1570 {
1569 return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | Right BorderEdge) 1571 return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | Right BorderEdge)
1570 || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge | BottomBorderEdge) 1572 || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge | BottomBorderEdge)
1571 || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge | LeftBorderEdge) 1573 || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge | LeftBorderEdge)
1572 || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBo rderEdge); 1574 || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBo rderEdge);
1573 } 1575 }
1574 1576
1575 void BoxPainter::paintTranslucentBorderSides(RenderObject& obj, GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedRect& outerBorder, cons t RoundedRect& innerBorder, const IntPoint& innerBorderAdjustment, 1577 void BoxPainter::paintTranslucentBorderSides(RenderObject& obj, GraphicsContext* graphicsContext, const RenderStyle* style, const FloatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder, const IntPoint& innerBorderAdjustment,
1576 const BorderEdge edges[], BorderEdgeFlags edgesToDraw, BackgroundBleedAvoida nce bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, b ool antialias) 1578 const BorderEdge edges[], BorderEdgeFlags edgesToDraw, BackgroundBleedAvoida nce bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, b ool antialias)
1577 { 1579 {
1578 // willBeOverdrawn assumes that we draw in order: top, bottom, left, right. 1580 // willBeOverdrawn assumes that we draw in order: top, bottom, left, right.
1579 // This is different from BoxSide enum order. 1581 // This is different from BoxSide enum order.
1580 static const BoxSide paintOrder[] = { BSTop, BSBottom, BSLeft, BSRight }; 1582 static const BoxSide paintOrder[] = { BSTop, BSBottom, BSLeft, BSRight };
1581 1583
1582 while (edgesToDraw) { 1584 while (edgesToDraw) {
1583 // Find undrawn edges sharing a color. 1585 // Find undrawn edges sharing a color.
1584 Color commonColor; 1586 Color commonColor;
1585 1587
(...skipping 29 matching lines...) Expand all
1615 edgesToDraw &= ~commonColorEdgeSet; 1617 edgesToDraw &= ~commonColorEdgeSet;
1616 } 1618 }
1617 } 1619 }
1618 1620
1619 LayoutRect BoxPainter::borderInnerRectAdjustedForBleedAvoidance(GraphicsContext* context, const LayoutRect& rect, BackgroundBleedAvoidance bleedAvoidance) 1621 LayoutRect BoxPainter::borderInnerRectAdjustedForBleedAvoidance(GraphicsContext* context, const LayoutRect& rect, BackgroundBleedAvoidance bleedAvoidance)
1620 { 1622 {
1621 // We shrink the rectangle by one pixel on each side to make it fully overla p the anti-aliased background border 1623 // We shrink the rectangle by one pixel on each side to make it fully overla p the anti-aliased background border
1622 return (bleedAvoidance == BackgroundBleedBackgroundOverBorder) ? shrinkRectB yOnePixel(context, rect) : rect; 1624 return (bleedAvoidance == BackgroundBleedBackgroundOverBorder) ? shrinkRectB yOnePixel(context, rect) : rect;
1623 } 1625 }
1624 1626
1625 void BoxPainter::paintOneBorderSide(RenderObject& obj, GraphicsContext* graphics Context, const RenderStyle* style, const RoundedRect& outerBorder, const Rounded Rect& innerBorder, 1627 void BoxPainter::paintOneBorderSide(RenderObject& obj, GraphicsContext* graphics Context, const RenderStyle* style, const FloatRoundedRect& outerBorder, const Fl oatRoundedRect& innerBorder,
1626 const IntRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjace ntSide2, const BorderEdge edges[], const Path* path, 1628 const FloatRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adja centSide2, const BorderEdge edges[], const Path* path,
1627 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool i ncludeLogicalRightEdge, bool antialias, const Color* overrideColor) 1629 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool i ncludeLogicalRightEdge, bool antialias, const Color* overrideColor)
1628 { 1630 {
1629 const BorderEdge& edgeToRender = edges[side]; 1631 const BorderEdge& edgeToRender = edges[side];
1630 ASSERT(edgeToRender.width); 1632 ASSERT(edgeToRender.width);
1631 const BorderEdge& adjacentEdge1 = edges[adjacentSide1]; 1633 const BorderEdge& adjacentEdge1 = edges[adjacentSide1];
1632 const BorderEdge& adjacentEdge2 = edges[adjacentSide2]; 1634 const BorderEdge& adjacentEdge2 = edges[adjacentSide2];
1633 1635
1634 bool mitreAdjacentSide1 = joinRequiresMitre(side, adjacentSide1, edges, !ant ialias); 1636 bool mitreAdjacentSide1 = joinRequiresMitre(side, adjacentSide1, edges, !ant ialias);
1635 bool mitreAdjacentSide2 = joinRequiresMitre(side, adjacentSide2, edges, !ant ialias); 1637 bool mitreAdjacentSide2 = joinRequiresMitre(side, adjacentSide2, edges, !ant ialias);
1636 1638
1637 bool adjacentSide1StylesMatch = colorsMatchAtCorner(side, adjacentSide1, edg es); 1639 bool adjacentSide1StylesMatch = colorsMatchAtCorner(side, adjacentSide1, edg es);
1638 bool adjacentSide2StylesMatch = colorsMatchAtCorner(side, adjacentSide2, edg es); 1640 bool adjacentSide2StylesMatch = colorsMatchAtCorner(side, adjacentSide2, edg es);
1639 1641
1640 const Color& colorToPaint = overrideColor ? *overrideColor : edgeToRender.co lor; 1642 const Color& colorToPaint = overrideColor ? *overrideColor : edgeToRender.co lor;
1641 1643
1642 if (path) { 1644 if (path) {
1643 GraphicsContextStateSaver stateSaver(*graphicsContext); 1645 GraphicsContextStateSaver stateSaver(*graphicsContext);
1644 if (innerBorder.isRenderable()) 1646 if (innerBorder.isRenderable())
1645 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, adjacentSide1StylesMatch, adjacentSide2StylesMatch); 1647 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, adjacentSide1StylesMatch, adjacentSide2StylesMatch);
1646 else 1648 else
1647 clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, inne rBorder, side, edges); 1649 clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, inne rBorder, side, edges);
1648 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi dth), adjacentEdge2.width); 1650 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi dth), adjacentEdge2.width);
1649 drawBoxSideFromPath(graphicsContext, outerBorder.rect(), *path, edges, e dgeToRender.width, thickness, side, style, 1651 drawBoxSideFromPath(graphicsContext, LayoutRect(outerBorder.rect()), *pa th, edges, edgeToRender.width, thickness, side, style,
1650 colorToPaint, edgeToRender.borderStyle(), bleedAvoidance, includeLog icalLeftEdge, includeLogicalRightEdge); 1652 colorToPaint, edgeToRender.borderStyle(), bleedAvoidance, includeLog icalLeftEdge, includeLogicalRightEdge);
1651 } else { 1653 } else {
1652 bool clipForStyle = styleRequiresClipPolygon(edgeToRender.borderStyle()) && (mitreAdjacentSide1 || mitreAdjacentSide2); 1654 bool clipForStyle = styleRequiresClipPolygon(edgeToRender.borderStyle()) && (mitreAdjacentSide1 || mitreAdjacentSide2);
1653 bool clipAdjacentSide1 = colorNeedsAntiAliasAtCorner(side, adjacentSide1 , edges) && mitreAdjacentSide1; 1655 bool clipAdjacentSide1 = colorNeedsAntiAliasAtCorner(side, adjacentSide1 , edges) && mitreAdjacentSide1;
1654 bool clipAdjacentSide2 = colorNeedsAntiAliasAtCorner(side, adjacentSide2 , edges) && mitreAdjacentSide2; 1656 bool clipAdjacentSide2 = colorNeedsAntiAliasAtCorner(side, adjacentSide2 , edges) && mitreAdjacentSide2;
1655 bool shouldClip = clipForStyle || clipAdjacentSide1 || clipAdjacentSide2 ; 1657 bool shouldClip = clipForStyle || clipAdjacentSide1 || clipAdjacentSide2 ;
1656 1658
1657 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip); 1659 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip);
1658 if (shouldClip) { 1660 if (shouldClip) {
1659 bool aliasAdjacentSide1 = clipAdjacentSide1 || (clipForStyle && mitr eAdjacentSide1); 1661 bool aliasAdjacentSide1 = clipAdjacentSide1 || (clipForStyle && mitr eAdjacentSide1);
1660 bool aliasAdjacentSide2 = clipAdjacentSide2 || (clipForStyle && mitr eAdjacentSide2); 1662 bool aliasAdjacentSide2 = clipAdjacentSide2 || (clipForStyle && mitr eAdjacentSide2);
1661 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, !aliasAdjacentSide1, !aliasAdjacentSide2); 1663 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, !aliasAdjacentSide1, !aliasAdjacentSide2);
1662 // Since we clipped, no need to draw with a mitre. 1664 // Since we clipped, no need to draw with a mitre.
1663 mitreAdjacentSide1 = false; 1665 mitreAdjacentSide1 = false;
1664 mitreAdjacentSide2 = false; 1666 mitreAdjacentSide2 = false;
1665 } 1667 }
1666 1668
1667 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec t.y(), sideRect.maxX(), sideRect.maxY(), side, colorToPaint, edgeToRender.border Style(), 1669 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec t.y(), sideRect.maxX(), sideRect.maxY(), side, colorToPaint, edgeToRender.border Style(),
1668 mitreAdjacentSide1 ? adjacentEdge1.width : 0, mitreAdjacentSide2 ? a djacentEdge2.width : 0, antialias); 1670 mitreAdjacentSide1 ? adjacentEdge1.width : 0, mitreAdjacentSide2 ? a djacentEdge2.width : 0, antialias);
1669 } 1671 }
1670 } 1672 }
1671 1673
1672 void BoxPainter::paintBorderSides(RenderObject& obj, GraphicsContext* graphicsCo ntext, const RenderStyle* style, const RoundedRect& outerBorder, const RoundedRe ct& innerBorder, 1674 void BoxPainter::paintBorderSides(RenderObject& obj, GraphicsContext* graphicsCo ntext, const RenderStyle* style, const FloatRoundedRect& outerBorder, const Floa tRoundedRect& innerBorder,
1673 const IntPoint& innerBorderAdjustment, const BorderEdge edges[], BorderEdgeF lags edgeSet, BackgroundBleedAvoidance bleedAvoidance, 1675 const IntPoint& innerBorderAdjustment, const BorderEdge edges[], BorderEdgeF lags edgeSet, BackgroundBleedAvoidance bleedAvoidance,
1674 bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, c onst Color* overrideColor) 1676 bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, c onst Color* overrideColor)
1675 { 1677 {
1676 bool renderRadii = outerBorder.isRounded(); 1678 bool renderRadii = outerBorder.isRounded();
1677 1679
1678 Path roundedPath; 1680 Path roundedPath;
1679 if (renderRadii) 1681 if (renderRadii)
1680 roundedPath.addRoundedRect(outerBorder); 1682 roundedPath.addRoundedRect(outerBorder);
1681 1683
1682 // The inner border adjustment for bleed avoidance mode BackgroundBleedBackg roundOverBorder 1684 // The inner border adjustment for bleed avoidance mode BackgroundBleedBackg roundOverBorder
1683 // is only applied to sideRect, which is okay since BackgroundBleedBackgroun dOverBorder 1685 // is only applied to sideRect, which is okay since BackgroundBleedBackgroun dOverBorder
1684 // is only to be used for solid borders and the shape of the border painted by drawBoxSideFromPath 1686 // is only to be used for solid borders and the shape of the border painted by drawBoxSideFromPath
1685 // only depends on sideRect when painting solid borders. 1687 // only depends on sideRect when painting solid borders.
1686 1688
1687 if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) { 1689 if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) {
1688 IntRect sideRect = outerBorder.rect(); 1690 FloatRect sideRect = outerBorder.rect();
1689 sideRect.setHeight(edges[BSTop].width + innerBorderAdjustment.y()); 1691 sideRect.setHeight(edges[BSTop].width + innerBorderAdjustment.y());
1690 1692
1691 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].bo rderStyle()) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorde r.radii().topRight())); 1693 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].bo rderStyle()) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorde r.radii().topRight()));
1692 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoi dance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor ); 1694 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoi dance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor );
1693 } 1695 }
1694 1696
1695 if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) { 1697 if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) {
1696 IntRect sideRect = outerBorder.rect(); 1698 FloatRect sideRect = outerBorder.rect();
1697 sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width - innerBor derAdjustment.y()); 1699 sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width - innerBor derAdjustment.y());
1698 1700
1699 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom] .borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), inne rBorder.radii().bottomRight())); 1701 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom] .borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), inne rBorder.radii().bottomRight()));
1700 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedA voidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideCo lor); 1702 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedA voidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideCo lor);
1701 } 1703 }
1702 1704
1703 if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) { 1705 if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) {
1704 IntRect sideRect = outerBorder.rect(); 1706 FloatRect sideRect = outerBorder.rect();
1705 sideRect.setWidth(edges[BSLeft].width + innerBorderAdjustment.x()); 1707 sideRect.setWidth(edges[BSLeft].width + innerBorderAdjustment.x());
1706 1708
1707 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].b orderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerB order.radii().topLeft())); 1709 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].b orderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerB order.radii().topLeft()));
1708 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvo idance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColo r); 1710 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvo idance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColo r);
1709 } 1711 }
1710 1712
1711 if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) { 1713 if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) {
1712 IntRect sideRect = outerBorder.rect(); 1714 FloatRect sideRect = outerBorder.rect();
1713 sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width - innerBord erAdjustment.x()); 1715 sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width - innerBord erAdjustment.x());
1714 1716
1715 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight]. borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), inne rBorder.radii().topRight())); 1717 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight]. borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), inne rBorder.radii().topRight()));
1716 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAv oidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideCol or); 1718 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAv oidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideCol or);
1717 } 1719 }
1718 } 1720 }
1719 1721
1720 void BoxPainter::drawBoxSideFromPath(GraphicsContext* graphicsContext, const Lay outRect& borderRect, const Path& borderPath, const BorderEdge edges[], 1722 void BoxPainter::drawBoxSideFromPath(GraphicsContext* graphicsContext, const Lay outRect& borderRect, const Path& borderPath, const BorderEdge edges[],
1721 float thickness, float drawThickness, BoxSide side, const RenderStyle* style , Color color, EBorderStyle borderStyle, BackgroundBleedAvoidance bleedAvoidance , 1723 float thickness, float drawThickness, BoxSide side, const RenderStyle* style , Color color, EBorderStyle borderStyle, BackgroundBleedAvoidance bleedAvoidance ,
1722 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 1724 bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 int innerBorderBottomWidth; 1788 int innerBorderBottomWidth;
1787 edges[BSBottom].getDoubleBorderStripeWidths(outerBorderBottomWidth, inne rBorderBottomWidth); 1789 edges[BSBottom].getDoubleBorderStripeWidths(outerBorderBottomWidth, inne rBorderBottomWidth);
1788 1790
1789 int outerBorderLeftWidth; 1791 int outerBorderLeftWidth;
1790 int innerBorderLeftWidth; 1792 int innerBorderLeftWidth;
1791 edges[BSLeft].getDoubleBorderStripeWidths(outerBorderLeftWidth, innerBor derLeftWidth); 1793 edges[BSLeft].getDoubleBorderStripeWidths(outerBorderLeftWidth, innerBor derLeftWidth);
1792 1794
1793 // Draw inner border line 1795 // Draw inner border line
1794 { 1796 {
1795 GraphicsContextStateSaver stateSaver(*graphicsContext); 1797 GraphicsContextStateSaver stateSaver(*graphicsContext);
1796 RoundedRect innerClip = style->getRoundedInnerBorderFor(borderRect, 1798 FloatRoundedRect innerClip = style->getRoundedInnerBorderFor(borderR ect,
1797 innerBorderTopWidth, innerBorderBottomWidth, innerBorderLeftWidt h, innerBorderRightWidth, 1799 innerBorderTopWidth, innerBorderBottomWidth, innerBorderLeftWidt h, innerBorderRightWidth,
1798 includeLogicalLeftEdge, includeLogicalRightEdge); 1800 includeLogicalLeftEdge, includeLogicalRightEdge);
1799 1801
1800 graphicsContext->clipRoundedRect(innerClip); 1802 graphicsContext->clipRoundedRect(innerClip);
1801 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge); 1803 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge);
1802 } 1804 }
1803 1805
1804 // Draw outer border line 1806 // Draw outer border line
1805 { 1807 {
1806 GraphicsContextStateSaver stateSaver(*graphicsContext); 1808 GraphicsContextStateSaver stateSaver(*graphicsContext);
1807 LayoutRect outerRect = borderRect; 1809 LayoutRect outerRect = borderRect;
1808 if (bleedAvoidance == BackgroundBleedClipBackground) { 1810 if (bleedAvoidance == BackgroundBleedClipBackground) {
1809 outerRect.inflate(1); 1811 outerRect.inflate(1);
1810 ++outerBorderTopWidth; 1812 ++outerBorderTopWidth;
1811 ++outerBorderBottomWidth; 1813 ++outerBorderBottomWidth;
1812 ++outerBorderLeftWidth; 1814 ++outerBorderLeftWidth;
1813 ++outerBorderRightWidth; 1815 ++outerBorderRightWidth;
1814 } 1816 }
1815 1817
1816 RoundedRect outerClip = style->getRoundedInnerBorderFor(outerRect, 1818 FloatRoundedRect outerClip = style->getRoundedInnerBorderFor(outerRe ct,
1817 outerBorderTopWidth, outerBorderBottomWidth, outerBorderLeftWidt h, outerBorderRightWidth, 1819 outerBorderTopWidth, outerBorderBottomWidth, outerBorderLeftWidt h, outerBorderRightWidth,
1818 includeLogicalLeftEdge, includeLogicalRightEdge); 1820 includeLogicalLeftEdge, includeLogicalRightEdge);
1819 graphicsContext->clipOutRoundedRect(outerClip); 1821 graphicsContext->clipOutRoundedRect(outerClip);
1820 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge); 1822 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge);
1821 } 1823 }
1822 return; 1824 return;
1823 } 1825 }
1824 case RIDGE: 1826 case RIDGE:
1825 case GROOVE: 1827 case GROOVE:
1826 { 1828 {
(...skipping 10 matching lines...) Expand all
1837 // Paint full border 1839 // Paint full border
1838 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s1, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge); 1840 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s1, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge);
1839 1841
1840 // Paint inner only 1842 // Paint inner only
1841 GraphicsContextStateSaver stateSaver(*graphicsContext); 1843 GraphicsContextStateSaver stateSaver(*graphicsContext);
1842 LayoutUnit topWidth = edges[BSTop].usedWidth() / 2; 1844 LayoutUnit topWidth = edges[BSTop].usedWidth() / 2;
1843 LayoutUnit bottomWidth = edges[BSBottom].usedWidth() / 2; 1845 LayoutUnit bottomWidth = edges[BSBottom].usedWidth() / 2;
1844 LayoutUnit leftWidth = edges[BSLeft].usedWidth() / 2; 1846 LayoutUnit leftWidth = edges[BSLeft].usedWidth() / 2;
1845 LayoutUnit rightWidth = edges[BSRight].usedWidth() / 2; 1847 LayoutUnit rightWidth = edges[BSRight].usedWidth() / 2;
1846 1848
1847 RoundedRect clipRect = style->getRoundedInnerBorderFor(borderRect, 1849 FloatRoundedRect clipRect = style->getRoundedInnerBorderFor(borderRect,
1848 topWidth, bottomWidth, leftWidth, rightWidth, 1850 topWidth, bottomWidth, leftWidth, rightWidth,
1849 includeLogicalLeftEdge, includeLogicalRightEdge); 1851 includeLogicalLeftEdge, includeLogicalRightEdge);
1850 1852
1851 graphicsContext->clipRoundedRect(clipRect); 1853 graphicsContext->clipRoundedRect(clipRect);
1852 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s2, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge); 1854 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s2, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge);
1853 return; 1855 return;
1854 } 1856 }
1855 case INSET: 1857 case INSET:
1856 if (side == BSTop || side == BSLeft) 1858 if (side == BSTop || side == BSLeft)
1857 color = color.dark(); 1859 color = color.dark();
(...skipping 11 matching lines...) Expand all
1869 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); 1871 graphicsContext->drawRect(pixelSnappedIntRect(borderRect));
1870 } 1872 }
1871 1873
1872 void BoxPainter::paintBoxShadow(const PaintInfo& info, const LayoutRect& paintRe ct, const RenderStyle* s, ShadowStyle shadowStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 1874 void BoxPainter::paintBoxShadow(const PaintInfo& info, const LayoutRect& paintRe ct, const RenderStyle* s, ShadowStyle shadowStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
1873 { 1875 {
1874 // FIXME: Deal with border-image. Would be great to use border-image as a ma sk. 1876 // FIXME: Deal with border-image. Would be great to use border-image as a ma sk.
1875 GraphicsContext* context = info.context; 1877 GraphicsContext* context = info.context;
1876 if (!s->boxShadow()) 1878 if (!s->boxShadow())
1877 return; 1879 return;
1878 1880
1879 RoundedRect border = (shadowStyle == Inset) ? s->getRoundedInnerBorderFor(pa intRect, includeLogicalLeftEdge, includeLogicalRightEdge) 1881 FloatRoundedRect border = (shadowStyle == Inset) ? s->getRoundedInnerBorderF or(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
1880 : s->getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogic alRightEdge); 1882 : s->getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogic alRightEdge);
1881 1883
1882 bool hasBorderRadius = s->hasBorderRadius(); 1884 bool hasBorderRadius = s->hasBorderRadius();
1883 bool isHorizontal = s->isHorizontalWritingMode(); 1885 bool isHorizontal = s->isHorizontalWritingMode();
1884 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).alpha() == 255; 1886 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).alpha() == 255;
1885 1887
1886 GraphicsContextStateSaver stateSaver(*context, false); 1888 GraphicsContextStateSaver stateSaver(*context, false);
1887 1889
1888 const ShadowList* shadowList = s->boxShadow(); 1890 const ShadowList* shadowList = s->boxShadow();
1889 for (size_t i = shadowList->shadows().size(); i--; ) { 1891 for (size_t i = shadowList->shadows().size(); i--; ) {
(...skipping 18 matching lines...) Expand all
1908 1910
1909 FloatRect shadowRect(border.rect()); 1911 FloatRect shadowRect(border.rect());
1910 shadowRect.inflate(shadowBlur + shadowSpread); 1912 shadowRect.inflate(shadowBlur + shadowSpread);
1911 shadowRect.move(shadowOffset); 1913 shadowRect.move(shadowOffset);
1912 1914
1913 // Save the state and clip, if not already done. 1915 // Save the state and clip, if not already done.
1914 // The clip does not depend on any shadow-specific properties. 1916 // The clip does not depend on any shadow-specific properties.
1915 if (!stateSaver.saved()) { 1917 if (!stateSaver.saved()) {
1916 stateSaver.save(); 1918 stateSaver.save();
1917 if (hasBorderRadius) { 1919 if (hasBorderRadius) {
1918 RoundedRect rectToClipOut = border; 1920 FloatRoundedRect rectToClipOut = border;
1919 1921
1920 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 1922 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time
1921 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the 1923 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the
1922 // corners. Those are avoided by insetting the clipping path by one pixel. 1924 // corners. Those are avoided by insetting the clipping path by one pixel.
1923 if (hasOpaqueBackground) 1925 if (hasOpaqueBackground)
1924 rectToClipOut.inflateWithRadii(-1); 1926 rectToClipOut.inflateWithRadii(-1);
1925 1927
1926 if (!rectToClipOut.isEmpty()) { 1928 if (!rectToClipOut.isEmpty()) {
1927 context->clipOutRoundedRect(rectToClipOut); 1929 context->clipOutRoundedRect(rectToClipOut);
1928 } 1930 }
1929 } else { 1931 } else {
1930 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle 1932 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle
1931 // of the box itself, which is always pixel-aligned. 1933 // of the box itself, which is always pixel-aligned.
1932 IntRect rectToClipOut = border.rect(); 1934 FloatRect rectToClipOut = border.rect();
1933 1935
1934 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 1936 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time
1935 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the 1937 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the
1936 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path 1938 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
1937 // by one pixel. 1939 // by one pixel.
1938 if (hasOpaqueBackground) { 1940 if (hasOpaqueBackground) {
1939 // FIXME: The function to decide on the policy based on the transform should be a named function. 1941 // FIXME: The function to decide on the policy based on the transform should be a named function.
1940 // FIXME: It's not clear if this check is right. What ab out integral scale factors? 1942 // FIXME: It's not clear if this check is right. What ab out integral scale factors?
1941 // FIXME: See crbug.com/382491. The use of getCTM may al so be wrong because it does not include 1943 // FIXME: See crbug.com/382491. The use of getCTM may al so be wrong because it does not include
1942 // device zoom applied at raster time. 1944 // device zoom applied at raster time.
1943 AffineTransform transform = context->getCTM(); 1945 AffineTransform transform = context->getCTM();
1944 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c()) 1946 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c())
1945 rectToClipOut.inflate(-1); 1947 rectToClipOut.inflate(-1);
1946 } 1948 }
1947 1949
1948 if (!rectToClipOut.isEmpty()) { 1950 if (!rectToClipOut.isEmpty()) {
1949 context->clipOut(rectToClipOut); 1951 context->clipOut(rectToClipOut);
1950 } 1952 }
1951 } 1953 }
1952 } 1954 }
1953 1955
1954 // Draw only the shadow. 1956 // Draw only the shadow.
1955 context->setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooper Builder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawSh adowOnly); 1957 context->setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooper Builder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawSh adowOnly);
1956 1958
1957 if (hasBorderRadius) { 1959 if (hasBorderRadius) {
1958 RoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowR ect)), border.radii()); 1960 FloatRoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(sh adowRect)), border.radii());
1959 influenceRect.expandRadii(2 * shadowBlur + shadowSpread); 1961 influenceRect.expandRadii(2 * shadowBlur + shadowSpread);
1960 if (allCornersClippedOut(influenceRect, info.rect)) { 1962 if (allCornersClippedOut(influenceRect, info.rect)) {
1961 context->fillRect(fillRect, Color::black); 1963 context->fillRect(fillRect, Color::black);
1962 } else { 1964 } else {
1963 // TODO: support non-integer shadows - crbug.com/334829 1965 // TODO: support non-integer shadows - crbug.com/334829
1964 RoundedRect roundedFillRect = border; 1966 FloatRoundedRect roundedFillRect = border;
1965 roundedFillRect.inflate(shadowSpread); 1967 roundedFillRect.inflate(shadowSpread);
1966 1968
1967 roundedFillRect.expandRadii(shadowSpread); 1969 roundedFillRect.expandRadii(shadowSpread);
1968 if (!roundedFillRect.isRenderable()) 1970 if (!roundedFillRect.isRenderable())
1969 roundedFillRect.adjustRadii(); 1971 roundedFillRect.adjustRadii();
1970 context->fillRoundedRect(roundedFillRect, Color::black); 1972 context->fillRoundedRect(roundedFillRect, Color::black);
1971 } 1973 }
1972 } else { 1974 } else {
1973 context->fillRect(fillRect, Color::black); 1975 context->fillRect(fillRect, Color::black);
1974 } 1976 }
(...skipping 11 matching lines...) Expand all
1986 clippedEdges |= GraphicsContext::RightEdge; 1988 clippedEdges |= GraphicsContext::RightEdge;
1987 else 1989 else
1988 clippedEdges |= GraphicsContext::BottomEdge; 1990 clippedEdges |= GraphicsContext::BottomEdge;
1989 } 1991 }
1990 // TODO: support non-integer shadows - crbug.com/334828 1992 // TODO: support non-integer shadows - crbug.com/334828
1991 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges); 1993 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges);
1992 } 1994 }
1993 } 1995 }
1994 } 1996 }
1995 1997
1996 void BoxPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, const R oundedRect& outerBorder, const RoundedRect& innerBorder, BoxSide side, bool firs tEdgeMatches, bool secondEdgeMatches) 1998 void BoxPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, const F loatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder, BoxSide side, bool firstEdgeMatches, bool secondEdgeMatches)
1997 { 1999 {
1998 FloatPoint quad[4]; 2000 FloatPoint quad[4];
1999 2001
2000 const LayoutRect& outerRect = outerBorder.rect(); 2002 const LayoutRect outerRect(outerBorder.rect());
2001 const LayoutRect& innerRect = innerBorder.rect(); 2003 const LayoutRect innerRect(innerBorder.rect());
2002 2004
2003 FloatPoint centerPoint(innerRect.location().x().toFloat() + innerRect.width( ).toFloat() / 2, innerRect.location().y().toFloat() + innerRect.height().toFloat () / 2); 2005 FloatPoint centerPoint(innerRect.location().x().toFloat() + innerRect.width( ).toFloat() / 2, innerRect.location().y().toFloat() + innerRect.height().toFloat () / 2);
2004 2006
2005 // For each side, create a quad that encompasses all parts of that side that may draw, 2007 // For each side, create a quad that encompasses all parts of that side that may draw,
2006 // including areas inside the innerBorder. 2008 // including areas inside the innerBorder.
2007 // 2009 //
2008 // 0----------------3 2010 // 0----------------3
2009 // 0 \ / 0 2011 // 0 \ / 0
2010 // |\ 1----------- 2 /| 2012 // |\ 1----------- 2 /|
2011 // | 1 1 | 2013 // | 1 1 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 2175
2174 FloatPoint secondQuad[4]; 2176 FloatPoint secondQuad[4];
2175 secondQuad[0] = quad[0]; 2177 secondQuad[0] = quad[0];
2176 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); 2178 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy);
2177 secondQuad[2] = quad[2]; 2179 secondQuad[2] = quad[2];
2178 secondQuad[3] = quad[3]; 2180 secondQuad[3] = quad[3];
2179 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches); 2181 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches);
2180 } 2182 }
2181 2183
2182 } // namespace blink 2184 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/paint/BoxPainter.h ('k') | Source/core/paint/LayerClipRecorder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698