From df3dec90182ac6b7ccea5ff7fea0207cfb4eb8cb Mon Sep 17 00:00:00 2001 From: Quinton Ashley Date: Fri, 27 Sep 2024 12:54:23 -0500 Subject: [PATCH] 2.5.0 --- .npmignore | 1 + README.md | 7 +- fonts/YaHei-256-msdf.json | 1 + fonts/YaHei-256.png | Bin 0 -> 72947 bytes fonts/YaHei-msdf.json | 1 + fonts/YaHei.png | Bin 0 -> 206821 bytes package.json | 2 +- q5.d.ts | 31 +- q5.js | 880 +++++++++++++++++++++++++++++++------- q5.min.js | 2 +- src/q5-2d-canvas.js | 9 - src/q5-2d-text.js | 29 +- src/q5-canvas.js | 18 +- src/q5-core.js | 4 +- src/q5-util.js | 18 +- src/q5-webgpu-canvas.js | 141 +++--- src/q5-webgpu-drawing.js | 34 +- src/q5-webgpu-image.js | 22 +- src/q5-webgpu-text.js | 605 ++++++++++++++++++++++++-- src/readme.md | 83 +++- 20 files changed, 1582 insertions(+), 306 deletions(-) create mode 100644 fonts/YaHei-256-msdf.json create mode 100644 fonts/YaHei-256.png create mode 100644 fonts/YaHei-msdf.json create mode 100644 fonts/YaHei.png diff --git a/.npmignore b/.npmignore index b678632..a3d91eb 100644 --- a/.npmignore +++ b/.npmignore @@ -2,6 +2,7 @@ CNAME assets demos dev +fonts home lang learn diff --git a/README.md b/README.md index e7be442..93f29d9 100644 --- a/README.md +++ b/README.md @@ -339,13 +339,13 @@ Unminified: - p5.js **5112kb** ⚠️ - p5.sound.js 488kb -- q5.js 93kb +- q5.js 110kb Minified: - p5.min.js 1034kb ⚠️ - p5.sound.min.js 200kb -- q5.min.js **61kb** 🎉 +- q5.min.js **70kb** 🎉 ## Benchmarks @@ -404,6 +404,9 @@ p5.js is licensed under the LGPLv2, the two small sections of p5' code directly ## Credits +q5-webgpu msdf text rendering: +https://webgpu.github.io/webgpu-samples/?sample=textRenderingMsdf + q5-webgpu blendMode: https://webgpufundamentals.org/webgpu/lessons/webgpu-transparency.html diff --git a/fonts/YaHei-256-msdf.json b/fonts/YaHei-256-msdf.json new file mode 100644 index 0000000..52de609 --- /dev/null +++ b/fonts/YaHei-256-msdf.json @@ -0,0 +1 @@ +{"pages":["YaHei-256.png"],"chars":"id index char width height xoffset yoffset xadvance chnl x y page\n106 80 \"j\" 16 48 -6 3 11 15 0 0 0\n87 61 \"W\" 46 36 -1 4 43 15 0 49 0\n81 55 \"Q\" 35 45 0 4 34 15 17 0 0\n64 38 \"@\" 40 40 2 4 43 15 0 86 0\n98 72 \"b\" 25 38 2 2 27 15 0 127 0\n100 74 \"d\" 25 38 0 2 27 15 0 166 0\n102 76 \"f\" 18 38 -1 2 15 15 0 205 0\n103 77 \"g\" 25 38 0 13 27 15 19 205 0\n104 78 \"h\" 23 38 2 2 26 15 26 127 0\n107 81 \"k\" 23 38 2 2 23 15 26 166 0\n108 82 \"l\" 8 38 2 2 11 15 41 86 0\n112 86 \"p\" 25 38 2 13 27 15 47 46 0\n113 87 \"q\" 25 38 0 13 27 15 53 0 0\n48 22 \"0\" 25 37 0 4 25 15 45 205 0\n51 25 \"3\" 23 37 1 4 25 15 50 85 0\n54 28 \"6\" 24 37 0 4 25 15 73 39 0\n56 30 \"8\" 24 37 0 4 25 15 79 0 0\n57 31 \"9\" 24 37 0 4 25 15 50 123 0\n67 41 \"C\" 28 37 0 4 28 15 50 161 0\n71 45 \"G\" 30 37 0 4 31 15 74 77 0\n77 51 \"M\" 37 36 2 4 41 15 98 38 0\n79 53 \"O\" 34 37 0 4 34 15 104 0 0\n83 57 \"S\" 24 37 1 4 24 15 75 115 0\n105 79 \"i\" 9 37 1 3 11 15 71 199 0\n109 83 \"m\" 37 27 2 13 39 15 79 153 0\n121 95 \"y\" 26 37 -2 13 22 15 100 115 0\n33 7 \"!\" 9 36 2 4 13 15 105 75 0\n49 23 \"1\" 22 36 2 4 25 15 115 75 0\n50 24 \"2\" 24 36 0 4 25 15 136 38 0\n52 26 \"4\" 27 36 -2 4 25 15 139 0 0\n53 27 \"5\" 22 36 2 4 25 15 81 181 0\n55 29 \"7\" 25 36 0 4 25 15 81 218 0\n65 39 \"A\" 33 36 -2 4 30 15 104 181 0\n66 40 \"B\" 24 36 2 4 26 15 107 218 0\n68 42 \"D\" 30 36 2 4 32 15 132 218 0\n69 43 \"E\" 21 36 2 4 23 15 127 112 0\n70 44 \"F\" 20 36 2 4 22 15 138 75 0\n72 46 \"H\" 28 36 2 4 32 15 138 149 0\n73 47 \"I\" 14 36 -1 4 12 15 149 112 0\n74 48 \"J\" 16 36 -2 4 17 15 159 75 0\n75 49 \"K\" 27 36 2 4 27 15 164 112 0\n76 50 \"L\" 21 36 2 4 22 15 161 37 0\n78 52 \"N\" 30 36 2 4 34 15 167 0 0\n80 54 \"P\" 24 36 2 4 26 15 176 74 0\n82 56 \"R\" 27 36 2 4 27 15 183 37 0\n84 58 \"T\" 26 36 -1 4 24 15 198 0 0\n85 59 \"U\" 28 36 2 4 31 15 225 0 0\n86 60 \"V\" 32 36 -2 4 28 15 211 37 0\n88 62 \"X\" 30 36 -1 4 27 15 201 74 0\n89 63 \"Y\" 29 36 -2 4 25 15 163 186 0\n90 64 \"Z\" 28 36 -1 4 26 15 167 149 0\n119 93 \"w\" 36 27 -1 13 33 15 163 223 0\n116 90 \"t\" 18 34 -1 7 16 15 193 186 0\n58 32 \":\" 9 28 0 13 10 15 127 149 0\n97 71 \"a\" 22 28 0 13 23 15 232 74 0\n99 73 \"c\" 21 28 0 13 21 15 138 186 0\n101 75 \"e\" 24 28 0 13 24 15 232 103 0\n111 85 \"o\" 27 28 0 13 27 15 200 221 0\n115 89 \"s\" 19 28 0 13 19 15 212 111 0\n110 84 \"n\" 23 27 2 13 26 15 232 132 0\n114 88 \"r\" 16 27 2 13 16 15 192 111 0\n117 91 \"u\" 23 27 1 13 26 15 228 160 0\n118 92 \"v\" 26 27 -2 13 22 15 228 188 0\n120 94 \"x\" 24 27 -1 13 21 15 228 216 0\n122 96 \"z\" 23 27 -1 13 21 15 196 140 0\n45 19 \"-\" 16 7 1 22 18 15 0 244 0\n44 18 \",\" 10 15 -1 31 10 15 220 140 0\n39 13 \"'\" 8 14 1 4 11 15 71 237 0\n34 8 \"\\\"\" 14 14 2 4 18 15 212 168 0\n46 20 \".\" 9 9 0 31 10 15 117 153 0","info":{"face":"YaHei-256","size":42},"common":{"lineHeight":45,"base":36,"scaleW":256,"scaleH":256},"kernings":"first second amount\n39 114 -1\n39 115 -1\n34 114 -1\n34 115 -1\n65 44 1\n65 67 -1\n65 71 -1\n65 74 2\n65 79 -1\n65 84 -3\n65 85 -1\n65 86 -3\n65 87 -2\n65 89 -3\n65 90 1\n65 116 -1\n65 118 -1\n65 119 -1\n65 121 -1\n66 84 -2\n66 89 -1\n67 67 -1\n67 71 -1\n67 79 -1\n67 81 -1\n68 44 -3\n68 46 -3\n68 65 -1\n68 84 -2\n68 88 -1\n68 90 -1\n69 65 0\n69 74 1\n69 84 0\n69 87 1\n69 88 0\n70 44 -3\n70 46 -3\n70 65 -3\n70 74 -1\n70 83 -1\n70 84 0\n70 97 -2\n70 102 0\n71 84 -1\n71 86 -1\n71 121 -1\n74 44 -2\n74 46 -2\n74 65 -1\n74 74 -1\n74 97 -1\n75 44 1\n75 67 -2\n75 71 -2\n75 74 2\n75 79 -2\n75 81 -2\n75 88 1\n75 90 1\n75 99 -1\n75 100 -1\n75 101 -1\n75 103 -1\n75 111 -1\n75 113 -1\n75 116 -1\n75 118 -2\n75 119 -1\n75 121 -2\n76 65 1\n76 67 -1\n76 71 -1\n76 74 2\n76 79 -2\n76 81 -2\n76 84 -3\n76 85 -1\n76 86 -3\n76 87 -1\n76 89 -3\n76 90 1\n76 116 -1\n76 118 -2\n76 119 -1\n76 121 -2\n79 44 -2\n79 46 -2\n79 65 -1\n79 74 0\n79 84 -2\n79 88 -1\n79 89 -1\n79 90 -1\n80 44 -7\n80 46 -7\n80 65 -4\n80 71 0\n80 74 -3\n80 87 1\n80 88 -1\n80 97 -1\n80 99 -2\n80 100 -2\n80 101 -2\n80 103 -2\n80 111 -2\n80 113 -2\n81 44 -2\n81 46 -3\n81 65 -1\n81 84 -2\n81 88 -1\n81 89 0\n81 90 -1\n82 67 -1\n82 71 -1\n82 74 1\n82 79 0\n82 81 0\n82 84 -1\n82 89 -1\n82 99 -1\n82 100 -1\n82 101 -1\n82 103 -1\n82 111 -1\n82 113 -1\n83 116 -1\n83 118 -1\n83 119 -1\n83 121 -1\n84 44 -3\n84 46 -4\n84 58 -1\n84 65 -3\n84 67 -2\n84 71 -2\n84 74 -3\n84 79 -2\n84 81 -2\n84 84 1\n84 86 1\n84 87 1\n84 88 0\n84 89 1\n84 97 -5\n84 99 -5\n84 100 -5\n84 101 -5\n84 102 -2\n84 103 -5\n84 109 -4\n84 110 -4\n84 111 -5\n84 112 -4\n84 113 -5\n84 114 -4\n84 115 -3\n84 117 -4\n84 118 -2\n84 119 -3\n84 120 -4\n84 121 -3\n84 122 -3\n85 65 -1\n86 44 -5\n86 46 -5\n86 65 -3\n86 67 -1\n86 71 -1\n86 74 -2\n86 79 0\n86 81 -1\n86 83 -1\n86 84 1\n86 97 -3\n86 99 -3\n86 100 -3\n86 101 -3\n86 103 -3\n86 109 -2\n86 110 -2\n86 111 -3\n86 112 -2\n86 113 -3\n86 114 -2\n86 115 -1\n86 117 -2\n87 44 -3\n87 46 -3\n87 65 -2\n87 84 1\n87 97 -2\n87 99 -1\n87 100 -1\n87 101 -1\n87 103 -1\n87 111 -1\n87 113 -1\n88 44 1\n88 46 1\n88 67 -1\n88 71 -1\n88 74 2\n88 79 -1\n88 81 -1\n88 84 1\n89 44 -4\n89 46 -4\n89 65 -4\n89 67 -1\n89 71 -1\n89 74 -1\n89 79 -1\n89 81 -1\n89 83 -1\n89 84 1\n89 97 -4\n89 99 -4\n89 100 -4\n89 101 -4\n89 102 -1\n89 103 -4\n89 109 -3\n89 110 -3\n89 111 -4\n89 112 -3\n89 113 -4\n89 114 -3\n89 115 -3\n89 117 -3\n90 74 2\n90 84 1\n90 121 -1\n98 97 -1\n98 102 0\n98 120 -1\n99 74 2\n99 84 -2\n99 89 -2\n101 39 -2\n101 34 -2\n102 44 -3\n102 45 -2\n102 46 -3\n102 58 2\n102 98 0\n102 104 0\n102 116 1\n102 118 1\n102 119 1\n102 120 0\n102 121 1\n103 106 1\n106 106 1\n107 44 2\n107 45 -3\n107 46 2\n107 58 2\n107 99 -1\n107 100 -1\n107 101 -1\n107 103 -1\n107 111 -1\n107 113 -1\n107 116 0\n110 39 -2\n110 34 -2\n111 39 -3\n111 34 -3\n111 97 -1\n111 102 -1\n111 120 -1\n112 97 -1\n112 102 -1\n112 120 -1\n113 106 2\n114 44 -4\n114 45 -3\n114 46 -4\n114 58 2\n114 99 -1\n114 100 -1\n114 101 -1\n114 102 1\n114 103 -1\n114 109 0\n114 110 0\n114 111 -1\n114 113 -1\n114 115 0\n114 116 1\n114 118 2\n114 119 2\n114 120 1\n114 121 2\n114 122 1\n116 45 -3\n116 99 -1\n116 100 -1\n116 101 0\n116 103 0\n116 111 0\n116 113 0\n116 120 1\n117 39 -1\n117 34 -1\n118 44 -3\n118 46 -3\n118 97 -1\n118 99 0\n118 100 0\n118 101 0\n118 103 0\n118 111 0\n118 113 0\n119 44 -2\n119 46 -2\n119 99 0\n119 100 0\n119 101 0\n119 103 0\n119 111 0\n119 113 0\n120 99 0\n120 100 0\n120 101 0\n120 103 0\n120 111 0\n120 113 0\n121 39 1\n121 34 1\n121 44 -2\n121 46 -3\n121 99 0\n121 100 0\n121 101 0\n121 102 0\n121 103 0\n121 111 0\n121 113 0\n121 116 0"} \ No newline at end of file diff --git a/fonts/YaHei-256.png b/fonts/YaHei-256.png new file mode 100644 index 0000000000000000000000000000000000000000..e721d32c977f8afd076bf2e08b98ee5263def459 GIT binary patch literal 72947 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 literal 0 HcmV?d00001 diff --git a/fonts/YaHei-msdf.json b/fonts/YaHei-msdf.json new file mode 100644 index 0000000..1ad4da9 --- /dev/null +++ b/fonts/YaHei-msdf.json @@ -0,0 +1 @@ +{"pages":["YaHei.png"],"chars":"id index char width height xoffset yoffset xadvance chnl x y page\n124 98 \"|\" 8 49 2 1 11 15 0 0 0\n253 190 \"ý\" 26 49 -2 2 22 15 0 50 0\n106 80 \"j\" 16 48 -6 3 11 15 9 0 0\n254 191 \"þ\" 25 48 2 2 27 15 26 0 0\n87 61 \"W\" 46 36 -1 4 43 15 0 100 0\n192 129 \"À\" 33 46 -2 -6 30 15 27 49 0\n193 130 \"Á\" 33 46 -2 -6 30 15 52 0 0\n194 131 \"Â\" 33 46 -2 -6 30 15 0 137 0\n199 136 \"Ç\" 28 46 0 4 28 15 0 184 0\n200 137 \"È\" 21 46 2 -6 23 15 0 231 0\n201 138 \"É\" 21 46 2 -6 23 15 0 278 0\n202 139 \"Ê\" 21 46 2 -6 23 15 0 325 0\n204 141 \"Ì\" 15 46 -1 -6 12 15 0 372 0\n205 142 \"Í\" 15 46 -1 -6 12 15 0 419 0\n206 143 \"Î\" 17 46 -2 -6 12 15 0 466 0\n210 147 \"Ò\" 34 46 0 -6 34 15 16 372 0\n211 148 \"Ó\" 34 46 0 -6 34 15 16 419 0\n212 149 \"Ô\" 34 46 0 -6 34 15 18 466 0\n217 154 \"Ù\" 28 46 2 -6 31 15 22 231 0\n218 155 \"Ú\" 28 46 2 -6 31 15 29 184 0\n219 156 \"Û\" 28 46 2 -6 31 15 34 137 0\n221 158 \"Ý\" 29 46 -2 -6 25 15 61 47 0\n255 192 \"ÿ\" 26 46 -2 5 22 15 86 0 0\n81 55 \"Q\" 35 45 0 4 34 15 22 278 0\n213 150 \"Õ\" 34 45 0 -4 34 15 51 231 0\n36 10 \"$\" 22 44 1 0 25 15 58 184 0\n195 132 \"Ã\" 33 44 -2 -4 30 15 22 324 0\n209 146 \"Ñ\" 30 44 2 -4 34 15 63 94 0\n214 151 \"Ö\" 34 44 0 -3 34 15 63 139 0\n220 157 \"Ü\" 28 44 2 -3 31 15 91 47 0\n40 14 \"(\" 14 43 1 4 14 15 81 184 0\n41 15 \")\" 15 43 -2 4 14 15 113 0 0\n91 65 \"[\" 12 43 2 4 14 15 94 92 0\n93 67 \"]\" 12 43 -1 4 14 15 51 369 0\n123 97 \"{\" 15 43 0 4 14 15 56 324 0\n125 99 \"}\" 15 43 -1 4 14 15 58 277 0\n196 133 \"Ä\" 33 43 -2 -3 30 15 51 413 0\n197 134 \"Å\" 33 43 -2 -3 30 15 64 368 0\n203 140 \"Ë\" 21 43 2 -3 23 15 72 321 0\n207 144 \"Ï\" 17 43 -2 -3 12 15 74 277 0\n47 21 \"/\" 23 41 -3 4 18 15 86 228 0\n92 66 \"\\\\\" 23 41 -3 4 17 15 96 184 0\n198 135 \"Æ\" 41 36 -2 4 39 15 98 136 0\n64 38 \"@\" 40 40 2 4 43 15 107 92 0\n223 160 \"ß\" 24 39 2 2 25 15 120 44 0\n224 161 \"à\" 22 39 0 2 23 15 129 0 0\n225 162 \"á\" 22 39 0 2 23 15 92 270 0\n226 163 \"â\" 22 39 0 2 23 15 110 226 0\n229 166 \"å\" 22 39 0 1 23 15 145 40 0\n232 169 \"è\" 24 39 0 2 24 15 152 0 0\n233 170 \"é\" 24 39 0 2 24 15 120 173 0\n234 171 \"ê\" 24 39 0 2 24 15 140 133 0\n242 179 \"ò\" 27 39 0 2 27 15 148 80 0\n243 180 \"ó\" 27 39 0 2 27 15 168 40 0\n244 181 \"ô\" 27 39 0 2 27 15 177 0 0\n249 186 \"ù\" 23 39 1 2 26 15 53 457 0\n250 187 \"ú\" 23 39 1 2 26 15 77 457 0\n251 188 \"û\" 23 39 1 2 26 15 85 412 0\n37 11 \"%\" 38 37 0 4 37 15 94 310 0\n98 72 \"b\" 25 38 2 2 27 15 115 266 0\n100 74 \"d\" 25 38 0 2 27 15 133 213 0\n102 76 \"f\" 18 38 -1 2 15 15 145 173 0\n103 77 \"g\" 25 38 0 13 27 15 101 452 0\n104 78 \"h\" 23 38 2 2 26 15 98 348 0\n107 81 \"k\" 23 38 2 2 23 15 109 387 0\n108 82 \"l\" 8 38 2 2 11 15 122 348 0\n112 86 \"p\" 25 38 2 13 27 15 131 348 0\n113 87 \"q\" 25 38 0 13 27 15 133 305 0\n216 153 \"Ø\" 34 38 0 3 34 15 141 252 0\n230 167 \"æ\" 38 28 0 13 38 15 159 212 0\n236 173 \"ì\" 13 38 -2 2 11 15 164 173 0\n237 174 \"í\" 13 38 0 2 11 15 47 96 0\n238 175 \"î\" 17 38 -3 2 11 15 165 120 0\n240 177 \"ð\" 25 38 0 2 26 15 176 80 0\n38 12 \"&\" 37 37 1 4 37 15 196 40 0\n48 22 \"0\" 25 37 0 4 25 15 205 0 0\n51 25 \"3\" 23 37 1 4 25 15 231 0 0\n54 28 \"6\" 24 37 0 4 25 15 178 159 0\n56 30 \"8\" 24 37 0 4 25 15 183 119 0\n57 31 \"9\" 24 37 0 4 25 15 202 78 0\n63 37 \"?\" 19 37 1 4 20 15 127 426 0\n67 41 \"C\" 28 37 0 4 28 15 133 387 0\n71 45 \"G\" 30 37 0 4 31 15 157 344 0\n77 51 \"M\" 37 36 2 4 41 15 127 464 0\n79 53 \"O\" 34 37 0 4 34 15 147 425 0\n83 57 \"S\" 24 37 1 4 24 15 162 382 0\n105 79 \"i\" 9 37 1 3 11 15 165 463 0\n109 83 \"m\" 37 27 2 13 39 15 175 463 0\n121 95 \"y\" 26 37 -2 13 22 15 182 420 0\n169 106 \"©\" 37 37 2 4 40 15 187 382 0\n174 111 \"®\" 37 37 2 4 40 15 209 420 0\n191 128 \"¿\" 19 37 1 13 20 15 159 291 0\n227 164 \"ã\" 22 37 0 4 23 15 176 241 0\n231 168 \"ç\" 21 37 0 13 21 15 198 197 0\n245 182 \"õ\" 27 37 0 4 27 15 203 157 0\n33 7 \"!\" 9 36 2 4 13 15 208 116 0\n49 23 \"1\" 22 36 2 4 25 15 218 116 0\n50 24 \"2\" 24 36 0 4 25 15 227 78 0\n52 26 \"4\" 27 36 -2 4 25 15 234 38 0\n53 27 \"5\" 22 36 2 4 25 15 255 0 0\n55 29 \"7\" 25 36 0 4 25 15 213 458 0\n65 39 \"A\" 33 36 -2 4 30 15 239 458 0\n66 40 \"B\" 24 36 2 4 26 15 179 279 0\n68 42 \"D\" 30 36 2 4 32 15 199 235 0\n69 43 \"E\" 21 36 2 4 23 15 220 195 0\n70 44 \"F\" 20 36 2 4 22 15 231 153 0\n72 46 \"H\" 28 36 2 4 32 15 241 115 0\n73 47 \"I\" 14 36 -1 4 12 15 252 75 0\n74 48 \"J\" 16 36 -2 4 17 15 262 37 0\n75 49 \"K\" 27 36 2 4 27 15 278 0 0\n76 50 \"L\" 21 36 2 4 22 15 267 74 0\n78 52 \"N\" 30 36 2 4 34 15 279 37 0\n80 54 \"P\" 24 36 2 4 26 15 306 0 0\n82 56 \"R\" 27 36 2 4 27 15 188 316 0\n84 58 \"T\" 26 36 -1 4 24 15 204 272 0\n85 59 \"U\" 28 36 2 4 31 15 230 232 0\n86 60 \"V\" 32 36 -2 4 28 15 242 190 0\n88 62 \"X\" 30 36 -1 4 27 15 252 152 0\n89 63 \"Y\" 29 36 -2 4 25 15 270 111 0\n90 64 \"Z\" 28 36 -1 4 26 15 289 74 0\n119 93 \"w\" 36 27 -1 13 33 15 188 353 0\n161 4 \"¡\" 9 36 2 13 13 15 310 37 0\n162 5 \"¢\" 21 36 2 5 25 15 216 309 0\n163 6 \"£\" 24 36 0 4 25 15 231 269 0\n165 102 \"¥\" 26 36 -1 4 25 15 225 346 0\n208 145 \"Ð\" 33 36 -1 4 32 15 225 383 0\n222 159 \"Þ\" 24 36 2 4 26 15 247 420 0\n228 165 \"ä\" 22 36 0 5 23 15 238 306 0\n235 172 \"ë\" 24 36 0 5 24 15 256 269 0\n241 178 \"ñ\" 23 36 2 4 26 15 252 343 0\n246 183 \"ö\" 27 36 0 5 27 15 261 306 0\n252 189 \"ü\" 23 36 1 5 26 15 259 380 0\n128 0 \"€\" 26 35 2 5 29 15 276 343 0\n239 176 \"ï\" 17 35 -3 5 11 15 272 417 0\n116 90 \"t\" 18 34 -1 7 16 15 283 379 0\n35 9 \"#\" 29 33 -1 4 27 15 259 227 0\n59 33 \";\" 11 33 -1 13 10 15 275 189 0\n248 185 \"ø\" 29 31 -1 11 27 15 283 148 0\n960 362 \"π\" 31 27 -2 13 29 15 300 111 0\n58 32 \":\" 9 28 0 13 10 15 318 74 0\n97 71 \"a\" 22 28 0 13 23 15 320 37 0\n99 73 \"c\" 21 28 0 13 21 15 331 0 0\n101 75 \"e\" 24 28 0 13 24 15 281 261 0\n111 85 \"o\" 27 28 0 13 27 15 328 66 0\n115 89 \"s\" 19 28 0 13 19 15 343 29 0\n110 84 \"n\" 23 27 2 13 26 15 353 0 0\n114 88 \"r\" 16 27 2 13 16 15 287 180 0\n117 91 \"u\" 23 27 1 13 26 15 289 290 0\n118 92 \"v\" 26 27 -2 13 22 15 289 208 0\n120 94 \"x\" 24 27 -1 13 21 15 304 180 0\n122 96 \"z\" 23 27 -1 13 21 15 313 139 0\n60 34 \"<\" 23 26 4 12 31 15 332 95 0\n62 36 \">\" 23 26 4 12 31 15 306 236 0\n126 100 \"~\" 26 11 3 19 31 15 53 501 0\n247 184 \"÷\" 25 26 3 12 31 15 306 263 0\n43 17 \"+\" 25 25 3 12 31 15 316 208 0\n61 35 \"=\" 25 17 3 17 31 15 101 491 0\n94 68 \"^\" 25 23 3 4 31 15 289 318 0\n179 116 \"³\" 16 24 1 4 17 15 289 236 0\n95 69 \"_\" 23 7 -2 40 19 15 120 84 0\n178 115 \"²\" 16 23 0 4 17 15 109 426 0\n185 122 \"¹\" 16 23 1 4 16 15 313 290 0\n215 152 \"×\" 23 23 4 13 31 15 330 234 0\n186 123 \"º\" 20 21 0 4 20 15 175 491 0\n42 16 \"*\" 20 20 0 4 19 15 329 167 0\n8220 532 \"“\" 17 14 25 4 42 15 178 197 0\n8221 533 \"”\" 17 14 0 4 42 15 159 329 0\n45 19 \"-\" 16 7 1 22 18 15 148 120 0\n176 113 \"°\" 16 16 0 4 17 15 332 122 0\n44 18 \",\" 10 15 -1 31 10 15 98 387 0\n34 8 \"\\\"\" 14 14 2 4 18 15 80 497 0\n39 13 \"'\" 8 14 1 4 11 15 179 316 0\n8216 528 \"‘\" 10 14 32 4 42 15 196 495 0\n8217 529 \"’\" 10 14 0 4 42 15 207 495 0\n96 70 \"`\" 13 11 0 2 12 15 127 501 0\n180 117 \"´\" 13 11 1 2 13 15 141 501 0\n46 20 \".\" 9 9 0 31 10 15 98 173 0\n183 120 \"·\" 9 9 0 20 10 15 159 241 0","info":{"face":"YaHei","size":42},"common":{"lineHeight":45,"base":36,"scaleW":512,"scaleH":512},"kernings":"first second amount\n34 114 -1\n34 115 -1\n39 114 -1\n39 115 -1\n40 106 5\n42 65 -4\n42 74 -3\n42 99 -2\n42 100 -2\n42 101 -2\n42 103 -2\n42 111 -2\n42 113 -2\n44 8216 -5\n44 8217 -5\n44 8220 -5\n44 8221 -5\n46 8216 -5\n46 8217 -4\n46 8220 -5\n46 8221 -4\n65 42 -3\n65 44 1\n65 59 1\n65 67 -1\n65 71 -1\n65 74 2\n65 79 -1\n65 84 -3\n65 85 -1\n65 86 -3\n65 87 -2\n65 89 -3\n65 90 1\n65 116 -1\n65 118 -1\n65 119 -1\n65 121 -1\n65 8216 -3\n65 8217 -4\n65 8220 -3\n65 8221 -4\n66 84 -2\n66 89 -1\n67 63 0\n67 67 -1\n67 71 -1\n67 79 -1\n67 81 -1\n68 44 -3\n68 46 -3\n68 65 -1\n68 84 -2\n68 88 -1\n68 90 -1\n69 65 0\n69 74 1\n69 84 0\n69 87 1\n69 88 0\n70 44 -3\n70 46 -3\n70 65 -3\n70 74 -1\n70 83 -1\n70 84 0\n70 97 -2\n70 102 0\n71 84 -1\n71 86 -1\n71 121 -1\n74 44 -2\n74 46 -2\n74 65 -1\n74 74 -1\n74 97 -1\n74 224 -1\n74 225 -1\n75 44 1\n75 59 1\n75 67 -2\n75 71 -2\n75 74 2\n75 79 -2\n75 81 -2\n75 88 1\n75 90 1\n75 99 -1\n75 100 -1\n75 101 -1\n75 103 -1\n75 111 -1\n75 113 -1\n75 116 -1\n75 118 -2\n75 119 -1\n75 121 -2\n75 232 -1\n75 233 -1\n75 234 -1\n75 237 -1\n75 242 -1\n75 243 -1\n76 42 -5\n76 63 -2\n76 65 1\n76 67 -1\n76 71 -1\n76 74 2\n76 79 -2\n76 81 -2\n76 84 -3\n76 85 -1\n76 86 -3\n76 87 -1\n76 89 -3\n76 90 1\n76 116 -1\n76 118 -2\n76 119 -1\n76 121 -2\n76 8216 -3\n76 8217 -3\n76 8220 -3\n76 8221 -3\n79 44 -2\n79 46 -2\n79 65 -1\n79 74 0\n79 84 -2\n79 88 -1\n79 89 -1\n79 90 -1\n80 44 -7\n80 46 -7\n80 65 -4\n80 71 0\n80 74 -3\n80 87 1\n80 88 -1\n80 97 -1\n80 99 -2\n80 100 -2\n80 101 -2\n80 103 -2\n80 111 -2\n80 113 -2\n80 224 -1\n80 225 -1\n80 232 -2\n80 233 -2\n80 234 -2\n80 242 -2\n80 243 -2\n81 44 -2\n81 46 -3\n81 65 -1\n81 84 -2\n81 88 -1\n81 89 0\n81 90 -1\n82 59 2\n82 67 -1\n82 71 -1\n82 74 1\n82 79 0\n82 81 0\n82 84 -1\n82 89 -1\n82 99 -1\n82 100 -1\n82 101 -1\n82 103 -1\n82 111 -1\n82 113 -1\n82 232 -1\n82 233 -1\n82 234 -1\n82 242 -1\n82 243 -1\n83 116 -1\n83 118 -1\n83 119 -1\n83 121 -1\n84 44 -3\n84 46 -4\n84 58 -1\n84 59 -1\n84 65 -3\n84 67 -2\n84 71 -2\n84 74 -3\n84 79 -2\n84 81 -2\n84 84 1\n84 86 1\n84 87 1\n84 88 0\n84 89 1\n84 97 -5\n84 99 -5\n84 100 -5\n84 101 -5\n84 102 -2\n84 103 -5\n84 109 -4\n84 110 -4\n84 111 -5\n84 112 -4\n84 113 -5\n84 114 -4\n84 115 -3\n84 117 -4\n84 118 -2\n84 119 -3\n84 120 -4\n84 121 -3\n84 122 -3\n84 224 -5\n84 225 -5\n84 232 -5\n84 233 -5\n84 234 -5\n84 237 -1\n84 242 -5\n84 243 -5\n84 249 -4\n84 250 -4\n84 252 -4\n84 8217 1\n84 8221 1\n85 65 -1\n86 44 -5\n86 46 -5\n86 65 -3\n86 67 -1\n86 71 -1\n86 74 -2\n86 79 0\n86 81 -1\n86 83 -1\n86 84 1\n86 97 -3\n86 99 -3\n86 100 -3\n86 101 -3\n86 103 -3\n86 109 -2\n86 110 -2\n86 111 -3\n86 112 -2\n86 113 -3\n86 114 -2\n86 115 -1\n86 117 -2\n86 224 -3\n86 225 -3\n86 232 -3\n86 233 -3\n86 234 -3\n86 242 -3\n86 243 -3\n86 249 -2\n86 250 -2\n86 252 -2\n87 44 -3\n87 46 -3\n87 65 -2\n87 84 1\n87 97 -2\n87 99 -1\n87 100 -1\n87 101 -1\n87 103 -1\n87 111 -1\n87 113 -1\n87 224 -2\n87 225 -2\n87 232 -1\n87 233 -1\n87 234 -1\n87 242 -1\n87 243 -1\n88 44 1\n88 46 1\n88 59 2\n88 67 -1\n88 71 -1\n88 74 2\n88 79 -1\n88 81 -1\n88 84 1\n89 44 -4\n89 46 -4\n89 65 -4\n89 67 -1\n89 71 -1\n89 74 -1\n89 79 -1\n89 81 -1\n89 83 -1\n89 84 1\n89 97 -4\n89 99 -4\n89 100 -4\n89 101 -4\n89 102 -1\n89 103 -4\n89 109 -3\n89 110 -3\n89 111 -4\n89 112 -3\n89 113 -4\n89 114 -3\n89 115 -3\n89 117 -3\n89 224 -4\n89 225 -4\n89 232 -4\n89 233 -4\n89 234 -4\n89 242 -4\n89 243 -4\n89 249 -3\n89 250 -3\n89 252 -3\n90 74 2\n90 84 1\n90 121 -1\n91 106 5\n98 97 -1\n98 102 0\n98 120 -1\n98 224 -1\n98 225 -1\n99 74 2\n99 84 -2\n99 89 -2\n101 34 -2\n101 39 -2\n102 41 3\n102 44 -3\n102 45 -2\n102 46 -3\n102 58 2\n102 59 2\n102 63 1\n102 93 3\n102 98 0\n102 104 0\n102 116 1\n102 118 1\n102 119 1\n102 120 0\n102 121 1\n102 125 2\n102 236 1\n102 8216 2\n102 8217 2\n102 8220 2\n102 8221 2\n103 106 1\n106 106 1\n107 44 2\n107 45 -3\n107 46 2\n107 58 2\n107 59 2\n107 99 -1\n107 100 -1\n107 101 -1\n107 103 -1\n107 111 -1\n107 113 -1\n107 116 0\n107 232 -1\n107 233 -1\n107 234 -1\n107 242 -1\n107 243 -1\n110 34 -2\n110 39 -2\n111 34 -3\n111 39 -3\n111 97 -1\n111 102 -1\n111 120 -1\n111 224 -1\n111 225 -1\n111 8216 -1\n111 8217 -3\n111 8220 -2\n111 8221 -3\n112 97 -1\n112 102 -1\n112 120 -1\n112 224 -1\n112 225 -1\n112 8216 -3\n112 8217 -3\n112 8220 -1\n112 8221 -3\n113 106 2\n114 44 -4\n114 45 -3\n114 46 -4\n114 58 2\n114 59 2\n114 99 -1\n114 100 -1\n114 101 -1\n114 102 1\n114 103 -1\n114 109 0\n114 110 0\n114 111 -1\n114 113 -1\n114 115 0\n114 116 1\n114 118 2\n114 119 2\n114 120 1\n114 121 2\n114 122 1\n114 232 -1\n114 233 -1\n114 234 -1\n114 242 -1\n114 243 -1\n114 8216 4\n114 8217 3\n114 8220 4\n114 8221 3\n116 45 -3\n116 63 -1\n116 99 -1\n116 100 -1\n116 101 0\n116 103 0\n116 111 0\n116 113 0\n116 120 1\n116 232 0\n116 233 0\n116 234 0\n116 242 0\n116 243 0\n117 34 -1\n117 39 -1\n118 44 -3\n118 46 -3\n118 97 -1\n118 99 0\n118 100 0\n118 101 0\n118 103 0\n118 111 0\n118 113 0\n118 224 -1\n118 225 -1\n118 232 0\n118 233 0\n118 234 0\n118 242 0\n118 243 0\n119 44 -2\n119 46 -2\n119 99 0\n119 100 0\n119 101 0\n119 103 0\n119 111 0\n119 113 0\n119 232 0\n119 233 0\n119 234 0\n119 242 0\n119 243 0\n120 99 0\n120 100 0\n120 101 0\n120 103 0\n120 111 0\n120 113 0\n120 232 0\n120 233 0\n120 234 0\n120 242 0\n120 243 0\n121 34 1\n121 39 1\n121 44 -2\n121 46 -3\n121 63 -2\n121 99 0\n121 100 0\n121 101 0\n121 102 0\n121 103 0\n121 111 0\n121 113 0\n121 116 0\n121 232 0\n121 233 0\n121 234 0\n121 242 0\n121 243 0\n123 106 4\n242 97 -1\n242 102 -1\n242 120 -1\n243 97 -1\n243 102 -1\n243 120 -1\n8216 65 -5\n8216 67 -1\n8216 74 -3\n8216 84 2\n8216 99 -3\n8216 100 -4\n8216 101 -3\n8216 103 -3\n8216 111 -3\n8216 115 -2\n8216 8216 -4\n8217 44 -2\n8217 46 -2\n8217 65 -4\n8217 74 -4\n8217 84 2\n8217 97 -2\n8217 99 -4\n8217 100 -4\n8217 101 -4\n8217 103 -4\n8217 111 -4\n8217 113 -3\n8217 115 -3\n8217 8217 -4\n8220 44 -2\n8220 46 -2\n8220 65 -5\n8220 74 -4\n8220 84 2\n8220 99 -3\n8220 100 -3\n8220 101 -3\n8220 103 -3\n8220 115 -2\n8221 44 -2\n8221 46 -2\n8221 65 -3\n8221 84 2\n8221 99 -1\n8221 100 -4\n8221 101 -4\n8221 103 -4\n8221 111 -4\n8221 115 -3"} \ No newline at end of file diff --git a/fonts/YaHei.png b/fonts/YaHei.png new file mode 100644 index 0000000000000000000000000000000000000000..cb4b5f10411ea9b88b64eb4dbcba9b5b42319d46 GIT binary patch literal 206821 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%0A3r8GYkg3yH{&jk9u*} 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∨`D#x$|9U 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 void): string; /** ✍️ - * Sets the current font to be used for text elements + * Sets the current font to be used for rendering text * @param fontName - name of the font */ function textFont(fontName: string): void; @@ -812,7 +835,7 @@ declare global { * @param horiz - horizontal alignment ('left', 'center', 'right') * @param vert - vertical alignment ('top', 'middle', 'bottom', 'alphabetic') */ - function textAlign(horiz: 'left' | 'center' | 'right', vert?: 'top' | 'middle' | 'bottom' | 'alphabetic'): void; + function textAlign(horiz: 'left' | 'center' | 'right', vert?: 'top' | 'center' | 'bottom' | 'alphabetic'): void; /** ✍️ * Calculates and returns the width of a given string of text @@ -894,7 +917,7 @@ declare global { /** 🎨 * Sets the color mode for the sketch. Changes the type of color object created by color functions. - * + * * In WebGPU, the default color mode is 'rgb' in float format. * @param mode - color mode ('rgb', 'srgb', or 'oklch') * @param format - color format (1 or 255) for floating point or legacy 8-bit integer representation @@ -1145,7 +1168,7 @@ declare global { */ function noiseDetail(lod: number, falloff: number): void; - // 🔊 q5-sound + // 🔊 sound /** 🔊 * Represents a sound object, extending the native `Audio` to diff --git a/q5.js b/q5.js index 057bbc5..0b3a21a 100644 --- a/q5.js +++ b/q5.js @@ -70,9 +70,9 @@ function Q5(scope, parent, renderer) { let ts = timestamp || performance.now(); $._lastFrameTime ??= ts - $._targetFrameDuration; - if ($._shouldResize) { + if ($._didResize) { $.windowResized(); - $._shouldResize = false; + $._didResize = false; } if ($._loop) looper = raf($._draw); @@ -483,7 +483,7 @@ Q5.modules.canvas = ($, q) => { function parentResized() { if ($.frameCount > 1) { - $._shouldResize = true; + $._didResize = true; $._adjustDisplay(); } } @@ -543,14 +543,9 @@ Q5.modules.canvas = ($, q) => { '_imageMode', '_rectMode', '_ellipseMode', - '_textFont', - '_textLeading', - '_leadingSet', '_textSize', '_textAlign', - '_textBaseline', - '_textStyle', - '_textWrap' + '_textBaseline' ]; $._styles = []; @@ -563,6 +558,15 @@ Q5.modules.canvas = ($, q) => { let styles = $._styles.pop(); for (let s of $._styleNames) $[s] = styles[s]; }; + + if (window && $._scope != 'graphics') { + window.addEventListener('resize', () => { + $._didResize = true; + q.windowWidth = window.innerWidth; + q.windowHeight = window.innerHeight; + q.deviceOrientation = window.screen?.orientation?.type; + }); + } }; Q5.canvasOptions = { @@ -713,15 +717,6 @@ Q5.renderers.q2d.canvas = ($, q) => { document.body.append(vid); return vid; }; - - if (window && $._scope != 'graphics') { - window.addEventListener('resize', () => { - $._shouldResize = true; - q.windowWidth = window.innerWidth; - q.windowHeight = window.innerHeight; - q.deviceOrientation = window.screen?.orientation?.type; - }); - } }; Q5.renderers.q2d.drawing = ($) => { $._doStroke = true; @@ -1424,9 +1419,10 @@ Q5.BLUR = 8; Q5.renderers.q2d.text = ($, q) => { $._textAlign = 'left'; $._textBaseline = 'alphabetic'; + $._textSize = 12; let font = 'sans-serif', - tSize = 12, + leadingSet = false, leading = 15, leadDiff = 3, emphasis = 'normal', @@ -1458,12 +1454,12 @@ Q5.renderers.q2d.text = ($, q) => { styleHash = -1; }; $.textSize = (x) => { - if (x === undefined) return tSize; + if (x === undefined) return $._textSize; if ($._da) x *= $._da; - tSize = x; + $._textSize = x; fontMod = true; styleHash = -1; - if (!$._leadingSet) { + if (!leadingSet) { leading = x * 1.25; leadDiff = leading - x; } @@ -1477,8 +1473,8 @@ Q5.renderers.q2d.text = ($, q) => { if (x === undefined) return leading; if ($._da) x *= $._da; leading = x; - leadDiff = x - tSize; - $._leadingSet = true; + leadDiff = x - $._textSize; + leadingSet = true; styleHash = -1; }; $.textAlign = (horiz, vert) => { @@ -1486,7 +1482,6 @@ Q5.renderers.q2d.text = ($, q) => { if (vert) { $.ctx.textBaseline = $._textBaseline = vert == $.CENTER ? 'middle' : vert; } - styleHash = -1; }; $.textWidth = (str) => $.ctx.measureText(str).width; @@ -1497,7 +1492,7 @@ Q5.renderers.q2d.text = ($, q) => { $.textStroke = $.stroke; let updateStyleHash = () => { - let styleString = font + tSize + emphasis + leading; + let styleString = font + $._textSize + emphasis + leading; let hash = 5381; for (let i = 0; i < styleString.length; i++) { @@ -1530,7 +1525,7 @@ Q5.renderers.q2d.text = ($, q) => { let img, tX, tY; if (fontMod) { - ctx.font = `${emphasis} ${tSize}px ${font}`; + ctx.font = `${emphasis} ${$._textSize}px ${font}`; fontMod = false; } @@ -1551,7 +1546,7 @@ Q5.renderers.q2d.text = ($, q) => { if (str.indexOf('\n') == -1) lines[0] = str; else lines = str.split('\n'); - if (w) { + if (str.length > w) { let wrapped = []; for (let line of lines) { let i = 0; @@ -1563,11 +1558,9 @@ Q5.renderers.q2d.text = ($, q) => { break; } let end = line.lastIndexOf(' ', max); - if (end === -1 || end < i) { - end = max; - } + if (end === -1 || end < i) end = max; wrapped.push(line.slice(i, end)); - i = end; + i = end + 1; } } lines = wrapped; @@ -1595,6 +1588,7 @@ Q5.renderers.q2d.text = ($, q) => { img._top = descent + leadDiff; img._middle = img._top + ascent * 0.5; img._bottom = img._top + ascent; + img._leading = leading; } img._fill = $._fill; @@ -1654,7 +1648,7 @@ Q5.renderers.q2d.text = ($, q) => { else if (ta == 'right') x -= img.width; let bl = $._textBaseline; - if (bl == 'alphabetic') y -= leading; + if (bl == 'alphabetic') y -= img._leading; else if (bl == 'middle') y -= img._middle; else if (bl == 'bottom') y -= img._bottom; else if (bl == 'top') y -= img._top; @@ -2740,10 +2734,11 @@ Q5.modules.util = ($, q) => { fetch(path) .then((r) => { if (type == 'json') return r.json(); - if (type == 'text') return r.text(); + return r.text(); }) .then((r) => { q._preloadCount--; + if (type == 'csv') r = $.CSV.parse(r); Object.assign(ret, r); if (cb) cb(r); }); @@ -2752,6 +2747,21 @@ Q5.modules.util = ($, q) => { $.loadStrings = (path, cb) => $._loadFile(path, cb, 'text'); $.loadJSON = (path, cb) => $._loadFile(path, cb, 'json'); + $.loadCSV = (path, cb) => $._loadFile(path, cb, 'csv'); + + $.CSV = {}; + $.CSV.parse = (csv, sep = ',', lineSep = '\n') => { + let a = [], + lns = csv.split(lineSep), + headers = lns[0].split(sep); + for (let i = 1; i < lns.length; i++) { + let o = {}, + ln = lns[i].split(sep); + headers.forEach((h, i) => (o[h] = JSON.parse(ln[i]))); + a.push(o); + } + return a; + }; if (typeof localStorage == 'object') { $.storeItem = localStorage.setItem; @@ -3064,7 +3074,8 @@ Q5.renderers.webgpu.canvas = ($, q) => { // colors used for each draw call let colorsStack = ($.colorsStack = [1, 1, 1, 1]); - $._envLayout = Q5.device.createBindGroupLayout({ + $._transformLayout = Q5.device.createBindGroupLayout({ + label: 'transformLayout', entries: [ { binding: 0, @@ -3073,14 +3084,9 @@ Q5.renderers.webgpu.canvas = ($, q) => { type: 'uniform', hasDynamicOffset: false } - } - ] - }); - - $._transformLayout = Q5.device.createBindGroupLayout({ - entries: [ + }, { - binding: 0, + binding: 1, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage', @@ -3090,9 +3096,9 @@ Q5.renderers.webgpu.canvas = ($, q) => { ] }); - $.bindGroupLayouts = [$._envLayout, $._transformLayout]; + $.bindGroupLayouts = [$._transformLayout]; - const uniformBuffer = Q5.device.createBuffer({ + let uniformBuffer = Q5.device.createBuffer({ size: 8, // Size of two floats usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }); @@ -3107,18 +3113,6 @@ Q5.renderers.webgpu.canvas = ($, q) => { Q5.device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([$.canvas.hw, $.canvas.hh])); - $._envBindGroup = Q5.device.createBindGroup({ - layout: $._envLayout, - entries: [ - { - binding: 0, - resource: { - buffer: uniformBuffer - } - } - ] - }); - return c; }; @@ -3128,7 +3122,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { // current color index, used to associate a vertex with a color let colorIndex = 0; - const addColor = (r, g, b, a = 1) => { + let addColor = (r, g, b, a = 1) => { if (typeof r == 'string') r = $.color(r); else if (b == undefined) { // grayscale mode `fill(1, 0.5)` @@ -3140,6 +3134,8 @@ Q5.renderers.webgpu.canvas = ($, q) => { colorIndex++; }; + $._fillIndex = $._strokeIndex = -1; + $.fill = (r, g, b, a) => { addColor(r, g, b, a); $._doFill = true; @@ -3171,56 +3167,70 @@ Q5.renderers.webgpu.canvas = ($, q) => { }; $.resetMatrix(); - // Boolean to track if the matrix has been modified + // tracks if the matrix has been modified $._matrixDirty = false; - // Array to store transformation matrices for the render pass + // array to store transformation matrices for the render pass $.transformStates = [$._matrix.slice()]; - // Stack to keep track of transformation matrix indexes + // stack to keep track of transformation matrix indexes $._transformIndexStack = []; $.translate = (x, y, z) => { if (!x && !y && !z) return; // Update the translation values - $._matrix[3] += x; - $._matrix[7] -= y; - $._matrix[11] += z || 0; + $._matrix[12] += x; + $._matrix[13] -= y; + $._matrix[14] += z || 0; $._matrixDirty = true; }; - $.rotate = (r) => { - if (!r) return; - if ($._angleMode) r *= $._DEGTORAD; + $.rotate = (a) => { + if (!a) return; + if ($._angleMode) a *= $._DEGTORAD; - let cosR = Math.cos(r); - let sinR = Math.sin(r); + let cosR = Math.cos(a); + let sinR = Math.sin(a); + + let m = $._matrix; + + let m0 = m[0], + m1 = m[1], + m4 = m[4], + m5 = m[5]; - let m0 = $._matrix[0], - m1 = $._matrix[1], - m4 = $._matrix[4], - m5 = $._matrix[5]; if (!m0 && !m1 && !m4 && !m5) { - $._matrix[0] = cosR; - $._matrix[1] = sinR; - $._matrix[4] = -sinR; - $._matrix[5] = cosR; + m[0] = cosR; + m[1] = sinR; + m[4] = -sinR; + m[5] = cosR; } else { - $._matrix[0] = m0 * cosR + m4 * sinR; - $._matrix[1] = m1 * cosR + m5 * sinR; - $._matrix[4] = m0 * -sinR + m4 * cosR; - $._matrix[5] = m1 * -sinR + m5 * cosR; + m[0] = m0 * cosR + m4 * sinR; + m[1] = m1 * cosR + m5 * sinR; + m[4] = m4 * cosR - m0 * sinR; + m[5] = m5 * cosR - m1 * sinR; } $._matrixDirty = true; }; - $.scale = (sx = 1, sy, sz = 1) => { - sy ??= sx; + $.scale = (x = 1, y, z = 1) => { + y ??= x; - $._matrix[0] *= sx; - $._matrix[5] *= sy; - $._matrix[10] *= sz; + let m = $._matrix; + + m[0] *= x; + m[1] *= x; + m[2] *= x; + m[3] *= x; + m[4] *= y; + m[5] *= y; + m[6] *= y; + m[7] *= y; + m[8] *= z; + m[9] *= z; + m[10] *= z; + m[11] *= z; $._matrixDirty = true; }; @@ -3292,7 +3302,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { if (!$._transformIndexStack.length) { return console.warn('Matrix index stack is empty!'); } - // Pop the last matrix index from the stack and set it as the current matrix index + // Pop the last matrix index and set it as the current matrix index let idx = $._transformIndexStack.pop(); $._matrix = $.transformStates[idx].slice(); $._transformIndex = idx; @@ -3315,7 +3325,6 @@ Q5.renderers.webgpu.canvas = ($, q) => { // left, right, top, bottom let l, r, t, b; if (!mode || mode == 'corner') { - // CORNER l = x; r = x + w; t = -y; @@ -3355,7 +3364,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { $._render = () => { if (transformStates.length > 1 || !$._transformBindGroup) { - const transformBuffer = Q5.device.createBuffer({ + let transformBuffer = Q5.device.createBuffer({ size: transformStates.length * 64, // Size of 16 floats usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST }); @@ -3367,6 +3376,12 @@ Q5.renderers.webgpu.canvas = ($, q) => { entries: [ { binding: 0, + resource: { + buffer: uniformBuffer + } + }, + { + binding: 1, resource: { buffer: transformBuffer } @@ -3375,35 +3390,47 @@ Q5.renderers.webgpu.canvas = ($, q) => { }); } - pass.setBindGroup(0, $._envBindGroup); - pass.setBindGroup(1, $._transformBindGroup); + pass.setBindGroup(0, $._transformBindGroup); for (let m of $._hooks.preRender) m(); let drawVertOffset = 0; let imageVertOffset = 0; + let textCharOffset = 0; let curPipelineIndex = -1; let curTextureIndex = -1; - pass.setPipeline($.pipelines[0]); - for (let i = 0; i < drawStack.length; i += 2) { let v = drawStack[i + 1]; + if (drawStack[i] == -1) { + v(); + continue; + } + if (curPipelineIndex != drawStack[i]) { curPipelineIndex = drawStack[i]; pass.setPipeline($.pipelines[curPipelineIndex]); } if (curPipelineIndex == 0) { - pass.draw(v, 1, drawVertOffset, 0); + // v is the number of vertices + pass.draw(v, 1, drawVertOffset); drawVertOffset += v; } else if (curPipelineIndex == 1) { if (curTextureIndex != v) { - pass.setBindGroup(3, $._textureBindGroups[v]); + // v is the texture index + pass.setBindGroup(2, $._textureBindGroups[v]); } - pass.draw(6, 1, imageVertOffset, 0); + pass.draw(6, 1, imageVertOffset); imageVertOffset += 6; + } else if (curPipelineIndex == 2) { + pass.setBindGroup(2, $._font.bindGroup); + pass.setBindGroup(3, $._textBindGroup); + + // v is the number of characters in the text + pass.draw(4, v, 0, textCharOffset); + textCharOffset += v; } } @@ -3412,7 +3439,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { $._finishRender = () => { pass.end(); - const commandBuffer = $.encoder.finish(); + let commandBuffer = $.encoder.finish(); Q5.device.queue.submit([commandBuffer]); q.pass = $.encoder = null; @@ -3455,8 +3482,8 @@ Q5.renderers.webgpu.drawing = ($, q) => { label: 'drawingVertexShader', code: ` struct VertexOutput { - @builtin(position) position: vec4, - @location(1) colorIndex: f32 + @builtin(position) position: vec4f, + @location(0) colorIndex: f32 }; struct Uniforms { @@ -3465,12 +3492,12 @@ struct Uniforms { }; @group(0) @binding(0) var uniforms: Uniforms; -@group(1) @binding(0) var transforms: array>; +@group(0) @binding(1) var transforms: array>; @vertex -fn vertexMain(@location(0) pos: vec2, @location(1) colorIndex: f32, @location(2) transformIndex: f32) -> VertexOutput { - var vert = vec4(pos, 0.0, 1.0); - vert *= transforms[i32(transformIndex)]; +fn vertexMain(@location(0) pos: vec2f, @location(1) colorIndex: f32, @location(2) transformIndex: f32) -> VertexOutput { + var vert = vec4f(pos, 0.0, 1.0); + vert = transforms[i32(transformIndex)] * vert; vert.x /= uniforms.halfWidth; vert.y /= uniforms.halfHeight; @@ -3485,17 +3512,18 @@ fn vertexMain(@location(0) pos: vec2, @location(1) colorIndex: f32, @locati let fragmentShader = Q5.device.createShaderModule({ label: 'drawingFragmentShader', code: ` -@group(2) @binding(0) var uColors : array>; +@group(1) @binding(0) var colors : array; @fragment -fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 { - let index = u32(colorIndex); - return mix(uColors[index], uColors[index + 1u], fract(colorIndex)); +fn fragmentMain(@location(0) colorIndex: f32) -> @location(0) vec4f { + let index = i32(colorIndex); + return mix(colors[index], colors[index + 1], fract(colorIndex)); } ` }); colorsLayout = Q5.device.createBindGroupLayout({ + label: 'colorsLayout', entries: [ { binding: 0, @@ -3726,10 +3754,17 @@ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 { $.background = (r, g, b, a) => { $.push(); $.resetMatrix(); - if (r.src) $.image(r, -c.hw, -c.hh, c.w, c.h); - else { + if (r.src) { + let og = $._imageMode; + $._imageMode = 'corner'; + $.image(r, -c.hw, -c.hh, c.w, c.h); + $._imageMode = og; + } else { + let og = $._rectMode; + $._rectMode = 'corner'; $.fill(r, g, b, a); $.rect(-c.hw, -c.hh, c.w, c.h); + $._rectMode = og; } $.pop(); }; @@ -3837,7 +3872,7 @@ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 { }); // set the bind group once before rendering - $.pass.setBindGroup(2, $._colorsBindGroup); + $.pass.setBindGroup(1, $._colorsBindGroup); }); $._hooks.postRender.push(() => { @@ -3852,8 +3887,8 @@ Q5.renderers.webgpu.image = ($, q) => { label: 'imageVertexShader', code: ` struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texCoord: vec2 + @builtin(position) position: vec4f, + @location(0) texCoord: vec2f }; struct Uniforms { @@ -3862,12 +3897,12 @@ struct Uniforms { }; @group(0) @binding(0) var uniforms: Uniforms; -@group(1) @binding(0) var transforms: array>; +@group(0) @binding(1) var transforms: array>; @vertex -fn vertexMain(@location(0) pos: vec2, @location(1) texCoord: vec2, @location(2) transformIndex: f32) -> VertexOutput { - var vert = vec4(pos, 0.0, 1.0); - vert *= transforms[i32(transformIndex)]; +fn vertexMain(@location(0) pos: vec2f, @location(1) texCoord: vec2f, @location(2) transformIndex: f32) -> VertexOutput { + var vert = vec4f(pos, 0.0, 1.0); + vert = transforms[i32(transformIndex)] * vert; vert.x /= uniforms.halfWidth; vert.y /= uniforms.halfHeight; @@ -3882,11 +3917,11 @@ fn vertexMain(@location(0) pos: vec2, @location(1) texCoord: vec2, @lo let fragmentShader = Q5.device.createShaderModule({ label: 'imageFragmentShader', code: ` -@group(3) @binding(0) var samp: sampler; -@group(3) @binding(1) var texture: texture_2d; +@group(2) @binding(0) var samp: sampler; +@group(2) @binding(1) var texture: texture_2d; @fragment -fn fragmentMain(@location(0) texCoord: vec2) -> @location(0) vec4 { +fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f { // Sample the texture using the interpolated texture coordinate return textureSample(texture, samp, texCoord); } @@ -3918,11 +3953,9 @@ fn fragmentMain(@location(0) texCoord: vec2) -> @location(0) vec4 { ] }; - $.bindGroupLayouts.push(textureLayout); - const pipelineLayout = Q5.device.createPipelineLayout({ label: 'imagePipelineLayout', - bindGroupLayouts: $.bindGroupLayouts + bindGroupLayouts: [...$.bindGroupLayouts, textureLayout] }); $.pipelines[1] = Q5.device.createRenderPipeline({ @@ -4079,34 +4112,522 @@ Q5.DILATE = 6; Q5.ERODE = 7; Q5.BLUR = 8; Q5.renderers.webgpu.text = ($, q) => { - let t = $.createGraphics(1, 1); - t.pixelDensity($._pixelDensity); - t._imageMode = 'corner'; + let textShader = Q5.device.createShaderModule({ + label: 'MSDF text shader', + code: ` +// Positions for simple quad geometry +const pos = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0)); - $.loadFont = (f) => { +struct VertexInput { + @builtin(vertex_index) vertex : u32, + @builtin(instance_index) instance : u32, +}; +struct VertexOutput { + @builtin(position) position : vec4f, + @location(0) texcoord : vec2f, + @location(1) colorIndex : f32 +}; +struct Char { + texOffset: vec2f, + texExtent: vec2f, + size: vec2f, + offset: vec2f, +}; +struct Text { + pos: vec2f, + scale: f32, + transformIndex: f32, + fillIndex: f32, + strokeIndex: f32 +}; +struct Uniforms { + halfWidth: f32, + halfHeight: f32 +}; + +@group(0) @binding(0) var uniforms: Uniforms; +@group(0) @binding(1) var transforms: array>; + +@group(1) @binding(0) var colors : array; + +@group(2) @binding(0) var fontTexture: texture_2d; +@group(2) @binding(1) var fontSampler: sampler; +@group(2) @binding(2) var fontChars: array; + +@group(3) @binding(0) var textChars: array; +@group(3) @binding(1) var textMetadata: array; + +@vertex +fn vertexMain(input : VertexInput) -> VertexOutput { + let char = textChars[input.instance]; + + let text = textMetadata[i32(char.w)]; + + let fontChar = fontChars[i32(char.z)]; + + let charPos = ((pos[input.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos; + + var vert = vec4f(charPos, 0.0, 1.0); + vert = transforms[i32(text.transformIndex)] * vert; + vert.x /= uniforms.halfWidth; + vert.y /= uniforms.halfHeight; + + var output : VertexOutput; + output.position = vert; + output.texcoord = (pos[input.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset; + output.colorIndex = text.fillIndex; + return output; +} + +fn sampleMsdf(texcoord: vec2f) -> f32 { + let c = textureSample(fontTexture, fontSampler, texcoord); + return max(min(c.r, c.g), min(max(c.r, c.g), c.b)); +} + +@fragment +fn fragmentMain(input : VertexOutput) -> @location(0) vec4f { + // pxRange (AKA distanceRange) comes from the msdfgen tool, + // uses the default which is 4. + let pxRange = 4.0; + let sz = vec2f(textureDimensions(fontTexture, 0)); + let dx = sz.x*length(vec2f(dpdxFine(input.texcoord.x), dpdyFine(input.texcoord.x))); + let dy = sz.y*length(vec2f(dpdxFine(input.texcoord.y), dpdyFine(input.texcoord.y))); + let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy); + let sigDist = sampleMsdf(input.texcoord) - 0.5; + let pxDist = sigDist * toPixels; + let edgeWidth = 0.5; + let alpha = smoothstep(-edgeWidth, edgeWidth, pxDist); + if (alpha < 0.001) { + discard; + } + let fillColor = colors[i32(input.colorIndex)]; + return vec4f(fillColor.rgb, fillColor.a * alpha); +} +` + }); + + class MsdfFont { + constructor(pipeline, bindGroup, lineHeight, chars, kernings) { + this.pipeline = pipeline; + this.bindGroup = bindGroup; + this.lineHeight = lineHeight; + this.chars = chars; + this.kernings = kernings; + let charArray = Object.values(chars); + this.charCount = charArray.length; + this.defaultChar = charArray[0]; + } + getChar(charCode) { + return this.chars[charCode] ?? this.defaultChar; + } + // Gets the distance in pixels a line should advance for a given character code. If the upcoming + // character code is given any kerning between the two characters will be taken into account. + getXAdvance(charCode, nextCharCode = -1) { + let char = this.getChar(charCode); + if (nextCharCode >= 0) { + let kerning = this.kernings.get(charCode); + if (kerning) { + return char.xadvance + (kerning.get(nextCharCode) ?? 0); + } + } + return char.xadvance; + } + } + + let textBindGroupLayout = Q5.device.createBindGroupLayout({ + label: 'MSDF text group layout', + entries: [ + { + binding: 0, + visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, + buffer: { type: 'read-only-storage' } + }, + { + binding: 1, + visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, + buffer: { type: 'read-only-storage' } + } + ] + }); + + let fonts = {}; + + let createFont = async (fontJsonUrl, fontName, cb) => { q._preloadCount++; - return t.loadFont(f, () => { + + let res = await fetch(fontJsonUrl); + if (res.status == 404) { q._preloadCount--; + return ''; + } + let atlas = await res.json(); + + let slashIdx = fontJsonUrl.lastIndexOf('/'); + let baseUrl = slashIdx != -1 ? fontJsonUrl.substring(0, slashIdx + 1) : ''; + // load font image + res = await fetch(baseUrl + atlas.pages[0]); + let img = await createImageBitmap(await res.blob()); + + // convert image to texture + let imgSize = [img.width, img.height, 1]; + let texture = Q5.device.createTexture({ + label: `MSDF ${fontName}`, + size: imgSize, + format: 'rgba8unorm', + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT }); + Q5.device.queue.copyExternalImageToTexture({ source: img }, { texture }, imgSize); + + // to make q5's default font file smaller, + // the chars and kernings are stored as csv strings + if (typeof atlas.chars == 'string') { + atlas.chars = $.CSV.parse(atlas.chars, ' '); + atlas.kernings = $.CSV.parse(atlas.kernings, ' '); + } + + let charCount = atlas.chars.length; + let charsBuffer = Q5.device.createBuffer({ + size: charCount * 32, + usage: GPUBufferUsage.STORAGE, + mappedAtCreation: true + }); + + let fontChars = new Float32Array(charsBuffer.getMappedRange()); + let u = 1 / atlas.common.scaleW; + let v = 1 / atlas.common.scaleH; + let chars = {}; + let o = 0; // offset + for (let [i, char] of atlas.chars.entries()) { + chars[char.id] = char; + chars[char.id].charIndex = i; + fontChars[o] = char.x * u; // texOffset.x + fontChars[o + 1] = char.y * v; // texOffset.y + fontChars[o + 2] = char.width * u; // texExtent.x + fontChars[o + 3] = char.height * v; // texExtent.y + fontChars[o + 4] = char.width; // size.x + fontChars[o + 5] = char.height; // size.y + fontChars[o + 6] = char.xoffset; // offset.x + fontChars[o + 7] = -char.yoffset; // offset.y + o += 8; + } + charsBuffer.unmap(); + + let fontSampler = Q5.device.createSampler({ + minFilter: 'linear', + magFilter: 'linear', + mipmapFilter: 'linear', + maxAnisotropy: 16 + }); + let fontBindGroupLayout = Q5.device.createBindGroupLayout({ + label: 'MSDF font group layout', + entries: [ + { + binding: 0, + visibility: GPUShaderStage.FRAGMENT, + texture: {} + }, + { + binding: 1, + visibility: GPUShaderStage.FRAGMENT, + sampler: {} + }, + { + binding: 2, + visibility: GPUShaderStage.VERTEX, + buffer: { type: 'read-only-storage' } + } + ] + }); + let fontPipeline = Q5.device.createRenderPipeline({ + label: 'msdf font pipeline', + layout: Q5.device.createPipelineLayout({ + bindGroupLayouts: [...$.bindGroupLayouts, fontBindGroupLayout, textBindGroupLayout] + }), + vertex: { + module: textShader, + entryPoint: 'vertexMain' + }, + fragment: { + module: textShader, + entryPoint: 'fragmentMain', + targets: [ + { + format: 'bgra8unorm', + blend: { + color: { + srcFactor: 'src-alpha', + dstFactor: 'one-minus-src-alpha' + }, + alpha: { + srcFactor: 'one', + dstFactor: 'one' + } + } + } + ] + }, + primitive: { + topology: 'triangle-strip', + stripIndexFormat: 'uint32' + } + }); + + let fontBindGroup = Q5.device.createBindGroup({ + label: 'msdf font bind group', + layout: fontBindGroupLayout, + entries: [ + { + binding: 0, + resource: texture.createView() + }, + { binding: 1, resource: fontSampler }, + { binding: 2, resource: { buffer: charsBuffer } } + ] + }); + + let kernings = new Map(); + if (atlas.kernings) { + for (let kerning of atlas.kernings) { + let charKerning = kernings.get(kerning.first); + if (!charKerning) { + charKerning = new Map(); + kernings.set(kerning.first, charKerning); + } + charKerning.set(kerning.second, kerning.amount); + } + } + + $._font = new MsdfFont(fontPipeline, fontBindGroup, atlas.common.lineHeight, chars, kernings); + + fonts[fontName] = $._font; + $.pipelines[2] = $._font.pipeline; + + q._preloadCount--; + + if (cb) cb(fontName); }; - // directly add these text setting functions to the webgpu renderer - $.textFont = t.textFont; - $.textSize = t.textSize; - $.textLeading = t.textLeading; - $.textStyle = t.textStyle; - $.textAlign = t.textAlign; - $.textWidth = t.textWidth; - $.textAscent = t.textAscent; - $.textDescent = t.textDescent; + // q2d graphics context to use for text image creation + let g = $.createGraphics(1, 1); + g.colorMode($.RGB, 1); + + $.loadFont = (url, cb) => { + let ext = url.slice(url.lastIndexOf('.') + 1); + if (ext != 'json') return g.loadFont(url, cb); + let fontName = url.slice(url.lastIndexOf('/') + 1, url.lastIndexOf('-')); + createFont(url, fontName, cb); + return fontName; + }; + + $._textSize = 18; + $._textAlign = 'left'; + $._textBaseline = 'alphabetic'; + let leadingSet = false, + leading = 22.5, + leadDiff = 4.5, + leadPercent = 1.25; + + $.textFont = (fontName) => { + $._font = fonts[fontName]; + + // replay the change of font in the draw stack + $.drawStack.push(-1, () => { + $._font = fonts[fontName]; + $.pipelines[2] = $._font.pipeline; + }); + }; + $.textSize = (size) => { + $._textSize = size; + if (!leadingSet) { + leading = size * leadPercent; + leadDiff = leading - size; + } + }; + $.textLeading = (lineHeight) => { + $._font.lineHeight = leading = lineHeight; + leadDiff = leading - $._textSize; + leadPercent = leading / $._textSize; + leadingSet = true; + }; + $.textAlign = (horiz, vert) => { + $._textAlign = horiz; + if (vert) $._textBaseline = vert; + }; + + $._charStack = []; + $._textStack = []; + + let measureText = (font, text, charCallback) => { + let maxWidth = 0, + offsetX = 0, + offsetY = 0, + line = 0, + printedCharCount = 0, + lineWidths = [], + nextCharCode = text.charCodeAt(0); + + for (let i = 0; i < text.length; ++i) { + let charCode = nextCharCode; + nextCharCode = i < text.length - 1 ? text.charCodeAt(i + 1) : -1; + switch (charCode) { + case 10: // Newline + lineWidths.push(offsetX); + line++; + maxWidth = Math.max(maxWidth, offsetX); + offsetX = 0; + offsetY -= font.lineHeight * leadPercent; + break; + case 13: // CR + break; + case 32: // Space + // advance the offset without actually adding a character + offsetX += font.getXAdvance(charCode); + break; + case 9: // Tab + offsetX += font.getXAdvance(charCode) * 2; + break; + default: + if (charCallback) { + charCallback(offsetX, offsetY, line, font.getChar(charCode)); + } + offsetX += font.getXAdvance(charCode, nextCharCode); + printedCharCount++; + } + } + lineWidths.push(offsetX); + maxWidth = Math.max(maxWidth, offsetX); + return { + width: maxWidth, + height: lineWidths.length * font.lineHeight * leadPercent, + lineWidths, + printedCharCount + }; + }; - $.textFill = (r, g, b, a) => t.fill($.color(r, g, b, a)); - $.textStroke = (r, g, b, a) => t.stroke($.color(r, g, b, a)); + let initLoadDefaultFont; $.text = (str, x, y, w, h) => { - let img = t.createTextImage(str, w, h); + if (!$._font) { + // check if online and loading the default font hasn't been attempted yet + if (navigator.onLine && !initLoadDefaultFont) { + initLoadDefaultFont = true; + $.loadFont('https://q5js.org/fonts/YaHei-msdf.json'); + } + return; + } - if (img.canvas.textureIndex === undefined) { + if (str.length > w) { + let wrapped = []; + let i = 0; + while (i < str.length) { + let max = i + w; + if (max >= str.length) { + wrapped.push(str.slice(i)); + break; + } + let end = str.lastIndexOf(' ', max); + if (end == -1 || end < i) end = max; + wrapped.push(str.slice(i, end)); + i = end + 1; + } + str = wrapped.join('\n'); + } + + let spaces = 0, // whitespace char count, not literal spaces + hasNewline; + for (let i = 0; i < str.length; i++) { + let c = str[i]; + switch (c) { + case '\n': + hasNewline = true; + case '\r': + case '\t': + case ' ': + spaces++; + } + } + + let charsData = new Float32Array((str.length - spaces) * 4); + + let ta = $._textAlign, + tb = $._textBaseline, + textIndex = $._textStack.length, + o = 0, // offset + measurements; + + if (ta == 'left' && !hasNewline) { + measurements = measureText($._font, str, (textX, textY, line, char) => { + charsData[o] = textX; + charsData[o + 1] = textY; + charsData[o + 2] = char.charIndex; + charsData[o + 3] = textIndex; + o += 4; + }); + + if (tb == 'alphabetic') y -= $._textSize; + else if (tb == 'center') y -= $._textSize * 0.5; + else if (tb == 'bottom') y -= leading; + } else { + // measure the text to get the line widths before setting + // the x position to properly align the text + measurements = measureText($._font, str); + + let offsetY = 0; + if (tb == 'alphabetic') y -= $._textSize; + else if (tb == 'center') offsetY = measurements.height * 0.5; + else if (tb == 'bottom') offsetY = measurements.height; + + measureText($._font, str, (textX, textY, line, char) => { + let offsetX = 0; + if (ta == 'center') { + offsetX = measurements.width * -0.5 - (measurements.width - measurements.lineWidths[line]) * -0.5; + } else if (ta == 'right') { + offsetX = measurements.width - measurements.lineWidths[line]; + } + charsData[o] = textX + offsetX; + charsData[o + 1] = textY + offsetY; + charsData[o + 2] = char.charIndex; + charsData[o + 3] = textIndex; + o += 4; + }); + } + $._charStack.push(charsData); + + let text = new Float32Array(6); + + if ($._matrixDirty) $._saveMatrix(); + + text[0] = x; + text[1] = -y; + text[2] = $._textSize / 44; + text[3] = $._transformIndex; + text[4] = $._fillIndex; + text[5] = $._strokeIndex; + + $._textStack.push(text); + $.drawStack.push(2, measurements.printedCharCount); + }; + + $.textWidth = (str) => { + if (!$._font) return 0; + return measureText($._font, str).width; + }; + + $.createTextImage = (str, w, h) => { + g.textSize($._textSize); + + if ($._doFill) { + let fi = $._fillIndex * 4; + g.fill(colorsStack.slice(fi, fi + 4)); + } + if ($._doStroke) { + let si = $._strokeIndex * 4; + g.stroke(colorsStack.slice(si, si + 4)); + } + + let img = g.createTextImage(str, w, h); + + if (img.canvas.textureIndex == undefined) { $._createTexture(img); } else if (img.modified) { let cnv = img.canvas; @@ -4120,27 +4641,92 @@ Q5.renderers.webgpu.text = ($, q) => { ); img.modified = false; } - - $.textImage(img, x, y); + return img; }; - $.createTextImage = t.createTextImage; - $.textImage = (img, x, y) => { let og = $._imageMode; $._imageMode = 'corner'; - let ta = t._textAlign; + let ta = $._textAlign; if (ta == 'center') x -= img.canvas.hw; else if (ta == 'right') x -= img.width; - let bl = t._textBaseline; - if (bl == 'alphabetic') y -= t._textLeading; - else if (bl == 'middle') y -= img._middle; + let bl = $._textBaseline; + if (bl == 'alphabetic') y -= img._leading; + else if (bl == 'center') y -= img._middle; else if (bl == 'bottom') y -= img._bottom; else if (bl == 'top') y -= img._top; $.image(img, x, y); $._imageMode = og; }; + + $._hooks.preRender.push(() => { + if (!$._charStack.length) return; + + // Calculate total buffer size for text data + let totalTextSize = 0; + for (let charsData of $._charStack) { + totalTextSize += charsData.length * 4; + } + + // Create a single buffer for all text data + let charBuffer = Q5.device.createBuffer({ + label: 'charBuffer', + size: totalTextSize, + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, + mappedAtCreation: true + }); + + // Copy all text data into the buffer + let textArray = new Float32Array(charBuffer.getMappedRange()); + let o = 0; + for (let array of $._charStack) { + textArray.set(array, o); + o += array.length; + } + charBuffer.unmap(); + + // Calculate total buffer size for metadata + let totalMetadataSize = $._textStack.length * 6 * 4; + + // Create a single buffer for all metadata + let textBuffer = Q5.device.createBuffer({ + label: 'textBuffer', + size: totalMetadataSize, + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, + mappedAtCreation: true + }); + + // Copy all metadata into the buffer + let metadataArray = new Float32Array(textBuffer.getMappedRange()); + o = 0; + for (let array of $._textStack) { + metadataArray.set(array, o); + o += array.length; + } + textBuffer.unmap(); + + // Create a single bind group for the text buffer and metadata buffer + $._textBindGroup = Q5.device.createBindGroup({ + label: 'msdf text bind group', + layout: textBindGroupLayout, + entries: [ + { + binding: 0, + resource: { buffer: charBuffer } + }, + { + binding: 1, + resource: { buffer: textBuffer } + } + ] + }); + }); + + $._hooks.postRender.push(() => { + $._charStack.length = 0; + $._textStack.length = 0; + }); }; diff --git a/q5.min.js b/q5.min.js index 68c33fd..60de0e2 100644 --- a/q5.min.js +++ b/q5.min.js @@ -5,4 +5,4 @@ * @license LGPL-3.0 * @class Q5 */ -function Q5(e,t,r){let a,o=this;if(o._q5=!0,o._parent=t,o._renderer=r||"q2d",o._preloadCount=0,e??="global","auto"==e){if(!window.setup&&!window.draw)return;e="global"}o._scope=e,"global"==e&&(Q5._hasGlobal=o._isGlobal=!0,a=Q5._nodejs?global:window);let n=new Proxy(o,{set:(e,t,r)=>(o[t]=r,o._isGlobal&&(a[t]=r),!0)});o.canvas=o.ctx=o.drawingContext=null,o.pixels=[];let i=null;o.frameCount=0,o.deltaTime=16,o._targetFrameRate=0,o._targetFrameDuration=16.666666666666668,o._frameRate=o._fps=60,o._loop=!0,o._hooks={postCanvas:[],preRender:[],postRender:[]};let s=0;o.millis=()=>performance.now()-s,o.noCanvas=()=>{o.canvas?.remove&&o.canvas.remove(),o.canvas=0,n.ctx=n.drawingContext=0},window&&(o.windowWidth=window.innerWidth,o.windowHeight=window.innerHeight,o.deviceOrientation=window.screen?.orientation?.type),o._incrementPreload=()=>n._preloadCount++,o._decrementPreload=()=>n._preloadCount--,o._draw=e=>{let t=e||performance.now();if(o._lastFrameTime??=t-o._targetFrameDuration,o._shouldResize&&(o.windowResized(),o._shouldResize=!1),o._loop)i=d(o._draw);else if(o.frameCount&&!o._redraw)return;if(i&&o.frameCount){if(t-o._lastFrameTime{o._loop=!1,i=null},o.loop=()=>{o._loop=!0,null==i&&o._draw()},o.isLooping=()=>o._loop,o.redraw=(e=1)=>{o._redraw=!0;for(let t=0;t{o.noLoop(),o.canvas.remove()},o.frameRate=e=>(e&&(o._targetFrameRate=e,o._targetFrameDuration=1e3/e),o._frameRate),o.getTargetFrameRate=()=>o._targetFrameRate,o.getFPS=()=>o._fps,o.Element=function(e){this.elt=e},o._elements=[],o.TWO_PI=o.TAU=2*Math.PI,o.log=o.print=console.log,o.describe=()=>{};for(let e in Q5.modules)Q5.modules[e](o,n);let l=Q5.renderers[o._renderer];for(let e in l)l[e](o,n);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(o[e]=Q5[e]);if("graphics"==e)return;"global"==e&&(Object.assign(Q5,o),delete Q5.Q5);for(let e of Q5.methods.init)e.call(o);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof o[e]&&(o[e]=t.bind(o));if("global"==e){let e=Object.getOwnPropertyNames(o);for(let t of e)"_"!=t[0]&&(a[t]=o[t])}"function"==typeof e&&e(o),Q5._instanceCount++;let d=window.requestAnimationFrame||function(e){const t=o._lastFrameTime+o._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},c=a||o;o._isTouchAware=c.touchStarted||c.touchMoved||c.mouseReleased;let h=c.preload,u=["setup","draw","preload","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of u)c[e]?o._isGlobal&&(o[e]=()=>{try{return c[e]()}catch(e){throw o._aiErrorAssistance&&o._aiErrorAssistance(e),e}}):o[e]=()=>{};async function p(){if(o._startDone=!0,o._preloadCount>0)return d(p);s=performance.now(),await o.setup(),o.frameCount||(null===o.ctx&&o.createCanvas(100,100),o._setupDone=!0,o.ctx&&o.resetMatrix(),d(o._draw))}(o.setup||o.draw)&&(arguments.length&&"namespace"!=e&&"webgpu"!=r||h?(o.preload(),p()):(c.preload=o.preload=()=>{o._startDone||p()},setTimeout(o.preload,32)))}Q5.renderers={},Q5.modules={},Q5._nodejs="object"==typeof process,Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{throw Error(t+": "+e)},Q5._validateParameters=()=>!0,Q5.methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.methods[e].push(t),Q5.prototype.registerPreloadMethod=(e,t)=>Q5.prototype[e]=t[e],Q5._nodejs?global.p5??=global.Q5=Q5:"object"==typeof window?window.p5??=window.Q5=Q5:global.window=0,"object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")})),Q5.modules.canvas=(e,t)=>{e.CENTER="center",e.LEFT="left",e.RIGHT="right",e.TOP="top",e.BOTTOM="bottom",e.BASELINE="alphabetic",e.NORMAL="normal",e.ITALIC="italic",e.BOLD="bold",e.BOLDITALIC="italic bold",e.ROUND="round",e.SQUARE="butt",e.PROJECT="square",e.MITER="miter",e.BEVEL="bevel",e.CHORD=0,e.PIE=1,e.OPEN=2,e.RADIUS="radius",e.CORNER="corner",e.CORNERS="corners",e.CLOSE=1,e.LANDSCAPE="landscape",e.PORTRAIT="portrait",e.BLEND="source-over",e.REMOVE="destination-out",e.ADD="lighter",e.DARKEST="darken",e.LIGHTEST="lighten",e.DIFFERENCE="difference",e.SUBTRACT="subtract",e.EXCLUSION="exclusion",e.MULTIPLY="multiply",e.SCREEN="screen",e.REPLACE="copy",e.OVERLAY="overlay",e.HARD_LIGHT="hard-light",e.SOFT_LIGHT="soft-light",e.DODGE="color-dodge",e.BURN="color-burn",e.P2D="2d",e.WEBGL="webgl",e._OffscreenCanvas=window.OffscreenCanvas||function(){return document.createElement("canvas")},Q5._nodejs?Q5._createNodeJSCanvas&&(t.canvas=Q5._createNodeJSCanvas(100,100)):"image"!=e._scope&&"graphics"!=e._scope||(t.canvas=new e._OffscreenCanvas(100,100)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas());let r=e.canvas;if(r.width=e.width=100,r.height=e.height=100,e._pixelDensity=1,e.displayDensity=()=>window.devicePixelRatio||1,"image"!=e._scope&&(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity())),e._adjustDisplay=()=>{r.style&&(r.style.width=r.w+"px",r.style.height=r.h+"px")},e.createCanvas=function(t,a,o){o??=arguments[3];let n=Object.assign({},Q5.canvasOptions);"object"==typeof o&&Object.assign(n,o),"image"!=e._scope&&("graphics"==e._scope?e._pixelDensity=this._pixelDensity:window.IntersectionObserver&&new IntersectionObserver((e=>{r.visible=e[0].isIntersecting})).observe(r)),e._setCanvasSize(t,a),Object.assign(r,n);let i=e._createCanvas(r.w,r.h,n);if(e._hooks)for(let t of e._hooks.postCanvas)t();return i},e.createGraphics=function(t,r,a){let o=new Q5("graphics");return a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace,o.createCanvas.call(e,t,r,a),o},e._save=async(e,t,r)=>{if(t=t||"untitled","jpg"==(r=r||"png")||"png"==r||"webp"==r)if(e instanceof OffscreenCanvas){const t=await e.convertToBlob({type:"image/"+r});e=await new Promise((e=>{const r=new FileReader;r.onloadend=()=>e(r.result),r.readAsDataURL(t)}))}else e=e.toDataURL("image/"+r);else{let t="text/plain";"json"==r&&("string"!=typeof e&&(e=JSON.stringify(e)),t="text/json"),e=new Blob([e],{type:t}),e=URL.createObjectURL(e)}let a=document.createElement("a");a.href=e,a.download=t+"."+r,a.click(),URL.revokeObjectURL(a.href)},e.save=(t,r,a)=>{if((!t||"string"==typeof t&&(!r||!a&&r.length<5))&&(a=r,r=t,t=e.canvas),a)return e._save(t,r,a);r?(r=r.split("."),e._save(t,r[0],r.at(-1))):e._save(t)},e._setCanvasSize=(a,o)=>{a??=window.innerWidth,o??=window.innerHeight,r.w=a=Math.ceil(a),r.h=o=Math.ceil(o),r.hw=a/2,r.hh=o/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(o*e._pixelDensity),e._da?e.flexibleCanvas(e._dau):(t.width=a,t.height=o),e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay()},"image"!=e._scope){if(r&&"graphics"!=e._scope){function a(){let t=e._parent;t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),r.parent(t)}r.parent=t=>{function a(){e.frameCount>1&&(e._shouldResize=!0,e._adjustDisplay())}r.parentElement&&r.parentElement.removeChild(r),"string"==typeof t&&(t=document.getElementById(t)),t.append(r),"function"==typeof ResizeObserver?(e._ro&&e._ro.disconnect(),e._ro=new ResizeObserver(a),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",a)},document.body?a():document.addEventListener("DOMContentLoaded",a)}e.resizeCanvas=(t,a)=>{if(!e.ctx)return e.createCanvas(t,a);t==r.w&&a==r.h||e._resizeCanvas(t,a)},e.canvas.resize=e.resizeCanvas,e.canvas.save=e.saveCanvas=e.save,e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._setCanvasSize(r.w,r.h),t):e._pixelDensity,e.flexibleCanvas=(a=400)=>{a?(e._da=r.width/(a*e._pixelDensity),t.width=e._dau=a,t.height=r.h/r.w*a):e._da=0},e._styleNames=["_doStroke","_doFill","_strokeSet","_fillSet","_tint","_imageMode","_rectMode","_ellipseMode","_textFont","_textLeading","_leadingSet","_textSize","_textAlign","_textBaseline","_textStyle","_textWrap"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t)},e.popStyles=()=>{let t=e._styles.pop();for(let r of e._styleNames)e[r]=t[r]}}},Q5.canvasOptions={alpha:!1,colorSpace:"display-p3"},window.matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches?Q5.supportsHDR=!0:Q5.canvasOptions.colorSpace="srgb",Q5.renderers.q2d={},Q5.renderers.q2d.canvas=(e,t)=>{let r=e.canvas;e.colorMode&&e.colorMode("rgb","integer"),e._createCanvas=function(a,o,n){return t.ctx=t.drawingContext=r.getContext("2d",n),"image"!=e._scope&&(e.ctx.fillStyle="white",e.ctx.strokeStyle="black",e.ctx.lineCap="round",e.ctx.lineJoin="miter",e.ctx.textAlign="left"),e.ctx.scale(e._pixelDensity,e._pixelDensity),e.ctx.save(),r},e.clear=()=>{e.ctx.save(),e.ctx.resetTransform(),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.restore()},"image"!=e._scope&&(e._resizeCanvas=(t,a)=>{let o,n={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(n[t]=e.ctx[t]);if(delete n.canvas,e.frameCount>1){o=new e._OffscreenCanvas(r.width,r.height),o.w=r.w,o.h=r.h,o.getContext("2d").drawImage(r,0,0)}e._setCanvasSize(t,a);for(let t in n)e.ctx[t]=n[t];e.scale(e._pixelDensity),o&&e.ctx.drawImage(o,0,0,o.w,o.h)},e.fill=function(t){if(e._doFill=!0,e._fillSet=!0,Q5.Color&&(t._q5Color||("string"!=typeof t?t=e.color(...arguments):e._namedColors[t]&&(t=e.color(...e._namedColors[t]))),t.a<=0))return e._doFill=!1;e.ctx.fillStyle=e._fill=t.toString()},e.noFill=()=>e._doFill=!1,e.stroke=function(t){if(e._doStroke=!0,e._strokeSet=!0,Q5.Color&&(t._q5Color||("string"!=typeof t?t=e.color(...arguments):e._namedColors[t]&&(t=e.color(...e._namedColors[t]))),t.a<=0))return e._doStroke=!1;e.ctx.strokeStyle=e._stroke=t.toString()},e.strokeWeight=t=>{t||(e._doStroke=!1),e._da&&(t*=e._da),e.ctx.lineWidth=e._strokeWeight=t||1e-4},e.noStroke=()=>e._doStroke=!1,e.opacity=t=>e.ctx.globalAlpha=t,e.translate=(t,r)=>{e._da&&(t*=e._da,r*=e._da),e.ctx.translate(t,r)},e.rotate=t=>{e._angleMode&&(t=e.radians(t)),e.ctx.rotate(t)},e.scale=(t,r)=>{r??=t,e.ctx.scale(t,r)},e.applyMatrix=(t,r,a,o,n,i)=>e.ctx.transform(t,r,a,o,n,i),e.shearX=t=>e.ctx.transform(1,0,e.tan(t),1,0,0),e.shearY=t=>e.ctx.transform(1,e.tan(t),0,1,0,0),e.resetMatrix=()=>{e.ctx.resetTransform(),e.scale(e._pixelDensity)},e.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore(),e.push=()=>{e.ctx.save(),e.pushStyles()},e.pop=()=>{e.ctx.restore(),e.popStyles()},e.createCapture=e=>{var t=document.createElement("video");return t.playsinline="playsinline",t.autoplay="autoplay",navigator.mediaDevices.getUserMedia(e).then((e=>{t.srcObject=e})),t.style.position="absolute",t.style.opacity=1e-5,t.style.zIndex=-1e3,document.body.append(t),t},window&&"graphics"!=e._scope&&window.addEventListener("resize",(()=>{e._shouldResize=!0,t.windowWidth=window.innerWidth,t.windowHeight=window.innerHeight,t.deviceOrientation=window.screen?.orientation?.type})))},Q5.renderers.q2d.drawing=e=>{e._doStroke=!0,e._doFill=!0,e._strokeSet=!1,e._fillSet=!1,e._ellipseMode=e.CENTER,e._rectMode=e.CORNER,e._curveDetail=20,e._curveAlpha=0;let t=!0,r=[];function a(){e._doFill&&e.ctx.fill(),e._doStroke&&e.ctx.stroke()}function o(t,r,o,n,i,s,l,d){if(!e._doFill&&!e._doStroke)return;let c=e._angleMode,h=c?360:e.TAU;if((i%=h)<0&&(i+=h),(s%=h)<0&&(s+=h),0!=i||0!=s){if(i>s&&([i,s]=[s,i]),e.ctx.beginPath(),o==n)c&&(i=e.radians(i),s=e.radians(s)),e.ctx.arc(t,r,o/2,i,s);else{for(let a=0;ae.ctx.globalCompositeOperation=t,e.strokeCap=t=>e.ctx.lineCap=t,e.strokeJoin=t=>e.ctx.lineJoin=t,e.ellipseMode=t=>e._ellipseMode=t,e.rectMode=t=>e._rectMode=t,e.curveDetail=t=>e._curveDetail=t,e.curveAlpha=t=>e._curveAlpha=t,e.curveTightness=t=>e._curveAlpha=t,e.background=function(t){e.ctx.save(),e.ctx.resetTransform(),t.canvas?e.image(t,0,0,e.width,e.height):(Q5.Color&&!t._q5Color&&("string"!=typeof t?t=e.color(...arguments):e._namedColors[t]&&(t=e.color(...e._namedColors[t]))),e.ctx.fillStyle=t.toString(),e.ctx.fillRect(0,0,e.canvas.width,e.canvas.height)),e.ctx.restore()},e.line=(t,r,a,o)=>{e._doStroke&&(e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(a,o),e.ctx.stroke())},e.arc=(t,r,a,n,i,s,l,d=25)=>{if(i==s)return e.ellipse(t,r,a,n);l??=e.PIE,e._ellipseMode==e.CENTER?o(t,r,a,n,i,s,l,d):e._ellipseMode==e.RADIUS?o(t,r,2*a,2*n,i,s,l,d):e._ellipseMode==e.CORNER?o(t+a/2,r+n/2,a,n,i,s,l,d):e._ellipseMode==e.CORNERS&&o((t+a)/2,(r+n)/2,a-t,n-r,i,s,l,d)},e.ellipse=(t,r,a,o)=>{o??=a,e._ellipseMode==e.CENTER?n(t,r,a,o):e._ellipseMode==e.RADIUS?n(t,r,2*a,2*o):e._ellipseMode==e.CORNER?n(t+a/2,r+o/2,a,o):e._ellipseMode==e.CORNERS&&n((t+a)/2,(r+o)/2,a-t,o-r)},e.circle=(t,r,o)=>{e._ellipseMode==e.CENTER?(e._da&&(t*=e._da,r*=e._da,o*=e._da),e.ctx.beginPath(),e.ctx.arc(t,r,o/2,0,e.TAU),a()):e.ellipse(t,r,o,o)},e.point=(t,r)=>{t.x&&(r=t.y,t=t.x),e._da&&(t*=e._da,r*=e._da),e.ctx.save(),e.ctx.beginPath(),e.ctx.arc(t,r,e.ctx.lineWidth/2,0,e.TAU),e.ctx.fillStyle=e.ctx.strokeStyle,e.ctx.fill(),e.ctx.restore()},e.rect=(t,r,a,o=a,n,s,l,d)=>{e._rectMode==e.CENTER?i(t-a/2,r-o/2,a,o,n,s,l,d):e._rectMode==e.RADIUS?i(t-a,r-o,2*a,2*o,n,s,l,d):e._rectMode==e.CORNER?i(t,r,a,o,n,s,l,d):e._rectMode==e.CORNERS&&i(t,r,a-t,o-r,n,s,l,d)},e.square=(t,r,a,o,n,i,s)=>e.rect(t,r,a,a,o,n,i,s),e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(a,o)=>{e._da&&(a*=e._da,o*=e._da),r=[],t?e.ctx.moveTo(a,o):e.ctx.lineTo(a,o),t=!1},e.bezierVertex=(t,a,o,n,i,s)=>{e._da&&(t*=e._da,a*=e._da,o*=e._da,n*=e._da,i*=e._da,s*=e._da),r=[],e.ctx.bezierCurveTo(t,a,o,n,i,s)},e.quadraticVertex=(t,a,o,n)=>{e._da&&(t*=e._da,a*=e._da,o*=e._da,n*=e._da),r=[],e.ctx.quadraticCurveTo(t,a,o,n)},e.bezier=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,o,n,i,s,l),e.endShape()},e.triangle=(t,r,a,o,n,i)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.endShape(e.CLOSE)},e.quad=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),a()},e.curveVertex=(a,o)=>{if(e._da&&(a*=e._da,o*=e._da),r.push([a,o]),r.length<4)return;let n=function(e,t,r,a,o,n,i,s,l,d){function c(e,t,r,a,o,n){let i=Math.pow(a-t,2)+Math.pow(o-r,2);return Math.pow(i,.5*n)+e}let h=[],u=c(0,e,t,r,a,d),p=c(u,r,a,o,n,d),_=c(p,o,n,i,s,d);for(let d=0;d0?(m[e]=1,m[e+1]=0):(m[e]=0,m[e+1]=1));let g=e*m[0]+r*m[1],x=t*m[0]+a*m[1],f=r*m[2]+o*m[3],v=a*m[2]+n*m[3],y=o*m[4]+i*m[5],w=n*m[4]+s*m[5],b=g*m[6]+f*m[7],M=x*m[6]+v*m[7],S=f*m[8]+y*m[9],C=v*m[8]+w*m[9],Q=b*m[2]+S*m[3],R=M*m[2]+C*m[3];h.push([Q,R])}return h}(...r.at(-4),...r.at(-3),...r.at(-2),...r.at(-1),e._curveDetail,e._curveAlpha);for(let r=0;r{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,o),e.curveVertex(n,i),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,a,o)=>{const n=o*o*o,i=o*o;return e*(-.5*n+i-.5*o)+t*(1.5*n-2.5*i+1)+r*(-1.5*n+2*i+.5*o)+a*(.5*n-.5*i)},e.bezierPoint=(e,t,r,a,o)=>{const n=1-o;return Math.pow(n,3)*e+3*Math.pow(n,2)*o*t+3*n*Math.pow(o,2)*r+Math.pow(o,3)*a},e.curveTangent=(e,t,r,a,o)=>{const n=o*o;return e*(-3*n/2+2*o-.5)+t*(9*n/2-5*o)+r*(-9*n/2+4*o+.5)+a*(3*n/2-o)},e.bezierTangent=(e,t,r,a,o)=>{const n=1-o;return 3*a*Math.pow(o,2)-3*r*Math.pow(o,2)+6*r*n*o-6*t*n*o+3*t*Math.pow(n,2)-3*e*Math.pow(n,2)},e.erase=function(t=255,r=255){e.ctx.save(),e.ctx.globalCompositeOperation="destination-out",e.ctx.fillStyle=`rgba(0, 0, 0, ${t/255})`,e.ctx.strokeStyle=`rgba(0, 0, 0, ${r/255})`},e.noErase=function(){e.ctx.globalCompositeOperation="source-over",e.ctx.restore()},e.inFill=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInPath(t*a,r*a)},e.inStroke=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInStroke(t*a,r*a)}},Q5.renderers.q2d.image=(e,t)=>{Q5.Image??=class{constructor(e,t,r){let a=this;a._scope="image",a.canvas=a.ctx=a.drawingContext=null,a.pixels=[],Q5.modules.canvas(a,a);let o=Q5.renderers.q2d;for(let e of["canvas","image","soft_filters"])o[e]&&o[e](a,a);a._pixelDensity=r.pixelDensity||1,a.createCanvas(e,t,r),delete a.createCanvas,a._loop=!1}get w(){return this.width}get h(){return this.height}},e.createImage=(t,r,a)=>(a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace||Q5.canvasOptions.colorSpace,new Q5.Image(t,r,a)),e.loadImage=function(r,a,o){if(r.canvas)return r;if("gif"==r.slice(-3).toLowerCase())throw new Error("q5 doesn't support GIFs due to their impact on performance. Use a video or animation instead.");t._preloadCount++;let n=[...arguments].at(-1);o="object"==typeof n?n:null;let i=e.createImage(1,1,o);function s(e){i.resize(e.naturalWidth||e.width,e.naturalHeight||e.height),i.ctx.drawImage(e,0,0),t._preloadCount--,a&&a(i)}if(Q5._nodejs&&global.CairoCanvas)global.CairoCanvas.loadImage(r).then(s).catch((e=>{throw t._preloadCount--,e}));else{let e=new window.Image;e.src=r,e.crossOrigin="Anonymous",e._pixelDensity=1,e.onload=()=>s(e),e.onerror=e=>{throw t._preloadCount--,e}}return i},e.imageMode=t=>e._imageMode=t,e.image=(t,r,a,o,n,i=0,s=0,l,d)=>{let c=t.canvas||t;Q5._createNodeJSCanvas&&(c=c.context.canvas),o??=t.width||t.videoWidth,n??=t.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*o,a-=.5*n),e._da&&(r*=e._da,a*=e._da,o*=e._da,n*=e._da,i*=e._da,s*=e._da,l*=e._da,d*=e._da);let h=t._pixelDensity||1;l?l*=h:l=c.width||c.videoWidth,d?d*=h:d=c.height||c.videoHeight,e.ctx.drawImage(c,i*h,s*h,l,d,r,a,o,n),e._tint&&(e.ctx.globalCompositeOperation="multiply",e.ctx.fillStyle=e._tint.toString(),e.ctx.fillRect(r,a,o,n),e.ctx.globalCompositeOperation="source-over")},e._tint=null;let r=null;e._softFilter=()=>{throw new Error("Load q5-2d-soft-filters.js to use software filters.")},e.filter=(t,r)=>{if(!e.ctx.filter)return e._softFilter(t,r);if("string"==typeof t)f=t;else if(t==Q5.GRAY)f="saturate(0%)";else if(t==Q5.INVERT)f="invert(100%)";else if(t==Q5.BLUR){let t=Math.ceil(r*e._pixelDensity)||1;f=`blur(${t}px)`}else{if(t!=Q5.THRESHOLD)return e._softFilter(t,r);{r??=.5;let e=Math.floor(.5/Math.max(r,1e-5)*100);f=`saturate(0%) brightness(${e}%) contrast(1000000%)`}}e.ctx.filter=f,e.ctx.drawImage(e.canvas,0,0,e.canvas.w,e.canvas.h),e.ctx.filter="none"},"image"==e._scope&&(e.resize=(t,r)=>{let a=new e._OffscreenCanvas(e.canvas.width,e.canvas.height);a.getContext("2d",{colorSpace:e.canvas.colorSpace}).drawImage(e.canvas,0,0),e._setCanvasSize(t,r),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.drawImage(a,0,0,e.canvas.width,e.canvas.height)}),e._getImageData=(t,r,a,o)=>e.ctx.getImageData(t,r,a,o,{colorSpace:e.canvas.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,r=e.canvas.width,a=e.canvas.height,o=e._getImageData(0,0,r,a).data,n=r,i=0,s=a,l=0,d=3;for(let e=0;ei&&(i=t),el&&(l=e)),d+=4;return s=Math.floor(s/t),l=Math.floor(l/t),n=Math.floor(n/t),i=Math.floor(i/t),e.get(n,s,i-n+1,l-s+1)},e.mask=t=>{e.ctx.save(),e.ctx.resetTransform();let r=e.ctx.globalCompositeOperation;e.ctx.globalCompositeOperation="destination-in",e.ctx.drawImage(t.canvas,0,0),e.ctx.globalCompositeOperation=r,e.ctx.restore()},e.get=(t,r,a,o)=>{let n=e._pixelDensity||1;if(void 0!==t&&void 0===a){let a=e._getImageData(t*n,r*n,1,1).data;return new e.Color(a[0],a[1],a[2],a[3]/255)}t=(t||0)*n,r=(r||0)*n;let i=a=a||e.width,s=o=o||e.height;a*=n,o*=n;let l=e.createImage(a,o),d=e._getImageData(t,r,a,o);return l.ctx.putImageData(d,0,0),l._pixelDensity=n,l.width=i,l.height=s,l},e.set=(t,r,a)=>{if(a.canvas){let o=e._tint;return e._tint=null,e.image(a,t,r),void(e._tint=o)}e.pixels.length||e.loadPixels();let o=e._pixelDensity||1;for(let n=0;n{r=e._getImageData(0,0,e.canvas.width,e.canvas.height),t.pixels=r.data},e.updatePixels=()=>{null!=r&&e.ctx.putImageData(r,0,0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,"image"!=e._scope&&(e.tint=function(t){e._tint=t._q5Color?t:e.color(...arguments)},e.noTint=()=>e._tint=null)},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.q2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic";let r="sans-serif",a=12,o=15,n=3,i="normal",s=!1,l=0,d=[],c=!1,h=!1,u=0,p=12e3,_=e._textCache={};e.loadFont=(e,r)=>{t._preloadCount++;let a=e.split("/").pop().split(".")[0].replace(" ",""),o=new FontFace(a,`url(${e})`);return document.fonts.add(o),o.load().then((()=>{t._preloadCount--,r&&r(a)})),a},e.textFont=e=>{r=e,s=!0,l=-1},e.textSize=t=>{if(void 0===t)return a;e._da&&(t*=e._da),a=t,s=!0,l=-1,e._leadingSet||(o=1.25*t,n=o-t)},e.textStyle=e=>{i=e,s=!0,l=-1},e.textLeading=t=>{if(void 0===t)return o;e._da&&(t*=e._da),o=t,n=t-a,e._leadingSet=!0,l=-1},e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r),l=-1},e.textWidth=t=>e.ctx.measureText(t).width,e.textAscent=t=>e.ctx.measureText(t).actualBoundingBoxAscent,e.textDescent=t=>e.ctx.measureText(t).actualBoundingBoxDescent,e.textFill=e.fill,e.textStroke=e.stroke;e.textCache=(e,t)=>(t&&(p=t),void 0!==e&&(c=e),c),e.createTextImage=(t,r,a)=>(h=!0,img=e.text(t,0,0,r,a),h=!1,img);let m=[];e.text=(t,g,x,f,v)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString(),e._da&&(g*=e._da,x*=e._da);let y,w,b,M,S=e.ctx;if(s&&(S.font=`${i} ${a}px ${r}`,s=!1),(c||h)&&(-1==l&&(()=>{let e=r+a+i+o,t=5381;for(let r=0;r>>0})(),y=_[t],y&&(y=y[l]),y)){if(y._fill==e._fill&&y._stroke==e._stroke&&y._strokeWeight==e._strokeWeight)return h?y:e.textImage(y,g,x);y.clear()}if(-1==t.indexOf("\n")?m[0]=t:m=t.split("\n"),f){let e=[];for(let t of m){let r=0;for(;r=t.length){e.push(t.slice(r));break}let o=t.lastIndexOf(" ",a);(-1===o||ov)break;if(m.length=0,e._fillSet||(S.fillStyle=M),c||h){if(d.push(l),(_[t]??={})[l]=y,u++,u>p){let e=Math.ceil(u/2),t=d.splice(0,e);for(let e in _){e=_[e];for(let r of t)delete e[r]}u-=e}if(h)return y;e.textImage(y,g,x)}},e.textImage=(t,r,a)=>{let n=e._imageMode;e._imageMode="corner";let i=e._textAlign;"center"==i?r-=t.canvas.hw:"right"==i&&(r-=t.width);let s=e._textBaseline;"alphabetic"==s?a-=o:"middle"==s?a-=t._middle:"bottom"==s?a-=t._bottom:"top"==s&&(a-=t._top),e.image(t,r,a),e._imageMode=n},e.nf=(e,t,r)=>{let a=e<0,o=(e=Math.abs(e)).toFixed(r).split(".");o[0]=o[0].padStart(t,"0");let n=o.join(".");return a&&(n="-"+n),n}},Q5.modules.ai=e=>{e.askAI=(e="")=>{throw Error("Ask AI ✨ "+e)},e._aiErrorAssistance=async t=>{let r=t.message?.includes("Ask AI ✨");if(Q5.disableFriendlyErrors&&!r)return;!r&&Q5.errorTolerant||e.noLoop();let a=t.stack?.split("\n");if(!t.stack||a.length<=1)return;let o=1,n="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(o=0,n="@");a[o].indexOf("q5")>=0;)o++;let i=a[o].split(n).at(-1);i=i.split(":");let s=parseInt(i.at(-2));r&&s++;let l=i.slice(0,-2).join(":"),d=l.split("/").at(-1);try{let e=(await(await fetch(l)).text()).split("\n"),a=e[s-1].trim(),o="",n=1;for(;o.length<1600&&(s-n>=0&&(o=e[s-n].trim()+"\n"+o),s+n10?t.message.slice(10):"Whats+wrong+with+this+line%3F+short+answer")+(r?"":"%0A%0A"+encodeURIComponent(t.name+": "+t.message))+"%0A%0ALine%3A+"+encodeURIComponent(a)+"%0A%0AExcerpt+for+context%3A%0A%0A"+encodeURIComponent(o);if(console.warn("Error in "+d+" on line "+s+":\n\n"+a),console.warn("Ask AI ✨ "+i),r)return window.open(i,"_blank")}catch(e){}}},Q5.modules.color=(e,t)=>{e.RGB=e.RGBA=e._colorMode="rgb",e.OKLCH="oklch",e.colorMode=(r,a)=>{e._colorMode=r;let o="srgb"==e.canvas.colorSpace||"srgb"==r;if(a??=o?"integer":"float",e._colorFormat="float"==a||1==a?1:255,"oklch"==r)t.Color=Q5.ColorOKLCH;else{let r="srgb"==e.canvas.colorSpace;255==e._colorFormat?t.Color=r?Q5.ColorRGBA_8:Q5.ColorRGBA_P3_8:t.Color=r?Q5.ColorRGBA:Q5.ColorRGBA_P3,e._colorMode="rgb"}},e._namedColors={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],cyan:[0,255,255],darkviolet:[148,0,211],gold:[255,215,0],green:[0,128,0],gray:[128,128,128],grey:[128,128,128],hotpink:[255,105,180],indigo:[75,0,130],khaki:[240,230,140],lightgreen:[144,238,144],lime:[0,255,0],magenta:[255,0,255],navy:[0,0,128],orange:[255,165,0],olive:[128,128,0],peachpuff:[255,218,185],pink:[255,192,203],purple:[128,0,128],red:[255,0,0],skyblue:[135,206,235],tan:[210,180,140],turquoise:[64,224,208],transparent:[0,0,0,0],white:[255,255,255],violet:[238,130,238],yellow:[255,255,0]},e.color=(t,r,a,o)=>{let n=e.Color;if(t._q5Color)return new n(...t.levels);if(null==r){if("string"==typeof t){if("#"==t[0])t.length<=5?(t.length>4&&(o=parseInt(t[4]+t[4],16)),a=parseInt(t[3]+t[3],16),r=parseInt(t[2]+t[2],16),t=parseInt(t[1]+t[1],16)):(t.length>7&&(o=parseInt(t.slice(7,9),16)),a=parseInt(t.slice(5,7),16),r=parseInt(t.slice(3,5),16),t=parseInt(t.slice(1,3),16));else{if(!e._namedColors[t])return console.error("q5 can't parse color: "+t+"\nOnly numeric input, hex, and common named colors are supported."),new n(0,0,0);[t,r,a,o]=e._namedColors[t]}1==e._colorFormat&&(t/=255,r&&(r/=255),a&&(a/=255),o&&(o/=255))}Array.isArray(t)&&([t,r,a,o]=t)}return null==a?new n(t,t,t,r):new n(t,r,a,o)},e.red=e=>e.r,e.green=e=>e.g,e.blue=e=>e.b,e.alpha=e=>e.a,e.lightness=e=>e.l?e.l:100*(.2126*e.r+.7152*e.g+.0722*e.b)/255,e.hue=t=>{if(t.h)return t.h;let r=t.r,a=t.g,o=t.b;255==e._colorFormat&&(r/=255,a/=255,o/=255);let n,i=Math.max(r,a,o),s=Math.min(r,a,o);return n=i==s?0:i==r?60*(a-o)/(i-s):i==a?60*(o-r)/(i-s)+120:60*(r-a)/(i-s)+240,n<0&&(n+=360),n},e.lerpColor=(t,r,a)=>{if("rgb"==e._colorMode)return new e.Color(e.constrain(e.lerp(t.r,r.r,a),0,255),e.constrain(e.lerp(t.g,r.g,a),0,255),e.constrain(e.lerp(t.b,r.b,a),0,255),e.constrain(e.lerp(t.a,r.a,a),0,255));{let o=r.h-t.h;o>180&&(o-=360),o<-180&&(o+=360);let n=t.h+a*o;return n<0&&(n+=360),n>360&&(n-=360),new e.Color(e.constrain(e.lerp(t.l,r.l,a),0,100),e.constrain(e.lerp(t.c,r.c,a),0,100),n,e.constrain(e.lerp(t.a,r.a,a),0,255))}}},Q5.Color=class{constructor(){this._q5Color=!0}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,a){super(),this.l=e,this.c=t,this.h=r,this.a=a??1}toString(){return`oklch(${this.l} ${this.c} ${this.h} / ${this.a})`}},Q5.ColorRGBA=class extends Q5.Color{constructor(e,t,r,a){super(),this.r=e,this.g=t,this.b=r,this.a=a??1}get levels(){return[this.r,this.g,this.b,this.a]}toString(){return`color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGBA_P3=class extends Q5.ColorRGBA{toString(){return`color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGBA_8=class extends Q5.ColorRGBA{constructor(e,t,r,a){super(e,t,r,a??255)}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}get levels(){return[this.r,this.g,this.b,this.a]}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGBA_P3_8=class extends Q5.ColorRGBA{constructor(e,t,r,a){super(e,t,r,a??255),this._edited=!0}get r(){return this._r}set r(e){this._r=e,this._edited=!0}get g(){return this._g}set g(e){this._g=e,this._edited=!0}get b(){return this._b}set b(e){this._b=e,this._edited=!0}get a(){return this._a}set a(e){this._a=e,this._edited=!0}toString(){if(this._edited){let e=(this._r/255).toFixed(3),t=(this._g/255).toFixed(3),r=(this._b/255).toFixed(3),a=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${a})`,this._edited=!1}return this._css}},Q5.modules.display=e=>{if(!e.canvas||"graphics"==e._scope)return;let t=e.canvas;e.CENTERED="centered",e.FULLSCREEN="fullscreen",e.MAXED="maxed",e.PIXELATED="pixelated",0!=Q5._instanceCount||Q5._nodejs||document.head.insertAdjacentHTML("beforeend",""),e._adjustDisplay=()=>{let r=t.style,a=t.parentElement;r&&a&&t.displayMode&&("pixelated"==t.renderQuality&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),"normal"==t.displayMode?(a.classList.remove("q5-centered","q5-maxed","q5-fullscreen"),r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"):(a.classList.add("q5-"+t.displayMode),a=a.getBoundingClientRect(),t.w/t.h>a.width/a.height?("centered"==t.displayMode?(r.width=t.w*t.displayScale+"px",r.maxWidth="100%"):r.width="100%",r.height="auto",r.maxHeight=""):(r.width="auto",r.maxWidth="","centered"==t.displayMode?(r.height=t.h*t.displayScale+"px",r.maxHeight="100%"):r.height="100%")))},e.displayMode=(r="normal",a="default",o=1)=>{"string"==typeof o&&(o=parseFloat(o.slice(1))),Object.assign(t,{displayMode:r,renderQuality:a,displayScale:o}),e._adjustDisplay()},e.fullscreen=e=>{if(void 0===e)return document.fullscreenElement;e?document.body.requestFullscreen():document.body.exitFullscreen()}},Q5.modules.input=(e,t)=>{if("graphics"==e._scope)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.mouseButton=null,e.keyIsPressed=!1,e.mouseIsPressed=!1,e.key=null,e.keyCode=null,e.UP_ARROW=38,e.DOWN_ARROW=40,e.LEFT_ARROW=37,e.RIGHT_ARROW=39,e.SHIFT=16,e.TAB=9,e.BACKSPACE=8,e.ENTER=e.RETURN=13,e.ALT=e.OPTION=18,e.CONTROL=17,e.DELETE=46,e.ESCAPE=27,e.ARROW="default",e.CROSS="crosshair",e.HAND="pointer",e.MOVE="move",e.TEXT="text";let r={},a=[e.LEFT,e.CENTER,e.RIGHT],o=e.canvas;function n(t){const r=e.canvas.getBoundingClientRect(),a=e.canvas.scrollWidth/e.width||1,o=e.canvas.scrollHeight/e.height||1;return{x:(t.clientX-r.left)/a,y:(t.clientY-r.top)/o,id:t.identifier}}if(e._startAudio=()=>{e.getAudioContext&&"suspended"==e.getAudioContext()?.state&&e.userStartAudio()},e._updateMouse=r=>{if(!r.changedTouches)if(o){let a=o.getBoundingClientRect(),n=o.scrollWidth/e.width||1,i=o.scrollHeight/e.height||1;t.mouseX=(r.clientX-a.left)/n,t.mouseY=(r.clientY-a.top)/i,"webgpu"==o.renderer&&(t.mouseX-=o.hw,t.mouseY-=o.hh)}else t.mouseX=r.clientX,t.mouseY=r.clientY},e._onmousedown=r=>{e._startAudio(),e._updateMouse(r),t.mouseIsPressed=!0,t.mouseButton=a[r.button],e.mousePressed(r)},e._onmousemove=t=>{e._updateMouse(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t)},e._onmouseup=r=>{e._updateMouse(r),t.mouseIsPressed=!1,e.mouseReleased(r)},e._onclick=r=>{e._updateMouse(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e.cursor=(t,r,a)=>{let o="";t.includes(".")&&(t=`url("${t}")`,o=", auto"),void 0!==r&&(t+=" "+r+" "+a),e.canvas.style.cursor=t+o},e.noCursor=()=>{e.canvas.style.cursor="none"},e.requestPointerLock=document.body?.requestPointerLock,e.exitPointerLock=document.exitPointerLock,e._onkeydown=a=>{a.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(a),1==a.key.length&&e.keyTyped(a))},e._onkeyup=a=>{t.keyIsPressed=!1,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(a)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._ontouchstart=r=>{e._startAudio(),t.touches=[...r.touches].map(n),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,t.mouseIsPressed=!0,t.mouseButton=e.LEFT,e.mousePressed(r)||r.preventDefault()),e.touchStarted(r)||r.preventDefault()},e._ontouchmove=r=>{t.touches=[...r.touches].map(n),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,e.mouseDragged(r)||r.preventDefault()),e.touchMoved(r)||r.preventDefault()},e._ontouchend=r=>{t.touches=[...r.touches].map(n),e._isTouchAware||e.touches.length||(t.mouseIsPressed=!1,e.mouseReleased(r)||r.preventDefault()),e.touchEnded(r)||r.preventDefault()},o&&(o.addEventListener("mousedown",(t=>e._onmousedown(t))),o.addEventListener("mouseup",(t=>e._onmouseup(t))),o.addEventListener("click",(t=>e._onclick(t))),o.addEventListener("touchstart",(t=>e._ontouchstart(t))),o.addEventListener("touchmove",(t=>e._ontouchmove(t))),o.addEventListener("touchcancel",(t=>e._ontouchend(t))),o.addEventListener("touchend",(t=>e._ontouchend(t)))),window){let t=window.addEventListener;t("mousemove",(t=>e._onmousemove(t)),!1),t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1)}},Q5.modules.math=(e,t)=>{e.RADIANS=0,e.DEGREES=1,e.PI=Math.PI,e.HALF_PI=Math.PI/2,e.QUARTER_PI=Math.PI/4,e.abs=Math.abs,e.ceil=Math.ceil,e.exp=Math.exp,e.floor=Math.floor,e.loge=Math.log,e.mag=Math.hypot,e.max=Math.max,e.min=Math.min,e.round=Math.round,e.pow=Math.pow,e.sqrt=Math.sqrt,e.SHR3=1,e.LCG=2;let r=0;e.angleMode=t=>{"radians"==t&&(t=0),r=e._angleMode=t};let a=e._DEGTORAD=Math.PI/180,o=e._RADTODEG=180/Math.PI;function n(){let e,t,r=4294967295;return{setSeed(a){e=t=(a??Math.random()*r)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/r)}}e.degrees=t=>t*e._RADTODEG,e.radians=t=>t*e._DEGTORAD,e.map=Q5.prototype.map=(e,t,r,a,o,n)=>{let i=a+1*(e-t)/(r-t)*(o-a);return n?ae*(1-r)+t*r,e.constrain=(e,t,r)=>Math.min(Math.max(e,t),r),e.dist=function(){let e=arguments;return 4==e.length?Math.hypot(e[0]-e[2],e[1]-e[3]):Math.hypot(e[0]-e[3],e[1]-e[4],e[2]-e[5])},e.norm=(t,r,a)=>e.map(t,r,a,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*a:e),e.cos=e=>Math.cos(r?e*a:e),e.tan=e=>Math.tan(r?e*a:e),e.asin=e=>{let t=Math.asin(e);return r?t*o:t},e.acos=e=>{let t=Math.acos(e);return r?t*o:t},e.atan=e=>{let t=Math.atan(e);return r?t*o:t},e.atan2=(e,t)=>{let a=Math.atan2(e,t);return r?a*o:a};let i=n();i.setSeed(),e.randomSeed=e=>i.setSeed(e),e.random=(e,t)=>void 0===e?i.rand():"number"==typeof e?void 0!==t?i.rand()*(t-e)+e:i.rand()*e:e[Math.trunc(e.length*i.rand())],e.randomGenerator=t=>{t==e.LCG?i=function(){const e=4294967296;let t,r;return{setSeed(a){r=t=(a??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(i=n()),i.setSeed()};var s=new function(){var e,t,r,a=new Array(128),o=new Array(256),n=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*i.rand()-2147483648,h=()=>.5+2.328306e-10*(c()|0),u=()=>{for(var t,o,i,l,d=3.44262;;){if(t=r*n[e],0==e){do{i=h(),l=h(),t=.2904764*-Math.log(i),o=-Math.log(l)}while(o+o0?d+t:-d-t}if(s[e]+h()*(s[e-1]-s[e]){for(var r;;){if(0==e)return 7.69711-Math.log(h());if(r=t*l[e],d[e]+h()*(d[e-1]-d[e])(r=c(),e=127&r,Math.abs(r)(t=c()>>>0){var e,t,r=2147483648,i=4294967296,c=3.442619855899,h=c,u=.00991256303526217,p=7.697117470131487,_=p,m=.003949659822581572;for(e=u/Math.exp(-.5*c*c),a[0]=Math.floor(c/e*r),a[1]=0,n[0]=e/r,n[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),a[t+1]=Math.floor(c/h*r),h=c,s[t]=Math.exp(-.5*c*c),n[t]=c/r;for(e=m/Math.exp(-p),o[0]=Math.floor(p/e*i),o[1]=0,l[0]=e/i,l[255]=p/i,d[0]=1,d[255]=Math.exp(-p),t=254;t>=1;t--)p=-Math.log(m/p+Math.exp(-p)),o[t+1]=Math.floor(p/_*i),_=p,d[t]=Math.exp(-p),l[t]=p/i}};let l;s.hasInit=!1,e.randomGaussian=(e,t)=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.RNOR()*t+e),e.randomExponential=()=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.REXP()),e.PERLIN="perlin",e.SIMPLEX="simplex",e.BLOCKY="blocky",e.Noise=Q5.PerlinNoise,e.noiseMode=e=>{t.Noise=Q5[e[0].toUpperCase()+e.slice(1)+"Noise"],l=null},e.noiseSeed=t=>{l=new e.Noise(t)},e.noise=(t=0,r=0,a=0)=>(l??=new e.Noise,l.noise(t,r,a)),e.noiseDetail=(t,r)=>{l??=new e.Noise,t>0&&(l.octaves=t),r>0&&(l.falloff=r)}},Q5.Noise=class{},Q5.PerlinNoise=class extends Q5.Noise{constructor(e){super(),this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.octaves=1,this.falloff=.5,this.p=null==e?Array.from({length:256},(()=>Math.floor(256*Math.random()))):this.seedPermutation(e),this.p=this.p.concat(this.p)}seedPermutation(e){let t,r,a=[];for(let e=0;e<256;e++)a[e]=e;for(let o=255;o>0;o--)t=(e=16807*e%2147483647)%(o+1),r=a[o],a[o]=a[t],a[t]=r;return a}dot(e,t,r,a){return e[0]*t+e[1]*r+e[2]*a}mix(e,t,r){return(1-r)*e+r*t}fade(e){return e*e*e*(e*(6*e-15)+10)}noise(e,t,r){let a=this,o=0,n=1,i=1,s=0;for(let l=0;l{e.Sound=Q5.Sound,e.loadSound=(e,r)=>{t._preloadCount++,Q5.aud??=new window.AudioContext;let a=new Q5.Sound(e,r);return a.addEventListener("canplaythrough",(()=>{t._preloadCount--,a.loaded=!0,r&&r(a)})),a},e.getAudioContext=()=>Q5.aud,e.userStartAudio=()=>Q5.aud.resume()},Q5.Sound=class extends Audio{constructor(e){super(e);let t=this;t.load(),t.panner=Q5.aud.createStereoPanner(),t.source=Q5.aud.createMediaElementSource(t),t.source.connect(t.panner),t.panner.connect(Q5.aud.destination),Object.defineProperty(t,"pan",{get:()=>t.panner.pan.value,set:e=>t.panner.pan.value=e})}setVolume(e){this.volume=e}setLoop(e){this.loop=e}setPan(e){this.pan=e}isLoaded(){return this.loaded}isPlaying(){return!this.paused}},Q5.modules.util=(e,t)=>{e._loadFile=(e,r,a)=>{t._preloadCount++;let o={};return fetch(e).then((e=>"json"==a?e.json():"text"==a?e.text():void 0)).then((e=>{t._preloadCount--,Object.assign(o,e),r&&r(e)})),o},e.loadStrings=(t,r)=>e._loadFile(t,r,"text"),e.loadJSON=(t,r)=>e._loadFile(t,r,"json"),"object"==typeof localStorage&&(e.storeItem=localStorage.setItem,e.getItem=localStorage.getItem,e.removeItem=localStorage.removeItem,e.clearStorage=localStorage.clear),e.year=()=>(new Date).getFullYear(),e.day=()=>(new Date).getDay(),e.hour=()=>(new Date).getHours(),e.minute=()=>(new Date).getMinutes(),e.second=()=>(new Date).getSeconds()},Q5.modules.vector=e=>{e.createVector=(t,r,a)=>new Q5.Vector(t,r,a,e)},Q5.Vector=class{constructor(e,t,r,a){this.x=e||0,this.y=t||0,this.z=r||0,this._$=a||window,this._cn=null,this._cnsq=null}set(e,t,r){return this.x=e?.x||e||0,this.y=e?.y||t||0,this.z=e?.z||r||0,this}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,r){return void 0!==e?.x?e:void 0!==t?{x:e,y:t,z:r||0}:{x:e,y:e,z:e}}_calcNorm(){this._cnsq=this.x*this.x+this.y*this.y+this.z*this.z,this._cn=Math.sqrt(this._cnsq)}add(){let e=this._arg2v(...arguments);return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}rem(){let e=this._arg2v(...arguments);return this.x%=e.x,this.y%=e.y,this.z%=e.z,this}sub(){let e=this._arg2v(...arguments);return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}mult(){let e=this._arg2v(...arguments);return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}div(){let e=this._arg2v(...arguments);return e.x?this.x/=e.x:this.x=0,e.y?this.y/=e.y:this.y=0,e.z?this.z/=e.z:this.z=0,this}mag(){return this._calcNorm(),this._cn}magSq(){return this._calcNorm(),this._cnsq}dot(){let e=this._arg2v(...arguments);return this.x*e.x+this.y*e.y+this.z*e.z}dist(){let e=this._arg2v(...arguments),t=this.x-e.x,r=this.y-e.y,a=this.z-e.z;return Math.sqrt(t*t+r*r+a*a)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,a=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=a,this}normalize(){this._calcNorm();let e=this._cn;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._cn=1,this._cnsq=1,this}limit(e){this._calcNorm();let t=this._cn;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._cn=e,this._cnsq=e*e}return this}setMag(e){this._calcNorm();let t=e/this._cn;return this.x*=t,this.y*=t,this.z*=t,this._cn=e,this._cnsq=e*e,this}heading(){return this._$.atan2(this.y,this.x)}setHeading(e){let t=this.mag();return this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),a=this.x*t-this.y*r,o=this.x*r+this.y*t;return this.x=a,this.y=o,this}angleBetween(){let e=this._arg2v(...arguments),t=Q5.Vector.cross(this,e);return this._$.atan2(t.mag(),this.dot(e))*Math.sign(t.z||1)}lerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));return this.x+=(r.x-this.x)*t,this.y+=(r.y-this.y)*t,this.z+=(r.z-this.z)*t,this}slerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));if(1==t)return this.set(r);let a=this.mag(),o=r.mag();if(0==a||0==o)return this.mult(1-t).add(r.mult(t));let n=Q5.Vector.cross(this,r),i=n.mag(),s=Math.atan2(i,this.dot(r));if(i>0)n.div(i);else{if(se.copy().add(t),Q5.Vector.cross=(e,t)=>e.copy().cross(t),Q5.Vector.dist=(e,t)=>Math.hypot(e.x-t.x,e.y-t.y,e.z-t.z),Q5.Vector.div=(e,t)=>e.copy().div(t),Q5.Vector.dot=(e,t)=>e.copy().dot(t),Q5.Vector.equals=(e,t,r)=>e.equals(t,r),Q5.Vector.lerp=(e,t,r)=>e.copy().lerp(t,r),Q5.Vector.slerp=(e,t,r)=>e.copy().slerp(t,r),Q5.Vector.limit=(e,t)=>e.copy().limit(t),Q5.Vector.heading=e=>this._$.atan2(e.y,e.x),Q5.Vector.magSq=e=>e.x*e.x+e.y*e.y+e.z*e.z,Q5.Vector.mag=e=>Math.sqrt(Q5.Vector.magSq(e)),Q5.Vector.mult=(e,t)=>e.copy().mult(t),Q5.Vector.normalize=e=>e.copy().normalize(),Q5.Vector.rem=(e,t)=>e.copy().rem(t),Q5.Vector.sub=(e,t)=>e.copy().sub(t);for(let e of["fromAngle","fromAngles","random2D","random3D"])Q5.Vector[e]=(t,r,a)=>(new Q5.Vector)[e](t,r,a);Q5.renderers.webgpu={},Q5.renderers.webgpu.canvas=(e,t)=>{let r,a=e.canvas;a.width=e.width=500,a.height=e.height=500,e.colorMode&&e.colorMode("rgb","float"),e.pipelines=[];let o=e.drawStack=[],n=e.colorsStack=[1,1,1,1];e._envLayout=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform",hasDynamicOffset:!1}}]}),e._transformLayout=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage",hasDynamicOffset:!1}}]}),e.bindGroupLayouts=[e._envLayout,e._transformLayout];const i=Q5.device.createBuffer({size:8,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});e._createCanvas=(r,o,n)=>(t.ctx=t.drawingContext=a.getContext("webgpu"),n.format??=navigator.gpu.getPreferredCanvasFormat(),n.device??=Q5.device,e.ctx.configure(n),Q5.device.queue.writeBuffer(i,0,new Float32Array([e.canvas.hw,e.canvas.hh])),e._envBindGroup=Q5.device.createBindGroup({layout:e._envLayout,entries:[{binding:0,resource:{buffer:i}}]}),a),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r)};let s=0;const l=(t,r,a,o=1)=>{"string"==typeof t?t=e.color(t):null==a&&(o=r??1,r=a=t),t._q5Color?n.push(t.r,t.g,t.b,t.a):n.push(t,r,a,o),s++};e.fill=(t,r,a,o)=>{l(t,r,a,o),e._doFill=!0,e._fillIndex=s},e.stroke=(t,r,a,o)=>{l(t,r,a,o),e._doStroke=!0,e._strokeIndex=s},e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e._strokeWeight=1,e.strokeWeight=t=>e._strokeWeight=Math.abs(t),e.resetMatrix=()=>{e._matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],e._transformIndex=0},e.resetMatrix(),e._matrixDirty=!1,e.transformStates=[e._matrix.slice()],e._transformIndexStack=[],e.translate=(t,r,a)=>{(t||r||a)&&(e._matrix[3]+=t,e._matrix[7]-=r,e._matrix[11]+=a||0,e._matrixDirty=!0)},e.rotate=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.cos(t),a=Math.sin(t),o=e._matrix[0],n=e._matrix[1],i=e._matrix[4],s=e._matrix[5];o||n||i||s?(e._matrix[0]=o*r+i*a,e._matrix[1]=n*r+s*a,e._matrix[4]=o*-a+i*r,e._matrix[5]=n*-a+s*r):(e._matrix[0]=r,e._matrix[1]=a,e._matrix[4]=-a,e._matrix[5]=r),e._matrixDirty=!0},e.scale=(t=1,r,a=1)=>{r??=t,e._matrix[0]*=t,e._matrix[5]*=r,e._matrix[10]*=a,e._matrixDirty=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=e._matrix[0],o=e._matrix[1],n=e._matrix[4],i=e._matrix[5];e._matrix[0]=a+n*r,e._matrix[1]=o+i*r,e._matrixDirty=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=e._matrix[0],o=e._matrix[1],n=e._matrix[4],i=e._matrix[5];e._matrix[4]=n+a*r,e._matrix[5]=i+o*r,e._matrixDirty=!0},e.applyMatrix=(...t)=>{let r;if(r=1==t.length?t[0]:t,9==r.length)r=[r[0],r[1],0,r[2],r[3],r[4],0,r[5],0,0,1,0,r[6],r[7],0,r[8]];else if(16!=r.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");e._matrix=r.slice(),e._matrixDirty=!0},e._saveMatrix=()=>{e.transformStates.push(e._matrix.slice()),e._transformIndex=e.transformStates.length-1,e._matrixDirty=!1},e.pushMatrix=()=>{e._matrixDirty&&e._saveMatrix(),e._transformIndexStack.push(e._transformIndex)},e.popMatrix=()=>{if(!e._transformIndexStack.length)return console.warn("Matrix index stack is empty!");let t=e._transformIndexStack.pop();e._matrix=e.transformStates[t].slice(),e._transformIndex=t,e._matrixDirty=!1},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()},e._calcBox=(e,t,r,a,o)=>{let n,i,s,l,d=r/2,c=a/2;return o&&"corner"!=o?"center"==o?(n=e-d,i=e+d,s=-(t-c),l=-(t+c)):(n=e,i=r,s=-t,l=-a):(n=e,i=e+r,s=-t,l=-(t+a)),[n,i,s,l]},e.clear=()=>{},e._beginRender=()=>{e.encoder=Q5.device.createCommandEncoder(),r=t.pass=e.encoder.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store"}]})},e._render=()=>{if(transformStates.length>1||!e._transformBindGroup){const t=Q5.device.createBuffer({size:64*transformStates.length,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(t,0,new Float32Array(transformStates.flat())),e._transformBindGroup=Q5.device.createBindGroup({layout:e._transformLayout,entries:[{binding:0,resource:{buffer:t}}]})}r.setBindGroup(0,e._envBindGroup),r.setBindGroup(1,e._transformBindGroup);for(let t of e._hooks.preRender)t();let t=0,a=0,n=-1;r.setPipeline(e.pipelines[0]);for(let i=0;i{r.end();const a=e.encoder.finish();Q5.device.queue.submit([a]),t.pass=e.encoder=null,e.drawStack.length=0,e.colorsStack.length=4,s=0,rotation=0,e.transformStates.length=1,e._transformIndexStack.length=0}},Q5.webgpu=async function(e,t){if(e&&"global"!=e||(Q5._hasGlobal=!0),!navigator.gpu){console.warn("q5 WebGPU not supported on this browser!");let r=new Q5(e,t);return r.colorMode("rgb",1),r._beginRender=()=>r.translate(r.canvas.hw,r.canvas.hh),r}let r=await navigator.gpu.requestAdapter();if(!r)throw new Error("No appropriate GPUAdapter found.");return Q5.device=await r.requestDevice(),new Q5(e,t,"webgpu")},Q5.renderers.webgpu.drawing=(e,t)=>{let r,a,o=e.canvas,n=e.drawStack,i=e.colorsStack,s=[],l=Q5.device.createShaderModule({label:"drawingVertexShader",code:"\nstruct VertexOutput {\n\t@builtin(position) position: vec4,\n\t@location(1) colorIndex: f32\n};\n\nstruct Uniforms {\n\thalfWidth: f32,\n\thalfHeight: f32\n};\n\n@group(0) @binding(0) var uniforms: Uniforms;\n@group(1) @binding(0) var transforms: array>;\n\n@vertex\nfn vertexMain(@location(0) pos: vec2, @location(1) colorIndex: f32, @location(2) transformIndex: f32) -> VertexOutput {\n\tvar vert = vec4(pos, 0.0, 1.0);\n\tvert *= transforms[i32(transformIndex)];\n\tvert.x /= uniforms.halfWidth;\n\tvert.y /= uniforms.halfHeight;\n\n\tvar output: VertexOutput;\n\toutput.position = vert;\n\toutput.colorIndex = colorIndex;\n\treturn output;\n}\n"}),d=Q5.device.createShaderModule({label:"drawingFragmentShader",code:"\n@group(2) @binding(0) var uColors : array>;\n\n@fragment\nfn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 {\n\tlet index = u32(colorIndex);\n\treturn mix(uColors[index], uColors[index + 1u], fract(colorIndex));\n}\n"});a=Q5.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage",hasDynamicOffset:!1}}]}),e.bindGroupLayouts.push(a);let c={arrayStride:16,attributes:[{format:"float32x2",offset:0,shaderLocation:0},{format:"float32",offset:8,shaderLocation:1},{format:"float32",offset:12,shaderLocation:2}]},h=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],u=["add","subtract","reverse-subtract","min","max"];const p={normal:[2,3,0,2,3,0],lighter:[2,1,0,2,1,0],subtract:[2,1,2,2,1,2],multiply:[4,0,0,5,0,0],screen:[1,3,0,1,3,0],darken:[1,3,3,1,3,3],lighten:[1,3,4,1,3,4],overlay:[2,3,0,2,3,0],hard_light:[2,3,0,2,3,0],soft_light:[2,3,0,2,3,0],difference:[2,3,2,2,3,2],exclusion:[2,3,0,2,3,0],color_dodge:[1,7,0,1,7,0],color_burn:[6,1,0,6,1,0],linear_dodge:[2,1,0,2,1,0],linear_burn:[2,7,1,2,7,1],vivid_light:[2,7,0,2,7,0],pin_light:[2,7,0,2,7,0],hard_mix:[2,7,0,2,7,0]};e.blendConfigs={};for(const[t,r]of Object.entries(p))e.blendConfigs[t]={color:{srcFactor:h[r[0]],dstFactor:h[r[1]],operation:u[r[2]]},alpha:{srcFactor:h[r[3]],dstFactor:h[r[4]],operation:u[r[5]]}};e._blendMode="normal",e.blendMode=t=>{t!=e._blendMode&&("source-over"==t&&(t="normal"),t=t.toLowerCase().replace(/[ -]/g,"_"),e._blendMode=t,e.pipelines[0]=e._createPipeline(e.blendConfigs[t]))};let _,m=Q5.device.createPipelineLayout({label:"drawingPipelineLayout",bindGroupLayouts:e.bindGroupLayouts});e._createPipeline=e=>Q5.device.createRenderPipeline({label:"drawingPipeline",layout:m,vertex:{module:l,entryPoint:"vertexMain",buffers:[c]},fragment:{module:d,entryPoint:"fragmentMain",targets:[{format:"bgra8unorm",blend:e}]},primitive:{topology:"triangle-list"}}),e.pipelines[0]=e._createPipeline(e.blendConfigs.normal),e.beginShape=()=>{_=[]},e.vertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),_.push(t,-r,e._fillIndex,e._transformIndex)},e.endShape=t=>{if(!e._doFill)return void(_=[]);let r=_;if(r.length<12)throw new Error("A shape must have at least 3 vertices.");t&&r.push(r[0],r[1],r[2],r[3]);let a=[];for(let e=4;e{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.endShape(1)},e.quad=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.vertex(s,l),e.endShape(1)},e.rectMode=t=>e._rectMode=t,e.rect=(t,a,o,i)=>{let[l,d,c,h]=e._calcBox(t,a,o,i,e._rectMode),u=r??e._fillIndex;e._matrixDirty&&e._saveMatrix();let p=e._transformIndex;s.push(l,c,u,p,d,c,u,p,l,h,u,p,d,c,u,p,l,h,u,p,d,h,u,p),n.push(0,6)},e.square=(t,r,a)=>e.rect(t,r,a,a),e.point=(t,a)=>{r=e._strokeIndex;let o=e._strokeWeight;o<2?(o=Math.round(o),e.rect(t,a,o,o)):e.ellipse(t,a,o,o),r=null},e.line=(t,a,o,n)=>{r=e._strokeIndex,e.push(),e.translate(t,a),e.rotate(e.atan2(n-a,o-t));let i=Math.sqrt((o-t)**2+(n-a)**2),s=e._strokeWeight;e.rect(0,-s/2,i,s),e.pop(),r=null},e.background=(t,r,a,n)=>{e.push(),e.resetMatrix(),t.src?e.image(t,-o.hw,-o.hh,o.w,o.h):(e.fill(t,r,a,n),e.rect(-o.hw,-o.hh,o.w,o.h)),e.pop()};e.ellipseMode=t=>e._ellipseMode=t,e.ellipse=(t,a,o,i)=>{const l=(d=o==i?o:Math.max(o,i))<4?6:d<6?8:d<10?10:d<16?12:d<20?14:d<22?16:d<24?18:d<28?20:d<34?22:d<42?24:d<48?26:d<56?28:d<64?30:d<72?32:d<84?34:d<96?36:d<98?38:d<113?40:d<149?44:d<199?48:d<261?52:d<353?56:d<461?60:d<585?64:d<1200?70:d<1800?80:d<2400?90:100;var d;let c=Math.max(o,1)/2,h=o==i?c:Math.max(i,1)/2,u=0;const p=e.TAU/l,_=r??e._fillIndex;e._matrixDirty&&e._saveMatrix();const m=e._transformIndex;let g,x,f,v;for(let e=0;e<=l;e++)g=f,x=v,f=t+c*Math.cos(u),v=a+h*Math.sin(u),u+=p,0!=e&&s.push(t,a,_,m,g,x,_,m,f,v,_,m);n.push(0,3*l)},e.circle=(t,r,a)=>e.ellipse(t,r,a,a),e._hooks.preRender.push((()=>{e.pass.setPipeline(e.pipelines[0]);const t=new Float32Array(s),r=Q5.device.createBuffer({size:t.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(r,0,t),e.pass.setVertexBuffer(0,r);const o=Q5.device.createBuffer({size:4*i.length,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(o,0,new Float32Array(i)),e._colorsBindGroup=Q5.device.createBindGroup({layout:a,entries:[{binding:0,resource:{buffer:o,offset:0,size:4*i.length}}]}),e.pass.setBindGroup(2,e._colorsBindGroup)})),e._hooks.postRender.push((()=>{s.length=0}))},Q5.renderers.webgpu.image=(e,t)=>{e._textureBindGroups=[];let r=[],a=Q5.device.createShaderModule({label:"imageVertexShader",code:"\nstruct VertexOutput {\n\t@builtin(position) position: vec4,\n\t@location(0) texCoord: vec2\n};\n\nstruct Uniforms {\n\thalfWidth: f32,\n\thalfHeight: f32\n};\n\n@group(0) @binding(0) var uniforms: Uniforms;\n@group(1) @binding(0) var transforms: array>;\n\n@vertex\nfn vertexMain(@location(0) pos: vec2, @location(1) texCoord: vec2, @location(2) transformIndex: f32) -> VertexOutput {\n\tvar vert = vec4(pos, 0.0, 1.0);\n\tvert *= transforms[i32(transformIndex)];\n\tvert.x /= uniforms.halfWidth;\n\tvert.y /= uniforms.halfHeight;\n\n\tvar output: VertexOutput;\n\toutput.position = vert;\n\toutput.texCoord = texCoord;\n\treturn output;\n}\n\t"}),o=Q5.device.createShaderModule({label:"imageFragmentShader",code:"\n@group(3) @binding(0) var samp: sampler;\n@group(3) @binding(1) var texture: texture_2d;\n\n@fragment\nfn fragmentMain(@location(0) texCoord: vec2) -> @location(0) vec4 {\n\t// Sample the texture using the interpolated texture coordinate\n\treturn textureSample(texture, samp, texCoord);\n}\n\t"}),n=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]});e.bindGroupLayouts.push(n);const i=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:e.bindGroupLayouts});e.pipelines[1]=Q5.device.createRenderPipeline({label:"imagePipeline",layout:i,vertex:{module:a,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},{arrayStride:20,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"},{shaderLocation:2,offset:16,format:"float32"}]}]},fragment:{module:o,entryPoint:"fragmentMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs?.normal||{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}});let s=Q5.device.createSampler({magFilter:"linear",minFilter:"linear"});e._textures=[];let l=0;e._createTexture=t=>{t.canvas&&(t=t.canvas);let r=[t.width,t.height,1],a=Q5.device.createTexture({size:r,format:"bgra8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:t},{texture:a,colorSpace:e.canvas.colorSpace},r),e._textures[l]=a,t.textureIndex=l;const o=Q5.device.createBindGroup({layout:n,entries:[{binding:0,resource:s},{binding:1,resource:a.createView()}]});e._textureBindGroups[l]=o,l=(l+1)%12e3,e._textures[l]&&(e._textures[l].destroy(),delete e._textures[l],delete e._textureBindGroups[l])},e.loadImage=e.loadTexture=r=>{t._preloadCount++;const a=new Image;return a.crossOrigin="Anonymous",a.onload=()=>{e._createTexture(a),t._preloadCount--},a.src=r,a},e.imageMode=t=>e._imageMode=t,e.image=(t,a,o,n,i)=>{if(t.canvas&&(t=t.canvas),null==t.textureIndex)return;e._matrixDirty&&e._saveMatrix();let s=e._transformIndex;n??=t.width/e._pixelDensity,i??=t.height/e._pixelDensity;let[l,d,c,h]=e._calcBox(a,o,n,i,e._imageMode);r.push(l,c,0,0,s,d,c,1,0,s,l,h,0,1,s,d,c,1,0,s,l,h,0,1,s,d,h,1,1,s),e.drawStack.push(1,t.textureIndex)},e._hooks.preRender.push((()=>{if(!e._textureBindGroups.length)return;e.pass.setPipeline(e.pipelines[1]);const t=new Float32Array(r),a=Q5.device.createBuffer({size:t.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(a,0,t),e.pass.setVertexBuffer(1,a)})),e._hooks.postRender.push((()=>{r.length=0}))},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.webgpu.text=(e,t)=>{let r=e.createGraphics(1,1);r.pixelDensity(e._pixelDensity),r._imageMode="corner",e.loadFont=e=>(t._preloadCount++,r.loadFont(e,(()=>{t._preloadCount--}))),e.textFont=r.textFont,e.textSize=r.textSize,e.textLeading=r.textLeading,e.textStyle=r.textStyle,e.textAlign=r.textAlign,e.textWidth=r.textWidth,e.textAscent=r.textAscent,e.textDescent=r.textDescent,e.textFill=(t,a,o,n)=>r.fill(e.color(t,a,o,n)),e.textStroke=(t,a,o,n)=>r.stroke(e.color(t,a,o,n)),e.text=(t,a,o,n,i)=>{let s=r.createTextImage(t,n,i);if(void 0===s.canvas.textureIndex)e._createTexture(s);else if(s.modified){let t=s.canvas,r=[t.width,t.height,1],a=e._textures[t.textureIndex];Q5.device.queue.copyExternalImageToTexture({source:t},{texture:a,colorSpace:e.canvas.colorSpace},r),s.modified=!1}e.textImage(s,a,o)},e.createTextImage=r.createTextImage,e.textImage=(t,a,o)=>{let n=e._imageMode;e._imageMode="corner";let i=r._textAlign;"center"==i?a-=t.canvas.hw:"right"==i&&(a-=t.width);let s=r._textBaseline;"alphabetic"==s?o-=r._textLeading:"middle"==s?o-=t._middle:"bottom"==s?o-=t._bottom:"top"==s&&(o-=t._top),e.image(t,a,o),e._imageMode=n}}; +function Q5(e,t,r){let a,n=this;if(n._q5=!0,n._parent=t,n._renderer=r||"q2d",n._preloadCount=0,e??="global","auto"==e){if(!window.setup&&!window.draw)return;e="global"}n._scope=e,"global"==e&&(Q5._hasGlobal=n._isGlobal=!0,a=Q5._nodejs?global:window);let o=new Proxy(n,{set:(e,t,r)=>(n[t]=r,n._isGlobal&&(a[t]=r),!0)});n.canvas=n.ctx=n.drawingContext=null,n.pixels=[];let i=null;n.frameCount=0,n.deltaTime=16,n._targetFrameRate=0,n._targetFrameDuration=16.666666666666668,n._frameRate=n._fps=60,n._loop=!0,n._hooks={postCanvas:[],preRender:[],postRender:[]};let s=0;n.millis=()=>performance.now()-s,n.noCanvas=()=>{n.canvas?.remove&&n.canvas.remove(),n.canvas=0,o.ctx=o.drawingContext=0},window&&(n.windowWidth=window.innerWidth,n.windowHeight=window.innerHeight,n.deviceOrientation=window.screen?.orientation?.type),n._incrementPreload=()=>o._preloadCount++,n._decrementPreload=()=>o._preloadCount--,n._draw=e=>{let t=e||performance.now();if(n._lastFrameTime??=t-n._targetFrameDuration,n._didResize&&(n.windowResized(),n._didResize=!1),n._loop)i=d(n._draw);else if(n.frameCount&&!n._redraw)return;if(i&&n.frameCount){if(t-n._lastFrameTime{n._loop=!1,i=null},n.loop=()=>{n._loop=!0,null==i&&n._draw()},n.isLooping=()=>n._loop,n.redraw=(e=1)=>{n._redraw=!0;for(let t=0;t{n.noLoop(),n.canvas.remove()},n.frameRate=e=>(e&&(n._targetFrameRate=e,n._targetFrameDuration=1e3/e),n._frameRate),n.getTargetFrameRate=()=>n._targetFrameRate,n.getFPS=()=>n._fps,n.Element=function(e){this.elt=e},n._elements=[],n.TWO_PI=n.TAU=2*Math.PI,n.log=n.print=console.log,n.describe=()=>{};for(let e in Q5.modules)Q5.modules[e](n,o);let l=Q5.renderers[n._renderer];for(let e in l)l[e](n,o);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(n[e]=Q5[e]);if("graphics"==e)return;"global"==e&&(Object.assign(Q5,n),delete Q5.Q5);for(let e of Q5.methods.init)e.call(n);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof n[e]&&(n[e]=t.bind(n));if("global"==e){let e=Object.getOwnPropertyNames(n);for(let t of e)"_"!=t[0]&&(a[t]=n[t])}"function"==typeof e&&e(n),Q5._instanceCount++;let d=window.requestAnimationFrame||function(e){const t=n._lastFrameTime+n._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},c=a||n;n._isTouchAware=c.touchStarted||c.touchMoved||c.mouseReleased;let h=c.preload,u=["setup","draw","preload","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of u)c[e]?n._isGlobal&&(n[e]=()=>{try{return c[e]()}catch(e){throw n._aiErrorAssistance&&n._aiErrorAssistance(e),e}}):n[e]=()=>{};async function p(){if(n._startDone=!0,n._preloadCount>0)return d(p);s=performance.now(),await n.setup(),n.frameCount||(null===n.ctx&&n.createCanvas(100,100),n._setupDone=!0,n.ctx&&n.resetMatrix(),d(n._draw))}(n.setup||n.draw)&&(arguments.length&&"namespace"!=e&&"webgpu"!=r||h?(n.preload(),p()):(c.preload=n.preload=()=>{n._startDone||p()},setTimeout(n.preload,32)))}Q5.renderers={},Q5.modules={},Q5._nodejs="object"==typeof process,Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{throw Error(t+": "+e)},Q5._validateParameters=()=>!0,Q5.methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.methods[e].push(t),Q5.prototype.registerPreloadMethod=(e,t)=>Q5.prototype[e]=t[e],Q5._nodejs?global.p5??=global.Q5=Q5:"object"==typeof window?window.p5??=window.Q5=Q5:global.window=0,"object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")})),Q5.modules.canvas=(e,t)=>{e.CENTER="center",e.LEFT="left",e.RIGHT="right",e.TOP="top",e.BOTTOM="bottom",e.BASELINE="alphabetic",e.NORMAL="normal",e.ITALIC="italic",e.BOLD="bold",e.BOLDITALIC="italic bold",e.ROUND="round",e.SQUARE="butt",e.PROJECT="square",e.MITER="miter",e.BEVEL="bevel",e.CHORD=0,e.PIE=1,e.OPEN=2,e.RADIUS="radius",e.CORNER="corner",e.CORNERS="corners",e.CLOSE=1,e.LANDSCAPE="landscape",e.PORTRAIT="portrait",e.BLEND="source-over",e.REMOVE="destination-out",e.ADD="lighter",e.DARKEST="darken",e.LIGHTEST="lighten",e.DIFFERENCE="difference",e.SUBTRACT="subtract",e.EXCLUSION="exclusion",e.MULTIPLY="multiply",e.SCREEN="screen",e.REPLACE="copy",e.OVERLAY="overlay",e.HARD_LIGHT="hard-light",e.SOFT_LIGHT="soft-light",e.DODGE="color-dodge",e.BURN="color-burn",e.P2D="2d",e.WEBGL="webgl",e._OffscreenCanvas=window.OffscreenCanvas||function(){return document.createElement("canvas")},Q5._nodejs?Q5._createNodeJSCanvas&&(t.canvas=Q5._createNodeJSCanvas(100,100)):"image"!=e._scope&&"graphics"!=e._scope||(t.canvas=new e._OffscreenCanvas(100,100)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas());let r=e.canvas;if(r.width=e.width=100,r.height=e.height=100,e._pixelDensity=1,e.displayDensity=()=>window.devicePixelRatio||1,"image"!=e._scope&&(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity())),e._adjustDisplay=()=>{r.style&&(r.style.width=r.w+"px",r.style.height=r.h+"px")},e.createCanvas=function(t,a,n){n??=arguments[3];let o=Object.assign({},Q5.canvasOptions);"object"==typeof n&&Object.assign(o,n),"image"!=e._scope&&("graphics"==e._scope?e._pixelDensity=this._pixelDensity:window.IntersectionObserver&&new IntersectionObserver((e=>{r.visible=e[0].isIntersecting})).observe(r)),e._setCanvasSize(t,a),Object.assign(r,o);let i=e._createCanvas(r.w,r.h,o);if(e._hooks)for(let t of e._hooks.postCanvas)t();return i},e.createGraphics=function(t,r,a){let n=new Q5("graphics");return a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace,n.createCanvas.call(e,t,r,a),n},e._save=async(e,t,r)=>{if(t=t||"untitled","jpg"==(r=r||"png")||"png"==r||"webp"==r)if(e instanceof OffscreenCanvas){const t=await e.convertToBlob({type:"image/"+r});e=await new Promise((e=>{const r=new FileReader;r.onloadend=()=>e(r.result),r.readAsDataURL(t)}))}else e=e.toDataURL("image/"+r);else{let t="text/plain";"json"==r&&("string"!=typeof e&&(e=JSON.stringify(e)),t="text/json"),e=new Blob([e],{type:t}),e=URL.createObjectURL(e)}let a=document.createElement("a");a.href=e,a.download=t+"."+r,a.click(),URL.revokeObjectURL(a.href)},e.save=(t,r,a)=>{if((!t||"string"==typeof t&&(!r||!a&&r.length<5))&&(a=r,r=t,t=e.canvas),a)return e._save(t,r,a);r?(r=r.split("."),e._save(t,r[0],r.at(-1))):e._save(t)},e._setCanvasSize=(a,n)=>{a??=window.innerWidth,n??=window.innerHeight,r.w=a=Math.ceil(a),r.h=n=Math.ceil(n),r.hw=a/2,r.hh=n/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(n*e._pixelDensity),e._da?e.flexibleCanvas(e._dau):(t.width=a,t.height=n),e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay()},"image"!=e._scope){if(r&&"graphics"!=e._scope){function a(){let t=e._parent;t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),r.parent(t)}r.parent=t=>{function a(){e.frameCount>1&&(e._didResize=!0,e._adjustDisplay())}r.parentElement&&r.parentElement.removeChild(r),"string"==typeof t&&(t=document.getElementById(t)),t.append(r),"function"==typeof ResizeObserver?(e._ro&&e._ro.disconnect(),e._ro=new ResizeObserver(a),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",a)},document.body?a():document.addEventListener("DOMContentLoaded",a)}e.resizeCanvas=(t,a)=>{if(!e.ctx)return e.createCanvas(t,a);t==r.w&&a==r.h||e._resizeCanvas(t,a)},e.canvas.resize=e.resizeCanvas,e.canvas.save=e.saveCanvas=e.save,e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._setCanvasSize(r.w,r.h),t):e._pixelDensity,e.flexibleCanvas=(a=400)=>{a?(e._da=r.width/(a*e._pixelDensity),t.width=e._dau=a,t.height=r.h/r.w*a):e._da=0},e._styleNames=["_doStroke","_doFill","_strokeSet","_fillSet","_tint","_imageMode","_rectMode","_ellipseMode","_textSize","_textAlign","_textBaseline"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t)},e.popStyles=()=>{let t=e._styles.pop();for(let r of e._styleNames)e[r]=t[r]},window&&"graphics"!=e._scope&&window.addEventListener("resize",(()=>{e._didResize=!0,t.windowWidth=window.innerWidth,t.windowHeight=window.innerHeight,t.deviceOrientation=window.screen?.orientation?.type}))}},Q5.canvasOptions={alpha:!1,colorSpace:"display-p3"},window.matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches?Q5.supportsHDR=!0:Q5.canvasOptions.colorSpace="srgb",Q5.renderers.q2d={},Q5.renderers.q2d.canvas=(e,t)=>{let r=e.canvas;e.colorMode&&e.colorMode("rgb","integer"),e._createCanvas=function(a,n,o){return t.ctx=t.drawingContext=r.getContext("2d",o),"image"!=e._scope&&(e.ctx.fillStyle="white",e.ctx.strokeStyle="black",e.ctx.lineCap="round",e.ctx.lineJoin="miter",e.ctx.textAlign="left"),e.ctx.scale(e._pixelDensity,e._pixelDensity),e.ctx.save(),r},e.clear=()=>{e.ctx.save(),e.ctx.resetTransform(),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.restore()},"image"!=e._scope&&(e._resizeCanvas=(t,a)=>{let n,o={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(o[t]=e.ctx[t]);if(delete o.canvas,e.frameCount>1){n=new e._OffscreenCanvas(r.width,r.height),n.w=r.w,n.h=r.h,n.getContext("2d").drawImage(r,0,0)}e._setCanvasSize(t,a);for(let t in o)e.ctx[t]=o[t];e.scale(e._pixelDensity),n&&e.ctx.drawImage(n,0,0,n.w,n.h)},e.fill=function(t){if(e._doFill=!0,e._fillSet=!0,Q5.Color&&(t._q5Color||("string"!=typeof t?t=e.color(...arguments):e._namedColors[t]&&(t=e.color(...e._namedColors[t]))),t.a<=0))return e._doFill=!1;e.ctx.fillStyle=e._fill=t.toString()},e.noFill=()=>e._doFill=!1,e.stroke=function(t){if(e._doStroke=!0,e._strokeSet=!0,Q5.Color&&(t._q5Color||("string"!=typeof t?t=e.color(...arguments):e._namedColors[t]&&(t=e.color(...e._namedColors[t]))),t.a<=0))return e._doStroke=!1;e.ctx.strokeStyle=e._stroke=t.toString()},e.strokeWeight=t=>{t||(e._doStroke=!1),e._da&&(t*=e._da),e.ctx.lineWidth=e._strokeWeight=t||1e-4},e.noStroke=()=>e._doStroke=!1,e.opacity=t=>e.ctx.globalAlpha=t,e.translate=(t,r)=>{e._da&&(t*=e._da,r*=e._da),e.ctx.translate(t,r)},e.rotate=t=>{e._angleMode&&(t=e.radians(t)),e.ctx.rotate(t)},e.scale=(t,r)=>{r??=t,e.ctx.scale(t,r)},e.applyMatrix=(t,r,a,n,o,i)=>e.ctx.transform(t,r,a,n,o,i),e.shearX=t=>e.ctx.transform(1,0,e.tan(t),1,0,0),e.shearY=t=>e.ctx.transform(1,e.tan(t),0,1,0,0),e.resetMatrix=()=>{e.ctx.resetTransform(),e.scale(e._pixelDensity)},e.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore(),e.push=()=>{e.ctx.save(),e.pushStyles()},e.pop=()=>{e.ctx.restore(),e.popStyles()},e.createCapture=e=>{var t=document.createElement("video");return t.playsinline="playsinline",t.autoplay="autoplay",navigator.mediaDevices.getUserMedia(e).then((e=>{t.srcObject=e})),t.style.position="absolute",t.style.opacity=1e-5,t.style.zIndex=-1e3,document.body.append(t),t})},Q5.renderers.q2d.drawing=e=>{e._doStroke=!0,e._doFill=!0,e._strokeSet=!1,e._fillSet=!1,e._ellipseMode=e.CENTER,e._rectMode=e.CORNER,e._curveDetail=20,e._curveAlpha=0;let t=!0,r=[];function a(){e._doFill&&e.ctx.fill(),e._doStroke&&e.ctx.stroke()}function n(t,r,n,o,i,s,l,d){if(!e._doFill&&!e._doStroke)return;let c=e._angleMode,h=c?360:e.TAU;if((i%=h)<0&&(i+=h),(s%=h)<0&&(s+=h),0!=i||0!=s){if(i>s&&([i,s]=[s,i]),e.ctx.beginPath(),n==o)c&&(i=e.radians(i),s=e.radians(s)),e.ctx.arc(t,r,n/2,i,s);else{for(let a=0;ae.ctx.globalCompositeOperation=t,e.strokeCap=t=>e.ctx.lineCap=t,e.strokeJoin=t=>e.ctx.lineJoin=t,e.ellipseMode=t=>e._ellipseMode=t,e.rectMode=t=>e._rectMode=t,e.curveDetail=t=>e._curveDetail=t,e.curveAlpha=t=>e._curveAlpha=t,e.curveTightness=t=>e._curveAlpha=t,e.background=function(t){e.ctx.save(),e.ctx.resetTransform(),t.canvas?e.image(t,0,0,e.width,e.height):(Q5.Color&&!t._q5Color&&("string"!=typeof t?t=e.color(...arguments):e._namedColors[t]&&(t=e.color(...e._namedColors[t]))),e.ctx.fillStyle=t.toString(),e.ctx.fillRect(0,0,e.canvas.width,e.canvas.height)),e.ctx.restore()},e.line=(t,r,a,n)=>{e._doStroke&&(e._da&&(t*=e._da,r*=e._da,a*=e._da,n*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(a,n),e.ctx.stroke())},e.arc=(t,r,a,o,i,s,l,d=25)=>{if(i==s)return e.ellipse(t,r,a,o);l??=e.PIE,e._ellipseMode==e.CENTER?n(t,r,a,o,i,s,l,d):e._ellipseMode==e.RADIUS?n(t,r,2*a,2*o,i,s,l,d):e._ellipseMode==e.CORNER?n(t+a/2,r+o/2,a,o,i,s,l,d):e._ellipseMode==e.CORNERS&&n((t+a)/2,(r+o)/2,a-t,o-r,i,s,l,d)},e.ellipse=(t,r,a,n)=>{n??=a,e._ellipseMode==e.CENTER?o(t,r,a,n):e._ellipseMode==e.RADIUS?o(t,r,2*a,2*n):e._ellipseMode==e.CORNER?o(t+a/2,r+n/2,a,n):e._ellipseMode==e.CORNERS&&o((t+a)/2,(r+n)/2,a-t,n-r)},e.circle=(t,r,n)=>{e._ellipseMode==e.CENTER?(e._da&&(t*=e._da,r*=e._da,n*=e._da),e.ctx.beginPath(),e.ctx.arc(t,r,n/2,0,e.TAU),a()):e.ellipse(t,r,n,n)},e.point=(t,r)=>{t.x&&(r=t.y,t=t.x),e._da&&(t*=e._da,r*=e._da),e.ctx.save(),e.ctx.beginPath(),e.ctx.arc(t,r,e.ctx.lineWidth/2,0,e.TAU),e.ctx.fillStyle=e.ctx.strokeStyle,e.ctx.fill(),e.ctx.restore()},e.rect=(t,r,a,n=a,o,s,l,d)=>{e._rectMode==e.CENTER?i(t-a/2,r-n/2,a,n,o,s,l,d):e._rectMode==e.RADIUS?i(t-a,r-n,2*a,2*n,o,s,l,d):e._rectMode==e.CORNER?i(t,r,a,n,o,s,l,d):e._rectMode==e.CORNERS&&i(t,r,a-t,n-r,o,s,l,d)},e.square=(t,r,a,n,o,i,s)=>e.rect(t,r,a,a,n,o,i,s),e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(a,n)=>{e._da&&(a*=e._da,n*=e._da),r=[],t?e.ctx.moveTo(a,n):e.ctx.lineTo(a,n),t=!1},e.bezierVertex=(t,a,n,o,i,s)=>{e._da&&(t*=e._da,a*=e._da,n*=e._da,o*=e._da,i*=e._da,s*=e._da),r=[],e.ctx.bezierCurveTo(t,a,n,o,i,s)},e.quadraticVertex=(t,a,n,o)=>{e._da&&(t*=e._da,a*=e._da,n*=e._da,o*=e._da),r=[],e.ctx.quadraticCurveTo(t,a,n,o)},e.bezier=(t,r,a,n,o,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,n,o,i,s,l),e.endShape()},e.triangle=(t,r,a,n,o,i)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,n),e.vertex(o,i),e.endShape(e.CLOSE)},e.quad=(t,r,a,n,o,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,n),e.vertex(o,i),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),a()},e.curveVertex=(a,n)=>{if(e._da&&(a*=e._da,n*=e._da),r.push([a,n]),r.length<4)return;let o=function(e,t,r,a,n,o,i,s,l,d){function c(e,t,r,a,n,o){let i=Math.pow(a-t,2)+Math.pow(n-r,2);return Math.pow(i,.5*o)+e}let h=[],u=c(0,e,t,r,a,d),p=c(u,r,a,n,o,d),f=c(p,n,o,i,s,d);for(let d=0;d0?(g[e]=1,g[e+1]=0):(g[e]=0,g[e+1]=1));let _=e*g[0]+r*g[1],x=t*g[0]+a*g[1],m=r*g[2]+n*g[3],v=a*g[2]+o*g[3],y=n*g[4]+i*g[5],w=o*g[4]+s*g[5],b=_*g[6]+m*g[7],S=x*g[6]+v*g[7],M=m*g[8]+y*g[9],C=v*g[8]+w*g[9],R=b*g[2]+M*g[3],Q=S*g[2]+C*g[3];h.push([R,Q])}return h}(...r.at(-4),...r.at(-3),...r.at(-2),...r.at(-1),e._curveDetail,e._curveAlpha);for(let r=0;r{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,n),e.curveVertex(o,i),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,a,n)=>{const o=n*n*n,i=n*n;return e*(-.5*o+i-.5*n)+t*(1.5*o-2.5*i+1)+r*(-1.5*o+2*i+.5*n)+a*(.5*o-.5*i)},e.bezierPoint=(e,t,r,a,n)=>{const o=1-n;return Math.pow(o,3)*e+3*Math.pow(o,2)*n*t+3*o*Math.pow(n,2)*r+Math.pow(n,3)*a},e.curveTangent=(e,t,r,a,n)=>{const o=n*n;return e*(-3*o/2+2*n-.5)+t*(9*o/2-5*n)+r*(-9*o/2+4*n+.5)+a*(3*o/2-n)},e.bezierTangent=(e,t,r,a,n)=>{const o=1-n;return 3*a*Math.pow(n,2)-3*r*Math.pow(n,2)+6*r*o*n-6*t*o*n+3*t*Math.pow(o,2)-3*e*Math.pow(o,2)},e.erase=function(t=255,r=255){e.ctx.save(),e.ctx.globalCompositeOperation="destination-out",e.ctx.fillStyle=`rgba(0, 0, 0, ${t/255})`,e.ctx.strokeStyle=`rgba(0, 0, 0, ${r/255})`},e.noErase=function(){e.ctx.globalCompositeOperation="source-over",e.ctx.restore()},e.inFill=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInPath(t*a,r*a)},e.inStroke=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInStroke(t*a,r*a)}},Q5.renderers.q2d.image=(e,t)=>{Q5.Image??=class{constructor(e,t,r){let a=this;a._scope="image",a.canvas=a.ctx=a.drawingContext=null,a.pixels=[],Q5.modules.canvas(a,a);let n=Q5.renderers.q2d;for(let e of["canvas","image","soft_filters"])n[e]&&n[e](a,a);a._pixelDensity=r.pixelDensity||1,a.createCanvas(e,t,r),delete a.createCanvas,a._loop=!1}get w(){return this.width}get h(){return this.height}},e.createImage=(t,r,a)=>(a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace||Q5.canvasOptions.colorSpace,new Q5.Image(t,r,a)),e.loadImage=function(r,a,n){if(r.canvas)return r;if("gif"==r.slice(-3).toLowerCase())throw new Error("q5 doesn't support GIFs due to their impact on performance. Use a video or animation instead.");t._preloadCount++;let o=[...arguments].at(-1);n="object"==typeof o?o:null;let i=e.createImage(1,1,n);function s(e){i.resize(e.naturalWidth||e.width,e.naturalHeight||e.height),i.ctx.drawImage(e,0,0),t._preloadCount--,a&&a(i)}if(Q5._nodejs&&global.CairoCanvas)global.CairoCanvas.loadImage(r).then(s).catch((e=>{throw t._preloadCount--,e}));else{let e=new window.Image;e.src=r,e.crossOrigin="Anonymous",e._pixelDensity=1,e.onload=()=>s(e),e.onerror=e=>{throw t._preloadCount--,e}}return i},e.imageMode=t=>e._imageMode=t,e.image=(t,r,a,n,o,i=0,s=0,l,d)=>{let c=t.canvas||t;Q5._createNodeJSCanvas&&(c=c.context.canvas),n??=t.width||t.videoWidth,o??=t.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*n,a-=.5*o),e._da&&(r*=e._da,a*=e._da,n*=e._da,o*=e._da,i*=e._da,s*=e._da,l*=e._da,d*=e._da);let h=t._pixelDensity||1;l?l*=h:l=c.width||c.videoWidth,d?d*=h:d=c.height||c.videoHeight,e.ctx.drawImage(c,i*h,s*h,l,d,r,a,n,o),e._tint&&(e.ctx.globalCompositeOperation="multiply",e.ctx.fillStyle=e._tint.toString(),e.ctx.fillRect(r,a,n,o),e.ctx.globalCompositeOperation="source-over")},e._tint=null;let r=null;e._softFilter=()=>{throw new Error("Load q5-2d-soft-filters.js to use software filters.")},e.filter=(t,r)=>{if(!e.ctx.filter)return e._softFilter(t,r);if("string"==typeof t)f=t;else if(t==Q5.GRAY)f="saturate(0%)";else if(t==Q5.INVERT)f="invert(100%)";else if(t==Q5.BLUR){let t=Math.ceil(r*e._pixelDensity)||1;f=`blur(${t}px)`}else{if(t!=Q5.THRESHOLD)return e._softFilter(t,r);{r??=.5;let e=Math.floor(.5/Math.max(r,1e-5)*100);f=`saturate(0%) brightness(${e}%) contrast(1000000%)`}}e.ctx.filter=f,e.ctx.drawImage(e.canvas,0,0,e.canvas.w,e.canvas.h),e.ctx.filter="none"},"image"==e._scope&&(e.resize=(t,r)=>{let a=new e._OffscreenCanvas(e.canvas.width,e.canvas.height);a.getContext("2d",{colorSpace:e.canvas.colorSpace}).drawImage(e.canvas,0,0),e._setCanvasSize(t,r),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.drawImage(a,0,0,e.canvas.width,e.canvas.height)}),e._getImageData=(t,r,a,n)=>e.ctx.getImageData(t,r,a,n,{colorSpace:e.canvas.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,r=e.canvas.width,a=e.canvas.height,n=e._getImageData(0,0,r,a).data,o=r,i=0,s=a,l=0,d=3;for(let e=0;ei&&(i=t),el&&(l=e)),d+=4;return s=Math.floor(s/t),l=Math.floor(l/t),o=Math.floor(o/t),i=Math.floor(i/t),e.get(o,s,i-o+1,l-s+1)},e.mask=t=>{e.ctx.save(),e.ctx.resetTransform();let r=e.ctx.globalCompositeOperation;e.ctx.globalCompositeOperation="destination-in",e.ctx.drawImage(t.canvas,0,0),e.ctx.globalCompositeOperation=r,e.ctx.restore()},e.get=(t,r,a,n)=>{let o=e._pixelDensity||1;if(void 0!==t&&void 0===a){let a=e._getImageData(t*o,r*o,1,1).data;return new e.Color(a[0],a[1],a[2],a[3]/255)}t=(t||0)*o,r=(r||0)*o;let i=a=a||e.width,s=n=n||e.height;a*=o,n*=o;let l=e.createImage(a,n),d=e._getImageData(t,r,a,n);return l.ctx.putImageData(d,0,0),l._pixelDensity=o,l.width=i,l.height=s,l},e.set=(t,r,a)=>{if(a.canvas){let n=e._tint;return e._tint=null,e.image(a,t,r),void(e._tint=n)}e.pixels.length||e.loadPixels();let n=e._pixelDensity||1;for(let o=0;o{r=e._getImageData(0,0,e.canvas.width,e.canvas.height),t.pixels=r.data},e.updatePixels=()=>{null!=r&&e.ctx.putImageData(r,0,0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,"image"!=e._scope&&(e.tint=function(t){e._tint=t._q5Color?t:e.color(...arguments)},e.noTint=()=>e._tint=null)},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.q2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic",e._textSize=12;let r="sans-serif",a=!1,n=15,o=3,i="normal",s=!1,l=0,d=[],c=!1,h=!1,u=0,p=12e3,f=e._textCache={};e.loadFont=(e,r)=>{t._preloadCount++;let a=e.split("/").pop().split(".")[0].replace(" ",""),n=new FontFace(a,`url(${e})`);return document.fonts.add(n),n.load().then((()=>{t._preloadCount--,r&&r(a)})),a},e.textFont=e=>{r=e,s=!0,l=-1},e.textSize=t=>{if(void 0===t)return e._textSize;e._da&&(t*=e._da),e._textSize=t,s=!0,l=-1,a||(n=1.25*t,o=n-t)},e.textStyle=e=>{i=e,s=!0,l=-1},e.textLeading=t=>{if(void 0===t)return n;e._da&&(t*=e._da),n=t,o=t-e._textSize,a=!0,l=-1},e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r)},e.textWidth=t=>e.ctx.measureText(t).width,e.textAscent=t=>e.ctx.measureText(t).actualBoundingBoxAscent,e.textDescent=t=>e.ctx.measureText(t).actualBoundingBoxDescent,e.textFill=e.fill,e.textStroke=e.stroke;e.textCache=(e,t)=>(t&&(p=t),void 0!==e&&(c=e),c),e.createTextImage=(t,r,a)=>(h=!0,img=e.text(t,0,0,r,a),h=!1,img);let g=[];e.text=(t,a,_,x,m)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString(),e._da&&(a*=e._da,_*=e._da);let v,y,w,b,S=e.ctx;if(s&&(S.font=`${i} ${e._textSize}px ${r}`,s=!1),(c||h)&&(-1==l&&(()=>{let t=r+e._textSize+i+n,a=5381;for(let e=0;e>>0})(),v=f[t],v&&(v=v[l]),v)){if(v._fill==e._fill&&v._stroke==e._stroke&&v._strokeWeight==e._strokeWeight)return h?v:e.textImage(v,a,_);v.clear()}if(-1==t.indexOf("\n")?g[0]=t:g=t.split("\n"),t.length>x){let e=[];for(let t of g){let r=0;for(;r=t.length){e.push(t.slice(r));break}let n=t.lastIndexOf(" ",a);(-1===n||nm)break;if(g.length=0,e._fillSet||(S.fillStyle=b),c||h){if(d.push(l),(f[t]??={})[l]=v,u++,u>p){let e=Math.ceil(u/2),t=d.splice(0,e);for(let e in f){e=f[e];for(let r of t)delete e[r]}u-=e}if(h)return v;e.textImage(v,a,_)}},e.textImage=(t,r,a)=>{let n=e._imageMode;e._imageMode="corner";let o=e._textAlign;"center"==o?r-=t.canvas.hw:"right"==o&&(r-=t.width);let i=e._textBaseline;"alphabetic"==i?a-=t._leading:"middle"==i?a-=t._middle:"bottom"==i?a-=t._bottom:"top"==i&&(a-=t._top),e.image(t,r,a),e._imageMode=n},e.nf=(e,t,r)=>{let a=e<0,n=(e=Math.abs(e)).toFixed(r).split(".");n[0]=n[0].padStart(t,"0");let o=n.join(".");return a&&(o="-"+o),o}},Q5.modules.ai=e=>{e.askAI=(e="")=>{throw Error("Ask AI ✨ "+e)},e._aiErrorAssistance=async t=>{let r=t.message?.includes("Ask AI ✨");if(Q5.disableFriendlyErrors&&!r)return;!r&&Q5.errorTolerant||e.noLoop();let a=t.stack?.split("\n");if(!t.stack||a.length<=1)return;let n=1,o="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(n=0,o="@");a[n].indexOf("q5")>=0;)n++;let i=a[n].split(o).at(-1);i=i.split(":");let s=parseInt(i.at(-2));r&&s++;let l=i.slice(0,-2).join(":"),d=l.split("/").at(-1);try{let e=(await(await fetch(l)).text()).split("\n"),a=e[s-1].trim(),n="",o=1;for(;n.length<1600&&(s-o>=0&&(n=e[s-o].trim()+"\n"+n),s+o10?t.message.slice(10):"Whats+wrong+with+this+line%3F+short+answer")+(r?"":"%0A%0A"+encodeURIComponent(t.name+": "+t.message))+"%0A%0ALine%3A+"+encodeURIComponent(a)+"%0A%0AExcerpt+for+context%3A%0A%0A"+encodeURIComponent(n);if(console.warn("Error in "+d+" on line "+s+":\n\n"+a),console.warn("Ask AI ✨ "+i),r)return window.open(i,"_blank")}catch(e){}}},Q5.modules.color=(e,t)=>{e.RGB=e.RGBA=e._colorMode="rgb",e.OKLCH="oklch",e.colorMode=(r,a)=>{e._colorMode=r;let n="srgb"==e.canvas.colorSpace||"srgb"==r;if(a??=n?"integer":"float",e._colorFormat="float"==a||1==a?1:255,"oklch"==r)t.Color=Q5.ColorOKLCH;else{let r="srgb"==e.canvas.colorSpace;255==e._colorFormat?t.Color=r?Q5.ColorRGBA_8:Q5.ColorRGBA_P3_8:t.Color=r?Q5.ColorRGBA:Q5.ColorRGBA_P3,e._colorMode="rgb"}},e._namedColors={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],cyan:[0,255,255],darkviolet:[148,0,211],gold:[255,215,0],green:[0,128,0],gray:[128,128,128],grey:[128,128,128],hotpink:[255,105,180],indigo:[75,0,130],khaki:[240,230,140],lightgreen:[144,238,144],lime:[0,255,0],magenta:[255,0,255],navy:[0,0,128],orange:[255,165,0],olive:[128,128,0],peachpuff:[255,218,185],pink:[255,192,203],purple:[128,0,128],red:[255,0,0],skyblue:[135,206,235],tan:[210,180,140],turquoise:[64,224,208],transparent:[0,0,0,0],white:[255,255,255],violet:[238,130,238],yellow:[255,255,0]},e.color=(t,r,a,n)=>{let o=e.Color;if(t._q5Color)return new o(...t.levels);if(null==r){if("string"==typeof t){if("#"==t[0])t.length<=5?(t.length>4&&(n=parseInt(t[4]+t[4],16)),a=parseInt(t[3]+t[3],16),r=parseInt(t[2]+t[2],16),t=parseInt(t[1]+t[1],16)):(t.length>7&&(n=parseInt(t.slice(7,9),16)),a=parseInt(t.slice(5,7),16),r=parseInt(t.slice(3,5),16),t=parseInt(t.slice(1,3),16));else{if(!e._namedColors[t])return console.error("q5 can't parse color: "+t+"\nOnly numeric input, hex, and common named colors are supported."),new o(0,0,0);[t,r,a,n]=e._namedColors[t]}1==e._colorFormat&&(t/=255,r&&(r/=255),a&&(a/=255),n&&(n/=255))}Array.isArray(t)&&([t,r,a,n]=t)}return null==a?new o(t,t,t,r):new o(t,r,a,n)},e.red=e=>e.r,e.green=e=>e.g,e.blue=e=>e.b,e.alpha=e=>e.a,e.lightness=e=>e.l?e.l:100*(.2126*e.r+.7152*e.g+.0722*e.b)/255,e.hue=t=>{if(t.h)return t.h;let r=t.r,a=t.g,n=t.b;255==e._colorFormat&&(r/=255,a/=255,n/=255);let o,i=Math.max(r,a,n),s=Math.min(r,a,n);return o=i==s?0:i==r?60*(a-n)/(i-s):i==a?60*(n-r)/(i-s)+120:60*(r-a)/(i-s)+240,o<0&&(o+=360),o},e.lerpColor=(t,r,a)=>{if("rgb"==e._colorMode)return new e.Color(e.constrain(e.lerp(t.r,r.r,a),0,255),e.constrain(e.lerp(t.g,r.g,a),0,255),e.constrain(e.lerp(t.b,r.b,a),0,255),e.constrain(e.lerp(t.a,r.a,a),0,255));{let n=r.h-t.h;n>180&&(n-=360),n<-180&&(n+=360);let o=t.h+a*n;return o<0&&(o+=360),o>360&&(o-=360),new e.Color(e.constrain(e.lerp(t.l,r.l,a),0,100),e.constrain(e.lerp(t.c,r.c,a),0,100),o,e.constrain(e.lerp(t.a,r.a,a),0,255))}}},Q5.Color=class{constructor(){this._q5Color=!0}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,a){super(),this.l=e,this.c=t,this.h=r,this.a=a??1}toString(){return`oklch(${this.l} ${this.c} ${this.h} / ${this.a})`}},Q5.ColorRGBA=class extends Q5.Color{constructor(e,t,r,a){super(),this.r=e,this.g=t,this.b=r,this.a=a??1}get levels(){return[this.r,this.g,this.b,this.a]}toString(){return`color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGBA_P3=class extends Q5.ColorRGBA{toString(){return`color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGBA_8=class extends Q5.ColorRGBA{constructor(e,t,r,a){super(e,t,r,a??255)}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}get levels(){return[this.r,this.g,this.b,this.a]}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGBA_P3_8=class extends Q5.ColorRGBA{constructor(e,t,r,a){super(e,t,r,a??255),this._edited=!0}get r(){return this._r}set r(e){this._r=e,this._edited=!0}get g(){return this._g}set g(e){this._g=e,this._edited=!0}get b(){return this._b}set b(e){this._b=e,this._edited=!0}get a(){return this._a}set a(e){this._a=e,this._edited=!0}toString(){if(this._edited){let e=(this._r/255).toFixed(3),t=(this._g/255).toFixed(3),r=(this._b/255).toFixed(3),a=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${a})`,this._edited=!1}return this._css}},Q5.modules.display=e=>{if(!e.canvas||"graphics"==e._scope)return;let t=e.canvas;e.CENTERED="centered",e.FULLSCREEN="fullscreen",e.MAXED="maxed",e.PIXELATED="pixelated",0!=Q5._instanceCount||Q5._nodejs||document.head.insertAdjacentHTML("beforeend",""),e._adjustDisplay=()=>{let r=t.style,a=t.parentElement;r&&a&&t.displayMode&&("pixelated"==t.renderQuality&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),"normal"==t.displayMode?(a.classList.remove("q5-centered","q5-maxed","q5-fullscreen"),r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"):(a.classList.add("q5-"+t.displayMode),a=a.getBoundingClientRect(),t.w/t.h>a.width/a.height?("centered"==t.displayMode?(r.width=t.w*t.displayScale+"px",r.maxWidth="100%"):r.width="100%",r.height="auto",r.maxHeight=""):(r.width="auto",r.maxWidth="","centered"==t.displayMode?(r.height=t.h*t.displayScale+"px",r.maxHeight="100%"):r.height="100%")))},e.displayMode=(r="normal",a="default",n=1)=>{"string"==typeof n&&(n=parseFloat(n.slice(1))),Object.assign(t,{displayMode:r,renderQuality:a,displayScale:n}),e._adjustDisplay()},e.fullscreen=e=>{if(void 0===e)return document.fullscreenElement;e?document.body.requestFullscreen():document.body.exitFullscreen()}},Q5.modules.input=(e,t)=>{if("graphics"==e._scope)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.mouseButton=null,e.keyIsPressed=!1,e.mouseIsPressed=!1,e.key=null,e.keyCode=null,e.UP_ARROW=38,e.DOWN_ARROW=40,e.LEFT_ARROW=37,e.RIGHT_ARROW=39,e.SHIFT=16,e.TAB=9,e.BACKSPACE=8,e.ENTER=e.RETURN=13,e.ALT=e.OPTION=18,e.CONTROL=17,e.DELETE=46,e.ESCAPE=27,e.ARROW="default",e.CROSS="crosshair",e.HAND="pointer",e.MOVE="move",e.TEXT="text";let r={},a=[e.LEFT,e.CENTER,e.RIGHT],n=e.canvas;function o(t){const r=e.canvas.getBoundingClientRect(),a=e.canvas.scrollWidth/e.width||1,n=e.canvas.scrollHeight/e.height||1;return{x:(t.clientX-r.left)/a,y:(t.clientY-r.top)/n,id:t.identifier}}if(e._startAudio=()=>{e.getAudioContext&&"suspended"==e.getAudioContext()?.state&&e.userStartAudio()},e._updateMouse=r=>{if(!r.changedTouches)if(n){let a=n.getBoundingClientRect(),o=n.scrollWidth/e.width||1,i=n.scrollHeight/e.height||1;t.mouseX=(r.clientX-a.left)/o,t.mouseY=(r.clientY-a.top)/i,"webgpu"==n.renderer&&(t.mouseX-=n.hw,t.mouseY-=n.hh)}else t.mouseX=r.clientX,t.mouseY=r.clientY},e._onmousedown=r=>{e._startAudio(),e._updateMouse(r),t.mouseIsPressed=!0,t.mouseButton=a[r.button],e.mousePressed(r)},e._onmousemove=t=>{e._updateMouse(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t)},e._onmouseup=r=>{e._updateMouse(r),t.mouseIsPressed=!1,e.mouseReleased(r)},e._onclick=r=>{e._updateMouse(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e.cursor=(t,r,a)=>{let n="";t.includes(".")&&(t=`url("${t}")`,n=", auto"),void 0!==r&&(t+=" "+r+" "+a),e.canvas.style.cursor=t+n},e.noCursor=()=>{e.canvas.style.cursor="none"},e.requestPointerLock=document.body?.requestPointerLock,e.exitPointerLock=document.exitPointerLock,e._onkeydown=a=>{a.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(a),1==a.key.length&&e.keyTyped(a))},e._onkeyup=a=>{t.keyIsPressed=!1,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(a)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._ontouchstart=r=>{e._startAudio(),t.touches=[...r.touches].map(o),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,t.mouseIsPressed=!0,t.mouseButton=e.LEFT,e.mousePressed(r)||r.preventDefault()),e.touchStarted(r)||r.preventDefault()},e._ontouchmove=r=>{t.touches=[...r.touches].map(o),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,e.mouseDragged(r)||r.preventDefault()),e.touchMoved(r)||r.preventDefault()},e._ontouchend=r=>{t.touches=[...r.touches].map(o),e._isTouchAware||e.touches.length||(t.mouseIsPressed=!1,e.mouseReleased(r)||r.preventDefault()),e.touchEnded(r)||r.preventDefault()},n&&(n.addEventListener("mousedown",(t=>e._onmousedown(t))),n.addEventListener("mouseup",(t=>e._onmouseup(t))),n.addEventListener("click",(t=>e._onclick(t))),n.addEventListener("touchstart",(t=>e._ontouchstart(t))),n.addEventListener("touchmove",(t=>e._ontouchmove(t))),n.addEventListener("touchcancel",(t=>e._ontouchend(t))),n.addEventListener("touchend",(t=>e._ontouchend(t)))),window){let t=window.addEventListener;t("mousemove",(t=>e._onmousemove(t)),!1),t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1)}},Q5.modules.math=(e,t)=>{e.RADIANS=0,e.DEGREES=1,e.PI=Math.PI,e.HALF_PI=Math.PI/2,e.QUARTER_PI=Math.PI/4,e.abs=Math.abs,e.ceil=Math.ceil,e.exp=Math.exp,e.floor=Math.floor,e.loge=Math.log,e.mag=Math.hypot,e.max=Math.max,e.min=Math.min,e.round=Math.round,e.pow=Math.pow,e.sqrt=Math.sqrt,e.SHR3=1,e.LCG=2;let r=0;e.angleMode=t=>{"radians"==t&&(t=0),r=e._angleMode=t};let a=e._DEGTORAD=Math.PI/180,n=e._RADTODEG=180/Math.PI;function o(){let e,t,r=4294967295;return{setSeed(a){e=t=(a??Math.random()*r)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/r)}}e.degrees=t=>t*e._RADTODEG,e.radians=t=>t*e._DEGTORAD,e.map=Q5.prototype.map=(e,t,r,a,n,o)=>{let i=a+1*(e-t)/(r-t)*(n-a);return o?ae*(1-r)+t*r,e.constrain=(e,t,r)=>Math.min(Math.max(e,t),r),e.dist=function(){let e=arguments;return 4==e.length?Math.hypot(e[0]-e[2],e[1]-e[3]):Math.hypot(e[0]-e[3],e[1]-e[4],e[2]-e[5])},e.norm=(t,r,a)=>e.map(t,r,a,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*a:e),e.cos=e=>Math.cos(r?e*a:e),e.tan=e=>Math.tan(r?e*a:e),e.asin=e=>{let t=Math.asin(e);return r?t*n:t},e.acos=e=>{let t=Math.acos(e);return r?t*n:t},e.atan=e=>{let t=Math.atan(e);return r?t*n:t},e.atan2=(e,t)=>{let a=Math.atan2(e,t);return r?a*n:a};let i=o();i.setSeed(),e.randomSeed=e=>i.setSeed(e),e.random=(e,t)=>void 0===e?i.rand():"number"==typeof e?void 0!==t?i.rand()*(t-e)+e:i.rand()*e:e[Math.trunc(e.length*i.rand())],e.randomGenerator=t=>{t==e.LCG?i=function(){const e=4294967296;let t,r;return{setSeed(a){r=t=(a??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(i=o()),i.setSeed()};var s=new function(){var e,t,r,a=new Array(128),n=new Array(256),o=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*i.rand()-2147483648,h=()=>.5+2.328306e-10*(c()|0),u=()=>{for(var t,n,i,l,d=3.44262;;){if(t=r*o[e],0==e){do{i=h(),l=h(),t=.2904764*-Math.log(i),n=-Math.log(l)}while(n+n0?d+t:-d-t}if(s[e]+h()*(s[e-1]-s[e]){for(var r;;){if(0==e)return 7.69711-Math.log(h());if(r=t*l[e],d[e]+h()*(d[e-1]-d[e])(r=c(),e=127&r,Math.abs(r)(t=c()>>>0){var e,t,r=2147483648,i=4294967296,c=3.442619855899,h=c,u=.00991256303526217,p=7.697117470131487,f=p,g=.003949659822581572;for(e=u/Math.exp(-.5*c*c),a[0]=Math.floor(c/e*r),a[1]=0,o[0]=e/r,o[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),a[t+1]=Math.floor(c/h*r),h=c,s[t]=Math.exp(-.5*c*c),o[t]=c/r;for(e=g/Math.exp(-p),n[0]=Math.floor(p/e*i),n[1]=0,l[0]=e/i,l[255]=p/i,d[0]=1,d[255]=Math.exp(-p),t=254;t>=1;t--)p=-Math.log(g/p+Math.exp(-p)),n[t+1]=Math.floor(p/f*i),f=p,d[t]=Math.exp(-p),l[t]=p/i}};let l;s.hasInit=!1,e.randomGaussian=(e,t)=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.RNOR()*t+e),e.randomExponential=()=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.REXP()),e.PERLIN="perlin",e.SIMPLEX="simplex",e.BLOCKY="blocky",e.Noise=Q5.PerlinNoise,e.noiseMode=e=>{t.Noise=Q5[e[0].toUpperCase()+e.slice(1)+"Noise"],l=null},e.noiseSeed=t=>{l=new e.Noise(t)},e.noise=(t=0,r=0,a=0)=>(l??=new e.Noise,l.noise(t,r,a)),e.noiseDetail=(t,r)=>{l??=new e.Noise,t>0&&(l.octaves=t),r>0&&(l.falloff=r)}},Q5.Noise=class{},Q5.PerlinNoise=class extends Q5.Noise{constructor(e){super(),this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.octaves=1,this.falloff=.5,this.p=null==e?Array.from({length:256},(()=>Math.floor(256*Math.random()))):this.seedPermutation(e),this.p=this.p.concat(this.p)}seedPermutation(e){let t,r,a=[];for(let e=0;e<256;e++)a[e]=e;for(let n=255;n>0;n--)t=(e=16807*e%2147483647)%(n+1),r=a[n],a[n]=a[t],a[t]=r;return a}dot(e,t,r,a){return e[0]*t+e[1]*r+e[2]*a}mix(e,t,r){return(1-r)*e+r*t}fade(e){return e*e*e*(e*(6*e-15)+10)}noise(e,t,r){let a=this,n=0,o=1,i=1,s=0;for(let l=0;l{e.Sound=Q5.Sound,e.loadSound=(e,r)=>{t._preloadCount++,Q5.aud??=new window.AudioContext;let a=new Q5.Sound(e,r);return a.addEventListener("canplaythrough",(()=>{t._preloadCount--,a.loaded=!0,r&&r(a)})),a},e.getAudioContext=()=>Q5.aud,e.userStartAudio=()=>Q5.aud.resume()},Q5.Sound=class extends Audio{constructor(e){super(e);let t=this;t.load(),t.panner=Q5.aud.createStereoPanner(),t.source=Q5.aud.createMediaElementSource(t),t.source.connect(t.panner),t.panner.connect(Q5.aud.destination),Object.defineProperty(t,"pan",{get:()=>t.panner.pan.value,set:e=>t.panner.pan.value=e})}setVolume(e){this.volume=e}setLoop(e){this.loop=e}setPan(e){this.pan=e}isLoaded(){return this.loaded}isPlaying(){return!this.paused}},Q5.modules.util=(e,t)=>{e._loadFile=(r,a,n)=>{t._preloadCount++;let o={};return fetch(r).then((e=>"json"==n?e.json():e.text())).then((r=>{t._preloadCount--,"csv"==n&&(r=e.CSV.parse(r)),Object.assign(o,r),a&&a(r)})),o},e.loadStrings=(t,r)=>e._loadFile(t,r,"text"),e.loadJSON=(t,r)=>e._loadFile(t,r,"json"),e.loadCSV=(t,r)=>e._loadFile(t,r,"csv"),e.CSV={},e.CSV.parse=(e,t=",",r="\n")=>{let a=[],n=e.split(r),o=n[0].split(t);for(let e=1;er[e]=JSON.parse(i[t]))),a.push(r)}return a},"object"==typeof localStorage&&(e.storeItem=localStorage.setItem,e.getItem=localStorage.getItem,e.removeItem=localStorage.removeItem,e.clearStorage=localStorage.clear),e.year=()=>(new Date).getFullYear(),e.day=()=>(new Date).getDay(),e.hour=()=>(new Date).getHours(),e.minute=()=>(new Date).getMinutes(),e.second=()=>(new Date).getSeconds()},Q5.modules.vector=e=>{e.createVector=(t,r,a)=>new Q5.Vector(t,r,a,e)},Q5.Vector=class{constructor(e,t,r,a){this.x=e||0,this.y=t||0,this.z=r||0,this._$=a||window,this._cn=null,this._cnsq=null}set(e,t,r){return this.x=e?.x||e||0,this.y=e?.y||t||0,this.z=e?.z||r||0,this}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,r){return void 0!==e?.x?e:void 0!==t?{x:e,y:t,z:r||0}:{x:e,y:e,z:e}}_calcNorm(){this._cnsq=this.x*this.x+this.y*this.y+this.z*this.z,this._cn=Math.sqrt(this._cnsq)}add(){let e=this._arg2v(...arguments);return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}rem(){let e=this._arg2v(...arguments);return this.x%=e.x,this.y%=e.y,this.z%=e.z,this}sub(){let e=this._arg2v(...arguments);return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}mult(){let e=this._arg2v(...arguments);return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}div(){let e=this._arg2v(...arguments);return e.x?this.x/=e.x:this.x=0,e.y?this.y/=e.y:this.y=0,e.z?this.z/=e.z:this.z=0,this}mag(){return this._calcNorm(),this._cn}magSq(){return this._calcNorm(),this._cnsq}dot(){let e=this._arg2v(...arguments);return this.x*e.x+this.y*e.y+this.z*e.z}dist(){let e=this._arg2v(...arguments),t=this.x-e.x,r=this.y-e.y,a=this.z-e.z;return Math.sqrt(t*t+r*r+a*a)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,a=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=a,this}normalize(){this._calcNorm();let e=this._cn;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._cn=1,this._cnsq=1,this}limit(e){this._calcNorm();let t=this._cn;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._cn=e,this._cnsq=e*e}return this}setMag(e){this._calcNorm();let t=e/this._cn;return this.x*=t,this.y*=t,this.z*=t,this._cn=e,this._cnsq=e*e,this}heading(){return this._$.atan2(this.y,this.x)}setHeading(e){let t=this.mag();return this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),a=this.x*t-this.y*r,n=this.x*r+this.y*t;return this.x=a,this.y=n,this}angleBetween(){let e=this._arg2v(...arguments),t=Q5.Vector.cross(this,e);return this._$.atan2(t.mag(),this.dot(e))*Math.sign(t.z||1)}lerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));return this.x+=(r.x-this.x)*t,this.y+=(r.y-this.y)*t,this.z+=(r.z-this.z)*t,this}slerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));if(1==t)return this.set(r);let a=this.mag(),n=r.mag();if(0==a||0==n)return this.mult(1-t).add(r.mult(t));let o=Q5.Vector.cross(this,r),i=o.mag(),s=Math.atan2(i,this.dot(r));if(i>0)o.div(i);else{if(se.copy().add(t),Q5.Vector.cross=(e,t)=>e.copy().cross(t),Q5.Vector.dist=(e,t)=>Math.hypot(e.x-t.x,e.y-t.y,e.z-t.z),Q5.Vector.div=(e,t)=>e.copy().div(t),Q5.Vector.dot=(e,t)=>e.copy().dot(t),Q5.Vector.equals=(e,t,r)=>e.equals(t,r),Q5.Vector.lerp=(e,t,r)=>e.copy().lerp(t,r),Q5.Vector.slerp=(e,t,r)=>e.copy().slerp(t,r),Q5.Vector.limit=(e,t)=>e.copy().limit(t),Q5.Vector.heading=e=>this._$.atan2(e.y,e.x),Q5.Vector.magSq=e=>e.x*e.x+e.y*e.y+e.z*e.z,Q5.Vector.mag=e=>Math.sqrt(Q5.Vector.magSq(e)),Q5.Vector.mult=(e,t)=>e.copy().mult(t),Q5.Vector.normalize=e=>e.copy().normalize(),Q5.Vector.rem=(e,t)=>e.copy().rem(t),Q5.Vector.sub=(e,t)=>e.copy().sub(t);for(let e of["fromAngle","fromAngles","random2D","random3D"])Q5.Vector[e]=(t,r,a)=>(new Q5.Vector)[e](t,r,a);Q5.renderers.webgpu={},Q5.renderers.webgpu.canvas=(e,t)=>{let r,a=e.canvas;a.width=e.width=500,a.height=e.height=500,e.colorMode&&e.colorMode("rgb","float"),e.pipelines=[];let n=e.drawStack=[],o=e.colorsStack=[1,1,1,1];e._transformLayout=Q5.device.createBindGroupLayout({label:"transformLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform",hasDynamicOffset:!1}},{binding:1,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage",hasDynamicOffset:!1}}]}),e.bindGroupLayouts=[e._transformLayout];let i=Q5.device.createBuffer({size:8,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});e._createCanvas=(r,n,o)=>(t.ctx=t.drawingContext=a.getContext("webgpu"),o.format??=navigator.gpu.getPreferredCanvasFormat(),o.device??=Q5.device,e.ctx.configure(o),Q5.device.queue.writeBuffer(i,0,new Float32Array([e.canvas.hw,e.canvas.hh])),a),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r)};let s=0,l=(t,r,a,n=1)=>{"string"==typeof t?t=e.color(t):null==a&&(n=r??1,r=a=t),t._q5Color?o.push(t.r,t.g,t.b,t.a):o.push(t,r,a,n),s++};e._fillIndex=e._strokeIndex=-1,e.fill=(t,r,a,n)=>{l(t,r,a,n),e._doFill=!0,e._fillIndex=s},e.stroke=(t,r,a,n)=>{l(t,r,a,n),e._doStroke=!0,e._strokeIndex=s},e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e._strokeWeight=1,e.strokeWeight=t=>e._strokeWeight=Math.abs(t),e.resetMatrix=()=>{e._matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],e._transformIndex=0},e.resetMatrix(),e._matrixDirty=!1,e.transformStates=[e._matrix.slice()],e._transformIndexStack=[],e.translate=(t,r,a)=>{(t||r||a)&&(e._matrix[12]+=t,e._matrix[13]-=r,e._matrix[14]+=a||0,e._matrixDirty=!0)},e.rotate=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.cos(t),a=Math.sin(t),n=e._matrix,o=n[0],i=n[1],s=n[4],l=n[5];o||i||s||l?(n[0]=o*r+s*a,n[1]=i*r+l*a,n[4]=s*r-o*a,n[5]=l*r-i*a):(n[0]=r,n[1]=a,n[4]=-a,n[5]=r),e._matrixDirty=!0},e.scale=(t=1,r,a=1)=>{r??=t;let n=e._matrix;n[0]*=t,n[1]*=t,n[2]*=t,n[3]*=t,n[4]*=r,n[5]*=r,n[6]*=r,n[7]*=r,n[8]*=a,n[9]*=a,n[10]*=a,n[11]*=a,e._matrixDirty=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=e._matrix[0],n=e._matrix[1],o=e._matrix[4],i=e._matrix[5];e._matrix[0]=a+o*r,e._matrix[1]=n+i*r,e._matrixDirty=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=e._matrix[0],n=e._matrix[1],o=e._matrix[4],i=e._matrix[5];e._matrix[4]=o+a*r,e._matrix[5]=i+n*r,e._matrixDirty=!0},e.applyMatrix=(...t)=>{let r;if(r=1==t.length?t[0]:t,9==r.length)r=[r[0],r[1],0,r[2],r[3],r[4],0,r[5],0,0,1,0,r[6],r[7],0,r[8]];else if(16!=r.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");e._matrix=r.slice(),e._matrixDirty=!0},e._saveMatrix=()=>{e.transformStates.push(e._matrix.slice()),e._transformIndex=e.transformStates.length-1,e._matrixDirty=!1},e.pushMatrix=()=>{e._matrixDirty&&e._saveMatrix(),e._transformIndexStack.push(e._transformIndex)},e.popMatrix=()=>{if(!e._transformIndexStack.length)return console.warn("Matrix index stack is empty!");let t=e._transformIndexStack.pop();e._matrix=e.transformStates[t].slice(),e._transformIndex=t,e._matrixDirty=!1},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()},e._calcBox=(e,t,r,a,n)=>{let o,i,s,l,d=r/2,c=a/2;return n&&"corner"!=n?"center"==n?(o=e-d,i=e+d,s=-(t-c),l=-(t+c)):(o=e,i=r,s=-t,l=-a):(o=e,i=e+r,s=-t,l=-(t+a)),[o,i,s,l]},e.clear=()=>{},e._beginRender=()=>{e.encoder=Q5.device.createCommandEncoder(),r=t.pass=e.encoder.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store"}]})},e._render=()=>{if(transformStates.length>1||!e._transformBindGroup){let t=Q5.device.createBuffer({size:64*transformStates.length,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(t,0,new Float32Array(transformStates.flat())),e._transformBindGroup=Q5.device.createBindGroup({layout:e._transformLayout,entries:[{binding:0,resource:{buffer:i}},{binding:1,resource:{buffer:t}}]})}r.setBindGroup(0,e._transformBindGroup);for(let t of e._hooks.preRender)t();let t=0,a=0,o=0,s=-1;for(let i=0;i{r.end();let a=e.encoder.finish();Q5.device.queue.submit([a]),t.pass=e.encoder=null,e.drawStack.length=0,e.colorsStack.length=4,s=0,rotation=0,e.transformStates.length=1,e._transformIndexStack.length=0}},Q5.webgpu=async function(e,t){if(e&&"global"!=e||(Q5._hasGlobal=!0),!navigator.gpu){console.warn("q5 WebGPU not supported on this browser!");let r=new Q5(e,t);return r.colorMode("rgb",1),r._beginRender=()=>r.translate(r.canvas.hw,r.canvas.hh),r}let r=await navigator.gpu.requestAdapter();if(!r)throw new Error("No appropriate GPUAdapter found.");return Q5.device=await r.requestDevice(),new Q5(e,t,"webgpu")},Q5.renderers.webgpu.drawing=(e,t)=>{let r,a,n=e.canvas,o=e.drawStack,i=e.colorsStack,s=[],l=Q5.device.createShaderModule({label:"drawingVertexShader",code:"\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) colorIndex: f32\n};\n\nstruct Uniforms {\n\thalfWidth: f32,\n\thalfHeight: f32\n};\n\n@group(0) @binding(0) var uniforms: Uniforms;\n@group(0) @binding(1) var transforms: array>;\n\n@vertex\nfn vertexMain(@location(0) pos: vec2f, @location(1) colorIndex: f32, @location(2) transformIndex: f32) -> VertexOutput {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(transformIndex)] * vert;\n\tvert.x /= uniforms.halfWidth;\n\tvert.y /= uniforms.halfHeight;\n\n\tvar output: VertexOutput;\n\toutput.position = vert;\n\toutput.colorIndex = colorIndex;\n\treturn output;\n}\n"}),d=Q5.device.createShaderModule({label:"drawingFragmentShader",code:"\n@group(1) @binding(0) var colors : array;\n\n@fragment\nfn fragmentMain(@location(0) colorIndex: f32) -> @location(0) vec4f {\n\tlet index = i32(colorIndex);\n\treturn mix(colors[index], colors[index + 1], fract(colorIndex));\n}\n"});a=Q5.device.createBindGroupLayout({label:"colorsLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage",hasDynamicOffset:!1}}]}),e.bindGroupLayouts.push(a);let c={arrayStride:16,attributes:[{format:"float32x2",offset:0,shaderLocation:0},{format:"float32",offset:8,shaderLocation:1},{format:"float32",offset:12,shaderLocation:2}]},h=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],u=["add","subtract","reverse-subtract","min","max"];const p={normal:[2,3,0,2,3,0],lighter:[2,1,0,2,1,0],subtract:[2,1,2,2,1,2],multiply:[4,0,0,5,0,0],screen:[1,3,0,1,3,0],darken:[1,3,3,1,3,3],lighten:[1,3,4,1,3,4],overlay:[2,3,0,2,3,0],hard_light:[2,3,0,2,3,0],soft_light:[2,3,0,2,3,0],difference:[2,3,2,2,3,2],exclusion:[2,3,0,2,3,0],color_dodge:[1,7,0,1,7,0],color_burn:[6,1,0,6,1,0],linear_dodge:[2,1,0,2,1,0],linear_burn:[2,7,1,2,7,1],vivid_light:[2,7,0,2,7,0],pin_light:[2,7,0,2,7,0],hard_mix:[2,7,0,2,7,0]};e.blendConfigs={};for(const[t,r]of Object.entries(p))e.blendConfigs[t]={color:{srcFactor:h[r[0]],dstFactor:h[r[1]],operation:u[r[2]]},alpha:{srcFactor:h[r[3]],dstFactor:h[r[4]],operation:u[r[5]]}};e._blendMode="normal",e.blendMode=t=>{t!=e._blendMode&&("source-over"==t&&(t="normal"),t=t.toLowerCase().replace(/[ -]/g,"_"),e._blendMode=t,e.pipelines[0]=e._createPipeline(e.blendConfigs[t]))};let f,g=Q5.device.createPipelineLayout({label:"drawingPipelineLayout",bindGroupLayouts:e.bindGroupLayouts});e._createPipeline=e=>Q5.device.createRenderPipeline({label:"drawingPipeline",layout:g,vertex:{module:l,entryPoint:"vertexMain",buffers:[c]},fragment:{module:d,entryPoint:"fragmentMain",targets:[{format:"bgra8unorm",blend:e}]},primitive:{topology:"triangle-list"}}),e.pipelines[0]=e._createPipeline(e.blendConfigs.normal),e.beginShape=()=>{f=[]},e.vertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),f.push(t,-r,e._fillIndex,e._transformIndex)},e.endShape=t=>{if(!e._doFill)return void(f=[]);let r=f;if(r.length<12)throw new Error("A shape must have at least 3 vertices.");t&&r.push(r[0],r[1],r[2],r[3]);let a=[];for(let e=4;e{e.beginShape(),e.vertex(t,r),e.vertex(a,n),e.vertex(o,i),e.endShape(1)},e.quad=(t,r,a,n,o,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,n),e.vertex(o,i),e.vertex(s,l),e.endShape(1)},e.rectMode=t=>e._rectMode=t,e.rect=(t,a,n,i)=>{let[l,d,c,h]=e._calcBox(t,a,n,i,e._rectMode),u=r??e._fillIndex;e._matrixDirty&&e._saveMatrix();let p=e._transformIndex;s.push(l,c,u,p,d,c,u,p,l,h,u,p,d,c,u,p,l,h,u,p,d,h,u,p),o.push(0,6)},e.square=(t,r,a)=>e.rect(t,r,a,a),e.point=(t,a)=>{r=e._strokeIndex;let n=e._strokeWeight;n<2?(n=Math.round(n),e.rect(t,a,n,n)):e.ellipse(t,a,n,n),r=null},e.line=(t,a,n,o)=>{r=e._strokeIndex,e.push(),e.translate(t,a),e.rotate(e.atan2(o-a,n-t));let i=Math.sqrt((n-t)**2+(o-a)**2),s=e._strokeWeight;e.rect(0,-s/2,i,s),e.pop(),r=null},e.background=(t,r,a,o)=>{if(e.push(),e.resetMatrix(),t.src){let r=e._imageMode;e._imageMode="corner",e.image(t,-n.hw,-n.hh,n.w,n.h),e._imageMode=r}else{let i=e._rectMode;e._rectMode="corner",e.fill(t,r,a,o),e.rect(-n.hw,-n.hh,n.w,n.h),e._rectMode=i}e.pop()};e.ellipseMode=t=>e._ellipseMode=t,e.ellipse=(t,a,n,i)=>{const l=(d=n==i?n:Math.max(n,i))<4?6:d<6?8:d<10?10:d<16?12:d<20?14:d<22?16:d<24?18:d<28?20:d<34?22:d<42?24:d<48?26:d<56?28:d<64?30:d<72?32:d<84?34:d<96?36:d<98?38:d<113?40:d<149?44:d<199?48:d<261?52:d<353?56:d<461?60:d<585?64:d<1200?70:d<1800?80:d<2400?90:100;var d;let c=Math.max(n,1)/2,h=n==i?c:Math.max(i,1)/2,u=0;const p=e.TAU/l,f=r??e._fillIndex;e._matrixDirty&&e._saveMatrix();const g=e._transformIndex;let _,x,m,v;for(let e=0;e<=l;e++)_=m,x=v,m=t+c*Math.cos(u),v=a+h*Math.sin(u),u+=p,0!=e&&s.push(t,a,f,g,_,x,f,g,m,v,f,g);o.push(0,3*l)},e.circle=(t,r,a)=>e.ellipse(t,r,a,a),e._hooks.preRender.push((()=>{e.pass.setPipeline(e.pipelines[0]);const t=new Float32Array(s),r=Q5.device.createBuffer({size:t.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(r,0,t),e.pass.setVertexBuffer(0,r);const n=Q5.device.createBuffer({size:4*i.length,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(n,0,new Float32Array(i)),e._colorsBindGroup=Q5.device.createBindGroup({layout:a,entries:[{binding:0,resource:{buffer:n,offset:0,size:4*i.length}}]}),e.pass.setBindGroup(1,e._colorsBindGroup)})),e._hooks.postRender.push((()=>{s.length=0}))},Q5.renderers.webgpu.image=(e,t)=>{e._textureBindGroups=[];let r=[],a=Q5.device.createShaderModule({label:"imageVertexShader",code:"\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f\n};\n\nstruct Uniforms {\n\thalfWidth: f32,\n\thalfHeight: f32\n};\n\n@group(0) @binding(0) var uniforms: Uniforms;\n@group(0) @binding(1) var transforms: array>;\n\n@vertex\nfn vertexMain(@location(0) pos: vec2f, @location(1) texCoord: vec2f, @location(2) transformIndex: f32) -> VertexOutput {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(transformIndex)] * vert;\n\tvert.x /= uniforms.halfWidth;\n\tvert.y /= uniforms.halfHeight;\n\n\tvar output: VertexOutput;\n\toutput.position = vert;\n\toutput.texCoord = texCoord;\n\treturn output;\n}\n\t"}),n=Q5.device.createShaderModule({label:"imageFragmentShader",code:"\n@group(2) @binding(0) var samp: sampler;\n@group(2) @binding(1) var texture: texture_2d;\n\n@fragment\nfn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {\n\t// Sample the texture using the interpolated texture coordinate\n\treturn textureSample(texture, samp, texCoord);\n}\n\t"}),o=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]});const i=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:[...e.bindGroupLayouts,o]});e.pipelines[1]=Q5.device.createRenderPipeline({label:"imagePipeline",layout:i,vertex:{module:a,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},{arrayStride:20,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"},{shaderLocation:2,offset:16,format:"float32"}]}]},fragment:{module:n,entryPoint:"fragmentMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs?.normal||{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}});let s=Q5.device.createSampler({magFilter:"linear",minFilter:"linear"});e._textures=[];let l=0;e._createTexture=t=>{t.canvas&&(t=t.canvas);let r=[t.width,t.height,1],a=Q5.device.createTexture({size:r,format:"bgra8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:t},{texture:a,colorSpace:e.canvas.colorSpace},r),e._textures[l]=a,t.textureIndex=l;const n=Q5.device.createBindGroup({layout:o,entries:[{binding:0,resource:s},{binding:1,resource:a.createView()}]});e._textureBindGroups[l]=n,l=(l+1)%12e3,e._textures[l]&&(e._textures[l].destroy(),delete e._textures[l],delete e._textureBindGroups[l])},e.loadImage=e.loadTexture=r=>{t._preloadCount++;const a=new Image;return a.crossOrigin="Anonymous",a.onload=()=>{e._createTexture(a),t._preloadCount--},a.src=r,a},e.imageMode=t=>e._imageMode=t,e.image=(t,a,n,o,i)=>{if(t.canvas&&(t=t.canvas),null==t.textureIndex)return;e._matrixDirty&&e._saveMatrix();let s=e._transformIndex;o??=t.width/e._pixelDensity,i??=t.height/e._pixelDensity;let[l,d,c,h]=e._calcBox(a,n,o,i,e._imageMode);r.push(l,c,0,0,s,d,c,1,0,s,l,h,0,1,s,d,c,1,0,s,l,h,0,1,s,d,h,1,1,s),e.drawStack.push(1,t.textureIndex)},e._hooks.preRender.push((()=>{if(!e._textureBindGroups.length)return;e.pass.setPipeline(e.pipelines[1]);const t=new Float32Array(r),a=Q5.device.createBuffer({size:t.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST});Q5.device.queue.writeBuffer(a,0,t),e.pass.setVertexBuffer(1,a)})),e._hooks.postRender.push((()=>{r.length=0}))},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.webgpu.text=(e,t)=>{let r=Q5.device.createShaderModule({label:"MSDF text shader",code:"\n// Positions for simple quad geometry\nconst pos = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));\n\nstruct VertexInput {\n\t@builtin(vertex_index) vertex : u32,\n\t@builtin(instance_index) instance : u32,\n};\nstruct VertexOutput {\n\t@builtin(position) position : vec4f,\n\t@location(0) texcoord : vec2f,\n\t@location(1) colorIndex : f32\n};\nstruct Char {\n\ttexOffset: vec2f,\n\ttexExtent: vec2f,\n\tsize: vec2f,\n\toffset: vec2f,\n};\nstruct Text {\n\tpos: vec2f,\n\tscale: f32,\n\ttransformIndex: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32\n};\nstruct Uniforms {\n\thalfWidth: f32,\n\thalfHeight: f32\n};\n\n@group(0) @binding(0) var uniforms: Uniforms;\n@group(0) @binding(1) var transforms: array>;\n\n@group(1) @binding(0) var colors : array;\n\n@group(2) @binding(0) var fontTexture: texture_2d;\n@group(2) @binding(1) var fontSampler: sampler;\n@group(2) @binding(2) var fontChars: array;\n\n@group(3) @binding(0) var textChars: array;\n@group(3) @binding(1) var textMetadata: array;\n\n@vertex\nfn vertexMain(input : VertexInput) -> VertexOutput {\n\tlet char = textChars[input.instance];\n\n\tlet text = textMetadata[i32(char.w)];\n\n\tlet fontChar = fontChars[i32(char.z)];\n\n\tlet charPos = ((pos[input.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos;\n\n\tvar vert = vec4f(charPos, 0.0, 1.0);\n\tvert = transforms[i32(text.transformIndex)] * vert;\n\tvert.x /= uniforms.halfWidth;\n\tvert.y /= uniforms.halfHeight;\n\n\tvar output : VertexOutput;\n\toutput.position = vert;\n\toutput.texcoord = (pos[input.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset;\n\toutput.colorIndex = text.fillIndex;\n\treturn output;\n}\n\nfn sampleMsdf(texcoord: vec2f) -> f32 {\n\tlet c = textureSample(fontTexture, fontSampler, texcoord);\n\treturn max(min(c.r, c.g), min(max(c.r, c.g), c.b));\n}\n\n@fragment\nfn fragmentMain(input : VertexOutput) -> @location(0) vec4f {\n\t// pxRange (AKA distanceRange) comes from the msdfgen tool,\n\t// uses the default which is 4.\n\tlet pxRange = 4.0;\n\tlet sz = vec2f(textureDimensions(fontTexture, 0));\n\tlet dx = sz.x*length(vec2f(dpdxFine(input.texcoord.x), dpdyFine(input.texcoord.x)));\n\tlet dy = sz.y*length(vec2f(dpdxFine(input.texcoord.y), dpdyFine(input.texcoord.y)));\n\tlet toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);\n\tlet sigDist = sampleMsdf(input.texcoord) - 0.5;\n\tlet pxDist = sigDist * toPixels;\n\tlet edgeWidth = 0.5;\n\tlet alpha = smoothstep(-edgeWidth, edgeWidth, pxDist);\n\tif (alpha < 0.001) {\n\t\tdiscard;\n\t}\n\tlet fillColor = colors[i32(input.colorIndex)];\n\treturn vec4f(fillColor.rgb, fillColor.a * alpha);\n}\n"});class a{constructor(e,t,r,a,n){this.pipeline=e,this.bindGroup=t,this.lineHeight=r,this.chars=a,this.kernings=n;let o=Object.values(a);this.charCount=o.length,this.defaultChar=o[0]}getChar(e){return this.chars[e]??this.defaultChar}getXAdvance(e,t=-1){let r=this.getChar(e);if(t>=0){let a=this.kernings.get(e);if(a)return r.xadvance+(a.get(t)??0)}return r.xadvance}}let n=Q5.device.createBindGroupLayout({label:"MSDF text group layout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),o={},i=e.createGraphics(1,1);i.colorMode(e.RGB,1),e.loadFont=(s,l)=>{if("json"!=s.slice(s.lastIndexOf(".")+1))return i.loadFont(s,l);let d=s.slice(s.lastIndexOf("/")+1,s.lastIndexOf("-"));return(async(i,s,l)=>{t._preloadCount++;let d=await fetch(i);if(404==d.status)return t._preloadCount--,"";let c=await d.json(),h=i.lastIndexOf("/"),u=-1!=h?i.substring(0,h+1):"";d=await fetch(u+c.pages[0]);let p=await createImageBitmap(await d.blob()),f=[p.width,p.height,1],g=Q5.device.createTexture({label:`MSDF ${s}`,size:f,format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:p},{texture:g},f),"string"==typeof c.chars&&(c.chars=e.CSV.parse(c.chars," "),c.kernings=e.CSV.parse(c.kernings," "));let _=c.chars.length,x=Q5.device.createBuffer({size:32*_,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),m=new Float32Array(x.getMappedRange()),v=1/c.common.scaleW,y=1/c.common.scaleH,w={},b=0;for(let[e,t]of c.chars.entries())w[t.id]=t,w[t.id].charIndex=e,m[b]=t.x*v,m[b+1]=t.y*y,m[b+2]=t.width*v,m[b+3]=t.height*y,m[b+4]=t.width,m[b+5]=t.height,m[b+6]=t.xoffset,m[b+7]=-t.yoffset,b+=8;x.unmap();let S=Q5.device.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:16}),M=Q5.device.createBindGroupLayout({label:"MSDF font group layout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),C=Q5.device.createRenderPipeline({label:"msdf font pipeline",layout:Q5.device.createPipelineLayout({bindGroupLayouts:[...e.bindGroupLayouts,M,n]}),vertex:{module:r,entryPoint:"vertexMain"},fragment:{module:r,entryPoint:"fragmentMain",targets:[{format:"bgra8unorm",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{srcFactor:"one",dstFactor:"one"}}}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"}}),R=Q5.device.createBindGroup({label:"msdf font bind group",layout:M,entries:[{binding:0,resource:g.createView()},{binding:1,resource:S},{binding:2,resource:{buffer:x}}]}),Q=new Map;if(c.kernings)for(let e of c.kernings){let t=Q.get(e.first);t||(t=new Map,Q.set(e.first,t)),t.set(e.second,e.amount)}e._font=new a(C,R,c.common.lineHeight,w,Q),o[s]=e._font,e.pipelines[2]=e._font.pipeline,t._preloadCount--,l&&l(s)})(s,d,l),d},e._textSize=18,e._textAlign="left",e._textBaseline="alphabetic";let s=!1,l=22.5,d=4.5,c=1.25;e.textFont=t=>{e._font=o[t],e.drawStack.push(-1,(()=>{e._font=o[t],e.pipelines[2]=e._font.pipeline}))},e.textSize=t=>{e._textSize=t,s||(l=t*c,d=l-t)},e.textLeading=t=>{e._font.lineHeight=l=t,d=l-e._textSize,c=l/e._textSize,s=!0},e.textAlign=(t,r)=>{e._textAlign=t,r&&(e._textBaseline=r)},e._charStack=[],e._textStack=[];let h,u=(e,t,r)=>{let a=0,n=0,o=0,i=0,s=0,l=[],d=t.charCodeAt(0);for(let h=0;h{if(!e._font)return void(navigator.onLine&&!h&&(h=!0,e.loadFont("https://q5js.org/fonts/YaHei-msdf.json")));if(t.length>n){let e=[],r=0;for(;r=t.length){e.push(t.slice(r));break}let o=t.lastIndexOf(" ",a);(-1==o||o{let o=0;"center"==p?o=-.5*d.width- -.5*(d.width-d.lineWidths[a]):"right"==p&&(o=d.width-d.lineWidths[a]),c[_]=e+o,c[_+1]=t+r,c[_+2]=n.charIndex,c[_+3]=g,_+=4}))}else d=u(e._font,t,((e,t,r,a)=>{c[_]=e,c[_+1]=t,c[_+2]=a.charIndex,c[_+3]=g,_+=4})),"alphabetic"==f?a-=e._textSize:"center"==f?a-=.5*e._textSize:"bottom"==f&&(a-=l);e._charStack.push(c);let x=new Float32Array(6);e._matrixDirty&&e._saveMatrix(),x[0]=r,x[1]=-a,x[2]=e._textSize/44,x[3]=e._transformIndex,x[4]=e._fillIndex,x[5]=e._strokeIndex,e._textStack.push(x),e.drawStack.push(2,d.printedCharCount)},e.textWidth=t=>e._font?u(e._font,t).width:0,e.createTextImage=(t,r,a)=>{if(i.textSize(e._textSize),e._doFill){let t=4*e._fillIndex;i.fill(colorsStack.slice(t,t+4))}if(e._doStroke){let t=4*e._strokeIndex;i.stroke(colorsStack.slice(t,t+4))}let n=i.createTextImage(t,r,a);if(null==n.canvas.textureIndex)e._createTexture(n);else if(n.modified){let t=n.canvas,r=[t.width,t.height,1],a=e._textures[t.textureIndex];Q5.device.queue.copyExternalImageToTexture({source:t},{texture:a,colorSpace:e.canvas.colorSpace},r),n.modified=!1}return n},e.textImage=(t,r,a)=>{let n=e._imageMode;e._imageMode="corner";let o=e._textAlign;"center"==o?r-=t.canvas.hw:"right"==o&&(r-=t.width);let i=e._textBaseline;"alphabetic"==i?a-=t._leading:"center"==i?a-=t._middle:"bottom"==i?a-=t._bottom:"top"==i&&(a-=t._top),e.image(t,r,a),e._imageMode=n},e._hooks.preRender.push((()=>{if(!e._charStack.length)return;let t=0;for(let r of e._charStack)t+=4*r.length;let r=Q5.device.createBuffer({label:"charBuffer",size:t,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),a=new Float32Array(r.getMappedRange()),o=0;for(let t of e._charStack)a.set(t,o),o+=t.length;r.unmap();let i=6*e._textStack.length*4,s=Q5.device.createBuffer({label:"textBuffer",size:i,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),l=new Float32Array(s.getMappedRange());o=0;for(let t of e._textStack)l.set(t,o),o+=t.length;s.unmap(),e._textBindGroup=Q5.device.createBindGroup({label:"msdf text bind group",layout:n,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:s}}]})})),e._hooks.postRender.push((()=>{e._charStack.length=0,e._textStack.length=0}))}; diff --git a/src/q5-2d-canvas.js b/src/q5-2d-canvas.js index 8e33fc5..6a67d38 100644 --- a/src/q5-2d-canvas.js +++ b/src/q5-2d-canvas.js @@ -138,13 +138,4 @@ Q5.renderers.q2d.canvas = ($, q) => { document.body.append(vid); return vid; }; - - if (window && $._scope != 'graphics') { - window.addEventListener('resize', () => { - $._shouldResize = true; - q.windowWidth = window.innerWidth; - q.windowHeight = window.innerHeight; - q.deviceOrientation = window.screen?.orientation?.type; - }); - } }; diff --git a/src/q5-2d-text.js b/src/q5-2d-text.js index 1877a1c..eb3f5d8 100644 --- a/src/q5-2d-text.js +++ b/src/q5-2d-text.js @@ -1,9 +1,10 @@ Q5.renderers.q2d.text = ($, q) => { $._textAlign = 'left'; $._textBaseline = 'alphabetic'; + $._textSize = 12; let font = 'sans-serif', - tSize = 12, + leadingSet = false, leading = 15, leadDiff = 3, emphasis = 'normal', @@ -35,12 +36,12 @@ Q5.renderers.q2d.text = ($, q) => { styleHash = -1; }; $.textSize = (x) => { - if (x === undefined) return tSize; + if (x === undefined) return $._textSize; if ($._da) x *= $._da; - tSize = x; + $._textSize = x; fontMod = true; styleHash = -1; - if (!$._leadingSet) { + if (!leadingSet) { leading = x * 1.25; leadDiff = leading - x; } @@ -54,8 +55,8 @@ Q5.renderers.q2d.text = ($, q) => { if (x === undefined) return leading; if ($._da) x *= $._da; leading = x; - leadDiff = x - tSize; - $._leadingSet = true; + leadDiff = x - $._textSize; + leadingSet = true; styleHash = -1; }; $.textAlign = (horiz, vert) => { @@ -63,7 +64,6 @@ Q5.renderers.q2d.text = ($, q) => { if (vert) { $.ctx.textBaseline = $._textBaseline = vert == $.CENTER ? 'middle' : vert; } - styleHash = -1; }; $.textWidth = (str) => $.ctx.measureText(str).width; @@ -74,7 +74,7 @@ Q5.renderers.q2d.text = ($, q) => { $.textStroke = $.stroke; let updateStyleHash = () => { - let styleString = font + tSize + emphasis + leading; + let styleString = font + $._textSize + emphasis + leading; let hash = 5381; for (let i = 0; i < styleString.length; i++) { @@ -107,7 +107,7 @@ Q5.renderers.q2d.text = ($, q) => { let img, tX, tY; if (fontMod) { - ctx.font = `${emphasis} ${tSize}px ${font}`; + ctx.font = `${emphasis} ${$._textSize}px ${font}`; fontMod = false; } @@ -128,7 +128,7 @@ Q5.renderers.q2d.text = ($, q) => { if (str.indexOf('\n') == -1) lines[0] = str; else lines = str.split('\n'); - if (w) { + if (str.length > w) { let wrapped = []; for (let line of lines) { let i = 0; @@ -140,11 +140,9 @@ Q5.renderers.q2d.text = ($, q) => { break; } let end = line.lastIndexOf(' ', max); - if (end === -1 || end < i) { - end = max; - } + if (end === -1 || end < i) end = max; wrapped.push(line.slice(i, end)); - i = end; + i = end + 1; } } lines = wrapped; @@ -172,6 +170,7 @@ Q5.renderers.q2d.text = ($, q) => { img._top = descent + leadDiff; img._middle = img._top + ascent * 0.5; img._bottom = img._top + ascent; + img._leading = leading; } img._fill = $._fill; @@ -231,7 +230,7 @@ Q5.renderers.q2d.text = ($, q) => { else if (ta == 'right') x -= img.width; let bl = $._textBaseline; - if (bl == 'alphabetic') y -= leading; + if (bl == 'alphabetic') y -= img._leading; else if (bl == 'middle') y -= img._middle; else if (bl == 'bottom') y -= img._bottom; else if (bl == 'top') y -= img._top; diff --git a/src/q5-canvas.js b/src/q5-canvas.js index dc52dd2..358844f 100644 --- a/src/q5-canvas.js +++ b/src/q5-canvas.js @@ -201,7 +201,7 @@ Q5.modules.canvas = ($, q) => { function parentResized() { if ($.frameCount > 1) { - $._shouldResize = true; + $._didResize = true; $._adjustDisplay(); } } @@ -261,14 +261,9 @@ Q5.modules.canvas = ($, q) => { '_imageMode', '_rectMode', '_ellipseMode', - '_textFont', - '_textLeading', - '_leadingSet', '_textSize', '_textAlign', - '_textBaseline', - '_textStyle', - '_textWrap' + '_textBaseline' ]; $._styles = []; @@ -281,6 +276,15 @@ Q5.modules.canvas = ($, q) => { let styles = $._styles.pop(); for (let s of $._styleNames) $[s] = styles[s]; }; + + if (window && $._scope != 'graphics') { + window.addEventListener('resize', () => { + $._didResize = true; + q.windowWidth = window.innerWidth; + q.windowHeight = window.innerHeight; + q.deviceOrientation = window.screen?.orientation?.type; + }); + } }; Q5.canvasOptions = { diff --git a/src/q5-core.js b/src/q5-core.js index 3ab9cc2..7e2c7b3 100644 --- a/src/q5-core.js +++ b/src/q5-core.js @@ -70,9 +70,9 @@ function Q5(scope, parent, renderer) { let ts = timestamp || performance.now(); $._lastFrameTime ??= ts - $._targetFrameDuration; - if ($._shouldResize) { + if ($._didResize) { $.windowResized(); - $._shouldResize = false; + $._didResize = false; } if ($._loop) looper = raf($._draw); diff --git a/src/q5-util.js b/src/q5-util.js index 3899ee7..33f8fd4 100644 --- a/src/q5-util.js +++ b/src/q5-util.js @@ -5,10 +5,11 @@ Q5.modules.util = ($, q) => { fetch(path) .then((r) => { if (type == 'json') return r.json(); - if (type == 'text') return r.text(); + return r.text(); }) .then((r) => { q._preloadCount--; + if (type == 'csv') r = $.CSV.parse(r); Object.assign(ret, r); if (cb) cb(r); }); @@ -17,6 +18,21 @@ Q5.modules.util = ($, q) => { $.loadStrings = (path, cb) => $._loadFile(path, cb, 'text'); $.loadJSON = (path, cb) => $._loadFile(path, cb, 'json'); + $.loadCSV = (path, cb) => $._loadFile(path, cb, 'csv'); + + $.CSV = {}; + $.CSV.parse = (csv, sep = ',', lineSep = '\n') => { + let a = [], + lns = csv.split(lineSep), + headers = lns[0].split(sep); + for (let i = 1; i < lns.length; i++) { + let o = {}, + ln = lns[i].split(sep); + headers.forEach((h, i) => (o[h] = JSON.parse(ln[i]))); + a.push(o); + } + return a; + }; if (typeof localStorage == 'object') { $.storeItem = localStorage.setItem; diff --git a/src/q5-webgpu-canvas.js b/src/q5-webgpu-canvas.js index dd132cc..c966218 100644 --- a/src/q5-webgpu-canvas.js +++ b/src/q5-webgpu-canvas.js @@ -24,7 +24,8 @@ Q5.renderers.webgpu.canvas = ($, q) => { // colors used for each draw call let colorsStack = ($.colorsStack = [1, 1, 1, 1]); - $._envLayout = Q5.device.createBindGroupLayout({ + $._transformLayout = Q5.device.createBindGroupLayout({ + label: 'transformLayout', entries: [ { binding: 0, @@ -33,14 +34,9 @@ Q5.renderers.webgpu.canvas = ($, q) => { type: 'uniform', hasDynamicOffset: false } - } - ] - }); - - $._transformLayout = Q5.device.createBindGroupLayout({ - entries: [ + }, { - binding: 0, + binding: 1, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage', @@ -50,9 +46,9 @@ Q5.renderers.webgpu.canvas = ($, q) => { ] }); - $.bindGroupLayouts = [$._envLayout, $._transformLayout]; + $.bindGroupLayouts = [$._transformLayout]; - const uniformBuffer = Q5.device.createBuffer({ + let uniformBuffer = Q5.device.createBuffer({ size: 8, // Size of two floats usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }); @@ -67,18 +63,6 @@ Q5.renderers.webgpu.canvas = ($, q) => { Q5.device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([$.canvas.hw, $.canvas.hh])); - $._envBindGroup = Q5.device.createBindGroup({ - layout: $._envLayout, - entries: [ - { - binding: 0, - resource: { - buffer: uniformBuffer - } - } - ] - }); - return c; }; @@ -88,7 +72,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { // current color index, used to associate a vertex with a color let colorIndex = 0; - const addColor = (r, g, b, a = 1) => { + let addColor = (r, g, b, a = 1) => { if (typeof r == 'string') r = $.color(r); else if (b == undefined) { // grayscale mode `fill(1, 0.5)` @@ -100,6 +84,8 @@ Q5.renderers.webgpu.canvas = ($, q) => { colorIndex++; }; + $._fillIndex = $._strokeIndex = -1; + $.fill = (r, g, b, a) => { addColor(r, g, b, a); $._doFill = true; @@ -131,56 +117,70 @@ Q5.renderers.webgpu.canvas = ($, q) => { }; $.resetMatrix(); - // Boolean to track if the matrix has been modified + // tracks if the matrix has been modified $._matrixDirty = false; - // Array to store transformation matrices for the render pass + // array to store transformation matrices for the render pass $.transformStates = [$._matrix.slice()]; - // Stack to keep track of transformation matrix indexes + // stack to keep track of transformation matrix indexes $._transformIndexStack = []; $.translate = (x, y, z) => { if (!x && !y && !z) return; // Update the translation values - $._matrix[3] += x; - $._matrix[7] -= y; - $._matrix[11] += z || 0; + $._matrix[12] += x; + $._matrix[13] -= y; + $._matrix[14] += z || 0; $._matrixDirty = true; }; - $.rotate = (r) => { - if (!r) return; - if ($._angleMode) r *= $._DEGTORAD; + $.rotate = (a) => { + if (!a) return; + if ($._angleMode) a *= $._DEGTORAD; - let cosR = Math.cos(r); - let sinR = Math.sin(r); + let cosR = Math.cos(a); + let sinR = Math.sin(a); + + let m = $._matrix; + + let m0 = m[0], + m1 = m[1], + m4 = m[4], + m5 = m[5]; - let m0 = $._matrix[0], - m1 = $._matrix[1], - m4 = $._matrix[4], - m5 = $._matrix[5]; if (!m0 && !m1 && !m4 && !m5) { - $._matrix[0] = cosR; - $._matrix[1] = sinR; - $._matrix[4] = -sinR; - $._matrix[5] = cosR; + m[0] = cosR; + m[1] = sinR; + m[4] = -sinR; + m[5] = cosR; } else { - $._matrix[0] = m0 * cosR + m4 * sinR; - $._matrix[1] = m1 * cosR + m5 * sinR; - $._matrix[4] = m0 * -sinR + m4 * cosR; - $._matrix[5] = m1 * -sinR + m5 * cosR; + m[0] = m0 * cosR + m4 * sinR; + m[1] = m1 * cosR + m5 * sinR; + m[4] = m4 * cosR - m0 * sinR; + m[5] = m5 * cosR - m1 * sinR; } $._matrixDirty = true; }; - $.scale = (sx = 1, sy, sz = 1) => { - sy ??= sx; + $.scale = (x = 1, y, z = 1) => { + y ??= x; + + let m = $._matrix; - $._matrix[0] *= sx; - $._matrix[5] *= sy; - $._matrix[10] *= sz; + m[0] *= x; + m[1] *= x; + m[2] *= x; + m[3] *= x; + m[4] *= y; + m[5] *= y; + m[6] *= y; + m[7] *= y; + m[8] *= z; + m[9] *= z; + m[10] *= z; + m[11] *= z; $._matrixDirty = true; }; @@ -252,7 +252,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { if (!$._transformIndexStack.length) { return console.warn('Matrix index stack is empty!'); } - // Pop the last matrix index from the stack and set it as the current matrix index + // Pop the last matrix index and set it as the current matrix index let idx = $._transformIndexStack.pop(); $._matrix = $.transformStates[idx].slice(); $._transformIndex = idx; @@ -275,7 +275,6 @@ Q5.renderers.webgpu.canvas = ($, q) => { // left, right, top, bottom let l, r, t, b; if (!mode || mode == 'corner') { - // CORNER l = x; r = x + w; t = -y; @@ -315,7 +314,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { $._render = () => { if (transformStates.length > 1 || !$._transformBindGroup) { - const transformBuffer = Q5.device.createBuffer({ + let transformBuffer = Q5.device.createBuffer({ size: transformStates.length * 64, // Size of 16 floats usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST }); @@ -327,6 +326,12 @@ Q5.renderers.webgpu.canvas = ($, q) => { entries: [ { binding: 0, + resource: { + buffer: uniformBuffer + } + }, + { + binding: 1, resource: { buffer: transformBuffer } @@ -335,35 +340,47 @@ Q5.renderers.webgpu.canvas = ($, q) => { }); } - pass.setBindGroup(0, $._envBindGroup); - pass.setBindGroup(1, $._transformBindGroup); + pass.setBindGroup(0, $._transformBindGroup); for (let m of $._hooks.preRender) m(); let drawVertOffset = 0; let imageVertOffset = 0; + let textCharOffset = 0; let curPipelineIndex = -1; let curTextureIndex = -1; - pass.setPipeline($.pipelines[0]); - for (let i = 0; i < drawStack.length; i += 2) { let v = drawStack[i + 1]; + if (drawStack[i] == -1) { + v(); + continue; + } + if (curPipelineIndex != drawStack[i]) { curPipelineIndex = drawStack[i]; pass.setPipeline($.pipelines[curPipelineIndex]); } if (curPipelineIndex == 0) { - pass.draw(v, 1, drawVertOffset, 0); + // v is the number of vertices + pass.draw(v, 1, drawVertOffset); drawVertOffset += v; } else if (curPipelineIndex == 1) { if (curTextureIndex != v) { - pass.setBindGroup(3, $._textureBindGroups[v]); + // v is the texture index + pass.setBindGroup(2, $._textureBindGroups[v]); } - pass.draw(6, 1, imageVertOffset, 0); + pass.draw(6, 1, imageVertOffset); imageVertOffset += 6; + } else if (curPipelineIndex == 2) { + pass.setBindGroup(2, $._font.bindGroup); + pass.setBindGroup(3, $._textBindGroup); + + // v is the number of characters in the text + pass.draw(4, v, 0, textCharOffset); + textCharOffset += v; } } @@ -372,7 +389,7 @@ Q5.renderers.webgpu.canvas = ($, q) => { $._finishRender = () => { pass.end(); - const commandBuffer = $.encoder.finish(); + let commandBuffer = $.encoder.finish(); Q5.device.queue.submit([commandBuffer]); q.pass = $.encoder = null; diff --git a/src/q5-webgpu-drawing.js b/src/q5-webgpu-drawing.js index 7ea7f00..9a35097 100644 --- a/src/q5-webgpu-drawing.js +++ b/src/q5-webgpu-drawing.js @@ -12,8 +12,8 @@ Q5.renderers.webgpu.drawing = ($, q) => { label: 'drawingVertexShader', code: ` struct VertexOutput { - @builtin(position) position: vec4, - @location(1) colorIndex: f32 + @builtin(position) position: vec4f, + @location(0) colorIndex: f32 }; struct Uniforms { @@ -22,12 +22,12 @@ struct Uniforms { }; @group(0) @binding(0) var uniforms: Uniforms; -@group(1) @binding(0) var transforms: array>; +@group(0) @binding(1) var transforms: array>; @vertex -fn vertexMain(@location(0) pos: vec2, @location(1) colorIndex: f32, @location(2) transformIndex: f32) -> VertexOutput { - var vert = vec4(pos, 0.0, 1.0); - vert *= transforms[i32(transformIndex)]; +fn vertexMain(@location(0) pos: vec2f, @location(1) colorIndex: f32, @location(2) transformIndex: f32) -> VertexOutput { + var vert = vec4f(pos, 0.0, 1.0); + vert = transforms[i32(transformIndex)] * vert; vert.x /= uniforms.halfWidth; vert.y /= uniforms.halfHeight; @@ -42,17 +42,18 @@ fn vertexMain(@location(0) pos: vec2, @location(1) colorIndex: f32, @locati let fragmentShader = Q5.device.createShaderModule({ label: 'drawingFragmentShader', code: ` -@group(2) @binding(0) var uColors : array>; +@group(1) @binding(0) var colors : array; @fragment -fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 { - let index = u32(colorIndex); - return mix(uColors[index], uColors[index + 1u], fract(colorIndex)); +fn fragmentMain(@location(0) colorIndex: f32) -> @location(0) vec4f { + let index = i32(colorIndex); + return mix(colors[index], colors[index + 1], fract(colorIndex)); } ` }); colorsLayout = Q5.device.createBindGroupLayout({ + label: 'colorsLayout', entries: [ { binding: 0, @@ -283,10 +284,17 @@ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 { $.background = (r, g, b, a) => { $.push(); $.resetMatrix(); - if (r.src) $.image(r, -c.hw, -c.hh, c.w, c.h); - else { + if (r.src) { + let og = $._imageMode; + $._imageMode = 'corner'; + $.image(r, -c.hw, -c.hh, c.w, c.h); + $._imageMode = og; + } else { + let og = $._rectMode; + $._rectMode = 'corner'; $.fill(r, g, b, a); $.rect(-c.hw, -c.hh, c.w, c.h); + $._rectMode = og; } $.pop(); }; @@ -394,7 +402,7 @@ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4 { }); // set the bind group once before rendering - $.pass.setBindGroup(2, $._colorsBindGroup); + $.pass.setBindGroup(1, $._colorsBindGroup); }); $._hooks.postRender.push(() => { diff --git a/src/q5-webgpu-image.js b/src/q5-webgpu-image.js index 462a7bb..da84516 100644 --- a/src/q5-webgpu-image.js +++ b/src/q5-webgpu-image.js @@ -6,8 +6,8 @@ Q5.renderers.webgpu.image = ($, q) => { label: 'imageVertexShader', code: ` struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texCoord: vec2 + @builtin(position) position: vec4f, + @location(0) texCoord: vec2f }; struct Uniforms { @@ -16,12 +16,12 @@ struct Uniforms { }; @group(0) @binding(0) var uniforms: Uniforms; -@group(1) @binding(0) var transforms: array>; +@group(0) @binding(1) var transforms: array>; @vertex -fn vertexMain(@location(0) pos: vec2, @location(1) texCoord: vec2, @location(2) transformIndex: f32) -> VertexOutput { - var vert = vec4(pos, 0.0, 1.0); - vert *= transforms[i32(transformIndex)]; +fn vertexMain(@location(0) pos: vec2f, @location(1) texCoord: vec2f, @location(2) transformIndex: f32) -> VertexOutput { + var vert = vec4f(pos, 0.0, 1.0); + vert = transforms[i32(transformIndex)] * vert; vert.x /= uniforms.halfWidth; vert.y /= uniforms.halfHeight; @@ -36,11 +36,11 @@ fn vertexMain(@location(0) pos: vec2, @location(1) texCoord: vec2, @lo let fragmentShader = Q5.device.createShaderModule({ label: 'imageFragmentShader', code: ` -@group(3) @binding(0) var samp: sampler; -@group(3) @binding(1) var texture: texture_2d; +@group(2) @binding(0) var samp: sampler; +@group(2) @binding(1) var texture: texture_2d; @fragment -fn fragmentMain(@location(0) texCoord: vec2) -> @location(0) vec4 { +fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f { // Sample the texture using the interpolated texture coordinate return textureSample(texture, samp, texCoord); } @@ -72,11 +72,9 @@ fn fragmentMain(@location(0) texCoord: vec2) -> @location(0) vec4 { ] }; - $.bindGroupLayouts.push(textureLayout); - const pipelineLayout = Q5.device.createPipelineLayout({ label: 'imagePipelineLayout', - bindGroupLayouts: $.bindGroupLayouts + bindGroupLayouts: [...$.bindGroupLayouts, textureLayout] }); $.pipelines[1] = Q5.device.createRenderPipeline({ diff --git a/src/q5-webgpu-text.js b/src/q5-webgpu-text.js index eff78e6..64cc7b7 100644 --- a/src/q5-webgpu-text.js +++ b/src/q5-webgpu-text.js @@ -1,32 +1,520 @@ Q5.renderers.webgpu.text = ($, q) => { - let t = $.createGraphics(1, 1); - t.pixelDensity($._pixelDensity); - t._imageMode = 'corner'; + let textShader = Q5.device.createShaderModule({ + label: 'MSDF text shader', + code: ` +// Positions for simple quad geometry +const pos = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0)); - $.loadFont = (f) => { +struct VertexInput { + @builtin(vertex_index) vertex : u32, + @builtin(instance_index) instance : u32, +}; +struct VertexOutput { + @builtin(position) position : vec4f, + @location(0) texcoord : vec2f, + @location(1) colorIndex : f32 +}; +struct Char { + texOffset: vec2f, + texExtent: vec2f, + size: vec2f, + offset: vec2f, +}; +struct Text { + pos: vec2f, + scale: f32, + transformIndex: f32, + fillIndex: f32, + strokeIndex: f32 +}; +struct Uniforms { + halfWidth: f32, + halfHeight: f32 +}; + +@group(0) @binding(0) var uniforms: Uniforms; +@group(0) @binding(1) var transforms: array>; + +@group(1) @binding(0) var colors : array; + +@group(2) @binding(0) var fontTexture: texture_2d; +@group(2) @binding(1) var fontSampler: sampler; +@group(2) @binding(2) var fontChars: array; + +@group(3) @binding(0) var textChars: array; +@group(3) @binding(1) var textMetadata: array; + +@vertex +fn vertexMain(input : VertexInput) -> VertexOutput { + let char = textChars[input.instance]; + + let text = textMetadata[i32(char.w)]; + + let fontChar = fontChars[i32(char.z)]; + + let charPos = ((pos[input.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos; + + var vert = vec4f(charPos, 0.0, 1.0); + vert = transforms[i32(text.transformIndex)] * vert; + vert.x /= uniforms.halfWidth; + vert.y /= uniforms.halfHeight; + + var output : VertexOutput; + output.position = vert; + output.texcoord = (pos[input.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset; + output.colorIndex = text.fillIndex; + return output; +} + +fn sampleMsdf(texcoord: vec2f) -> f32 { + let c = textureSample(fontTexture, fontSampler, texcoord); + return max(min(c.r, c.g), min(max(c.r, c.g), c.b)); +} + +@fragment +fn fragmentMain(input : VertexOutput) -> @location(0) vec4f { + // pxRange (AKA distanceRange) comes from the msdfgen tool, + // uses the default which is 4. + let pxRange = 4.0; + let sz = vec2f(textureDimensions(fontTexture, 0)); + let dx = sz.x*length(vec2f(dpdxFine(input.texcoord.x), dpdyFine(input.texcoord.x))); + let dy = sz.y*length(vec2f(dpdxFine(input.texcoord.y), dpdyFine(input.texcoord.y))); + let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy); + let sigDist = sampleMsdf(input.texcoord) - 0.5; + let pxDist = sigDist * toPixels; + let edgeWidth = 0.5; + let alpha = smoothstep(-edgeWidth, edgeWidth, pxDist); + if (alpha < 0.001) { + discard; + } + let fillColor = colors[i32(input.colorIndex)]; + return vec4f(fillColor.rgb, fillColor.a * alpha); +} +` + }); + + class MsdfFont { + constructor(pipeline, bindGroup, lineHeight, chars, kernings) { + this.pipeline = pipeline; + this.bindGroup = bindGroup; + this.lineHeight = lineHeight; + this.chars = chars; + this.kernings = kernings; + let charArray = Object.values(chars); + this.charCount = charArray.length; + this.defaultChar = charArray[0]; + } + getChar(charCode) { + return this.chars[charCode] ?? this.defaultChar; + } + // Gets the distance in pixels a line should advance for a given character code. If the upcoming + // character code is given any kerning between the two characters will be taken into account. + getXAdvance(charCode, nextCharCode = -1) { + let char = this.getChar(charCode); + if (nextCharCode >= 0) { + let kerning = this.kernings.get(charCode); + if (kerning) { + return char.xadvance + (kerning.get(nextCharCode) ?? 0); + } + } + return char.xadvance; + } + } + + let textBindGroupLayout = Q5.device.createBindGroupLayout({ + label: 'MSDF text group layout', + entries: [ + { + binding: 0, + visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, + buffer: { type: 'read-only-storage' } + }, + { + binding: 1, + visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, + buffer: { type: 'read-only-storage' } + } + ] + }); + + let fonts = {}; + + let createFont = async (fontJsonUrl, fontName, cb) => { q._preloadCount++; - return t.loadFont(f, () => { + + let res = await fetch(fontJsonUrl); + if (res.status == 404) { q._preloadCount--; + return ''; + } + let atlas = await res.json(); + + let slashIdx = fontJsonUrl.lastIndexOf('/'); + let baseUrl = slashIdx != -1 ? fontJsonUrl.substring(0, slashIdx + 1) : ''; + // load font image + res = await fetch(baseUrl + atlas.pages[0]); + let img = await createImageBitmap(await res.blob()); + + // convert image to texture + let imgSize = [img.width, img.height, 1]; + let texture = Q5.device.createTexture({ + label: `MSDF ${fontName}`, + size: imgSize, + format: 'rgba8unorm', + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT + }); + Q5.device.queue.copyExternalImageToTexture({ source: img }, { texture }, imgSize); + + // to make q5's default font file smaller, + // the chars and kernings are stored as csv strings + if (typeof atlas.chars == 'string') { + atlas.chars = $.CSV.parse(atlas.chars, ' '); + atlas.kernings = $.CSV.parse(atlas.kernings, ' '); + } + + let charCount = atlas.chars.length; + let charsBuffer = Q5.device.createBuffer({ + size: charCount * 32, + usage: GPUBufferUsage.STORAGE, + mappedAtCreation: true + }); + + let fontChars = new Float32Array(charsBuffer.getMappedRange()); + let u = 1 / atlas.common.scaleW; + let v = 1 / atlas.common.scaleH; + let chars = {}; + let o = 0; // offset + for (let [i, char] of atlas.chars.entries()) { + chars[char.id] = char; + chars[char.id].charIndex = i; + fontChars[o] = char.x * u; // texOffset.x + fontChars[o + 1] = char.y * v; // texOffset.y + fontChars[o + 2] = char.width * u; // texExtent.x + fontChars[o + 3] = char.height * v; // texExtent.y + fontChars[o + 4] = char.width; // size.x + fontChars[o + 5] = char.height; // size.y + fontChars[o + 6] = char.xoffset; // offset.x + fontChars[o + 7] = -char.yoffset; // offset.y + o += 8; + } + charsBuffer.unmap(); + + let fontSampler = Q5.device.createSampler({ + minFilter: 'linear', + magFilter: 'linear', + mipmapFilter: 'linear', + maxAnisotropy: 16 + }); + let fontBindGroupLayout = Q5.device.createBindGroupLayout({ + label: 'MSDF font group layout', + entries: [ + { + binding: 0, + visibility: GPUShaderStage.FRAGMENT, + texture: {} + }, + { + binding: 1, + visibility: GPUShaderStage.FRAGMENT, + sampler: {} + }, + { + binding: 2, + visibility: GPUShaderStage.VERTEX, + buffer: { type: 'read-only-storage' } + } + ] + }); + let fontPipeline = Q5.device.createRenderPipeline({ + label: 'msdf font pipeline', + layout: Q5.device.createPipelineLayout({ + bindGroupLayouts: [...$.bindGroupLayouts, fontBindGroupLayout, textBindGroupLayout] + }), + vertex: { + module: textShader, + entryPoint: 'vertexMain' + }, + fragment: { + module: textShader, + entryPoint: 'fragmentMain', + targets: [ + { + format: 'bgra8unorm', + blend: { + color: { + srcFactor: 'src-alpha', + dstFactor: 'one-minus-src-alpha' + }, + alpha: { + srcFactor: 'one', + dstFactor: 'one' + } + } + } + ] + }, + primitive: { + topology: 'triangle-strip', + stripIndexFormat: 'uint32' + } + }); + + let fontBindGroup = Q5.device.createBindGroup({ + label: 'msdf font bind group', + layout: fontBindGroupLayout, + entries: [ + { + binding: 0, + resource: texture.createView() + }, + { binding: 1, resource: fontSampler }, + { binding: 2, resource: { buffer: charsBuffer } } + ] }); + + let kernings = new Map(); + if (atlas.kernings) { + for (let kerning of atlas.kernings) { + let charKerning = kernings.get(kerning.first); + if (!charKerning) { + charKerning = new Map(); + kernings.set(kerning.first, charKerning); + } + charKerning.set(kerning.second, kerning.amount); + } + } + + $._font = new MsdfFont(fontPipeline, fontBindGroup, atlas.common.lineHeight, chars, kernings); + + fonts[fontName] = $._font; + $.pipelines[2] = $._font.pipeline; + + q._preloadCount--; + + if (cb) cb(fontName); }; - // directly add these text setting functions to the webgpu renderer - $.textFont = t.textFont; - $.textSize = t.textSize; - $.textLeading = t.textLeading; - $.textStyle = t.textStyle; - $.textAlign = t.textAlign; - $.textWidth = t.textWidth; - $.textAscent = t.textAscent; - $.textDescent = t.textDescent; + // q2d graphics context to use for text image creation + let g = $.createGraphics(1, 1); + g.colorMode($.RGB, 1); - $.textFill = (r, g, b, a) => t.fill($.color(r, g, b, a)); - $.textStroke = (r, g, b, a) => t.stroke($.color(r, g, b, a)); + $.loadFont = (url, cb) => { + let ext = url.slice(url.lastIndexOf('.') + 1); + if (ext != 'json') return g.loadFont(url, cb); + let fontName = url.slice(url.lastIndexOf('/') + 1, url.lastIndexOf('-')); + createFont(url, fontName, cb); + return fontName; + }; + + $._textSize = 18; + $._textAlign = 'left'; + $._textBaseline = 'alphabetic'; + let leadingSet = false, + leading = 22.5, + leadDiff = 4.5, + leadPercent = 1.25; + + $.textFont = (fontName) => { + $._font = fonts[fontName]; + + // replay the change of font in the draw stack + $.drawStack.push(-1, () => { + $._font = fonts[fontName]; + $.pipelines[2] = $._font.pipeline; + }); + }; + $.textSize = (size) => { + $._textSize = size; + if (!leadingSet) { + leading = size * leadPercent; + leadDiff = leading - size; + } + }; + $.textLeading = (lineHeight) => { + $._font.lineHeight = leading = lineHeight; + leadDiff = leading - $._textSize; + leadPercent = leading / $._textSize; + leadingSet = true; + }; + $.textAlign = (horiz, vert) => { + $._textAlign = horiz; + if (vert) $._textBaseline = vert; + }; + + $._charStack = []; + $._textStack = []; + + let measureText = (font, text, charCallback) => { + let maxWidth = 0, + offsetX = 0, + offsetY = 0, + line = 0, + printedCharCount = 0, + lineWidths = [], + nextCharCode = text.charCodeAt(0); + + for (let i = 0; i < text.length; ++i) { + let charCode = nextCharCode; + nextCharCode = i < text.length - 1 ? text.charCodeAt(i + 1) : -1; + switch (charCode) { + case 10: // Newline + lineWidths.push(offsetX); + line++; + maxWidth = Math.max(maxWidth, offsetX); + offsetX = 0; + offsetY -= font.lineHeight * leadPercent; + break; + case 13: // CR + break; + case 32: // Space + // advance the offset without actually adding a character + offsetX += font.getXAdvance(charCode); + break; + case 9: // Tab + offsetX += font.getXAdvance(charCode) * 2; + break; + default: + if (charCallback) { + charCallback(offsetX, offsetY, line, font.getChar(charCode)); + } + offsetX += font.getXAdvance(charCode, nextCharCode); + printedCharCount++; + } + } + lineWidths.push(offsetX); + maxWidth = Math.max(maxWidth, offsetX); + return { + width: maxWidth, + height: lineWidths.length * font.lineHeight * leadPercent, + lineWidths, + printedCharCount + }; + }; + + let initLoadDefaultFont; $.text = (str, x, y, w, h) => { - let img = t.createTextImage(str, w, h); + if (!$._font) { + // check if online and loading the default font hasn't been attempted yet + if (navigator.onLine && !initLoadDefaultFont) { + initLoadDefaultFont = true; + $.loadFont('https://q5js.org/fonts/YaHei-msdf.json'); + } + return; + } + + if (str.length > w) { + let wrapped = []; + let i = 0; + while (i < str.length) { + let max = i + w; + if (max >= str.length) { + wrapped.push(str.slice(i)); + break; + } + let end = str.lastIndexOf(' ', max); + if (end == -1 || end < i) end = max; + wrapped.push(str.slice(i, end)); + i = end + 1; + } + str = wrapped.join('\n'); + } - if (img.canvas.textureIndex === undefined) { + let spaces = 0, // whitespace char count, not literal spaces + hasNewline; + for (let i = 0; i < str.length; i++) { + let c = str[i]; + switch (c) { + case '\n': + hasNewline = true; + case '\r': + case '\t': + case ' ': + spaces++; + } + } + + let charsData = new Float32Array((str.length - spaces) * 4); + + let ta = $._textAlign, + tb = $._textBaseline, + textIndex = $._textStack.length, + o = 0, // offset + measurements; + + if (ta == 'left' && !hasNewline) { + measurements = measureText($._font, str, (textX, textY, line, char) => { + charsData[o] = textX; + charsData[o + 1] = textY; + charsData[o + 2] = char.charIndex; + charsData[o + 3] = textIndex; + o += 4; + }); + + if (tb == 'alphabetic') y -= $._textSize; + else if (tb == 'center') y -= $._textSize * 0.5; + else if (tb == 'bottom') y -= leading; + } else { + // measure the text to get the line widths before setting + // the x position to properly align the text + measurements = measureText($._font, str); + + let offsetY = 0; + if (tb == 'alphabetic') y -= $._textSize; + else if (tb == 'center') offsetY = measurements.height * 0.5; + else if (tb == 'bottom') offsetY = measurements.height; + + measureText($._font, str, (textX, textY, line, char) => { + let offsetX = 0; + if (ta == 'center') { + offsetX = measurements.width * -0.5 - (measurements.width - measurements.lineWidths[line]) * -0.5; + } else if (ta == 'right') { + offsetX = measurements.width - measurements.lineWidths[line]; + } + charsData[o] = textX + offsetX; + charsData[o + 1] = textY + offsetY; + charsData[o + 2] = char.charIndex; + charsData[o + 3] = textIndex; + o += 4; + }); + } + $._charStack.push(charsData); + + let text = new Float32Array(6); + + if ($._matrixDirty) $._saveMatrix(); + + text[0] = x; + text[1] = -y; + text[2] = $._textSize / 44; + text[3] = $._transformIndex; + text[4] = $._fillIndex; + text[5] = $._strokeIndex; + + $._textStack.push(text); + $.drawStack.push(2, measurements.printedCharCount); + }; + + $.textWidth = (str) => { + if (!$._font) return 0; + return measureText($._font, str).width; + }; + + $.createTextImage = (str, w, h) => { + g.textSize($._textSize); + + if ($._doFill) { + let fi = $._fillIndex * 4; + g.fill(colorsStack.slice(fi, fi + 4)); + } + if ($._doStroke) { + let si = $._strokeIndex * 4; + g.stroke(colorsStack.slice(si, si + 4)); + } + + let img = g.createTextImage(str, w, h); + + if (img.canvas.textureIndex == undefined) { $._createTexture(img); } else if (img.modified) { let cnv = img.canvas; @@ -40,27 +528,92 @@ Q5.renderers.webgpu.text = ($, q) => { ); img.modified = false; } - - $.textImage(img, x, y); + return img; }; - $.createTextImage = t.createTextImage; - $.textImage = (img, x, y) => { let og = $._imageMode; $._imageMode = 'corner'; - let ta = t._textAlign; + let ta = $._textAlign; if (ta == 'center') x -= img.canvas.hw; else if (ta == 'right') x -= img.width; - let bl = t._textBaseline; - if (bl == 'alphabetic') y -= t._textLeading; - else if (bl == 'middle') y -= img._middle; + let bl = $._textBaseline; + if (bl == 'alphabetic') y -= img._leading; + else if (bl == 'center') y -= img._middle; else if (bl == 'bottom') y -= img._bottom; else if (bl == 'top') y -= img._top; $.image(img, x, y); $._imageMode = og; }; + + $._hooks.preRender.push(() => { + if (!$._charStack.length) return; + + // Calculate total buffer size for text data + let totalTextSize = 0; + for (let charsData of $._charStack) { + totalTextSize += charsData.length * 4; + } + + // Create a single buffer for all text data + let charBuffer = Q5.device.createBuffer({ + label: 'charBuffer', + size: totalTextSize, + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, + mappedAtCreation: true + }); + + // Copy all text data into the buffer + let textArray = new Float32Array(charBuffer.getMappedRange()); + let o = 0; + for (let array of $._charStack) { + textArray.set(array, o); + o += array.length; + } + charBuffer.unmap(); + + // Calculate total buffer size for metadata + let totalMetadataSize = $._textStack.length * 6 * 4; + + // Create a single buffer for all metadata + let textBuffer = Q5.device.createBuffer({ + label: 'textBuffer', + size: totalMetadataSize, + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, + mappedAtCreation: true + }); + + // Copy all metadata into the buffer + let metadataArray = new Float32Array(textBuffer.getMappedRange()); + o = 0; + for (let array of $._textStack) { + metadataArray.set(array, o); + o += array.length; + } + textBuffer.unmap(); + + // Create a single bind group for the text buffer and metadata buffer + $._textBindGroup = Q5.device.createBindGroup({ + label: 'msdf text bind group', + layout: textBindGroupLayout, + entries: [ + { + binding: 0, + resource: { buffer: charBuffer } + }, + { + binding: 1, + resource: { buffer: textBuffer } + } + ] + }); + }); + + $._hooks.postRender.push(() => { + $._charStack.length = 0; + $._textStack.length = 0; + }); }; diff --git a/src/readme.md b/src/readme.md index 022511b..9c286bd 100644 --- a/src/readme.md +++ b/src/readme.md @@ -54,6 +54,11 @@ WebGPU rendering modules are in development: - [webgpu-drawing](#webgpu-drawing) - [webgpu-image](#webgpu-image) - [webgpu-text](#webgpu-text) + - [Default Font](#default-font) + - [Loading Custom Fonts](#loading-custom-fonts) + - [Displaying Emojis](#displaying-emojis) + - [Lightweight Use](#lightweight-use) + - [Implemented functions](#implemented-functions) - [math](#math) - [noisier](#noisier) @@ -179,13 +184,83 @@ Implemented functions: ## webgpu-text -> Use `textFill` and `textStroke` to set text colors. +The q5 WebGPU text renderer uses the multi-channel signed distance fields (MSDF) technique for high performance and high quality real-time text rendering. Text can be rapidly recolored, rotated, and scaled without any loss in quality or performance. -Internally, q5's WebGPU renderer uses a q5 graphics object to draw text to a Canvas2D canvas via `createTextImage`, then converts that canvas to a WebGPU texture. Each texture is cached, so it doesn't have to be recreated every frame that users want to display the same text. +MSDF, introduced by Chlumsky Viktor in his master's thesis ["Shape Decomposition for Multi-channel Distance Fields" (2015)](https://dspace.cvut.cz/bitstream/handle/10467/62770/F8-DP-2015-Chlumsky-Viktor-thesis.pdf), improves upon the signed distance field (SDF) technique, popularized by Chris Green and [Valve Software](https://www.valvesoftware.com/en/) in ["Improved Alpha-Tested Magnification for Vector Textures and Special Effects" (2007)](https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf). -Implemented functions: +| SDF | MSDF | +| -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| ![demo-sdf16](https://user-images.githubusercontent.com/18639794/106391905-e679af00-63ef-11eb-96c3-993176330911.png) | ![demo-msdf16](https://user-images.githubusercontent.com/18639794/106391899-e37ebe80-63ef-11eb-988b-4764004bb196.png) | + +### Default Font + +For convenience, if no font is loaded before `text` is run, then q5's default MSDF font is loaded: https://q5js.org/fonts/YaHei-msdf.json + +![YaHei msdf texture](https://q5js.org/fonts/YaHei.png) + +This 512x512 msdf texture (207kb) was made with the [Microsoft YaHei](https://learn.microsoft.com/en-us/typography/font-list/microsoft-yahei) font and stores every character visible on a standard English keyboard, letters with diacritics (accents) used in European languages, and mathematical symbols. + +``` +!"#$%&'()\*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^\_`abcdefghijklmnopqrstuvwxyz{|}~€¡¢£¥©®°²³´·¹º¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ‘’“”π +``` + +> Do you think any other characters ought to be included in the default set? Let us know! https://github.com/q5js/q5.js/issues + +### Loading Custom Fonts + +You can choose a custom set of characters and convert fonts to MSDF format by using the [msdf-bmfont-xml](https://msdf-bmfont.donmccurdy.com/) website, created by Don McCurdy. + +Here's how to load an MSDF font: + +```js +function preload() { + loadFont('arial-msdf.json'); +} + +function setup() { + createCanvas(200, 200); +} + +function draw() { + fill(0.71, 0.92, 1); + text('Hello, World!', mouseX, mouseY); +} + +Q5.webgpu(); +``` + +### Displaying Emojis + +Full color emoji characters can't be rendered using the MSDF technique, so use `createTextImage` and display them with `textImage`: + +```js +let puppy; + +function setup() { + createCanvas(200, 200); + textSize(100); + puppy = createTextImage('🐶'); +} + +function draw() { + textAlign(CENTER, CENTER); + textImage(puppy, 0, 0); +} + +Q5.webgpu(); +``` + +### Lightweight Use + +For super lightweight use load , which has a limited character set of english letters and some common punctuation symbols that completely fill in a 256x256 texture (73kb). + +``` +!@'",-.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +``` + +### Implemented functions -`loadFont`,`textFont`, `textSize`, `textLeading`, `textStyle`, `textAlign`, `textWidth`, `textAscent`, `textDescent`, `textFill`, `textStroke`, `text` +`loadFont`, `text`, `textSize`, `textAlign`, `textWidth`, `createTextImage`, `textImage` ## math