1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google LLC 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/SkPaint.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPathBuilder.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci// crbug.com/982968 14cb93a386Sopenharmony_ci// Intended to draw a curvy triangle. 15cb93a386Sopenharmony_ci// With the bug, we extend the left side of the triangle with lines, a bit like a flag pole. 16cb93a386Sopenharmony_ci// The bug/fix is related to precision of the calculation. The original impl used all floats, 17cb93a386Sopenharmony_ci// but the very shallow angle causes our sin/cos and other calcs to lose too many bits. 18cb93a386Sopenharmony_ci// The fix was to use doubles for this part of the calc in SkPath::arcTo(). 19cb93a386Sopenharmony_ci// 20cb93a386Sopenharmony_ciDEF_SIMPLE_GM(shallow_angle_path_arcto, canvas, 300, 300) { 21cb93a386Sopenharmony_ci SkPathBuilder path; 22cb93a386Sopenharmony_ci SkPaint paint; 23cb93a386Sopenharmony_ci paint.setStyle(SkPaint::kStroke_Style); 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci path.moveTo(313.44189096331155f, 106.6009423589212f) 26cb93a386Sopenharmony_ci .arcTo({284.3113082008462f, 207.1407719157063f}, 27cb93a386Sopenharmony_ci {255.15053777129728f, 307.6718505416374f}, 28cb93a386Sopenharmony_ci 697212.0011054524f) 29cb93a386Sopenharmony_ci .lineTo(255.15053777129728f, 307.6718505416374f) 30cb93a386Sopenharmony_ci .arcTo({340.4737465981018f, 252.6907319346971f}, 31cb93a386Sopenharmony_ci {433.54333477716153f, 212.18116363345337f}, 32cb93a386Sopenharmony_ci 1251.2484277907251f) 33cb93a386Sopenharmony_ci .lineTo(433.54333477716153f, 212.18116363345337f) 34cb93a386Sopenharmony_ci .arcTo({350.19513833839466f, 185.89280014838369f}, 35cb93a386Sopenharmony_ci {313.44189096331155f, 106.6009423589212f}, 36cb93a386Sopenharmony_ci 198.03116885327813f); 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci canvas->translate(-200, -50); 39cb93a386Sopenharmony_ci canvas->drawPath(path.detach(), paint); 40cb93a386Sopenharmony_ci}; 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci#include "include/utils/SkParsePath.h" 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ciDEF_SIMPLE_GM(arcto_skbug_9272, canvas, 150, 150) { 45cb93a386Sopenharmony_ci const char* str = "M66.652,65.509c0.663,-2 -0.166,-4.117 -2.117,-5.212 -0.673,-0.378 -1.36,-0.733 -2.04,-1.1a1647300864,1647300864 0,0 1,-31.287 -16.86c-5.39,-2.903 -10.78,-5.808 -16.171,-8.713 -1.626,-0.876 -3.253,-1.752 -4.88,-2.63 -1.224,-0.659 -2.4,-1.413 -3.851,-1.413 -1.135,0 -2.242,0.425 -3.049,1.197 0.08,-0.083 0.164,-0.164 0.248,-0.246l5.309,-5.13 9.37,-9.054 9.525,-9.204 5.903,-5.704C34.237,0.836 34.847,0.297 35.75,0.13c0.982,-0.182 1.862,0.127 2.703,0.592l6.23,3.452L55.76,10.31l11.951,6.62 9.02,4.996c1.74,0.963 4.168,1.854 4.205,4.21 0.011,0.678 -0.246,1.28 -0.474,1.9l-1.005,2.733 -5.665,15.42 -7.106,19.338 -0.034,-0.018z"; 46cb93a386Sopenharmony_ci SkPath path; 47cb93a386Sopenharmony_ci SkParsePath::FromSVGString(str, &path); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci const char* str2 = "M10.156,30.995l4.881,2.63 16.17,8.713a1647300736,1647300736 0,0 0,31.287 16.86c0.68,0.366 1.368,0.721 2.041,1.1 2.242,1.257 3.002,3.864 1.72,6.094 -0.659,1.147 -1.296,2.31 -1.978,3.442 -1.276,2.117 -3.973,2.632 -6.102,1.536 -0.244,-0.125 -0.485,-0.259 -0.727,-0.388l-4.102,-2.19 -15.401,-8.225 -18.536,-9.9 -13.893,-7.419c-0.939,-0.501 -1.88,-0.998 -2.816,-1.504C1.2,40.935 0.087,39.5 0.004,37.75c-0.08,-1.672 1.078,-3.277 1.826,-4.702 0.248,-0.471 0.479,-0.958 0.75,-1.416 0.772,-1.306 2.224,-2.05 3.726,-2.05 1.45,0 2.627,0.754 3.85,1.414z"; 50cb93a386Sopenharmony_ci SkPath path2; 51cb93a386Sopenharmony_ci SkParsePath::FromSVGString(str2, &path2); 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci SkPaint paint; 54cb93a386Sopenharmony_ci paint.setStyle(SkPaint::kStroke_Style); 55cb93a386Sopenharmony_ci canvas->translate(30, 30); 56cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 57cb93a386Sopenharmony_ci canvas->drawPath(path2, paint); 58cb93a386Sopenharmony_ci} 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_cistatic SkPath old_school_polygon(const SkPoint pts[], size_t count, bool isClosed) { 61cb93a386Sopenharmony_ci SkPath path; 62cb93a386Sopenharmony_ci path.addPoly(pts, count, isClosed); 63cb93a386Sopenharmony_ci return path; 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_cistatic SkPath new_school_polygon(const SkPoint pts[], size_t count, bool isClosed) { 67cb93a386Sopenharmony_ci return SkPath::Polygon(pts, count, isClosed); 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ciDEF_SIMPLE_GM(path_append_extend, canvas, 400, 400) { 71cb93a386Sopenharmony_ci const SkPoint p0[] = { 72cb93a386Sopenharmony_ci { 10, 30 }, {30, 10}, {50, 30}, 73cb93a386Sopenharmony_ci }; 74cb93a386Sopenharmony_ci const SkPoint p1[] = { 75cb93a386Sopenharmony_ci { 10, 50 }, {30, 70}, {50, 50}, 76cb93a386Sopenharmony_ci }; 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci const SkPath path1 = SkPath::Polygon(p1, SK_ARRAY_COUNT(p1), false); 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci SkPaint paint; 81cb93a386Sopenharmony_ci paint.setStroke(true); 82cb93a386Sopenharmony_ci paint.setStrokeWidth(9); 83cb93a386Sopenharmony_ci paint.setAntiAlias(true); 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci // addPath() sometimes checks for perspective, so we want to test that 86cb93a386Sopenharmony_ci const SkScalar x = 0.0001f; // tiny amount of perspective 87cb93a386Sopenharmony_ci const SkMatrix perspective = SkMatrix::MakeAll(1, 0, 0, 88cb93a386Sopenharmony_ci 0, 1, 0, 89cb93a386Sopenharmony_ci x, 0, 1); 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci for (bool isClosed : {false, true}) { 92cb93a386Sopenharmony_ci for (auto proc : {old_school_polygon, new_school_polygon}) { 93cb93a386Sopenharmony_ci canvas->save(); 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci SkPath path0 = proc(p0, SK_ARRAY_COUNT(p0), isClosed); 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci canvas->drawPath(path0, paint); 98cb93a386Sopenharmony_ci canvas->drawPath(path1, paint); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci canvas->translate(80, 0); 101cb93a386Sopenharmony_ci { 102cb93a386Sopenharmony_ci SkPath path = path0; 103cb93a386Sopenharmony_ci path.addPath(path1, SkPath::kAppend_AddPathMode); 104cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci canvas->translate(80, 0); 108cb93a386Sopenharmony_ci { 109cb93a386Sopenharmony_ci SkPath path = path0; 110cb93a386Sopenharmony_ci path.addPath(path1, perspective, SkPath::kAppend_AddPathMode); 111cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci canvas->translate(80, 0); 115cb93a386Sopenharmony_ci { 116cb93a386Sopenharmony_ci SkPath path = path0; 117cb93a386Sopenharmony_ci path.addPath(path1, SkPath::kExtend_AddPathMode); 118cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci canvas->translate(80, 0); 122cb93a386Sopenharmony_ci { 123cb93a386Sopenharmony_ci SkPath path = path0; 124cb93a386Sopenharmony_ci path.addPath(path1, perspective, SkPath::kExtend_AddPathMode); 125cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci canvas->restore(); 129cb93a386Sopenharmony_ci canvas->translate(0, 100); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci} 134