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" 9ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon#include "SkInsetConvexPolygon.h" 10026beb52a29a620290fcfb24f1e7e9e75547b80freed#include "SkPathPriv.h" 117272935744670aebf82699c2f91aaff3cd4c3172robertphillips 127272935744670aebf82699c2f91aaff3cd4c3172robertphillipsstatic void create_ngon(int n, SkPoint* pts, SkScalar width, SkScalar height) { 137272935744670aebf82699c2f91aaff3cd4c3172robertphillips float angleStep = 360.0f / n, angle = 0.0f, sin, cos; 147272935744670aebf82699c2f91aaff3cd4c3172robertphillips if ((n % 2) == 1) { 157272935744670aebf82699c2f91aaff3cd4c3172robertphillips angle = angleStep/2.0f; 167272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 177272935744670aebf82699c2f91aaff3cd4c3172robertphillips 187272935744670aebf82699c2f91aaff3cd4c3172robertphillips for (int i = 0; i < n; ++i) { 197272935744670aebf82699c2f91aaff3cd4c3172robertphillips sin = SkScalarSinCos(SkDegreesToRadians(angle), &cos); 207272935744670aebf82699c2f91aaff3cd4c3172robertphillips pts[i].fX = -sin * width; 217272935744670aebf82699c2f91aaff3cd4c3172robertphillips pts[i].fY = cos * height; 227272935744670aebf82699c2f91aaff3cd4c3172robertphillips angle += angleStep; 237272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 247272935744670aebf82699c2f91aaff3cd4c3172robertphillips} 257272935744670aebf82699c2f91aaff3cd4c3172robertphillips 26ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonnamespace ConvexLineOnlyData { 27ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// narrow rect 28ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints0[] = { 29ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -1.5f, -50.0f }, 30ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 1.5f, -50.0f }, 31ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 1.5f, 50.0f }, 32ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -1.5f, 50.0f } 33ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 34ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// narrow rect on an angle 35ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints1[] = { 36ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -50.0f, -49.0f }, 37ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -49.0f, -50.0f }, 38ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 50.0f, 49.0f }, 39ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 49.0f, 50.0f } 40ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 41ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// trap - narrow on top - wide on bottom 42ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints2[] = { 43ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -10.0f, -50.0f }, 44ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, -50.0f }, 45ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 50.0f, 50.0f }, 46ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -50.0f, 50.0f } 47ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 48ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// wide skewed rect 49ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints3[] = { 50ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -50.0f, -50.0f }, 51ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 0.0f, -50.0f }, 52ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 50.0f, 50.0f }, 53ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 0.0f, 50.0f } 54ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 55ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// thin rect with colinear-ish lines 56ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints4[] = { 57ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -6.0f, -50.0f }, 58ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 4.0f, -50.0f }, 59ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 5.0f, -25.0f }, 60ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 6.0f, 0.0f }, 61ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 5.0f, 25.0f }, 62ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 4.0f, 50.0f }, 63ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -4.0f, 50.0f } 64ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 65ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// degenerate 66ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints5[] = { 67ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -0.025f, -0.025f }, 68ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 0.025f, -0.025f }, 69ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 0.025f, 0.025f }, 70ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -0.025f, 0.025f } 71ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 72ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// Triangle in which the first point should fuse with last 73ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints6[] = { 74ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -20.0f, -13.0f }, 75ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -20.0f, -13.05f }, 76ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 20.0f, -13.0f }, 77ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 20.0f, 27.0f } 78ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 79ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// thin rect with colinear lines 80ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints7[] = { 81ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -10.0f, -50.0f }, 82ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, -50.0f }, 83ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, -25.0f }, 84ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, 0.0f }, 85ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, 25.0f }, 86ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, 50.0f }, 87ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -10.0f, 50.0f } 88ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 89ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// capped teardrop 90ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints8[] = { 91ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 50.00f, 50.00f }, 92ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 0.00f, 50.00f }, 93ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -15.45f, 47.55f }, 94ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -29.39f, 40.45f }, 95ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -40.45f, 29.39f }, 96ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -47.55f, 15.45f }, 97ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -50.00f, 0.00f }, 98ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -47.55f, -15.45f }, 99ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -40.45f, -29.39f }, 100ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -29.39f, -40.45f }, 101ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -15.45f, -47.55f }, 102ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 0.00f, -50.00f }, 103ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 50.00f, -50.00f } 104ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 105ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// teardrop 106ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints9[] = { 107ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 4.39f, 40.45f }, 108ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -9.55f, 47.55f }, 109ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -25.00f, 50.00f }, 110ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -40.45f, 47.55f }, 111ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -54.39f, 40.45f }, 112ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -65.45f, 29.39f }, 113ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -72.55f, 15.45f }, 114ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -75.00f, 0.00f }, 115ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -72.55f, -15.45f }, 116ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -65.45f, -29.39f }, 117ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -54.39f, -40.45f }, 118ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -40.45f, -47.55f }, 119ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -25.0f, -50.0f }, 120ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -9.55f, -47.55f }, 121ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 4.39f, -40.45f }, 122ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 75.00f, 0.00f } 123ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 124ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// clipped triangle 125ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint gPoints10[] = { 126ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -10.0f, -50.0f }, 127ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 10.0f, -50.0f }, 128ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 50.0f, 31.0f }, 129ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 40.0f, 50.0f }, 130ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -40.0f, 50.0f }, 131ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { -50.0f, 31.0f }, 132ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 133ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 134ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst SkPoint* gPoints[] = { 135ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon gPoints0, gPoints1, gPoints2, gPoints3, gPoints4, gPoints5, gPoints6, 136ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon gPoints7, gPoints8, gPoints9, gPoints10, 137ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 138ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 139ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonconst size_t gSizes[] = { 140ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints0), 141ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints1), 142ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints2), 143ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints3), 144ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints4), 145ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints5), 146ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints6), 147ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints7), 148ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints8), 149ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints9), 150ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SK_ARRAY_COUNT(gPoints10), 151ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 152ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonstatic_assert(SK_ARRAY_COUNT(gSizes) == SK_ARRAY_COUNT(gPoints), "array_mismatch"); 153ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon} 154ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 1557272935744670aebf82699c2f91aaff3cd4c3172robertphillipsnamespace skiagm { 1567272935744670aebf82699c2f91aaff3cd4c3172robertphillips 1577272935744670aebf82699c2f91aaff3cd4c3172robertphillips// This GM is intended to exercise Ganesh's handling of convex line-only 1587272935744670aebf82699c2f91aaff3cd4c3172robertphillips// paths 1597272935744670aebf82699c2f91aaff3cd4c3172robertphillipsclass ConvexLineOnlyPathsGM : public GM { 1607272935744670aebf82699c2f91aaff3cd4c3172robertphillipspublic: 161ad2344693c70f13d5e4216df8458b4d907395bderobertphillips ConvexLineOnlyPathsGM(bool doStrokeAndFill) : fDoStrokeAndFill(doStrokeAndFill) { 1627272935744670aebf82699c2f91aaff3cd4c3172robertphillips this->setBGColor(0xFFFFFFFF); 1637272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 1647272935744670aebf82699c2f91aaff3cd4c3172robertphillips 1657272935744670aebf82699c2f91aaff3cd4c3172robertphillipsprotected: 166ad2344693c70f13d5e4216df8458b4d907395bderobertphillips SkString onShortName() override { 167ad2344693c70f13d5e4216df8458b4d907395bderobertphillips if (fDoStrokeAndFill) { 168ad2344693c70f13d5e4216df8458b4d907395bderobertphillips return SkString("convex-lineonly-paths-stroke-and-fill"); 169ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 170ad2344693c70f13d5e4216df8458b4d907395bderobertphillips return SkString("convex-lineonly-paths"); 171ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 1727272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); } 1737272935744670aebf82699c2f91aaff3cd4c3172robertphillips bool runAsBench() const override { return true; } 1747272935744670aebf82699c2f91aaff3cd4c3172robertphillips 175ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon static SkPath GetPath(int index, SkPath::Direction dir) { 1767ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner std::unique_ptr<SkPoint[]> data(nullptr); 1777272935744670aebf82699c2f91aaff3cd4c3172robertphillips const SkPoint* points; 1787272935744670aebf82699c2f91aaff3cd4c3172robertphillips int numPts; 179ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (index < (int) SK_ARRAY_COUNT(ConvexLineOnlyData::gPoints)) { 1807272935744670aebf82699c2f91aaff3cd4c3172robertphillips // manually specified 181ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon points = ConvexLineOnlyData::gPoints[index]; 182ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon numPts = (int)ConvexLineOnlyData::gSizes[index]; 1837272935744670aebf82699c2f91aaff3cd4c3172robertphillips } else { 1847272935744670aebf82699c2f91aaff3cd4c3172robertphillips // procedurally generated 1857272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkScalar width = kMaxPathHeight/2; 1867272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkScalar height = kMaxPathHeight/2; 187ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon switch (index-SK_ARRAY_COUNT(ConvexLineOnlyData::gPoints)) { 1887272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 0: 1897272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 3; 1907272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 1917272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 1: 1927272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 4; 1937272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 1947272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 2: 1957272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 5; 1967272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 1977272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 3: // squashed pentagon 1987272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 5; 1997272935744670aebf82699c2f91aaff3cd4c3172robertphillips width = kMaxPathHeight/5; 2007272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2017272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 4: 2027272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 6; 2037272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2047272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 5: 2057272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 8; 2067272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2077272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 6: // squashed octogon 2087272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 8; 2097272935744670aebf82699c2f91aaff3cd4c3172robertphillips width = kMaxPathHeight/5; 2107272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2117272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 7: 2127272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 20; 2137272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2147272935744670aebf82699c2f91aaff3cd4c3172robertphillips case 8: 2157272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 100; 2167272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2177272935744670aebf82699c2f91aaff3cd4c3172robertphillips default: 2187272935744670aebf82699c2f91aaff3cd4c3172robertphillips numPts = 3; 2197272935744670aebf82699c2f91aaff3cd4c3172robertphillips break; 2207272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2217272935744670aebf82699c2f91aaff3cd4c3172robertphillips 222385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary data.reset(new SkPoint[numPts]); 2237272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2247272935744670aebf82699c2f91aaff3cd4c3172robertphillips create_ngon(numPts, data.get(), width, height); 2257272935744670aebf82699c2f91aaff3cd4c3172robertphillips points = data.get(); 2267272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2277272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2287272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkPath path; 2297272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2307272935744670aebf82699c2f91aaff3cd4c3172robertphillips if (SkPath::kCW_Direction == dir) { 2317272935744670aebf82699c2f91aaff3cd4c3172robertphillips path.moveTo(points[0]); 2327272935744670aebf82699c2f91aaff3cd4c3172robertphillips for (int i = 1; i < numPts; ++i) { 2337272935744670aebf82699c2f91aaff3cd4c3172robertphillips path.lineTo(points[i]); 2347272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2357272935744670aebf82699c2f91aaff3cd4c3172robertphillips } else { 2367272935744670aebf82699c2f91aaff3cd4c3172robertphillips path.moveTo(points[numPts-1]); 2377272935744670aebf82699c2f91aaff3cd4c3172robertphillips for (int i = numPts-2; i >= 0; --i) { 2387272935744670aebf82699c2f91aaff3cd4c3172robertphillips path.lineTo(points[i]); 2397272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2407272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2417272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2427272935744670aebf82699c2f91aaff3cd4c3172robertphillips path.close(); 2437272935744670aebf82699c2f91aaff3cd4c3172robertphillips#ifdef SK_DEBUG 2447272935744670aebf82699c2f91aaff3cd4c3172robertphillips // Each path this method returns should be convex, only composed of 2457272935744670aebf82699c2f91aaff3cd4c3172robertphillips // lines, wound the right direction, and short enough to fit in one 2467272935744670aebf82699c2f91aaff3cd4c3172robertphillips // of the GMs rows. 2477272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkASSERT(path.isConvex()); 2487272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkASSERT(SkPath::kLine_SegmentMask == path.getSegmentMasks()); 249026beb52a29a620290fcfb24f1e7e9e75547b80freed SkPathPriv::FirstDirection actualDir; 250026beb52a29a620290fcfb24f1e7e9e75547b80freed SkASSERT(SkPathPriv::CheapComputeFirstDirection(path, &actualDir)); 251026beb52a29a620290fcfb24f1e7e9e75547b80freed SkASSERT(SkPathPriv::AsFirstDirection(dir) == actualDir); 2527272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkRect bounds = path.getBounds(); 2537272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkASSERT(SkScalarNearlyEqual(bounds.centerX(), 0.0f)); 2547272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkASSERT(bounds.height() <= kMaxPathHeight); 2557272935744670aebf82699c2f91aaff3cd4c3172robertphillips#endif 2567272935744670aebf82699c2f91aaff3cd4c3172robertphillips return path; 2577272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2587272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2597272935744670aebf82699c2f91aaff3cd4c3172robertphillips // Draw a single path several times, shrinking it, flipping its direction 2607272935744670aebf82699c2f91aaff3cd4c3172robertphillips // and changing its start vertex each time. 2612a974625c559fcb2640b587fed6f92d5b58cab24robertphillips void drawPath(SkCanvas* canvas, int index, SkPoint* offset) { 2627272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2637272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkPoint center; 2647272935744670aebf82699c2f91aaff3cd4c3172robertphillips { 265ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPath path = GetPath(index, SkPath::kCW_Direction); 2662a974625c559fcb2640b587fed6f92d5b58cab24robertphillips if (offset->fX+path.getBounds().width() > kGMWidth) { 2672a974625c559fcb2640b587fed6f92d5b58cab24robertphillips offset->fX = 0; 2682a974625c559fcb2640b587fed6f92d5b58cab24robertphillips offset->fY += kMaxPathHeight; 269ad2344693c70f13d5e4216df8458b4d907395bderobertphillips if (fDoStrokeAndFill) { 270ad2344693c70f13d5e4216df8458b4d907395bderobertphillips offset->fX += kStrokeWidth / 2.0f; 271ad2344693c70f13d5e4216df8458b4d907395bderobertphillips offset->fY += kStrokeWidth / 2.0f; 272ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 2737272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2742a974625c559fcb2640b587fed6f92d5b58cab24robertphillips center = { offset->fX + SkScalarHalf(path.getBounds().width()), offset->fY}; 2752a974625c559fcb2640b587fed6f92d5b58cab24robertphillips offset->fX += path.getBounds().width(); 276ad2344693c70f13d5e4216df8458b4d907395bderobertphillips if (fDoStrokeAndFill) { 277ad2344693c70f13d5e4216df8458b4d907395bderobertphillips offset->fX += kStrokeWidth; 278ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 2797272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 2807272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2817272935744670aebf82699c2f91aaff3cd4c3172robertphillips const SkColor colors[2] = { SK_ColorBLACK, SK_ColorWHITE }; 2827272935744670aebf82699c2f91aaff3cd4c3172robertphillips const SkPath::Direction dirs[2] = { SkPath::kCW_Direction, SkPath::kCCW_Direction }; 2837272935744670aebf82699c2f91aaff3cd4c3172robertphillips const float scales[] = { 1.0f, 0.75f, 0.5f, 0.25f, 0.1f, 0.01f, 0.001f }; 284dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const SkPaint::Join joins[3] = { SkPaint::kRound_Join, 285ad2344693c70f13d5e4216df8458b4d907395bderobertphillips SkPaint::kBevel_Join, 286ad2344693c70f13d5e4216df8458b4d907395bderobertphillips SkPaint::kMiter_Join }; 2877272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2887272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkPaint paint; 2897272935744670aebf82699c2f91aaff3cd4c3172robertphillips paint.setAntiAlias(true); 2907272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2917272935744670aebf82699c2f91aaff3cd4c3172robertphillips for (size_t i = 0; i < SK_ARRAY_COUNT(scales); ++i) { 292ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPath path = GetPath(index, dirs[i%2]); 293ad2344693c70f13d5e4216df8458b4d907395bderobertphillips if (fDoStrokeAndFill) { 294ad2344693c70f13d5e4216df8458b4d907395bderobertphillips paint.setStyle(SkPaint::kStrokeAndFill_Style); 295ad2344693c70f13d5e4216df8458b4d907395bderobertphillips paint.setStrokeJoin(joins[i%3]); 296ad2344693c70f13d5e4216df8458b4d907395bderobertphillips paint.setStrokeWidth(SkIntToScalar(kStrokeWidth)); 297ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 2987272935744670aebf82699c2f91aaff3cd4c3172robertphillips 2997272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->save(); 3007272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->translate(center.fX, center.fY); 3017272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->scale(scales[i], scales[i]); 3027272935744670aebf82699c2f91aaff3cd4c3172robertphillips paint.setColor(colors[i%2]); 3037272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->drawPath(path, paint); 3047272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->restore(); 3057272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 3067272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 3077272935744670aebf82699c2f91aaff3cd4c3172robertphillips 3087272935744670aebf82699c2f91aaff3cd4c3172robertphillips void onDraw(SkCanvas* canvas) override { 3092a974625c559fcb2640b587fed6f92d5b58cab24robertphillips // the right edge of the last drawn path 3109d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary SkPoint offset = { 0, SkScalarHalf(kMaxPathHeight) }; 311ad2344693c70f13d5e4216df8458b4d907395bderobertphillips if (fDoStrokeAndFill) { 312ad2344693c70f13d5e4216df8458b4d907395bderobertphillips offset.fX += kStrokeWidth / 2.0f; 313ad2344693c70f13d5e4216df8458b4d907395bderobertphillips offset.fY += kStrokeWidth / 2.0f; 314ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 3152a974625c559fcb2640b587fed6f92d5b58cab24robertphillips 3167272935744670aebf82699c2f91aaff3cd4c3172robertphillips for (int i = 0; i < kNumPaths; ++i) { 3172a974625c559fcb2640b587fed6f92d5b58cab24robertphillips this->drawPath(canvas, i, &offset); 3187272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 3197272935744670aebf82699c2f91aaff3cd4c3172robertphillips 3207272935744670aebf82699c2f91aaff3cd4c3172robertphillips // Repro for crbug.com/472723 (Missing AA on portions of graphic with GPU rasterization) 3217272935744670aebf82699c2f91aaff3cd4c3172robertphillips { 3227272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->translate(356.0f, 50.0f); 3237272935744670aebf82699c2f91aaff3cd4c3172robertphillips 3247272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkPaint p; 3257272935744670aebf82699c2f91aaff3cd4c3172robertphillips p.setAntiAlias(true); 326ad2344693c70f13d5e4216df8458b4d907395bderobertphillips if (fDoStrokeAndFill) { 327ad2344693c70f13d5e4216df8458b4d907395bderobertphillips p.setStyle(SkPaint::kStrokeAndFill_Style); 328ad2344693c70f13d5e4216df8458b4d907395bderobertphillips p.setStrokeJoin(SkPaint::kMiter_Join); 329ad2344693c70f13d5e4216df8458b4d907395bderobertphillips p.setStrokeWidth(SkIntToScalar(kStrokeWidth)); 330ad2344693c70f13d5e4216df8458b4d907395bderobertphillips } 3317272935744670aebf82699c2f91aaff3cd4c3172robertphillips 3327272935744670aebf82699c2f91aaff3cd4c3172robertphillips SkPath p1; 3337272935744670aebf82699c2f91aaff3cd4c3172robertphillips p1.moveTo(60.8522949f, 364.671021f); 3347272935744670aebf82699c2f91aaff3cd4c3172robertphillips p1.lineTo(59.4380493f, 364.671021f); 3357272935744670aebf82699c2f91aaff3cd4c3172robertphillips p1.lineTo(385.414276f, 690.647217f); 3367272935744670aebf82699c2f91aaff3cd4c3172robertphillips p1.lineTo(386.121399f, 689.940125f); 3377272935744670aebf82699c2f91aaff3cd4c3172robertphillips canvas->drawPath(p1, p); 3387272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 3397272935744670aebf82699c2f91aaff3cd4c3172robertphillips } 3407272935744670aebf82699c2f91aaff3cd4c3172robertphillips 3417272935744670aebf82699c2f91aaff3cd4c3172robertphillipsprivate: 342dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kStrokeWidth = 10; 343dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kNumPaths = 20; 344dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kMaxPathHeight = 100; 345dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kGMWidth = 512; 346dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kGMHeight = 512; 3477272935744670aebf82699c2f91aaff3cd4c3172robertphillips 348ad2344693c70f13d5e4216df8458b4d907395bderobertphillips bool fDoStrokeAndFill; 349ad2344693c70f13d5e4216df8458b4d907395bderobertphillips 3507272935744670aebf82699c2f91aaff3cd4c3172robertphillips typedef GM INHERITED; 3517272935744670aebf82699c2f91aaff3cd4c3172robertphillips}; 3527272935744670aebf82699c2f91aaff3cd4c3172robertphillips 353ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon// This GM is intended to exercise the insetting of convex polygons 354ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonclass ConvexPolygonInsetGM : public GM { 355ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonpublic: 356ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon ConvexPolygonInsetGM() { 357ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon this->setBGColor(0xFFFFFFFF); 358ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 359ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 360ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonprotected: 361ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkString onShortName() override { 362ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon return SkString("convex-polygon-inset"); 363ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 364ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); } 365ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon bool runAsBench() const override { return true; } 366ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 367ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon static void GetPath(int index, SkPath::Direction dir, 368ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon std::unique_ptr<SkPoint[]>* data, int* numPts) { 369ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (index < (int)SK_ARRAY_COUNT(ConvexLineOnlyData::gPoints)) { 370ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // manually specified 371ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = (int)ConvexLineOnlyData::gSizes[index]; 372ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon data->reset(new SkPoint[*numPts]); 373ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (SkPath::kCW_Direction == dir) { 374ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 0; i < *numPts; ++i) { 375ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon (*data)[i] = ConvexLineOnlyData::gPoints[index][i]; 376ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 377ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } else { 378ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 0; i < *numPts; ++i) { 379ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon (*data)[i] = ConvexLineOnlyData::gPoints[index][*numPts - i - 1]; 380ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 381ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 382ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } else { 383ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // procedurally generated 384ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkScalar width = kMaxPathHeight / 2; 385ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkScalar height = kMaxPathHeight / 2; 386ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon switch (index - SK_ARRAY_COUNT(ConvexLineOnlyData::gPoints)) { 387ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 0: 388ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 3; 389ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 390ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 1: 391ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 4; 392ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 393ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 2: 394ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 5; 395ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 396ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 3: // squashed pentagon 397ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 5; 398ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon width = kMaxPathHeight / 5; 399ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 400ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 4: 401ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 6; 402ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 403ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 5: 404ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 8; 405ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 406ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 6: // squashed octogon 407ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 8; 408ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon width = kMaxPathHeight / 5; 409ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 410ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 7: 411ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 20; 412ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 413ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon case 8: 414ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 100; 415ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 416ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon default: 417ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon *numPts = 3; 418ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon break; 419ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 420ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 421ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon data->reset(new SkPoint[*numPts]); 422ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 423ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon create_ngon(*numPts, data->get(), width, height); 424ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (SkPath::kCCW_Direction == dir) { 425ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // reverse it 426ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 0; i < *numPts/2; ++i) { 427ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPoint tmp = (*data)[i]; 428ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon (*data)[i] = (*data)[*numPts - i - 1]; 429ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon (*data)[*numPts - i - 1] = tmp; 430ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 431ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 432ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 433ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 434ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 435ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // Draw a single path several times, shrinking it, flipping its direction 436ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // and changing its start vertex each time. 437ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon void drawPath(SkCanvas* canvas, int index, SkPoint* offset) { 438ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 439ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPoint center; 440ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 441ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon std::unique_ptr<SkPoint[]> data(nullptr); 442ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon int numPts; 443ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon GetPath(index, SkPath::kCW_Direction, &data, &numPts); 444ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkRect bounds; 445ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon bounds.set(data.get(), numPts); 446ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (offset->fX + bounds.width() > kGMWidth) { 447ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon offset->fX = 0; 448ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon offset->fY += kMaxPathHeight; 449ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 450ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon center = { offset->fX + SkScalarHalf(bounds.width()), offset->fY }; 451ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon offset->fX += bounds.width(); 452ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 453ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 454ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon const SkPath::Direction dirs[2] = { SkPath::kCW_Direction, SkPath::kCCW_Direction }; 455ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon const float insets[] = { 5, 10, 15, 20, 25, 30, 35, 40 }; 456ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon const SkColor colors[] = { 0xFF901313, 0xFF8D6214, 0xFF698B14, 0xFF1C8914, 457ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 0xFF148755, 0xFF146C84, 0xFF142482, 0xFF4A1480 }; 458ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 459ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPaint paint; 460ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon paint.setAntiAlias(true); 461ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon paint.setStyle(SkPaint::kStroke_Style); 462ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon paint.setStrokeWidth(1); 463ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 464ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon std::unique_ptr<SkPoint[]> data(nullptr); 465ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon int numPts; 466ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon GetPath(index, dirs[index % 2], &data, &numPts); 467ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon { 468ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPath path; 469ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon path.moveTo(data.get()[0]); 470ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 1; i < numPts; ++i) { 471ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon path.lineTo(data.get()[i]); 472ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 473ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon path.close(); 474ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->save(); 475ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->translate(center.fX, center.fY); 476ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->drawPath(path, paint); 477ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->restore(); 478ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 479ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 480ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkTDArray<SkPoint> insetPoly; 481ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (size_t i = 0; i < SK_ARRAY_COUNT(insets); ++i) { 482ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon if (SkInsetConvexPolygon(data.get(), numPts, insets[i], &insetPoly)) { 483ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPath path; 484ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon path.moveTo(insetPoly[0]); 485ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 1; i < insetPoly.count(); ++i) { 486ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon path.lineTo(insetPoly[i]); 487ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 488ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon path.close(); 489ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 490ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon paint.setColor(colors[i]); 491ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->save(); 492ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->translate(center.fX, center.fY); 493ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->drawPath(path, paint); 494ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon canvas->restore(); 495ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 496ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 497ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 498ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 499ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon void onDraw(SkCanvas* canvas) override { 500ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon // the right edge of the last drawn path 501ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon SkPoint offset = { 0, SkScalarHalf(kMaxPathHeight) }; 502ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 503ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon for (int i = 0; i < kNumPaths; ++i) { 504ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon this->drawPath(canvas, i, &offset); 505ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 506ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon } 507ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 508ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomonprivate: 509ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon static constexpr int kNumPaths = 20; 510ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon static constexpr int kMaxPathHeight = 100; 511ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon static constexpr int kGMWidth = 512; 512ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon static constexpr int kGMHeight = 512; 513ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 514ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon typedef GM INHERITED; 515ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon}; 516ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian Salomon 5177272935744670aebf82699c2f91aaff3cd4c3172robertphillips////////////////////////////////////////////////////////////////////////////// 5187272935744670aebf82699c2f91aaff3cd4c3172robertphillips 519ad2344693c70f13d5e4216df8458b4d907395bderobertphillipsDEF_GM(return new ConvexLineOnlyPathsGM(false);) 520ad2344693c70f13d5e4216df8458b4d907395bderobertphillipsDEF_GM(return new ConvexLineOnlyPathsGM(true);) 521ab664fa5b5fb96dd1079c090534330ca7e8a10efBrian SalomonDEF_GM(return new ConvexPolygonInsetGM();) 5227272935744670aebf82699c2f91aaff3cd4c3172robertphillips} 523