| /* |
| * Copyright 2024 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include <cmath> |
| #include <utility> |
| #include <deque> |
| #include <vector> |
| |
| #include "include/core/SkCanvas.h" |
| #include "include/core/SkCubicMap.h" |
| #include "include/core/SkMatrix.h" |
| #include "include/core/SkPaint.h" |
| #include "include/core/SkPath.h" |
| #include "include/core/SkPathMeasure.h" |
| #include "include/core/SkPathTypes.h" |
| #include "include/core/SkSize.h" |
| #include "include/core/SkString.h" |
| #include "include/private/SkPathRef.h" |
| #include "include/private/base/SkAssert.h" |
| #include "include/utils/SkParsePath.h" |
| #include "src/core/SkGeometry.h" |
| #include "src/core/SkPathPriv.h" |
| #include "tools/viewer/Slide.h" |
| |
| #include "imgui.h" |
| |
| namespace { |
| |
| static constexpr struct PathDesc { |
| const char* fName; |
| const char* fSVGString; |
| } gSamplePaths[] = { |
| { "Arc 1", "M0,0.5 Q0,0 0.5,0 Q1,0 1,0.5"}, |
| { "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"}, |
| { "Pentagon", |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 8.27108L10.1192 4.09438Z)"}, |
| { "Droplet", |
| 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 |
| 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 |
| C8.36301 20.7625 10.1435 21.5 12 21.5V21.5Z)"}, |
| { "Shield", |
| 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 |
| 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 |
| C20 8 20 6 20 6Z)"}, |
| { "Spiral", |
| 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 |
| 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 |
| C301,7881.75 300.552,7881 300,7881 L288,7881 C287.448,7881 287,7881.75 287,7882.302 L287,7896.302 |
| C287,7896.854 287.448,7897 288,7897 L302,7897 C302.552,7897 303,7897.524 303,7898.076 L303,7898.151 |
| C303,7898.703 302.552,7899 302,7899 L287,7899 C285.896,7899 285,7898.407 285,7897.302 L285,7881.302 |
| C285,7880.197 285.896,7879 287,7879 L301,7879 C302.105,7879 303,7880.197 303,7881.302 L303,7893.302 |
| C303,7894.407 302.105,7895 301,7895 L291,7895 C289.896,7895 289,7894.407 289,7893.302 L289,7885.302 |
| C289,7884.197 289.896,7883 291,7883 L297,7883 C298.105,7883 299,7884.197 299,7885.302 L299,7889.302 |
| C299,7890.407 298.105,7891 297,7891 L295,7891 C293.896,7891 293,7890.407 293,7889.302 L293,7888.302 |
| C293,7887.75 293.448,7887.302 294,7887.302 C294.552,7887.302 295,7887.75 295,7888.302 |
| C295,7888.854 295.448,7889.302 296,7889.302 C296.552,7889.302 297,7888.854 297,7888.302)"}, |
| { "Cat", |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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)" }, |
| { "Rabit", |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| c4.79-3.407,5.814-9.878,2.436-15.043C532.355,246.691,529.156,241.407,526.834,235.822z)"}, |
| { "Fish", |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| C545.79,301.29,535.933,300.849,522.697,299.679z)"}, |
| { "Turtle", |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| C565.33,247.536,565.375,246.798,565.399,246.059z)"}, |
| }; |
| |
| /* |
| * Helper function that gets the all of the t-values that need to be added between |
| * one t-value on a path to the next, from a sorted queue |tValuesToAdd|. Converts |
| * the value from its proportion across the whole line to it's proportion relative |
| * to the current segment. |
| */ |
| std::vector<SkScalar> getTValuesForSegment(std::deque<float>* tValuesToAdd, float t, float tNext) { |
| std::vector<SkScalar> tVector; |
| while (!tValuesToAdd->empty() && tValuesToAdd->front() > t && tValuesToAdd->front() < tNext) { |
| SkScalar total_t = tValuesToAdd->front(); |
| tValuesToAdd->pop_front(); |
| SkScalar relative_t = (total_t - t) / (tNext - t); |
| tVector.push_back(relative_t); |
| } |
| return tVector; |
| } |
| |
| /* |
| * Helper function that takes a vector of t-values and chops a cubic at those correct |
| * values, added it to the path |out|. |
| */ |
| void addSegmentsFromTValues(const SkPoint cubic_pts[4], std::vector<SkScalar> t_values, SkPath* out) { |
| const size_t arr_size = t_values.size(); |
| const int dst_size = (3*arr_size) + 4; |
| std::vector<SkPoint> split_pts(dst_size); |
| SkChopCubicAt(cubic_pts, split_pts.data(), t_values.data(), arr_size); |
| |
| SkPathBuilder builder; |
| for (size_t i = 0; i < arr_size + 1; i++) { |
| builder.cubicTo(split_pts[(i*3)+1], split_pts[(i*3)+2], split_pts[(i*3)+3]); |
| } |
| *out = builder.detach(); |
| } |
| |
| /* |
| * Helper function that given a path, it's t-values (sorted), and t-values to add |
| * (sorted), returns a new path that is all cubic beziers, with verbs at each of |
| * those t-values. |
| */ |
| bool createPathFromTValues(const SkPath& in, std::deque<float> tValuesToAdd, std::vector<float> tValues, SkPath* out) { |
| SkPath::Iter iter(in, false); |
| bool fBreak = false; |
| |
| // Only increment if we draw on the path. |
| size_t t_value_idx = 0; |
| SkPathBuilder builder; |
| |
| for (;;) { |
| if (fBreak) break; |
| bool needToSplit = false; |
| SkPoint pts[4]; |
| SkPath::Verb verb = iter.next(pts); |
| |
| // The last t-value is always the end of the path (when t=1). |
| if (t_value_idx >= tValues.size() - 1) { |
| break; |
| } |
| // t and tNext are the start and end of the current segment. |
| float t = tValues[t_value_idx]; |
| float tNext = tValues[t_value_idx+1]; |
| |
| // Check if current tValueToAdd is on this current segment. |
| if (!tValuesToAdd.empty() && tValuesToAdd.front() > t && tValuesToAdd.front() < tNext) { |
| needToSplit = true; |
| } |
| |
| switch (verb) { |
| case SkPath::kMove_Verb: |
| // Only supports one contour currently. |
| builder.moveTo(pts[0]); |
| break; |
| case SkPath::kLine_Verb: { |
| t_value_idx++; |
| SkPoint pt1, pt2; |
| pt1 = pts[0]*(1.0f / 3.0f) + pts[1]*(2.0f / 3.0f); |
| pt2 = pts[0]*(2.0f / 3.0f) + pts[1]*(1.0f / 3.0f); |
| if (!needToSplit) { |
| builder.cubicTo(pt1, pt2, pts[1]); |
| } else { |
| std::vector<SkScalar> tVector = getTValuesForSegment(&tValuesToAdd, t, tNext); |
| const SkPoint cubic_pts[4] = {pts[0], pt1, pt2, pts[1]}; |
| addSegmentsFromTValues(cubic_pts, tVector, out); |
| } |
| break; |
| } |
| case SkPath::kQuad_Verb: { |
| t_value_idx++; |
| SkPoint pt1, pt2; |
| pt1 = pts[0] + (pts[1]-pts[0])*(2.0f / 3.0f); |
| pt2 = pts[2] + (pts[1]-pts[2])*(2.0f / 3.0f); |
| if (!needToSplit) { |
| builder.cubicTo(pt1, pt2, pts[2]); |
| } else { |
| std::vector<SkScalar> tVector = getTValuesForSegment(&tValuesToAdd, t, tNext); |
| const SkPoint cubic_pts[4] = {pts[0], pt1, pt2, pts[2]}; |
| addSegmentsFromTValues(cubic_pts, tVector, out); |
| } |
| break; |
| } |
| case SkPath::kCubic_Verb: |
| t_value_idx++; |
| if (!needToSplit) { |
| builder.cubicTo(pts[1], pts[2], pts[3]); |
| } else { |
| std::vector<SkScalar> tVector = getTValuesForSegment(&tValuesToAdd, t, tNext); |
| addSegmentsFromTValues(pts, tVector, out); |
| } |
| break; |
| case SkPath::kConic_Verb: |
| // Conic not yet supported. |
| return false; |
| case SkPath::kClose_Verb: |
| // Close not yet supported. |
| builder.close(); |
| break; |
| case SkPath::kDone_Verb: |
| fBreak = true; |
| } |
| } |
| *out = builder.detach(); |
| return true; |
| } |
| |
| /* |
| * Helper function to get the total lengths the verbs take of a path and put it |
| * into a vector. |
| */ |
| std::vector<SkScalar> getTValues(const SkPath& path) { |
| std::vector<SkScalar> tValues; |
| SkPathMeasure measure(path, false); |
| SkScalar length = measure.getLength(); |
| if (length <= 0) { |
| SkDebugf("Length of path is 0.\n"); |
| return tValues; |
| } |
| const SkContourMeasure* cmeasure = measure.currentMeasure(); |
| tValues.push_back(0.0f); |
| for (const auto vmeasure: *cmeasure) { |
| tValues.push_back(vmeasure.fDistance / length); |
| } |
| |
| if (measure.nextContour()) { |
| SkDebugf("Path has more than 1 contour.\n"); |
| return {}; |
| } |
| return tValues; |
| } |
| |
| /* |
| * Helper function that creates a deque from a sorted vector |original| and adds |
| * values from a sorted vector |additional| in sorted order. |
| */ |
| std::deque<float> getTValuesToAdd(std::vector<SkScalar> original, std::vector<SkScalar> additional) { |
| std::deque<float> tValuesToAdd; |
| size_t i = 0, j = 0; |
| while (i < original.size() && j < additional.size()) { |
| if (additional[j] < original[i]) { |
| tValuesToAdd.push_back(additional[j]); |
| j++; |
| } else if (additional[j] > original[i]) { |
| i++; |
| } else { // additional[j] == original[i] |
| i++; |
| j++; |
| } |
| } |
| while (j < additional.size()) { |
| tValuesToAdd.push_back(additional[j]); |
| j++; |
| } |
| return tValuesToAdd; |
| } |
| |
| /* |
| * Extension to SkPath::Interpolate function that takes two arbitrary SkPaths. |
| * |
| * The current functionality of SkPath::Interpolate requires that the two paths |
| * have identical verbs (same number of verbs and verb types). This function does |
| * preprocessing on the two paths to create two new paths that fit this requirement |
| * without modifying the original path. |
| * |
| * The function uses a list of t-values to determine where to place points along |
| * the path, and adds more of these points based on the other paths values. Then all |
| * verbs are converted to cubic functions. When t-values need to be added, the cubic |
| * is chopped at the correct positions in accordance to the t-values. |
| * |
| * TODO: Add support for multiple contours, conic verbs, and close verbs. |
| * TODO: Fix phrasing as we don't use actual t-values of the curves just proportional |
| * distances(?) |
| */ |
| bool generalInterpolate(const SkPath& beginning, const SkPath& ending, SkScalar weight, SkPath* out) { |
| // Use existing path interpolation if possible. |
| if (beginning.isInterpolatable(ending)) { |
| return beginning.interpolate(ending, weight, out); |
| } |
| |
| // TODO: Check if isValid()? |
| if (beginning.isEmpty() || !beginning.isFinite() || ending.isEmpty() || !ending.isFinite()) { |
| return false; |
| } |
| |
| // New paths to store the transformed paths. |
| SkPath beginningCubic; |
| SkPath endingCubic; |
| beginningCubic.reset(); |
| endingCubic.reset(); |
| |
| // Append the total distances up to each verb in the path into a vector. |
| std::vector<SkScalar> tValues1 = getTValues(beginning); |
| std::vector<SkScalar> tValues2 = getTValues(ending); |
| if (tValues1.empty() || tValues2.empty()) { |
| return false; |
| } |
| |
| // The t-values to add for the respective paths from the other. |
| std::deque<float> tValuesToAdd1 = getTValuesToAdd(tValues1, tValues2); |
| std::deque<float> tValuesToAdd2 = getTValuesToAdd(tValues2, tValues1); |
| |
| // Form the cubic versions of each path with the new points along it. |
| createPathFromTValues(beginning, tValuesToAdd1, tValues1, &beginningCubic); |
| createPathFromTValues(ending, tValuesToAdd2, tValues2, &endingCubic); |
| |
| return beginningCubic.interpolate(endingCubic, weight, out); |
| } |
| |
| class PathLerpSlide final : public Slide { |
| public: |
| PathLerpSlide() |
| : fTimeMapper({0.5f, 0}, {0.5f, 1}) { |
| fName = "PathLerp"; |
| } |
| |
| private: |
| void load(SkScalar w, SkScalar h) override { |
| fSize = {w, h}; |
| |
| this->updateAnimatingPaths(); |
| } |
| |
| void resize(SkScalar w, SkScalar h) override { fSize = {w, h}; } |
| |
| void draw(SkCanvas* canvas) override { |
| SkPaint path_paint; |
| path_paint.setColor(0xff424242); |
| path_paint.setStyle(SkPaint::kStroke_Style); |
| path_paint.setAntiAlias(true); |
| path_paint.setStrokeCap(SkPaint::kRound_Cap); |
| path_paint.setStrokeWidth(10 / fPathTransform.getScaleX()); |
| |
| SkAutoCanvasRestore acr(canvas, true); |
| canvas->concat(fPathTransform); |
| canvas->drawPath(fInterpolatedPath, path_paint); |
| |
| const auto draw_vertices = [this](SkCanvas* canvas, const SkPath& path, float opacity) { |
| SkPaint vertex_paint, ctrl_paint; |
| vertex_paint.setColor4f({1, 0, 0, opacity}); |
| vertex_paint.setAntiAlias(true); |
| ctrl_paint.setColor4f({0, 0, 1, opacity}); |
| ctrl_paint.setAntiAlias(true); |
| |
| const float vertex_radius = 6 / fPathTransform.getScaleX(), |
| ctrl_radius = 4 / fPathTransform.getScaleX(); |
| |
| for (const auto [verb, pts, weights] : SkPathPriv::Iterate(path)) { |
| switch (verb) { |
| case SkPathVerb::kMove: // pts: [ vertex ] |
| canvas->drawCircle(pts[0], vertex_radius, vertex_paint); |
| break; |
| case SkPathVerb::kLine: // pts: [ prev_vertex, vertex ] |
| canvas->drawCircle(pts[1], vertex_radius, vertex_paint); |
| break; |
| case SkPathVerb::kQuad: // pts: [ prev_vertex, ctrl, vertex ] |
| canvas->drawCircle(pts[1], ctrl_radius, ctrl_paint); |
| canvas->drawCircle(pts[2], vertex_radius, vertex_paint); |
| break; |
| case SkPathVerb::kCubic: // pts: [ prev_vertex, ctrl0, ctrl1, vertex ] |
| canvas->drawCircle(pts[1], ctrl_radius, ctrl_paint); |
| canvas->drawCircle(pts[2], ctrl_radius, ctrl_paint); |
| canvas->drawCircle(pts[3], vertex_radius, vertex_paint); |
| break; |
| case SkPathVerb::kConic: // pts: [ prev_vertex, ctrl, vertex ] |
| canvas->drawCircle(pts[1], ctrl_radius, ctrl_paint); |
| canvas->drawCircle(pts[2], vertex_radius, vertex_paint); |
| break; |
| case SkPathVerb::kClose: // pts: [] |
| break; |
| } |
| } |
| }; |
| |
| if (fShowVertices) { |
| draw_vertices(canvas, fInterpolatedPath, 1); |
| |
| // also show the input paths & vertices |
| path_paint.setAlphaf(.15f); |
| path_paint.setStrokeWidth(3 / fPathTransform.getScaleX()); |
| |
| canvas->drawPath(fPaths.first , path_paint); |
| canvas->drawPath(fPaths.second, path_paint); |
| draw_vertices(canvas, fPaths.first , .15f); |
| draw_vertices(canvas, fPaths.second, .15f); |
| } |
| |
| this->drawControls(); |
| } |
| |
| bool animate(double nanos) override { |
| if (!fTimeBase) { |
| fTimeBase = nanos; |
| } |
| |
| if (fDraggingProgress) { |
| // When progress is controlled by dragging the slidebar, adjust the time base such |
| // that the animation continues seamlessly when the slider is released. |
| |
| // what the (signed) progress should be according to the clock |
| const float clock_progress_signed = |
| std::fmod((nanos - fTimeBase)*0.000000001*fAnimationSpeed, 2) - 1; |
| // what progress should be to match the slidebar |
| const float clock_progress_adjusted = |
| std::copysign(fCurrentProgress, clock_progress_signed); |
| // what the clock should be to match the slidebar |
| const float nanos_adjusted = (clock_progress_adjusted + 1)*1000000000/fAnimationSpeed; |
| |
| fTimeBase = nanos - nanos_adjusted; |
| } else { |
| // Oscillating between 0..1 |
| fCurrentProgress = |
| std::abs((std::fmod((nanos - fTimeBase)*0.000000001*fAnimationSpeed, 2) - 1)); |
| } |
| |
| // Interpolate with easing |
| // TODO: generate the synthetic paths once, in updateAnimatingPaths(), then use |
| // regular interpolation here. |
| return generalInterpolate(fPaths.first, |
| fPaths.second, |
| fTimeMapper.computeYFromX(fCurrentProgress), |
| &fInterpolatedPath); |
| } |
| |
| bool onChar(SkUnichar c) override { |
| switch (c) { |
| case 'v': |
| fShowVertices = !fShowVertices; |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| bool onMouse(SkScalar x, SkScalar y, skui::InputState state, skui::ModifierKey) override { |
| // Show the progress slider when hovering the bottom third. |
| fShowSlider = y > fSize.height() * .66f; |
| |
| return false; |
| } |
| |
| void updateAnimatingPaths() { |
| auto p0 = SkParsePath::FromSVGString(fSelectedPaths[0]->fSVGString); |
| auto p1 = SkParsePath::FromSVGString(fSelectedPaths[1]->fSVGString); |
| SkAssertResult(p0.has_value()); |
| SkAssertResult(p1.has_value()); |
| |
| const SkRect b0 = p0->computeTightBounds(), |
| b1 = p1->computeTightBounds(); |
| |
| // Transform all paths to a normalized size, such that they occupy roughly the same space. |
| static constexpr SkRect kNormRect = {0, 0, 512, 512}; |
| |
| fPaths = { |
| p0->makeTransform(SkMatrix::RectToRectOrIdentity(b0, kNormRect, |
| SkMatrix::kCenter_ScaleToFit)), |
| p1->makeTransform(SkMatrix::RectToRectOrIdentity(b1, kNormRect, |
| SkMatrix::kCenter_ScaleToFit)), |
| }; |
| |
| |
| // Scale and center such that the path animation fills 90% of the view. |
| SkRect bounds = fPaths.first.computeTightBounds(); |
| bounds.join(fPaths.second.computeTightBounds()); |
| |
| const SkRect dst_rect = SkRect::MakeSize(fSize) |
| .makeInset(fSize.width() * .05f, fSize.height() * .05f); |
| fPathTransform = |
| SkMatrix::RectToRectOrIdentity(kNormRect, dst_rect, SkMatrix::kCenter_ScaleToFit); |
| } |
| |
| void drawControls() { |
| // path controls |
| if (ImGui::Begin("Path Options")) { |
| for (size_t i = 0; i < 2; ++i) { |
| const SkString label = SkStringPrintf("Path %zu", i + 1); |
| if (ImGui::BeginCombo(label.c_str(), fSelectedPaths[i]->fName)) { |
| for (const auto& path_desc : gSamplePaths) { |
| const auto is_selected = (fSelectedPaths[i] == &path_desc); |
| if (ImGui::Selectable(path_desc.fName) && !is_selected) { |
| fSelectedPaths[i] = &path_desc; |
| this->updateAnimatingPaths(); |
| } |
| if (is_selected) { |
| ImGui::SetItemDefaultFocus(); |
| } |
| } |
| ImGui::EndCombo(); |
| } |
| } |
| |
| ImGui::Checkbox("Show vertices", &fShowVertices); |
| |
| } |
| ImGui::End(); |
| |
| if (!fShowSlider) { |
| return; |
| } |
| |
| // progress slider |
| ImGui::SetNextWindowBgAlpha(.75f); |
| if (ImGui::Begin("Progress Slider", nullptr, ImGuiWindowFlags_NoDecoration | |
| ImGuiWindowFlags_NoResize | |
| ImGuiWindowFlags_NoMove | |
| ImGuiWindowFlags_NoSavedSettings | |
| ImGuiWindowFlags_NoFocusOnAppearing | |
| ImGuiWindowFlags_NoNav)) { |
| static constexpr float kSliderHeight = 100; |
| ImGui::SetWindowPos({0, fSize.height() - kSliderHeight}); |
| ImGui::SetWindowSize({fSize.width(), kSliderHeight}); |
| |
| ImGui::PushItemWidth(-1); |
| ImGui::SliderFloat("", &fCurrentProgress, 0, 1, nullptr, ImGuiSliderFlags_NoInput); |
| fDraggingProgress = ImGui::IsItemActive(); |
| ImGui::PopItemWidth(); |
| } |
| ImGui::End(); |
| } |
| |
| SkSize fSize = {0,0}; |
| std::pair<SkPath, SkPath> fPaths; // currently morphing paths |
| SkPath fInterpolatedPath; |
| SkMatrix fPathTransform = SkMatrix::I(); |
| |
| float fAnimationSpeed = 1.f; |
| double fTimeBase = 0; |
| const SkCubicMap fTimeMapper; // for animation easing |
| float fCurrentProgress = 0; // Interpolation progress [0..1] |
| |
| // UI stuff |
| const PathDesc* fSelectedPaths[2] = {&gSamplePaths[0], &gSamplePaths[1]}; |
| bool fDraggingProgress = false; |
| bool fShowVertices = false; |
| bool fShowSlider = false; |
| }; |
| |
| } // namespace |
| |
| DEF_SLIDE(return new PathLerpSlide();) |
| |
| |