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

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

Issue 1167293004: [SP] Always anti-alias borders (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: expectations Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "platform/RuntimeEnabledFeatures.h"
11 #include "platform/graphics/GraphicsContext.h" 12 #include "platform/graphics/GraphicsContext.h"
12 #include "platform/graphics/GraphicsContextStateSaver.h" 13 #include "platform/graphics/GraphicsContextStateSaver.h"
13 #include "wtf/Vector.h" 14 #include "wtf/Vector.h"
14 #include <algorithm> 15 #include <algorithm>
15 16
16 namespace blink { 17 namespace blink {
17 18
18 namespace { 19 namespace {
19 20
20 enum BorderEdgeFlag { 21 enum BorderEdgeFlag {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 inline bool willOverdraw(BoxSide side, EBorderStyle style, BorderEdgeFlags compl etedEdges) 98 inline bool willOverdraw(BoxSide side, EBorderStyle style, BorderEdgeFlags compl etedEdges)
98 { 99 {
99 // If we're done with this side, it will obviously not overdraw any portion of the current edge. 100 // If we're done with this side, it will obviously not overdraw any portion of the current edge.
100 if (includesEdge(completedEdges, side)) 101 if (includesEdge(completedEdges, side))
101 return false; 102 return false;
102 103
103 // The side is still to be drawn. It overdraws the current edge iff it has a solid fill style. 104 // The side is still to be drawn. It overdraws the current edge iff it has a solid fill style.
104 return borderStyleFillsBorderArea(style); 105 return borderStyleFillsBorderArea(style);
105 } 106 }
106 107
107 inline bool borderStylesRequireMitre(BoxSide side, BoxSide adjacentSide, EBorder Style style, EBorderStyle adjacentStyle) 108 inline bool borderStylesRequireMiter(BoxSide side, BoxSide adjacentSide, EBorder Style style, EBorderStyle adjacentStyle)
108 { 109 {
109 if (style == DOUBLE || adjacentStyle == DOUBLE || adjacentStyle == GROOVE || adjacentStyle == RIDGE) 110 if (style == DOUBLE || adjacentStyle == DOUBLE || adjacentStyle == GROOVE || adjacentStyle == RIDGE)
110 return true; 111 return true;
111 112
112 if (borderStyleIsDottedOrDashed(style) != borderStyleIsDottedOrDashed(adjace ntStyle)) 113 if (borderStyleIsDottedOrDashed(style) != borderStyleIsDottedOrDashed(adjace ntStyle))
113 return true; 114 return true;
114 115
115 if (style != adjacentStyle) 116 if (style != adjacentStyle)
116 return true; 117 return true;
117 118
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 2 /* GROOVE */, 343 2 /* GROOVE */,
343 2 /* OUTSET */, 344 2 /* OUTSET */,
344 2 /* RIDGE */, 345 2 /* RIDGE */,
345 1 /* DOTTED */, 346 1 /* DOTTED */,
346 1 /* DASHED */, 347 1 /* DASHED */,
347 3 /* SOLID */, 348 3 /* SOLID */,
348 1 /* DOUBLE */ 349 1 /* DOUBLE */
349 }; 350 };
350 351
351 // Given the same style, prefer drawing in non-adjacent order to minimize the nu mber of sides 352 // Given the same style, prefer drawing in non-adjacent order to minimize the nu mber of sides
352 // which require mitres. 353 // which require miters.
353 const unsigned kSidePriority[] = { 354 const unsigned kSidePriority[] = {
354 0, /* BSTop */ 355 0, /* BSTop */
355 2, /* BSRight */ 356 2, /* BSRight */
356 1, /* BSBottom */ 357 1, /* BSBottom */
357 3, /* BSLeft */ 358 3, /* BSLeft */
358 }; 359 };
359 360
360 // Edges sharing the same opacity. Stores both a side list and an edge bitfield to support 361 // Edges sharing the same opacity. Stores both a side list and an edge bitfield to support
361 // constant time iteration + membership tests. 362 // constant time iteration + membership tests.
362 struct OpacityGroup { 363 struct OpacityGroup {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already applied. 597 // For BackgroundBleedClip{Only,Layer}, the outer rrect clip is already applied.
597 if (!bleedAvoidanceIsClipping(m_bleedAvoidance)) 598 if (!bleedAvoidanceIsClipping(m_bleedAvoidance))
598 graphicsContext->clipRoundedRect(m_outer); 599 graphicsContext->clipRoundedRect(m_outer);
599 600
600 // For BackgroundBleedBackgroundOverBorder, we're going to draw an opaqu e background over 601 // For BackgroundBleedBackgroundOverBorder, we're going to draw an opaqu e background over
601 // the inner rrect - so clipping is not needed (nor desirable due to bac kdrop bleeding). 602 // the inner rrect - so clipping is not needed (nor desirable due to bac kdrop bleeding).
602 if (m_bleedAvoidance != BackgroundBleedBackgroundOverBorder && m_inner.i sRenderable() && !m_inner.isEmpty()) 603 if (m_bleedAvoidance != BackgroundBleedBackgroundOverBorder && m_inner.i sRenderable() && !m_inner.isEmpty())
603 graphicsContext->clipOutRoundedRect(m_inner); 604 graphicsContext->clipOutRoundedRect(m_inner);
604 } 605 }
605 606
606 // If only one edge visible antialiasing doesn't create seams 607 bool antialias =
607 bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext) || m_visi bleEdgeCount == 1; 608 RuntimeEnabledFeatures::slimmingPaintEnabled()
609 || m_visibleEdgeCount == 1
610 || BoxPainter::shouldAntialiasLines(graphicsContext);
608 611
609 const ComplexBorderInfo borderInfo(*this, antialias); 612 const ComplexBorderInfo borderInfo(*this, antialias);
610 paintOpacityGroup(graphicsContext, borderInfo, 0, 1); 613 paintOpacityGroup(graphicsContext, borderInfo, 0, 1);
611 } 614 }
612 615
613 // In order to maximize the use of overdraw as a corner seam avoidance technique , we draw 616 // In order to maximize the use of overdraw as a corner seam avoidance technique , we draw
614 // translucent border sides using the following algorithm: 617 // translucent border sides using the following algorithm:
615 // 618 //
616 // 1) cluster sides sharing the same opacity into "opacity groups" [ComplexBor derInfo] 619 // 1) cluster sides sharing the same opacity into "opacity groups" [ComplexBor derInfo]
617 // 2) sort groups in increasing opacity order [ComplexBorderInfo] 620 // 2) sort groups in increasing opacity order [ComplexBorderInfo]
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 767
765 paintOneBorderSide(context, sideRect, BSRight, BSTop, BSBottom, path, bo rderInfo.antiAlias, 768 paintOneBorderSide(context, sideRect, BSRight, BSTop, BSBottom, path, bo rderInfo.antiAlias,
766 color, completedEdges); 769 color, completedEdges);
767 break; 770 break;
768 } 771 }
769 default: 772 default:
770 ASSERT_NOT_REACHED(); 773 ASSERT_NOT_REACHED();
771 } 774 }
772 } 775 }
773 776
774 BoxBorderPainter::MitreType BoxBorderPainter::computeMitre(BoxSide side, BoxSide adjacentSide, 777 BoxBorderPainter::MiterType BoxBorderPainter::computeMiter(BoxSide side, BoxSide adjacentSide,
775 BorderEdgeFlags completedEdges, bool antialias) const 778 BorderEdgeFlags completedEdges, bool antialias) const
776 { 779 {
777 const BorderEdge& adjacentEdge = m_edges[adjacentSide]; 780 const BorderEdge& adjacentEdge = m_edges[adjacentSide];
778 781
779 // No miters for missing edges. 782 // No miters for missing edges.
780 if (!adjacentEdge.isPresent) 783 if (!adjacentEdge.isPresent)
781 return NoMitre; 784 return NoMiter;
782 785
783 // Legacy behavior - preserve for now. 786 // The adjacent edge will overdraw this corner, resulting in a correct miter .
784 bool allowOverdraw = !antialias; 787 if (willOverdraw(adjacentSide, adjacentEdge.borderStyle(), completedEdges))
788 return NoMiter;
785 789
786 // The adjacent edge will overdraw this corner, resulting in a correct mitre . 790 // Color transitions require miters. Use miters compatible with the AA drawi ng mode to avoid
787 if (allowOverdraw && willOverdraw(adjacentSide, adjacentEdge.borderStyle(), completedEdges))
788 return NoMitre;
789
790 // Color transitions require mitres. Use mitres compatible with the AA drawi ng mode to avoid
791 // introducing extra clips. 791 // introducing extra clips.
792 if (!colorsMatchAtCorner(side, adjacentSide, m_edges)) 792 if (!colorsMatchAtCorner(side, adjacentSide, m_edges))
793 return antialias ? SoftMitre : HardMitre; 793 return antialias ? SoftMiter : HardMiter;
794 794
795 // Non-anti-aliased mitres ensure correct same-color seaming when required b y style. 795 // Non-anti-aliased miters ensure correct same-color seaming when required b y style.
796 if (borderStylesRequireMitre(side, adjacentSide, m_edges[side].borderStyle() , adjacentEdge.borderStyle())) 796 if (borderStylesRequireMiter(side, adjacentSide, m_edges[side].borderStyle() , adjacentEdge.borderStyle()))
797 return HardMitre; 797 return HardMiter;
798 798
799 // Overdraw the adjacent edge when the colors match and we have no style res trictions. 799 // Overdraw the adjacent edge when the colors match and we have no style res trictions.
800 return NoMitre; 800 return NoMiter;
801 } 801 }
802 802
803 bool BoxBorderPainter::mitresRequireClipping(MitreType mitre1, MitreType mitre2, EBorderStyle style, 803 bool BoxBorderPainter::mitersRequireClipping(MiterType miter1, MiterType miter2, EBorderStyle style,
804 bool antialias) 804 bool antialias)
805 { 805 {
806 // Clipping is required if any of the present mitres doesn't match the curre nt AA mode. 806 // Clipping is required if any of the present miters doesn't match the curre nt AA mode.
807 bool shouldClip = antialias 807 bool shouldClip = antialias
808 ? mitre1 == HardMitre || mitre2 == HardMitre 808 ? miter1 == HardMiter || miter2 == HardMiter
809 : mitre1 == SoftMitre || mitre2 == SoftMitre; 809 : miter1 == SoftMiter || miter2 == SoftMiter;
810 810
811 // Some styles require clipping for any type of mitre. 811 // Some styles require clipping for any type of miter.
812 shouldClip = shouldClip 812 shouldClip = shouldClip
813 || ((mitre1 != NoMitre || mitre2 != NoMitre) && styleRequiresClipPolygon (style)); 813 || ((miter1 != NoMiter || miter2 != NoMiter) && styleRequiresClipPolygon (style));
814 814
815 return shouldClip; 815 return shouldClip;
816 } 816 }
817 817
818 void BoxBorderPainter::paintOneBorderSide(GraphicsContext* graphicsContext, 818 void BoxBorderPainter::paintOneBorderSide(GraphicsContext* graphicsContext,
819 const FloatRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adja centSide2, 819 const FloatRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adja centSide2,
820 const Path* path, bool antialias, Color color, BorderEdgeFlags completedEdge s) const 820 const Path* path, bool antialias, Color color, BorderEdgeFlags completedEdge s) const
821 { 821 {
822 const BorderEdge& edgeToRender = m_edges[side]; 822 const BorderEdge& edgeToRender = m_edges[side];
823 ASSERT(edgeToRender.width); 823 ASSERT(edgeToRender.width);
824 const BorderEdge& adjacentEdge1 = m_edges[adjacentSide1]; 824 const BorderEdge& adjacentEdge1 = m_edges[adjacentSide1];
825 const BorderEdge& adjacentEdge2 = m_edges[adjacentSide2]; 825 const BorderEdge& adjacentEdge2 = m_edges[adjacentSide2];
826 826
827 if (path) { 827 if (path) {
828 MitreType mitre1 = colorsMatchAtCorner(side, adjacentSide1, m_edges) ? H ardMitre : SoftMitre; 828 MiterType miter1 = colorsMatchAtCorner(side, adjacentSide1, m_edges) ? H ardMiter : SoftMiter;
829 MitreType mitre2 = colorsMatchAtCorner(side, adjacentSide2, m_edges) ? H ardMitre : SoftMitre; 829 MiterType miter2 = colorsMatchAtCorner(side, adjacentSide2, m_edges) ? H ardMiter : SoftMiter;
830 830
831 GraphicsContextStateSaver stateSaver(*graphicsContext); 831 GraphicsContextStateSaver stateSaver(*graphicsContext);
832 if (m_inner.isRenderable()) 832 if (m_inner.isRenderable())
833 clipBorderSidePolygon(graphicsContext, side, mitre1, mitre2); 833 clipBorderSidePolygon(graphicsContext, side, miter1, miter2);
834 else 834 else
835 clipBorderSideForComplexInnerPath(graphicsContext, side); 835 clipBorderSideForComplexInnerPath(graphicsContext, side);
836 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi dth), adjacentEdge2.width); 836 float thickness = std::max(std::max(edgeToRender.width, adjacentEdge1.wi dth), adjacentEdge2.width);
837 drawBoxSideFromPath(graphicsContext, LayoutRect(m_outer.rect()), *path, edgeToRender.width, 837 drawBoxSideFromPath(graphicsContext, LayoutRect(m_outer.rect()), *path, edgeToRender.width,
838 thickness, side, color, edgeToRender.borderStyle()); 838 thickness, side, color, edgeToRender.borderStyle());
839 } else { 839 } else {
840 MitreType mitre1 = computeMitre(side, adjacentSide1, completedEdges, ant ialias); 840 MiterType miter1 = computeMiter(side, adjacentSide1, completedEdges, ant ialias);
841 MitreType mitre2 = computeMitre(side, adjacentSide2, completedEdges, ant ialias); 841 MiterType miter2 = computeMiter(side, adjacentSide2, completedEdges, ant ialias);
842 bool shouldClip = mitresRequireClipping(mitre1, mitre2, edgeToRender.bor derStyle(), antialias); 842 bool shouldClip = mitersRequireClipping(miter1, miter2, edgeToRender.bor derStyle(), antialias);
843 843
844 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip); 844 GraphicsContextStateSaver clipStateSaver(*graphicsContext, shouldClip);
845 if (shouldClip) { 845 if (shouldClip) {
846 clipBorderSidePolygon(graphicsContext, side, mitre1, mitre2); 846 clipBorderSidePolygon(graphicsContext, side, miter1, miter2);
847 847
848 // Mitres are applied via clipping, no need to draw them. 848 // Miters are applied via clipping, no need to draw them.
849 mitre1 = mitre2 = NoMitre; 849 miter1 = miter2 = NoMiter;
850 } 850 }
851 851
852 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec t.y(), 852 ObjectPainter::drawLineForBoxSide(graphicsContext, sideRect.x(), sideRec t.y(),
853 sideRect.maxX(), sideRect.maxY(), side, color, edgeToRender.borderSt yle(), 853 sideRect.maxX(), sideRect.maxY(), side, color, edgeToRender.borderSt yle(),
854 mitre1 != NoMitre ? adjacentEdge1.width : 0, mitre2 != NoMitre ? adj acentEdge2.width : 0, 854 miter1 != NoMiter ? adjacentEdge1.width : 0, miter2 != NoMiter ? adj acentEdge2.width : 0,
855 antialias); 855 antialias);
856 } 856 }
857 } 857 }
858 858
859 void BoxBorderPainter::drawBoxSideFromPath(GraphicsContext* graphicsContext, 859 void BoxBorderPainter::drawBoxSideFromPath(GraphicsContext* graphicsContext,
860 const LayoutRect& borderRect, const Path& borderPath, float thickness, float drawThickness, 860 const LayoutRect& borderRect, const Path& borderPath, float thickness, float drawThickness,
861 BoxSide side, Color color, EBorderStyle borderStyle) const 861 BoxSide side, Color color, EBorderStyle borderStyle) const
862 { 862 {
863 if (thickness <= 0) 863 if (thickness <= 0)
864 return; 864 return;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 void BoxBorderPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphi csContext, 999 void BoxBorderPainter::clipBorderSideForComplexInnerPath(GraphicsContext* graphi csContext,
1000 BoxSide side) const 1000 BoxSide side) const
1001 { 1001 {
1002 graphicsContext->clip(calculateSideRectIncludingInner(m_outer, m_edges, side )); 1002 graphicsContext->clip(calculateSideRectIncludingInner(m_outer, m_edges, side ));
1003 FloatRoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(m_inner, s ide); 1003 FloatRoundedRect adjustedInnerRect = calculateAdjustedInnerBorder(m_inner, s ide);
1004 if (!adjustedInnerRect.isEmpty()) 1004 if (!adjustedInnerRect.isEmpty())
1005 graphicsContext->clipOutRoundedRect(adjustedInnerRect); 1005 graphicsContext->clipOutRoundedRect(adjustedInnerRect);
1006 } 1006 }
1007 1007
1008 void BoxBorderPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, B oxSide side, 1008 void BoxBorderPainter::clipBorderSidePolygon(GraphicsContext* graphicsContext, B oxSide side,
1009 MitreType firstMitre, MitreType secondMitre) const 1009 MiterType firstMiter, MiterType secondMiter) const
1010 { 1010 {
1011 ASSERT(firstMitre != NoMitre || secondMitre != NoMitre); 1011 ASSERT(firstMiter != NoMiter || secondMiter != NoMiter);
1012 1012
1013 FloatPoint quad[4]; 1013 FloatPoint quad[4];
1014 1014
1015 const LayoutRect outerRect(m_outer.rect()); 1015 const LayoutRect outerRect(m_outer.rect());
1016 const LayoutRect innerRect(m_inner.rect()); 1016 const LayoutRect innerRect(m_inner.rect());
1017 1017
1018 // For each side, create a quad that encompasses all parts of that side that may draw, 1018 // For each side, create a quad that encompasses all parts of that side that may draw,
1019 // including areas inside the innerBorder. 1019 // including areas inside the innerBorder.
1020 // 1020 //
1021 // 0----------------3 1021 // 0----------------3
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 quad[2].x() - m_inner.radii().bottomRight().width(), 1140 quad[2].x() - m_inner.radii().bottomRight().width(),
1141 quad[2].y()), 1141 quad[2].y()),
1142 FloatPoint( 1142 FloatPoint(
1143 quad[2].x(), 1143 quad[2].x(),
1144 quad[2].y() - m_inner.radii().bottomRight().height()), 1144 quad[2].y() - m_inner.radii().bottomRight().height()),
1145 quad[2]); 1145 quad[2]);
1146 } 1146 }
1147 break; 1147 break;
1148 } 1148 }
1149 1149
1150 if (firstMitre == secondMitre) { 1150 if (firstMiter == secondMiter) {
1151 graphicsContext->clipPolygon(4, quad, firstMitre == SoftMitre); 1151 graphicsContext->clipPolygon(4, quad, firstMiter == SoftMiter);
1152 return; 1152 return;
1153 } 1153 }
1154 1154
1155 // If antialiasing settings for the first edge and second edge is different, 1155 // If antialiasing settings for the first edge and second edge is different,
1156 // they have to be addressed separately. We do this by breaking the quad int o 1156 // they have to be addressed separately. We do this by breaking the quad int o
1157 // two parallelograms, made by moving quad[1] and quad[2]. 1157 // two parallelograms, made by moving quad[1] and quad[2].
1158 float ax = quad[1].x() - quad[0].x(); 1158 float ax = quad[1].x() - quad[0].x();
1159 float ay = quad[1].y() - quad[0].y(); 1159 float ay = quad[1].y() - quad[0].y();
1160 float bx = quad[2].x() - quad[1].x(); 1160 float bx = quad[2].x() - quad[1].x();
1161 float by = quad[2].y() - quad[1].y(); 1161 float by = quad[2].y() - quad[1].y();
1162 float cx = quad[3].x() - quad[2].x(); 1162 float cx = quad[3].x() - quad[2].x();
1163 float cy = quad[3].y() - quad[2].y(); 1163 float cy = quad[3].y() - quad[2].y();
1164 1164
1165 const static float kEpsilon = 1e-2f; 1165 const static float kEpsilon = 1e-2f;
1166 float r1, r2; 1166 float r1, r2;
1167 if (fabsf(bx) < kEpsilon && fabsf(by) < kEpsilon) { 1167 if (fabsf(bx) < kEpsilon && fabsf(by) < kEpsilon) {
1168 // The quad was actually a triangle. 1168 // The quad was actually a triangle.
1169 r1 = r2 = 1.0f; 1169 r1 = r2 = 1.0f;
1170 } else { 1170 } else {
1171 // Extend parallelogram a bit to hide calculation error 1171 // Extend parallelogram a bit to hide calculation error
1172 const static float kExtendFill = 1e-2f; 1172 const static float kExtendFill = 1e-2f;
1173 1173
1174 r1 = (-ax * by + ay * bx) / (cx * by - cy * bx) + kExtendFill; 1174 r1 = (-ax * by + ay * bx) / (cx * by - cy * bx) + kExtendFill;
1175 r2 = (-cx * by + cy * bx) / (ax * by - ay * bx) + kExtendFill; 1175 r2 = (-cx * by + cy * bx) / (ax * by - ay * bx) + kExtendFill;
1176 } 1176 }
1177 1177
1178 if (firstMitre != NoMitre) { 1178 if (firstMiter != NoMiter) {
1179 FloatPoint firstQuad[4]; 1179 FloatPoint firstQuad[4];
1180 firstQuad[0] = quad[0]; 1180 firstQuad[0] = quad[0];
1181 firstQuad[1] = quad[1]; 1181 firstQuad[1] = quad[1];
1182 firstQuad[2] = FloatPoint(quad[3].x() + r2 * ax, quad[3].y() + r2 * ay); 1182 firstQuad[2] = FloatPoint(quad[3].x() + r2 * ax, quad[3].y() + r2 * ay);
1183 firstQuad[3] = quad[3]; 1183 firstQuad[3] = quad[3];
1184 graphicsContext->clipPolygon(4, firstQuad, firstMitre == SoftMitre); 1184 graphicsContext->clipPolygon(4, firstQuad, firstMiter == SoftMiter);
1185 } 1185 }
1186 1186
1187 if (secondMitre != NoMitre) { 1187 if (secondMiter != NoMiter) {
1188 FloatPoint secondQuad[4]; 1188 FloatPoint secondQuad[4];
1189 secondQuad[0] = quad[0]; 1189 secondQuad[0] = quad[0];
1190 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy) ; 1190 secondQuad[1] = FloatPoint(quad[0].x() - r1 * cx, quad[0].y() - r1 * cy) ;
1191 secondQuad[2] = quad[2]; 1191 secondQuad[2] = quad[2];
1192 secondQuad[3] = quad[3]; 1192 secondQuad[3] = quad[3];
1193 graphicsContext->clipPolygon(4, secondQuad, secondMitre == SoftMitre); 1193 graphicsContext->clipPolygon(4, secondQuad, secondMiter == SoftMiter);
1194 } 1194 }
1195 } 1195 }
1196 1196
1197 } // namespace blink 1197 } // namespace blink
OLDNEW
« Source/core/paint/BoxBorderPainter.h ('K') | « Source/core/paint/BoxBorderPainter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698