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

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 6 years 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
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 if (overshoot > 0) {
1286 ASSERT(!(newRadii.topLeft().width() && newRadii.topRight().width())) ; 1286 ASSERT(!(newRadii.topLeft().width() && newRadii.topRight().width())) ;
1287 newRect.setWidth(newRect.width() + overshoot); 1287 newRect.setWidth(newRect.width() + overshoot);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 newRadii.setTopLeft(IntSize(0, 0)); 1338 newRadii.setTopLeft(IntSize(0, 0));
1339 newRadii.setBottomLeft(IntSize(0, 0)); 1339 newRadii.setBottomLeft(IntSize(0, 0));
1340 maxRadii = std::max(newRadii.topRight().width(), newRadii.bottomRight(). width()); 1340 maxRadii = std::max(newRadii.topRight().width(), newRadii.bottomRight(). width());
1341 if (maxRadii > newRect.width()) { 1341 if (maxRadii > newRect.width()) {
1342 newRect.move(newRect.width() - maxRadii, 0); 1342 newRect.move(newRect.width() - maxRadii, 0);
1343 newRect.setWidth(maxRadii); 1343 newRect.setWidth(maxRadii);
1344 } 1344 }
1345 break; 1345 break;
1346 } 1346 }
1347 1347
1348 return RoundedRect(newRect, newRadii); 1348 return FloatRoundedRect(newRect, newRadii);
1349 } 1349 }
1350 1350
1351 void BoxPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphicsCont ext, const RoundedRect& outerBorder, const RoundedRect& innerBorder, 1351 void BoxPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphicsCont ext, const FloatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder,
1352 BoxSide side, const BorderEdge edges[]) 1352 BoxSide side, const BorderEdge edges[])
1353 { 1353 {
1354 graphicsContext->clip(calculateSideRectIncludingInner(outerBorder, edges, si de)); 1354 graphicsContext->clip(calculateSideRectIncludingInner(outerBorder, edges, si de));
1355 RoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(innerBorder, si de); 1355 FloatRoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(innerBorde r, side);
1356 if (!adjustedInnerRect.isEmpty()) 1356 if (!adjustedInnerRect.isEmpty())
1357 graphicsContext->clipOutRoundedRect(adjustedInnerRect); 1357 graphicsContext->clipOutRoundedRect(adjustedInnerRect);
1358 } 1358 }
1359 1359
1360 static bool allCornersClippedOut(const RoundedRect& border, const LayoutRect& cl ipRect) 1360 static bool allCornersClippedOut(const FloatRoundedRect& border, const LayoutRec t& clipRect)
1361 { 1361 {
1362 LayoutRect boundingRect = border.rect(); 1362 LayoutRect boundingRect(border.rect());
1363 if (clipRect.contains(boundingRect)) 1363 if (clipRect.contains(boundingRect))
1364 return false; 1364 return false;
1365 1365
1366 RoundedRect::Radii radii = border.radii(); 1366 FloatRoundedRect::Radii radii = border.radii();
1367 1367
1368 LayoutRect topLeftRect(boundingRect.location(), LayoutSize(radii.topLeft())) ; 1368 LayoutRect topLeftRect(boundingRect.location(), LayoutSize(radii.topLeft())) ;
1369 if (clipRect.intersects(topLeftRect)) 1369 if (clipRect.intersects(topLeftRect))
1370 return false; 1370 return false;
1371 1371
1372 LayoutRect topRightRect(boundingRect.location(), LayoutSize(radii.topRight() )); 1372 LayoutRect topRightRect(boundingRect.location(), LayoutSize(radii.topRight() ));
1373 topRightRect.setX(boundingRect.maxX() - topRightRect.width()); 1373 topRightRect.setX(boundingRect.maxX() - topRightRect.width());
1374 if (clipRect.intersects(topRightRect)) 1374 if (clipRect.intersects(topRightRect))
1375 return false; 1375 return false;
1376 1376
(...skipping 13 matching lines...) Expand all
1390 1390
1391 void BoxPainter::paintBorder(RenderBoxModelObject& obj, const PaintInfo& info, c onst LayoutRect& rect, const RenderStyle* style, BackgroundBleedAvoidance bleedA voidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 1391 void BoxPainter::paintBorder(RenderBoxModelObject& obj, const PaintInfo& info, c onst LayoutRect& rect, const RenderStyle* style, BackgroundBleedAvoidance bleedA voidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
1392 { 1392 {
1393 GraphicsContext* graphicsContext = info.context; 1393 GraphicsContext* graphicsContext = info.context;
1394 // border-image is not affected by border-radius. 1394 // border-image is not affected by border-radius.
1395 if (paintNinePieceImage(obj, graphicsContext, rect, style, style->borderImag e())) 1395 if (paintNinePieceImage(obj, graphicsContext, rect, style, style->borderImag e()))
1396 return; 1396 return;
1397 1397
1398 BorderEdge edges[4]; 1398 BorderEdge edges[4];
1399 style->getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightE dge); 1399 style->getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightE dge);
1400 RoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogicalLef tEdge, includeLogicalRightEdge); 1400 FloatRoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogic alLeftEdge, includeLogicalRightEdge);
1401 RoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRectAdj ustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogicalLef tEdge, includeLogicalRightEdge); 1401 FloatRoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRe ctAdjustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogic alLeftEdge, includeLogicalRightEdge);
1402 1402
1403 if (outerBorder.rect().isEmpty()) 1403 if (outerBorder.rect().isEmpty())
1404 return; 1404 return;
1405 1405
1406 bool haveAlphaColor = false; 1406 bool haveAlphaColor = false;
1407 bool haveAllSolidEdges = true; 1407 bool haveAllSolidEdges = true;
1408 bool haveAllDoubleEdges = true; 1408 bool haveAllDoubleEdges = true;
1409 int numEdgesVisible = 4; 1409 int numEdgesVisible = 4;
1410 bool allEdgesShareColor = true; 1410 bool allEdgesShareColor = true;
1411 bool allEdgesShareWidth = true; 1411 bool allEdgesShareWidth = true;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 1468
1469 graphicsContext->fillBetweenRoundedRects(outerBorder, innerBorde r, edges[firstVisibleEdge].color); 1469 graphicsContext->fillBetweenRoundedRects(outerBorder, innerBorde r, edges[firstVisibleEdge].color);
1470 return; 1470 return;
1471 } 1471 }
1472 if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedClip Background) 1472 if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedClip Background)
1473 path.addRoundedRect(outerBorder); 1473 path.addRoundedRect(outerBorder);
1474 else 1474 else
1475 path.addRect(outerBorder.rect()); 1475 path.addRect(outerBorder.rect());
1476 1476
1477 if (haveAllDoubleEdges) { 1477 if (haveAllDoubleEdges) {
1478 IntRect innerThirdRect = outerBorder.rect(); 1478 FloatRect innerThirdRect = outerBorder.rect();
1479 IntRect outerThirdRect = outerBorder.rect(); 1479 FloatRect outerThirdRect = outerBorder.rect();
1480 for (int side = BSTop; side <= BSLeft; ++side) { 1480 for (int side = BSTop; side <= BSLeft; ++side) {
1481 int outerWidth; 1481 int outerWidth;
1482 int innerWidth; 1482 int innerWidth;
1483 edges[side].getDoubleBorderStripeWidths(outerWidth, innerWid th); 1483 edges[side].getDoubleBorderStripeWidths(outerWidth, innerWid th);
1484 1484
1485 if (side == BSTop) { 1485 if (side == BSTop) {
1486 innerThirdRect.shiftYEdgeTo(innerThirdRect.y() + innerWi dth); 1486 innerThirdRect.shiftYEdgeTo(innerThirdRect.y() + innerWi dth);
1487 outerThirdRect.shiftYEdgeTo(outerThirdRect.y() + outerWi dth); 1487 outerThirdRect.shiftYEdgeTo(outerThirdRect.y() + outerWi dth);
1488 } else if (side == BSBottom) { 1488 } else if (side == BSBottom) {
1489 innerThirdRect.setHeight(innerThirdRect.height() - inner Width); 1489 innerThirdRect.setHeight(innerThirdRect.height() - inner Width);
1490 outerThirdRect.setHeight(outerThirdRect.height() - outer Width); 1490 outerThirdRect.setHeight(outerThirdRect.height() - outer Width);
1491 } else if (side == BSLeft) { 1491 } else if (side == BSLeft) {
1492 innerThirdRect.shiftXEdgeTo(innerThirdRect.x() + innerWi dth); 1492 innerThirdRect.shiftXEdgeTo(innerThirdRect.x() + innerWi dth);
1493 outerThirdRect.shiftXEdgeTo(outerThirdRect.x() + outerWi dth); 1493 outerThirdRect.shiftXEdgeTo(outerThirdRect.x() + outerWi dth);
1494 } else { 1494 } else {
1495 innerThirdRect.setWidth(innerThirdRect.width() - innerWi dth); 1495 innerThirdRect.setWidth(innerThirdRect.width() - innerWi dth);
1496 outerThirdRect.setWidth(outerThirdRect.width() - outerWi dth); 1496 outerThirdRect.setWidth(outerThirdRect.width() - outerWi dth);
1497 } 1497 }
1498 } 1498 }
1499 1499
1500 RoundedRect outerThird = outerBorder; 1500 FloatRoundedRect outerThird = outerBorder;
1501 RoundedRect innerThird = innerBorder; 1501 FloatRoundedRect innerThird = innerBorder;
1502 innerThird.setRect(innerThirdRect); 1502 innerThird.setRect(innerThirdRect);
1503 outerThird.setRect(outerThirdRect); 1503 outerThird.setRect(outerThirdRect);
1504 1504
1505 if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground) 1505 if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground)
1506 path.addRoundedRect(outerThird); 1506 path.addRoundedRect(outerThird);
1507 else 1507 else
1508 path.addRect(outerThird.rect()); 1508 path.addRect(outerThird.rect());
1509 1509
1510 if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground) 1510 if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedC lipBackground)
1511 path.addRoundedRect(innerThird); 1511 path.addRoundedRect(innerThird);
(...skipping 11 matching lines...) Expand all
1523 graphicsContext->fillPath(path); 1523 graphicsContext->fillPath(path);
1524 return; 1524 return;
1525 } 1525 }
1526 // Avoid creating transparent layers 1526 // Avoid creating transparent layers
1527 if (haveAllSolidEdges && numEdgesVisible != 4 && !outerBorder.isRounded( ) && haveAlphaColor) { 1527 if (haveAllSolidEdges && numEdgesVisible != 4 && !outerBorder.isRounded( ) && haveAlphaColor) {
1528 Path path; 1528 Path path;
1529 1529
1530 for (int i = BSTop; i <= BSLeft; ++i) { 1530 for (int i = BSTop; i <= BSLeft; ++i) {
1531 const BorderEdge& currEdge = edges[i]; 1531 const BorderEdge& currEdge = edges[i];
1532 if (currEdge.shouldRender()) { 1532 if (currEdge.shouldRender()) {
1533 IntRect sideRect = calculateSideRect(outerBorder, edges, i); 1533 FloatRect sideRect = calculateSideRect(outerBorder, edges, i );
1534 path.addRect(sideRect); 1534 path.addRect(sideRect);
1535 } 1535 }
1536 } 1536 }
1537 1537
1538 graphicsContext->setFillRule(RULE_NONZERO); 1538 graphicsContext->setFillRule(RULE_NONZERO);
1539 graphicsContext->setFillColor(edges[firstVisibleEdge].color); 1539 graphicsContext->setFillColor(edges[firstVisibleEdge].color);
1540 graphicsContext->fillPath(path); 1540 graphicsContext->fillPath(path);
1541 return; 1541 return;
1542 } 1542 }
1543 } 1543 }
1544 1544
1545 bool clipToOuterBorder = outerBorder.isRounded(); 1545 bool clipToOuterBorder = outerBorder.isRounded();
1546 GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder); 1546 GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder);
1547 if (clipToOuterBorder) { 1547 if (clipToOuterBorder) {
1548 // Clip to the inner and outer radii rects. 1548 // Clip to the inner and outer radii rects.
1549 if (bleedAvoidance != BackgroundBleedClipBackground) 1549 if (bleedAvoidance != BackgroundBleedClipBackground)
1550 graphicsContext->clipRoundedRect(outerBorder); 1550 graphicsContext->clipRoundedRect(outerBorder);
1551 // isRenderable() check avoids issue described in https://bugs.webkit.or g/show_bug.cgi?id=38787 1551 // 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) 1552 // The inside will be clipped out later (in clipBorderSideForComplexInne rPath)
1553 if (innerBorder.isRenderable() && !innerBorder.isEmpty()) 1553 if (innerBorder.isRenderable() && !innerBorder.isEmpty())
1554 graphicsContext->clipOutRoundedRect(innerBorder); 1554 graphicsContext->clipOutRoundedRect(innerBorder);
1555 } 1555 }
1556 1556
1557 // If only one edge visible antialiasing doesn't create seams 1557 // If only one edge visible antialiasing doesn't create seams
1558 bool antialias = shouldAntialiasLines(graphicsContext) || numEdgesVisible == 1; 1558 bool antialias = shouldAntialiasLines(graphicsContext) || numEdgesVisible == 1;
1559 RoundedRect unadjustedInnerBorder = (bleedAvoidance == BackgroundBleedBackgr oundOverBorder) ? style->getRoundedInnerBorderFor(rect, includeLogicalLeftEdge, includeLogicalRightEdge) : innerBorder; 1559 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()); 1560 IntPoint innerBorderAdjustment(innerBorder.rect().x() - unadjustedInnerBorde r.rect().x(), innerBorder.rect().y() - unadjustedInnerBorder.rect().y());
1561 if (haveAlphaColor) 1561 if (haveAlphaColor)
1562 paintTranslucentBorderSides(obj, graphicsContext, style, outerBorder, un adjustedInnerBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias); 1562 paintTranslucentBorderSides(obj, graphicsContext, style, outerBorder, un adjustedInnerBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
1563 else 1563 else
1564 paintBorderSides(obj, graphicsContext, style, outerBorder, unadjustedInn erBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge, antialias); 1564 paintBorderSides(obj, graphicsContext, style, outerBorder, unadjustedInn erBorder, innerBorderAdjustment, edges, edgesToDraw, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge, antialias);
1565 } 1565 }
1566 1566
1567 static inline bool includesAdjacentEdges(BorderEdgeFlags flags) 1567 static inline bool includesAdjacentEdges(BorderEdgeFlags flags)
1568 { 1568 {
1569 return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | Right BorderEdge) 1569 return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | Right BorderEdge)
1570 || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge | BottomBorderEdge) 1570 || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge | BottomBorderEdge)
1571 || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge | LeftBorderEdge) 1571 || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge | LeftBorderEdge)
1572 || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBo rderEdge); 1572 || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBo rderEdge);
1573 } 1573 }
1574 1574
1575 void BoxPainter::paintTranslucentBorderSides(RenderObject& obj, GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedRect& outerBorder, cons t RoundedRect& innerBorder, const IntPoint& innerBorderAdjustment, 1575 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) 1576 const BorderEdge edges[], BorderEdgeFlags edgesToDraw, BackgroundBleedAvoida nce bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, b ool antialias)
1577 { 1577 {
1578 // willBeOverdrawn assumes that we draw in order: top, bottom, left, right. 1578 // willBeOverdrawn assumes that we draw in order: top, bottom, left, right.
1579 // This is different from BoxSide enum order. 1579 // This is different from BoxSide enum order.
1580 static const BoxSide paintOrder[] = { BSTop, BSBottom, BSLeft, BSRight }; 1580 static const BoxSide paintOrder[] = { BSTop, BSBottom, BSLeft, BSRight };
1581 1581
1582 while (edgesToDraw) { 1582 while (edgesToDraw) {
1583 // Find undrawn edges sharing a color. 1583 // Find undrawn edges sharing a color.
1584 Color commonColor; 1584 Color commonColor;
1585 1585
(...skipping 29 matching lines...) Expand all
1615 edgesToDraw &= ~commonColorEdgeSet; 1615 edgesToDraw &= ~commonColorEdgeSet;
1616 } 1616 }
1617 } 1617 }
1618 1618
1619 LayoutRect BoxPainter::borderInnerRectAdjustedForBleedAvoidance(GraphicsContext* context, const LayoutRect& rect, BackgroundBleedAvoidance bleedAvoidance) 1619 LayoutRect BoxPainter::borderInnerRectAdjustedForBleedAvoidance(GraphicsContext* context, const LayoutRect& rect, BackgroundBleedAvoidance bleedAvoidance)
1620 { 1620 {
1621 // We shrink the rectangle by one pixel on each side to make it fully overla p the anti-aliased background border 1621 // 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; 1622 return (bleedAvoidance == BackgroundBleedBackgroundOverBorder) ? shrinkRectB yOnePixel(context, rect) : rect;
1623 } 1623 }
1624 1624
1625 void BoxPainter::paintOneBorderSide(RenderObject& obj, GraphicsContext* graphics Context, const RenderStyle* style, const RoundedRect& outerBorder, const Rounded Rect& innerBorder, 1625 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, 1626 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) 1627 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool i ncludeLogicalRightEdge, bool antialias, const Color* overrideColor)
1628 { 1628 {
1629 const BorderEdge& edgeToRender = edges[side]; 1629 const BorderEdge& edgeToRender = edges[side];
1630 ASSERT(edgeToRender.width); 1630 ASSERT(edgeToRender.width);
1631 const BorderEdge& adjacentEdge1 = edges[adjacentSide1]; 1631 const BorderEdge& adjacentEdge1 = edges[adjacentSide1];
1632 const BorderEdge& adjacentEdge2 = edges[adjacentSide2]; 1632 const BorderEdge& adjacentEdge2 = edges[adjacentSide2];
1633 1633
1634 bool mitreAdjacentSide1 = joinRequiresMitre(side, adjacentSide1, edges, !ant ialias); 1634 bool mitreAdjacentSide1 = joinRequiresMitre(side, adjacentSide1, edges, !ant ialias);
1635 bool mitreAdjacentSide2 = joinRequiresMitre(side, adjacentSide2, edges, !ant ialias); 1635 bool mitreAdjacentSide2 = joinRequiresMitre(side, adjacentSide2, edges, !ant ialias);
1636 1636
1637 bool adjacentSide1StylesMatch = colorsMatchAtCorner(side, adjacentSide1, edg es); 1637 bool adjacentSide1StylesMatch = colorsMatchAtCorner(side, adjacentSide1, edg es);
1638 bool adjacentSide2StylesMatch = colorsMatchAtCorner(side, adjacentSide2, edg es); 1638 bool adjacentSide2StylesMatch = colorsMatchAtCorner(side, adjacentSide2, edg es);
1639 1639
1640 const Color& colorToPaint = overrideColor ? *overrideColor : edgeToRender.co lor; 1640 const Color& colorToPaint = overrideColor ? *overrideColor : edgeToRender.co lor;
1641 1641
1642 if (path) { 1642 if (path) {
1643 GraphicsContextStateSaver stateSaver(*graphicsContext); 1643 GraphicsContextStateSaver stateSaver(*graphicsContext);
1644 if (innerBorder.isRenderable()) 1644 if (innerBorder.isRenderable())
1645 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, adjacentSide1StylesMatch, adjacentSide2StylesMatch); 1645 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, adjacentSide1StylesMatch, adjacentSide2StylesMatch);
1646 else 1646 else
1647 clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, inne rBorder, side, edges); 1647 clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, inne rBorder, side, edges);
1648 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi dth), adjacentEdge2.width); 1648 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, 1649 drawBoxSideFromPath(graphicsContext, LayoutRect(outerBorder.rect()), *pa th, edges, edgeToRender.width, thickness, side, style,
1650 colorToPaint, edgeToRender.borderStyle(), bleedAvoidance, includeLog icalLeftEdge, includeLogicalRightEdge); 1650 colorToPaint, edgeToRender.borderStyle(), bleedAvoidance, includeLog icalLeftEdge, includeLogicalRightEdge);
1651 } else { 1651 } else {
1652 bool clipForStyle = styleRequiresClipPolygon(edgeToRender.borderStyle()) && (mitreAdjacentSide1 || mitreAdjacentSide2); 1652 bool clipForStyle = styleRequiresClipPolygon(edgeToRender.borderStyle()) && (mitreAdjacentSide1 || mitreAdjacentSide2);
1653 bool clipAdjacentSide1 = colorNeedsAntiAliasAtCorner(side, adjacentSide1 , edges) && mitreAdjacentSide1; 1653 bool clipAdjacentSide1 = colorNeedsAntiAliasAtCorner(side, adjacentSide1 , edges) && mitreAdjacentSide1;
1654 bool clipAdjacentSide2 = colorNeedsAntiAliasAtCorner(side, adjacentSide2 , edges) && mitreAdjacentSide2; 1654 bool clipAdjacentSide2 = colorNeedsAntiAliasAtCorner(side, adjacentSide2 , edges) && mitreAdjacentSide2;
1655 bool shouldClip = clipForStyle || clipAdjacentSide1 || clipAdjacentSide2 ; 1655 bool shouldClip = clipForStyle || clipAdjacentSide1 || clipAdjacentSide2 ;
1656 1656
1657 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip); 1657 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip);
1658 if (shouldClip) { 1658 if (shouldClip) {
1659 bool aliasAdjacentSide1 = clipAdjacentSide1 || (clipForStyle && mitr eAdjacentSide1); 1659 bool aliasAdjacentSide1 = clipAdjacentSide1 || (clipForStyle && mitr eAdjacentSide1);
1660 bool aliasAdjacentSide2 = clipAdjacentSide2 || (clipForStyle && mitr eAdjacentSide2); 1660 bool aliasAdjacentSide2 = clipAdjacentSide2 || (clipForStyle && mitr eAdjacentSide2);
1661 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, !aliasAdjacentSide1, !aliasAdjacentSide2); 1661 clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, sid e, !aliasAdjacentSide1, !aliasAdjacentSide2);
1662 // Since we clipped, no need to draw with a mitre. 1662 // Since we clipped, no need to draw with a mitre.
1663 mitreAdjacentSide1 = false; 1663 mitreAdjacentSide1 = false;
1664 mitreAdjacentSide2 = false; 1664 mitreAdjacentSide2 = false;
1665 } 1665 }
1666 1666
1667 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec t.y(), sideRect.maxX(), sideRect.maxY(), side, colorToPaint, edgeToRender.border Style(), 1667 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); 1668 mitreAdjacentSide1 ? adjacentEdge1.width : 0, mitreAdjacentSide2 ? a djacentEdge2.width : 0, antialias);
1669 } 1669 }
1670 } 1670 }
1671 1671
1672 void BoxPainter::paintBorderSides(RenderObject& obj, GraphicsContext* graphicsCo ntext, const RenderStyle* style, const RoundedRect& outerBorder, const RoundedRe ct& innerBorder, 1672 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, 1673 const IntPoint& innerBorderAdjustment, const BorderEdge edges[], BorderEdgeF lags edgeSet, BackgroundBleedAvoidance bleedAvoidance,
1674 bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, c onst Color* overrideColor) 1674 bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, c onst Color* overrideColor)
1675 { 1675 {
1676 bool renderRadii = outerBorder.isRounded(); 1676 bool renderRadii = outerBorder.isRounded();
1677 1677
1678 Path roundedPath; 1678 Path roundedPath;
1679 if (renderRadii) 1679 if (renderRadii)
1680 roundedPath.addRoundedRect(outerBorder); 1680 roundedPath.addRoundedRect(outerBorder);
1681 1681
1682 // The inner border adjustment for bleed avoidance mode BackgroundBleedBackg roundOverBorder 1682 // The inner border adjustment for bleed avoidance mode BackgroundBleedBackg roundOverBorder
1683 // is only applied to sideRect, which is okay since BackgroundBleedBackgroun dOverBorder 1683 // 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 1684 // 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. 1685 // only depends on sideRect when painting solid borders.
1686 1686
1687 if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) { 1687 if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) {
1688 IntRect sideRect = outerBorder.rect(); 1688 FloatRect sideRect = outerBorder.rect();
1689 sideRect.setHeight(edges[BSTop].width + innerBorderAdjustment.y()); 1689 sideRect.setHeight(edges[BSTop].width + innerBorderAdjustment.y());
1690 1690
1691 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].bo rderStyle()) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorde r.radii().topRight())); 1691 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 ); 1692 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSTop, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedAvoi dance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColor );
1693 } 1693 }
1694 1694
1695 if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) { 1695 if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) {
1696 IntRect sideRect = outerBorder.rect(); 1696 FloatRect sideRect = outerBorder.rect();
1697 sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width - innerBor derAdjustment.y()); 1697 sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width - innerBor derAdjustment.y());
1698 1698
1699 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom] .borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), inne rBorder.radii().bottomRight())); 1699 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); 1700 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSBottom, BSLeft, BSRight, edges, usePath ? &roundedPath : 0, bleedA voidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideCo lor);
1701 } 1701 }
1702 1702
1703 if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) { 1703 if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) {
1704 IntRect sideRect = outerBorder.rect(); 1704 FloatRect sideRect = outerBorder.rect();
1705 sideRect.setWidth(edges[BSLeft].width + innerBorderAdjustment.x()); 1705 sideRect.setWidth(edges[BSLeft].width + innerBorderAdjustment.x());
1706 1706
1707 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].b orderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerB order.radii().topLeft())); 1707 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); 1708 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSLeft, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAvo idance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideColo r);
1709 } 1709 }
1710 1710
1711 if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) { 1711 if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) {
1712 IntRect sideRect = outerBorder.rect(); 1712 FloatRect sideRect = outerBorder.rect();
1713 sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width - innerBord erAdjustment.x()); 1713 sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width - innerBord erAdjustment.x());
1714 1714
1715 bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight]. borderStyle()) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), inne rBorder.radii().topRight())); 1715 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); 1716 paintOneBorderSide(obj, graphicsContext, style, outerBorder, innerBorder , sideRect, BSRight, BSTop, BSBottom, edges, usePath ? &roundedPath : 0, bleedAv oidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias, overrideCol or);
1717 } 1717 }
1718 } 1718 }
1719 1719
1720 void BoxPainter::drawBoxSideFromPath(GraphicsContext* graphicsContext, const Lay outRect& borderRect, const Path& borderPath, const BorderEdge edges[], 1720 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 , 1721 float thickness, float drawThickness, BoxSide side, const RenderStyle* style , Color color, EBorderStyle borderStyle, BackgroundBleedAvoidance bleedAvoidance ,
1722 bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 1722 bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 int innerBorderBottomWidth; 1786 int innerBorderBottomWidth;
1787 edges[BSBottom].getDoubleBorderStripeWidths(outerBorderBottomWidth, inne rBorderBottomWidth); 1787 edges[BSBottom].getDoubleBorderStripeWidths(outerBorderBottomWidth, inne rBorderBottomWidth);
1788 1788
1789 int outerBorderLeftWidth; 1789 int outerBorderLeftWidth;
1790 int innerBorderLeftWidth; 1790 int innerBorderLeftWidth;
1791 edges[BSLeft].getDoubleBorderStripeWidths(outerBorderLeftWidth, innerBor derLeftWidth); 1791 edges[BSLeft].getDoubleBorderStripeWidths(outerBorderLeftWidth, innerBor derLeftWidth);
1792 1792
1793 // Draw inner border line 1793 // Draw inner border line
1794 { 1794 {
1795 GraphicsContextStateSaver stateSaver(*graphicsContext); 1795 GraphicsContextStateSaver stateSaver(*graphicsContext);
1796 RoundedRect innerClip = style->getRoundedInnerBorderFor(borderRect, 1796 FloatRoundedRect innerClip = style->getRoundedInnerBorderFor(borderR ect,
1797 innerBorderTopWidth, innerBorderBottomWidth, innerBorderLeftWidt h, innerBorderRightWidth, 1797 innerBorderTopWidth, innerBorderBottomWidth, innerBorderLeftWidt h, innerBorderRightWidth,
1798 includeLogicalLeftEdge, includeLogicalRightEdge); 1798 includeLogicalLeftEdge, includeLogicalRightEdge);
1799 1799
1800 graphicsContext->clipRoundedRect(innerClip); 1800 graphicsContext->clipRoundedRect(innerClip);
1801 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge); 1801 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge);
1802 } 1802 }
1803 1803
1804 // Draw outer border line 1804 // Draw outer border line
1805 { 1805 {
1806 GraphicsContextStateSaver stateSaver(*graphicsContext); 1806 GraphicsContextStateSaver stateSaver(*graphicsContext);
1807 LayoutRect outerRect = borderRect; 1807 LayoutRect outerRect = borderRect;
1808 if (bleedAvoidance == BackgroundBleedClipBackground) { 1808 if (bleedAvoidance == BackgroundBleedClipBackground) {
1809 outerRect.inflate(1); 1809 outerRect.inflate(1);
1810 ++outerBorderTopWidth; 1810 ++outerBorderTopWidth;
1811 ++outerBorderBottomWidth; 1811 ++outerBorderBottomWidth;
1812 ++outerBorderLeftWidth; 1812 ++outerBorderLeftWidth;
1813 ++outerBorderRightWidth; 1813 ++outerBorderRightWidth;
1814 } 1814 }
1815 1815
1816 RoundedRect outerClip = style->getRoundedInnerBorderFor(outerRect, 1816 FloatRoundedRect outerClip = style->getRoundedInnerBorderFor(outerRe ct,
1817 outerBorderTopWidth, outerBorderBottomWidth, outerBorderLeftWidt h, outerBorderRightWidth, 1817 outerBorderTopWidth, outerBorderBottomWidth, outerBorderLeftWidt h, outerBorderRightWidth,
1818 includeLogicalLeftEdge, includeLogicalRightEdge); 1818 includeLogicalLeftEdge, includeLogicalRightEdge);
1819 graphicsContext->clipOutRoundedRect(outerClip); 1819 graphicsContext->clipOutRoundedRect(outerClip);
1820 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge); 1820 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thickness, drawThickness, side, style, color, SOLID, bleedAvoidance, includeLogi calLeftEdge, includeLogicalRightEdge);
1821 } 1821 }
1822 return; 1822 return;
1823 } 1823 }
1824 case RIDGE: 1824 case RIDGE:
1825 case GROOVE: 1825 case GROOVE:
1826 { 1826 {
(...skipping 10 matching lines...) Expand all
1837 // Paint full border 1837 // Paint full border
1838 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s1, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge); 1838 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s1, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge);
1839 1839
1840 // Paint inner only 1840 // Paint inner only
1841 GraphicsContextStateSaver stateSaver(*graphicsContext); 1841 GraphicsContextStateSaver stateSaver(*graphicsContext);
1842 LayoutUnit topWidth = edges[BSTop].usedWidth() / 2; 1842 LayoutUnit topWidth = edges[BSTop].usedWidth() / 2;
1843 LayoutUnit bottomWidth = edges[BSBottom].usedWidth() / 2; 1843 LayoutUnit bottomWidth = edges[BSBottom].usedWidth() / 2;
1844 LayoutUnit leftWidth = edges[BSLeft].usedWidth() / 2; 1844 LayoutUnit leftWidth = edges[BSLeft].usedWidth() / 2;
1845 LayoutUnit rightWidth = edges[BSRight].usedWidth() / 2; 1845 LayoutUnit rightWidth = edges[BSRight].usedWidth() / 2;
1846 1846
1847 RoundedRect clipRect = style->getRoundedInnerBorderFor(borderRect, 1847 FloatRoundedRect clipRect = style->getRoundedInnerBorderFor(borderRect,
1848 topWidth, bottomWidth, leftWidth, rightWidth, 1848 topWidth, bottomWidth, leftWidth, rightWidth,
1849 includeLogicalLeftEdge, includeLogicalRightEdge); 1849 includeLogicalLeftEdge, includeLogicalRightEdge);
1850 1850
1851 graphicsContext->clipRoundedRect(clipRect); 1851 graphicsContext->clipRoundedRect(clipRect);
1852 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s2, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge); 1852 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, edges, thic kness, drawThickness, side, style, color, s2, bleedAvoidance, includeLogicalLeft Edge, includeLogicalRightEdge);
1853 return; 1853 return;
1854 } 1854 }
1855 case INSET: 1855 case INSET:
1856 if (side == BSTop || side == BSLeft) 1856 if (side == BSTop || side == BSLeft)
1857 color = color.dark(); 1857 color = color.dark();
(...skipping 11 matching lines...) Expand all
1869 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); 1869 graphicsContext->drawRect(pixelSnappedIntRect(borderRect));
1870 } 1870 }
1871 1871
1872 void BoxPainter::paintBoxShadow(const PaintInfo& info, const LayoutRect& paintRe ct, const RenderStyle* s, ShadowStyle shadowStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) 1872 void BoxPainter::paintBoxShadow(const PaintInfo& info, const LayoutRect& paintRe ct, const RenderStyle* s, ShadowStyle shadowStyle, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
1873 { 1873 {
1874 // FIXME: Deal with border-image. Would be great to use border-image as a ma sk. 1874 // FIXME: Deal with border-image. Would be great to use border-image as a ma sk.
1875 GraphicsContext* context = info.context; 1875 GraphicsContext* context = info.context;
1876 if (!s->boxShadow()) 1876 if (!s->boxShadow())
1877 return; 1877 return;
1878 1878
1879 RoundedRect border = (shadowStyle == Inset) ? s->getRoundedInnerBorderFor(pa intRect, includeLogicalLeftEdge, includeLogicalRightEdge) 1879 FloatRoundedRect border = (shadowStyle == Inset) ? s->getRoundedInnerBorderF or(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
1880 : s->getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogic alRightEdge); 1880 : s->getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogic alRightEdge);
1881 1881
1882 bool hasBorderRadius = s->hasBorderRadius(); 1882 bool hasBorderRadius = s->hasBorderRadius();
1883 bool isHorizontal = s->isHorizontalWritingMode(); 1883 bool isHorizontal = s->isHorizontalWritingMode();
1884 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).alpha() == 255; 1884 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).alpha() == 255;
1885 1885
1886 GraphicsContextStateSaver stateSaver(*context, false); 1886 GraphicsContextStateSaver stateSaver(*context, false);
1887 1887
1888 const ShadowList* shadowList = s->boxShadow(); 1888 const ShadowList* shadowList = s->boxShadow();
1889 for (size_t i = shadowList->shadows().size(); i--; ) { 1889 for (size_t i = shadowList->shadows().size(); i--; ) {
(...skipping 18 matching lines...) Expand all
1908 1908
1909 FloatRect shadowRect(border.rect()); 1909 FloatRect shadowRect(border.rect());
1910 shadowRect.inflate(shadowBlur + shadowSpread); 1910 shadowRect.inflate(shadowBlur + shadowSpread);
1911 shadowRect.move(shadowOffset); 1911 shadowRect.move(shadowOffset);
1912 1912
1913 // Save the state and clip, if not already done. 1913 // Save the state and clip, if not already done.
1914 // The clip does not depend on any shadow-specific properties. 1914 // The clip does not depend on any shadow-specific properties.
1915 if (!stateSaver.saved()) { 1915 if (!stateSaver.saved()) {
1916 stateSaver.save(); 1916 stateSaver.save();
1917 if (hasBorderRadius) { 1917 if (hasBorderRadius) {
1918 RoundedRect rectToClipOut = border; 1918 FloatRoundedRect rectToClipOut = border;
1919 1919
1920 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 1920 // 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 1921 // 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. 1922 // corners. Those are avoided by insetting the clipping path by one pixel.
1923 if (hasOpaqueBackground) 1923 if (hasOpaqueBackground)
1924 rectToClipOut.inflateWithRadii(-1); 1924 rectToClipOut.inflateWithRadii(-1);
1925 1925
1926 if (!rectToClipOut.isEmpty()) { 1926 if (!rectToClipOut.isEmpty()) {
1927 context->clipOutRoundedRect(rectToClipOut); 1927 context->clipOutRoundedRect(rectToClipOut);
1928 } 1928 }
1929 } else { 1929 } else {
1930 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle 1930 // 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. 1931 // of the box itself, which is always pixel-aligned.
1932 IntRect rectToClipOut = border.rect(); 1932 FloatRect rectToClipOut = border.rect();
1933 1933
1934 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 1934 // 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 1935 // 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 1936 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
1937 // by one pixel. 1937 // by one pixel.
1938 if (hasOpaqueBackground) { 1938 if (hasOpaqueBackground) {
1939 // FIXME: The function to decide on the policy based on the transform should be a named function. 1939 // 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? 1940 // 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 1941 // 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. 1942 // device zoom applied at raster time.
1943 AffineTransform transform = context->getCTM(); 1943 AffineTransform transform = context->getCTM();
1944 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c()) 1944 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c())
1945 rectToClipOut.inflate(-1); 1945 rectToClipOut.inflate(-1);
1946 } 1946 }
1947 1947
1948 if (!rectToClipOut.isEmpty()) { 1948 if (!rectToClipOut.isEmpty()) {
1949 context->clipOut(rectToClipOut); 1949 context->clipOut(rectToClipOut);
1950 } 1950 }
1951 } 1951 }
1952 } 1952 }
1953 1953
1954 // Draw only the shadow. 1954 // Draw only the shadow.
1955 context->setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooper Builder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawSh adowOnly); 1955 context->setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooper Builder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawSh adowOnly);
1956 1956
1957 if (hasBorderRadius) { 1957 if (hasBorderRadius) {
1958 RoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowR ect)), border.radii()); 1958 FloatRoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(sh adowRect)), border.radii());
1959 influenceRect.expandRadii(2 * shadowBlur + shadowSpread); 1959 influenceRect.expandRadii(2 * shadowBlur + shadowSpread);
1960 if (allCornersClippedOut(influenceRect, info.rect)) { 1960 if (allCornersClippedOut(influenceRect, info.rect)) {
1961 context->fillRect(fillRect, Color::black); 1961 context->fillRect(fillRect, Color::black);
1962 } else { 1962 } else {
1963 // TODO: support non-integer shadows - crbug.com/334829 1963 // TODO: support non-integer shadows - crbug.com/334829
1964 RoundedRect roundedFillRect = border; 1964 FloatRoundedRect roundedFillRect = border;
1965 roundedFillRect.inflate(shadowSpread); 1965 roundedFillRect.inflate(shadowSpread);
1966 1966
1967 roundedFillRect.expandRadii(shadowSpread); 1967 roundedFillRect.expandRadii(shadowSpread);
1968 if (!roundedFillRect.isRenderable()) 1968 if (!roundedFillRect.isRenderable())
1969 roundedFillRect.adjustRadii(); 1969 roundedFillRect.adjustRadii();
1970 context->fillRoundedRect(roundedFillRect, Color::black); 1970 context->fillRoundedRect(roundedFillRect, Color::black);
1971 } 1971 }
1972 } else { 1972 } else {
1973 context->fillRect(fillRect, Color::black); 1973 context->fillRect(fillRect, Color::black);
1974 } 1974 }
(...skipping 11 matching lines...) Expand all
1986 clippedEdges |= GraphicsContext::RightEdge; 1986 clippedEdges |= GraphicsContext::RightEdge;
1987 else 1987 else
1988 clippedEdges |= GraphicsContext::BottomEdge; 1988 clippedEdges |= GraphicsContext::BottomEdge;
1989 } 1989 }
1990 // TODO: support non-integer shadows - crbug.com/334828 1990 // TODO: support non-integer shadows - crbug.com/334828
1991 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges); 1991 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges);
1992 } 1992 }
1993 } 1993 }
1994 } 1994 }
1995 1995
1996 void BoxPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, const R oundedRect& outerBorder, const RoundedRect& innerBorder, BoxSide side, bool firs tEdgeMatches, bool secondEdgeMatches) 1996 void BoxPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, const F loatRoundedRect& outerBorder, const FloatRoundedRect& innerBorder, BoxSide side, bool firstEdgeMatches, bool secondEdgeMatches)
1997 { 1997 {
1998 FloatPoint quad[4]; 1998 FloatPoint quad[4];
1999 1999
2000 const LayoutRect& outerRect = outerBorder.rect(); 2000 const LayoutRect& outerRect(outerBorder.rect());
2001 const LayoutRect& innerRect = innerBorder.rect(); 2001 const LayoutRect& innerRect(innerBorder.rect());
2002 2002
2003 FloatPoint centerPoint(innerRect.location().x().toFloat() + innerRect.width( ).toFloat() / 2, innerRect.location().y().toFloat() + innerRect.height().toFloat () / 2); 2003 FloatPoint centerPoint(innerRect.location().x().toFloat() + innerRect.width( ).toFloat() / 2, innerRect.location().y().toFloat() + innerRect.height().toFloat () / 2);
2004 2004
2005 // For each side, create a quad that encompasses all parts of that side that may draw, 2005 // For each side, create a quad that encompasses all parts of that side that may draw,
2006 // including areas inside the innerBorder. 2006 // including areas inside the innerBorder.
2007 // 2007 //
2008 // 0----------------3 2008 // 0----------------3
2009 // 0 \ / 0 2009 // 0 \ / 0
2010 // |\ 1----------- 2 /| 2010 // |\ 1----------- 2 /|
2011 // | 1 1 | 2011 // | 1 1 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 2173
2174 FloatPoint secondQuad[4]; 2174 FloatPoint secondQuad[4];
2175 secondQuad[0] = quad[0]; 2175 secondQuad[0] = quad[0];
2176 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy); 2176 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy);
2177 secondQuad[2] = quad[2]; 2177 secondQuad[2] = quad[2];
2178 secondQuad[3] = quad[3]; 2178 secondQuad[3] = quad[3];
2179 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches); 2179 graphicsContext->clipPolygon(4, secondQuad, !secondEdgeMatches);
2180 } 2180 }
2181 2181
2182 } // namespace blink 2182 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698