11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "gm.h"
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkCanvas.h"
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkPaint.h"
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkRandom.h"
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace skiagm {
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass DegenerateSegmentsGM : public GM {
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    DegenerateSegmentsGM() {}
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    struct PathAndName {
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPath      fPath;
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const char* fName1;
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const char* fName2;
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkString onShortName() {
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return SkString("degeneratesegments");
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkISize onISize() { return make_isize(896, 930); }
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef SkPoint (*AddSegmentFunc)(SkPath&, SkPoint&);
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We need to use explicit commands here, instead of addPath, because we
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // do not want the moveTo that is added at the beginning of a path to
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // appear in the appended path.
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMove(SkPath& path, SkPoint& startPt) {
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveClose(SkPath& path, SkPoint& startPt) {
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddDegenLine(SkPath& path, SkPoint& startPt) {
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.lineTo(startPt);
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return startPt;
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveDegenLine(SkPath& path, SkPoint& startPt) {
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.lineTo(moveToPt);
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveDegenLineClose(SkPath& path, SkPoint& startPt) {
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.lineTo(moveToPt);
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddDegenQuad(SkPath& path, SkPoint& startPt) {
701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.quadTo(startPt, startPt);
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return startPt;
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveDegenQuad(SkPath& path, SkPoint& startPt) {
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.quadTo(moveToPt, moveToPt);
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveDegenQuadClose(SkPath& path, SkPoint& startPt) {
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.quadTo(moveToPt, moveToPt);
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddDegenCubic(SkPath& path, SkPoint& startPt) {
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.cubicTo(startPt, startPt, startPt);
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return startPt;
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveDegenCubic(SkPath& path, SkPoint& startPt) {
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.cubicTo(moveToPt, moveToPt, moveToPt);
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveDegenCubicClose(SkPath& path, SkPoint& startPt) {
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.cubicTo(moveToPt, moveToPt, moveToPt);
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return moveToPt;
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddClose(SkPath& path, SkPoint& startPt) {
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return startPt;
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddLine(SkPath& path, SkPoint& startPt) {
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.lineTo(endPt);
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveLine(SkPath& path, SkPoint& startPt) {
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.lineTo(endPt);
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveLineClose(SkPath& path, SkPoint& startPt) {
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.lineTo(endPt);
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddQuad(SkPath& path, SkPoint& startPt) {
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint midPt = startPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.quadTo(midPt, endPt);
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveQuad(SkPath& path, SkPoint& startPt) {
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.quadTo(midPt, endPt);
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveQuadClose(SkPath& path, SkPoint& startPt) {
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.quadTo(midPt, endPt);
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddCubic(SkPath& path, SkPoint& startPt) {
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint t1Pt = startPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint t2Pt = startPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.cubicTo(t1Pt, t2Pt, endPt);
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveCubic(SkPath& path, SkPoint& startPt) {
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.cubicTo(t1Pt, t2Pt, endPt);
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static SkPoint AddMoveCubicClose(SkPath& path, SkPoint& startPt) {
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(moveToPt);
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.cubicTo(t1Pt, t2Pt, endPt);
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.close();
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return endPt;
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    void drawPath(SkPath& path, SkCanvas* canvas, SkColor color,
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                  const SkRect& clip, SkPaint::Cap cap, SkPaint::Join join,
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                  SkPaint::Style style, SkPath::FillType fill,
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                  SkScalar strokeWidth) {
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.setFillType(fill);
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPaint paint;
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setStrokeCap(cap);
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setStrokeWidth(strokeWidth);
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setStrokeJoin(join);
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setColor(color);
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setStyle(style);
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->save();
2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->clipRect(clip);
2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->drawPath(path, paint);
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->restore();
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void onDraw(SkCanvas* canvas) {
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const AddSegmentFunc gSegmentFunctions[] = {
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMove,
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveClose,
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddDegenLine,
2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveDegenLine,
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveDegenLineClose,
2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddDegenQuad,
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveDegenQuad,
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveDegenQuadClose,
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddDegenCubic,
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveDegenCubic,
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveDegenCubicClose,
2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddClose,
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddLine,
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveLine,
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveLineClose,
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddQuad,
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveQuad,
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveQuadClose,
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddCubic,
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveCubic,
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AddMoveCubicClose
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const char* gSegmentNames[] = {
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "Move",
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveClose",
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "DegenLine",
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveDegenLine",
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveDegenLineClose",
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "DegenQuad",
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveDegenQuad",
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveDegenQuadClose",
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "DegenCubic",
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveDegenCubic",
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveDegenCubicClose",
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "Close",
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "Line",
2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveLine",
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveLineClose",
2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "Quad",
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveQuad",
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveQuadClose",
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "Cubic",
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveCubic",
2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "MoveCubicClose"
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        struct FillAndName {
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkPath::FillType fFill;
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const char*      fName;
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static const FillAndName gFills[] = {
2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPath::kWinding_FillType, "Winding"},
2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPath::kEvenOdd_FillType, "Even / Odd"},
2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPath::kInverseWinding_FillType, "Inverse Winding"},
2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}
2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        struct StyleAndName {
2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkPaint::Style fStyle;
2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const char*    fName;
2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static const StyleAndName gStyles[] = {
2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPaint::kFill_Style, "Fill"},
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPaint::kStroke_Style, "Stroke 10"},
2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPaint::kStrokeAndFill_Style, "Stroke 10 And Fill"}
2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        struct CapAndName {
2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkPaint::Cap  fCap;
2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkPaint::Join fJoin;
2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const char*   fName;
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static const CapAndName gCaps[] = {
2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPaint titlePaint;
2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        titlePaint.setColor(SK_ColorBLACK);
2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        titlePaint.setAntiAlias(true);
2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        titlePaint.setLCDRenderText(true);
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        titlePaint.setTextSize(15 * SK_Scalar1);
2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const char title[] = "Random Paths Drawn Into Rectangle Clips With "
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             "Indicated Style, Fill and Linecaps, "
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             "with Stroke width 6";
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->drawText(title, strlen(title),
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            20 * SK_Scalar1,
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            20 * SK_Scalar1,
2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            titlePaint);
2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRandom rand;
3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRect rect = SkRect::MakeWH(220*SK_Scalar1, 50*SK_Scalar1);
3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->save();
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->translate(2*SK_Scalar1, 30 * SK_Scalar1); // The title
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->save();
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        unsigned numSegments = SK_ARRAY_COUNT(gSegmentFunctions);
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        unsigned numCaps = SK_ARRAY_COUNT(gCaps);
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        unsigned numStyles = SK_ARRAY_COUNT(gStyles);
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        unsigned numFills = SK_ARRAY_COUNT(gFills);
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (size_t row = 0; row < 6; ++row) {
3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (0 < row) {
3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->translate(0, rect.height() + 100*SK_Scalar1);
3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            canvas->save();
3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (size_t column = 0; column < 4; ++column) {
3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (0 < column) {
3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    canvas->translate(rect.width() + 4*SK_Scalar1, 0);
3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkColor color = 0xff007000;
3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                StyleAndName style = gStyles[(rand.nextU() >> 16) % numStyles];
3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                CapAndName cap = gCaps[(rand.nextU() >> 16) % numCaps];
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                FillAndName fill = gFills[(rand.nextU() >> 16) % numFills];
3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkPath path;
3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                unsigned s1 = (rand.nextU() >> 16) % numSegments;
3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                unsigned s2 = (rand.nextU() >> 16) % numSegments;
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                unsigned s3 = (rand.nextU() >> 16) % numSegments;
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                unsigned s4 = (rand.nextU() >> 16) % numSegments;
3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                unsigned s5 = (rand.nextU() >> 16) % numSegments;
3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkPoint pt = SkPoint::Make(10*SK_Scalar1, 0);
3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pt = gSegmentFunctions[s1](path, pt);
3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pt = gSegmentFunctions[s2](path, pt);
3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pt = gSegmentFunctions[s3](path, pt);
3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pt = gSegmentFunctions[s4](path, pt);
3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pt = gSegmentFunctions[s5](path, pt);
3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                this->drawPath(path, canvas, color, rect,
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               cap.fCap, cap.fJoin, style.fStyle,
3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               fill.fFill, SK_Scalar1*6);
3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkPaint rectPaint;
3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                rectPaint.setColor(SK_ColorBLACK);
3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                rectPaint.setStyle(SkPaint::kStroke_Style);
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                rectPaint.setStrokeWidth(-1);
3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                rectPaint.setAntiAlias(true);
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawRect(rect, rectPaint);
3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkPaint labelPaint;
3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                labelPaint.setColor(color);
3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                labelPaint.setAntiAlias(true);
3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                labelPaint.setLCDRenderText(true);
3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                labelPaint.setTextSize(10 * SK_Scalar1);
3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(style.fName,
3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(style.fName),
3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 12 * SK_Scalar1,
3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(fill.fName,
3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(fill.fName),
3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 24 * SK_Scalar1,
3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(cap.fName,
3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(cap.fName),
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 36 * SK_Scalar1,
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(gSegmentNames[s1],
3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(gSegmentNames[s1]),
3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 48 * SK_Scalar1,
3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(gSegmentNames[s2],
3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(gSegmentNames[s2]),
3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 60 * SK_Scalar1,
3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(gSegmentNames[s3],
3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(gSegmentNames[s3]),
3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 72 * SK_Scalar1,
3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(gSegmentNames[s4],
3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(gSegmentNames[s4]),
3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 84 * SK_Scalar1,
3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->drawText(gSegmentNames[s5],
3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 strlen(gSegmentNames[s5]),
3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, rect.height() + 96 * SK_Scalar1,
3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 labelPaint);
3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            canvas->restore();
3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->restore();
3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        canvas->restore();
3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef GM INHERITED;
3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////
3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic GM* MyFactory(void*) { return new DegenerateSegmentsGM; }
3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic GMRegistry reg(MyFactory);
3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
401