golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.32k stars 17.47k forks source link

proposal: x/image/font: add sTypoAscent and sTypoDescent #68394

Open zhuowenchen opened 1 month ago

zhuowenchen commented 1 month ago

Proposal Details

Now we will parse the ascender and descender in the hhea table of the font file, but this is not enough. According to the protocol description, the ascender and descender in the hhea table are applied to the apple platform, while the applications developed based on the windows platform require the ascender and descender to parse the sTypoAscender and sTypoDescender in the os2 table. (https://learn.microsoft.com/en-us/typography/opentype/spec/hheaimage However, our library does not provide such support. Can the sTypoAscender and sTypoDescender in the os2 table be added to the parse in the sfnt/sfnt.go file of golang.org/x/image/font/sfnt/? The structure of the os2 table is described in this document, which contains the required sTypoAscender and sTypoDescender.(https://learn.microsoft.com/da-dk/typography/opentype/spec/os2

zhuowenchen commented 1 month ago

We can obtain sTypoAscent and sTypoDescent as follows.And exponse them to golang.org/x/images/font/font.go. image

ianlancetaylor commented 1 month ago

CC @nigeltao

nigeltao commented 1 month ago

What does FreeType do when you ask it for a font's ascent?

zhuowenchen commented 1 month ago

oh,I gave it a try and it would return the same value to me.It seems to be working correctly.

zhuowenchen commented 1 month ago

But my point is not to indicate that there is a problem with obtaining ascent. I mean that in some occasions we may need sTypoAscent.Should we provide an API to obtain sTypoAscender?

zhuowenchen commented 1 month ago

I tried to view the FreeType source code, and it seems that they have parsed sTypoAscender.

image
nigeltao commented 1 month ago

Sorry for not being clearer. FreeType parses os2.sTypoAscender (https://github.com/freetype/freetype/blob/1452355de99d22b0cba6ccc17bf5cdf3682ef61e/src/sfnt/ttload.c#L1193) but it also parses hhea.Ascender (https://github.com/freetype/freetype/blob/1452355de99d22b0cba6ccc17bf5cdf3682ef61e/src/sfnt/ttmtx.c#L143).

My question is, as it parses both, which one does FreeType prefer when you ask it for a font's ascent?

zhuowenchen commented 1 month ago

I tried it. The FreeType will return the value which is parsed from hhea.Ascender when i ask it for a font's ascent.

zhuowenchen commented 1 month ago

Now, x/image/font return the same value. There is no problem in this logic. I mean sometimes we need the sTypoAscender, but now x/image/font can not support that. Maybe we could provide a new field which is named sTypoAscender in class Face or we could provide other ways to get sTypoAscender?

zhuowenchen commented 1 month ago

What do you think of this proposal? If you are busy here, or let me submit the code and you help review it. I really want to be a code contributor, haha🤣

nigeltao commented 1 month ago

Maybe we could provide a new field which is named sTypoAscender in class Face

font.Face and font.Metrics aren't specific to TrueType / OpenType. I'd rather not add something TTF-specific like sTypoAscender to that more-general font package. Maybe the sfnt package is a better place to contain that change, but I'm hesitant to provide two APIs for ascent before better understanding the motivation.

Can you elaborate on what you're eventually trying to do such that using OS_2.sTypoAscender works for you but using hhea.ascent does not?

Can you link to an example ttf file that demonstrates this?

zhuowenchen commented 1 month ago

Can you elaborate on what you're eventually trying to do such that using OS_2.sTypoAscender works for you but using hhea.ascent does not?

Sorry,I miss the message for a few day. Now , I have 2 services , which is called A and the other is called B (calling them A and B is just for easy understanding).Service A is written in C++,it uses OS_2.sTypoAscender to render the font. The OS_2.sTypoAscender is got by this method https://github.com/nothings/stb/blob/master/stb_truetype.h#L2641. However, service B is written in Go, so it cannot parse os_2.sTypoAscender now. If hhea.Ascender is used, it will cause the size of the rendered font to be different from that rendered by service A.The difference between them will cause some errors.

zhuowenchen commented 1 month ago

Can you link to an example ttf file that demonstrates this?

站酷庆科黄油体.ttf.zip Let's take this file as an example. If we parse hhea.ascender, we will get 854. But if we parse os2.sTypoAscender, we will get 750. This gap will cause a difference in the size of the font we render.