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

Side by Side Diff: src/pathops/SkPathOpsCommon.cpp

Issue 2321973005: Rewriting path writer (Closed)
Patch Set: revert unneeded test changes Created 4 years, 3 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/pathops/SkPathOpsCommon.h ('k') | src/pathops/SkPathOpsCurve.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 #include "SkAddIntersections.h" 7 #include "SkAddIntersections.h"
8 #include "SkOpCoincidence.h" 8 #include "SkOpCoincidence.h"
9 #include "SkOpEdgeBuilder.h" 9 #include "SkOpEdgeBuilder.h"
10 #include "SkPathOpsCommon.h" 10 #include "SkPathOpsCommon.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 *contourList = contourHead; 191 *contourList = contourHead;
192 for (int index = 1; index < count; ++index) { 192 for (int index = 1; index < count; ++index) {
193 SkOpContour* next = list[index]; 193 SkOpContour* next = list[index];
194 contour->setNext(next); 194 contour->setNext(next);
195 contour = next; 195 contour = next;
196 } 196 }
197 contour->setNext(nullptr); 197 contour->setNext(nullptr);
198 return true; 198 return true;
199 } 199 }
200 200
201 class DistanceLessThan {
202 public:
203 DistanceLessThan(double* distances) : fDistances(distances) { }
204 double* fDistances;
205 bool operator()(const int one, const int two) {
206 return fDistances[one] < fDistances[two];
207 }
208 };
209
210 /*
211 check start and end of each contour
212 if not the same, record them
213 match them up
214 connect closest
215 reassemble contour pieces into new path
216 */
217 void Assemble(const SkPathWriter& path, SkPathWriter* simple) {
218 SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
219 SkOpContourHead contour;
220 SkOpGlobalState globalState(&contour, &allocator SkDEBUGPARAMS(false)
221 SkDEBUGPARAMS(nullptr));
222 #if DEBUG_SHOW_TEST_NAME
223 SkDebugf("</div>\n");
224 #endif
225 #if DEBUG_PATH_CONSTRUCTION
226 SkDebugf("%s\n", __FUNCTION__);
227 #endif
228 SkOpEdgeBuilder builder(path, &contour, &globalState);
229 builder.finish();
230 SkTDArray<const SkOpContour* > runs; // indices of partial contours
231 const SkOpContour* eContour = builder.head();
232 do {
233 if (!eContour->count()) {
234 continue;
235 }
236 const SkPoint& eStart = eContour->start();
237 const SkPoint& eEnd = eContour->end();
238 #if DEBUG_ASSEMBLE
239 SkDebugf("%s contour", __FUNCTION__);
240 if (!SkDPoint::ApproximatelyEqual(eStart, eEnd)) {
241 SkDebugf("[%d]", runs.count());
242 } else {
243 SkDebugf(" ");
244 }
245 SkDebugf(" start=(%1.9g,%1.9g) end=(%1.9g,%1.9g)\n",
246 eStart.fX, eStart.fY, eEnd.fX, eEnd.fY);
247 #endif
248 if (SkDPoint::ApproximatelyEqual(eStart, eEnd)) {
249 eContour->toPath(simple);
250 continue;
251 }
252 *runs.append() = eContour;
253 } while ((eContour = eContour->next()));
254 int count = runs.count();
255 if (count == 0) {
256 return;
257 }
258 SkTDArray<int> sLink, eLink;
259 sLink.append(count);
260 eLink.append(count);
261 int rIndex, iIndex;
262 for (rIndex = 0; rIndex < count; ++rIndex) {
263 sLink[rIndex] = eLink[rIndex] = SK_MaxS32;
264 }
265 const int ends = count * 2; // all starts and ends
266 const int entries = (ends - 1) * count; // folded triangle : n * (n - 1) / 2
267 SkTDArray<double> distances;
268 distances.append(entries);
269 for (rIndex = 0; rIndex < ends - 1; ++rIndex) {
270 const SkOpContour* oContour = runs[rIndex >> 1];
271 const SkPoint& oPt = rIndex & 1 ? oContour->end() : oContour->start();
272 const int row = rIndex < count - 1 ? rIndex * ends : (ends - rIndex - 2)
273 * ends - rIndex - 1;
274 for (iIndex = rIndex + 1; iIndex < ends; ++iIndex) {
275 const SkOpContour* iContour = runs[iIndex >> 1];
276 const SkPoint& iPt = iIndex & 1 ? iContour->end() : iContour->start( );
277 double dx = iPt.fX - oPt.fX;
278 double dy = iPt.fY - oPt.fY;
279 double dist = dx * dx + dy * dy;
280 distances[row + iIndex] = dist; // oStart distance from iStart
281 }
282 }
283 SkTDArray<int> sortedDist;
284 sortedDist.append(entries);
285 for (rIndex = 0; rIndex < entries; ++rIndex) {
286 sortedDist[rIndex] = rIndex;
287 }
288 SkTQSort<int>(sortedDist.begin(), sortedDist.end() - 1, DistanceLessThan(dis tances.begin()));
289 int remaining = count; // number of start/end pairs
290 for (rIndex = 0; rIndex < entries; ++rIndex) {
291 int pair = sortedDist[rIndex];
292 int row = pair / ends;
293 int col = pair - row * ends;
294 int thingOne = row < col ? row : ends - row - 2;
295 int ndxOne = thingOne >> 1;
296 bool endOne = thingOne & 1;
297 int* linkOne = endOne ? eLink.begin() : sLink.begin();
298 if (linkOne[ndxOne] != SK_MaxS32) {
299 continue;
300 }
301 int thingTwo = row < col ? col : ends - row + col - 1;
302 int ndxTwo = thingTwo >> 1;
303 bool endTwo = thingTwo & 1;
304 int* linkTwo = endTwo ? eLink.begin() : sLink.begin();
305 if (linkTwo[ndxTwo] != SK_MaxS32) {
306 continue;
307 }
308 SkASSERT(&linkOne[ndxOne] != &linkTwo[ndxTwo]);
309 bool flip = endOne == endTwo;
310 linkOne[ndxOne] = flip ? ~ndxTwo : ndxTwo;
311 linkTwo[ndxTwo] = flip ? ~ndxOne : ndxOne;
312 if (!--remaining) {
313 break;
314 }
315 }
316 SkASSERT(!remaining);
317 #if DEBUG_ASSEMBLE
318 for (rIndex = 0; rIndex < count; ++rIndex) {
319 int s = sLink[rIndex];
320 int e = eLink[rIndex];
321 SkDebugf("%s %c%d <- s%d - e%d -> %c%d\n", __FUNCTION__, s < 0 ? 's' : ' e',
322 s < 0 ? ~s : s, rIndex, rIndex, e < 0 ? 'e' : 's', e < 0 ? ~e : e);
323 }
324 #endif
325 rIndex = 0;
326 do {
327 bool forward = true;
328 bool first = true;
329 int sIndex = sLink[rIndex];
330 SkASSERT(sIndex != SK_MaxS32);
331 sLink[rIndex] = SK_MaxS32;
332 int eIndex;
333 if (sIndex < 0) {
334 eIndex = sLink[~sIndex];
335 sLink[~sIndex] = SK_MaxS32;
336 } else {
337 eIndex = eLink[sIndex];
338 eLink[sIndex] = SK_MaxS32;
339 }
340 SkASSERT(eIndex != SK_MaxS32);
341 #if DEBUG_ASSEMBLE
342 SkDebugf("%s sIndex=%c%d eIndex=%c%d\n", __FUNCTION__, sIndex < 0 ? 's' : 'e',
343 sIndex < 0 ? ~sIndex : sIndex, eIndex < 0 ? 's' : 'e',
344 eIndex < 0 ? ~eIndex : eIndex);
345 #endif
346 do {
347 const SkOpContour* contour = runs[rIndex];
348 if (first) {
349 first = false;
350 const SkPoint* startPtr = &contour->start();
351 simple->deferredMove(startPtr[0]);
352 }
353 if (forward) {
354 contour->toPartialForward(simple);
355 } else {
356 contour->toPartialBackward(simple);
357 }
358 #if DEBUG_ASSEMBLE
359 SkDebugf("%s rIndex=%d eIndex=%s%d close=%d\n", __FUNCTION__, rIndex ,
360 eIndex < 0 ? "~" : "", eIndex < 0 ? ~eIndex : eIndex,
361 sIndex == ((rIndex != eIndex) ^ forward ? eIndex : ~eIndex));
362 #endif
363 if (sIndex == ((rIndex != eIndex) ^ forward ? eIndex : ~eIndex)) {
364 simple->close();
365 break;
366 }
367 if (forward) {
368 eIndex = eLink[rIndex];
369 SkASSERT(eIndex != SK_MaxS32);
370 eLink[rIndex] = SK_MaxS32;
371 if (eIndex >= 0) {
372 SkASSERT(sLink[eIndex] == rIndex);
373 sLink[eIndex] = SK_MaxS32;
374 } else {
375 SkASSERT(eLink[~eIndex] == ~rIndex);
376 eLink[~eIndex] = SK_MaxS32;
377 }
378 } else {
379 eIndex = sLink[rIndex];
380 SkASSERT(eIndex != SK_MaxS32);
381 sLink[rIndex] = SK_MaxS32;
382 if (eIndex >= 0) {
383 SkASSERT(eLink[eIndex] == rIndex);
384 eLink[eIndex] = SK_MaxS32;
385 } else {
386 SkASSERT(sLink[~eIndex] == ~rIndex);
387 sLink[~eIndex] = SK_MaxS32;
388 }
389 }
390 rIndex = eIndex;
391 if (rIndex < 0) {
392 forward ^= 1;
393 rIndex = ~rIndex;
394 }
395 } while (true);
396 for (rIndex = 0; rIndex < count; ++rIndex) {
397 if (sLink[rIndex] != SK_MaxS32) {
398 break;
399 }
400 }
401 } while (rIndex < count);
402 #if DEBUG_ASSEMBLE
403 for (rIndex = 0; rIndex < count; ++rIndex) {
404 SkASSERT(sLink[rIndex] == SK_MaxS32);
405 SkASSERT(eLink[rIndex] == SK_MaxS32);
406 }
407 #endif
408 }
409
410 static void calcAngles(SkOpContourHead* contourList) { 201 static void calcAngles(SkOpContourHead* contourList) {
411 SkOpContour* contour = contourList; 202 SkOpContour* contour = contourList;
412 do { 203 do {
413 contour->calcAngles(); 204 contour->calcAngles();
414 } while ((contour = contour->next())); 205 } while ((contour = contour->next()));
415 } 206 }
416 207
417 static bool missingCoincidence(SkOpContourHead* contourList) { 208 static bool missingCoincidence(SkOpContourHead* contourList) {
418 SkOpContour* contour = contourList; 209 SkOpContour* contour = contourList;
419 bool result = false; 210 bool result = false;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 } 383 }
593 #if DEBUG_COINCIDENCE_VERBOSE 384 #if DEBUG_COINCIDENCE_VERBOSE
594 coincidence->debugShowCoincidence(); 385 coincidence->debugShowCoincidence();
595 #endif 386 #endif
596 #if DEBUG_COINCIDENCE 387 #if DEBUG_COINCIDENCE
597 coincidence->debugValidate(); 388 coincidence->debugValidate();
598 #endif 389 #endif
599 SkPathOpsDebug::ShowActiveSpans(contourList); 390 SkPathOpsDebug::ShowActiveSpans(contourList);
600 return true; 391 return true;
601 } 392 }
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsCommon.h ('k') | src/pathops/SkPathOpsCurve.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698