1 /*
2 * Copyright 2024 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include <cmath>
9 #include <utility>
10 #include <deque>
11 #include <vector>
12
13 #include "include/core/SkCanvas.h"
14 #include "include/core/SkCubicMap.h"
15 #include "include/core/SkMatrix.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkPath.h"
18 #include "include/core/SkPathMeasure.h"
19 #include "include/core/SkPathTypes.h"
20 #include "include/core/SkSize.h"
21 #include "include/core/SkString.h"
22 #include "include/private/SkPathRef.h"
23 #include "include/private/base/SkAssert.h"
24 #include "include/utils/SkParsePath.h"
25 #include "src/core/SkGeometry.h"
26 #include "src/core/SkPathPriv.h"
27 #include "tools/viewer/Slide.h"
28
29 #include "imgui.h"
30
31 namespace {
32
33 static constexpr struct PathDesc {
34 const char* fName;
35 const char* fSVGString;
36 } gSamplePaths[] = {
37 { "Arc 1", "M0,0.5 Q0,0 0.5,0 Q1,0 1,0.5"},
38 { "Arc 2", "M0,0.5 Q0,1 0.5,1 Q1,1 1,0.5 L1.1,0.5 L1.2,0.5 L1.3,0.5 L1.5,0.5"},
39 { "Pentagon",
40 R"(M10.1192 4.09438C10.7952 3.60324 11.1332 3.35767 11.5027 3.26278C11.829 3.17901 12.1712 3.17901 12.4975
41 3.26278C12.867 3.35767 13.205 3.60324 13.881 4.09438L19.6298 8.27108C20.3058 8.76222 20.6437 9.0078 20.8482
42 9.32992C21.0287 9.61436 21.1344 9.93978 21.1556 10.276C21.1795 10.6568 21.0504 11.0541 20.7922 11.8488L18.5964
43 18.6068C18.3382 19.4015 18.2091 19.7989 17.9659 20.0928C17.7512 20.3524 17.4743 20.5535 17.1611 20.6775C16.8064
44 20.818 16.3886 20.818 15.553 20.818H8.44718C7.6116 20.818 7.19381 20.818 6.83908 20.6775C6.52586 20.5535 6.24904
45 20.3524 6.0343 20.0928C5.79111 19.7989 5.66201 19.4015 5.4038 18.6068L3.20798 11.8488C2.94977 11.0541 2.82066
46 10.6568 2.84462 10.276C2.86577 9.93978 2.97151 9.61436 3.15202 9.32992C3.35645 9.0078 3.69445 8.76222 4.37045
47 8.27108L10.1192 4.09438Z)"},
48 { "Droplet",
49 R"(M12 21.5C13.8565 21.5 15.637 20.7625 16.9497 19.4497C18.2625 18.137 19 16.3565 19 14.5C19 12.5 18 10.6 16 9
50 C14 7.4 12.5 5 12 2.5C11.5 5 10 7.4 8 9C6 10.6 5 12.5 5 14.5C5 16.3565 5.7375 18.137 7.05025 19.4497
51 C8.36301 20.7625 10.1435 21.5 12 21.5V21.5Z)"},
52 { "Shield",
53 R"(M20 6C20 6 19.1843 6 19.0001 6C16.2681 6 13.8871 4.93485 11.9999 3C10.1128 4.93478 7.73199 6 5.00009 6
54 C4.81589 6 4.00009 6 4.00009 6C4.00009 6 4 8 4 9.16611C4 14.8596 7.3994 19.6436 12 21C16.6006 19.6436 20 14.8596 20 9.16611
55 C20 8 20 6 20 6Z)"},
56 { "Spiral",
57 R"(M297,7888.302 L297,7886.302 C297,7885.75 296.552,7885 296,7885 L292,7885 C291.448,7885 291,7885.75 291,7886.302
58 L291,7892.302 C291,7892.854 291.448,7893 292,7893 L300,7893 C300.552,7893 301,7892.854 301,7892.302 L301,7882.302
59 C301,7881.75 300.552,7881 300,7881 L288,7881 C287.448,7881 287,7881.75 287,7882.302 L287,7896.302
60 C287,7896.854 287.448,7897 288,7897 L302,7897 C302.552,7897 303,7897.524 303,7898.076 L303,7898.151
61 C303,7898.703 302.552,7899 302,7899 L287,7899 C285.896,7899 285,7898.407 285,7897.302 L285,7881.302
62 C285,7880.197 285.896,7879 287,7879 L301,7879 C302.105,7879 303,7880.197 303,7881.302 L303,7893.302
63 C303,7894.407 302.105,7895 301,7895 L291,7895 C289.896,7895 289,7894.407 289,7893.302 L289,7885.302
64 C289,7884.197 289.896,7883 291,7883 L297,7883 C298.105,7883 299,7884.197 299,7885.302 L299,7889.302
65 C299,7890.407 298.105,7891 297,7891 L295,7891 C293.896,7891 293,7890.407 293,7889.302 L293,7888.302
66 C293,7887.75 293.448,7887.302 294,7887.302 C294.552,7887.302 295,7887.75 295,7888.302
67 C295,7888.854 295.448,7889.302 296,7889.302 C296.552,7889.302 297,7888.854 297,7888.302)"},
68 { "Cat",
69 R"(M26.753,210.905c-4.68,19.271-1.375,33.856,8.258,46.243c9.633,12.387-1.102,19.543-9.082,23.398
70 s-11.012,6.332-11.562,11.836s6.883,26.978,10.461,30.556s11.563,11.285,16.789,19.27c5.231,7.98,12.11,2.754,12.11,2.754
71 c4.953,3.855,9.91,0,9.91,0c8.809,4.129,14.039-1.652,14.039-1.652c4.402-5.23-4.953-10.734-4.953-10.734
72 c-5.781-10.184-10.184-1.926-11.836-4.129s-3.027-2.477-11.836-12.66s14.039-6.883,22.02-8.809s23.122-12.109,23.122-12.109
73 c0,12.109,4.129,10.184,10.184,16.516s8.809,10.461,16.789,13.762c7.98,3.305,11.836,2.754,18.993,7.434s22.02,3.855,22.02,3.855
74 c6.605,2.204,12.938,0,12.938,0c15.965,0,9.359-5.504,3.578-12.938s-17.34-1.102-22.57-4.68s-18.168-9.082-24.774-12.938
75 c-6.605-3.855,0-10.734,0-17.066s4.953-11.285,4.953-11.285h25.598c0,0,19.816-1.375,25.047,9.359s13.211,12.938,13.488,18.719
76 c0.278,5.781-4.68,6.332-4.68,6.332c-11.012-3.027-11.285,14.59-11.285,14.59c13.488,17.892,39.638-7.434,39.638-7.434
77 c30.277-2.754,28.074-47.344,28.074-47.344c6.055-4.402,15.691-15.965,22.02-26.427c6.332-10.461,24.223-18.441,40.188-10.734
78 c15.965,7.707,18.719-5.23,18.719-5.23c5.504,0.824,7.156-6.332,7.156-6.332c7.156-7.98-5.504-9.91-5.781-29.727
79 s-16.789-23.399-15.965-29.176c0.824-5.781,17.617-24.223,13.488-22.571c-3.603,1.44-18.739,8.964-22.53,10.853
80 c-0.126-0.498-0.375-1.208-0.868-2.317c-2.204-4.953-26.427,10.734-26.427,10.734s-38.396,22.709-45.83,24.362
81 c-7.435,1.652-6.605-3.305-15.688-2.477c-9.083,0.824-13.628,1.652-54.501-15.692c-40.877-17.34-115.325,10.546-115.325,10.546
82 S-8.608,82.798,40.935,41.924S24.215-33.009,8.111,56.167C-7.992,145.344,31.433,191.64,26.753,210.905z)" },
83 { "Rabit",
84 R"(M526.834,235.822c-6.308-15.153-11.856-30.576-18.748-45.546c-5.969-12.966-15.985-20.689-27.282-27.287
85 c-6.455-3.766-13.681-6.205-20.563-8.865c-2.102-0.812-3.447-3.309-3.007-5.517c1.126-5.643,2.379-11.607,3.187-17.629
86 c0.489-3.664-0.425-7.495-0.47-11.253c-0.061-5.101-0.012-10.204,0.196-15.3c0.363-8.829-1.918-17.157-4.039-25.614
87 c-1.359-5.423-0.367-11.478-1.959-16.789c-1.652-5.521,0.322-12.212-4.961-16.614c-0.118-0.098-0.184-0.343-0.167-0.51
88 c0.844-8.576-5.484-14.574-8.373-21.714c-2.933-7.246-7.752-14.157-15.879-17.617c-2.881-1.225-5.516-3.023-8.482-4.974
89 c-1.881-1.24-4.007-0.466-4.745,1.664c-2.546,7.364-5.116,14.035-6.622,20.935c-1.488,6.847-5.111,13.048-3.998,20.898
90 c0.8,5.618-2.685,11.771-3.88,17.764c-0.633,3.17-0.963,6.397-1.302,9.649c-0.232,2.24-1.656,2.685-3.06,0.918
91 c-3.366-4.243-6.328-8.507-10.38-11.004c-6.977-4.296-12.162-10.689-18.996-14.745c-10.674-6.332-21.519-12.917-33.138-16.956
92 c-11.519-4.007-24.027-5.463-36.23-7.047c-3.212-0.416-6.643,0.845-10.507,2.049c-2.15,0.669-3.076,2.713-2.036,4.712
93 c3.594,6.908,6.817,13.358,10.457,19.563c6.027,10.278,12.286,20.433,18.813,30.4c3.701,5.651,8.192,10.779,12.232,16.214
94 c4.153,5.594,7.988,11.437,12.342,16.867c3.015,3.758,6.744,6.936,10.017,10.497c3.606,3.926,7.299,7.802,10.526,12.028
95 c8.841,11.579,12.276,25.182,14.116,39.319c0.069,0.538,0.151,1.117,0.396,1.591c4.636,8.895-0.236,14.582-6.527,19.935
96 c-0.886,0.755-0.959,2.444-1.453,3.685c-0.844,2.113-1.313,4.533-2.66,6.259c-4.174,5.332-4.953,11.493-5.471,17.911
97 c-0.322,3.978-1.502,7.874-2.068,11.844c-0.09,0.637-0.041,1.294,0.053,1.901c0.159,1.041-0.534,3.477-1.469,5.528
98 c-3.473,7.634-5.899,16.026-13.064,21.172c-1.832,1.313-2.35,1.921-0.91,1.75c1.44-0.171,2.641-0.18,2.686-0.021
99 s-1.637,0.926-3.746,1.714c-0.318,0.118-0.641,0.236-0.963,0.358c-2.113,0.788-2.848,1.689-1.644,2.016
100 c1.203,0.327,0.461,1.2-1.665,1.955c-1.889,0.669-3.709,1.313-5.569,1.975c-2.126,0.75-3.035,1.767-2.036,2.264
101 c1,0.498,0.245,1.294-1.681,1.779s-3.272,1.375-3.003,1.979c0.27,0.604-1.306,1.444-3.509,1.91
102 c-3.966,0.836-7.939,1.701-11.963,2.068c-1.301,0.118-2.7-0.086-4.08-0.478c-2.166-0.616-5.605-1.624-7.858-1.575
103 c-13.17,0.282-35.672,4.391-44.778,6.148c-2.211,0.429-5.818,0.979-8.062,1.212c-3.052,0.314-6.308,0.649-9.666,0.996
104 c-2.24,0.232-3.77,0.689-3.411,1.023c0.355,0.335-1.089,1.184-3.228,1.897c-9.833,3.288-19.849,6.634-29.906,9.996
105 c-2.138,0.714-3.297,1.611-2.583,2.003c0.714,0.392-0.4,1.403-2.521,2.171c-5.675,2.048-11.355,3.725-15.802,7.054
106 c-4.814,3.607-10.164,6.479-14.913,10.286c-5.349,4.284-12.795,5.944-19.331,8.747c-0.62,0.266-1.24,0.53-2.056,0.886
107 c-1.139,0.489-1.155,1.293-0.033,1.795s0.563,1.999-1.245,3.346c-3.929,2.922-7.813,5.814-11.738,8.735
108 c-1.808,1.347-2.734,2.746-2.069,3.129c0.665,0.384-0.396,1.571-2.371,2.656c-1.33,0.73-2.64,1.448-3.941,2.167
109 c-1.975,1.085-3.484,2.146-3.375,2.37c0.114,0.225,1.424,0.188,2.934-0.086c1.505-0.273,1.408,0.771-0.22,2.326
110 c-7.181,6.854-14.125,13.492-21.094,20.106c-0.718,0.681-1.481,1.313-2.436,2.101c-1.375,1.131-1.008,1.648,0.808,1.146
111 c1.816-0.497,2.272,0.62,1.044,2.51c-3.472,5.32-6.842,10.579-10.453,15.667c-2.317,3.26-5.271,6.071-7.899,9.114
112 c-0.082,0.099-0.065,0.282-0.029,0.485c0.045,0.273,0.796,0.359,1.681,0.196s0.526,1.179-0.8,3.003
113 c-2.199,3.015-4.345,5.965-6.679,9.168c-1.326,1.819-0.947,2.518,0.844,1.555c1.792-0.963,2.518-0.062,1.559,1.979
114 c-3.537,7.52-7.226,14.052-7.789,21.93c-0.277,3.88-2.317,7.63-4.304,11.824c-0.963,2.036-0.853,3.162,0.126,2.46
115 c0.979-0.702,1.469,0.534,1.085,2.754c-1.812,10.457-3.578,20.669-5.328,30.768c-0.384,2.22-0.106,3.773,0.624,3.468
116 s0.812,1.199,0.184,3.366c-0.498,1.709-0.979,3.361-1.457,5.015c-0.628,2.162-0.481,3.745,0.322,3.533
117 c0.808-0.213,0.795,1.334,0.404,3.554c-1.02,5.797-0.355,11.938-4.602,16.703c-1.498,1.681-2.236,2.628-1.159,2.628
118 s0.877,1.48-0.441,3.312c-0.359,0.498-0.714,0.995-1.081,1.501c-1.318,1.828-1.665,3.068-0.779,2.763s1.677-0.44,1.767-0.306
119 c0.062,0.089,0.11,0.175,0.114,0.261c0.029,0.538,0.057,1.085-0.004,1.615c-1.134,9.771,2.023,17.349,11.33,21.555
120 c6.749,3.052,11.62,9.915,20.433,9.078c2.762-0.261,5.822,2.709,8.764,4.158c0.114,0.057,0.286,0.004,0.469-0.07
121 c0.253-0.098,0.265-0.628,0.029-1.187c-0.237-0.56,1.358-0.641,3.566-0.176c1.583,0.335,3.17,0.669,4.773,1.008
122 c2.208,0.465,3.705,0.229,3.354-0.526c-0.351-0.751,1.061-0.673,3.199,0.033c18.458,6.091,37.271,3.562,55.928,3.912
123 c2.252,0.041,3.832-0.229,3.534-0.661c-0.302-0.437,1.285-0.787,3.542-0.783c6.417,0.013,12.889,0.037,19.355-0.032
124 c3.007-0.033,6.03-0.217,9.008-0.62c6.626-0.894,13.244-1.849,19.829-2.991c7.222-1.252,14.517,1.604,21.962-2.746
125 c4.357-2.545,8.319-4.476,9.854-7.833c0.934-2.048,2.415-4.423,4.61-4.941c4.08-0.967,7.936-1.848,11.706-3.007
126 c5.283-1.623,9.849-3.541,10.967-10.521c0.792-4.958,0.396-9.507-4.1-12.146c-0.441-0.257-0.682-0.849-0.849-1.469
127 c-0.245-0.927-2.211-1.849-4.456-2.036c-0.498-0.041-1.008-0.086-1.53-0.131c-2.244-0.188-3.125-1.905-1.962-3.839
128 c0.673-1.118,1.302-2.162,1.905-3.17c1.163-1.93,2.375-3.35,2.709-3.175c0.334,0.176,0.702,1.657,0.816,3.31
129 s1.02,1.362,2.016-0.661c0.489-0.991,0.958-1.942,1.412-2.868c0.996-2.02,2.048-3.574,2.346-3.469
130 c0.298,0.106,0.673,1.506,0.833,3.117c0.159,1.612,0.967,1.225,1.808-0.869c0.269-0.673,0.539-1.342,0.812-2.027
131 c0.836-2.093,1.636-2.276,1.787-0.416c0.151,1.86,0.71,1.583,1.64-0.474c1.856-4.101,4.762-7.188,9.323-9.127
132 c6.304-2.676,12.371-5.916,18.675-8.604c1.061-0.453,3.337,0.2,4.104,1.126c3.08,3.705,5.699,7.789,8.666,11.6
133 c3.112,4.003,6.344,7.919,9.673,11.742c4.239,4.863,8.63,9.592,12.946,14.39c0.245,0.273,0.461,0.567,0.686,0.882
134 c0.354,0.506,0.967,0.399,1.362-0.229s1.457,0.53,2.375,2.591c0.322,0.722,0.648,1.456,0.983,2.216
135 c0.913,2.06,1.827,2.599,2.035,1.203s1.412-1.024,2.685,0.832c3.396,4.953,6.684,9.752,9.891,14.427
136 c1.272,1.861,2.305,2.203,2.305,0.771s1.024-1.077,2.285,0.787c1.885,2.787,3.676,5.431,5.59,8.258
137 c1.265,1.865,2.093,1.946,1.86,0.18c-0.236-1.767-0.139-3.406,0.212-3.659c0.351-0.257,1.714,1.012,3.04,2.831
138 c0.755,1.032,1.505,2.064,2.256,3.097c1.326,1.82,2.844,2.844,3.293,2.216c0.465-0.648,0.51-0.959,0.53-1.27
139 c0.012-0.171-0.139-0.354-0.123-0.525c0.005-0.065,0.09-0.119,0.241-0.221c0.15-0.102,1.75,0.877,3.578,2.195
140 c1.248,0.897,2.514,1.815,3.818,2.754c1.828,1.317,3.224,1.562,3.117,0.551c-0.105-1.012,1.498-1.135,3.562-0.232
141 c1.782,0.779,3.479,1.469,5.242,1.746c4.517,0.718,9.393-0.147,13.705,1.089c8.629,2.469,15.851-1.326,21.596-5.899
142 c3.603-2.868,6.98-3.644,10.901-3.998c2.244-0.204,5.397-1.53,7.034-3.081c2.244-2.13,4.545-4.316,6.72-6.377
143 c1.632-1.55,2.179-4.459,1.167-6.475c-2.525-5.035-5.292-9.417-10.698-11.021c-2.158-0.641-3.178-1.338-2.142-2.207
144 s0.049-1.575-2.203-1.575c-0.629,0-1.236,0-1.828,0c-2.252,0-4.08-0.114-4.084-0.257s0.881-0.494,1.982-0.787
145 c1.102-0.294,0.339-1.302-1.705-2.252c-0.612-0.282-1.212-0.563-1.812-0.841c-2.044-0.946-2.905-1.909-1.922-2.142
146 c0.983-0.237,0.172-1.298-1.812-2.371c-3.741-2.031-7.495-4.08-11.293-6.055c-0.8-0.416-1.661-0.714-2.677-1.04
147 c-1.514-0.485-1.778-1.175-0.6-1.522c1.179-0.343,1.085-1.122-0.204-1.737c-1.289-0.616-1.102-1.31,0.424-1.547
148 c1.526-0.236,1.073-1.126-1.007-1.987c-1.751-0.722-3.489-1.439-5.149-2.125c-2.081-0.861-3.044-2.534-2.081-3.676
149 c0.865-1.028,1.498-1.808,1.318-2.273c-0.481-1.244-1.176-2.402-1.954-3.59c-1.241-1.881-1.629-3.362-0.841-3.329
150 c0.787,0.032,1.138-0.897,0.791-2.077c-0.212-0.714-0.407-1.428-0.555-2.15c-0.897-4.394-0.856-9.232-2.766-13.117
151 c-2.611-5.316-2.102-9.433,0.832-13.121c1.403-1.763,3.187-2.407,3.574-1.808c0.392,0.6,1.403-0.269,2.256-1.941
152 c0.856-1.673,1.759-2.521,2.016-1.897s1.645-0.27,3.097-1.991c1.208-1.432,2.439-2.893,3.692-4.378
153 c1.452-1.722,2.885-2.428,3.19-1.574c0.311,0.853,1.208-0.168,2.228-2.18c5.104-10.094,13.729-18.106,15.725-29.62
154 c0.008-0.049,0.106-0.086,0.216-0.118c0.135-0.041,0.734,0.379,1.335,0.942c0.6,0.562,1.599-0.734,2.231-2.897
155 c3.525-12.117,6.936-23.852,10.416-35.813c0.629-2.163,2.293-5.341,3.615-7.165c6.536-8.979,8.209-15.063,8.434-18.649
156 c0.143-2.248-1.987-5.153-3.187-7.062c-2.362-3.762-1.856-7.776-2.163-11.706c-0.416-5.271,0.168-10.62,0.608-15.862
157 c0.188-2.244,0.534-3.958,1.012-3.741c0.474,0.216,0.457-1.416,0.498-3.668c0.167-9.657,8.706-12.102,15.973-15.137
158 c2.081-0.869,5.316-2.204,7.3-2.832c1.252-0.396,2.436-0.873,3.354-1.656c2.591-2.207,4.488-5.243,6.617-7.98
159 c1.946-2.501,4.293-4.35,6.879-6.263c4.419-3.264,7.598-8.164,11.539-12.13c3.271-3.288,6.658-6.561,10.42-9.241
160 c4.79-3.407,5.814-9.878,2.436-15.043C532.355,246.691,529.156,241.407,526.834,235.822z)"},
161 { "Fish",
162 R"(M522.697,299.679c13.88-10.49,25.688-19.413,38.038-28.744c-1.648-2.281-2.497-4.243-3.979-5.374
163 c-26.703-20.388-53.346-40.865-80.294-60.931c-26.104-19.437-56.994-25.949-88.075-32.102c-5.618-1.114-10.882-5.141-15.77-8.588
164 c-12.089-8.535-23.321-18.434-36.01-25.883c-5.459-3.207-13.676-1.706-22.428-2.509c-0.098,0.404-0.804,3.256-1.726,6.989
165 c-4.035-2.469-7.446-4.554-11.359-6.948c-0.244,4.247-0.452,7.833-0.722,12.497c-3.582-0.661-6.504-1.204-9.775-1.807
166 c-1.311,4.088-2.636,8.229-4.224,13.17c-4.197-1.774-7.491-3.17-11.326-4.794c-1.188,4.056-2.366,8.07-3.807,12.991
167 c-4.635-1.428-8.36-2.579-12.791-3.945c-0.849,11.473-7.107,11.844-11.685,9.176c-6.997,2.737-10.902,4.451-14.929,5.806
168 c-14.17,4.77-28.531,9.013-42.542,14.202c-17.871,6.622-35.472,13.97-55.786,22.041c1.342,9.065,3.011,20.322,4.753,32.057
169 c-15.386,2.427-31.298,1.057-46.087-10.375c-16.071-12.428-32.771-24.284-50.278-34.537c-10.865-6.361-23.745-9.278-35.72-13.742
170 c-0.567,1.232-1.134,2.464-1.701,3.692c2.57,6.471,6.173,12.742,7.479,19.458c2.326,11.958,3.786,24.149,4.61,36.312
171 c0.722,10.669-0.763,21.51,0.225,32.134c1.673,18.014-2.375,34.569-10.025,50.579c-1.75,3.664-3.345,7.401-6.765,15.011
172 c11.481-2.216,20.714-2.183,28.201-5.781c21.269-10.225,42.95-20.277,62.391-33.46c27.14-18.401,52.22-7.903,78.079,0.946
173 c0.763,0.262,1.044,1.926,2.497,4.839c-25.296,1.755-23.097,19.27-22.334,36.622c0.318,7.263-1.604,14.619-2.676,23.31
174 c15.369,0.212,29.16-6.933,42.656-14.606c6.32-3.595,11.473-9.69,20.123-5.929c1.604,0.697,4.924-0.959,6.671-2.443
175 c10.273-8.74,20.11-6.59,31.877-1.89c30.914,12.342,63.416,15.9,96.598,12.954c3.149-0.277,6.345-0.037,13.056-0.037
176 c-15.263,6.822-12.57,15.644-8.801,25.872c4.831,13.112,7.956,26.854,12.392,42.33c3.391-3.844,7.479-6.761,9.184-10.706
177 c7.716-17.83,15.549-35.692,21.633-54.105c2.333-7.066,4.859-9.755,11.954-10.987c37.969-6.581,75.994-13.007,113.665-21.064
178 c13.97-2.987,27.111-10.062,40.424-15.749c2.555-1.094,4.158-4.419,6.198-6.716c-2.763-2.109-5.305-5.594-8.327-6.075
179 C545.79,301.29,535.933,300.849,522.697,299.679z)"},
180 { "Turtle",
181 R"(M565.399,246.059c0.196-6.079-4.357-10.624-10.514-10.812c-2.342-0.069-4.696-0.143-7.034,0.012
182 c-1.824,0.123-3.619,0.094-5.394-0.041c-0.412-0.094-0.837-0.135-1.273-0.11c-6.581-0.689-12.885-2.803-19.322-4.529
183 c-5.117-1.371-10.764-0.795-16.174-1.057c-0.697-0.033-1.42,0.27-2.105,0.188c-5.177-0.608-9.559,1.163-13.284,4.582
184 c-2.488,2.285-5.373,3.093-8.617,3.093c-7.221,0-14.442,0-21.562,0c-1.714-5.443-3.366-10.881-5.055-16.3
185 c-2.134-9.311-5.316-18.307-9.466-26.81c-4.876-11.208-11.09-21.677-19.458-31.008c-9.249-10.311-20.416-17.887-32.203-24.823
186 c-8.915-5.247-17.784-10.608-26.341-16.41c-6.675-4.528-12.889-9.747-19.208-14.786c-6.259-4.994-13.692-7.503-21.024-10.212
187 c-7.393-2.729-14.88-5.214-22.326-7.813c-6.426-2.244-12.754-4.839-19.302-6.626c-4.092-1.118-8.568-1.644-12.783-1.314
188 c-4.524,0.355-9.017,1.808-13.407,3.158c-12.056,3.705-24.088,7.503-36.063,11.46c-11.995,3.962-23.978,3.142-36.251,1.326
189 c-11.501-1.701-23.105-2.052-34.851-0.535c-11.539,1.489-20.331,6.92-28.258,14.835c-4.243,4.235-8.743,8.111-13.472,11.673
190 c-9.078,4.664-17.858,9.768-26.01,15.704c-3.46,1.616-7.062,2.95-10.588,4.435c-7.833,3.296-12.317,9.874-16.487,16.777
191 c-6.414,10.612-11.346,21.938-14.872,33.75c-2.774,9.303-4.304,18.976-6.446,28.47c-1.448,6.435-2.88,12.914-9.996,15.786
192 c-2.603,1.053-5.182,2.17-7.789,3.219c-0.559,0.225-1.098,0.478-1.62,0.743c-1.64,0.571-3.28,1.138-4.921,1.709
193 c-0.449-0.024-0.901-0.049-1.35-0.069c-1.102-0.065-2.163,0.126-3.15,0.498c-0.212,0.041-0.424,0.094-0.637,0.151
194 c-4.675,1.285-7.927,6.52-6.41,11.29c4.288,13.472,11.123,25.944,20,36.748c0.037,0.062,0.069,0.122,0.106,0.184
195 c2.982,5.039,7.438,9.355,11.775,13.415c6.202,5.81,5.977,5.455,3.603,13.542c-2.138,7.274-4.941,14.431-5.177,22.239
196 c-0.196,6.353,1.909,12.069,3.696,17.937c0.094,0.306,0.188,0.615,0.282,0.922c0,0.021,0.004,0.045,0.008,0.065
197 c0.135,0.979,0.453,1.954,0.89,2.904c0.996,3.313,1.954,6.639,2.726,10.005c0.559,2.447,0.224,4.622-0.755,6.531
198 c-0.625,0.67-1.146,1.429-1.55,2.253c-0.637,0.722-1.367,1.399-2.187,2.023c-4.549,3.468-7.654,7.503-7.405,13.668
199 c0.13,3.223,1.897,5.218,3.852,7.226c2.485,2.55,5.259,4.826,7.634,7.467c3.717,4.137,8.445,5.94,13.741,5.871
200 c6.711-0.086,12.448,2.248,17.516,6.263c3.733,2.958,7.401,2.949,11.102,0.571c3.798-2.444,7.417-2.469,11.62-1.004
201 c3.17,1.105,6.72,1.118,10.098,1.619c2.24,0.335,3.888-0.347,4.88-1.615c0.241-0.249,0.453-0.522,0.636-0.832
202 c0.661-1.126,0.767-2.444,0.412-3.627c-0.082-0.751-0.257-1.526-0.547-2.313c-0.6-1.633-1.424-3.19-2.044-4.807
203 c-0.122-0.914-0.383-1.804-0.771-2.647c-0.478-2.375-0.375-4.655,0.143-6.843c2.261-3.35,4.08-6.984,5.443-10.783
204 c3.905-7.507,3.644-15.562,2.733-23.811c-0.098-0.873-0.204-1.742-0.297-2.469c2.533,0.453,5.067,0.901,7.601,1.354
205 c5.529,1.771,11.126,3.558,16.781,5.137c3.464,0.967,6.969,1.787,10.498,2.514c6.324,1.66,12.791,2.7,19.323,3.007
206 c1.84,0.208,3.68,0.412,5.516,0.628c6.916,0.816,13.823,1.812,20.767,2.289c7.605,0.526,15.243,0.624,22.869,0.775
207 c5.74,0.114,5.577,0.098,7.993,5.169c0.494,1.032,1.048,2.04,1.624,3.031c1.188,2.514,2.33,5.047,3.436,7.602
208 c1.081,2.664,2.122,5.341,3.113,8.037c0.29,3.717-0.596,7.394-3.239,10.927c-2.848,3.807-5.692,7.621-8.47,11.477
209 c-4.806,6.659-6.124,14.027-4.072,21.935c0.334,1.297,1.293,2.55,2.256,3.541c5.304,5.455,10.677,10.845,16.083,16.202
210 c0.767,0.763,1.758,1.42,2.766,1.791c4.594,1.693,9.38,2.876,12.403,7.393c0.64,0.959,2.697,1.249,4.129,1.339
211 c0.171,0.012,0.338,0.028,0.506,0.04c1.313,0.779,2.909,0.983,4.402,0.661c1.995,0.449,3.954,1.081,5.981,1.897
212 c3.015,1.216,7.609,2.203,11.077-1.021c1.146-1.064,2.811-1.546,4.096-2.492c1.22-0.897,2.448-1.384,3.725-1.302
213 c0.853,0.396,1.738,0.706,2.636,0.935c7.947,4.084,16.111-1.347,20.396-5.811c1.865-1.941,2.077-5.765,0.429-8.486
214 c-1.322-2.183-2.737-4.309-4.166-6.43c-1.391-2.497-2.782-4.994-4.174-7.487c-0.611-2.713,0.307-5.169,2.819-7.923
215 c7.189-7.858,13.501-16.304,18.548-25.741c2.469-4.614,2.99-9.563,3.529-14.479c0.146-1.334,0.265-2.673,0.375-4.011
216 c0.307-1.538,0.408-3.084,0.327-4.606c0.257-4.309,0.411-8.625,0.628-12.934c0.081-1.656,0.682-2.199,2.374-2.366
217 c9.038-0.901,18.111-1.632,27.071-3.064c10.608-1.697,21.139-3.921,31.648-6.181c3.599-0.775,7.07-2.224,10.515-3.582
218 c2.611-1.032,4.528-0.845,5.63,0.596c0.188,1.465,0.56,2.88,1.094,4.255c0.44,6.969,0.562,13.97,1.281,20.906
219 c0.616,5.978,1.86,11.897,3.007,17.805c0.253,1.306,1.008,2.746,1.971,3.647c1.652,1.551,3.011,3.256,4.17,5.067
220 c0.432,0.768,0.877,1.53,1.334,2.285c1.636,3.056,2.855,6.332,4.051,9.633c0.359,1.889,0.976,3.68,1.918,5.279
221 c0.151,0.392,0.302,0.783,0.465,1.171c2.317,5.614,7.34,6.178,13.917,5.753c2.669-0.171,5.41-0.143,8.042,0.273
222 c3.06,0.481,5.998,1.718,9.054,2.216c3.986,0.652,7.731-0.44,11.42-2.073c0.583-0.257,1.228-0.469,1.897-0.62
223 c0.534,0.168,1.093,0.282,1.668,0.331c1.562,0.139,3.113,0.114,4.644-0.041c2.28,0.098,4.394-0.425,6.373-1.502
224 c2.031-0.767,3.97-1.786,5.772-3.027c1.339-0.367,2.746-0.506,4.276-0.403c3.554,0.236,7.132,0.057,10.702,0.053
225 c0.566,0,1.109-0.065,1.636-0.18c0.975-0.102,1.877-0.514,2.647-1.13c2.893-1.95,4.293-5.757,2.521-9.221
226 c-0.27-0.53-0.571-1.057-0.885-1.579c-0.421-1.354-1.253-2.591-2.407-3.342c-0.882-1.02-1.845-1.95-2.877-2.717
227 c-6.642-4.929-11.722-10.775-13.496-19.009c-0.657-3.048-1.081-6.186-1.24-9.299c-0.314-6.083-0.649-12.187-0.478-18.266
228 c0.326-11.542-2.313-21.999-8.642-31.375c-2.023-3.84-4.524-7.405-7.471-10.588c-0.979-1.546-1.934-3.093-2.921-4.586
229 c0.832-0.905,1.66-1.815,2.488-2.722c3.668-2.79,8.124-3.378,12.461-3.855c5.618-0.62,10-3.431,14.3-6.564
230 c2.697-1.963,4.97-4.549,7.781-6.291c5.218-3.235,11.236-4.166,17.209-5.092c10.755-1.673,21.375-3.688,30.556-10.185
231 c5.01-3.541,7.58-8.747,9.225-14.198c2.023-6.69,3.149-13.668,4.438-20.567c0.033-0.179,0.062-0.362,0.09-0.546
232 c0.245-0.584,0.453-1.188,0.629-1.812l0.546-4.068c0-0.763-0.057-1.521-0.171-2.268
233 C565.33,247.536,565.375,246.798,565.399,246.059z)"},
234 };
235
236 /*
237 * Helper function that gets the all of the t-values that need to be added between
238 * one t-value on a path to the next, from a sorted queue |tValuesToAdd|. Converts
239 * the value from its proportion across the whole line to it's proportion relative
240 * to the current segment.
241 */
getTValuesForSegment(std::deque<float> * tValuesToAdd,float t,float tNext)242 std::vector<SkScalar> getTValuesForSegment(std::deque<float>* tValuesToAdd, float t, float tNext) {
243 std::vector<SkScalar> tVector;
244 while (!tValuesToAdd->empty() && tValuesToAdd->front() > t && tValuesToAdd->front() < tNext) {
245 SkScalar total_t = tValuesToAdd->front();
246 tValuesToAdd->pop_front();
247 SkScalar relative_t = (total_t - t) / (tNext - t);
248 tVector.push_back(relative_t);
249 }
250 return tVector;
251 }
252
253 /*
254 * Helper function that takes a vector of t-values and chops a cubic at those correct
255 * values, added it to the path |out|.
256 */
addSegmentsFromTValues(const SkPoint cubic_pts[4],std::vector<SkScalar> t_values,SkPath * out)257 void addSegmentsFromTValues(const SkPoint cubic_pts[4], std::vector<SkScalar> t_values, SkPath* out) {
258 const size_t arr_size = t_values.size();
259 const int dst_size = (3*arr_size) + 4;
260 std::vector<SkPoint> split_pts(dst_size);
261 SkChopCubicAt(cubic_pts, split_pts.data(), t_values.data(), arr_size);
262
263 for (size_t i = 0; i < arr_size + 1; i++) {
264 out->cubicTo(split_pts[(i*3)+1], split_pts[(i*3)+2], split_pts[(i*3)+3]);
265 }
266 }
267
268 /*
269 * Helper function that given a path, it's t-values (sorted), and t-values to add
270 * (sorted), returns a new path that is all cubic beziers, with verbs at each of
271 * those t-values.
272 */
createPathFromTValues(const SkPath & in,std::deque<float> tValuesToAdd,std::vector<float> tValues,SkPath * out)273 bool createPathFromTValues(const SkPath& in, std::deque<float> tValuesToAdd, std::vector<float> tValues, SkPath* out) {
274 SkPath::Iter iter(in, false);
275 bool fBreak = false;
276
277 // Only increment if we draw on the path.
278 size_t t_value_idx = 0;
279
280 for (;;) {
281 if (fBreak) break;
282 bool needToSplit = false;
283 SkPoint pts[4];
284 SkPath::Verb verb = iter.next(pts);
285
286 // The last t-value is always the end of the path (when t=1).
287 if (t_value_idx >= tValues.size() - 1) {
288 break;
289 }
290 // t and tNext are the start and end of the current segment.
291 float t = tValues[t_value_idx];
292 float tNext = tValues[t_value_idx+1];
293
294 // Check if current tValueToAdd is on this current segment.
295 if (!tValuesToAdd.empty() && tValuesToAdd.front() > t && tValuesToAdd.front() < tNext) {
296 needToSplit = true;
297 }
298
299 switch (verb) {
300 case SkPath::kMove_Verb:
301 // Only supports one contour currently.
302 out->moveTo(pts[0]);
303 break;
304 case SkPath::kLine_Verb: {
305 t_value_idx++;
306 SkPoint pt1, pt2;
307 pt1 = pts[0]*(1.0f / 3.0f) + pts[1]*(2.0f / 3.0f);
308 pt2 = pts[0]*(2.0f / 3.0f) + pts[1]*(1.0f / 3.0f);
309 if (!needToSplit) {
310 out->cubicTo(pt1, pt2, pts[1]);
311 } else {
312 std::vector<SkScalar> tVector = getTValuesForSegment(&tValuesToAdd, t, tNext);
313 const SkPoint cubic_pts[4] = {pts[0], pt1, pt2, pts[1]};
314 addSegmentsFromTValues(cubic_pts, tVector, out);
315 }
316 break;
317 }
318 case SkPath::kQuad_Verb: {
319 t_value_idx++;
320 SkPoint pt1, pt2;
321 pt1 = pts[0] + (pts[1]-pts[0])*(2.0f / 3.0f);
322 pt2 = pts[2] + (pts[1]-pts[2])*(2.0f / 3.0f);
323 if (!needToSplit) {
324 out->cubicTo(pt1, pt2, pts[2]);
325 } else {
326 std::vector<SkScalar> tVector = getTValuesForSegment(&tValuesToAdd, t, tNext);
327 const SkPoint cubic_pts[4] = {pts[0], pt1, pt2, pts[2]};
328 addSegmentsFromTValues(cubic_pts, tVector, out);
329 }
330 break;
331 }
332 case SkPath::kCubic_Verb:
333 t_value_idx++;
334 if (!needToSplit) {
335 out->cubicTo(pts[1], pts[2], pts[3]);
336 } else {
337 std::vector<SkScalar> tVector = getTValuesForSegment(&tValuesToAdd, t, tNext);
338 addSegmentsFromTValues(pts, tVector, out);
339 }
340 break;
341 case SkPath::kConic_Verb:
342 // Conic not yet supported.
343 return false;
344 case SkPath::kClose_Verb:
345 // Close not yet supported.
346 out->close();
347 break;
348 case SkPath::kDone_Verb:
349 fBreak = true;
350 }
351 }
352 return true;
353 }
354
355 /*
356 * Helper function to get the total lengths the verbs take of a path and put it
357 * into a vector.
358 */
getTValues(const SkPath & path)359 std::vector<SkScalar> getTValues(const SkPath& path) {
360 std::vector<SkScalar> tValues;
361 SkPathMeasure measure(path, false);
362 SkScalar length = measure.getLength();
363 if (length <= 0) {
364 SkDebugf("Length of path is 0.\n");
365 return tValues;
366 }
367 const SkContourMeasure* cmeasure = measure.currentMeasure();
368 tValues.push_back(0.0f);
369 for (const auto vmeasure: *cmeasure) {
370 tValues.push_back(vmeasure.fDistance / length);
371 }
372
373 if (measure.nextContour()) {
374 SkDebugf("Path has more than 1 contour.\n");
375 return {};
376 }
377 return tValues;
378 }
379
380 /*
381 * Helper function that creates a deque from a sorted vector |original| and adds
382 * values from a sorted vector |additional| in sorted order.
383 */
getTValuesToAdd(std::vector<SkScalar> original,std::vector<SkScalar> additional)384 std::deque<float> getTValuesToAdd(std::vector<SkScalar> original, std::vector<SkScalar> additional) {
385 std::deque<float> tValuesToAdd;
386 size_t i = 0, j = 0;
387 while (i < original.size() && j < additional.size()) {
388 if (additional[j] < original[i]) {
389 tValuesToAdd.push_back(additional[j]);
390 j++;
391 } else if (additional[j] > original[i]) {
392 i++;
393 } else { // additional[j] == original[i]
394 i++;
395 j++;
396 }
397 }
398 while (j < additional.size()) {
399 tValuesToAdd.push_back(additional[j]);
400 j++;
401 }
402 return tValuesToAdd;
403 }
404
405 /*
406 * Extension to SkPath::Interpolate function that takes two arbitrary SkPaths.
407 *
408 * The current functionality of SkPath::Interpolate requires that the two paths
409 * have identical verbs (same number of verbs and verb types). This function does
410 * preprocessing on the two paths to create two new paths that fit this requirement
411 * without modifying the original path.
412 *
413 * The function uses a list of t-values to determine where to place points along
414 * the path, and adds more of these points based on the other paths values. Then all
415 * verbs are converted to cubic functions. When t-values need to be added, the cubic
416 * is chopped at the correct positions in accordance to the t-values.
417 *
418 * TODO: Add support for multiple contours, conic verbs, and close verbs.
419 * TODO: Fix phrasing as we don't use actual t-values of the curves just proportional
420 * distances(?)
421 */
generalInterpolate(const SkPath & beginning,const SkPath & ending,SkScalar weight,SkPath * out)422 bool generalInterpolate(const SkPath& beginning, const SkPath& ending, SkScalar weight, SkPath* out) {
423 // Use existing path interpolation if possible.
424 if (beginning.isInterpolatable(ending)) {
425 return beginning.interpolate(ending, weight, out);
426 }
427
428 // TODO: Check if isValid()?
429 if (beginning.isEmpty() || !beginning.isFinite() || ending.isEmpty() || !ending.isFinite()) {
430 return false;
431 }
432
433 // New paths to store the transformed paths.
434 SkPath beginningCubic;
435 SkPath endingCubic;
436 beginningCubic.reset();
437 endingCubic.reset();
438
439 // Append the total distances up to each verb in the path into a vector.
440 std::vector<SkScalar> tValues1 = getTValues(beginning);
441 std::vector<SkScalar> tValues2 = getTValues(ending);
442 if (tValues1.empty() || tValues2.empty()) {
443 return false;
444 }
445
446 // The t-values to add for the respective paths from the other.
447 std::deque<float> tValuesToAdd1 = getTValuesToAdd(tValues1, tValues2);
448 std::deque<float> tValuesToAdd2 = getTValuesToAdd(tValues2, tValues1);
449
450 // Form the cubic versions of each path with the new points along it.
451 createPathFromTValues(beginning, tValuesToAdd1, tValues1, &beginningCubic);
452 createPathFromTValues(ending, tValuesToAdd2, tValues2, &endingCubic);
453
454 return beginningCubic.interpolate(endingCubic, weight, out);
455 }
456
457 class PathLerpSlide final : public Slide {
458 public:
PathLerpSlide()459 PathLerpSlide()
460 : fTimeMapper({0.5f, 0}, {0.5f, 1}) {
461 fName = "PathLerp";
462 }
463
464 private:
load(SkScalar w,SkScalar h)465 void load(SkScalar w, SkScalar h) override {
466 fSize = {w, h};
467
468 this->updateAnimatingPaths();
469 }
470
resize(SkScalar w,SkScalar h)471 void resize(SkScalar w, SkScalar h) override { fSize = {w, h}; }
472
draw(SkCanvas * canvas)473 void draw(SkCanvas* canvas) override {
474 SkPaint path_paint;
475 path_paint.setColor(0xff424242);
476 path_paint.setStyle(SkPaint::kStroke_Style);
477 path_paint.setAntiAlias(true);
478 path_paint.setStrokeCap(SkPaint::kRound_Cap);
479 path_paint.setStrokeWidth(10 / fPathTransform.getScaleX());
480
481 SkAutoCanvasRestore acr(canvas, true);
482 canvas->concat(fPathTransform);
483 canvas->drawPath(fInterpolatedPath, path_paint);
484
485 const auto draw_vertices = [this](SkCanvas* canvas, const SkPath& path, float opacity) {
486 SkPaint vertex_paint, ctrl_paint;
487 vertex_paint.setColor4f({1, 0, 0, opacity});
488 vertex_paint.setAntiAlias(true);
489 ctrl_paint.setColor4f({0, 0, 1, opacity});
490 ctrl_paint.setAntiAlias(true);
491
492 const float vertex_radius = 6 / fPathTransform.getScaleX(),
493 ctrl_radius = 4 / fPathTransform.getScaleX();
494
495 for (const auto [verb, pts, weights] : SkPathPriv::Iterate(path)) {
496 switch (verb) {
497 case SkPathVerb::kMove: // pts: [ vertex ]
498 canvas->drawCircle(pts[0], vertex_radius, vertex_paint);
499 break;
500 case SkPathVerb::kLine: // pts: [ prev_vertex, vertex ]
501 canvas->drawCircle(pts[1], vertex_radius, vertex_paint);
502 break;
503 case SkPathVerb::kQuad: // pts: [ prev_vertex, ctrl, vertex ]
504 canvas->drawCircle(pts[1], ctrl_radius, ctrl_paint);
505 canvas->drawCircle(pts[2], vertex_radius, vertex_paint);
506 break;
507 case SkPathVerb::kCubic: // pts: [ prev_vertex, ctrl0, ctrl1, vertex ]
508 canvas->drawCircle(pts[1], ctrl_radius, ctrl_paint);
509 canvas->drawCircle(pts[2], ctrl_radius, ctrl_paint);
510 canvas->drawCircle(pts[3], vertex_radius, vertex_paint);
511 break;
512 case SkPathVerb::kConic: // pts: [ prev_vertex, ctrl, vertex ]
513 canvas->drawCircle(pts[1], ctrl_radius, ctrl_paint);
514 canvas->drawCircle(pts[2], vertex_radius, vertex_paint);
515 break;
516 case SkPathVerb::kClose: // pts: []
517 break;
518 }
519 }
520 };
521
522 if (fShowVertices) {
523 draw_vertices(canvas, fInterpolatedPath, 1);
524
525 // also show the input paths & vertices
526 path_paint.setAlphaf(.15f);
527 path_paint.setStrokeWidth(3 / fPathTransform.getScaleX());
528
529 canvas->drawPath(fPaths.first , path_paint);
530 canvas->drawPath(fPaths.second, path_paint);
531 draw_vertices(canvas, fPaths.first , .15f);
532 draw_vertices(canvas, fPaths.second, .15f);
533 }
534
535 this->drawControls();
536 }
537
animate(double nanos)538 bool animate(double nanos) override {
539 if (!fTimeBase) {
540 fTimeBase = nanos;
541 }
542
543 if (fDraggingProgress) {
544 // When progress is controlled by dragging the slidebar, adjust the time base such
545 // that the animation continues seamlessly when the slider is released.
546
547 // what the (signed) progress should be according to the clock
548 const float clock_progress_signed =
549 std::fmod((nanos - fTimeBase)*0.000000001*fAnimationSpeed, 2) - 1;
550 // what progress should be to match the slidebar
551 const float clock_progress_adjusted =
552 std::copysign(fCurrentProgress, clock_progress_signed);
553 // what the clock should be to match the slidebar
554 const float nanos_adjusted = (clock_progress_adjusted + 1)*1000000000/fAnimationSpeed;
555
556 fTimeBase = nanos - nanos_adjusted;
557 } else {
558 // Oscillating between 0..1
559 fCurrentProgress =
560 std::abs((std::fmod((nanos - fTimeBase)*0.000000001*fAnimationSpeed, 2) - 1));
561 }
562
563 // Interpolate with easing
564 // TODO: generate the synthetic paths once, in updateAnimatingPaths(), then use
565 // regular interpolation here.
566 return generalInterpolate(fPaths.first,
567 fPaths.second,
568 fTimeMapper.computeYFromX(fCurrentProgress),
569 &fInterpolatedPath);
570 }
571
onChar(SkUnichar c)572 bool onChar(SkUnichar c) override {
573 switch (c) {
574 case 'v':
575 fShowVertices = !fShowVertices;
576 return true;
577 default:
578 return false;
579 }
580 }
581
onMouse(SkScalar x,SkScalar y,skui::InputState state,skui::ModifierKey)582 bool onMouse(SkScalar x, SkScalar y, skui::InputState state, skui::ModifierKey) override {
583 // Show the progress slider when hovering the bottom third.
584 fShowSlider = y > fSize.height() * .66f;
585
586 return false;
587 }
588
updateAnimatingPaths()589 void updateAnimatingPaths() {
590 SkPath p0, p1;
591 SkAssertResult(SkParsePath::FromSVGString(fSelectedPaths[0]->fSVGString, &p0));
592 SkAssertResult(SkParsePath::FromSVGString(fSelectedPaths[1]->fSVGString, &p1));
593
594 const SkRect b0 = p0.computeTightBounds(),
595 b1 = p1.computeTightBounds();
596
597 // Transform all paths to a normalized size, such that they occupy roughly the same space.
598 static constexpr SkRect kNormRect = {0, 0, 512, 512};
599
600 fPaths = {
601 p0.transform(SkMatrix::MakeRectToRect(b0, kNormRect, SkMatrix::kCenter_ScaleToFit)),
602 p1.transform(SkMatrix::MakeRectToRect(b1, kNormRect, SkMatrix::kCenter_ScaleToFit)),
603 };
604
605
606 // Scale and center such that the path animation fills 90% of the view.
607 SkRect bounds = p0.computeTightBounds();
608 bounds.join(p1.computeTightBounds());
609
610 const SkRect dst_rect = SkRect::MakeSize(fSize)
611 .makeInset(fSize.width() * .05f, fSize.height() * .05f);
612 fPathTransform =
613 SkMatrix::MakeRectToRect(kNormRect, dst_rect, SkMatrix::kCenter_ScaleToFit);
614 }
615
drawControls()616 void drawControls() {
617 // path controls
618 if (ImGui::Begin("Path Options")) {
619 for (size_t i = 0; i < 2; ++i) {
620 const SkString label = SkStringPrintf("Path %zu", i + 1);
621 if (ImGui::BeginCombo(label.c_str(), fSelectedPaths[i]->fName)) {
622 for (const auto& path_desc : gSamplePaths) {
623 const auto is_selected = (fSelectedPaths[i] == &path_desc);
624 if (ImGui::Selectable(path_desc.fName) && !is_selected) {
625 fSelectedPaths[i] = &path_desc;
626 this->updateAnimatingPaths();
627 }
628 if (is_selected) {
629 ImGui::SetItemDefaultFocus();
630 }
631 }
632 ImGui::EndCombo();
633 }
634 }
635
636 ImGui::Checkbox("Show vertices", &fShowVertices);
637
638 }
639 ImGui::End();
640
641 if (!fShowSlider) {
642 return;
643 }
644
645 // progress slider
646 ImGui::SetNextWindowBgAlpha(.75f);
647 if (ImGui::Begin("Progress Slider", nullptr, ImGuiWindowFlags_NoDecoration |
648 ImGuiWindowFlags_NoResize |
649 ImGuiWindowFlags_NoMove |
650 ImGuiWindowFlags_NoSavedSettings |
651 ImGuiWindowFlags_NoFocusOnAppearing |
652 ImGuiWindowFlags_NoNav)) {
653 static constexpr float kSliderHeight = 100;
654 ImGui::SetWindowPos({0, fSize.height() - kSliderHeight});
655 ImGui::SetWindowSize({fSize.width(), kSliderHeight});
656
657 ImGui::PushItemWidth(-1);
658 ImGui::SliderFloat("", &fCurrentProgress, 0, 1, nullptr, ImGuiSliderFlags_NoInput);
659 fDraggingProgress = ImGui::IsItemActive();
660 ImGui::PopItemWidth();
661 }
662 ImGui::End();
663 }
664
665 SkSize fSize = {0,0};
666 std::pair<SkPath, SkPath> fPaths; // currently morphing paths
667 SkPath fInterpolatedPath;
668 SkMatrix fPathTransform = SkMatrix::I();
669
670 float fAnimationSpeed = 1.f;
671 double fTimeBase = 0;
672 const SkCubicMap fTimeMapper; // for animation easing
673 float fCurrentProgress = 0; // Interpolation progress [0..1]
674
675 // UI stuff
676 const PathDesc* fSelectedPaths[2] = {&gSamplePaths[0], &gSamplePaths[1]};
677 bool fDraggingProgress = false;
678 bool fShowVertices = false;
679 bool fShowSlider = false;
680 };
681
682 } // namespace
683
684 DEF_SLIDE(return new PathLerpSlide();)
685
686
687