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

Side by Side Diff: src/core/SkEdgeBuilder.cpp

Issue 1654433002: combine vertical overlapping edges (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « src/core/SkEdgeBuilder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkEdgeBuilder.h" 8 #include "SkEdgeBuilder.h"
9 #include "SkPath.h" 9 #include "SkPath.h"
10 #include "SkEdge.h" 10 #include "SkEdge.h"
11 #include "SkEdgeClipper.h" 11 #include "SkEdgeClipper.h"
12 #include "SkLineClipper.h" 12 #include "SkLineClipper.h"
13 #include "SkGeometry.h" 13 #include "SkGeometry.h"
14 14
15 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) { 15 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) {
16 return static_cast<T*>(alloc.allocThrow(sizeof(T))); 16 return static_cast<T*>(alloc.allocThrow(sizeof(T)));
17 } 17 }
18 18
19 /////////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////////
20 20
21 SkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) { 21 SkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) {
22 fEdgeList = nullptr; 22 fEdgeList = nullptr;
23 } 23 }
24 24
25 SkEdgeBuilder::Combine SkEdgeBuilder::CombineVertical(const SkEdge* edge, SkEdge * last) {
26 if (last->fCurveCount || last->fDX || edge->fX != last->fX) {
27 return kNo_Combine;
28 }
29 if (edge->fWinding == last->fWinding) {
30 if (edge->fLastY + 1 == last->fFirstY) {
31 last->fFirstY = edge->fFirstY;
32 return kPartial_Combine;
33 }
34 if (edge->fFirstY == last->fLastY + 1) {
35 last->fLastY = edge->fLastY;
36 return kPartial_Combine;
37 }
38 return kNo_Combine;
39 }
40 if (edge->fFirstY == last->fFirstY) {
41 if (edge->fLastY == last->fLastY) {
42 return kTotal_Combine;
43 }
44 if (edge->fLastY < last->fLastY) {
45 last->fFirstY = edge->fLastY + 1;
46 return kPartial_Combine;
47 }
48 last->fFirstY = last->fLastY + 1;
49 last->fLastY = edge->fLastY;
50 last->fWinding = edge->fWinding;
51 return kPartial_Combine;
52 }
53 if (edge->fLastY == last->fLastY) {
54 if (edge->fFirstY > last->fFirstY) {
55 last->fLastY = edge->fFirstY - 1;
56 return kPartial_Combine;
57 }
58 last->fLastY = last->fFirstY - 1;
59 last->fFirstY = edge->fFirstY;
60 last->fWinding = edge->fWinding;
61 return kPartial_Combine;
62 }
63 return kNo_Combine;
64 }
65
66 static bool vertical_line(const SkEdge* edge) {
67 #ifdef SK_SUPPORT_LEGACY_VERTICAL_EDGE // this disables combining vertical over lapping edges
68 return false;
69 #endif
70 return !edge->fDX && !edge->fCurveCount;
71 }
72
25 void SkEdgeBuilder::addLine(const SkPoint pts[]) { 73 void SkEdgeBuilder::addLine(const SkPoint pts[]) {
26 SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc); 74 SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
27 if (edge->setLine(pts[0], pts[1], fShiftUp)) { 75 if (edge->setLine(pts[0], pts[1], fShiftUp)) {
76 if (vertical_line(edge) && fList.count()) {
77 Combine combine = CombineVertical(edge, *(fList.end() - 1));
78 if (kNo_Combine != combine) {
79 if (kTotal_Combine == combine) {
80 fList.pop();
81 }
82 goto unallocate_edge;
83 }
84 }
28 fList.push(edge); 85 fList.push(edge);
29 } else { 86 } else {
87 unallocate_edge:
88 ;
30 // TODO: unallocate edge from storage... 89 // TODO: unallocate edge from storage...
31 } 90 }
32 } 91 }
33 92
34 void SkEdgeBuilder::addQuad(const SkPoint pts[]) { 93 void SkEdgeBuilder::addQuad(const SkPoint pts[]) {
35 SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc); 94 SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc);
36 if (edge->setQuadratic(pts, fShiftUp)) { 95 if (edge->setQuadratic(pts, fShiftUp)) {
37 fList.push(edge); 96 fList.push(edge);
38 } else { 97 } else {
39 // TODO: unallocate edge from storage... 98 // TODO: unallocate edge from storage...
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 131
73 /////////////////////////////////////////////////////////////////////////////// 132 ///////////////////////////////////////////////////////////////////////////////
74 133
75 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) { 134 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
76 dst->set(SkIntToScalar(src.fLeft >> shift), 135 dst->set(SkIntToScalar(src.fLeft >> shift),
77 SkIntToScalar(src.fTop >> shift), 136 SkIntToScalar(src.fTop >> shift),
78 SkIntToScalar(src.fRight >> shift), 137 SkIntToScalar(src.fRight >> shift),
79 SkIntToScalar(src.fBottom >> shift)); 138 SkIntToScalar(src.fBottom >> shift));
80 } 139 }
81 140
141 SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkEdge* edge, SkEdge** edgePtr) {
142 return !vertical_line(edge) || edgePtr <= fEdgeList ? kNo_Combine :
143 CombineVertical(edge, edgePtr[-1]);
144 }
145
82 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift Up, 146 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift Up,
83 bool canCullToTheRight) { 147 bool canCullToTheRight) {
84 SkPath::Iter iter(path, true); 148 SkPath::Iter iter(path, true);
85 SkPoint pts[4]; 149 SkPoint pts[4];
86 SkPath::Verb verb; 150 SkPath::Verb verb;
87 151
88 int maxEdgeCount = path.countPoints(); 152 int maxEdgeCount = path.countPoints();
89 if (iclip) { 153 if (iclip) {
90 // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since 154 // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
91 // we turn portions that are clipped out on the left/right into vertical 155 // we turn portions that are clipped out on the left/right into vertical
(...skipping 20 matching lines...) Expand all
112 case SkPath::kClose_Verb: 176 case SkPath::kClose_Verb:
113 // we ignore these, and just get the whole segment from 177 // we ignore these, and just get the whole segment from
114 // the corresponding line/quad/cubic verbs 178 // the corresponding line/quad/cubic verbs
115 break; 179 break;
116 case SkPath::kLine_Verb: { 180 case SkPath::kLine_Verb: {
117 SkPoint lines[SkLineClipper::kMaxPoints]; 181 SkPoint lines[SkLineClipper::kMaxPoints];
118 int lineCount = SkLineClipper::ClipLine(pts, clip, lines, ca nCullToTheRight); 182 int lineCount = SkLineClipper::ClipLine(pts, clip, lines, ca nCullToTheRight);
119 SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments ); 183 SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments );
120 for (int i = 0; i < lineCount; i++) { 184 for (int i = 0; i < lineCount; i++) {
121 if (edge->setLine(lines[i], lines[i + 1], shiftUp)) { 185 if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
122 *edgePtr++ = edge++; 186 Combine combine = checkVertical(edge, edgePtr);
187 if (kNo_Combine == combine) {
188 *edgePtr++ = edge++;
189 } else if (kTotal_Combine == combine) {
190 --edgePtr;
191 }
123 } 192 }
124 } 193 }
125 break; 194 break;
126 } 195 }
127 default: 196 default:
128 SkDEBUGFAIL("unexpected verb"); 197 SkDEBUGFAIL("unexpected verb");
129 break; 198 break;
130 } 199 }
131 } 200 }
132 } else { 201 } else {
133 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 202 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
134 switch (verb) { 203 switch (verb) {
135 case SkPath::kMove_Verb: 204 case SkPath::kMove_Verb:
136 case SkPath::kClose_Verb: 205 case SkPath::kClose_Verb:
137 // we ignore these, and just get the whole segment from 206 // we ignore these, and just get the whole segment from
138 // the corresponding line/quad/cubic verbs 207 // the corresponding line/quad/cubic verbs
139 break; 208 break;
140 case SkPath::kLine_Verb: 209 case SkPath::kLine_Verb:
141 if (edge->setLine(pts[0], pts[1], shiftUp)) { 210 if (edge->setLine(pts[0], pts[1], shiftUp)) {
142 *edgePtr++ = edge++; 211 Combine combine = checkVertical(edge, edgePtr);
212 if (kNo_Combine == combine) {
213 *edgePtr++ = edge++;
214 } else if (kTotal_Combine == combine) {
215 --edgePtr;
216 }
143 } 217 }
144 break; 218 break;
145 default: 219 default:
146 SkDEBUGFAIL("unexpected verb"); 220 SkDEBUGFAIL("unexpected verb");
147 break; 221 break;
148 } 222 }
149 } 223 }
150 } 224 }
151 SkASSERT((char*)edge <= (char*)fEdgeList); 225 SkASSERT((char*)edge <= (char*)fEdgeList);
152 SkASSERT(edgePtr - fEdgeList <= maxEdgeCount); 226 SkASSERT(edgePtr - fEdgeList <= maxEdgeCount);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 } 330 }
257 default: 331 default:
258 SkDEBUGFAIL("unexpected verb"); 332 SkDEBUGFAIL("unexpected verb");
259 break; 333 break;
260 } 334 }
261 } 335 }
262 } 336 }
263 fEdgeList = fList.begin(); 337 fEdgeList = fList.begin();
264 return fList.count(); 338 return fList.count();
265 } 339 }
OLDNEW
« no previous file with comments | « src/core/SkEdgeBuilder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698