OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/BoxBorderPainter.h" | 6 #include "core/paint/BoxBorderPainter.h" |
7 | 7 |
8 #include "core/paint/BoxPainter.h" | 8 #include "core/paint/BoxPainter.h" |
9 #include "core/paint/PaintInfo.h" | 9 #include "core/paint/PaintInfo.h" |
10 #include "core/style/BorderEdge.h" | 10 #include "core/style/BorderEdge.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 LayoutRectOutsets doubleStripeInsets(const BorderEdge edges[], BorderEdge::Doubl
eBorderStripe stripe) | 244 LayoutRectOutsets doubleStripeInsets(const BorderEdge edges[], BorderEdge::Doubl
eBorderStripe stripe) |
245 { | 245 { |
246 // Insets are representes as negative outsets. | 246 // Insets are representes as negative outsets. |
247 return LayoutRectOutsets( | 247 return LayoutRectOutsets( |
248 -edges[BSTop].getDoubleBorderStripeWidth(stripe), | 248 -edges[BSTop].getDoubleBorderStripeWidth(stripe), |
249 -edges[BSRight].getDoubleBorderStripeWidth(stripe), | 249 -edges[BSRight].getDoubleBorderStripeWidth(stripe), |
250 -edges[BSBottom].getDoubleBorderStripeWidth(stripe), | 250 -edges[BSBottom].getDoubleBorderStripeWidth(stripe), |
251 -edges[BSLeft].getDoubleBorderStripeWidth(stripe)); | 251 -edges[BSLeft].getDoubleBorderStripeWidth(stripe)); |
252 } | 252 } |
253 | 253 |
254 void drawSolidBorderRect(GraphicsContext* context, const FloatRect& borderRect, | 254 void drawSolidBorderRect(GraphicsContext& context, const FloatRect& borderRect, |
255 float borderWidth, const Color& color) | 255 float borderWidth, const Color& color) |
256 { | 256 { |
257 FloatRect strokeRect(borderRect); | 257 FloatRect strokeRect(borderRect); |
258 strokeRect.inflate(-borderWidth / 2); | 258 strokeRect.inflate(-borderWidth / 2); |
259 | 259 |
260 bool wasAntialias = context->shouldAntialias(); | 260 bool wasAntialias = context.shouldAntialias(); |
261 if (!wasAntialias) | 261 if (!wasAntialias) |
262 context->setShouldAntialias(true); | 262 context.setShouldAntialias(true); |
263 | 263 |
264 context->setStrokeStyle(SolidStroke); | 264 context.setStrokeStyle(SolidStroke); |
265 context->setStrokeColor(color); | 265 context.setStrokeColor(color); |
266 context->strokeRect(strokeRect, borderWidth); | 266 context.strokeRect(strokeRect, borderWidth); |
267 | 267 |
268 if (!wasAntialias) | 268 if (!wasAntialias) |
269 context->setShouldAntialias(false); | 269 context.setShouldAntialias(false); |
270 } | 270 } |
271 | 271 |
272 void drawBleedAdjustedDRRect(GraphicsContext* context, BackgroundBleedAvoidance
bleedAvoidance, | 272 void drawBleedAdjustedDRRect(GraphicsContext& context, BackgroundBleedAvoidance
bleedAvoidance, |
273 const FloatRoundedRect& outer, const FloatRoundedRect& inner, Color color) | 273 const FloatRoundedRect& outer, const FloatRoundedRect& inner, Color color) |
274 { | 274 { |
275 switch (bleedAvoidance) { | 275 switch (bleedAvoidance) { |
276 case BackgroundBleedClipLayer: { | 276 case BackgroundBleedClipLayer: { |
277 // BackgroundBleedClipLayer clips the outer rrect for the whole layer. B
ased on this, | 277 // BackgroundBleedClipLayer clips the outer rrect for the whole layer. B
ased on this, |
278 // we can avoid background bleeding by filling the *outside* of inner rr
ect, all the | 278 // we can avoid background bleeding by filling the *outside* of inner rr
ect, all the |
279 // way to the layer bounds (enclosing int rect for the clip, in device s
pace). | 279 // way to the layer bounds (enclosing int rect for the clip, in device s
pace). |
280 ASSERT(outer.isRounded()); | 280 ASSERT(outer.isRounded()); |
281 | 281 |
282 SkPath path; | 282 SkPath path; |
283 path.addRRect(inner); | 283 path.addRRect(inner); |
284 path.setFillType(SkPath::kInverseWinding_FillType); | 284 path.setFillType(SkPath::kInverseWinding_FillType); |
285 | 285 |
286 SkPaint paint; | 286 SkPaint paint; |
287 paint.setColor(color.rgb()); | 287 paint.setColor(color.rgb()); |
288 paint.setStyle(SkPaint::kFill_Style); | 288 paint.setStyle(SkPaint::kFill_Style); |
289 paint.setAntiAlias(true); | 289 paint.setAntiAlias(true); |
290 context->drawPath(path, paint); | 290 context.drawPath(path, paint); |
291 | 291 |
292 break; | 292 break; |
293 } | 293 } |
294 case BackgroundBleedClipOnly: | 294 case BackgroundBleedClipOnly: |
295 if (outer.isRounded()) { | 295 if (outer.isRounded()) { |
296 // BackgroundBleedClipOnly clips the outer rrect corners for us. | 296 // BackgroundBleedClipOnly clips the outer rrect corners for us. |
297 FloatRoundedRect adjustedOuter = outer; | 297 FloatRoundedRect adjustedOuter = outer; |
298 adjustedOuter.setRadii(FloatRoundedRect::Radii()); | 298 adjustedOuter.setRadii(FloatRoundedRect::Radii()); |
299 context->fillDRRect(adjustedOuter, inner, color); | 299 context.fillDRRect(adjustedOuter, inner, color); |
300 break; | 300 break; |
301 } | 301 } |
302 // fall through | 302 // fall through |
303 default: | 303 default: |
304 context->fillDRRect(outer, inner, color); | 304 context.fillDRRect(outer, inner, color); |
305 break; | 305 break; |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 bool bleedAvoidanceIsClipping(BackgroundBleedAvoidance bleedAvoidance) | 309 bool bleedAvoidanceIsClipping(BackgroundBleedAvoidance bleedAvoidance) |
310 { | 310 { |
311 return bleedAvoidance == BackgroundBleedClipOnly || bleedAvoidance == Backgr
oundBleedClipLayer; | 311 return bleedAvoidance == BackgroundBleedClipOnly || bleedAvoidance == Backgr
oundBleedClipLayer; |
312 } | 312 } |
313 | 313 |
314 // The LUTs below assume specific enum values. | 314 // The LUTs below assume specific enum values. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 ASSERT(!opacityGroups.isEmpty()); | 432 ASSERT(!opacityGroups.isEmpty()); |
433 OpacityGroup& currentGroup = opacityGroups.last(); | 433 OpacityGroup& currentGroup = opacityGroups.last(); |
434 currentGroup.sides.append(side); | 434 currentGroup.sides.append(side); |
435 currentGroup.edgeFlags |= edgeFlagForSide(side); | 435 currentGroup.edgeFlags |= edgeFlagForSide(side); |
436 } | 436 } |
437 | 437 |
438 ASSERT(!opacityGroups.isEmpty()); | 438 ASSERT(!opacityGroups.isEmpty()); |
439 } | 439 } |
440 }; | 440 }; |
441 | 441 |
442 void BoxBorderPainter::drawDoubleBorder(GraphicsContext* context, const LayoutRe
ct& borderRect) const | 442 void BoxBorderPainter::drawDoubleBorder(GraphicsContext& context, const LayoutRe
ct& borderRect) const |
443 { | 443 { |
444 ASSERT(m_isUniformColor); | 444 ASSERT(m_isUniformColor); |
445 ASSERT(m_isUniformStyle); | 445 ASSERT(m_isUniformStyle); |
446 ASSERT(firstEdge().borderStyle() == DOUBLE); | 446 ASSERT(firstEdge().borderStyle() == DOUBLE); |
447 ASSERT(m_visibleEdgeSet == AllBorderEdges); | 447 ASSERT(m_visibleEdgeSet == AllBorderEdges); |
448 | 448 |
449 const Color color = firstEdge().color; | 449 const Color color = firstEdge().color; |
450 | 450 |
451 // outer stripe | 451 // outer stripe |
452 const LayoutRectOutsets outerThirdInsets = | 452 const LayoutRectOutsets outerThirdInsets = |
453 doubleStripeInsets(m_edges, BorderEdge::DoubleBorderStripeOuter); | 453 doubleStripeInsets(m_edges, BorderEdge::DoubleBorderStripeOuter); |
454 const FloatRoundedRect outerThirdRect = m_style.getRoundedInnerBorderFor(bor
derRect, | 454 const FloatRoundedRect outerThirdRect = m_style.getRoundedInnerBorderFor(bor
derRect, |
455 outerThirdInsets, m_includeLogicalLeftEdge, m_includeLogicalRightEdge); | 455 outerThirdInsets, m_includeLogicalLeftEdge, m_includeLogicalRightEdge); |
456 drawBleedAdjustedDRRect(context, m_bleedAvoidance, m_outer, outerThirdRect,
color); | 456 drawBleedAdjustedDRRect(context, m_bleedAvoidance, m_outer, outerThirdRect,
color); |
457 | 457 |
458 // inner stripe | 458 // inner stripe |
459 const LayoutRectOutsets innerThirdInsets = | 459 const LayoutRectOutsets innerThirdInsets = |
460 doubleStripeInsets(m_edges, BorderEdge::DoubleBorderStripeInner); | 460 doubleStripeInsets(m_edges, BorderEdge::DoubleBorderStripeInner); |
461 const FloatRoundedRect innerThirdRect = m_style.getRoundedInnerBorderFor(bor
derRect, | 461 const FloatRoundedRect innerThirdRect = m_style.getRoundedInnerBorderFor(bor
derRect, |
462 innerThirdInsets, m_includeLogicalLeftEdge, m_includeLogicalRightEdge); | 462 innerThirdInsets, m_includeLogicalLeftEdge, m_includeLogicalRightEdge); |
463 context->fillDRRect(innerThirdRect, m_inner, color); | 463 context.fillDRRect(innerThirdRect, m_inner, color); |
464 } | 464 } |
465 | 465 |
466 bool BoxBorderPainter::paintBorderFastPath(GraphicsContext* context, const Layou
tRect& borderRect) const | 466 bool BoxBorderPainter::paintBorderFastPath(GraphicsContext& context, const Layou
tRect& borderRect) const |
467 { | 467 { |
468 if (!m_isUniformColor || !m_isUniformStyle || !m_inner.isRenderable()) | 468 if (!m_isUniformColor || !m_isUniformStyle || !m_inner.isRenderable()) |
469 return false; | 469 return false; |
470 | 470 |
471 if (firstEdge().borderStyle() != SOLID && firstEdge().borderStyle() != DOUBL
E) | 471 if (firstEdge().borderStyle() != SOLID && firstEdge().borderStyle() != DOUBL
E) |
472 return false; | 472 return false; |
473 | 473 |
474 if (m_visibleEdgeSet == AllBorderEdges) { | 474 if (m_visibleEdgeSet == AllBorderEdges) { |
475 if (firstEdge().borderStyle() == SOLID) { | 475 if (firstEdge().borderStyle() == SOLID) { |
476 if (m_isUniformWidth && !m_outer.isRounded()) { | 476 if (m_isUniformWidth && !m_outer.isRounded()) { |
(...skipping 19 matching lines...) Expand all Loading... |
496 // solid, rectangular border => one drawPath() | 496 // solid, rectangular border => one drawPath() |
497 Path path; | 497 Path path; |
498 path.setWindRule(RULE_NONZERO); | 498 path.setWindRule(RULE_NONZERO); |
499 | 499 |
500 for (int i = BSTop; i <= BSLeft; ++i) { | 500 for (int i = BSTop; i <= BSLeft; ++i) { |
501 const BorderEdge& currEdge = m_edges[i]; | 501 const BorderEdge& currEdge = m_edges[i]; |
502 if (currEdge.shouldRender()) | 502 if (currEdge.shouldRender()) |
503 path.addRect(calculateSideRect(m_outer, currEdge, i)); | 503 path.addRect(calculateSideRect(m_outer, currEdge, i)); |
504 } | 504 } |
505 | 505 |
506 context->setFillColor(firstEdge().color); | 506 context.setFillColor(firstEdge().color); |
507 context->fillPath(path); | 507 context.fillPath(path); |
508 return true; | 508 return true; |
509 } | 509 } |
510 | 510 |
511 return false; | 511 return false; |
512 } | 512 } |
513 | 513 |
514 BoxBorderPainter::BoxBorderPainter(const LayoutRect& borderRect, const ComputedS
tyle& style, | 514 BoxBorderPainter::BoxBorderPainter(const LayoutRect& borderRect, const ComputedS
tyle& style, |
515 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, | 515 BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, |
516 bool includeLogicalRightEdge) | 516 bool includeLogicalRightEdge) |
517 : m_style(style) | 517 : m_style(style) |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 m_isUniformWidth &= edge.width == m_edges[m_firstVisibleEdge].width; | 593 m_isUniformWidth &= edge.width == m_edges[m_firstVisibleEdge].width; |
594 m_isUniformColor &= edge.color == m_edges[m_firstVisibleEdge].color; | 594 m_isUniformColor &= edge.color == m_edges[m_firstVisibleEdge].color; |
595 } | 595 } |
596 } | 596 } |
597 | 597 |
598 void BoxBorderPainter::paintBorder(const PaintInfo& info, const LayoutRect& rect
) const | 598 void BoxBorderPainter::paintBorder(const PaintInfo& info, const LayoutRect& rect
) const |
599 { | 599 { |
600 if (!m_visibleEdgeCount || m_outer.rect().isEmpty()) | 600 if (!m_visibleEdgeCount || m_outer.rect().isEmpty()) |
601 return; | 601 return; |
602 | 602 |
603 GraphicsContext* graphicsContext = info.context; | 603 GraphicsContext& graphicsContext = info.context; |
604 | 604 |
605 if (paintBorderFastPath(graphicsContext, rect)) | 605 if (paintBorderFastPath(graphicsContext, rect)) |
606 return; | 606 return; |
607 | 607 |
608 bool clipToOuterBorder = m_outer.isRounded(); | 608 bool clipToOuterBorder = m_outer.isRounded(); |
609 GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder); | 609 GraphicsContextStateSaver stateSaver(graphicsContext, clipToOuterBorder); |
610 if (clipToOuterBorder) { | 610 if (clipToOuterBorder) { |
611 // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already
applied. | 611 // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already
applied. |
612 if (!bleedAvoidanceIsClipping(m_bleedAvoidance)) | 612 if (!bleedAvoidanceIsClipping(m_bleedAvoidance)) |
613 graphicsContext->clipRoundedRect(m_outer); | 613 graphicsContext.clipRoundedRect(m_outer); |
614 | 614 |
615 if (m_inner.isRenderable() && !m_inner.isEmpty()) | 615 if (m_inner.isRenderable() && !m_inner.isEmpty()) |
616 graphicsContext->clipOutRoundedRect(m_inner); | 616 graphicsContext.clipOutRoundedRect(m_inner); |
617 } | 617 } |
618 | 618 |
619 const ComplexBorderInfo borderInfo(*this, true); | 619 const ComplexBorderInfo borderInfo(*this, true); |
620 paintOpacityGroup(graphicsContext, borderInfo, 0, 1); | 620 paintOpacityGroup(graphicsContext, borderInfo, 0, 1); |
621 } | 621 } |
622 | 622 |
623 // In order to maximize the use of overdraw as a corner seam avoidance technique
, we draw | 623 // In order to maximize the use of overdraw as a corner seam avoidance technique
, we draw |
624 // translucent border sides using the following algorithm: | 624 // translucent border sides using the following algorithm: |
625 // | 625 // |
626 // 1) cluster sides sharing the same opacity into "opacity groups" [ComplexBor
derInfo] | 626 // 1) cluster sides sharing the same opacity into "opacity groups" [ComplexBor
derInfo] |
(...skipping 28 matching lines...) Expand all Loading... |
655 // beginLayer(0.5) // layer for group 2 (effective opacity: 0.5
* 0.5 == 0.25) | 655 // beginLayer(0.5) // layer for group 2 (effective opacity: 0.5
* 0.5 == 0.25) |
656 // paintSides(right, left) // paint group 2 | 656 // paintSides(right, left) // paint group 2 |
657 // endLayer | 657 // endLayer |
658 // paintSides(bottom) // paint group 1 | 658 // paintSides(bottom) // paint group 1 |
659 // endLayer | 659 // endLayer |
660 // paintSides(top) // paint group 0 | 660 // paintSides(top) // paint group 0 |
661 // | 661 // |
662 // Note that we're always drawing using opaque paints on top of less-opaque cont
ent - hence | 662 // Note that we're always drawing using opaque paints on top of less-opaque cont
ent - hence |
663 // we can use overdraw to mask portions of the previous sides. | 663 // we can use overdraw to mask portions of the previous sides. |
664 // | 664 // |
665 BorderEdgeFlags BoxBorderPainter::paintOpacityGroup(GraphicsContext* context, | 665 BorderEdgeFlags BoxBorderPainter::paintOpacityGroup(GraphicsContext& context, |
666 const ComplexBorderInfo& borderInfo, unsigned index, float effectiveOpacity)
const | 666 const ComplexBorderInfo& borderInfo, unsigned index, float effectiveOpacity)
const |
667 { | 667 { |
668 ASSERT(effectiveOpacity > 0 && effectiveOpacity <= 1); | 668 ASSERT(effectiveOpacity > 0 && effectiveOpacity <= 1); |
669 | 669 |
670 const size_t opacityGroupCount = borderInfo.opacityGroups.size(); | 670 const size_t opacityGroupCount = borderInfo.opacityGroups.size(); |
671 | 671 |
672 // For overdraw logic purposes, treat missing/transparent edges as completed
. | 672 // For overdraw logic purposes, treat missing/transparent edges as completed
. |
673 if (index >= opacityGroupCount) | 673 if (index >= opacityGroupCount) |
674 return ~m_visibleEdgeSet; | 674 return ~m_visibleEdgeSet; |
675 | 675 |
676 // Groups are sorted in increasing opacity order, but we need to create laye
rs in | 676 // Groups are sorted in increasing opacity order, but we need to create laye
rs in |
677 // decreasing opacity order - hence the reverse iteration. | 677 // decreasing opacity order - hence the reverse iteration. |
678 const OpacityGroup& group = borderInfo.opacityGroups[opacityGroupCount - ind
ex - 1]; | 678 const OpacityGroup& group = borderInfo.opacityGroups[opacityGroupCount - ind
ex - 1]; |
679 | 679 |
680 // Adjust this group's paint opacity to account for ancestor transparency la
yers | 680 // Adjust this group's paint opacity to account for ancestor transparency la
yers |
681 // (needed in case we avoid creating a layer below). | 681 // (needed in case we avoid creating a layer below). |
682 unsigned paintAlpha = group.alpha / effectiveOpacity; | 682 unsigned paintAlpha = group.alpha / effectiveOpacity; |
683 ASSERT(paintAlpha <= 255); | 683 ASSERT(paintAlpha <= 255); |
684 | 684 |
685 // For the last (bottom) group, we can skip the layer even in the presence o
f opacity iff | 685 // For the last (bottom) group, we can skip the layer even in the presence o
f opacity iff |
686 // it contains no adjecent edges (no in-group overdraw possibility). | 686 // it contains no adjecent edges (no in-group overdraw possibility). |
687 bool needsLayer = group.alpha != 255 | 687 bool needsLayer = group.alpha != 255 |
688 && (includesAdjacentEdges(group.edgeFlags) || (index + 1 < borderInfo.op
acityGroups.size())); | 688 && (includesAdjacentEdges(group.edgeFlags) || (index + 1 < borderInfo.op
acityGroups.size())); |
689 | 689 |
690 if (needsLayer) { | 690 if (needsLayer) { |
691 const float groupOpacity = static_cast<float>(group.alpha) / 255; | 691 const float groupOpacity = static_cast<float>(group.alpha) / 255; |
692 ASSERT(groupOpacity < effectiveOpacity); | 692 ASSERT(groupOpacity < effectiveOpacity); |
693 | 693 |
694 context->beginLayer(groupOpacity / effectiveOpacity); | 694 context.beginLayer(groupOpacity / effectiveOpacity); |
695 effectiveOpacity = groupOpacity; | 695 effectiveOpacity = groupOpacity; |
696 | 696 |
697 // Group opacity is applied via a layer => we draw the members using opa
que paint. | 697 // Group opacity is applied via a layer => we draw the members using opa
que paint. |
698 paintAlpha = 255; | 698 paintAlpha = 255; |
699 } | 699 } |
700 | 700 |
701 // Recursion may seem unpalatable here, but | 701 // Recursion may seem unpalatable here, but |
702 // a) it has an upper bound of 4 | 702 // a) it has an upper bound of 4 |
703 // b) only triggers at all when mixing border sides with different opaciti
es | 703 // b) only triggers at all when mixing border sides with different opaciti
es |
704 // c) it allows us to express the layer nesting algorithm more naturally | 704 // c) it allows us to express the layer nesting algorithm more naturally |
705 BorderEdgeFlags completedEdges = paintOpacityGroup(context, borderInfo, inde
x + 1, effectiveOpacity); | 705 BorderEdgeFlags completedEdges = paintOpacityGroup(context, borderInfo, inde
x + 1, effectiveOpacity); |
706 | 706 |
707 // Paint the actual group edges with an alpha adjusted to account for ancens
tor layers opacity. | 707 // Paint the actual group edges with an alpha adjusted to account for ancens
tor layers opacity. |
708 for (BoxSide side : group.sides) { | 708 for (BoxSide side : group.sides) { |
709 paintSide(context, borderInfo, side, paintAlpha, completedEdges); | 709 paintSide(context, borderInfo, side, paintAlpha, completedEdges); |
710 completedEdges |= edgeFlagForSide(side); | 710 completedEdges |= edgeFlagForSide(side); |
711 } | 711 } |
712 | 712 |
713 if (needsLayer) | 713 if (needsLayer) |
714 context->endLayer(); | 714 context.endLayer(); |
715 | 715 |
716 return completedEdges; | 716 return completedEdges; |
717 } | 717 } |
718 | 718 |
719 void BoxBorderPainter::paintSide(GraphicsContext* context, const ComplexBorderIn
fo& borderInfo, | 719 void BoxBorderPainter::paintSide(GraphicsContext& context, const ComplexBorderIn
fo& borderInfo, |
720 BoxSide side, unsigned alpha, BorderEdgeFlags completedEdges) const | 720 BoxSide side, unsigned alpha, BorderEdgeFlags completedEdges) const |
721 { | 721 { |
722 const BorderEdge& edge = m_edges[side]; | 722 const BorderEdge& edge = m_edges[side]; |
723 ASSERT(edge.shouldRender()); | 723 ASSERT(edge.shouldRender()); |
724 const Color color(edge.color.red(), edge.color.green(), edge.color.blue(), a
lpha); | 724 const Color color(edge.color.red(), edge.color.green(), edge.color.blue(), a
lpha); |
725 | 725 |
726 FloatRect sideRect = m_outer.rect(); | 726 FloatRect sideRect = m_outer.rect(); |
727 const Path* path = nullptr; | 727 const Path* path = nullptr; |
728 | 728 |
729 // TODO(fmalita): find a way to consolidate these without sacrificing readab
ility. | 729 // TODO(fmalita): find a way to consolidate these without sacrificing readab
ility. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 ? miter1 == HardMiter || miter2 == HardMiter | 815 ? miter1 == HardMiter || miter2 == HardMiter |
816 : miter1 == SoftMiter || miter2 == SoftMiter; | 816 : miter1 == SoftMiter || miter2 == SoftMiter; |
817 | 817 |
818 // Some styles require clipping for any type of miter. | 818 // Some styles require clipping for any type of miter. |
819 shouldClip = shouldClip | 819 shouldClip = shouldClip |
820 || ((miter1 != NoMiter || miter2 != NoMiter) && styleRequiresClipPolygon
(style)); | 820 || ((miter1 != NoMiter || miter2 != NoMiter) && styleRequiresClipPolygon
(style)); |
821 | 821 |
822 return shouldClip; | 822 return shouldClip; |
823 } | 823 } |
824 | 824 |
825 void BoxBorderPainter::paintOneBorderSide(GraphicsContext* graphicsContext, | 825 void BoxBorderPainter::paintOneBorderSide(GraphicsContext& graphicsContext, |
826 const FloatRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adja
centSide2, | 826 const FloatRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adja
centSide2, |
827 const Path* path, bool antialias, Color color, BorderEdgeFlags completedEdge
s) const | 827 const Path* path, bool antialias, Color color, BorderEdgeFlags completedEdge
s) const |
828 { | 828 { |
829 const BorderEdge& edgeToRender = m_edges[side]; | 829 const BorderEdge& edgeToRender = m_edges[side]; |
830 ASSERT(edgeToRender.width); | 830 ASSERT(edgeToRender.width); |
831 const BorderEdge& adjacentEdge1 = m_edges[adjacentSide1]; | 831 const BorderEdge& adjacentEdge1 = m_edges[adjacentSide1]; |
832 const BorderEdge& adjacentEdge2 = m_edges[adjacentSide2]; | 832 const BorderEdge& adjacentEdge2 = m_edges[adjacentSide2]; |
833 | 833 |
834 if (path) { | 834 if (path) { |
835 MiterType miter1 = colorsMatchAtCorner(side, adjacentSide1, m_edges) ? H
ardMiter : SoftMiter; | 835 MiterType miter1 = colorsMatchAtCorner(side, adjacentSide1, m_edges) ? H
ardMiter : SoftMiter; |
836 MiterType miter2 = colorsMatchAtCorner(side, adjacentSide2, m_edges) ? H
ardMiter : SoftMiter; | 836 MiterType miter2 = colorsMatchAtCorner(side, adjacentSide2, m_edges) ? H
ardMiter : SoftMiter; |
837 | 837 |
838 GraphicsContextStateSaver stateSaver(*graphicsContext); | 838 GraphicsContextStateSaver stateSaver(graphicsContext); |
839 if (m_inner.isRenderable()) | 839 if (m_inner.isRenderable()) |
840 clipBorderSidePolygon(graphicsContext, side, miter1, miter2); | 840 clipBorderSidePolygon(graphicsContext, side, miter1, miter2); |
841 else | 841 else |
842 clipBorderSideForComplexInnerPath(graphicsContext, side); | 842 clipBorderSideForComplexInnerPath(graphicsContext, side); |
843 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi
dth), adjacentEdge2.width); | 843 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi
dth), adjacentEdge2.width); |
844 drawBoxSideFromPath(graphicsContext, LayoutRect(m_outer.rect()), *path,
edgeToRender.width, | 844 drawBoxSideFromPath(graphicsContext, LayoutRect(m_outer.rect()), *path,
edgeToRender.width, |
845 thickness, side, color, edgeToRender.borderStyle()); | 845 thickness, side, color, edgeToRender.borderStyle()); |
846 } else { | 846 } else { |
847 MiterType miter1 = computeMiter(side, adjacentSide1, completedEdges, ant
ialias); | 847 MiterType miter1 = computeMiter(side, adjacentSide1, completedEdges, ant
ialias); |
848 MiterType miter2 = computeMiter(side, adjacentSide2, completedEdges, ant
ialias); | 848 MiterType miter2 = computeMiter(side, adjacentSide2, completedEdges, ant
ialias); |
849 bool shouldClip = mitersRequireClipping(miter1, miter2, edgeToRender.bor
derStyle(), antialias); | 849 bool shouldClip = mitersRequireClipping(miter1, miter2, edgeToRender.bor
derStyle(), antialias); |
850 | 850 |
851 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip); | 851 GraphicsContextStateSaver clipStateSaver(graphicsContext, shouldClip); |
852 if (shouldClip) { | 852 if (shouldClip) { |
853 clipBorderSidePolygon(graphicsContext, side, miter1, miter2); | 853 clipBorderSidePolygon(graphicsContext, side, miter1, miter2); |
854 | 854 |
855 // Miters are applied via clipping, no need to draw them. | 855 // Miters are applied via clipping, no need to draw them. |
856 miter1 = miter2 = NoMiter; | 856 miter1 = miter2 = NoMiter; |
857 } | 857 } |
858 | 858 |
859 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec
t.y(), | 859 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec
t.y(), |
860 sideRect.maxX(), sideRect.maxY(), side, color, edgeToRender.borderSt
yle(), | 860 sideRect.maxX(), sideRect.maxY(), side, color, edgeToRender.borderSt
yle(), |
861 miter1 != NoMiter ? adjacentEdge1.width : 0, miter2 != NoMiter ? adj
acentEdge2.width : 0, | 861 miter1 != NoMiter ? adjacentEdge1.width : 0, miter2 != NoMiter ? adj
acentEdge2.width : 0, |
862 antialias); | 862 antialias); |
863 } | 863 } |
864 } | 864 } |
865 | 865 |
866 void BoxBorderPainter::drawBoxSideFromPath(GraphicsContext* graphicsContext, | 866 void BoxBorderPainter::drawBoxSideFromPath(GraphicsContext& graphicsContext, |
867 const LayoutRect& borderRect, const Path& borderPath, float thickness, float
drawThickness, | 867 const LayoutRect& borderRect, const Path& borderPath, float thickness, float
drawThickness, |
868 BoxSide side, Color color, EBorderStyle borderStyle) const | 868 BoxSide side, Color color, EBorderStyle borderStyle) const |
869 { | 869 { |
870 if (thickness <= 0) | 870 if (thickness <= 0) |
871 return; | 871 return; |
872 | 872 |
873 if (borderStyle == DOUBLE && thickness < 3) | 873 if (borderStyle == DOUBLE && thickness < 3) |
874 borderStyle = SOLID; | 874 borderStyle = SOLID; |
875 | 875 |
876 switch (borderStyle) { | 876 switch (borderStyle) { |
877 case BNONE: | 877 case BNONE: |
878 case BHIDDEN: | 878 case BHIDDEN: |
879 return; | 879 return; |
880 case DOTTED: | 880 case DOTTED: |
881 case DASHED: { | 881 case DASHED: { |
882 graphicsContext->setStrokeColor(color); | 882 graphicsContext.setStrokeColor(color); |
883 | 883 |
884 // The stroke is doubled here because the provided path is the | 884 // The stroke is doubled here because the provided path is the |
885 // outside edge of the border so half the stroke is clipped off. | 885 // outside edge of the border so half the stroke is clipped off. |
886 // The extra multiplier is so that the clipping mask can antialias | 886 // The extra multiplier is so that the clipping mask can antialias |
887 // the edges to prevent jaggies. | 887 // the edges to prevent jaggies. |
888 graphicsContext->setStrokeThickness(drawThickness * 2 * 1.1f); | 888 graphicsContext.setStrokeThickness(drawThickness * 2 * 1.1f); |
889 graphicsContext->setStrokeStyle(borderStyle == DASHED ? DashedStroke : D
ottedStroke); | 889 graphicsContext.setStrokeStyle(borderStyle == DASHED ? DashedStroke : Do
ttedStroke); |
890 | 890 |
891 // If the number of dashes that fit in the path is odd and non-integral
then we | 891 // If the number of dashes that fit in the path is odd and non-integral
then we |
892 // will have an awkwardly-sized dash at the end of the path. To try to a
void that | 892 // will have an awkwardly-sized dash at the end of the path. To try to a
void that |
893 // here, we simply make the whitespace dashes ever so slightly bigger. | 893 // here, we simply make the whitespace dashes ever so slightly bigger. |
894 // FIXME: This could be even better if we tried to manipulate the dash o
ffset | 894 // FIXME: This could be even better if we tried to manipulate the dash o
ffset |
895 // and possibly the gapLength to get the corners dash-symmetrical. | 895 // and possibly the gapLength to get the corners dash-symmetrical. |
896 float dashLength = thickness * ((borderStyle == DASHED) ? 3.0f : 1.0f); | 896 float dashLength = thickness * ((borderStyle == DASHED) ? 3.0f : 1.0f); |
897 float gapLength = dashLength; | 897 float gapLength = dashLength; |
898 float numberOfDashes = borderPath.length() / dashLength; | 898 float numberOfDashes = borderPath.length() / dashLength; |
899 // Don't try to show dashes if we have less than 2 dashes + 2 gaps. | 899 // Don't try to show dashes if we have less than 2 dashes + 2 gaps. |
900 // FIXME: should do this test per side. | 900 // FIXME: should do this test per side. |
901 if (numberOfDashes >= 4) { | 901 if (numberOfDashes >= 4) { |
902 bool evenNumberOfFullDashes = !((int)numberOfDashes % 2); | 902 bool evenNumberOfFullDashes = !((int)numberOfDashes % 2); |
903 bool integralNumberOfDashes = !(numberOfDashes - (int)numberOfDashes
); | 903 bool integralNumberOfDashes = !(numberOfDashes - (int)numberOfDashes
); |
904 if (!evenNumberOfFullDashes && !integralNumberOfDashes) { | 904 if (!evenNumberOfFullDashes && !integralNumberOfDashes) { |
905 float numberOfGaps = numberOfDashes / 2; | 905 float numberOfGaps = numberOfDashes / 2; |
906 gapLength += (dashLength / numberOfGaps); | 906 gapLength += (dashLength / numberOfGaps); |
907 } | 907 } |
908 | 908 |
909 DashArray lineDash; | 909 DashArray lineDash; |
910 lineDash.append(dashLength); | 910 lineDash.append(dashLength); |
911 lineDash.append(gapLength); | 911 lineDash.append(gapLength); |
912 graphicsContext->setLineDash(lineDash, dashLength); | 912 graphicsContext.setLineDash(lineDash, dashLength); |
913 } | 913 } |
914 | 914 |
915 // FIXME: stroking the border path causes issues with tight corners: | 915 // FIXME: stroking the border path causes issues with tight corners: |
916 // https://bugs.webkit.org/show_bug.cgi?id=58711 | 916 // https://bugs.webkit.org/show_bug.cgi?id=58711 |
917 // Also, to get the best appearance we should stroke a path between the
two borders. | 917 // Also, to get the best appearance we should stroke a path between the
two borders. |
918 graphicsContext->strokePath(borderPath); | 918 graphicsContext.strokePath(borderPath); |
919 return; | 919 return; |
920 } | 920 } |
921 case DOUBLE: { | 921 case DOUBLE: { |
922 // Draw inner border line | 922 // Draw inner border line |
923 { | 923 { |
924 GraphicsContextStateSaver stateSaver(*graphicsContext); | 924 GraphicsContextStateSaver stateSaver(graphicsContext); |
925 const LayoutRectOutsets innerInsets = doubleStripeInsets(m_edges, Bo
rderEdge::DoubleBorderStripeInner); | 925 const LayoutRectOutsets innerInsets = doubleStripeInsets(m_edges, Bo
rderEdge::DoubleBorderStripeInner); |
926 FloatRoundedRect innerClip = m_style.getRoundedInnerBorderFor(border
Rect, innerInsets, | 926 FloatRoundedRect innerClip = m_style.getRoundedInnerBorderFor(border
Rect, innerInsets, |
927 m_includeLogicalLeftEdge, m_includeLogicalRightEdge); | 927 m_includeLogicalLeftEdge, m_includeLogicalRightEdge); |
928 | 928 |
929 graphicsContext->clipRoundedRect(innerClip); | 929 graphicsContext.clipRoundedRect(innerClip); |
930 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickne
ss, drawThickness, | 930 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickne
ss, drawThickness, |
931 side, color, SOLID); | 931 side, color, SOLID); |
932 } | 932 } |
933 | 933 |
934 // Draw outer border line | 934 // Draw outer border line |
935 { | 935 { |
936 GraphicsContextStateSaver stateSaver(*graphicsContext); | 936 GraphicsContextStateSaver stateSaver(graphicsContext); |
937 LayoutRect outerRect = borderRect; | 937 LayoutRect outerRect = borderRect; |
938 LayoutRectOutsets outerInsets = doubleStripeInsets(m_edges, BorderEd
ge::DoubleBorderStripeOuter); | 938 LayoutRectOutsets outerInsets = doubleStripeInsets(m_edges, BorderEd
ge::DoubleBorderStripeOuter); |
939 | 939 |
940 if (bleedAvoidanceIsClipping(m_bleedAvoidance)) { | 940 if (bleedAvoidanceIsClipping(m_bleedAvoidance)) { |
941 outerRect.inflate(1); | 941 outerRect.inflate(1); |
942 outerInsets.setTop(outerInsets.top() - 1); | 942 outerInsets.setTop(outerInsets.top() - 1); |
943 outerInsets.setRight(outerInsets.right() - 1); | 943 outerInsets.setRight(outerInsets.right() - 1); |
944 outerInsets.setBottom(outerInsets.bottom() - 1); | 944 outerInsets.setBottom(outerInsets.bottom() - 1); |
945 outerInsets.setLeft(outerInsets.left() - 1); | 945 outerInsets.setLeft(outerInsets.left() - 1); |
946 } | 946 } |
947 | 947 |
948 FloatRoundedRect outerClip = m_style.getRoundedInnerBorderFor(outerR
ect, outerInsets, | 948 FloatRoundedRect outerClip = m_style.getRoundedInnerBorderFor(outerR
ect, outerInsets, |
949 m_includeLogicalLeftEdge, m_includeLogicalRightEdge); | 949 m_includeLogicalLeftEdge, m_includeLogicalRightEdge); |
950 graphicsContext->clipOutRoundedRect(outerClip); | 950 graphicsContext.clipOutRoundedRect(outerClip); |
951 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickne
ss, drawThickness, | 951 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickne
ss, drawThickness, |
952 side, color, SOLID); | 952 side, color, SOLID); |
953 } | 953 } |
954 return; | 954 return; |
955 } | 955 } |
956 case RIDGE: | 956 case RIDGE: |
957 case GROOVE: | 957 case GROOVE: |
958 { | 958 { |
959 EBorderStyle s1; | 959 EBorderStyle s1; |
960 EBorderStyle s2; | 960 EBorderStyle s2; |
961 if (borderStyle == GROOVE) { | 961 if (borderStyle == GROOVE) { |
962 s1 = INSET; | 962 s1 = INSET; |
963 s2 = OUTSET; | 963 s2 = OUTSET; |
964 } else { | 964 } else { |
965 s1 = OUTSET; | 965 s1 = OUTSET; |
966 s2 = INSET; | 966 s2 = INSET; |
967 } | 967 } |
968 | 968 |
969 // Paint full border | 969 // Paint full border |
970 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickness,
drawThickness, | 970 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickness,
drawThickness, |
971 side, color, s1); | 971 side, color, s1); |
972 | 972 |
973 // Paint inner only | 973 // Paint inner only |
974 GraphicsContextStateSaver stateSaver(*graphicsContext); | 974 GraphicsContextStateSaver stateSaver(graphicsContext); |
975 LayoutUnit topWidth = m_edges[BSTop].usedWidth() / 2; | 975 LayoutUnit topWidth = m_edges[BSTop].usedWidth() / 2; |
976 LayoutUnit bottomWidth = m_edges[BSBottom].usedWidth() / 2; | 976 LayoutUnit bottomWidth = m_edges[BSBottom].usedWidth() / 2; |
977 LayoutUnit leftWidth = m_edges[BSLeft].usedWidth() / 2; | 977 LayoutUnit leftWidth = m_edges[BSLeft].usedWidth() / 2; |
978 LayoutUnit rightWidth = m_edges[BSRight].usedWidth() / 2; | 978 LayoutUnit rightWidth = m_edges[BSRight].usedWidth() / 2; |
979 | 979 |
980 FloatRoundedRect clipRect = m_style.getRoundedInnerBorderFor(borderRect, | 980 FloatRoundedRect clipRect = m_style.getRoundedInnerBorderFor(borderRect, |
981 LayoutRectOutsets(-topWidth, -rightWidth, -bottomWidth, -leftWidth), | 981 LayoutRectOutsets(-topWidth, -rightWidth, -bottomWidth, -leftWidth), |
982 m_includeLogicalLeftEdge, m_includeLogicalRightEdge); | 982 m_includeLogicalLeftEdge, m_includeLogicalRightEdge); |
983 | 983 |
984 graphicsContext->clipRoundedRect(clipRect); | 984 graphicsContext.clipRoundedRect(clipRect); |
985 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickness,
drawThickness, | 985 drawBoxSideFromPath(graphicsContext, borderRect, borderPath, thickness,
drawThickness, |
986 side, color, s2); | 986 side, color, s2); |
987 return; | 987 return; |
988 } | 988 } |
989 case INSET: | 989 case INSET: |
990 if (side == BSTop || side == BSLeft) | 990 if (side == BSTop || side == BSLeft) |
991 color = color.dark(); | 991 color = color.dark(); |
992 break; | 992 break; |
993 case OUTSET: | 993 case OUTSET: |
994 if (side == BSBottom || side == BSRight) | 994 if (side == BSBottom || side == BSRight) |
995 color = color.dark(); | 995 color = color.dark(); |
996 break; | 996 break; |
997 default: | 997 default: |
998 break; | 998 break; |
999 } | 999 } |
1000 | 1000 |
1001 graphicsContext->setStrokeStyle(NoStroke); | 1001 graphicsContext.setStrokeStyle(NoStroke); |
1002 graphicsContext->setFillColor(color); | 1002 graphicsContext.setFillColor(color); |
1003 graphicsContext->drawRect(pixelSnappedIntRect(borderRect)); | 1003 graphicsContext.drawRect(pixelSnappedIntRect(borderRect)); |
1004 } | 1004 } |
1005 | 1005 |
1006 void BoxBorderPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphi
csContext, | 1006 void BoxBorderPainter::clipBorderSideForComplexInnerPath(GraphicsContext& graphi
csContext, |
1007 BoxSide side) const | 1007 BoxSide side) const |
1008 { | 1008 { |
1009 graphicsContext->clip(calculateSideRectIncludingInner(m_outer, m_edges, side
)); | 1009 graphicsContext.clip(calculateSideRectIncludingInner(m_outer, m_edges, side)
); |
1010 FloatRoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(m_inner, s
ide); | 1010 FloatRoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(m_inner, s
ide); |
1011 if (!adjustedInnerRect.isEmpty()) | 1011 if (!adjustedInnerRect.isEmpty()) |
1012 graphicsContext->clipOutRoundedRect(adjustedInnerRect); | 1012 graphicsContext.clipOutRoundedRect(adjustedInnerRect); |
1013 } | 1013 } |
1014 | 1014 |
1015 void BoxBorderPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, B
oxSide side, | 1015 void BoxBorderPainter::clipBorderSidePolygon(GraphicsContext& graphicsContext, B
oxSide side, |
1016 MiterType firstMiter, MiterType secondMiter) const | 1016 MiterType firstMiter, MiterType secondMiter) const |
1017 { | 1017 { |
1018 ASSERT(firstMiter != NoMiter || secondMiter != NoMiter); | 1018 ASSERT(firstMiter != NoMiter || secondMiter != NoMiter); |
1019 | 1019 |
1020 FloatPoint quad[4]; | 1020 FloatPoint quad[4]; |
1021 | 1021 |
1022 const LayoutRect outerRect(m_outer.rect()); | 1022 const LayoutRect outerRect(m_outer.rect()); |
1023 const LayoutRect innerRect(m_inner.rect()); | 1023 const LayoutRect innerRect(m_inner.rect()); |
1024 | 1024 |
1025 // For each side, create a quad that encompasses all parts of that side that
may draw, | 1025 // For each side, create a quad that encompasses all parts of that side that
may draw, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 quad[2].y()), | 1148 quad[2].y()), |
1149 FloatPoint( | 1149 FloatPoint( |
1150 quad[2].x(), | 1150 quad[2].x(), |
1151 quad[2].y() - m_inner.radii().bottomRight().height()), | 1151 quad[2].y() - m_inner.radii().bottomRight().height()), |
1152 quad[2]); | 1152 quad[2]); |
1153 } | 1153 } |
1154 break; | 1154 break; |
1155 } | 1155 } |
1156 | 1156 |
1157 if (firstMiter == secondMiter) { | 1157 if (firstMiter == secondMiter) { |
1158 graphicsContext->clipPolygon(4, quad, firstMiter == SoftMiter); | 1158 graphicsContext.clipPolygon(4, quad, firstMiter == SoftMiter); |
1159 return; | 1159 return; |
1160 } | 1160 } |
1161 | 1161 |
1162 // If antialiasing settings for the first edge and second edge is different, | 1162 // If antialiasing settings for the first edge and second edge is different, |
1163 // they have to be addressed separately. We do this by breaking the quad int
o | 1163 // they have to be addressed separately. We do this by breaking the quad int
o |
1164 // two parallelograms, made by moving quad[1] and quad[2]. | 1164 // two parallelograms, made by moving quad[1] and quad[2]. |
1165 float ax = quad[1].x() - quad[0].x(); | 1165 float ax = quad[1].x() - quad[0].x(); |
1166 float ay = quad[1].y() - quad[0].y(); | 1166 float ay = quad[1].y() - quad[0].y(); |
1167 float bx = quad[2].x() - quad[1].x(); | 1167 float bx = quad[2].x() - quad[1].x(); |
1168 float by = quad[2].y() - quad[1].y(); | 1168 float by = quad[2].y() - quad[1].y(); |
(...skipping 12 matching lines...) Expand all Loading... |
1181 r1 = (-ax * by + ay * bx) / (cx * by - cy * bx) + kExtendFill; | 1181 r1 = (-ax * by + ay * bx) / (cx * by - cy * bx) + kExtendFill; |
1182 r2 = (-cx * by + cy * bx) / (ax * by - ay * bx) + kExtendFill; | 1182 r2 = (-cx * by + cy * bx) / (ax * by - ay * bx) + kExtendFill; |
1183 } | 1183 } |
1184 | 1184 |
1185 if (firstMiter != NoMiter) { | 1185 if (firstMiter != NoMiter) { |
1186 FloatPoint firstQuad[4]; | 1186 FloatPoint firstQuad[4]; |
1187 firstQuad[0] = quad[0]; | 1187 firstQuad[0] = quad[0]; |
1188 firstQuad[1] = quad[1]; | 1188 firstQuad[1] = quad[1]; |
1189 firstQuad[2] = FloatPoint(quad[3].x() + r2 * ax, quad[3].y() + r2 * ay); | 1189 firstQuad[2] = FloatPoint(quad[3].x() + r2 * ax, quad[3].y() + r2 * ay); |
1190 firstQuad[3] = quad[3]; | 1190 firstQuad[3] = quad[3]; |
1191 graphicsContext->clipPolygon(4, firstQuad, firstMiter == SoftMiter); | 1191 graphicsContext.clipPolygon(4, firstQuad, firstMiter == SoftMiter); |
1192 } | 1192 } |
1193 | 1193 |
1194 if (secondMiter != NoMiter) { | 1194 if (secondMiter != NoMiter) { |
1195 FloatPoint secondQuad[4]; | 1195 FloatPoint secondQuad[4]; |
1196 secondQuad[0] = quad[0]; | 1196 secondQuad[0] = quad[0]; |
1197 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy)
; | 1197 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy)
; |
1198 secondQuad[2] = quad[2]; | 1198 secondQuad[2] = quad[2]; |
1199 secondQuad[3] = quad[3]; | 1199 secondQuad[3] = quad[3]; |
1200 graphicsContext->clipPolygon(4, secondQuad, secondMiter == SoftMiter); | 1200 graphicsContext.clipPolygon(4, secondQuad, secondMiter == SoftMiter); |
1201 } | 1201 } |
1202 } | 1202 } |
1203 | 1203 |
1204 } // namespace blink | 1204 } // namespace blink |
OLD | NEW |