Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

“Constraints” instead of PS or TT hints #43

Closed
jenskutilek opened this issue Nov 4, 2016 · 5 comments
Closed

“Constraints” instead of PS or TT hints #43

jenskutilek opened this issue Nov 4, 2016 · 5 comments

Comments

@jenskutilek
Copy link
Contributor

At the spec meeting after Robothon 2015 I said I would think about how to represent TrueType instructions in the UFO format. After some distractions (like having a baby and changing jobs) and false starts (too literally going along the VTT language) and finally reading Erik’s thoughts on issue #42 I think I finally came up with something I consider a good starting point for discussion.

I’m curious for your comments and thoughts, and have already started to build some example code which is not quite ready yet, but looks promising. CC’ing @typesupply, @LettError, @robmck-ms, @anthrotype, @unified-font-object/ufo-4-researchers, please add further interested parties.

Summary

Neither store literal TT instructions or PS hints in the UFO, as they are too specfic, but store a more abstract system of “constraints” that describe basic relations and measurements in the design of the typeface. From this constraints information, PS hints as well as TT programs can be derived and compiled.

The constraints objects would have a name (which can be referenced from a glyph point label) and a value, and a parent constraint object to realize inheritance like in VTT’s CVT program.

Font-Level Constraints

Some examples for constraints related to vertical dimensions of the typeface:

Name             Value   Parent
-----------------------------------------
baseline             0   None
base_overshoot     -14   baseline
x_height           432   baseline
x_overshoot         14   x_height
cap                644   baseline
sups_bottom       -400   cap
sups_b_overshoot    -8   sups_b_overshoot [1]

And some related to glyph (stem) dimensions:

Name             Value   Parent
-----------------------------------------
main_stem           86   None
main_stem_x         90   main_stem
main_stem_y         80   main_stem
hairline            54   main_stem
hairline_cap_x      66   hairline
hairline_lc_y       50   hairline

If you are familiar with the VTT CVT program, you will notice the similarities. For PS hinting, the values for the blue zones and the stem dicts can be derived from this information.

Each of these constraints should be given a list of glyph group names from the UFO, which could serve as a filter for which constraints an editor will offer for a specific glyph, e.g. different baselines for Latin and Hebrew, different x-height for LC and Small Caps, different stems for Latin and Arabic.

What needs to be figures out is a way to force the constraints to conform with their parent values up to a certain ppm size, as well as user-provided deltas, like in VTT.

Glyph-Level Constraints

What takes the most time in both PS and TT hinting is setting the glyph hint structures (at least for more complicated glyphs where the autohinters don’t produce the optimum results), and especially in TT hinting, setting up the CVT values with inheritance and exceptions (deltas).

We would have to do a reality-check on this, but I think for setting the relationships of points in glyphs we could get away with a very limited set, at least for targeting modern rasterizers.

  • Tie a point by its label to a constraint or to the pixel grid (VTT: X/YAnchor, FL: AlignTop/Bottom)
  • Link two point labels, either with or without referencing a constraint (X/YDist/Move, SingleLinkH/V)
  • Interpolating a series of points between the two outermost referenced points
  • Deltas
Instruction   Point Label(s)               Direction   Constraint
---------------------------------------------------------------------
anchor        E_lower_left                 y           baseline
anchor        e_top                        y           x_overshoot
anchor        e_bottom                     y           base_overshoot
interpolate   e_top e_bottom e_bar_lower   y           None
dist          e_bar_lower e_bar_upper      y           hairline_lc_y

Compiling to Hints/Instructions

On the other hand, the font programs and pre-programs of TT fonts are highly distinct for each available tool producing the final output. FontLab’s fpgm is always the same, Monotype has their standard prep and fpgm, and VTT also brings its own.

But most of the stem links/dists/moves are always treated the same when the byte code is produced. Even the logic to differentiate between the current rasterizer environment will usually be applied in the same way to all applicable VTT Talk instructions.

Storing the constraints and relations of the basic dimensions, and the relationships of points in the glyphs to these constraints or each other, will preserve the part of manual hinting work that was the most time consuming, the product of which you really don’t want to lose and repeat every time a font is updated. And it leaves enough freedom for tools to compile specialised instruction code using proprietary compilers and font-/pre-programs.

Variable Fonts

Well, they need to be mentioned of course ;) The constraint values can be interpolated (probably except for deltas), and if you have set up the constraints in a glyph correctly, you could also use them to modify some segments, like making the ascenders taller, and the rest of the points will interpolate or stay in place. Editors can get this feature "for free" if they have implemented constraints. Something like the power guides in FontLab VI.

Footnotes

[1] The inheritance makes it possible to ensure that e.g. the bottoms of the superscript figures always line up, because the pixel size of the figures is rounded from the already rounded cap height constraint. This is different than if the sups bottom vertical position was rounded freely.

E.g. in FontLab, it’s not possible to set up inheritance between the vertical “alignment zones” or even the flat and round values of one zone. The result is that you see an overshoot in one size, because the bottom value rounds down and the top value rounds up, but no overshoot again in the next bigger size, because now the bottom value rounds up and the top value rounds down.

The math for inheritance is easy:

parent.pixel_value = int(round(parent.font_units_value * ppm / upm))
child.pixel_value = parent.pixel_value + int(round(child.font_units_value * ppm / upm))
@jenskutilek jenskutilek changed the title "Constraints" instead of PS or TT hints “Constraints” instead of PS or TT hints Nov 4, 2016
@schriftgestalt
Copy link

This sound interesting.
The first thing that comes to my mind (because I came across when I set up the structure on how to store hints in Glyphs) is that you need to be able to distinct between TT and PS hints. The PS hints can be reused as TT hints but quite often you need more stuff for TT that would confuse the PS hints.

@jenskutilek
Copy link
Contributor Author

The unscaled constraint values could also be used to constrain stems in outline interpolation, helping to avoid changing stem widths due to rounding errors.

@benkiel
Copy link
Contributor

benkiel commented May 1, 2018

@jenskutilek does #53 close this? I know it's not the same idea, but it is PS hints in UFO

@jenskutilek
Copy link
Contributor Author

As interest in this issue is apparently not very strong, I think we can close this.

@benkiel
Copy link
Contributor

benkiel commented May 2, 2018

@jenskutilek I do think it's interesting, but for now the practical — put what we have into the format seems best (yes, we need this for TTF now too). But, I do think it may be worth a think for a later version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants