gfx/skia/trunk/src/pathops/SkPathWriter.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/pathops/SkPathWriter.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,166 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +#include "SkPathOpsPoint.h"
    1.11 +#include "SkPathWriter.h"
    1.12 +
    1.13 +// wrap path to keep track of whether the contour is initialized and non-empty
    1.14 +SkPathWriter::SkPathWriter(SkPath& path)
    1.15 +    : fPathPtr(&path)
    1.16 +    , fCloses(0)
    1.17 +    , fMoves(0)
    1.18 +{
    1.19 +    init();
    1.20 +}
    1.21 +
    1.22 +void SkPathWriter::close() {
    1.23 +    if (!fHasMove) {
    1.24 +        return;
    1.25 +    }
    1.26 +    bool callClose = isClosed();
    1.27 +    lineTo();
    1.28 +    if (fEmpty) {
    1.29 +        return;
    1.30 +    }
    1.31 +    if (callClose) {
    1.32 +#if DEBUG_PATH_CONSTRUCTION
    1.33 +        SkDebugf("path.close();\n");
    1.34 +#endif
    1.35 +        fPathPtr->close();
    1.36 +        fCloses++;
    1.37 +    }
    1.38 +    init();
    1.39 +}
    1.40 +
    1.41 +void SkPathWriter::cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkPoint& pt3) {
    1.42 +    lineTo();
    1.43 +    if (fEmpty && AlmostEqualUlps(fDefer[0], pt1) && AlmostEqualUlps(pt1, pt2)
    1.44 +            && AlmostEqualUlps(pt2, pt3)) {
    1.45 +        deferredLine(pt3);
    1.46 +        return;
    1.47 +    }
    1.48 +    moveTo();
    1.49 +    fDefer[1] = pt3;
    1.50 +    nudge();
    1.51 +    fDefer[0] = fDefer[1];
    1.52 +#if DEBUG_PATH_CONSTRUCTION
    1.53 +    SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n",
    1.54 +            pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
    1.55 +#endif
    1.56 +    fPathPtr->cubicTo(pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
    1.57 +    fEmpty = false;
    1.58 +}
    1.59 +
    1.60 +void SkPathWriter::deferredLine(const SkPoint& pt) {
    1.61 +    if (pt == fDefer[1]) {
    1.62 +        return;
    1.63 +    }
    1.64 +    if (changedSlopes(pt)) {
    1.65 +        lineTo();
    1.66 +        fDefer[0] = fDefer[1];
    1.67 +    }
    1.68 +    fDefer[1] = pt;
    1.69 +}
    1.70 +
    1.71 +void SkPathWriter::deferredMove(const SkPoint& pt) {
    1.72 +    fMoved = true;
    1.73 +    fHasMove = true;
    1.74 +    fEmpty = true;
    1.75 +    fDefer[0] = fDefer[1] = pt;
    1.76 +}
    1.77 +
    1.78 +void SkPathWriter::deferredMoveLine(const SkPoint& pt) {
    1.79 +    if (!fHasMove) {
    1.80 +        deferredMove(pt);
    1.81 +    }
    1.82 +    deferredLine(pt);
    1.83 +}
    1.84 +
    1.85 +bool SkPathWriter::hasMove() const {
    1.86 +    return fHasMove;
    1.87 +}
    1.88 +
    1.89 +void SkPathWriter::init() {
    1.90 +    fEmpty = true;
    1.91 +    fHasMove = false;
    1.92 +    fMoved = false;
    1.93 +}
    1.94 +
    1.95 +bool SkPathWriter::isClosed() const {
    1.96 +    return !fEmpty && SkDPoint::ApproximatelyEqual(fFirstPt, fDefer[1]);
    1.97 +}
    1.98 +
    1.99 +void SkPathWriter::lineTo() {
   1.100 +    if (fDefer[0] == fDefer[1]) {
   1.101 +        return;
   1.102 +    }
   1.103 +    moveTo();
   1.104 +    nudge();
   1.105 +    fEmpty = false;
   1.106 +#if DEBUG_PATH_CONSTRUCTION
   1.107 +    SkDebugf("path.lineTo(%1.9g,%1.9g);\n", fDefer[1].fX, fDefer[1].fY);
   1.108 +#endif
   1.109 +    fPathPtr->lineTo(fDefer[1].fX, fDefer[1].fY);
   1.110 +    fDefer[0] = fDefer[1];
   1.111 +}
   1.112 +
   1.113 +const SkPath* SkPathWriter::nativePath() const {
   1.114 +    return fPathPtr;
   1.115 +}
   1.116 +
   1.117 +void SkPathWriter::nudge() {
   1.118 +    if (fEmpty || !AlmostEqualUlps(fDefer[1].fX, fFirstPt.fX)
   1.119 +            || !AlmostEqualUlps(fDefer[1].fY, fFirstPt.fY)) {
   1.120 +        return;
   1.121 +    }
   1.122 +    fDefer[1] = fFirstPt;
   1.123 +}
   1.124 +
   1.125 +void SkPathWriter::quadTo(const SkPoint& pt1, const SkPoint& pt2) {
   1.126 +    lineTo();
   1.127 +    if (fEmpty && AlmostEqualUlps(fDefer[0], pt1) && AlmostEqualUlps(pt1, pt2)) {
   1.128 +        deferredLine(pt2);
   1.129 +        return;
   1.130 +    }
   1.131 +    moveTo();
   1.132 +    fDefer[1] = pt2;
   1.133 +    nudge();
   1.134 +    fDefer[0] = fDefer[1];
   1.135 +#if DEBUG_PATH_CONSTRUCTION
   1.136 +    SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n",
   1.137 +            pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
   1.138 +#endif
   1.139 +    fPathPtr->quadTo(pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
   1.140 +    fEmpty = false;
   1.141 +}
   1.142 +
   1.143 +bool SkPathWriter::someAssemblyRequired() const {
   1.144 +    return fCloses < fMoves;
   1.145 +}
   1.146 +
   1.147 +bool SkPathWriter::changedSlopes(const SkPoint& pt) const {
   1.148 +    if (fDefer[0] == fDefer[1]) {
   1.149 +        return false;
   1.150 +    }
   1.151 +    SkScalar deferDx = fDefer[1].fX - fDefer[0].fX;
   1.152 +    SkScalar deferDy = fDefer[1].fY - fDefer[0].fY;
   1.153 +    SkScalar lineDx = pt.fX - fDefer[1].fX;
   1.154 +    SkScalar lineDy = pt.fY - fDefer[1].fY;
   1.155 +    return deferDx * lineDy != deferDy * lineDx;
   1.156 +}
   1.157 +
   1.158 +void SkPathWriter::moveTo() {
   1.159 +    if (!fMoved) {
   1.160 +        return;
   1.161 +    }
   1.162 +    fFirstPt = fDefer[0];
   1.163 +#if DEBUG_PATH_CONSTRUCTION
   1.164 +    SkDebugf("path.moveTo(%1.9g,%1.9g);\n", fDefer[0].fX, fDefer[0].fY);
   1.165 +#endif
   1.166 +    fPathPtr->moveTo(fDefer[0].fX, fDefer[0].fY);
   1.167 +    fMoved = false;
   1.168 +    fMoves++;
   1.169 +}

mercurial