convex_all_line_paths.cpp revision 2a974625c559fcb2640b587fed6f92d5b58cab24
17272935744670aebf82699c2f91aaff3cd4c3172robertphillips/*
27272935744670aebf82699c2f91aaff3cd4c3172robertphillips * Copyright 2015 Google Inc.
37272935744670aebf82699c2f91aaff3cd4c3172robertphillips *
47272935744670aebf82699c2f91aaff3cd4c3172robertphillips * Use of this source code is governed by a BSD-style license that can be
57272935744670aebf82699c2f91aaff3cd4c3172robertphillips * found in the LICENSE file.
67272935744670aebf82699c2f91aaff3cd4c3172robertphillips */
77272935744670aebf82699c2f91aaff3cd4c3172robertphillips
87272935744670aebf82699c2f91aaff3cd4c3172robertphillips#include "gm.h"
97272935744670aebf82699c2f91aaff3cd4c3172robertphillips
107272935744670aebf82699c2f91aaff3cd4c3172robertphillipsstatic void create_ngon(int n, SkPoint* pts, SkScalar width, SkScalar height) {
117272935744670aebf82699c2f91aaff3cd4c3172robertphillips    float angleStep = 360.0f / n, angle = 0.0f, sin, cos;
127272935744670aebf82699c2f91aaff3cd4c3172robertphillips    if ((n % 2) == 1) {
137272935744670aebf82699c2f91aaff3cd4c3172robertphillips        angle = angleStep/2.0f;
147272935744670aebf82699c2f91aaff3cd4c3172robertphillips    }
157272935744670aebf82699c2f91aaff3cd4c3172robertphillips
167272935744670aebf82699c2f91aaff3cd4c3172robertphillips    for (int i = 0; i < n; ++i) {
177272935744670aebf82699c2f91aaff3cd4c3172robertphillips        sin = SkScalarSinCos(SkDegreesToRadians(angle), &cos);
187272935744670aebf82699c2f91aaff3cd4c3172robertphillips        pts[i].fX = -sin * width;
197272935744670aebf82699c2f91aaff3cd4c3172robertphillips        pts[i].fY = cos * height;
207272935744670aebf82699c2f91aaff3cd4c3172robertphillips        angle += angleStep;
217272935744670aebf82699c2f91aaff3cd4c3172robertphillips    }
227272935744670aebf82699c2f91aaff3cd4c3172robertphillips}
237272935744670aebf82699c2f91aaff3cd4c3172robertphillips
247272935744670aebf82699c2f91aaff3cd4c3172robertphillipsnamespace skiagm {
257272935744670aebf82699c2f91aaff3cd4c3172robertphillips
267272935744670aebf82699c2f91aaff3cd4c3172robertphillips// This GM is intended to exercise Ganesh's handling of convex line-only
277272935744670aebf82699c2f91aaff3cd4c3172robertphillips// paths
287272935744670aebf82699c2f91aaff3cd4c3172robertphillipsclass ConvexLineOnlyPathsGM : public GM {
297272935744670aebf82699c2f91aaff3cd4c3172robertphillipspublic:
307272935744670aebf82699c2f91aaff3cd4c3172robertphillips    ConvexLineOnlyPathsGM() {
317272935744670aebf82699c2f91aaff3cd4c3172robertphillips        this->setBGColor(0xFFFFFFFF);
327272935744670aebf82699c2f91aaff3cd4c3172robertphillips    }
337272935744670aebf82699c2f91aaff3cd4c3172robertphillips
347272935744670aebf82699c2f91aaff3cd4c3172robertphillipsprotected:
357272935744670aebf82699c2f91aaff3cd4c3172robertphillips    SkString onShortName() override { return SkString("convex-lineonly-paths"); }
367272935744670aebf82699c2f91aaff3cd4c3172robertphillips    SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); }
377272935744670aebf82699c2f91aaff3cd4c3172robertphillips    bool runAsBench() const override { return true; }
387272935744670aebf82699c2f91aaff3cd4c3172robertphillips
397272935744670aebf82699c2f91aaff3cd4c3172robertphillips    static SkPath GetPath(int index, int offset, SkPath::Direction dir) {
407272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // narrow rect
417272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints0[] = {
427272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -1.5f, -50.0f },
437272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  1.5f, -50.0f },
447272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  1.5f,  50.0f },
457272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -1.5f,  50.0f }
467272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
477272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // narrow rect on an angle
487272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints1[] = {
497272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -50.0f, -49.0f },
507272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -49.0f, -50.0f },
517272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  50.0f,  49.0f },
527272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  49.0f,  50.0f }
537272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
547272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // trap - narrow on top - wide on bottom
557272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints2[] = {
567272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -10.0f, -50.0f },
577272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f, -50.0f },
587272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  50.0f,  50.0f },
597272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -50.0f,  50.0f }
607272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
617272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // wide skewed rect
627272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints3[] = {
637272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -50.0f, -50.0f },
647272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {   0.0f, -50.0f },
657272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  50.0f,  50.0f },
667272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {   0.0f,  50.0f }
677272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
687272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // thin rect with colinear-ish lines
697272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints4[] = {
707272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -6.0f, -50.0f },
717272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  4.0f, -50.0f },
727272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  5.0f, -25.0f },
737272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  6.0f,   0.0f },
747272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  5.0f,  25.0f },
757272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  4.0f,  50.0f },
767272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -4.0f,  50.0f }
777272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
787272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // degenerate
797272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints5[] = {
807272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -0.025f, -0.025f  },
817272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  0.025f, -0.025f  },
827272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  0.025f,  0.025f },
837272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -0.025f,  0.025f }
847272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
857272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // Triangle in which the first point should fuse with last
867272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints6[] = {
877272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -20.0f, -13.0f },
887272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -20.0f, -13.05f },
897272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  20.0f, -13.0f },
907272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  20.0f,  27.0f }
917272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
927272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // thin rect with colinear lines
937272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints7[] = {
947272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -10.0f, -50.0f },
957272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f, -50.0f },
967272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f, -25.0f },
977272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f,   0.0f },
987272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f,  25.0f },
997272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f,  50.0f },
1007272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -10.0f,  50.0f }
1017272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
1027272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // capped teardrop
1037272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints8[] = {
1047272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  50.00f,  50.00f },
1057272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {   0.00f,  50.00f },
1067272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -15.45f,  47.55f },
1077272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -29.39f,  40.45f },
1087272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -40.45f,  29.39f },
1097272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -47.55f,  15.45f },
1107272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -50.00f,   0.00f },
1117272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -47.55f, -15.45f },
1127272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -40.45f, -29.39f },
1137272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -29.39f, -40.45f },
1147272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -15.45f, -47.55f },
1157272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {   0.00f, -50.00f },
1167272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  50.00f, -50.00f }
1177272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
1187272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // teardrop
1197272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints9[] = {
1207272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {   4.39f,  40.45f },
1217272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  -9.55f,  47.55f },
1227272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -25.00f,  50.00f },
1237272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -40.45f,  47.55f },
1247272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -54.39f,  40.45f },
1257272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -65.45f,  29.39f },
1267272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -72.55f,  15.45f },
1277272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -75.00f,   0.00f },
1287272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -72.55f, -15.45f },
1297272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -65.45f, -29.39f },
1307272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -54.39f, -40.45f },
1317272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -40.45f, -47.55f },
1327272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -25.0f,  -50.0f },
1337272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  -9.55f, -47.55f },
1347272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {   4.39f, -40.45f },
1357272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  75.00f,   0.00f }
1367272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
1377272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // clipped triangle
1387272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint gPoints10[] = {
1397272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -10.0f, -50.0f },
1407272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  10.0f, -50.0f },
1417272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  50.0f,  31.0f },
1427272935744670aebf82699c2f91aaff3cd4c3172robertphillips            {  40.0f,  50.0f },
1437272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -40.0f,  50.0f },
1447272935744670aebf82699c2f91aaff3cd4c3172robertphillips            { -50.0f,  31.0f },
1457272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
1467272935744670aebf82699c2f91aaff3cd4c3172robertphillips
1477272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint* gPoints[] = {
1487272935744670aebf82699c2f91aaff3cd4c3172robertphillips            gPoints0, gPoints1, gPoints2, gPoints3, gPoints4, gPoints5, gPoints6,
1497272935744670aebf82699c2f91aaff3cd4c3172robertphillips            gPoints7, gPoints8, gPoints9, gPoints10,
1507272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
1517272935744670aebf82699c2f91aaff3cd4c3172robertphillips
1527272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const size_t gSizes[] = {
1537272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints0),
1547272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints1),
1557272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints2),
1567272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints3),
1577272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints4),
1587272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints5),
1597272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints6),
1607272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints7),
1617272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints8),
1627272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints9),
1637272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SK_ARRAY_COUNT(gPoints10),
1647272935744670aebf82699c2f91aaff3cd4c3172robertphillips        };
1657272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSizes) == SK_ARRAY_COUNT(gPoints), array_mismatch);
1667272935744670aebf82699c2f91aaff3cd4c3172robertphillips
167db3f8cdb5969dbdc65008b87ab90a0bfe33a406brobertphillips        SkAutoTDeleteArray<SkPoint> data(NULL);
1687272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPoint* points;
1697272935744670aebf82699c2f91aaff3cd4c3172robertphillips        int numPts;
1707272935744670aebf82699c2f91aaff3cd4c3172robertphillips        if (index < (int) SK_ARRAY_COUNT(gPoints)) {
1717272935744670aebf82699c2f91aaff3cd4c3172robertphillips            // manually specified
1727272935744670aebf82699c2f91aaff3cd4c3172robertphillips            points = gPoints[index];
1737272935744670aebf82699c2f91aaff3cd4c3172robertphillips            numPts = (int) gSizes[index];
1747272935744670aebf82699c2f91aaff3cd4c3172robertphillips        } else {
1757272935744670aebf82699c2f91aaff3cd4c3172robertphillips            // procedurally generated
1767272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SkScalar width = kMaxPathHeight/2;
1777272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SkScalar height = kMaxPathHeight/2;
1787272935744670aebf82699c2f91aaff3cd4c3172robertphillips            switch (index-SK_ARRAY_COUNT(gPoints)) {
1797272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 0:
1807272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 3;
1817272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
1827272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 1:
1837272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 4;
1847272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
1857272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 2:
1867272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 5;
1877272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
1887272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 3:             // squashed pentagon
1897272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 5;
1907272935744670aebf82699c2f91aaff3cd4c3172robertphillips                width = kMaxPathHeight/5;
1917272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
1927272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 4:
1937272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 6;
1947272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
1957272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 5:
1967272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 8;
1977272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
1987272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 6:              // squashed octogon
1997272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 8;
2007272935744670aebf82699c2f91aaff3cd4c3172robertphillips                width = kMaxPathHeight/5;
2017272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
2027272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 7:
2037272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 20;
2047272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
2057272935744670aebf82699c2f91aaff3cd4c3172robertphillips            case 8:
2067272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 100;
2077272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
2087272935744670aebf82699c2f91aaff3cd4c3172robertphillips            default:
2097272935744670aebf82699c2f91aaff3cd4c3172robertphillips                numPts = 3;
2107272935744670aebf82699c2f91aaff3cd4c3172robertphillips                break;
2117272935744670aebf82699c2f91aaff3cd4c3172robertphillips            }
2127272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2137272935744670aebf82699c2f91aaff3cd4c3172robertphillips            data.reset(SkNEW_ARRAY(SkPoint, numPts));
2147272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2157272935744670aebf82699c2f91aaff3cd4c3172robertphillips            create_ngon(numPts, data.get(), width, height);
2167272935744670aebf82699c2f91aaff3cd4c3172robertphillips            points = data.get();
2177272935744670aebf82699c2f91aaff3cd4c3172robertphillips        }
2187272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2197272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkPath path;
2207272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2217272935744670aebf82699c2f91aaff3cd4c3172robertphillips        if (SkPath::kCW_Direction == dir) {
2227272935744670aebf82699c2f91aaff3cd4c3172robertphillips            path.moveTo(points[0]);
2237272935744670aebf82699c2f91aaff3cd4c3172robertphillips            for (int i = 1; i < numPts; ++i) {
2247272935744670aebf82699c2f91aaff3cd4c3172robertphillips                path.lineTo(points[i]);
2257272935744670aebf82699c2f91aaff3cd4c3172robertphillips            }
2267272935744670aebf82699c2f91aaff3cd4c3172robertphillips        } else {
2277272935744670aebf82699c2f91aaff3cd4c3172robertphillips            path.moveTo(points[numPts-1]);
2287272935744670aebf82699c2f91aaff3cd4c3172robertphillips            for (int i = numPts-2; i >= 0; --i) {
2297272935744670aebf82699c2f91aaff3cd4c3172robertphillips                path.lineTo(points[i]);
2307272935744670aebf82699c2f91aaff3cd4c3172robertphillips            }
2317272935744670aebf82699c2f91aaff3cd4c3172robertphillips        }
2327272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2337272935744670aebf82699c2f91aaff3cd4c3172robertphillips        path.close();
2347272935744670aebf82699c2f91aaff3cd4c3172robertphillips#ifdef SK_DEBUG
2357272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // Each path this method returns should be convex, only composed of
2367272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // lines, wound the right direction, and short enough to fit in one
2377272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // of the GMs rows.
2387272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkASSERT(path.isConvex());
2397272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkASSERT(SkPath::kLine_SegmentMask == path.getSegmentMasks());
2407272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkPath::Direction actualDir;
2417272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkASSERT(path.cheapComputeDirection(&actualDir));
2427272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkASSERT(dir == actualDir);
2437272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkRect bounds = path.getBounds();
2447272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkASSERT(SkScalarNearlyEqual(bounds.centerX(), 0.0f));
2457272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkASSERT(bounds.height() <= kMaxPathHeight);
2467272935744670aebf82699c2f91aaff3cd4c3172robertphillips#endif
2477272935744670aebf82699c2f91aaff3cd4c3172robertphillips        return path;
2487272935744670aebf82699c2f91aaff3cd4c3172robertphillips    }
2497272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2507272935744670aebf82699c2f91aaff3cd4c3172robertphillips    // Draw a single path several times, shrinking it, flipping its direction
2517272935744670aebf82699c2f91aaff3cd4c3172robertphillips    // and changing its start vertex each time.
2522a974625c559fcb2640b587fed6f92d5b58cab24robertphillips    void drawPath(SkCanvas* canvas, int index, SkPoint* offset) {
2537272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2547272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkPoint center;
2557272935744670aebf82699c2f91aaff3cd4c3172robertphillips        {
2567272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SkPath path = GetPath(index, 0, SkPath::kCW_Direction);
2572a974625c559fcb2640b587fed6f92d5b58cab24robertphillips            if (offset->fX+path.getBounds().width() > kGMWidth) {
2582a974625c559fcb2640b587fed6f92d5b58cab24robertphillips                offset->fX = 0;
2592a974625c559fcb2640b587fed6f92d5b58cab24robertphillips                offset->fY += kMaxPathHeight;
2607272935744670aebf82699c2f91aaff3cd4c3172robertphillips            }
2612a974625c559fcb2640b587fed6f92d5b58cab24robertphillips            center = { offset->fX + SkScalarHalf(path.getBounds().width()), offset->fY};
2622a974625c559fcb2640b587fed6f92d5b58cab24robertphillips            offset->fX += path.getBounds().width();
2637272935744670aebf82699c2f91aaff3cd4c3172robertphillips        }
2647272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2657272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkColor colors[2] = { SK_ColorBLACK, SK_ColorWHITE };
2667272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const SkPath::Direction dirs[2] = { SkPath::kCW_Direction, SkPath::kCCW_Direction };
2677272935744670aebf82699c2f91aaff3cd4c3172robertphillips        const float scales[] = { 1.0f, 0.75f, 0.5f, 0.25f, 0.1f, 0.01f, 0.001f };
2687272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2697272935744670aebf82699c2f91aaff3cd4c3172robertphillips        SkPaint paint;
2707272935744670aebf82699c2f91aaff3cd4c3172robertphillips        paint.setAntiAlias(true);
2717272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2727272935744670aebf82699c2f91aaff3cd4c3172robertphillips        for (size_t i = 0; i < SK_ARRAY_COUNT(scales); ++i) {
2737272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SkPath path = GetPath(index, (int) i, dirs[i%2]);
2747272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2757272935744670aebf82699c2f91aaff3cd4c3172robertphillips            canvas->save();
2767272935744670aebf82699c2f91aaff3cd4c3172robertphillips                canvas->translate(center.fX, center.fY);
2777272935744670aebf82699c2f91aaff3cd4c3172robertphillips                canvas->scale(scales[i], scales[i]);
2787272935744670aebf82699c2f91aaff3cd4c3172robertphillips                paint.setColor(colors[i%2]);
2797272935744670aebf82699c2f91aaff3cd4c3172robertphillips                canvas->drawPath(path, paint);
2807272935744670aebf82699c2f91aaff3cd4c3172robertphillips            canvas->restore();
2817272935744670aebf82699c2f91aaff3cd4c3172robertphillips        }
2827272935744670aebf82699c2f91aaff3cd4c3172robertphillips    }
2837272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2847272935744670aebf82699c2f91aaff3cd4c3172robertphillips    void onDraw(SkCanvas* canvas) override {
2852a974625c559fcb2640b587fed6f92d5b58cab24robertphillips        // the right edge of the last drawn path
2862a974625c559fcb2640b587fed6f92d5b58cab24robertphillips        SkPoint offset = { 0, SkScalarHalf(kMaxPathHeight) };
2872a974625c559fcb2640b587fed6f92d5b58cab24robertphillips
2887272935744670aebf82699c2f91aaff3cd4c3172robertphillips        for (int i = 0; i < kNumPaths; ++i) {
2892a974625c559fcb2640b587fed6f92d5b58cab24robertphillips            this->drawPath(canvas, i, &offset);
2907272935744670aebf82699c2f91aaff3cd4c3172robertphillips        }
2917272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2927272935744670aebf82699c2f91aaff3cd4c3172robertphillips        // Repro for crbug.com/472723 (Missing AA on portions of graphic with GPU rasterization)
2937272935744670aebf82699c2f91aaff3cd4c3172robertphillips        {
2947272935744670aebf82699c2f91aaff3cd4c3172robertphillips            canvas->translate(356.0f, 50.0f);
2957272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2967272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SkPaint p;
2977272935744670aebf82699c2f91aaff3cd4c3172robertphillips            p.setAntiAlias(true);
2987272935744670aebf82699c2f91aaff3cd4c3172robertphillips
2997272935744670aebf82699c2f91aaff3cd4c3172robertphillips            SkPath p1;
3007272935744670aebf82699c2f91aaff3cd4c3172robertphillips            p1.moveTo(60.8522949f, 364.671021f);
3017272935744670aebf82699c2f91aaff3cd4c3172robertphillips            p1.lineTo(59.4380493f, 364.671021f);
3027272935744670aebf82699c2f91aaff3cd4c3172robertphillips            p1.lineTo(385.414276f, 690.647217f);
3037272935744670aebf82699c2f91aaff3cd4c3172robertphillips            p1.lineTo(386.121399f, 689.940125f);
3047272935744670aebf82699c2f91aaff3cd4c3172robertphillips            canvas->drawPath(p1, p);
3057272935744670aebf82699c2f91aaff3cd4c3172robertphillips        }
3067272935744670aebf82699c2f91aaff3cd4c3172robertphillips    }
3077272935744670aebf82699c2f91aaff3cd4c3172robertphillips
3087272935744670aebf82699c2f91aaff3cd4c3172robertphillipsprivate:
3097272935744670aebf82699c2f91aaff3cd4c3172robertphillips    static const int kNumPaths      = 20;
3107272935744670aebf82699c2f91aaff3cd4c3172robertphillips    static const int kMaxPathHeight = 100;
3117272935744670aebf82699c2f91aaff3cd4c3172robertphillips    static const int kGMWidth       = 512;
3127272935744670aebf82699c2f91aaff3cd4c3172robertphillips    static const int kGMHeight      = 512;
3137272935744670aebf82699c2f91aaff3cd4c3172robertphillips
3147272935744670aebf82699c2f91aaff3cd4c3172robertphillips    typedef GM INHERITED;
3157272935744670aebf82699c2f91aaff3cd4c3172robertphillips};
3167272935744670aebf82699c2f91aaff3cd4c3172robertphillips
3177272935744670aebf82699c2f91aaff3cd4c3172robertphillips//////////////////////////////////////////////////////////////////////////////
3187272935744670aebf82699c2f91aaff3cd4c3172robertphillips
3197272935744670aebf82699c2f91aaff3cd4c3172robertphillipsDEF_GM( return SkNEW(ConvexLineOnlyPathsGM); )
3207272935744670aebf82699c2f91aaff3cd4c3172robertphillips
3217272935744670aebf82699c2f91aaff3cd4c3172robertphillips}
322