1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "gm/gm.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 12cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 13cb93a386Sopenharmony_ci#include "include/core/SkPoint.h" 14cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 15cb93a386Sopenharmony_ci#include "include/core/SkScalar.h" 16cb93a386Sopenharmony_ci#include "include/core/SkSize.h" 17cb93a386Sopenharmony_ci#include "include/core/SkString.h" 18cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 19cb93a386Sopenharmony_ci#include "include/private/SkTDArray.h" 20cb93a386Sopenharmony_ci#include "src/utils/SkPolyUtils.h" 21cb93a386Sopenharmony_ci#include "tools/ToolUtils.h" 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci#include <functional> 24cb93a386Sopenharmony_ci#include <memory> 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_cistatic void create_ngon(int n, SkPoint* pts, SkScalar w, SkScalar h, SkPathDirection dir) { 27cb93a386Sopenharmony_ci float angleStep = 360.0f / n, angle = 0.0f; 28cb93a386Sopenharmony_ci if ((n % 2) == 1) { 29cb93a386Sopenharmony_ci angle = angleStep/2.0f; 30cb93a386Sopenharmony_ci } 31cb93a386Sopenharmony_ci if (SkPathDirection::kCCW == dir) { 32cb93a386Sopenharmony_ci angle = -angle; 33cb93a386Sopenharmony_ci angleStep = -angleStep; 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci for (int i = 0; i < n; ++i) { 37cb93a386Sopenharmony_ci pts[i].fX = -SkScalarSin(SkDegreesToRadians(angle)) * w; 38cb93a386Sopenharmony_ci pts[i].fY = SkScalarCos(SkDegreesToRadians(angle)) * h; 39cb93a386Sopenharmony_ci angle += angleStep; 40cb93a386Sopenharmony_ci } 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_cinamespace PolygonOffsetData { 44cb93a386Sopenharmony_ci// narrow rect 45cb93a386Sopenharmony_ciconst SkPoint gPoints0[] = { 46cb93a386Sopenharmony_ci { -1.5f, -50.0f }, 47cb93a386Sopenharmony_ci { 1.5f, -50.0f }, 48cb93a386Sopenharmony_ci { 1.5f, 50.0f }, 49cb93a386Sopenharmony_ci { -1.5f, 50.0f } 50cb93a386Sopenharmony_ci}; 51cb93a386Sopenharmony_ci// narrow rect on an angle 52cb93a386Sopenharmony_ciconst SkPoint gPoints1[] = { 53cb93a386Sopenharmony_ci { -50.0f, -49.0f }, 54cb93a386Sopenharmony_ci { -49.0f, -50.0f }, 55cb93a386Sopenharmony_ci { 50.0f, 49.0f }, 56cb93a386Sopenharmony_ci { 49.0f, 50.0f } 57cb93a386Sopenharmony_ci}; 58cb93a386Sopenharmony_ci// trap - narrow on top - wide on bottom 59cb93a386Sopenharmony_ciconst SkPoint gPoints2[] = { 60cb93a386Sopenharmony_ci { -10.0f, -50.0f }, 61cb93a386Sopenharmony_ci { 10.0f, -50.0f }, 62cb93a386Sopenharmony_ci { 50.0f, 50.0f }, 63cb93a386Sopenharmony_ci { -50.0f, 50.0f } 64cb93a386Sopenharmony_ci}; 65cb93a386Sopenharmony_ci// wide skewed rect 66cb93a386Sopenharmony_ciconst SkPoint gPoints3[] = { 67cb93a386Sopenharmony_ci { -50.0f, -50.0f }, 68cb93a386Sopenharmony_ci { 0.0f, -50.0f }, 69cb93a386Sopenharmony_ci { 50.0f, 50.0f }, 70cb93a386Sopenharmony_ci { 0.0f, 50.0f } 71cb93a386Sopenharmony_ci}; 72cb93a386Sopenharmony_ci// thin rect with colinear-ish lines 73cb93a386Sopenharmony_ciconst SkPoint gPoints4[] = { 74cb93a386Sopenharmony_ci { -6.0f, -50.0f }, 75cb93a386Sopenharmony_ci { 4.0f, -50.0f }, 76cb93a386Sopenharmony_ci { 5.0f, -25.0f }, 77cb93a386Sopenharmony_ci { 6.0f, 0.0f }, 78cb93a386Sopenharmony_ci { 5.0f, 25.0f }, 79cb93a386Sopenharmony_ci { 4.0f, 50.0f }, 80cb93a386Sopenharmony_ci { -4.0f, 50.0f } 81cb93a386Sopenharmony_ci}; 82cb93a386Sopenharmony_ci// degenerate 83cb93a386Sopenharmony_ciconst SkPoint gPoints5[] = { 84cb93a386Sopenharmony_ci { -0.025f, -0.025f }, 85cb93a386Sopenharmony_ci { 0.025f, -0.025f }, 86cb93a386Sopenharmony_ci { 0.025f, 0.025f }, 87cb93a386Sopenharmony_ci { -0.025f, 0.025f } 88cb93a386Sopenharmony_ci}; 89cb93a386Sopenharmony_ci// Quad with near coincident point 90cb93a386Sopenharmony_ciconst SkPoint gPoints6[] = { 91cb93a386Sopenharmony_ci { -20.0f, -13.0f }, 92cb93a386Sopenharmony_ci { -20.0f, -13.05f }, 93cb93a386Sopenharmony_ci { 20.0f, -13.0f }, 94cb93a386Sopenharmony_ci { 20.0f, 27.0f } 95cb93a386Sopenharmony_ci}; 96cb93a386Sopenharmony_ci// thin rect with colinear lines 97cb93a386Sopenharmony_ciconst SkPoint gPoints7[] = { 98cb93a386Sopenharmony_ci { -10.0f, -50.0f }, 99cb93a386Sopenharmony_ci { 10.0f, -50.0f }, 100cb93a386Sopenharmony_ci { 10.0f, -20.0f }, 101cb93a386Sopenharmony_ci { 10.0f, 0.0f }, 102cb93a386Sopenharmony_ci { 10.0f, 35.0f }, 103cb93a386Sopenharmony_ci { 10.0f, 50.0f }, 104cb93a386Sopenharmony_ci { -10.0f, 50.0f } 105cb93a386Sopenharmony_ci}; 106cb93a386Sopenharmony_ci// capped teardrop 107cb93a386Sopenharmony_ciconst SkPoint gPoints8[] = { 108cb93a386Sopenharmony_ci { 50.00f, 50.00f }, 109cb93a386Sopenharmony_ci { 0.00f, 50.00f }, 110cb93a386Sopenharmony_ci { -15.45f, 47.55f }, 111cb93a386Sopenharmony_ci { -29.39f, 40.45f }, 112cb93a386Sopenharmony_ci { -40.45f, 29.39f }, 113cb93a386Sopenharmony_ci { -47.55f, 15.45f }, 114cb93a386Sopenharmony_ci { -50.00f, 0.00f }, 115cb93a386Sopenharmony_ci { -47.55f, -15.45f }, 116cb93a386Sopenharmony_ci { -40.45f, -29.39f }, 117cb93a386Sopenharmony_ci { -29.39f, -40.45f }, 118cb93a386Sopenharmony_ci { -15.45f, -47.55f }, 119cb93a386Sopenharmony_ci { 0.00f, -50.00f }, 120cb93a386Sopenharmony_ci { 50.00f, -50.00f } 121cb93a386Sopenharmony_ci}; 122cb93a386Sopenharmony_ci// teardrop 123cb93a386Sopenharmony_ciconst SkPoint gPoints9[] = { 124cb93a386Sopenharmony_ci { 4.39f, 40.45f }, 125cb93a386Sopenharmony_ci { -9.55f, 47.55f }, 126cb93a386Sopenharmony_ci { -25.00f, 50.00f }, 127cb93a386Sopenharmony_ci { -40.45f, 47.55f }, 128cb93a386Sopenharmony_ci { -54.39f, 40.45f }, 129cb93a386Sopenharmony_ci { -65.45f, 29.39f }, 130cb93a386Sopenharmony_ci { -72.55f, 15.45f }, 131cb93a386Sopenharmony_ci { -75.00f, 0.00f }, 132cb93a386Sopenharmony_ci { -72.55f, -15.45f }, 133cb93a386Sopenharmony_ci { -65.45f, -29.39f }, 134cb93a386Sopenharmony_ci { -54.39f, -40.45f }, 135cb93a386Sopenharmony_ci { -40.45f, -47.55f }, 136cb93a386Sopenharmony_ci { -25.0f, -50.0f }, 137cb93a386Sopenharmony_ci { -9.55f, -47.55f }, 138cb93a386Sopenharmony_ci { 4.39f, -40.45f }, 139cb93a386Sopenharmony_ci { 75.00f, 0.00f } 140cb93a386Sopenharmony_ci}; 141cb93a386Sopenharmony_ci// clipped triangle 142cb93a386Sopenharmony_ciconst SkPoint gPoints10[] = { 143cb93a386Sopenharmony_ci { -10.0f, -50.0f }, 144cb93a386Sopenharmony_ci { 10.0f, -50.0f }, 145cb93a386Sopenharmony_ci { 50.0f, 31.0f }, 146cb93a386Sopenharmony_ci { 40.0f, 50.0f }, 147cb93a386Sopenharmony_ci { -40.0f, 50.0f }, 148cb93a386Sopenharmony_ci { -50.0f, 31.0f }, 149cb93a386Sopenharmony_ci}; 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci// tab 152cb93a386Sopenharmony_ciconst SkPoint gPoints11[] = { 153cb93a386Sopenharmony_ci { -45, -25 }, 154cb93a386Sopenharmony_ci { 45, -25 }, 155cb93a386Sopenharmony_ci { 45, 25 }, 156cb93a386Sopenharmony_ci { 20, 25 }, 157cb93a386Sopenharmony_ci { 19.6157f, 25.f + 3.9018f }, 158cb93a386Sopenharmony_ci { 18.4776f, 25.f + 7.6537f }, 159cb93a386Sopenharmony_ci { 16.6294f, 25.f + 11.1114f }, 160cb93a386Sopenharmony_ci { 14.1421f, 25.f + 14.1421f }, 161cb93a386Sopenharmony_ci { 11.1114f, 25.f + 16.6294f }, 162cb93a386Sopenharmony_ci { 7.6537f, 25.f + 18.4776f }, 163cb93a386Sopenharmony_ci { 3.9018f, 25.f + 19.6157f }, 164cb93a386Sopenharmony_ci { 0, 45.f }, 165cb93a386Sopenharmony_ci { -3.9018f, 25.f + 19.6157f }, 166cb93a386Sopenharmony_ci { -7.6537f, 25.f + 18.4776f }, 167cb93a386Sopenharmony_ci { -11.1114f, 25.f + 16.6294f }, 168cb93a386Sopenharmony_ci { -14.1421f, 25.f + 14.1421f }, 169cb93a386Sopenharmony_ci { -16.6294f, 25.f + 11.1114f }, 170cb93a386Sopenharmony_ci { -18.4776f, 25.f + 7.6537f }, 171cb93a386Sopenharmony_ci { -19.6157f, 25.f + 3.9018f }, 172cb93a386Sopenharmony_ci { -20, 25 }, 173cb93a386Sopenharmony_ci { -45, 25 } 174cb93a386Sopenharmony_ci}; 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_ci// star of david 177cb93a386Sopenharmony_ciconst SkPoint gPoints12[] = { 178cb93a386Sopenharmony_ci { 0.0f, -50.0f }, 179cb93a386Sopenharmony_ci { 14.43f, -25.0f }, 180cb93a386Sopenharmony_ci { 43.30f, -25.0f }, 181cb93a386Sopenharmony_ci { 28.86f, 0.0f }, 182cb93a386Sopenharmony_ci { 43.30f, 25.0f }, 183cb93a386Sopenharmony_ci { 14.43f, 25.0f }, 184cb93a386Sopenharmony_ci { 0.0f, 50.0f }, 185cb93a386Sopenharmony_ci { -14.43f, 25.0f }, 186cb93a386Sopenharmony_ci { -43.30f, 25.0f }, 187cb93a386Sopenharmony_ci { -28.86f, 0.0f }, 188cb93a386Sopenharmony_ci { -43.30f, -25.0f }, 189cb93a386Sopenharmony_ci { -14.43f, -25.0f }, 190cb93a386Sopenharmony_ci}; 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_ci// notch 193cb93a386Sopenharmony_ciconst SkScalar kBottom = 25.f; 194cb93a386Sopenharmony_ciconst SkPoint gPoints13[] = { 195cb93a386Sopenharmony_ci { -50, kBottom - 50.f }, 196cb93a386Sopenharmony_ci { 50, kBottom - 50.f }, 197cb93a386Sopenharmony_ci { 50, kBottom }, 198cb93a386Sopenharmony_ci { 20, kBottom }, 199cb93a386Sopenharmony_ci { 19.6157f, kBottom - 3.9018f }, 200cb93a386Sopenharmony_ci { 18.4776f, kBottom - 7.6537f }, 201cb93a386Sopenharmony_ci { 16.6294f, kBottom - 11.1114f }, 202cb93a386Sopenharmony_ci { 14.1421f, kBottom - 14.1421f }, 203cb93a386Sopenharmony_ci { 11.1114f, kBottom - 16.6294f }, 204cb93a386Sopenharmony_ci { 7.6537f, kBottom - 18.4776f }, 205cb93a386Sopenharmony_ci { 3.9018f, kBottom - 19.6157f }, 206cb93a386Sopenharmony_ci { 0, kBottom - 20.f }, 207cb93a386Sopenharmony_ci { -3.9018f, kBottom - 19.6157f }, 208cb93a386Sopenharmony_ci { -7.6537f, kBottom - 18.4776f }, 209cb93a386Sopenharmony_ci { -11.1114f, kBottom - 16.6294f }, 210cb93a386Sopenharmony_ci { -14.1421f, kBottom - 14.1421f }, 211cb93a386Sopenharmony_ci { -16.6294f, kBottom - 11.1114f }, 212cb93a386Sopenharmony_ci { -18.4776f, kBottom - 7.6537f }, 213cb93a386Sopenharmony_ci { -19.6157f, kBottom - 3.9018f }, 214cb93a386Sopenharmony_ci { -20, kBottom }, 215cb93a386Sopenharmony_ci { -50, kBottom } 216cb93a386Sopenharmony_ci}; 217cb93a386Sopenharmony_ci 218cb93a386Sopenharmony_ci// crown 219cb93a386Sopenharmony_ciconst SkPoint gPoints14[] = { 220cb93a386Sopenharmony_ci { -40, -39 }, 221cb93a386Sopenharmony_ci { 40, -39 }, 222cb93a386Sopenharmony_ci { 40, -20 }, 223cb93a386Sopenharmony_ci { 30, 40 }, 224cb93a386Sopenharmony_ci { 20, -20 }, 225cb93a386Sopenharmony_ci { 10, 40 }, 226cb93a386Sopenharmony_ci { 0, -20 }, 227cb93a386Sopenharmony_ci { -10, 40 }, 228cb93a386Sopenharmony_ci { -20, -20 }, 229cb93a386Sopenharmony_ci { -30, 40 }, 230cb93a386Sopenharmony_ci { -40, -20 } 231cb93a386Sopenharmony_ci}; 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_ci// dumbbell 234cb93a386Sopenharmony_ciconst SkPoint gPoints15[] = { 235cb93a386Sopenharmony_ci { -26, -3 }, 236cb93a386Sopenharmony_ci { -24, -6.2f }, 237cb93a386Sopenharmony_ci { -22.5f, -8 }, 238cb93a386Sopenharmony_ci { -20, -9.9f }, 239cb93a386Sopenharmony_ci { -17.5f, -10.3f }, 240cb93a386Sopenharmony_ci { -15, -10.9f }, 241cb93a386Sopenharmony_ci { -12.5f, -10.2f }, 242cb93a386Sopenharmony_ci { -10, -9.7f }, 243cb93a386Sopenharmony_ci { -7.5f, -8.1f }, 244cb93a386Sopenharmony_ci { -5, -7.7f }, 245cb93a386Sopenharmony_ci { -2.5f, -7.4f }, 246cb93a386Sopenharmony_ci { 0, -7.7f }, 247cb93a386Sopenharmony_ci { 3, -9 }, 248cb93a386Sopenharmony_ci { 6.5f, -11.5f }, 249cb93a386Sopenharmony_ci { 10.6f, -14 }, 250cb93a386Sopenharmony_ci { 14, -15.2f }, 251cb93a386Sopenharmony_ci { 17, -15.5f }, 252cb93a386Sopenharmony_ci { 20, -15.2f }, 253cb93a386Sopenharmony_ci { 23.4f, -14 }, 254cb93a386Sopenharmony_ci { 27.5f, -11.5f }, 255cb93a386Sopenharmony_ci { 30, -8 }, 256cb93a386Sopenharmony_ci { 32, -4 }, 257cb93a386Sopenharmony_ci { 32.5f, 0 }, 258cb93a386Sopenharmony_ci { 32, 4 }, 259cb93a386Sopenharmony_ci { 30, 8 }, 260cb93a386Sopenharmony_ci { 27.5f, 11.5f }, 261cb93a386Sopenharmony_ci { 23.4f, 14 }, 262cb93a386Sopenharmony_ci { 20, 15.2f }, 263cb93a386Sopenharmony_ci { 17, 15.5f }, 264cb93a386Sopenharmony_ci { 14, 15.2f }, 265cb93a386Sopenharmony_ci { 10.6f, 14 }, 266cb93a386Sopenharmony_ci { 6.5f, 11.5f }, 267cb93a386Sopenharmony_ci { 3, 9 }, 268cb93a386Sopenharmony_ci { 0, 7.7f }, 269cb93a386Sopenharmony_ci { -2.5f, 7.4f }, 270cb93a386Sopenharmony_ci { -5, 7.7f }, 271cb93a386Sopenharmony_ci { -7.5f, 8.1f }, 272cb93a386Sopenharmony_ci { -10, 9.7f }, 273cb93a386Sopenharmony_ci { -12.5f, 10.2f }, 274cb93a386Sopenharmony_ci { -15, 10.9f }, 275cb93a386Sopenharmony_ci { -17.5f, 10.3f }, 276cb93a386Sopenharmony_ci { -20, 9.9f }, 277cb93a386Sopenharmony_ci { -22.5f, 8 }, 278cb93a386Sopenharmony_ci { -24, 6.2f }, 279cb93a386Sopenharmony_ci { -26, 3 }, 280cb93a386Sopenharmony_ci { -26.5f, 0 } 281cb93a386Sopenharmony_ci}; 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci// truncated dumbbell 284cb93a386Sopenharmony_ci// (checks winding computation in OffsetSimplePolygon) 285cb93a386Sopenharmony_ciconst SkPoint gPoints16[] = { 286cb93a386Sopenharmony_ci { -15 + 3, -9 }, 287cb93a386Sopenharmony_ci { -15 + 6.5f, -11.5f }, 288cb93a386Sopenharmony_ci { -15 + 10.6f, -14 }, 289cb93a386Sopenharmony_ci { -15 + 14, -15.2f }, 290cb93a386Sopenharmony_ci { -15 + 17, -15.5f }, 291cb93a386Sopenharmony_ci { -15 + 20, -15.2f }, 292cb93a386Sopenharmony_ci { -15 + 23.4f, -14 }, 293cb93a386Sopenharmony_ci { -15 + 27.5f, -11.5f }, 294cb93a386Sopenharmony_ci { -15 + 30, -8 }, 295cb93a386Sopenharmony_ci { -15 + 32, -4 }, 296cb93a386Sopenharmony_ci { -15 + 32.5f, 0 }, 297cb93a386Sopenharmony_ci { -15 + 32, 4 }, 298cb93a386Sopenharmony_ci { -15 + 30, 8 }, 299cb93a386Sopenharmony_ci { -15 + 27.5f, 11.5f }, 300cb93a386Sopenharmony_ci { -15 + 23.4f, 14 }, 301cb93a386Sopenharmony_ci { -15 + 20, 15.2f }, 302cb93a386Sopenharmony_ci { -15 + 17, 15.5f }, 303cb93a386Sopenharmony_ci { -15 + 14, 15.2f }, 304cb93a386Sopenharmony_ci { -15 + 10.6f, 14 }, 305cb93a386Sopenharmony_ci { -15 + 6.5f, 11.5f }, 306cb93a386Sopenharmony_ci { -15 + 3, 9 }, 307cb93a386Sopenharmony_ci}; 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci// square notch 310cb93a386Sopenharmony_ci// (to detect segment-segment intersection) 311cb93a386Sopenharmony_ciconst SkPoint gPoints17[] = { 312cb93a386Sopenharmony_ci { -50, kBottom - 50.f }, 313cb93a386Sopenharmony_ci { 50, kBottom - 50.f }, 314cb93a386Sopenharmony_ci { 50, kBottom }, 315cb93a386Sopenharmony_ci { 20, kBottom }, 316cb93a386Sopenharmony_ci { 20, kBottom - 20.f }, 317cb93a386Sopenharmony_ci { -20, kBottom - 20.f }, 318cb93a386Sopenharmony_ci { -20, kBottom }, 319cb93a386Sopenharmony_ci { -50, kBottom } 320cb93a386Sopenharmony_ci}; 321cb93a386Sopenharmony_ci 322cb93a386Sopenharmony_ci// box with Peano curve 323cb93a386Sopenharmony_ciconst SkPoint gPoints18[] = { 324cb93a386Sopenharmony_ci { 0, 0 }, 325cb93a386Sopenharmony_ci { 0, -12 }, 326cb93a386Sopenharmony_ci { -6, -12 }, 327cb93a386Sopenharmony_ci { -6, 0 }, 328cb93a386Sopenharmony_ci { -12, 0 }, 329cb93a386Sopenharmony_ci { -12, -12}, 330cb93a386Sopenharmony_ci { -18, -12}, 331cb93a386Sopenharmony_ci { -18, 18}, 332cb93a386Sopenharmony_ci { -12, 18}, 333cb93a386Sopenharmony_ci {-12, 6}, 334cb93a386Sopenharmony_ci {-6, 6}, 335cb93a386Sopenharmony_ci {-6, 36}, 336cb93a386Sopenharmony_ci {-12, 36}, 337cb93a386Sopenharmony_ci {-12, 24}, 338cb93a386Sopenharmony_ci {-18, 24}, 339cb93a386Sopenharmony_ci {-18, 36}, 340cb93a386Sopenharmony_ci {-24, 36}, 341cb93a386Sopenharmony_ci {-24, 24}, 342cb93a386Sopenharmony_ci {-30, 24}, 343cb93a386Sopenharmony_ci {-30, 36}, 344cb93a386Sopenharmony_ci {-36, 36}, 345cb93a386Sopenharmony_ci {-36, 6}, 346cb93a386Sopenharmony_ci {-30, 6}, 347cb93a386Sopenharmony_ci {-30, 18}, 348cb93a386Sopenharmony_ci {-24, 18}, 349cb93a386Sopenharmony_ci {-24, -12}, 350cb93a386Sopenharmony_ci {-30, -12}, 351cb93a386Sopenharmony_ci {-30, 0}, 352cb93a386Sopenharmony_ci {-36, 0}, 353cb93a386Sopenharmony_ci {-36, -36}, 354cb93a386Sopenharmony_ci {36, -36}, 355cb93a386Sopenharmony_ci {36, 36}, 356cb93a386Sopenharmony_ci {12, 36}, 357cb93a386Sopenharmony_ci {12, 24}, 358cb93a386Sopenharmony_ci {6, 24}, 359cb93a386Sopenharmony_ci {6, 36}, 360cb93a386Sopenharmony_ci {0, 36}, 361cb93a386Sopenharmony_ci {0, 6}, 362cb93a386Sopenharmony_ci {6, 6}, 363cb93a386Sopenharmony_ci {6, 18}, 364cb93a386Sopenharmony_ci {12, 18}, 365cb93a386Sopenharmony_ci {12, -12}, 366cb93a386Sopenharmony_ci {6, -12}, 367cb93a386Sopenharmony_ci {6, 0} 368cb93a386Sopenharmony_ci}; 369cb93a386Sopenharmony_ci 370cb93a386Sopenharmony_ci 371cb93a386Sopenharmony_ciconst SkPoint* gConvexPoints[] = { 372cb93a386Sopenharmony_ci gPoints0, gPoints1, gPoints2, gPoints3, gPoints4, gPoints5, gPoints6, 373cb93a386Sopenharmony_ci gPoints7, gPoints8, gPoints9, gPoints10, 374cb93a386Sopenharmony_ci}; 375cb93a386Sopenharmony_ci 376cb93a386Sopenharmony_ciconst size_t gConvexSizes[] = { 377cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints0), 378cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints1), 379cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints2), 380cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints3), 381cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints4), 382cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints5), 383cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints6), 384cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints7), 385cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints8), 386cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints9), 387cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints10), 388cb93a386Sopenharmony_ci}; 389cb93a386Sopenharmony_cistatic_assert(SK_ARRAY_COUNT(gConvexSizes) == SK_ARRAY_COUNT(gConvexPoints), "array_mismatch"); 390cb93a386Sopenharmony_ci 391cb93a386Sopenharmony_ciconst SkPoint* gSimplePoints[] = { 392cb93a386Sopenharmony_ci gPoints0, gPoints1, gPoints2, gPoints4, gPoints5, gPoints7, 393cb93a386Sopenharmony_ci gPoints8, gPoints11, gPoints12, gPoints13, gPoints14, gPoints15, 394cb93a386Sopenharmony_ci gPoints16, gPoints17, gPoints18, 395cb93a386Sopenharmony_ci}; 396cb93a386Sopenharmony_ci 397cb93a386Sopenharmony_ciconst size_t gSimpleSizes[] = { 398cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints0), 399cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints1), 400cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints2), 401cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints4), 402cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints5), 403cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints7), 404cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints8), 405cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints11), 406cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints12), 407cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints13), 408cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints14), 409cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints15), 410cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints16), 411cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints17), 412cb93a386Sopenharmony_ci SK_ARRAY_COUNT(gPoints18), 413cb93a386Sopenharmony_ci}; 414cb93a386Sopenharmony_cistatic_assert(SK_ARRAY_COUNT(gSimpleSizes) == SK_ARRAY_COUNT(gSimplePoints), "array_mismatch"); 415cb93a386Sopenharmony_ci 416cb93a386Sopenharmony_ci} // namespace PolygonOffsetData 417cb93a386Sopenharmony_ci 418cb93a386Sopenharmony_cinamespace skiagm { 419cb93a386Sopenharmony_ci 420cb93a386Sopenharmony_ci// This GM is intended to exercise the offsetting of polygons 421cb93a386Sopenharmony_ci// When fVariableOffset is true it will skew the offset by x, 422cb93a386Sopenharmony_ci// to test perspective and other variable offset functions 423cb93a386Sopenharmony_ciclass PolygonOffsetGM : public GM { 424cb93a386Sopenharmony_cipublic: 425cb93a386Sopenharmony_ci PolygonOffsetGM(bool convexOnly) 426cb93a386Sopenharmony_ci : fConvexOnly(convexOnly) { 427cb93a386Sopenharmony_ci this->setBGColor(0xFFFFFFFF); 428cb93a386Sopenharmony_ci } 429cb93a386Sopenharmony_ci 430cb93a386Sopenharmony_ciprotected: 431cb93a386Sopenharmony_ci SkString onShortName() override { 432cb93a386Sopenharmony_ci if (fConvexOnly) { 433cb93a386Sopenharmony_ci return SkString("convex-polygon-inset"); 434cb93a386Sopenharmony_ci } else { 435cb93a386Sopenharmony_ci return SkString("simple-polygon-offset"); 436cb93a386Sopenharmony_ci } 437cb93a386Sopenharmony_ci } 438cb93a386Sopenharmony_ci SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); } 439cb93a386Sopenharmony_ci bool runAsBench() const override { return true; } 440cb93a386Sopenharmony_ci 441cb93a386Sopenharmony_ci static void GetConvexPolygon(int index, SkPathDirection dir, 442cb93a386Sopenharmony_ci std::unique_ptr<SkPoint[]>* data, int* numPts) { 443cb93a386Sopenharmony_ci if (index < (int)SK_ARRAY_COUNT(PolygonOffsetData::gConvexPoints)) { 444cb93a386Sopenharmony_ci // manually specified 445cb93a386Sopenharmony_ci *numPts = (int)PolygonOffsetData::gConvexSizes[index]; 446cb93a386Sopenharmony_ci *data = std::make_unique<SkPoint[]>(*numPts); 447cb93a386Sopenharmony_ci if (SkPathDirection::kCW == dir) { 448cb93a386Sopenharmony_ci for (int i = 0; i < *numPts; ++i) { 449cb93a386Sopenharmony_ci (*data)[i] = PolygonOffsetData::gConvexPoints[index][i]; 450cb93a386Sopenharmony_ci } 451cb93a386Sopenharmony_ci } else { 452cb93a386Sopenharmony_ci for (int i = 0; i < *numPts; ++i) { 453cb93a386Sopenharmony_ci (*data)[i] = PolygonOffsetData::gConvexPoints[index][*numPts - i - 1]; 454cb93a386Sopenharmony_ci } 455cb93a386Sopenharmony_ci } 456cb93a386Sopenharmony_ci } else { 457cb93a386Sopenharmony_ci // procedurally generated 458cb93a386Sopenharmony_ci SkScalar width = kMaxPathHeight / 2; 459cb93a386Sopenharmony_ci SkScalar height = kMaxPathHeight / 2; 460cb93a386Sopenharmony_ci int numPtsArray[] = { 3, 4, 5, 5, 6, 8, 8, 20, 100 }; 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_ci size_t arrayIndex = index - SK_ARRAY_COUNT(PolygonOffsetData::gConvexPoints); 463cb93a386Sopenharmony_ci SkASSERT(arrayIndex < SK_ARRAY_COUNT(numPtsArray)); 464cb93a386Sopenharmony_ci *numPts = numPtsArray[arrayIndex]; 465cb93a386Sopenharmony_ci if (arrayIndex == 3 || arrayIndex == 6) { 466cb93a386Sopenharmony_ci // squashed pentagon and octagon 467cb93a386Sopenharmony_ci width = kMaxPathHeight / 5; 468cb93a386Sopenharmony_ci } 469cb93a386Sopenharmony_ci 470cb93a386Sopenharmony_ci *data = std::make_unique<SkPoint[]>(*numPts); 471cb93a386Sopenharmony_ci 472cb93a386Sopenharmony_ci create_ngon(*numPts, data->get(), width, height, dir); 473cb93a386Sopenharmony_ci } 474cb93a386Sopenharmony_ci } 475cb93a386Sopenharmony_ci 476cb93a386Sopenharmony_ci static void GetSimplePolygon(int index, SkPathDirection dir, 477cb93a386Sopenharmony_ci std::unique_ptr<SkPoint[]>* data, int* numPts) { 478cb93a386Sopenharmony_ci if (index < (int)SK_ARRAY_COUNT(PolygonOffsetData::gSimplePoints)) { 479cb93a386Sopenharmony_ci // manually specified 480cb93a386Sopenharmony_ci *numPts = (int)PolygonOffsetData::gSimpleSizes[index]; 481cb93a386Sopenharmony_ci *data = std::make_unique<SkPoint[]>(*numPts); 482cb93a386Sopenharmony_ci if (SkPathDirection::kCW == dir) { 483cb93a386Sopenharmony_ci for (int i = 0; i < *numPts; ++i) { 484cb93a386Sopenharmony_ci (*data)[i] = PolygonOffsetData::gSimplePoints[index][i]; 485cb93a386Sopenharmony_ci } 486cb93a386Sopenharmony_ci } else { 487cb93a386Sopenharmony_ci for (int i = 0; i < *numPts; ++i) { 488cb93a386Sopenharmony_ci (*data)[i] = PolygonOffsetData::gSimplePoints[index][*numPts - i - 1]; 489cb93a386Sopenharmony_ci } 490cb93a386Sopenharmony_ci } 491cb93a386Sopenharmony_ci } else { 492cb93a386Sopenharmony_ci // procedurally generated 493cb93a386Sopenharmony_ci SkScalar width = kMaxPathHeight / 2; 494cb93a386Sopenharmony_ci SkScalar height = kMaxPathHeight / 2; 495cb93a386Sopenharmony_ci int numPtsArray[] = { 5, 7, 8, 20, 100 }; 496cb93a386Sopenharmony_ci 497cb93a386Sopenharmony_ci size_t arrayIndex = index - SK_ARRAY_COUNT(PolygonOffsetData::gSimplePoints); 498cb93a386Sopenharmony_ci arrayIndex = std::min(arrayIndex, SK_ARRAY_COUNT(numPtsArray) - 1); 499cb93a386Sopenharmony_ci SkASSERT(arrayIndex < SK_ARRAY_COUNT(numPtsArray)); 500cb93a386Sopenharmony_ci *numPts = numPtsArray[arrayIndex]; 501cb93a386Sopenharmony_ci // squash horizontally 502cb93a386Sopenharmony_ci width = kMaxPathHeight / 5; 503cb93a386Sopenharmony_ci 504cb93a386Sopenharmony_ci *data = std::make_unique<SkPoint[]>(*numPts); 505cb93a386Sopenharmony_ci 506cb93a386Sopenharmony_ci create_ngon(*numPts, data->get(), width, height, dir); 507cb93a386Sopenharmony_ci } 508cb93a386Sopenharmony_ci } 509cb93a386Sopenharmony_ci // Draw a single polygon with insets and potentially outsets 510cb93a386Sopenharmony_ci void drawPolygon(SkCanvas* canvas, int index, SkPoint* position) { 511cb93a386Sopenharmony_ci 512cb93a386Sopenharmony_ci SkPoint center; 513cb93a386Sopenharmony_ci { 514cb93a386Sopenharmony_ci std::unique_ptr<SkPoint[]> data(nullptr); 515cb93a386Sopenharmony_ci int numPts; 516cb93a386Sopenharmony_ci if (fConvexOnly) { 517cb93a386Sopenharmony_ci GetConvexPolygon(index, SkPathDirection::kCW, &data, &numPts); 518cb93a386Sopenharmony_ci } else { 519cb93a386Sopenharmony_ci GetSimplePolygon(index, SkPathDirection::kCW, &data, &numPts); 520cb93a386Sopenharmony_ci } 521cb93a386Sopenharmony_ci SkRect bounds; 522cb93a386Sopenharmony_ci bounds.setBounds(data.get(), numPts); 523cb93a386Sopenharmony_ci if (!fConvexOnly) { 524cb93a386Sopenharmony_ci bounds.outset(kMaxOutset, kMaxOutset); 525cb93a386Sopenharmony_ci } 526cb93a386Sopenharmony_ci if (position->fX + bounds.width() > kGMWidth) { 527cb93a386Sopenharmony_ci position->fX = 0; 528cb93a386Sopenharmony_ci position->fY += kMaxPathHeight; 529cb93a386Sopenharmony_ci } 530cb93a386Sopenharmony_ci center = { position->fX + SkScalarHalf(bounds.width()), position->fY }; 531cb93a386Sopenharmony_ci position->fX += bounds.width(); 532cb93a386Sopenharmony_ci } 533cb93a386Sopenharmony_ci 534cb93a386Sopenharmony_ci const SkPathDirection dirs[2] = { SkPathDirection::kCW, SkPathDirection::kCCW }; 535cb93a386Sopenharmony_ci const float insets[] = { 5, 10, 15, 20, 25, 30, 35, 40 }; 536cb93a386Sopenharmony_ci const float offsets[] = { 2, 5, 9, 14, 20, 27, 35, 44, -2, -5, -9 }; 537cb93a386Sopenharmony_ci const SkColor colors[] = { 0xFF901313, 0xFF8D6214, 0xFF698B14, 0xFF1C8914, 538cb93a386Sopenharmony_ci 0xFF148755, 0xFF146C84, 0xFF142482, 0xFF4A1480, 539cb93a386Sopenharmony_ci 0xFF901313, 0xFF8D6214, 0xFF698B14 }; 540cb93a386Sopenharmony_ci 541cb93a386Sopenharmony_ci SkPaint paint; 542cb93a386Sopenharmony_ci paint.setAntiAlias(true); 543cb93a386Sopenharmony_ci paint.setStyle(SkPaint::kStroke_Style); 544cb93a386Sopenharmony_ci paint.setStrokeWidth(1); 545cb93a386Sopenharmony_ci 546cb93a386Sopenharmony_ci std::unique_ptr<SkPoint[]> data(nullptr); 547cb93a386Sopenharmony_ci int numPts; 548cb93a386Sopenharmony_ci if (fConvexOnly) { 549cb93a386Sopenharmony_ci GetConvexPolygon(index, dirs[index % 2], &data, &numPts); 550cb93a386Sopenharmony_ci } else { 551cb93a386Sopenharmony_ci GetSimplePolygon(index, dirs[index % 2], &data, &numPts); 552cb93a386Sopenharmony_ci } 553cb93a386Sopenharmony_ci 554cb93a386Sopenharmony_ci { 555cb93a386Sopenharmony_ci SkPath path; 556cb93a386Sopenharmony_ci path.moveTo(data.get()[0]); 557cb93a386Sopenharmony_ci for (int i = 1; i < numPts; ++i) { 558cb93a386Sopenharmony_ci path.lineTo(data.get()[i]); 559cb93a386Sopenharmony_ci } 560cb93a386Sopenharmony_ci path.close(); 561cb93a386Sopenharmony_ci canvas->save(); 562cb93a386Sopenharmony_ci canvas->translate(center.fX, center.fY); 563cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 564cb93a386Sopenharmony_ci canvas->restore(); 565cb93a386Sopenharmony_ci } 566cb93a386Sopenharmony_ci 567cb93a386Sopenharmony_ci SkTDArray<SkPoint> offsetPoly; 568cb93a386Sopenharmony_ci size_t count = fConvexOnly ? SK_ARRAY_COUNT(insets) : SK_ARRAY_COUNT(offsets); 569cb93a386Sopenharmony_ci for (size_t i = 0; i < count; ++i) { 570cb93a386Sopenharmony_ci SkScalar offset = fConvexOnly ? insets[i] : offsets[i]; 571cb93a386Sopenharmony_ci std::function<SkScalar(const SkPoint&)> offsetFunc; 572cb93a386Sopenharmony_ci 573cb93a386Sopenharmony_ci bool result; 574cb93a386Sopenharmony_ci if (fConvexOnly) { 575cb93a386Sopenharmony_ci result = SkInsetConvexPolygon(data.get(), numPts, offset, &offsetPoly); 576cb93a386Sopenharmony_ci } else { 577cb93a386Sopenharmony_ci SkRect bounds; 578cb93a386Sopenharmony_ci bounds.setBoundsCheck(data.get(), numPts); 579cb93a386Sopenharmony_ci result = SkOffsetSimplePolygon(data.get(), numPts, bounds, offset, &offsetPoly); 580cb93a386Sopenharmony_ci } 581cb93a386Sopenharmony_ci if (result) { 582cb93a386Sopenharmony_ci SkPath path; 583cb93a386Sopenharmony_ci path.moveTo(offsetPoly[0]); 584cb93a386Sopenharmony_ci for (int j = 1; j < offsetPoly.count(); ++j) { 585cb93a386Sopenharmony_ci path.lineTo(offsetPoly[j]); 586cb93a386Sopenharmony_ci } 587cb93a386Sopenharmony_ci path.close(); 588cb93a386Sopenharmony_ci 589cb93a386Sopenharmony_ci paint.setColor(ToolUtils::color_to_565(colors[i])); 590cb93a386Sopenharmony_ci canvas->save(); 591cb93a386Sopenharmony_ci canvas->translate(center.fX, center.fY); 592cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 593cb93a386Sopenharmony_ci canvas->restore(); 594cb93a386Sopenharmony_ci } 595cb93a386Sopenharmony_ci } 596cb93a386Sopenharmony_ci } 597cb93a386Sopenharmony_ci 598cb93a386Sopenharmony_ci void onDraw(SkCanvas* canvas) override { 599cb93a386Sopenharmony_ci // the right edge of the last drawn path 600cb93a386Sopenharmony_ci SkPoint offset = { 0, SkScalarHalf(kMaxPathHeight) }; 601cb93a386Sopenharmony_ci if (!fConvexOnly) { 602cb93a386Sopenharmony_ci offset.fY += kMaxOutset; 603cb93a386Sopenharmony_ci } 604cb93a386Sopenharmony_ci 605cb93a386Sopenharmony_ci for (int i = 0; i < kNumPaths; ++i) { 606cb93a386Sopenharmony_ci this->drawPolygon(canvas, i, &offset); 607cb93a386Sopenharmony_ci } 608cb93a386Sopenharmony_ci } 609cb93a386Sopenharmony_ci 610cb93a386Sopenharmony_ciprivate: 611cb93a386Sopenharmony_ci inline static constexpr int kNumPaths = 20; 612cb93a386Sopenharmony_ci inline static constexpr int kMaxPathHeight = 100; 613cb93a386Sopenharmony_ci inline static constexpr int kMaxOutset = 16; 614cb93a386Sopenharmony_ci inline static constexpr int kGMWidth = 512; 615cb93a386Sopenharmony_ci inline static constexpr int kGMHeight = 512; 616cb93a386Sopenharmony_ci 617cb93a386Sopenharmony_ci bool fConvexOnly; 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_ci using INHERITED = GM; 620cb93a386Sopenharmony_ci}; 621cb93a386Sopenharmony_ci 622cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 623cb93a386Sopenharmony_ci 624cb93a386Sopenharmony_ciDEF_GM(return new PolygonOffsetGM(true);) 625cb93a386Sopenharmony_ciDEF_GM(return new PolygonOffsetGM(false);) 626cb93a386Sopenharmony_ci} // namespace skiagm 627