| Index: src/pathops/SkPathWriter.cpp
|
| ===================================================================
|
| --- src/pathops/SkPathWriter.cpp (revision 0)
|
| +++ src/pathops/SkPathWriter.cpp (revision 0)
|
| @@ -0,0 +1,157 @@
|
| +/*
|
| + * Copyright 2012 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +#include "SkPathOpsTypes.h"
|
| +#include "SkPathWriter.h"
|
| +
|
| +// wrap path to keep track of whether the contour is initialized and non-empty
|
| +SkPathWriter::SkPathWriter(SkPath& path)
|
| + : fPathPtr(&path)
|
| + , fCloses(0)
|
| + , fMoves(0)
|
| +{
|
| + init();
|
| +}
|
| +
|
| +void SkPathWriter::close() {
|
| + if (!fHasMove) {
|
| + return;
|
| + }
|
| + bool callClose = isClosed();
|
| + lineTo();
|
| + if (fEmpty) {
|
| + return;
|
| + }
|
| + if (callClose) {
|
| +#if DEBUG_PATH_CONSTRUCTION
|
| + SkDebugf("path.close();\n");
|
| +#endif
|
| + fPathPtr->close();
|
| + fCloses++;
|
| + }
|
| + init();
|
| +}
|
| +
|
| +void SkPathWriter::cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkPoint& pt3) {
|
| + lineTo();
|
| + moveTo();
|
| + fDefer[1] = pt3;
|
| + nudge();
|
| + fDefer[0] = fDefer[1];
|
| +#if DEBUG_PATH_CONSTRUCTION
|
| + SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n",
|
| + pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
|
| +#endif
|
| + fPathPtr->cubicTo(pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
|
| + fEmpty = false;
|
| +}
|
| +
|
| +void SkPathWriter::deferredLine(const SkPoint& pt) {
|
| + if (pt == fDefer[1]) {
|
| + return;
|
| + }
|
| + if (changedSlopes(pt)) {
|
| + lineTo();
|
| + fDefer[0] = fDefer[1];
|
| + }
|
| + fDefer[1] = pt;
|
| +}
|
| +
|
| +void SkPathWriter::deferredMove(const SkPoint& pt) {
|
| + fMoved = true;
|
| + fHasMove = true;
|
| + fEmpty = true;
|
| + fDefer[0] = fDefer[1] = pt;
|
| +}
|
| +
|
| +void SkPathWriter::deferredMoveLine(const SkPoint& pt) {
|
| + if (!fHasMove) {
|
| + deferredMove(pt);
|
| + }
|
| + deferredLine(pt);
|
| +}
|
| +
|
| +bool SkPathWriter::hasMove() const {
|
| + return fHasMove;
|
| +}
|
| +
|
| +void SkPathWriter::init() {
|
| + fEmpty = true;
|
| + fHasMove = false;
|
| + fMoved = false;
|
| +}
|
| +
|
| +bool SkPathWriter::isClosed() const {
|
| + return !fEmpty && fFirstPt == fDefer[1];
|
| +}
|
| +
|
| +void SkPathWriter::lineTo() {
|
| + if (fDefer[0] == fDefer[1]) {
|
| + return;
|
| + }
|
| + moveTo();
|
| + nudge();
|
| + fEmpty = false;
|
| +#if DEBUG_PATH_CONSTRUCTION
|
| + SkDebugf("path.lineTo(%1.9g,%1.9g);\n", fDefer[1].fX, fDefer[1].fY);
|
| +#endif
|
| + fPathPtr->lineTo(fDefer[1].fX, fDefer[1].fY);
|
| + fDefer[0] = fDefer[1];
|
| +}
|
| +
|
| +const SkPath* SkPathWriter::nativePath() const {
|
| + return fPathPtr;
|
| +}
|
| +
|
| +void SkPathWriter::nudge() {
|
| + if (fEmpty || !AlmostEqualUlps(fDefer[1].fX, fFirstPt.fX)
|
| + || !AlmostEqualUlps(fDefer[1].fY, fFirstPt.fY)) {
|
| + return;
|
| + }
|
| + fDefer[1] = fFirstPt;
|
| +}
|
| +
|
| +void SkPathWriter::quadTo(const SkPoint& pt1, const SkPoint& pt2) {
|
| + lineTo();
|
| + moveTo();
|
| + fDefer[1] = pt2;
|
| + nudge();
|
| + fDefer[0] = fDefer[1];
|
| +#if DEBUG_PATH_CONSTRUCTION
|
| + SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n",
|
| + pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
|
| +#endif
|
| + fPathPtr->quadTo(pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
|
| + fEmpty = false;
|
| +}
|
| +
|
| +bool SkPathWriter::someAssemblyRequired() const {
|
| + return fCloses < fMoves;
|
| +}
|
| +
|
| +bool SkPathWriter::changedSlopes(const SkPoint& pt) const {
|
| + if (fDefer[0] == fDefer[1]) {
|
| + return false;
|
| + }
|
| + SkScalar deferDx = fDefer[1].fX - fDefer[0].fX;
|
| + SkScalar deferDy = fDefer[1].fY - fDefer[0].fY;
|
| + SkScalar lineDx = pt.fX - fDefer[1].fX;
|
| + SkScalar lineDy = pt.fY - fDefer[1].fY;
|
| + return deferDx * lineDy != deferDy * lineDx;
|
| +}
|
| +
|
| +void SkPathWriter::moveTo() {
|
| + if (!fMoved) {
|
| + return;
|
| + }
|
| + fFirstPt = fDefer[0];
|
| +#if DEBUG_PATH_CONSTRUCTION
|
| + SkDebugf("path.moveTo(%1.9g,%1.9g);\n", fDefer[0].fX, fDefer[0].fY);
|
| +#endif
|
| + fPathPtr->moveTo(fDefer[0].fX, fDefer[0].fY);
|
| + fMoved = false;
|
| + fMoves++;
|
| +}
|
|
|