[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ttfautohint — additional feature requests.

From: Werner LEMBERG
Subject: Re: ttfautohint — additional feature requests.
Date: Sat, 08 Feb 2020 00:25:40 +0100 (CET)

Hello Piotr,

finally I have some time to answer your e-mail.  Thanks a lot for your
thoughts, which I have tried to group for easier reading!  Note that
your ideas look quite generic; it probably makes more sense to add
some of your ideas to FreeType's auto-hinter (which would then be
exported to ttfautohint); I'm thus CCing the 'freetype-devel' mailing

> ======
> First of all, handling diagonal stems on the S/s characters.  I've
> actually figured out a way to do it:
> .  It involves there being an interpolate instruction from the top
> of the top and bottom stems to a control point of the top of the
> diagonal stem, and so with the bottoms of stems, and this
> interpolation automatically makes the middle stem hinted to the
> proper weight.

Looks good.  Could you transform this image to some (mathematically
based) algorithm?  Or reformulate it using bytecode instructions?

> It doesn't require two control points to just so happen to be in a
> stem distance.  Therefore, with this method ttfautohint would select
> any of the control points on the top and bottom of the diagonal stem
> and perform the interpolate.

Code would have to be added to the auto-hinter to identify such

> Keep in mind, this is a method for low contrast fonts.  So for high
> stroke contrast font, the diagonal stem would end up thicker than
> the horizontal stems (even if the cvts always specify a single
> pixel), which is actually not right (but still better than the
> current unhinted way).

Please be aware that FreeType's auto-hinter doesn't specifically use
'CVT'; instead, the various stem widths are stored in arrays.

> Keep in mind, ttfautohint will detect stems like this throughout the
> font.  So, in some fonts a similar middle stem is found within the a
> [?].  In this case ttfautohint will hint the diagonal stem.  Chances
> are, if a stem is at a steep angle like this it should have vertical
> hinting.  Implementing this feature will give the hinted font an
> overall smoother look in a ppem size waterfall.  It will make
> rounding stems to two pixels actually look right.

Detecting and handling diagonals would definitely be an improvement.

> Diagonal stems in characters including k, z, x, y, w, M.

Well, yes, but the 'latin' auto-hinter module (also used by
ttfautohint) covers much more scripts.  You thus have to take care of
other scripts, too.

> Those are hinted horizontally.  But watch out.  Keep in mind that
> they are at a different angle, so with calculations (relative to the
> horizontal and vertical stem weights) the points that terminate the
> diagonal stems need to be at a specific horizontal distance.  It
> should be consistent with the horizontal and vertical stem weights —
> especially when those are 1 pixel, where an unhinted stem stands
> out.  You could have various diagonal cvts that would determine the
> horizontal distances for diagonal stems at various angles.

You mean precomputed values?

> For bilevel optimized hinting, be sure to keep them 1 pixel if the
> horizontal and vertical weight is 1 pixel, this way in bilevel
> rendering they will roughly produce a 1 pixel stem.

This case we don't have to consider, since FreeType (and thus
ttfautohint) doesn't support bi-level hinting.  While there is some
very rudimentary code for B/W hinting in the auto-hinter, it is never
active because the results are so ugly.

While the current increase of computing power would allow for better
algorithms to handle B/W auto-hinting, it becomes moot at the same
time because the increase of today's screen resolution even for the
cheapest displays makes hinting unnecessary, more or less.

> In all other cases, they don't have to be integer, but should jump
> when the corresponding horizontal or vertical stem weight jumps
> rather than gradually increasing (which would defeat the point of
> the cvt).
> ======
> Another problem I've seen is with the character 1.  It has a
> diagonal stem in it, closer to horizontal, but ttfautohint doesn't
> recognize this.  It is a more subtle error than the S/s as the
> thickness doesn't inversely scale with the other stems.  In this
> case, the solution would be the same as the previous section: use a
> cvt of the proper angle and hint vertically with it.

There is a major issue: Right now, the auto-hinter is completely
agnostic of scripts.  In other words, it doesn't know what features of
a glyph must be preserved to get good hinting.  There have been ideas
to build script-specific databases that contain such knowledge (for
example, telling the auto-hinter that the dot in letters 'i' and 'j'
must always be cleanly separated from the base stem), but nobody
implemented that yet.

As far as I can see, your suggested improvement of handling character
'1' would be a case of such a database entry, since it can't be
applied globally – there might be scripts where your suggestion
pronounces the small diagonal stem far too much.

> ======
> Width control: In proportional fonts, horizontal hinting may change
> widths.

Not with FreeType's auto-hinter that gets used by ttfautohint!  The
widths are always identical to the original ones.

> This is used when the horizontal hints don't add up, so the hinter
> decides that the width should narrow or widen with that rounding.

