nfroidure / svgicons2svgfont

Concatenate SVG icons and ouput an SVG font
http://nfroidure.github.io/svgiconfont/
MIT License
335 stars 72 forks source link

Icons with multiple unicode codepoints should always have the same path #133

Closed zbream closed 3 years ago

zbream commented 3 years ago

I am using the tool icon-font-buildr which utilizes svgicons2svgfont to generate an SVG font, which is then used to generate TTF/WOFF/etc fonts. I'm running into an issue in my final output, which I've tracked down to behavior in svgicons2svgfont.

Issue

I'm a gentledev i:

Expected behavior

When a single icon has multiple unicode strings for ligatures, multiple matching glyphs are added to the final SVG font. Each entry is given a unique name, the unicode string, and path.

It is expected that the path for a particular icon be the same for each glyph in the final output.

<glyph glyph-name="rotate_left" unicode="&#xE008;" horiz-adv-x="4096" 
  d="M375.4990933333335 2890.4584533333336C677.1353600000001 3512.5828266666667 1317.0978133333333 3925.334016 2048 3925.334016C3080.9258666666665 3925.334016 3925.3333333333326 3080.92416 3925.3333333333326 2048H3584C3584 2892.4108800000004 2892.4074666666666 3584 2048 3584C1447.7021866666666 3584 927.1313066666668 3245.81888 682.6342400000001 2741.5432533333333L375.4990933333335 2890.4584533333336zM538.7212800000001 4014.9843626666666L675.3058133333334 3007.6757333333335L1699.679573333333 3144.2602666666667L1744.7936 2805.9204266666666L382.8275200000001 2624.3242666666665L200.4821333333334 3969.1216213333337L538.7212800000001 4014.9843626666666zM3794.9781333333326 1359.0357333333336L3720.4821333333334 1205.5040000000004C3640.012799999999 1039.6671999999999 3535.479466666666 888.6442666666671 3411.6437333333333 756.3434666666667L3295.010133333333 631.7397333333333L3045.819733333333 864.9898666666668L3162.4362666666666 989.5936000000002C3263.1978666666664 1097.2330666666667 3348.104533333333 1219.9594666666667 3413.384533333333 1354.5130666666664L3487.8976000000002 1508.0448000000001L3794.9781333333326 1359.0357333333336zM2855.7482666666665 342.4767999999999L2695.3898666666664 284.0576000000001C2507.0421333333334 215.4495999999999 2304.9045333333333 176.2816000000003 2094.7797333333333 171.2298666666666L1924.1472 167.1167999999998L1915.938133333333 508.3648000000003L2086.5535999999997 512.4608000000003C2259.4048 516.625066666667 2424.8831999999998 548.7957333333334 2578.551466666667 604.7744000000002L2738.909866666667 663.1936000000001L2855.7482666666665 342.4767999999999zM832.9164800000001 1096.3797333333332L952.3643733333334 974.4896000000005C1072.2013866666666 852.1898666666671 1212.2948266666667 749.6362666666664 1366.6747733333334 672.529066666667L1519.3531733333332 596.2752L1366.8266666666664 290.9013333333333L1214.14656 367.1722666666665C1025.4865066666666 461.4144000000006 854.6252800000001 586.5301333333332 708.5636266666668 735.5904L589.1174400000001 857.4976000000001L832.9164800000001 1096.3797333333332zM512.0000000000001 2218.666666666667V2048C512.0000000000001 1887.9488 536.8712533333334 1733.597866666667 582.7430400000001 1588.4629333333332L634.1768533333334 1425.7322666666669L308.7138133333334 1322.8544000000002L257.2782933333334 1485.5850666666665C201.0914133333334 1663.3685333333333 170.6666666666668 1852.3818666666668 170.6666666666668 2048V2218.666666666667H512.0000000000001z" />
