Fix badge rendering without GD

This commit is contained in:
Anton Komarev
2023-10-11 18:55:24 +03:00
parent 8c49635ac2
commit 85c0193d72
5 changed files with 358 additions and 4 deletions

View File

@@ -27,10 +27,10 @@ final class BadgeImageRendererService
public function __construct()
{
$this->poser = new Poser([
new SvgPlasticRender(),
new SvgFlatRender(),
new SvgFlatSquareRender(),
new SvgForTheBadgeRenderer(),
new SvgPlasticRender(new SvgTextSizeCalculator()),
new SvgFlatRender(new SvgTextSizeCalculator()),
new SvgFlatSquareRender(new SvgTextSizeCalculator()),
new SvgForTheBadgeRenderer(null, new SvgTextSizeCalculator()),
]);
}

146
src/DejaVuSans-webfont.svg Normal file
View File

@@ -0,0 +1,146 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>
This is a custom SVG webfont generated by Font Squirrel.
Copyright : Copyright c 2003 by Bitstream Inc All Rights ReservedCopyright c 2006 by Tavmjong Bah All Rights ReservedDejaVu changes are in public domain
Foundry : DejaVu fonts team
Foundry URL : httpdejavusourceforgenet
</metadata>
<defs>
<font id="DejaVuSansBook" horiz-adv-x="1303" >
<font-face units-per-em="2048" ascent="1556" descent="-492" />
<missing-glyph horiz-adv-x="651" />
<glyph unicode=" " horiz-adv-x="651" />
<glyph unicode="&#x09;" horiz-adv-x="651" />
<glyph unicode="&#xa0;" horiz-adv-x="651" />
<glyph unicode="!" horiz-adv-x="821" d="M309 0v254h203v-254h-203zM309 838v655h203v-655l-20 -357h-162z" />
<glyph unicode="&#x22;" horiz-adv-x="942" d="M197 938v555h170v-555h-170zM575 938v555h170v-555h-170z" />
<glyph unicode="#" horiz-adv-x="1716" d="M158 414v153h352l84 334h-322v154h361l102 415h162l-104 -415h292l105 415h160l-103 -415h312v-154h-351l-82 -334h318v-153h-357l-104 -414h-160l103 414h-293l-103 -414h-161l104 414h-315zM672 567h293l82 334h-291z" />
<glyph unicode="$" d="M170 92v180q102 -64 206.5 -96.5t215.5 -33.5v456q-221 36 -321.5 122t-100.5 236q0 163 109 257t313 108v235h100v-232q93 -4 180 -19.5t170 -42.5v-175q-83 42 -170.5 65t-179.5 27v-427q227 -35 334 -125t107 -246q0 -169 -113.5 -266.5t-327.5 -112.5v-303h-100 l-1 301q-105 2 -210 24.5t-211 67.5zM354 973q0 -86 56.5 -134t181.5 -69v410q-116 -13 -177 -66t-61 -141zM692 145q127 17 191.5 72t64.5 145q0 88 -61.5 140t-194.5 76v-433z" />
<glyph unicode="%" horiz-adv-x="1946" d="M113 1114q0 186 93 296t251 110t252 -109.5t94 -296.5q0 -189 -93.5 -298t-252.5 -109t-251.5 109.5t-92.5 297.5zM272 1114q0 -132 49 -206t136 -74t136.5 74t49.5 206q0 129 -50 204t-136 75t-135.5 -74.5t-49.5 -204.5zM426 -29l934 1549h160l-934 -1549h-160z M1143 377q0 188 93.5 297.5t252.5 109.5q158 0 251 -110t93 -297t-93.5 -296.5t-250.5 -109.5q-160 0 -253 109.5t-93 296.5zM1303 377q0 -130 49.5 -204.5t136.5 -74.5q85 0 134.5 74.5t49.5 204.5q0 131 -49.5 205.5t-134.5 74.5q-87 0 -136.5 -74t-49.5 -206z" />
<glyph unicode="&#x26;" horiz-adv-x="1597" d="M129 461q0 128 67 240.5t201 211.5q-48 63 -73 125.5t-25 122.5q0 162 111 260.5t295 98.5q83 0 165.5 -18t167.5 -54v-182q-87 47 -166 71.5t-147 24.5q-105 0 -170.5 -55.5t-65.5 -143.5q0 -51 29.5 -102.5t120.5 -145.5l508 -520q59 89 92 190.5t39 215.5h186 q-12 -132 -64 -261t-145 -255l279 -285h-252l-143 147q-104 -89 -218 -132.5t-245 -43.5q-241 0 -394 137.5t-153 352.5zM322 473q0 -146 106 -243t266 -97q95 0 178 31.5t156 95.5l-530 543q-91 -81 -133.5 -161.5t-42.5 -168.5z" />
<glyph unicode="'" horiz-adv-x="563" d="M197 938v555h170v-555h-170z" />
<glyph unicode="(" horiz-adv-x="799" d="M176 643q0 223 74 449t225 462h160q-134 -230 -199 -455t-65 -456t65.5 -457.5t198.5 -455.5h-160q-150 235 -224.5 462t-74.5 451z" />
<glyph unicode=")" horiz-adv-x="799" d="M164 -270q133 229 198.5 455.5t65.5 457.5t-65.5 456t-198.5 455h160q150 -236 224.5 -462t74.5 -449q0 -224 -74.5 -451t-224.5 -462h-160z" />
<glyph unicode="*" horiz-adv-x="1024" d="M61 858l359 195l-359 194l58 99l336 -203v377h114v-377l336 203l58 -99l-359 -194l359 -195l-58 -98l-336 203v-377h-114v377l-336 -203z" />
<glyph unicode="+" horiz-adv-x="1716" d="M217 557v170h557v557h168v-557h557v-170h-557v-557h-168v557h-557z" />
<glyph unicode="," horiz-adv-x="651" d="M158 -238l82 320v172h211v-172l-164 -320h-129z" />
<glyph unicode="-" horiz-adv-x="739" d="M100 479v164h539v-164h-539z" />
<glyph unicode="." horiz-adv-x="651" d="M219 0v254h211v-254h-211z" />
<glyph unicode="/" horiz-adv-x="690" d="M0 -190l520 1683h170l-520 -1683h-170z" />
<glyph unicode="0" d="M135 745q0 378 132.5 576.5t383.5 198.5t383.5 -198.5t132.5 -576.5q0 -377 -132.5 -575.5t-383.5 -198.5t-383.5 198.5t-132.5 575.5zM338 745q0 -307 78.5 -460.5t234.5 -153.5q157 0 235.5 153.5t78.5 460.5q0 308 -78.5 461.5t-235.5 153.5q-156 0 -234.5 -153.5 t-78.5 -461.5z" />
<glyph unicode="1" d="M225 1237v184l357 72h202v-1323h330v-170h-860v170h330v1139z" />
<glyph unicode="2" d="M150 0v170q115 119 313.5 319.5t249.5 258.5q97 109 135.5 184.5t38.5 148.5q0 119 -83.5 194t-217.5 75q-95 0 -200.5 -33t-225.5 -100v204q122 49 228 74t194 25q232 0 370 -116t138 -310q0 -92 -34.5 -174.5t-125.5 -194.5q-25 -29 -159 -167.5t-378 -387.5h705v-170 h-948z" />
<glyph unicode="3" d="M156 45v195q84 -49 184 -74t209 -25q190 0 289.5 75t99.5 218q0 132 -92.5 206.5t-257.5 74.5h-174v166h182q149 0 228 59.5t79 171.5q0 115 -81.5 176.5t-233.5 61.5q-83 0 -178 -18t-209 -56v180q115 32 215.5 48t189.5 16q230 0 364 -104.5t134 -282.5 q0 -124 -71 -209.5t-202 -118.5q145 -31 226.5 -129t81.5 -242q0 -221 -152 -342t-432 -121q-94 0 -193.5 18.5t-205.5 55.5z" />
<glyph unicode="4" d="M100 352v195l621 946h254v-973h213v-168h-213v-352h-201v352h-674zM264 520h510v797z" />
<glyph unicode="5" d="M158 35v203q90 -49 186 -73t203 -24q173 0 274 91t101 247t-101 247t-274 91q-81 0 -161.5 -18t-164.5 -56v750h793v-170h-608v-366q44 15 88 22.5t88 7.5q250 0 396 -137t146 -371q0 -241 -150 -374.5t-423 -133.5q-94 0 -191.5 16t-201.5 48z" />
<glyph unicode="6" d="M143 745q0 354 168 564.5t451 210.5q76 0 153.5 -15t161.5 -45v-184q-76 36 -153.5 55t-153.5 19q-200 0 -305.5 -135t-120.5 -408q59 87 148 133.5t196 46.5q225 0 355.5 -136.5t130.5 -371.5q0 -230 -136 -369t-362 -139q-259 0 -396 198.5t-137 575.5zM381 479 q0 -161 79.5 -254.5t215.5 -93.5t215.5 93.5t79.5 254.5q0 162 -79.5 255t-215.5 93t-215.5 -93t-79.5 -255z" />
<glyph unicode="7" d="M168 1323v170h960v-86l-542 -1407h-211l510 1323h-717z" />
<glyph unicode="8" d="M139 420q0 143 82 242t228 133q-130 32 -202.5 121t-72.5 217q0 179 127.5 283t349.5 104q223 0 350 -104t127 -283q0 -128 -72.5 -217t-201.5 -121q146 -34 227.5 -133t81.5 -242q0 -217 -132.5 -333t-379.5 -116t-379.5 116t-132.5 333zM342 420q0 -135 82.5 -212 t226.5 -77t227 77.5t83 211.5q0 135 -82.5 212t-227.5 77q-144 0 -226.5 -77t-82.5 -212zM375 1114q0 -116 72.5 -181t203.5 -65q130 0 203.5 65t73.5 181t-73.5 181t-203.5 65q-131 0 -203.5 -65t-72.5 -181z" />
<glyph unicode="9" d="M129 1012q0 230 136 369t362 139q259 0 395.5 -198.5t136.5 -576.5q0 -353 -167.5 -563.5t-450.5 -210.5q-76 0 -154 15t-162 45v184q76 -36 154 -55t153 -19q200 0 305.5 134.5t120.5 408.5q-58 -86 -147 -132t-197 -46q-224 0 -354.5 135.5t-130.5 370.5zM332 1012 q0 -162 79.5 -255t215.5 -93t215.5 93t79.5 255q0 161 -79.5 254.5t-215.5 93.5t-215.5 -93.5t-79.5 -254.5z" />
<glyph unicode=":" horiz-adv-x="690" d="M240 0v254h211v-254h-211zM240 805v254h211v-254h-211z" />
<glyph unicode=";" horiz-adv-x="690" d="M158 -238l82 320v172h211v-172l-164 -320h-129zM240 805v254h211v-254h-211z" />
<glyph unicode="&#x3c;" horiz-adv-x="1716" d="M217 559v166l1282 465v-182l-1032 -367l1032 -365v-182z" />
<glyph unicode="=" horiz-adv-x="1716" d="M217 352v170h1282v-170h-1282zM217 762v168h1282v-168h-1282z" />
<glyph unicode="&#x3e;" horiz-adv-x="1716" d="M217 94v182l1030 365l-1030 367v182l1282 -465v-166z" />
<glyph unicode="?" horiz-adv-x="1087" d="M147 1219v188q94 57 190.5 85t199.5 28q184 0 295.5 -97t111.5 -256q0 -76 -36 -144.5t-126 -154.5l-88 -86q-47 -47 -66.5 -73.5t-27.5 -51.5q-6 -21 -9 -51t-3 -82v-123h-191v154q0 101 28 166t118 151l90 89q57 53 82.5 100t25.5 96q0 89 -65.5 144t-173.5 55 q-79 0 -168.5 -35t-186.5 -102zM391 0v254h203v-254h-203z" />
<glyph unicode="@" horiz-adv-x="2048" d="M135 543q0 182 68 347t194 290q129 127 298 194.5t358 67.5q212 0 393.5 -87t304.5 -247q75 -98 114.5 -213t39.5 -238q0 -263 -159 -415t-439 -158v154q-60 -77 -137.5 -113.5t-180.5 -36.5q-172 0 -279.5 124.5t-107.5 324.5t108 325t279 125q103 0 181 -37.5 t137 -113.5v131h143v-736q146 22 228.5 133.5t82.5 288.5q0 107 -31.5 201t-95.5 174q-104 131 -253.5 200.5t-325.5 69.5q-123 0 -236 -32.5t-209 -96.5q-157 -102 -245.5 -267.5t-88.5 -358.5q0 -159 57.5 -298t166.5 -245q105 -104 243 -158.5t295 -54.5 q129 0 253.5 43.5t228.5 124.5l90 -111q-125 -97 -272.5 -148.5t-299.5 -51.5q-185 0 -349 65.5t-292 190.5t-195 289.5t-67 353.5zM762 537q0 -143 71 -224.5t195 -81.5q123 0 193.5 82t70.5 224q0 140 -72 222.5t-194 82.5q-121 0 -192.5 -82t-71.5 -223z" />
<glyph unicode="A" horiz-adv-x="1401" d="M16 0l570 1493h229l569 -1493h-210l-136 383h-673l-136 -383h-213zM426 551h549l-275 743z" />
<glyph unicode="B" horiz-adv-x="1405" d="M201 0v1493h516q231 0 356 -96t125 -273q0 -137 -64 -218t-188 -101q149 -32 231.5 -133.5t82.5 -253.5q0 -200 -136 -309t-387 -109h-536zM403 166h324q163 0 241.5 67.5t78.5 206.5q0 140 -78.5 206.5t-241.5 66.5h-324v-547zM403 877h299q148 0 220.5 55.5t72.5 169.5 q0 113 -72.5 169t-220.5 56h-299v-450z" />
<glyph unicode="C" horiz-adv-x="1430" d="M115 745q0 360 195 567.5t534 207.5q134 0 252.5 -35.5t222.5 -106.5v-213q-102 95 -217.5 142t-245.5 47q-256 0 -392 -156.5t-136 -452.5q0 -295 136 -451.5t392 -156.5q130 0 245.5 47t217.5 142v-211q-106 -72 -224.5 -108t-250.5 -36q-339 0 -534 207.5t-195 566.5z " />
<glyph unicode="D" horiz-adv-x="1577" d="M201 0v1493h415q434 0 637 -180.5t203 -564.5q0 -386 -204 -567t-636 -181h-415zM403 166h244q309 0 452.5 140t143.5 442q0 300 -143.5 439.5t-452.5 139.5h-244v-1161z" />
<glyph unicode="E" horiz-adv-x="1294" d="M201 0v1493h944v-170h-742v-442h711v-170h-711v-541h760v-170h-962z" />
<glyph unicode="F" horiz-adv-x="1178" d="M201 0v1493h858v-170h-656v-440h592v-170h-592v-713h-202z" />
<glyph unicode="G" horiz-adv-x="1587" d="M115 745q0 366 197.5 570.5t547.5 204.5q146 0 277.5 -36t242.5 -106v-215q-112 95 -238 143t-265 48q-274 0 -411.5 -153t-137.5 -456q0 -302 137.5 -455t411.5 -153q107 0 191 18.5t151 57.5v401h-330v166h530v-641q-117 -83 -258 -125.5t-301 -42.5 q-350 0 -547.5 204.5t-197.5 569.5z" />
<glyph unicode="H" horiz-adv-x="1540" d="M201 0v1493h202v-612h734v612h202v-1493h-202v711h-734v-711h-202z" />
<glyph unicode="I" horiz-adv-x="604" d="M201 0v1493h202v-1493h-202z" />
<glyph unicode="J" horiz-adv-x="604" d="M-106 -240h63q134 0 189 75t55 269v1389h202v-1389q0 -270 -102.5 -392t-329.5 -122h-77v170z" />
<glyph unicode="K" horiz-adv-x="1343" d="M201 0v1493h202v-631l670 631h260l-741 -696l794 -797h-266l-717 719v-719h-202z" />
<glyph unicode="L" horiz-adv-x="1141" d="M201 0v1493h202v-1323h727v-170h-929z" />
<glyph unicode="M" horiz-adv-x="1767" d="M201 0v1493h301l381 -1016l383 1016h301v-1493h-197v1311l-385 -1024h-203l-385 1024v-1311h-196z" />
<glyph unicode="N" horiz-adv-x="1532" d="M201 0v1493h272l662 -1249v1249h196v-1493h-272l-662 1249v-1249h-196z" />
<glyph unicode="O" horiz-adv-x="1612" d="M115 745q0 354 188.5 564.5t503.5 210.5q314 0 502 -210.5t188 -564.5q0 -353 -188 -563.5t-502 -210.5q-315 0 -503.5 210t-188.5 564zM328 745q0 -282 129.5 -446t349.5 -164t348.5 164t128.5 446q0 283 -128.5 447t-348.5 164t-349.5 -164t-129.5 -447z" />
<glyph unicode="P" horiz-adv-x="1235" d="M201 0v1493h456q251 0 379.5 -113.5t128.5 -332.5q0 -221 -128.5 -334t-379.5 -113h-254v-600h-202zM403 766h254q141 0 218 73t77 208q0 134 -77 207t-218 73h-254v-561z" />
<glyph unicode="Q" horiz-adv-x="1612" d="M115 745q0 354 188.5 564.5t503.5 210.5q314 0 502 -210.5t188 -564.5q0 -260 -104.5 -445t-302.5 -273l266 -291h-244l-221 239q-33 -2 -50.5 -3t-33.5 -1q-315 0 -503.5 210.5t-188.5 563.5zM328 745q0 -282 129.5 -446t349.5 -164t348.5 164t128.5 446 q0 283 -128.5 447t-348.5 164t-349.5 -164t-129.5 -447z" />
<glyph unicode="R" horiz-adv-x="1423" d="M201 0v1493h456q256 0 382 -107t126 -323q0 -141 -65.5 -234t-190.5 -129q65 -22 126.5 -94t123.5 -198l205 -408h-217l-191 383q-74 150 -143.5 199t-189.5 49h-220v-631h-202zM403 797h254q146 0 220.5 67.5t74.5 198.5t-74.5 197.5t-220.5 66.5h-254v-530z" />
<glyph unicode="S" horiz-adv-x="1300" d="M135 1094q0 198 139.5 312t384.5 114q105 0 214 -19t223 -57v-197q-115 55 -217 82t-197 27q-165 0 -254.5 -64t-89.5 -182q0 -99 59.5 -149.5t225.5 -81.5l122 -25q226 -43 333.5 -151.5t107.5 -290.5q0 -217 -145.5 -329t-426.5 -112q-106 0 -225.5 24t-247.5 71v208 q123 -69 241 -104t232 -35q173 0 267 68t94 194q0 110 -67.5 172t-221.5 93l-123 24q-226 45 -327 141t-101 267z" />
<glyph unicode="T" horiz-adv-x="1251" d="M-6 1323v170h1263v-170h-530v-1323h-203v1323h-530z" />
<glyph unicode="U" horiz-adv-x="1499" d="M178 561v932h203v-907q0 -240 87 -345.5t282 -105.5q194 0 281 105.5t87 345.5v907h203v-932q0 -292 -144.5 -441t-426.5 -149q-283 0 -427.5 149t-144.5 441z" />
<glyph unicode="V" horiz-adv-x="1401" d="M16 1493h211l473 -1257l474 1257h210l-569 -1493h-229z" />
<glyph unicode="W" horiz-adv-x="2025" d="M68 1493h204l314 -1262l313 1262h227l314 -1262l313 1262h205l-375 -1493h-254l-315 1296l-318 -1296h-254z" />
<glyph unicode="X" horiz-adv-x="1403" d="M61 0l533 797l-465 696h217l371 -555l373 555h217l-480 -717l512 -776h-217l-420 635l-423 -635h-218z" />
<glyph unicode="Y" horiz-adv-x="1251" d="M-4 1493h217l414 -614l411 614h217l-528 -782v-711h-203v711z" />
<glyph unicode="Z" horiz-adv-x="1403" d="M92 0v154l944 1169h-921v170h1173v-154l-944 -1169h967v-170h-1219z" />
<glyph unicode="[" horiz-adv-x="799" d="M176 -270v1826h424v-143h-240v-1540h240v-143h-424z" />
<glyph unicode="\" horiz-adv-x="690" d="M0 1493h170l520 -1683h-170z" />
<glyph unicode="]" horiz-adv-x="799" d="M199 -127h239v1540h-239v143h424v-1826h-424v143z" />
<glyph unicode="^" horiz-adv-x="1716" d="M217 936l543 557h196l543 -557h-201l-440 395l-440 -395h-201z" />
<glyph unicode="_" horiz-adv-x="1024" d="M-20 -340h1064v-143h-1064v143z" />
<glyph unicode="`" horiz-adv-x="1024" d="M170 1638h197l282 -374h-153z" />
<glyph unicode="a" horiz-adv-x="1255" d="M123 326q0 189 126.5 285t377.5 96h258v18q0 127 -83.5 196.5t-234.5 69.5q-96 0 -187 -23t-175 -69v170q101 39 196 58.5t185 19.5q243 0 363 -126t120 -382v-639h-184v170q-63 -102 -157 -150.5t-230 -48.5q-172 0 -273.5 96.5t-101.5 258.5zM307 338 q0 -98 64.5 -155.5t175.5 -57.5q153 0 245.5 108.5t92.5 288.5v41h-183q-223 0 -309 -51t-86 -174z" />
<glyph unicode="b" horiz-adv-x="1300" d="M186 0v1556h185v-606q58 100 146.5 148.5t211.5 48.5q204 0 331.5 -162t127.5 -426t-127.5 -426t-331.5 -162q-123 0 -211.5 48.5t-146.5 148.5v-168h-185zM371 559q0 -203 83.5 -318.5t229.5 -115.5t229.5 115.5t83.5 318.5t-83.5 318.5t-229.5 115.5t-229.5 -115.5 t-83.5 -318.5z" />
<glyph unicode="c" horiz-adv-x="1126" d="M113 559q0 274 150.5 431t412.5 157q85 0 166 -17.5t157 -52.5v-172q-78 43 -156.5 64.5t-158.5 21.5q-179 0 -278 -113.5t-99 -318.5t99 -318.5t278 -113.5q80 0 158.5 21.5t156.5 64.5v-170q-77 -36 -159.5 -54t-175.5 -18q-253 0 -402 159t-149 429z" />
<glyph unicode="d" horiz-adv-x="1300" d="M113 559q0 264 127.5 426t330.5 162q124 0 212.5 -48.5t146.5 -148.5v606h184v-1556h-184v168q-58 -100 -146.5 -148.5t-212.5 -48.5q-203 0 -330.5 162t-127.5 426zM303 559q0 -203 83.5 -318.5t229.5 -115.5t230 115.5t84 318.5t-84 318.5t-230 115.5t-229.5 -115.5 t-83.5 -318.5z" />
<glyph unicode="e" horiz-adv-x="1260" d="M113 549q0 275 148.5 436.5t400.5 161.5q226 0 357.5 -145.5t131.5 -395.5v-90h-846q12 -190 114.5 -289.5t285.5 -99.5q106 0 205.5 26t197.5 78v-174q-99 -42 -203 -64t-211 -22q-268 0 -424.5 156t-156.5 422zM311 659l656 1q-2 151 -84.5 241t-218.5 90 q-154 0 -246.5 -87t-106.5 -245z" />
<glyph unicode="f" horiz-adv-x="721" d="M47 977v143h176v78q0 187 87 272.5t276 85.5h174v-153h-176q-99 0 -137.5 -40t-38.5 -144v-99h303v-143h-303v-977h-185v977h-176z" />
<glyph unicode="g" horiz-adv-x="1300" d="M113 573q0 260 126 417t332 157q124 0 213 -49t146 -148v170h184v-981q0 -286 -127 -425.5t-389 -139.5q-97 0 -183 14.5t-167 44.5v179q81 -44 160 -65t161 -21q181 0 271 94.5t90 285.5v91q-57 -99 -146 -148t-213 -49q-206 0 -332 157t-126 416zM303 573 q0 -199 82.5 -309t230.5 -110q149 0 231.5 110t82.5 309q0 200 -82.5 310t-231.5 110q-148 0 -230.5 -110t-82.5 -310z" />
<glyph unicode="h" horiz-adv-x="1298" d="M186 0v1556h185v-610q66 101 155.5 151t206.5 50q193 0 292 -119.5t99 -351.5v-676h-184v670q0 159 -62 238t-186 79q-149 0 -235 -95t-86 -259v-633h-185z" />
<glyph unicode="i" horiz-adv-x="569" d="M193 0v1120h184v-1120h-184zM193 1323v233h184v-233h-184z" />
<glyph unicode="j" horiz-adv-x="569" d="M-37 -270h49q105 0 143 48.5t38 201.5v1140h184v-1140q0 -214 -81.5 -310t-262.5 -96h-70v156zM193 1323v233h184v-233h-184z" />
<glyph unicode="k" horiz-adv-x="1186" d="M186 0v1556h185v-919l549 483h235l-594 -524l619 -596h-240l-569 547v-547h-185z" />
<glyph unicode="l" horiz-adv-x="569" d="M193 0v1556h184v-1556h-184z" />
<glyph unicode="m" horiz-adv-x="1995" d="M186 0v1120h185v-174q63 103 151 152t209 49q122 0 207.5 -62t126.5 -180q69 124 165 183t226 59q175 0 270 -122.5t95 -348.5v-676h-185v670q0 161 -57 239t-174 78q-143 0 -226 -95t-83 -259v-633h-185v670q0 162 -57 239.5t-176 77.5q-141 0 -224 -95.5t-83 -258.5 v-633h-185z" />
<glyph unicode="n" horiz-adv-x="1298" d="M186 0v1120h185v-174q66 101 155.5 151t206.5 50q193 0 292 -119.5t99 -351.5v-676h-184v670q0 159 -62 238t-186 79q-149 0 -235 -95t-86 -259v-633h-185z" />
<glyph unicode="o" horiz-adv-x="1253" d="M113 559q0 276 136.5 432t377.5 156q240 0 377 -156t137 -432q0 -275 -137 -431.5t-377 -156.5q-241 0 -377.5 156.5t-136.5 431.5zM307 559q0 -201 85.5 -316.5t234.5 -115.5q147 0 233 116t86 316q0 199 -86 315.5t-233 116.5q-148 0 -234 -115.5t-86 -316.5z" />
<glyph unicode="p" horiz-adv-x="1300" d="M186 -426v1546h185v-170q58 100 146.5 148.5t211.5 48.5q204 0 331.5 -162t127.5 -426t-127.5 -426t-331.5 -162q-123 0 -211.5 48.5t-146.5 148.5v-594h-185zM371 559q0 -203 83.5 -318.5t229.5 -115.5t229.5 115.5t83.5 318.5t-83.5 318.5t-229.5 115.5t-229.5 -115.5 t-83.5 -318.5z" />
<glyph unicode="q" horiz-adv-x="1300" d="M113 559q0 264 127.5 426t330.5 162q124 0 212.5 -48.5t146.5 -148.5v170h184v-1546h-184v594q-58 -100 -146.5 -148.5t-212.5 -48.5q-203 0 -330.5 162t-127.5 426zM303 559q0 -203 83.5 -318.5t229.5 -115.5t230 115.5t84 318.5t-84 318.5t-230 115.5t-229.5 -115.5 t-83.5 -318.5z" />
<glyph unicode="r" horiz-adv-x="842" d="M186 0v1120h185v-174q58 102 151 151.5t226 49.5q19 0 42 -2.5t51 -7.5l1 -189q-31 18 -67.5 26.5t-80.5 8.5q-156 0 -239.5 -101.5t-83.5 -291.5v-590h-185z" />
<glyph unicode="s" horiz-adv-x="1067" d="M111 41v190q102 -53 201 -79.5t196 -26.5q130 0 200 44.5t70 125.5q0 75 -50.5 115t-221.5 77l-64 15q-171 36 -247 110.5t-76 204.5q0 158 112 244t318 86q102 0 192 -15t166 -45v-174q-78 40 -162 60t-174 20q-137 0 -205.5 -42t-68.5 -126q0 -64 49 -100.5t197 -69.5 l63 -14q196 -42 278.5 -118.5t82.5 -213.5q0 -156 -123.5 -247t-339.5 -91q-90 0 -187.5 17.5t-205.5 52.5z" />
<glyph unicode="t" horiz-adv-x="803" d="M55 977v143h135v318h185v-318h379v-143h-379v-608q0 -137 37.5 -176t152.5 -39h189v-154h-189q-213 0 -294 79.5t-81 289.5v608h-135z" />
<glyph unicode="u" horiz-adv-x="1298" d="M174 442v678h184v-671q0 -159 62 -238.5t186 -79.5q149 0 235.5 95t86.5 259v635h184v-1120h-184v172q-67 -102 -155.5 -151.5t-205.5 -49.5q-193 0 -293 120t-100 351zM637 1147z" />
<glyph unicode="v" horiz-adv-x="1212" d="M61 1120h195l350 -940l350 940h195l-420 -1120h-250z" />
<glyph unicode="w" horiz-adv-x="1675" d="M86 1120h184l230 -874l229 874h217l230 -874l229 874h184l-293 -1120h-217l-241 918l-242 -918h-217z" />
<glyph unicode="x" horiz-adv-x="1212" d="M59 0l435 586l-398 534h217l297 -399l297 399h217l-405 -545l426 -575h-217l-326 440l-326 -440h-217z" />
<glyph unicode="y" horiz-adv-x="1212" d="M61 1120h195l350 -876l350 876h195l-492 -1224q-78 -200 -152 -261t-198 -61h-147v154h108q76 0 118 36t93 170l33 84z" />
<glyph unicode="z" horiz-adv-x="1075" d="M88 0v168l692 805h-667v147h874v-168l-692 -805h692v-147h-899z" />
<glyph unicode="{" d="M256 541v143h61q143 0 196.5 57.5t53.5 206.5v240q0 221 84.5 294.5t333.5 73.5h62v-143h-68q-141 0 -184 -44t-43 -185v-248q0 -157 -45.5 -228t-155.5 -96q111 -27 156 -98t45 -227v-248q0 -141 43 -185t184 -44h68v-144h-62q-249 0 -333.5 74t-84.5 295v239 q0 151 -54 209t-196 58h-61z" />
<glyph unicode="|" horiz-adv-x="690" d="M260 -483v2048h170v-2048h-170z" />
<glyph unicode="}" d="M256 -190h70q140 0 182.5 43t42.5 186v248q0 156 45 227t156 98q-111 25 -156 96t-45 228v248q0 142 -42.5 185.5t-182.5 43.5h-70v143h63q249 0 332.5 -73.5t83.5 -294.5v-240q0 -149 54 -206.5t196 -57.5h62v-143h-62q-142 0 -196 -58t-54 -209v-239q0 -221 -83.5 -295 t-332.5 -74h-63v144z" />
<glyph unicode="~" horiz-adv-x="1716" d="M217 467v178q105 79 194.5 113.5t186.5 34.5q110 0 257 -60l15 -6q8 -3 22 -8q155 -62 249 -62q86 0 170.5 38t187.5 122v-178q-105 -79 -194.5 -113t-186.5 -34q-110 0 -256 59q-11 4 -16 6q-7 3 -22 8q-155 62 -249 62q-88 0 -174 -38.5t-184 -121.5z" />
<glyph unicode="&#xa2;" d="M172 559q0 258 132.5 411t373.5 175v287h102l1 -287q73 -4 141.5 -20.5t136.5 -47.5v-172q-74 41 -142 62t-136 24l-1 -864q70 5 138.5 26t140.5 60v-170q-65 -30 -133.5 -47.5t-145.5 -24.5v-284h-102v288q-241 20 -373.5 173.5t-132.5 410.5zM367 559q0 -185 82 -298 t229 -130v856q-147 -18 -229 -131t-82 -297z" />
<glyph unicode="&#xa3;" d="M129 0v170h236v465h-199v143h199v238q0 261 107 382.5t339 121.5q61 0 136.5 -15.5t154.5 -44.5v-182q-76 41 -144 61.5t-129 20.5q-148 0 -206 -77.5t-58 -289.5v-215h391v-143h-391v-465h557v-170h-993z" />
<glyph unicode="&#xa5;" d="M82 1493h190l379 -700l377 700h191l-318 -586h264v-123h-331l-84 -155v-51h415v-123h-413v-455h-201v455h-416v123h416v51l-84 155h-332v123h264z" />
<glyph unicode="&#xa9;" horiz-adv-x="2048" d="M283 741q0 154 54 285t163 240t240.5 164t283.5 55t283.5 -55t240.5 -164t163 -240t54 -285q0 -152 -54 -282.5t-163 -239.5t-240.5 -164t-283.5 -55t-283.5 55t-240.5 164t-163 239.5t-54 282.5zM383 741q0 -129 48 -242.5t142 -207.5t207 -141.5t244 -47.5 q132 0 245.5 47.5t207.5 141.5q93 93 139.5 206t46.5 244q0 133 -47 246.5t-139 206.5q-94 94 -207.5 141t-245.5 47q-131 0 -244 -47t-207 -141t-142 -208.5t-48 -244.5zM582 741q0 209 125.5 330t341.5 121q73 0 141 -14t133 -41v-129q-66 33 -131 49t-131 16 q-149 0 -232.5 -87.5t-83.5 -244.5q0 -159 85.5 -246t240.5 -87q64 0 125 15.5t127 49.5v-127q-67 -29 -135.5 -43t-138.5 -14q-216 0 -341.5 122t-125.5 330z" />
<glyph unicode="&#xad;" horiz-adv-x="739" d="M100 479v164h539v-164h-539z" />
<glyph unicode="&#xae;" horiz-adv-x="2048" d="M283 741q0 154 54 285t163 240t240.5 164t283.5 55t283.5 -55t240.5 -164t163 -240t54 -285q0 -152 -54 -282.5t-163 -239.5t-240.5 -164t-283.5 -55t-283.5 55t-240.5 164t-163 239.5t-54 282.5zM383 741q0 -129 48 -242.5t142 -207.5t207 -141.5t244 -47.5 q132 0 245.5 47.5t207.5 141.5q93 93 139.5 206t46.5 244q0 133 -47 246.5t-139 206.5q-94 94 -207.5 141t-245.5 47q-131 0 -244 -47t-207 -141t-142 -208.5t-48 -244.5zM719 338v836h285q176 0 263 -59.5t87 -180.5q0 -86 -52.5 -142t-148.5 -73q24 -8 57.5 -46.5 t79.5 -111.5l137 -223h-172l-129 209q-59 96 -95.5 121.5t-90.5 25.5h-66v-356h-155zM874 795h123q110 0 153.5 31t43.5 106q0 76 -44 107.5t-153 31.5h-123v-276z" />
<glyph unicode="&#xb4;" horiz-adv-x="1024" d="M371 1262l280 376h199l-326 -376h-153z" />
<glyph unicode="&#x2000;" horiz-adv-x="819" />
<glyph unicode="&#x2001;" horiz-adv-x="1638" />
<glyph unicode="&#x2002;" horiz-adv-x="819" />
<glyph unicode="&#x2003;" horiz-adv-x="1638" />
<glyph unicode="&#x2004;" horiz-adv-x="546" />
<glyph unicode="&#x2005;" horiz-adv-x="409" />
<glyph unicode="&#x2006;" horiz-adv-x="273" />
<glyph unicode="&#x2007;" horiz-adv-x="273" />
<glyph unicode="&#x2008;" horiz-adv-x="204" />
<glyph unicode="&#x2009;" horiz-adv-x="327" />
<glyph unicode="&#x200a;" horiz-adv-x="91" />
<glyph unicode="&#x2010;" horiz-adv-x="739" d="M100 479v164h539v-164h-539z" />
<glyph unicode="&#x2011;" horiz-adv-x="739" d="M100 479v164h539v-164h-539z" />
<glyph unicode="&#x2012;" horiz-adv-x="739" d="M100 479v164h539v-164h-539z" />
<glyph unicode="&#x2013;" horiz-adv-x="1024" d="M100 489v144h824v-144h-824z" />
<glyph unicode="&#x2014;" horiz-adv-x="2048" d="M100 489v144h1848v-144h-1848z" />
<glyph unicode="&#x2018;" horiz-adv-x="651" d="M174 1001v173l164 319h129l-82 -319v-173h-211z" />
<glyph unicode="&#x2019;" horiz-adv-x="651" d="M178 1022l82 319v152h211v-152l-164 -319h-129z" />
<glyph unicode="&#x201c;" horiz-adv-x="1061" d="M174 1001v173l164 319h129l-82 -319v-173h-211zM584 1001v173l164 319h129l-82 -319v-173h-211z" />
<glyph unicode="&#x201d;" horiz-adv-x="1061" d="M174 1001l82 320v172h211v-172l-164 -320h-129zM584 1001l82 320v172h211v-172l-164 -320h-129z" />
<glyph unicode="&#x2022;" horiz-adv-x="1208" d="M307 762q0 124 86.5 209.5t212.5 85.5q124 0 209.5 -85.5t85.5 -209.5q0 -125 -86 -211t-211 -86t-211 86t-86 211z" />
<glyph unicode="&#x2026;" horiz-adv-x="2048" d="M236 0v254h213v-254h-213zM918 0v254h212v-254h-212zM1599 0v254h213v-254h-213z" />
<glyph unicode="&#x202f;" horiz-adv-x="327" />
<glyph unicode="&#x205f;" horiz-adv-x="409" />
<glyph unicode="&#x20ac;" d="M0 520l55 123h139q0 23 -0.5 46.5t-0.5 55.5q0 35 0.5 58.5t0.5 46.5h-194l55 123h156q40 257 195 402t391 145q98 0 190.5 -35.5t179.5 -106.5v-213q-91 105 -175.5 150t-186.5 45q-157 0 -258 -100t-133 -287h577l-55 -123h-538q-2 -24 -2.5 -47t-0.5 -58 q0 -32 0.5 -55t2.5 -47h446l-56 -123h-374q32 -187 133 -288t258 -101q102 0 186.5 45t175.5 150v-211q-89 -72 -181.5 -108t-188.5 -36q-237 0 -391.5 145t-194.5 404h-211z" />
<glyph unicode="&#x2122;" horiz-adv-x="2048" d="M295 1399v94h518v-94h-203v-484h-114v484h-201zM926 915v578h172l174 -256l164 256h170v-578h-113v484l-195 -303h-55l-203 303v-484h-114z" />
<glyph unicode="&#xe000;" horiz-adv-x="1120" d="M0 1120h1120v-1120h-1120v1120z" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 24 KiB