FreeType calls such a mode 'strong auto-hinting'.  What ttfautohint
uses is 'light auto-hinting' (which doesn't change the glyph widths).
Note that the light auto-hinting mode also comes with a special
feature called 'warping' that can be activated at runtime (provided
the feature is compiled into the library); it tries to slightly shift
glyphs horizontally to make vertical stems align on the grid as much
as possible.  Warping also slightly adjusts glyph widths.

> Width control is to enforce a rounded version of the original width
> (preventing any other hints from influencing that), and then match
> the horizontal hints to that width for every size, this way
> horizontal hinting is useful for monospaced fonts as well.

Certainly, but the auto-hinter doesn't support it ...

> You might encounter some tricky situations. For example, if the
> character m is 7 pixels wide on a monospaced font, and the x-height
> is 7 pixels, it can be difficult to find which stem pattern is the
> best; if each counter is 2 pixels the m has no spacing, so each
> counter is perhaps 1 pixel, or etc. .  It's even more difficult with
> a bold font, where the horizontal stem weight is 2 pixels.  And,
> say, 9ppem has a width of 5 pixels, even those situations have to be
> handled by ttfautohint, to hint a suitable bold for 9ppem.  Some
> fonts, such as Arial, give up on an actual bold on 9ppem and 10ppem.
> Other fonts, such as Times New Roman, heavily distort the font to
> fit in the two pixel stems.  Keep on thinking of ways to hint!

... and probably never will support it except some volunteer is going
to implement it.  As mentioned above, I consider this not very useful

> ======
> Bilevel hinting: After figuring out the stem weights to balance the
> contrast while rounding to integer, and hinting all stems, for sizes
> that use all one pixel stems figure out what flawed pixel patterns
> remain (dropout curves or doubled diagonals) and attempt to utilize
> deltas on the nearby points to fix them, selecting the pixel pattern
> that's closest to the outline before deltaing.

While ttfautohint supports delta instructions to shift points
vertically, ...

> The default behavior would then be utilizing this delta algorithm
> among the sizes that have both stem weights 1 pixel, then disable
> anti-aliasing for those sizes.  The standard is to optimize down to
> 9 ppem, but the user might as well also enable to try and find
> optimizations for 8ppem and 7ppem as well.

... its use is again restricted to AA hinting only.

It's not clear to me why you are concentrating so much on hinting at
such small sizes.  As the old MS core fonts (Times, Arial, Palatino)
have demonstrated, it is an incredible amount of work to do this
correctly.  Note also that MS abandoned B/W hinting for characters
that have been added later to the core fonts.  This means that today
only a small fraction of the glyphs in those fonts actually do work
correctly with B/W hinting.

For such small sizes, a cheaper, probably better, and definitely much
easier solution is to create embedded bitmaps and/or pixmaps, the
latter using a low number of gray values.  A few years ago I visited
the famous Morisawa company in Japan, which produces probably the best
Japanese fonts.  In one department there were a bunch of people who
created such pixmaps of CJK characters.  In other words, this *is*
used, at least for CJK glyphs, and I don't see why this can't be used
for non-CJK scripts, too.

> Extreme scenario handling: Utilizing bilevel optimized hinting, how
> to hint the letter m in DMCA Sans Serif Condensed Bold (which is of
> course monospaced) in 9ppem and 10ppem, both having a width of four
> pixels?  The Bold should also be distinct from the Regular.

You would be able to use such hinted fonts for screen-display only,
for example, to display menus.  If you want to have something similar
to WYSIWYG, such hints are completely useless.

While FreeType tries to render bi-level hinting as good as possible
(in v35 mode), there is no support on the auto-hinter side to generate
such hints.

> ======
> Cvt cut in: It is a feature of Visual TrueType to adjust this per
> size.  A cvt gets discarded if its rounded value is more than the
> cvt cut-in off from the actual amount of pixels of the stem.
> Implementing hinting as VTT instructions will help when implementing
> the VTT source export feature.  I do recommend implementing the VTT
> source export feature.

I'm not well enough acquainted with VTT stuff.  If you want to
contribute code to ttfautohint, you are very welcomed!

> Unify the blue zones for ascenders and descenders if possible by the
> font design.  Because some fonts have them the same, or within 1
> unit, etc. it makes for consistent hinting.

This I don't understand.  Please elaborate and give an example.

> Width delta: The monospaced width becomes a cvt rounded to an
> integer, and the user can choose to delta it.  By default, this
> feature is not used.

No idea what you are talking about.  What feature do you mean?

> When deltaing a width and horizontally hinting, ttfautohint must
> ensure to do the width control feature to the new width.

Again, you are talking about hinting modes that are not supported by
ttfautohint.  I don't plan to add more along this direction, but I'm
open to integrate submitted code by volunteers...

> ClearType optimized hinting: If the renderer is detected as
> grayscale but not bilevel, use poor quality hinting.

???  WHat exactly do you mean?

> This will encourage the user to use ClearType, and the font will
> easily sell to Microsoft.  Such fonts on grayscale rendering tend to
> use exaggerated stem weight horizontally that has only the left side
> of the stem rounded to integer.  In GDI, when ClearType is disabled
> the renderer is classic GDI.  Classic GDI is a hybrid, using
> grayscale rendering with 4×4 oversampling if gasp enabled
> anti-aliasing, and bilevel rendering if gasp disables anti-aliasing.

Yes, these are known facts but what do you want to suggest?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]