17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/* 27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2012 Google Inc. 37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file. 67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPathOpsPoint.h" 87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPathWriter.h" 97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// wrap path to keep track of whether the contour is initialized and non-empty 117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerSkPathWriter::SkPathWriter(SkPath& path) 127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger : fPathPtr(&path) 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger , fCloses(0) 147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger , fMoves(0) 157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger{ 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger init(); 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::close() { 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!fHasMove) { 217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool callClose = isClosed(); 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger lineTo(); 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fEmpty) { 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (callClose) { 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_PATH_CONSTRUCTION 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("path.close();\n"); 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fPathPtr->close(); 337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fCloses++; 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger init(); 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkPoint& pt3) { 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger lineTo(); 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fEmpty && AlmostEqualUlps(fDefer[0], pt1) && AlmostEqualUlps(pt1, pt2) 417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && AlmostEqualUlps(pt2, pt3)) { 427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger deferredLine(pt3); 437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger moveTo(); 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[1] = pt3; 477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger nudge(); 487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[0] = fDefer[1]; 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_PATH_CONSTRUCTION 507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n", 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY); 527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fPathPtr->cubicTo(pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY); 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fEmpty = false; 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::deferredLine(const SkPoint& pt) { 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (pt == fDefer[1]) { 597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (changedSlopes(pt)) { 627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger lineTo(); 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[0] = fDefer[1]; 647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[1] = pt; 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::deferredMove(const SkPoint& pt) { 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fMoved = true; 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fHasMove = true; 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fEmpty = true; 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[0] = fDefer[1] = pt; 737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::deferredMoveLine(const SkPoint& pt) { 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!fHasMove) { 777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger deferredMove(pt); 787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger deferredLine(pt); 807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkPathWriter::hasMove() const { 837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return fHasMove; 847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::init() { 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fEmpty = true; 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fHasMove = false; 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fMoved = false; 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkPathWriter::isClosed() const { 930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return !fEmpty && SkDPoint::ApproximatelyEqual(fFirstPt, fDefer[1]); 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::lineTo() { 977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fDefer[0] == fDefer[1]) { 987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger moveTo(); 1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger nudge(); 1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fEmpty = false; 1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_PATH_CONSTRUCTION 1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("path.lineTo(%1.9g,%1.9g);\n", fDefer[1].fX, fDefer[1].fY); 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fPathPtr->lineTo(fDefer[1].fX, fDefer[1].fY); 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[0] = fDefer[1]; 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerconst SkPath* SkPathWriter::nativePath() const { 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return fPathPtr; 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::nudge() { 1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fEmpty || !AlmostEqualUlps(fDefer[1].fX, fFirstPt.fX) 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || !AlmostEqualUlps(fDefer[1].fY, fFirstPt.fY)) { 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[1] = fFirstPt; 1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::quadTo(const SkPoint& pt1, const SkPoint& pt2) { 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger lineTo(); 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fEmpty && AlmostEqualUlps(fDefer[0], pt1) && AlmostEqualUlps(pt1, pt2)) { 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger deferredLine(pt2); 1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger moveTo(); 1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[1] = pt2; 1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger nudge(); 1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fDefer[0] = fDefer[1]; 1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_PATH_CONSTRUCTION 1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n", 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY); 1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fPathPtr->quadTo(pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY); 1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fEmpty = false; 1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkPathWriter::someAssemblyRequired() const { 1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return fCloses < fMoves; 1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool SkPathWriter::changedSlopes(const SkPoint& pt) const { 1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (fDefer[0] == fDefer[1]) { 1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar deferDx = fDefer[1].fX - fDefer[0].fX; 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar deferDy = fDefer[1].fY - fDefer[0].fY; 1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar lineDx = pt.fX - fDefer[1].fX; 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar lineDy = pt.fY - fDefer[1].fY; 1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return deferDx * lineDy != deferDy * lineDx; 1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid SkPathWriter::moveTo() { 1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!fMoved) { 1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fFirstPt = fDefer[0]; 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_PATH_CONSTRUCTION 1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("path.moveTo(%1.9g,%1.9g);\n", fDefer[0].fX, fDefer[0].fY); 1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fPathPtr->moveTo(fDefer[0].fX, fDefer[0].fY); 1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fMoved = false; 1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fMoves++; 1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 167