125
src/SvgFont.php Normal file
View File

@@ -0,0 +1,125 @@
<?php
declare(strict_types=1);
namespace Komarev\GitHubProfileViewsCounter;
use XMLReader;
final class SvgFont
{
private const UNICODE_CODE_POINT_M_LOWERCASE = 109;
private array $glyphs;
public int $unitsPerEm;
private int $glyphSpacingAdvX;
private int $missingGlyphAdvX;
public function __construct(
array $glyphs = [],
int $unitsPerEm = 0,
int $glyphSpacingAdvX = 0,
int $missingGlyphAdvX = 0
) {
$this->glyphs = $glyphs;
$this->unitsPerEm = $unitsPerEm;
$this->glyphSpacingAdvX = $glyphSpacingAdvX;
$this->missingGlyphAdvX = $missingGlyphAdvX;
}
/**
* Takes path to SVG font (local path) and processes its XML
* to get path representation of every character and additional
* font parameters.
*/
public static function fromFile(
string $filePath
): self {
$xml = new XMLReader();
$xml->open($filePath);
$glyphs = [];
$defaultHorizAdvX = 0;
$unitsPerEm = 0;
$glyphSpacingHorizAdvX = 0;
$missingGlyphHorizAdvX = 0;
while ($xml->read()) {
if ($xml->nodeType !== XMLReader::ELEMENT) {
continue;
}
if ($xml->name === 'font') {
$defaultHorizAdvX = intval($xml->getAttribute('horiz-adv-x'));
}
if ($xml->name === 'font-face') {
$unitsPerEm = intval($xml->getAttribute('units-per-em'));
}
if ($xml->name === 'missing-glyph') {
$missingGlyphHorizAdvX = intval($xml->getAttribute('horiz-adv-x'));
}
if ($xml->name === 'glyph') {
$unicode = $xml->getAttribute('unicode');
if (isset($unicode)) {
$codePoints = TextUnicodeConverter::convertTextToCodePoints($unicode);
if (isset($codePoints[0])) {
$codePoint = $codePoints[0];
$glyphs[$codePoint] = new \stdClass();
$glyphHorizAdvX = $xml->getAttribute('horiz-adv-x');
if (empty($glyphHorizAdvX)) {
$glyphs[$codePoint]->horizAdvX = $defaultHorizAdvX;
} else {
$glyphs[$codePoint]->horizAdvX = intval($glyphHorizAdvX);
}
$glyphs[$codePoint]->d = $xml->getAttribute('d');
if ($codePoint === self::UNICODE_CODE_POINT_M_LOWERCASE) {
$glyphSpacingHorizAdvX = $glyphs[$codePoint]->horizAdvX;
}
}
}
}
}
return new self(
$glyphs,
$unitsPerEm,
$glyphSpacingHorizAdvX,
$missingGlyphHorizAdvX,
);
}
public function computeWidth(
int $codePoint,
int $size,
float $glyphSpacing = 0.0
): float {
$size = $size / $this->unitsPerEm;
$glyphAdvX = $this->getGlyphAdvX($codePoint);
$glyphWidth = $glyphAdvX * $size;
$glyphSpacingWidth = $this->glyphSpacingAdvX * $glyphSpacing * $size;
return $glyphWidth + $glyphSpacingWidth;
}
private function getGlyphAdvX(
int $codePoint
): int {
return isset($this->glyphs[$codePoint])
? $this->glyphs[$codePoint]->horizAdvX
: $this->missingGlyphAdvX;
}
}

View File

@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Komarev\GitHubProfileViewsCounter;
use PUGX\Poser\Calculator\TextSizeCalculatorInterface;
class SvgTextSizeCalculator implements TextSizeCalculatorInterface
{
private const SHIELD_PADDING = 12;
private const UNICODE_CODE_POINT_LINE_FEED = 10;
/**
* Calculate the width of the text box.
*/
public function calculateWidth(string $text, int $size = self::TEXT_SIZE): float
{
$font = SvgFont::fromFile(__DIR__ . '/DejaVuSans-webfont.svg');
$textUnicode = TextUnicodeConverter::convertTextToCodePoints($text);
$width = 0;
$lineWidth = 0;
foreach ($textUnicode as $unicodeCodePoint) {
if ($unicodeCodePoint === self::UNICODE_CODE_POINT_LINE_FEED) {
$width = max($width, $lineWidth);
$lineWidth = 0;
continue;
}
$lineWidth += $font->computeWidth($unicodeCodePoint, $size);
}
$width = max($width, $lineWidth);
return \round($width + self::SHIELD_PADDING, 1);
}
}

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace Komarev\GitHubProfileViewsCounter;
final class TextUnicodeConverter
{
/**
* Converts UTF-8 encoded string and returns unicode number for every character.
*/
public static function convertTextToCodePoints(
string $string
): array {
$unicode = [];
$values = [];
$lookingFor = 1;
for ($i = 0, $iMax = strlen($string); $i < $iMax; $i++) {
$thisValue = ord($string[$i]);
if ($thisValue < 128) {
$unicode[] = $thisValue;
} else {
if (count($values) === 0) {
$lookingFor = ($thisValue < 224) ? 2 : 3;
}
$values[] = $thisValue;
if (count($values) === $lookingFor) {
$number = ($lookingFor === 3) ?
(($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64) :
(($values[0] % 32) * 64) + ($values[1] % 64);
$unicode[] = $number;
$values = [];
$lookingFor = 1;
}
}
}
return $unicode;
}
}