<glyph glyph-name="rotate_left-1" unicode="&#x72;&#x6F;&#x74;&#x61;&#x74;&#x65;&#x5F;&#x6C;&#x65;&#x66;&#x74;" horiz-adv-x="4096"
  d="M375.4990933333335 2890.4584533333336C677.1353600000001 3512.5828266666667 1317.0978133333333 3925.334016 2048 3925.334016C3080.9258666666665 3925.334016 3925.3333333333326 3080.92416 3925.3333333333326 2048H3584C3584 2892.4108800000004 2892.4074666666666 3584 2048 3584C1447.7021866666666 3584 927.1313066666668 3245.81888 682.6342400000001 2741.5432533333333L375.4990933333335 2890.4584533333336zM538.7212800000001 4014.9843626666666L675.3058133333334 3007.6757333333335L1699.679573333333 3144.2602666666667L1744.7936 2805.9204266666666L382.8275200000001 2624.3242666666665L200.4821333333334 3969.1216213333337L538.7212800000001 4014.9843626666666zM3794.9781333333326 1359.0357333333336L3720.4821333333334 1205.5040000000004C3640.012799999999 1039.6671999999999 3535.479466666666 888.6442666666671 3411.6437333333333 756.3434666666667L3295.010133333333 631.7397333333333L3045.819733333333 864.9898666666668L3162.4362666666666 989.5936000000002C3263.1978666666664 1097.2330666666667 3348.104533333333 1219.9594666666667 3413.384533333333 1354.5130666666664L3487.8976000000002 1508.0448000000001L3794.9781333333326 1359.0357333333336zM2855.7482666666665 342.4767999999999L2695.3898666666664 284.0576000000001C2507.0421333333334 215.4495999999999 2304.9045333333333 176.2816000000003 2094.7797333333333 171.2298666666666L1924.1472 167.1167999999998L1915.938133333333 508.3648000000003L2086.5535999999997 512.4608000000003C2259.4048 516.625066666667 2424.8831999999998 548.7957333333334 2578.551466666667 604.7744000000002L2738.909866666667 663.1936000000001L2855.7482666666665 342.4767999999999zM832.9164800000001 1096.3797333333332L952.3643733333334 974.4896000000005C1072.2013866666666 852.1898666666671 1212.2948266666667 749.6362666666664 1366.6747733333334 672.529066666667L1519.3531733333332 596.2752L1366.8266666666664 290.9013333333333L1214.14656 367.1722666666665C1025.4865066666666 461.4144000000006 854.6252800000001 586.5301333333332 708.5636266666668 735.5904L589.1174400000001 857.4976000000001L832.9164800000001 1096.3797333333332zM512.0000000000001 2218.666666666667V2048C512.0000000000001 1887.9488 536.8712533333334 1733.597866666667 582.7430400000001 1588.4629333333332L634.1768533333334 1425.7322666666669L308.7138133333334 1322.8544000000002L257.2782933333334 1485.5850666666665C201.0914133333334 1663.3685333333333 170.6666666666668 1852.3818666666668 170.6666666666668 2048V2218.666666666667H512.0000000000001z" />

Actual behavior

It is possible for the path for a particular icon to change slightly between the different glyph entries. In my example, the precision of some of the coordinates seems to change between each glyph.

<glyph glyph-name="rotate_right" unicode="&#xE009;" horiz-adv-x="4096"
  d="M2355.2 2713.6000000000004L3720.5333333333338 2525.866666666667L3908.2666666666664 3874.1333333333337L3566.933333333333 3925.3333333333335L3464.5333333333333 3191.4666666666667C3123.2 3584 2611.2 3840 2048 3840C1006.9333333333336 3840 170.6666666666668 3003.7333333333336 170.6666666666668 1962.6666666666667H512.0000000000001C512.0000000000001 2798.9333333333334 1211.7333333333331 3498.666666666667 2048 3498.666666666667C2525.866666666667 3498.666666666667 2935.4666666666662 3293.866666666667 3225.5999999999995 2952.5333333333333L2389.333333333333 3054.9333333333334L2355.2 2713.6000000000004zM682.6666666666667 1262.9333333333334L614.4000000000001 1416.5333333333338L307.2000000000001 1262.9333333333334L375.4666666666668 1109.3333333333335C460.8000000000001 938.666666666667 563.2 785.0666666666671 682.6666666666667 665.5999999999999L802.1333333333334 546.1333333333332L1058.1333333333332 785.0666666666671L938.6666666666669 904.5333333333338C836.2666666666668 1006.9333333333334 750.9333333333335 1126.4000000000005 682.6666666666667 1262.9333333333334zM1518.9333333333334 512L1365.3333333333333 580.2666666666664L1245.8666666666666 256L1399.4666666666665 204.8000000000002C1587.2 136.5333333333338 1792 102.4000000000006 1996.7999999999995 85.3333333333335H2167.4666666666662V426.666666666667H1996.7999999999995C1843.2 426.666666666667 1672.5333333333333 460.8000000000002 1518.9333333333334 512zM3140.2666666666664 887.4666666666667C3020.7999999999997 768 2884.2666666666664 665.5999999999999 2730.6666666666665 580.2666666666664L2577.0666666666666 512L2730.6666666666665 204.8000000000002L2884.2666666666664 273.0666666666671C3072 375.4666666666667 3242.6666666666665 494.9333333333334 3396.2666666666664 648.5333333333338L3515.7333333333336 768L3276.7999999999997 1006.9333333333334L3140.2666666666664 887.4666666666667zM3584 2133.3333333333335V1962.6666666666667C3584 1809.0666666666668 3566.933333333333 1655.4666666666667 3515.7333333333336 1501.8666666666668L3464.5333333333333 1331.2000000000003L3788.8 1228.8000000000002L3840 1399.4666666666667C3891.2 1570.1333333333332 3925.3333333333326 1757.8666666666668 3925.3333333333326 1962.6666666666667V2133.3333333333335H3584z" />
<glyph glyph-name="rotate_right-1" unicode="&#x72;&#x6F;&#x74;&#x61;&#x74;&#x65;&#x5F;&#x72;&#x69;&#x67;&#x68;&#x74;" horiz-adv-x="4096"
  d="M2355.2 2713.6000000000004L3720.5333333333338 2525.866666666667L3908.2666666666664 3874.1333333333337L3566.933333333333 3925.3333333333335L3464.5333333333333 3191.4666666666667C3123.2 3584 2611.2 3840 2048 3840C1006.9333333333336 3840 170.6666666666668 3003.7333333333336 170.6666666666668 1962.6666666666667H512.0000000000001C512.0000000000001 2798.9333333333334 1211.7333333333331 3498.666666666667 2048 3498.666666666667C2525.866666666667 3498.666666666667 2935.4666666666662 3293.866666666667 3225.5999999999995 2952.5333333333333L2389.333333333333 3054.9333333333334L2355.2 2713.6000000000004zM682.6666666666667 1262.9333333333334L614.4000000000001 1416.5333333333338L307.2000000000001 1262.9333333333334L375.4666666666668 1109.3333333333335C460.8000000000001 938.666666666667 563.2 785.0666666666671 682.6666666666667 665.5999999999999L802.1333333333334 546.1333333333332L1058.1333333333332 785.0666666666671L938.6666666666669 904.5333333333338C836.2666666666668 1006.9333333333334 750.9333333333335 1126.4000000000005 682.6666666666667 1262.9333333333334zM1518.9333333333334 512L1365.3333333333333 580.2666666666664L1245.8666666666666 256L1399.4666666666665 204.8000000000002C1587.2 136.5333333333338 1792 102.4000000000006 1996.7999999999995 85.3333333333335H2167.4666666666662V426.6666666666671H1996.7999999999995C1843.2 426.6666666666671 1672.5333333333333 460.8000000000002 1518.9333333333334 512zM3140.2666666666664 887.4666666666667C3020.7999999999997 768 2884.2666666666664 665.5999999999999 2730.6666666666665 580.2666666666664L2577.0666666666666 512L2730.6666666666665 204.8000000000002L2884.2666666666664 273.0666666666671C3072 375.4666666666667 3242.6666666666665 494.9333333333334 3396.2666666666664 648.5333333333338L3515.7333333333336 768L3276.7999999999997 1006.9333333333334L3140.2666666666664 887.4666666666667zM3584 2133.3333333333335V1962.6666666666667C3584 1809.0666666666668 3566.933333333333 1655.4666666666667 3515.7333333333336 1501.8666666666668L3464.5333333333333 1331.2000000000003L3788.8 1228.8000000000002L3840 1399.4666666666667C3891.2 1570.1333333333332 3925.3333333333326 1757.8666666666668 3925.3333333333326 1962.6666666666667V2133.3333333333335H3584z" />

Steps to reproduce the behavior

I have a particular icon that causes this reliably. I've referenced how icon-font-buildr is calling into svgicons2svgfont, to create the following minimal reproduction:

https://github.com/zbream/issue-svgicons2svgfont-multiple-unicode

git clone https://github.com/zbream/issue-svgicons2svgfont-multiple-unicode.git
cd issue-svgicons2svgfont-multiple-unicode
npm install
npm run build

Check the output file, out.svg.

Why does this matter?

This causes problems using the final SVG font down the road. For example, the tool svg2ttf converts an SVG font into a TTF font. As part of this, it attemps to dedupe the glyphs in the SVG font. Because these two glyphs are technically different (d does not match), the final TTF ends up with duplicate unexpected glyphs (rotate_right and rotate_right-1) for a single icon.

image

image

Debugging informations

Solution

I believe this can be solved easily, by moving this line of code. For each glyph, we compute d multiple times, one for each unicode entry. Instead, we should bump this up and compute d once per icon. This would eliminate any chance of precision errors showing up between each glyph.