Closed yisibl closed 3 years ago
I found that if the accuracy is greater than 0.153
, there will be problems. Can we use a smaller accuracy?
https://github.com/fontello/svg2ttf/blob/d8a426247c6f61b00e4cdd5bd36ec0c57b404444/index.js#L167-L171
I found that if the accuracy is greater than
0.153
, there will be problems. Can we use a smaller accuracy?
There are no clear criteria how to select accuracy. Without criteria, this is "magical number". Tuning magical numbers is not good idea.
I'd suggest 2 alternate approaches:
Increasing existing accuracy demand will cause increase of segments (=> font size) and is not nice.
Or... if you know better accuracy criteria - that's discussable. I'm sure, better algorythm possible, but had no time to investigate.
I mean, visual criteria is ~ obvious. Visual error should be < 0.5px for 1000*1000px bounding box. But turning that into math metrics is not so easy.
Are there any side effects of smaller accuracy? I cannot change the SVG source files, because these are uploaded by other users. There should be many similar SVG files on our platform, and many of them are historical data.
Maybe we can change the calculation method of usWinAscent, in nanoemoji os2.usWinAscent = ascender + linegap
, yMax is not currently considered.
In terms of vertical measurement, do icons need to consider clipping?
# These are ufo2ft's fallback WinAscent/WinDescent, good enough for now.
# https://github.com/googlefonts/ufo2ft/blob/a5267d135d5a8dba7e6a5d3ac44139afa6159429/Lib/ufo2ft/fontInfoData.py#L241-L247
# TODO: Set to the actual global yMin/yMax to prevent any clipping?
assert os2.usWinAscent == ascender + linegap
assert os2.usWinDescent == abs(descender) # always positive
This is svg2ttf: https://github.com/fontello/svg2ttf/blob/d8a426247c6f61b00e4cdd5bd36ec0c57b404444/lib/ttf/tables/os2.js#L62-L67
In addition, cu2qu uses 0.001
as the default approximation error: https://github.com/googlefonts/cu2qu/issues/76
@anthrotype is an expert in fonts, I hope he can provide some help.
Are there any side effects of smaller accuracy?
Yes. Smaller accuracy => more splits => higher font size. Problem is, everybody will be affected, and you will not give any guarantees. It will be still possible to draw crazy arc or third-order bezier curve to break everything.
Ideally, "accuracy" should depend on concrete segment.
I cannot change the SVG source files, because these are uploaded by other users. There should be many similar SVG files on our platform, and many of them are historical data.
If you don't care about font size, you can set TTF glyph height to ~ 4000 instead of 500-1000 as you have now. Result will be similar as accuracy value change. You can scale your src by svgpath
without loss of precision.
I'm open to any alternate suggestions with strong math background. It would be nice to drop use of current "magical values".
This is the original SVG file. Is it because the size is too small (8x10)? If so, can we use different accuracy number when the SVG size is small?
<svg width="8" height="10" viewBox="0 0 8 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g fill="none" fill-rule="evenodd">
<path d="M4.537 9.417V1.979c0-.002.003-.003.003-.002l2.537 2.807c.133.146.33.207.516.158a.552.552 0 0 0 .386-.396.596.596 0 0 0-.129-.553L4.397.173A.524.524 0 0 0 4.011 0a.524.524 0 0 0-.386.174L.15 4.013A.588.588 0 0 0 0 4.42a.584.584 0 0 0 .165.4c.214.217.552.21.758-.016L3.46 1.999h.003v7.43c0 .305.223.552.502.57.15.008.296-.05.404-.16a.598.598 0 0 0 .167-.422z" fill="#41D2D9" />
</g>
</svg>
Another idea is that we can get the SVG BoundingBox, calculate the height, and then make usWinAscent
not greater than the BoundingBox's height. Is this feasible?
This is the original SVG file. Is it because the size is too small (8x10)? If so, can we use different accuracy number when the SVG size is small?
Since font glyph usually are 500*500...4000*4000 int px, better approach would be to scale up your image BEFORE converting to second order bezier and rounding. Use svgpath
for that.
Another idea is that we can get the SVG BoundingBox, calculate the height, and then make usWinAscent not greater than the BoundingBox's height. Is this feasible?
Problem is not with bounding box, but with processing of third order bezier & arcs. It's technically possible write those such way to break any static limit (then, after rounding you will get something bad).
Found a new issue, this font cannot be displayed in Mac Chrome and Firefox. https://at.alicdn.com/t/project/37546/21049af9-0257-43a6-8c7e-2fd08733737d.html
Chrome DevTools says: OTS parsing error: head: Failed to parse table
@yisibl if that's not related to current issue, please fill new one. With minimalistic sample how to reproduce (source SVG + reduce glyphs count as much as possible). You provided only final result, but without proof why this is caused by svg2ttf (i don't decline, but there may be multiple reasons of broken fonts).
PS. FF shows more concrete error: downloadable font: head: Bad x dimension in the font bounding box (-39, -13440) (font-family: "iconfont" style:normal weight:400 stretch:100 src index:2) source: https://at.alicdn.com/t/font_37546_hgtmiiq9vft.woff?t=1620616818531
@yisibl if that's not related to current issue, please fill new one. With minimalistic sample how to reproduce (source SVG + reduce glyphs count as much as possible). You provided only final result, but without proof why this is caused by svg2ttf (i don't decline, but there may be multiple reasons of broken fonts).
PS. FF shows more concrete error:
downloadable font: head: Bad x dimension in the font bounding box (-39, -13440) (font-family: "iconfont" style:normal weight:400 stretch:100 src index:2) source: https://at.alicdn.com/t/font_37546_hgtmiiq9vft.woff?t=1620616818531
I have tried some fixes here. If the above problem cannot be solved, I will reopen an issue. https://github.com/fontello/svg2ttf/pull/102/commits/46c0df27ad44936c16e94fa67a5a3694afde8a89
In any case, too large usWinAscent and usWinDescent is definitely a problem.
fontbakery check-notofonts iconfont.ttf
output:
Rationale: A font's winAscent and winDescent values should be greater than the head table's yMax, abs(yMin) values. If they are less than these values, clipping can occur on Windows platforms (https://github.com/RedHatBrand/Overpass/issues/33).
If the font includes tall/deep writing systems such as Arabic or
Devanagari, the winAscent and winDescent can be greater than the yMax and
abs(yMin) to accommodate vowel marks.
When the win Metrics are significantly greater than the upm, the
linespacing can appear too loose. To counteract this, enabling the OS/2
fsSelection bit 7 (Use_Typo_Metrics), will force Windows to use the OS/2
typo values instead. This means the font developer can control the
linespacing with the typo values, whilst avoiding clipping by setting the
win values to values greater than the yMax and abs(yMin).
FAIL: OS/2.usWinDescent value 38262 is too large. It should be less than double the yMin. Current absolute yMin value is 727 [code: descent] FAIL: ots-sanitize returned an error code (1). Output follows: ERROR: head: Bad x dimension in the font bounding box (-39, -13440) ERROR: head: Failed to parse table Failed to sanitize file!
Some users have encountered similar problems a long time ago: https://github.com/thx/iconfont-plus/issues/661
In the result returned by cubic2quad, 32147.26312251112 is abnormal. [ 'Q', 566.970047, 32147.26312251112, 567.27723, 693.5669409999996 ]
That is an error in cubic2quad error detection algorithm. Right over here:
https://github.com/fontello/cubic2quad/blob/master/index.js#L198-L199
We check every(ish) point on the cubic curve to match quadratic. We do not check any point on the quadratic curve to match cubic.
The problem is: if middle point of cubic curve is within error from its origin, approximation will be good no matter what (quadratic control point may be on the moon for all it cares).
Nice picture here:
Your SVG file has all 4 cubic curve points very close together, so the difference between them falls well within the accuracy.
console.log(require('cubic2quad')(566.970047,693.362153,566.970047,693.566941,567.277229,693.669335,567.27723,693.566941,1))
Here's the exact curve:
<!DOCTYPE html>
<html>
<body>
<svg height="600" width="600" viewBox="566.5 693 1 2">
<circle id="pointA" cx="566.970047" cy="693.566941" r="0.01" />
<circle id="pointB" cx="567.277229" cy="693.669335" r="0.01" /> </g>
<path d="M 566.970047 693.362153 C 566.970047 693.566941 567.277229 693.669335 567.27723 693.566941" stroke="red" stroke-width="0.005" fill="none" />
<path d="M 566.970047 693.362153 Q 566.970047 32147.26312251112 567.27723 693.5669409999996" stroke="blue" stroke-width="0.005" fill="none" />
</svg>
</body>
</html>
try here: https://www.w3schools.com/graphics/tryit.asp?filename=trysvg_path2
fixed in fontello/cubic2quad@44c53ad
Awesome, thank you for your amazing work!
I update a test case that caused the error:
head.yMin = 27274
head.xMax = -13440
I update a test case that caused the error:
What is this test for? Does it still show any issues after cubic2quad update?
@rlidwka This is used to test the version of cubic2quad before 1.2.0. see also: https://github.com/yisibl/svg2ttf/pull/1/files#diff-a561630bb56b82342bc66697aee2ad96efddcbc9d150665abd6fb7ecb7c0ab2fR246-R260
svg2ttf must have more test cases based on font tables.
I have deployed to pre-release for testing(usWinAscent/usWinDescent does not depend on the value of yMax/yMin), and it seems to be completely resolved. The generated ttf
file is also smaller.
before: https://at.alicdn.com/t/project/37546/21049af9-0257-43a6-8c7e-2fd08733737d.html after: https://at.alicdn.com/t/project/37546/f49c07e1-448c-4e92-80a0-7544b91a29e8.html
Can we close this?
Can we close this?
Need to wait, please let me test it online for a few days.
I encountered a new failed test case: https://github.com/yisibl/svg2ttf/pull/1/commits/56b273660993af64057cd1787d68baf0cf6b43e6
@rlidwka PTAL, thanks!
@yisibl in your example glyph has the following instruction near the end of the path:
a86173505653221920 86173505653221920 0 0 1 34.50966791-4.60128904
Does this arc have a good reason to be there? Looks like an error in the test file.
@yisibl in your example glyph has the following instruction near the end of the path:
a86173505653221920 86173505653221920 0 0 1 34.50966791-4.60128904
Does this arc have a good reason to be there? Looks like an error in the test file.
Yes, we have some icons with very strange paths. This causes the generated font to fail the ots check, and an error will be reported in Chrome.
I think for this kind of SVG should throw an error.
Here is another example: https://at.alicdn.com/t/project/2567398/0794db68-7c83-4d28-8e2f-0dc819833051.html Test SVG font in: https://github.com/yisibl/svg2ttf/pull/2/files#diff-3ec56eb2d7d4c0768bcdb3b4db2508775c2efb3cfb976c7f09f8618aa2ab291d
I think for this kind of SVG should throw an error.
I do not agree.
Also, i'd suggest to focus on release, instead of "new features". Let's solve minimal mandatory set - svg2ttf should produce good result from good data. Is current master ok or something was missed?
@puzrin I think 5.3 can be released. Special SVG errors can wait for me to write test cases more concisely and concretely.
Thanks. I will release.
After thinking a bit, we could use some of chrome/mozilla criteria to check obvious (most annoying) artefacts:
Can you test that somehow? I mean, create dummy svg with small square and move that square to up/down/left/right until chrome/mozilla fails?
Released 6.0.0, also added special thanks to changelog.
As far as i understand, we have 3 pending issues with notable added value:
name
table
head
table value)
If nothing critical missed, I'd suggest consider close existing issues/prs as "too noisy" and create new ones (more organized) to discuss details.
Thank you very much for your summary, let us discuss it in a separate issue.
This will cause the line height in Windows to be too large. https://github.com/thx/iconfont-plus/issues/1953#issuecomment-834044570
I guess it is a problem introduced by(v2.1.0) https://github.com/fontello/svg2ttf/issues/25 , and there is a problem with the conversion of the cubic2quad module.
In the result returned by cubic2quad,
32147.26312251112
is abnormal.[ 'Q', 566.970047, 32147.26312251112, 567.27723, 693.5669409999996 ]
https://github.com/fontello/svg2ttf/blob/df30be9043ccb9d00e1c9087b21f084a8fface4f/lib/svg.js#L96-L111
Test file and test case in:
https://github.com/fontello/svg2ttf/pull/102/commits/ae425be18907eb9e93ceca2ecfd8ac73dcba77fd
TTX file