Giter VIP home page Giter VIP logo

Comments (21)

RazrFalcon avatar RazrFalcon commented on May 25, 2024 1

@hasenbanck Yes, that font version doesn't mirror d for b. But it doesn't seem like the old font itself have a bug. ttf-parser, freetype and harfbuzz are processing it correctly. Something is missing between ttf-parser and fontdue.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024 1

Sure, I will add such method.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

I can add a glyph_source method which will return the TableName or a specific type. We have 7 glyph sources right now.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

By the way, the font that you have linked doesn't have a CFF table.

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024

Apologies, I assumed it had an OTF table like CFF in it because some of the points are defined in the order expected of the CFF/CFF2 tables.

Here's what I believe is happening: Looking at it closer, some glyphs in this font are defined as an affine transform, for example b is actually just a mirrored d. When this transform happens, ttf-parser is maintaining the the original point order. This is correct for most transforms, but incorrect if the glyph is mirrored over any axis. If mirrored over the x or y axis, OutlineBuilder should be called with the points reversed, if the glyph is mirrored over both axis no change is needed.

I would appreciate the glyph_source method for where the glyph's outline is sourced from. This would remove some ambiguity.

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024

Some extra information on point ordering for TrueType fonts:

image

Contours that need to be filled black must have a clockwise direction. If we want to make a white area inside an existing contour we must make the direction of the new contour counter clockwise. Contour direction is determined by seeing in which direction the point index values increase or decrease. Contour direction is from the smaller point index to the larger. The general rule is that the contour direction should be such that "black is on the right". Using the glyph "O" as an example, the outer contour should travel clockwise, and the inner contour counter clockwise.

For CFF based contours the direction is exactly the opposite, so contours that need to be filled black must have a counter clockwise direction.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024
  1. Can I reproduce this issue with Comfortaa-Regular.ttf?
  2. Can you post a link to the specification were this behavior is explained?
  3. Emitting points in reverse is highly problematic, since we do not allocate, therefore we have to store points on stack first, which is quite limiting.
  4. I will check what freetype does in this case.

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024
  1. Yes

  2. This font may just be out of spec and it should not define this transform. Apple notes the contour order restriction here. It appears stb_truetype will flip the points.
    image

  3. Really only the individual calls in OutlineBuilder need to be reversed. i.e. quad_to/curve_to/line_to

  4. Okay

Also feel free to message me on xi.zulipchat.com if you want.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

Very strange. FreeType produces the same outline, but the points order and values are very different. Looks like the problem not in mirroring, but in the second contour points order.

I will try to write a tool that will help me with debugging this issue tomorrow.

The most interesting part, is that if you export both outlines (ttf-parser one and ft2 one) to SVG, they will be filled equally, while having different points. Here: issue-43-test.zip
This is probably the reason why I'm missed this.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

So I've added points enumeration:

FreeType:

ft

ttf-parser:

ttfp

As you can see, the points order/direction is roughly the same. Looks like FreeType does some slight changes to the output (not rounding). I will have to run FreeType under debugger to figure it out.

PS: this is GID 232 without Y mirroring, i.e. as is.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

So in the end, mirroring and direction are the same as in FreeType. Maybe the problem is somewhere else?

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024

The glyph in question should be 225 'b', which is a transform of 232.

Given this is a glyph from the glyf table, the outer outline should be clockwise for this character b. It may just be that FreeType is correcting it internally. I would be happy to do so in my raster, but I don't have enough information from ttf-parser to do that, since I would need to know the transform performed on the composite glyph on top of the table source of the glyph.

I don't think any solution here is elegant,

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

Here is 225 'b'. The directions is still correct.

FreeType:

ft

ttf-parser:

ttfp

I don't think any solution here is elegant,

First, we have to prove that there are an actual bug.

from ttf-parser.

hasenbanck avatar hasenbanck commented on May 25, 2024

Just as an information. I just downloaded the version from the google fonts directory and this version doesn't seem to have this problem:
https://fonts.google.com/specimen/Comfortaa

So it might very well be that the TTF file in the above repository is just plain broken.

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024

@RazrFalcon Your images are upside down, and also both of your comments for 'b' and 'd' have different windings which illustrates the problem. Your 'd' is counter clockwise and your 'b' is clockwise. There's nothing wrong with fontdue, you're giving me different windings for 'b' and 'd' and there's no way for the raster to know this without knowing information about the transform. Freetype likely holds onto this information given it handles both the parsing and rasterization itself.

I don't think any solution here is elegant

You'll need to expose both the glyph source and transforms applied for each contour to handle this correctly downstream, which is kind of a pain.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

All I was able to find is FT_Outline_Get_Orientation, which indeed returns FT_ORIENTATION_POSTSCRIPT for d and FT_ORIENTATION_TRUETYPE for b. I will see how freetype implements it.

PS: And could you please tone down your demands. This is open source and not a commercial support line.

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024

PS: And could you please tone down your demands. This is open source and not a commercial support line.

Apologies that the last comment came on too strong. I appreciate your work on ttf-parser. I worded the comment to more directly specify the issue in response to "First, we have to prove that there are an actual bug", which felt like a dismissal that there was an issue in the first place.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

Ok. My point was that there is no bug, if all other libraries are doing the same. Which is still true.
I consider this a feature, not a bug. Because the current code is correct. You just want information, which is unnecessary in many cases. Aka optional.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

So FT_Outline_Get_Orientation is very simple. It tires to fill a path and accumulates the final area. That it. So I guess you can implement this on your side. Since in case of ttf-parser we would have to outline the glyph twice or track the area.

Once again, I don't see a bug here. It's a tricky feature with no clear solution. And as far a I can tell, transformations has nothing to with this. You can make such malformed font even without transformations.

Also, looks like it's not glyf specific. CFF also affected.

from ttf-parser.

mooman219 avatar mooman219 commented on May 25, 2024

Thank you for the extra information and context on FreeType's solution. I agree this is a malformed font and not a failure on ttf-parser's side. Given this, I agree that a feature request for exposing the transforms doesn't fix the problem that fonts can just be malformed in a different way to produce the same bad result. I'll take FreeType's approach to guess the orientation based on the sign of the accumulation, which although is undesirable to compute, seems like the only way of actually knowing.

Would the feature request for the glyph source still be reasonable to add in ttf-parser? Right now I'm guessing the source based on the tables present in the font.

from ttf-parser.

RazrFalcon avatar RazrFalcon commented on May 25, 2024

Right now I'm guessing the source based on the tables present in the font.

I think that this is the right way to do this. I've updated the docs. They mention parsing order now.

The problem with glyph_source method is that it's too vague. We have glyph outlining method and raster glyph extraction method. And outlining in case of glyf and variable fonts becomes even more confusing.

Basically, the current implementation is gvar+glyf -> glyf -> cff -> cff2. No fallback.

from ttf-parser.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.