Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save migurski/24ae6088b6667d3cacdb2563ff58a914 to your computer and use it in GitHub Desktop.
Save migurski/24ae6088b6667d3cacdb2563ff58a914 to your computer and use it in GitHub Desktop.
d-parser.py
import re
import cairo
import bezier
import numpy
import itertools
# https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path
paths = [
'''M500.04,309.630308 C817.696558,309.630308 931.823304,522.666719 936.58,532.180112 L936.58,549.295931 C931.824662,557.855539 817.696558,770.894667 500.04,770.894667 C182.383442,770.894667 68.2566964,557.858256 63.5,548.344863 L63.5,531.229044 C68.2553377,522.669436 182.383442,309.630308 500.04,309.630308 Z M520.015815,422.809043 L520.015815,422.806648 C524.766058,399.02996 514.304315,374.305261 494.342086,360.983862 L494.342086,360.035189 C475.315641,360.991352 456.295139,367.645088 440.12784,378.107171 C424.909061,388.570612 412.543655,402.840022 403.985575,419.955841 C407.793242,444.686993 425.863525,464.656354 450.589583,469.413051 C482.924181,476.067127 513.355115,455.143641 520.015815,422.809043 Z M357.379869,438.976342 L357.373076,438.975833 C364.033945,404.737401 383.053598,375.254308 409.690282,354.330822 C375.451851,359.086159 344.064924,367.644748 316.487362,377.158141 C303.173265,404.735703 295.563876,436.12263 295.563876,467.507859 C295.563876,580.681499 386.864661,671.987379 500.043397,671.987379 C613.217037,671.987379 704.522917,580.686594 704.522917,467.507859 C704.522917,436.12263 696.914037,404.735703 683.599432,377.158141 C656.015076,367.645428 625.584312,359.087518 591.34588,354.330822 C602.755294,363.8381 612.269196,374.299504 620.827276,386.66542 C642.700131,418.052347 650.30952,457.047814 642.700131,495.087119 C635.098384,533.126424 613.218735,565.467815 580.884137,587.34067 C556.151286,603.508649 528.573724,612.066728 500.04,612.066728 C490.525928,612.066728 481.019668,611.118038 471.506276,609.214035 C433.466971,601.612288 401.125579,578.784969 379.252724,547.398041 C357.379869,516.011114 349.77048,477.015647 357.379869,438.976342 Z M102.493769,539.787803 L102.491901,539.784406 C119.611117,568.318131 181.42711,653.917606 309.824624,700.516518 C242.302226,644.403534 198.549722,560.711289 198.549722,466.553904 C198.549722,457.048324 199.505053,446.585901 200.453725,437.072509 C144.342439,477.97181 113.904542,521.715821 102.493769,539.787803 Z M691.204575,700.519915 L691.202707,700.523312 C818.654249,653.924399 880.470242,568.324924 898.53543,539.7912 C887.124318,520.771547 856.68676,477.968413 800.575474,437.075905 C801.530804,446.581486 802.479477,457.043908 802.479477,466.557301 C802.479477,560.712987 758.733767,645.357998 691.204575,700.519915 Z M500.04,267.783336 L500.036603,267.783336 C304.11669,267.783336 182.383442,338.164032 114.85425,397.135315 L90.1281927,368.60159 C162.409326,304.873272 291.754511,229.742333 500.038302,229.742333 C708.322093,229.742333 837.668976,304.873272 909.948411,368.594797 L885.222353,397.128521 C817.696558,338.164032 695.959913,267.783336 500.04,267.783336 Z''',
'''M958 135l60 328h-196v126h220l46 230h-208v125h231l63 333h134l-63 -333h205l63 333h129l-63 -333h198v-125h-222l-45 -230h214v-126h-238l-64 -328h-132l63 328h-202l-62 -328h-131zM1175 589h203l45 230h-203z"''',
'''M1449 320l-156 310l-136 -309l-199 100l218 290l-332 26l33 209l351 -102l-40 357h221l-42 -357l361 102l28 -212l-336 -23l220 -291z"''',
'''M1298 177q210 0 299 156t89 432q0 186 -42.5 317.5t-128.5 201t-217 69.5q-140 0 -224.5 -70t-122.5 -201.5t-38 -316.5q0 -276 94 -432t291 -156zM1297 322q-117 0 -164 110.5t-47 332.5q0 148 20 246.5t66.5 147.5t124.5 49q77 0 123.5 -49t67.5 -147.5t21 -246.5
q0 -223 -48.5 -333t-163.5 -110z"''',
'''M1364 194h172v1143h-144l-328 -258l88 -112l124 101q30 24 50.5 42.5t44.5 44.5q-3 -48 -5 -98.5t-2 -109.5v-753z"''',
'''M915 194h770v153h-551v8l208 203q91 89 159 165.5t105 154t37 168.5q0 139 -94 222.5t-256 83.5q-83 0 -149.5 -19.5t-120.5 -52t-100 -72.5l94 -114q66 53 129 82t141 29q81 0 130.5 -44t49.5 -129q0 -70 -28 -129.5t-85 -124.5t-143 -152l-296 -298v-134z"''',
'''M1237 178q231 0 338 97t107 247q0 113 -68.5 182t-205.5 86v6q106 22 173 91.5t67 185.5q0 124 -93 201.5t-271 77.5q-118 0 -208 -34t-154 -82l85 -119q56 36 120 63.5t153 27.5q93 0 143 -41.5t50 -117.5q0 -58 -28.5 -102t-89.5 -68.5t-159 -24.5h-104v-142h103
q154 0 229.5 -44.5t75.5 -139.5q0 -98 -62.5 -152.5t-208.5 -54.5q-74 0 -156.5 19.5t-154.5 55.5v-156q71 -33 149 -47.5t170 -14.5z"''',
'''M1401 194h169v252h157v147h-157v743h-171l-526 -754v-136h528v-252zM1036 593l298 427q19 27 37.5 60.5t31.5 64.5h6q-1 -28 -3 -68.5t-3.5 -87t-1.5 -95.5v-301h-365z"''',
'''M1231 179q210 0 323.5 103t113.5 283q0 164 -104 252t-272 88q-55 0 -97 -6t-69 -11l25 294h438v154h-588l-44 -553l79 -47q34 9 88 17t100 8q138 0 202.5 -55t64.5 -158q0 -115 -71 -169.5t-190 -54.5q-75 0 -157.5 21t-141.5 54v-158q55 -31 133 -46.5t167 -15.5z"''',
'''M1311 323q-55 0 -96 24t-69 63t-42 86.5t-14 95.5q0 47 28 91t79 73t118 29q100 0 150 -58.5t50 -159.5q0 -125 -56.5 -184.5t-147.5 -59.5zM1313 180q171 0 271.5 104t100.5 284q0 169 -90 260.5t-239 91.5q-101 0 -165 -38.5t-99 -94.5h-9q6 118 39 215t113.5 154.5
t226.5 57.5q36 0 72.5 -4.5t65.5 -13.5v144q-28 7 -70 10t-75 3q-167 0 -273 -57.5t-164 -154.5t-80.5 -216t-22.5 -242q0 -128 30.5 -223t85 -157t127 -92.5t155.5 -30.5z"''',
'''M1051 194h188l453 1019v123h-785v-153h599z"''',
'''M1299 313q-111 0 -165 50.5t-54 126.5q0 53 23.5 94.5t68.5 75t108 60.5l23 -9q94 -37 155 -89.5t61 -129.5q0 -79 -56.5 -129t-163.5 -50zM1302 179q116 0 202 38t133.5 108t47.5 166q0 77 -34.5 133.5t-91 99t-124.5 75.5q89 46 151.5 111.5t62.5 168.5q0 90 -46 150.5
t-125 92t-179 31.5q-96 0 -175.5 -31.5t-126.5 -92t-47 -149.5q0 -69 26 -122t70 -93.5t99 -72.5q-93 -43 -162 -116.5t-69 -189.5q0 -145 100.5 -226t287.5 -81zM1303 869q-77 35 -131 79t-54 122q0 72 50.5 110.5t129.5 38.5q81 0 132 -38.5t51 -110.5q0 -78 -52 -123.5
t-126 -77.5z"''',
'''M2244 -89q-32 0 -54 25.5t-22 65.5q0 53 39 109q-47 -4 -86.5 -7t-73.5 -3q-107 0 -200 54t-163 146.5t-109 210t-39 245.5q0 135 34 213.5t106 78.5q54 0 100.5 -38t82 -101t55 -139t19.5 -152q0 -75 -23 -133q28 -93 68.5 -147.5t107 -77.5t170.5 -23q78 0 107.5 -17
t29.5 -56q0 -15 -3 -31.5t-11 -36.5l-33 -86q-19 -48 -44 -74t-58 -26zM356 -143q-32 0 -57.5 26t-43.5 73l-33 87q-7 20 -11 36.5t-4 31.5q0 39 29.5 59t105.5 36q132 28 185.5 53t53.5 55q0 26 -28.5 72.5t-57 112.5t-28.5 150q0 97 33.5 188.5t90 151t124.5 59.5
q51 0 84.5 -32.5t33.5 -80.5q0 -26 -12.5 -61.5t-25 -76.5t-12.5 -85q0 -74 8 -122.5t19 -84.5t19 -71.5t8 -83.5q0 -76 -39.5 -124.5t-135.5 -87t-264 -85.5q17 -30 25.5 -55.5t8.5 -49.5q0 -40 -21.5 -65.5t-54.5 -25.5zM967 -143q-113 0 -113 69q0 22 4.5 68t11 100
t11 98t4.5 60q0 32 -58 65.5t-176 77.5l120 176q120 -57 185.5 -99t91 -74.5t25.5 -67.5q0 -38 -8.5 -94.5t-22 -113t-27.5 -98.5q15 4 27.5 5.5t26.5 1.5q55 0 90.5 -23.5t35.5 -63.5t-36 -63.5t-96 -23.5h-96zM1046 553q-96 0 -176 47t-127 125t-47 173l112 54
q17 -84 43.5 -130.5t71 -67.5t116.5 -29q57 -5 78 -31.5t21 -59.5q0 -35 -29 -58t-63 -23zM1407 -143q-60 0 -96 23.5t-36 63.5t36 63.5t90 23.5q23 0 59 -8q-51 73 -87 148t-36 129q0 35 22.5 68t82.5 72.5t169 91.5l120 -177q-196 -71 -196 -133q0 -20 12 -59.5
t28.5 -85.5t28.5 -87t12 -64q0 -69 -113 -69h-96zM1571 817q-105 31 -201.5 45t-192.5 14q-201 0 -404 -58l-64 146q248 44 467 44q114 0 227 -7.5t217 -35.5zM847 985q-76 0 -139.5 38t-101 101.5t-37.5 140.5t37.5 140t101 100.5t139.5 37.5q77 0 140.5 -37.5
t101.5 -100.5t38 -140t-38 -140.5t-101.5 -101.5t-140.5 -38zM1160 860q-40 0 -68 28t-28 66q0 39 28 67t68 28q39 0 66.5 -28t27.5 -67q0 -38 -27.5 -66t-66.5 -28zM1296 587q-47 0 -74 26.5t-27 64.5t27 59.5t74 21.5q105 0 167 8.5t83 43.5l192 -34q-21 -84 -81 -125
t-151.5 -53t-209.5 -12zM1244 862q-43 0 -73.5 23t-30.5 55q0 33 30.5 56.5t73.5 23.5q41 0 71 -23.5t30 -56.5q0 -32 -29.5 -55t-71.5 -23zM1553 985q-77 0 -140.5 38t-101 101.5t-37.5 140.5t37.5 140t101 100.5t140.5 37.5t140 -37.5t101 -100.5t38 -140t-38 -140.5
t-101 -101.5t-140 -38z''',
'''M573 -343q-165 0 -242 145l76 40q29 -52 68.5 -75.5t97.5 -23.5q59 0 106.5 18.5t94 42.5t102.5 42.5t132 18.5q80 0 133 -18.5t94.5 -42.5t87 -42.5t109.5 -18.5q69 0 124 22t106.5 50.5t111 50t137.5 21.5q71 0 123 -19.5t95 -39t88 -19.5q40 0 85 22l38 -78
q-66 -30 -123 -30q-64 0 -109 19.5t-89.5 39t-107.5 19.5q-68 0 -121 -21.5t-103.5 -50t-111 -50.5t-143.5 -22t-135 18.5t-92 42.5t-84.5 42.5t-112.5 18.5t-117 -18.5t-93.5 -42.5t-97 -42.5t-127.5 -18.5zM540 73q-106 0 -191.5 49t-135.5 136l78 40q78 -138 249 -138
q60 0 106 18.5t92.5 42.5t105 42.5t141.5 18.5q89 0 145 -18.5t96 -42.5t81 -42.5t101 -18.5q65 0 115 22t99.5 50.5t112 50t152.5 21.5q93 0 162.5 -26t125.5 -52t105 -26q34 0 68 16l39 -78q-51 -25 -107 -25q-65 0 -124.5 26t-123.5 52t-145 26q-79 0 -135 -21.5
t-105 -50t-105 -50.5t-134 -22q-73 0 -121.5 18.5t-89.5 42.5t-89.5 42.5t-122.5 18.5q-73 0 -125.5 -18.5t-98.5 -42.5t-97.5 -42.5t-123.5 -18.5zM585 1264l-11 52q83 6 142 36.5t104 89.5l42 -32q-51 -68 -120 -103.5t-157 -42.5zM653 1180l-37 51q108 5 177 46.5
t112 127.5l48 -24q-89 -179 -300 -201zM639 1296q-60 96 -60 185q0 35 8.5 72.5t24.5 77.5l54 22q-21 -46 -27.5 -86.5t-6.5 -85.5q0 -73 51 -156zM728 1119l-13 52q117 16 178.5 53t103.5 119l48 -26q-48 -92 -120.5 -136.5t-196.5 -61.5zM739 1344q-65 96 -65 197
q0 38 10 78t30 85l48 -15q-18 -46 -26 -81t-8 -67q0 -86 55 -166zM831 1100q-88 0 -161 43.5t-117 116.5t-44 162q0 88 44 161t117 116.5t161 43.5q89 0 161.5 -43.5t116.5 -116.5t44 -161q0 -89 -44 -162t-116.5 -116.5t-161.5 -43.5zM831 1153q73 0 134.5 37t97.5 98
t36 134t-36 134t-97.5 97.5t-134.5 36.5t-134 -36.5t-97.5 -97.5t-36.5 -134t36.5 -134t97.5 -98t134 -37zM1049 1260q-47 69 -101.5 104t-124.5 45l7 53q80 -10 144.5 -52.5t118.5 -119.5zM806 1415q-12 37 -20.5 70.5t-8.5 66.5q0 41 11 82.5t34 85.5l47 -24
q-20 -39 -29 -73.5t-9 -69.5q0 -28 6 -57.5t19 -58.5zM1099 1357q-56 77 -117 110.5t-141 33.5h-12h-13l-3 53h14.5h14.5q177 0 294 -159zM1111 1456q-66 85 -126 115.5t-144 30.5h-9h-11v54h11h10q90 0 156.5 -30.5t131.5 -108.5zM1758 -48l-35 25q-30 22 -35 59t14 71l4 7
q13 23 39 47t48 52t22 61q0 39 -33.5 69.5t-82.5 30.5q-44 0 -82 -26.5t-62 -75.5l-86 -175q-60 0 -130.5 22t-146.5 50.5t-153 50.5t-150 22q35 49 50 89.5t15 82.5q0 71 -34 108t-84.5 55.5t-101 34.5t-84.5 43.5t-34 84.5q0 56 29 109.5t57.5 101.5t28.5 86
q0 30 -13 54.5t-16 48.5q87 0 144 5t95 17t67 32q-6 -38 -29 -75t-52 -79.5t-51.5 -95t-26.5 -121.5q65 -13 146 -33t184.5 -47t233.5 -64q189 0 332.5 -55t224.5 -145.5t81 -198.5q0 -35 -12.5 -75t-47 -94t-98.5 -129l-6 -7q-25 -29 -62 -37t-67 14zM1448 660
q-86 0 -157.5 42t-113.5 113.5t-42 158.5q0 86 42 156.5t113.5 113t157.5 42.5q87 0 157.5 -42.5t112.5 -113t42 -156.5q0 -87 -42 -158.5t-112.5 -113.5t-157.5 -42z''',
'''M1961 -159q-32 0 -61.5 18t-44.5 48q-25 -27 -76.5 -44t-112.5 -17q-104 0 -213.5 106.5t-183.5 325.5h-129q-20 71 -41 158.5t-36 182t-20 183.5q-107 -50 -167 -106.5t-95 -105.5t-65.5 -80t-79.5 -31q-48 0 -73.5 29t-25.5 80q0 110 126.5 221t375.5 226
q-82 42 -128.5 115.5t-46.5 163.5q0 86 41.5 155.5t111.5 111t155 41.5q86 0 155.5 -41.5t111 -111t41.5 -155.5q0 -52 -20 -108t-67 -132q40 35 78.5 51.5t79.5 28.5q94 27 146.5 63t87.5 103q40 78 77.5 108.5t84.5 30.5q50 0 83 -30.5t33 -94.5t-37 -116t-95.5 -95
t-123.5 -80t-123.5 -71.5t-95.5 -69t-37 -73.5q0 -27 18 -64t41.5 -91.5t41.5 -132.5t18 -186q0 -129 16 -198t67 -69q31 0 51.5 18.5t43 36.5t60.5 18q66 0 108 -57.5t42 -135.5q0 -60 -27 -93.5t-70 -33.5zM904 -343q-75 0 -112 21.5t-37 69.5q0 39 20.5 73t67.5 71
q16 13 22.5 35.5t6.5 52.5v203q0 110 76.5 181.5t265.5 126.5l187 -351q-76 26 -111.5 34.5t-57.5 8.5q-139 0 -139 -159q0 -59 6.5 -116.5t6.5 -109.5q0 -68 -49.5 -104.5t-152.5 -36.5zM1811 1243q-68 0 -125.5 34t-91 91t-33.5 125q0 70 33.5 126.5t91 90t125.5 33.5
q69 0 125.5 -33.5t90 -90t33.5 -126.5q0 -68 -33.5 -125t-90 -91t-125.5 -34zM1811 1323q70 0 119.5 50t49.5 120q0 71 -49.5 120.5t-119.5 49.5t-120 -50t-50 -120t50.5 -120t119.5 -50z''',
'''M677 261q-115 0 -207 55.5t-145 153.5t-53 224q0 154 66 265.5t186 172t282 60.5h690q163 0 282.5 -60.5t185 -172t65.5 -265.5q0 -126 -53 -224t-144 -153.5t-207 -55.5t-183 30t-104 73.5t-63 85.5q-33 54 -58.5 77.5t-65.5 23.5t-65.5 -23.5t-58.5 -76.5
q-26 -43 -63 -87t-104 -73.5t-183 -29.5zM1069 -343q-72 0 -72 77v179h76v-167q0 -9 3 -12.5t11 -3.5h130q8 0 11 3.5t3 12.5v167h76v-179q0 -77 -72 -77h-166zM1151 -134q-132 0 -210 68.5t-81 198.5h584q-3 -130 -81.5 -198.5t-211.5 -68.5zM1151 -69q81 0 138.5 33
t73.5 104h-422q15 -71 71.5 -104t138.5 -33zM1151 210q-102 0 -192 24.5t-146 70.5l56 62q45 -35 120 -54.5t162 -19.5t162.5 19.5t119.5 54.5l56 -62q-55 -46 -145.5 -70.5t-192.5 -24.5zM677 344q88 0 139.5 22t82 57.5t55.5 75.5q43 69 85.5 102t111.5 33q68 0 110.5 -33
t85.5 -101q26 -40 56.5 -76t82.5 -58t139 -22q93 0 165 44.5t114 123.5t42 182q0 197 -120 306t-330 109h-690q-209 0 -330 -109t-121 -306q0 -103 42 -182t115 -123.5t165 -44.5zM687 435q-100 0 -164.5 74.5t-64.5 185.5q0 155 93 238.5t264 83.5h672q171 0 264 -83.5
t93 -238.5q0 -111 -64.5 -185.5t-164.5 -74.5q-87 0 -141 50t-104 114q-39 50 -69 77.5t-63.5 38t-86.5 10.5q-56 0 -91 -12.5t-62.5 -40t-64.5 -73.5q-50 -64 -104 -114t-142 -50zM687 509q58 0 96 35t86 96q36 48 71.5 83.5t84.5 55.5t126 20q72 0 119.5 -17t85 -52
t78.5 -90q47 -62 85 -96.5t96 -34.5q69 0 112 52.5t43 133.5q0 248 -283 248h-672q-283 0 -283 -248q0 -81 43 -133.5t112 -52.5zM1276 -299v83h371q163 0 286 69.5t192.5 193.5t69.5 288v238h83v-238q0 -187 -80 -330t-222.5 -223.5t-328.5 -80.5h-371zM1279 -119l13 83
h353q170 0 268.5 100t98.5 271v238h84v-238q0 -137 -56 -239t-157 -158.5t-238 -56.5h-366zM2078 528q-114 0 -114 114v106q0 115 114 115h135q115 0 115 -115v-106q0 -114 -115 -114h-135zM2084 611h123q24 0 31 7.5t7 31.5v90q0 25 -7 32.5t-31 7.5h-123q-23 0 -30 -7.5
t-7 -32.5v-90q0 -24 7 -31.5t30 -7.5zM2012 817v554h84v-554h-84zM2195 817v554h83v-554h-83zM2078 1317q-114 0 -114 114v197q0 115 114 115h135q115 0 115 -115v-197q0 -114 -115 -114h-135zM2084 1400h123q24 0 31 7.5t7 31.5v181q0 25 -7 32.5t-31 7.5h-123
q-23 0 -30 -7.5t-7 -32.5v-181q0 -24 7 -31.5t30 -7.5z''',
'''M1650 -43q-107 0 -231.5 26.5t-276.5 81.5q-180 66 -317.5 140.5t-239.5 172.5t-178 233.5t-135 323.5q-9 29 6 52t43 27l516 76q41 6 85.5 10.5t85.5 6.5q56 164 174.5 250t282.5 86q135 0 243 -64t171 -172t63 -240q0 -45 -14 -101t-25 -83q31 -28 60.5 -58.5
t57.5 -66.5l294 -364q19 -24 16 -50.5t-28 -43.5q-185 -123 -349 -183t-304 -60zM858 409q-29 0 -50.5 21.5t-21.5 50.5q0 30 21.5 51t50.5 21q30 0 51 -21t21 -51q0 -29 -21 -50.5t-51 -21.5zM1198 259q-29 0 -50.5 21.5t-21.5 50.5q0 30 21.5 51t50.5 21q30 0 51 -21
t21 -51q0 -29 -21 -50.5t-51 -21.5zM1578 138q-29 0 -50.5 21.5t-21.5 50.5q0 30 21 51t51 21t51 -21t21 -51q0 -29 -21 -50.5t-51 -21.5zM2266 225q-182 0 -437.5 61t-551.5 167q-213 77 -399.5 157.5t-331 162t-233.5 158.5l49 76q91 -81 242 -164.5t334 -161t369 -144.5
q280 -99 534 -160.5t438 -61.5zM1644 48q123 0 266.5 53t309.5 160l-270 338q-36 44 -73.5 81t-80.5 70l23 59q15 40 23.5 79t8.5 77q0 108 -52 196.5t-140 141t-195 52.5q-138 0 -242.5 -78.5t-135.5 -212.5l-12 -50q-58 0 -111 -4t-111 -12l-477 -71q52 -160 120 -279
t161 -208t219.5 -158.5t297.5 -131.5q144 -52 258.5 -77t212.5 -25zM1852 756q-24 -11 -57.5 -16t-73.5 -5q-87 0 -186.5 23t-196.5 64.5t-176 97t-125 121.5l13 49q20 5 43.5 8t34.5 3q94 0 207 -28.5t221 -74t189.5 -97t111.5 -98.5zM1494 941l-69 25l45 127q7 19 -2.5 34
t-17.5 34.5t3 49.5q11 32 45.5 45.5t70.5 -0.5q37 -13 55 -45t5 -65q-11 -29 -29.5 -39t-36 -15.5t-24.5 -25.5z''',
'''M741 123q-137 0 -254.5 34t-205 92t-136.5 132t-49 152q0 82 56.5 135.5t140.5 53.5q55 0 101 7t70 18l1141 548q18 9 40 27t48 42q100 91 208.5 135t212.5 44q118 0 205.5 -49.5t136 -135.5t48.5 -195q0 -73 -22 -144.5t-63 -126.5t-95 -81l-1278 -616
q-71 -34 -145.5 -53t-159.5 -19zM577 65q-54 0 -115.5 45.5t-81.5 113.5l371 -62q-27 -44 -73 -70.5t-101 -26.5zM883 93l-83 50l107 34zM1073 -143q-85 0 -145 60.5t-60 145.5t60 145t145 60q86 0 145.5 -60t59.5 -145t-59.5 -145.5t-145.5 -60.5zM1131 -31q26 0 45 19.5
t19 45.5t-19 45t-45 19t-45.5 -19t-19.5 -45q0 -27 19 -46t46 -19zM638 530q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5zM815 426q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5z
M821 614q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5zM993 510q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5zM726 219q79 0 139.5 15t124.5 45l1283 619q40 19 70 62t47 98.5
t17 111.5q0 130 -81.5 206.5t-211.5 76.5q-88 0 -182.5 -39.5t-175.5 -114.5q-35 -32 -61.5 -52.5t-49.5 -31.5l-1142 -549q-33 -16 -87 -25t-117 -9q-48 0 -80.5 -25t-32.5 -69q0 -56 44 -112.5t120.5 -103.5t173.5 -75t202 -28zM1608 1010q-20 0 -34 12t-14 29q0 32 41 32
q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5zM1785 906q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5zM2164 406q-86 0 -146 60t-60 146q0 85 60 145t146 60q85 0 145.5 -60t60.5 -145q0 -86 -60.5 -146t-145.5 -60z
M2221 518q26 0 45 19.5t19 45.5t-19 45t-45 19t-45.5 -19t-19.5 -45q0 -27 19 -46t46 -19zM1791 1094q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5q0 -14 -12 -24.5t-29 -10.5zM1963 990q-20 0 -34 12t-14 29q0 32 41 32q19 0 33.5 -11.5t14.5 -26.5
q0 -14 -12 -24.5t-29 -10.5z''',
'''M1653 -9q2 27 5.5 54t9.5 54l-1050 5l-185 106q-91 0 -168.5 -18.5t-157.5 -53.5q0 71 22 142.5t92 114.5q-25 13 -44 46.5t-19 88.5q0 65 31 102t78 37q50 0 93 -26t70 -59.5t27 -58.5q0 -21 -17 -43.5t-40.5 -40.5t-41.5 -26q45 0 91 -10t86 -31l46 42
q-49 72 -77.5 171.5t-28.5 199.5q0 162 33.5 305.5t109.5 312.5l-182 168q-35 32 -52 58t-17 49q0 32 25.5 47.5t71.5 15.5h485q44 0 85 -81h1063q89 0 159.5 -40.5t114.5 -109t53 -151.5l67 -577q7 -59 -17 -101v-692h-159l-192 196h-170l-172 -196h-128zM477 -343
q-81 0 -148 39.5t-106.5 105.5t-39.5 147q0 82 39.5 148.5t106.5 106t148 39.5t147 -39.5t105.5 -106t39.5 -148.5q0 -81 -39.5 -147t-105.5 -105.5t-147 -39.5zM477 -243q80 0 136 56.5t56 135.5q0 81 -56 137.5t-136 56.5q-81 0 -137.5 -57t-56.5 -137q0 -79 56.5 -135.5
t137.5 -56.5zM265 450q19 0 33 23t14 56q0 32 -14 55t-33 23t-33 -23t-14 -55q0 -33 14 -56t33 -23zM501 870v74h271q28 0 28 28v387h73v-391q0 -54 -21.5 -76t-54.5 -22h-296zM1072 192h162v271q0 26 4 42t13 35h-75q-15 33 -15 64q0 32 15 63h306v88h90v-563h184v363
q0 41 21 82.5t61 70t94 28.5h436q21 0 27.5 11.5t2.5 41.5l-65 558q-7 67 -43 118t-87 79.5t-106 28.5h-1115q-12 38 -31.5 60t-37.5 22h-336l17 26l279 -255v-67h-180q-47 -118 -74 -205.5t-37.5 -168.5t-10.5 -180q0 -33 3 -70h498v-543zM1482 638v657h-410v-639h-90v727
h971q26 0 43.5 -17.5t17.5 -43.5v-660h-90v602q0 31 -31 31h-321v-657h-90zM2057 -343q-81 0 -148 39.5t-106.5 105.5t-39.5 147q0 82 39.5 148.5t106.5 106t148 39.5t147 -39.5t105.5 -106t39.5 -148.5q0 -81 -39.5 -147t-105.5 -105.5t-147 -39.5zM2057 -243
q80 0 136 56.5t56 135.5q0 81 -56 137.5t-136 56.5q-81 0 -137.5 -57t-56.5 -137q0 -79 56.5 -135.5t137.5 -56.5zM1976 504h281v105h-281v-105z''',
'''M118 127q-25 0 -42 17.5t-17 42.5v122q0 29 18 39t52 10h232l49 55q25 27 62 27h314q22 0 37 -9.5t28 -26.5l151 -189h685l87 173q27 53 79 53h525q2 32 2.5 69t0.5 76q0 64 -2 129.5t-7 121.5q-2 24 -26 24l-886 2v90l904 -2q38 0 65.5 -22.5t31.5 -60.5
q9 -79 13.5 -157t4.5 -156q0 -45 -1 -90t-4 -89q67 0 67 -60v-129q0 -25 -16.5 -42.5t-42.5 -17.5h-210l-170 203h-167l-153 -203h-913l-143 201l-187 1l-154 -202h-267zM625 -143q-75 0 -137.5 37t-99.5 99.5t-37 137.5q0 76 37 138.5t99.5 99.5t137.5 37q76 0 138.5 -37
t99.5 -99.5t37 -138.5q0 -75 -37 -137.5t-99.5 -99.5t-138.5 -37zM625 -43q72 0 123.5 51.5t51.5 122.5q0 72 -51.5 123.5t-123.5 51.5t-123 -51.5t-51 -123.5q0 -71 51 -122.5t123 -51.5zM181 457v71h93q11 0 17 6t6 17v123l-33 67l-88 9l5 71l129 -13l58 -118v-164
q0 -69 -50 -69h-137zM1382 199v1236q0 20 -20 20h-362q-56 0 -105.5 -30t-74.5 -78l-240 -466h-342q-39 0 -42 -39q-3 -38 -3.5 -84.5t-0.5 -97.5q0 -71 5.5 -153.5t16.5 -159.5l-91 -7q-12 81 -18.5 160.5t-6.5 159.5q0 55 1.5 109t5.5 109q3 38 28.5 65t65.5 27h325
l216 421q37 71 107 111.5t151 40.5h414q26 0 44.5 -16.5t18.5 -43.5v-1284h-93zM724 865q-14 0 -21 11.5t0 24.5l203 390q15 29 42.5 46.5t59.5 17.5h234q17 0 29 -13t12 -30v-406q0 -17 -12.5 -29t-29.5 -12h-517zM857 947h321q22 0 22 23v280q0 23 -22 23h-160
q-28 0 -42 -28l-138 -265q-6 -11 -0.5 -22t19.5 -11zM2020 -143q-75 0 -137.5 37t-99.5 99.5t-37 137.5q0 76 36.5 138.5t99 99.5t138.5 37q75 0 137.5 -37t100 -99.5t37.5 -138.5q0 -75 -37 -137.5t-99.5 -99.5t-138.5 -37zM2020 -43q72 0 123.5 51.5t51.5 122.5
q0 72 -51.5 123.5t-123.5 51.5q-71 0 -122.5 -51.5t-51.5 -123.5q0 -71 51.5 -122.5t122.5 -51.5zM2331 518q-17 0 -29 12t-12 29v172q0 17 12 28t29 11h82v-252h-82z''',
]
num = r'-?\d+(?:\.\d+(?:e-?\d+)?)?' # Any kind of integer or float
br = r'[,\s]+' # comma or space between numbers
breaker = re.compile(br)
command_pat = re.compile(
rf'''
(
( [Zz] )
|
( [HhVv] (\s*{num})+ )
|
( [MmLlTt] (\s*{num}{br}{num})+ )
|
( [SsQq] (\s*{num}{br}{num}{br}{num}{br}{num})+ )
|
( [Cc] (\s*{num}{br}{num}{br}{num}{br}{num}{br}{num}{br}{num})+ )
|
( [Aa] (\s*{num}{br}{num}{br}{num}{br}{num}{br}{num}{br}{num}{br}{num})+ )
)
''',
re.VERBOSE,
)
width, height = 8.5*72, 11*72
positions = itertools.product(
range(int(.5*72), int(height), int(1*72)),
range(int(.5*72), int(width), int(1*72)),
)
scale = .025
with cairo.SVGSurface('d-parsed.svg', width, height) as surface:
context = cairo.Context(surface)
context.set_line_width(.5)
for path in paths:
offy, offx = next(positions)
context.translate(offx, offy)
context.move_to(0, 0)
context.line_to(4, 0)
context.line_to(0, 4)
context.line_to(0, 0)
context.set_source_rgb(0, .6, 1)
context.fill()
context.translate(0, 72)
context.scale(scale, -scale)
print(path)
letters = re.findall('[a-zA-Z]', path)
matches = [
m[0]
for m in command_pat.findall(path)
]
assert len(letters) == len(matches), f'{len(letters)} != {len(matches)}'
start_point, prev_command = None, None
for curr_match in matches:
command, xys = curr_match[0], [float(a) for a in breaker.split(curr_match[1:]) if a]
print(command, xys)
if command == 'M':
context.move_to(xys[0], xys[1])
start_point = context.get_current_point()
if len(xys) > 2:
raise NotImplementedError('M: Any subsequent coordinate pair(s) are interpreted as parameter(s) for implicit absolute LineTo (L) command(s)')
elif command == 'm':
context.rel_move_to(xys[0], xys[1])
start_point = context.get_current_point()
if len(xys) > 2:
raise NotImplementedError('m: Any subsequent coordinate pair(s) are interpreted as parameter(s) for implicit relative LineTo (l) command(s)')
elif command == 'L':
context.line_to(xys[0], xys[1])
if len(xys) > 2:
raise NotImplementedError('L: Any subsequent coordinate pair(s) are interpreted as parameter(s) for implicit absolute LineTo (L) command(s)')
elif command == 'l':
context.rel_line_to(xys[0], xys[1])
if len(xys) > 2:
raise NotImplementedError('l: Any subsequent coordinate pair(s) are interpreted as parameter(s) for implicit relative LineTo (l) command(s)')
elif command == 'H':
_, y = context.get_current_point()
context.line_to(xys[0], y)
if len(xys) > 1:
raise NotImplementedError('H: Any subsequent value(s) are interpreted as parameter(s) for implicit absolute horizontal LineTo (H) command(s)')
elif command == 'h':
context.rel_line_to(xys[0], 0)
if len(xys) > 1:
raise NotImplementedError('h: Any subsequent value(s) are interpreted as parameter(s) for implicit relative horizontal LineTo (h) command(s)')
elif command == 'V':
x, _ = context.get_current_point()
context.line_to(x, xys[0])
if len(xys) > 1:
raise NotImplementedError('V: Any subsequent values are interpreted as parameters for implicit absolute vertical LineTo (V) command(s)')
elif command == 'v':
context.rel_line_to(0, xys[0])
if len(xys) > 1:
raise NotImplementedError('v: Any subsequent value(s) are interpreted as parameter(s) for implicit relative vertical LineTo (v) command(s)')
elif command == 'C':
x, y = context.get_current_point()
nodes = numpy.array([
(x, y),
(xys[0], xys[1]),
(xys[2], xys[3]),
(xys[4], xys[5]),
])
curve = bezier.Curve.from_nodes(nodes.transpose())
range = numpy.linspace(0, 1, int(curve.length / 10) + 2)
points = curve.evaluate_multi(range).transpose()
for (x, y) in points[1:]:
context.line_to(x, y)
if len(xys) > 6:
raise NotImplementedError('C: Any subsequent triplet(s) of coordinate pairs are interpreted as parameter(s) for implicit absolute cubic Bézier curve (C) command(s)')
elif command in ('q', 't'):
if command == 't':
if prev_command[0] != 'q':
raise NotImplementedError("t: If the previous command wasn't a quadratic Bézier curve, the control point is the same as the curve starting point (current point)")
command = 'q'
xys = [
# The control point is a reflection of the
# control point of the previous curve command.
prev_command[1][-2] - prev_command[1][-4],
prev_command[1][-1] - prev_command[1][-3],
xys[0],
xys[1],
]
x, y = context.get_current_point()
nodes = numpy.array([
(x, y),
(x + xys[0], y + xys[1]),
(x + xys[2], y + xys[3]),
])
curve = bezier.Curve.from_nodes(nodes.transpose())
range = numpy.linspace(0, 1, int(curve.length / 10) + 2)
points = curve.evaluate_multi(range).transpose()
for (x, y) in points[1:]:
context.line_to(x, y)
if len(xys) > 4:
raise NotImplementedError('q: Any subsequent pair(s) of coordinate pairs are interpreted as parameter(s) for implicit relative quadratic Bézier curve (q) command(s)')
elif command in ('Z', 'z'):
context.line_to(*start_point)
else:
raise NotImplementedError(f"{command}: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path")
prev_command = command, xys
context.set_line_width(.5 / scale)
context.set_source_rgb(0, 0, 0)
context.set_fill_rule(cairo.FillRule.WINDING)
context.fill()
print('')
context.scale(1/scale, -1/scale)
context.translate(0, -72)
context.translate(-offx, -offy)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment