Calling all Hinting Programming Gurus

hrant's picture

What would it take to write a utility (or possibly Python code)
that takes two outline-compatible TT fonts, let's call them Main
and Alternate, and creates one TT font that's essentially Main
but with hinting to make it be Alternate at a given PPEM?

hhp

John Hudson's picture

So what you want is a set of hints that distort the normal outlines to match the bitmaps that result from the outlines of the Alternate outlines at a given size?

hrant's picture

That would just be superhinting. What I'd like:
1) Does the hinting for you.
2) Works from outline fonts, without "external" references like bitmaps.
3) Most of all: isn't limited to screen rendering needs...

--

BTW, I should have said "at a given PPEM range".

hhp

hankzane's picture

I'd like to see code that will design a typeface for me!

hrant's picture

This isn't nearly that bad. The code doesn't have to be smart - not at all. All it has to do is deploy hinting that makes the points of the Main font become the points of the Alternate when the PPEM is within a certain range (including a single PPEM* in the case of bitmap rendering).

* Or actually, a set of single PPEMs, to get multiple bitmaps in one outline font.

hhp

hankzane's picture

What kind of hinting are we talking about?

hrant's picture

The kind that moves points around?

hhp

hankzane's picture

Ah, so you're not talking about hinting in the traditional sense. You simply want outline substitution?

John Hudson's picture

Yes, I did understand your desired process correctly. I just wanted to be sure what the result was supposed to be.

The short answer is no, I don't think there is a way to do this.

The results of gridfitting are size-specific, so at best you would get an outline correspondence at one size only. Delta hints are expressed, obviously, as deltas to the unadjusted position, not as target point positions. You are saying 'Move this point a distance from its current position', not 'Move this point to this location', and since the delta technology was designed to turn whole pixels on or off the units are quite crude. Even if you knew exactly what the target position was, in xy coordinates from your alternate outline, the chance of being able to hit it precisely with hinting is very remote, unless that alternate outline had been designed very precisely for a particular ppem size.

I think Sergej is right, and what you are looking for is outline substitution. No idea if that is possible.

hrant's picture

> Delta hints are expressed, obviously, as deltas to
> the unadjusted position, not as target point positions.

Sure. But how does this make it impossible?
You measure the difference between the points,
and you move the Main points by that amount.

Also: Deltas are applied per PPEM, right? So, just like you
do in 1-bit, you have sets of deltas that make a glyph come
out right for each point size.

> unless that alternate outline had been
> designed very precisely for a particular ppem size.

It has.
It's designed to 1/4 pixels in each dimension.

> since the delta technology was designed to turn whole pixels on or off

But I was pretty sure that it was ammended to address partial pixels, no?

--

What I'm describing can be done manually, I'm pretty sure.
The question is, how hard would it be to automate it based
on a explicit outline pair? In the worst case, a low-level
utility would have to be written to do with the TT code as
it pleases (which would be too much work, unless somebody
were to process truck-loads of such fonts). In the best case, I
suspect Python could be made to splice in the needed hints, no?

hhp

vinceconnare's picture

you can't mix tt code and composite code unfortunately so you can't use say an if statement and select one glyph or another.

sort of like that. But VTT does not allow it since composite commands for glyphs are different than normal tt instructions. You can use some tt code in composites. But you can't mix the 2 apparently like below.

USEMYMETRICS[]
OVERLAP[]
OFFSET[R],35,0,0
#PUSHOFF
#PUSH, 28
MPPEM[]
IF[]
OVERLAP[]
OFFSET[R],380,319,0
ELSE[]
OVERLAP[]
OFFSET[R],381,319,0
EIF[]

hrant's picture

I think you've overshot my grasp of all this. Patience, please! :-)
I'd rather not get into outline subbing though.

OK, let me ask this:
1) Can't you use something like VTT to take the Main font, choose a PPEM, and manually move the points so you get the points of the Alternate?
2) Can't this difference information be extracted from comparing the two outlines?

If the answer to both those is Yes, shouldn't it be possible to write some code that takes the Main font, observes its differences with the Alternate font, is given a PPEM, and with all that info generates a font like I'm saying?

hhp

vinceconnare's picture

MPPEM[] returns the PPEM
the instruction for PointSize doesn't work and is useless since size is dependant on resolution.

So yes you can check what PPEM you are at and do something. I wrote a function that flattens flairs on a contour until a specified distance is reached (in 64ths of a pixel). Usually sometihng like 2 pixels.

/* Function 81 TAKES 3 ARGUMENTS, aligns a point until a specific distance is reached.Used for flares. First link p1 to p2, then call the function. VC Dec 11,1995*/
/* CALL[], amt, p1, p2, 81 ... amt is in 64ths, p1 is start pt, p2 is point moved, 81 is function# */
FDEF[], 81
#BEGIN
#PUSHOFF
DUP[]
ROLL[]
SWAP[]
MD[N]
ABS[]
ROLL[]
SWAP[]
GTEQ[]
IF[]
ALIGNRP[]
ELSE[]
POP[]
EIF[]
#END
#PUSHON
ENDF[]

point related instructions are here:
http://www.microsoft.com/typography/tt/ttf_spec/ttch06b.doc

Also the instruction I was thinking of before was 'FLIPPT[]' Flip point which will make an on curve point an off curve point and the other way around. That way you don't have curves just straight lines everywhere, easier to put on grid boundries.

The TrueType instruction set was not designed to do what you are asking. But you can, at a certain PPEM use one CVT (control value) for small sizes (using MIAP and setting it to not look at the cut-in limit), an X height for instance, and then use a smaller one for larger print sizes. You could also move points or use larger CVT values to thicken up the stems at smaller sizes.

But using instructions in a heavy handed way is always dangerous since they might not get used by some devices. (like some printers)

TrueType has the ability to manipulate outlines using a matrix but its implementation doesn't always support this. Ie. Hp Deskjets back in the early 1990's couldn't handle flipped glyphs or scaled glyphs. In theory the SOFFSET let's you skew, scale, or flip. FontLab will output a composite in TTF using the SOFFSET if you flip or scale it.

vinceconnare's picture

fun flipping fun...

FLIPRGON[],0,42
turns all the points into on curve points 'vectorizing' the outline. (the mid 1980's digital typesetters used straight line vectors to create curves, Ikarus followed making curvilinear outlines)

vinceconnare's picture


the left images is 24 PPEM, it uses a CVT that is 2 times (418 UnitsPerEM) that of the outline distance (209 UPEM). the right is 25PPEM it uses the actual value

/* previously the glyph is hinted as normal then this */
<\code>
#PUSHOFF /* set instructions to manual mode */
MPPEM[] /* get the ppem size */
#PUSH, 24 /* this is the size I want to change */
EQ[] /* are they equal ? */
IF[] /* if true do this */
#PUSHON /* set instructions to automatic mode */
#BEGIN /* begin block */
SVTCA[X] /* set direction to X */
SRP0[], 5 /* start link at pt 5 */
MIRP[m>RBl], 36, 192 /* link pt 5 to pt 36 using cvt 192 */
SRP0[], 14 /* start a link from pt 14 */
MIRP[m>RBl], 26, 192 /* link from 14 to 26, using cvt 192 */
IUP[X] /* interpolate all the other points in X */
#END
EIF[]
<\code>

vinceconnare's picture

the only problem with doing this kind of thing is that the screen size will not represent the printer output. You could use embedding bitmaps to solve that at the main sizes. if you really wanted to.

Does that prove you can manipulate the glyph at certain sizes for you ?

hrant's picture

Vincent, thanks for all this. DM is lucky to have you.

First, some asides:

> the instruction for PointSize doesn’t work and
> is useless since size is dependant on resolution.

Unless there's a way for the font to find
out the OS's nominal resolution setting...
Is there?

Speaking of fonts detecting things: did I read you mention
that there's a way for a font to check if CT is on or not?

> in 64ths of a pixel

BTW, why such a fine scale? I thought Windows (for one) uses
only 16 shades of gray when rendering gs fonts, which would
mean 1/4 pixels (in each dimension) should be enough, no?

--

> FLIPPT[] ... straight lines everywhere

Useful!
BTW, you could nick-name that process "Downerize". :-)

> thicken up the stems at smaller sizes.

Heh, heh - you're reading my mind concering my #3 above...

> using instructions in a heavy handed way is always
> dangerous since they might not get used by some devices.

But if they're ignored, what's the worst that can happen?
Won't you just get what you were going to anyway, like in
the case of bitmap tuning you'd revert to the fuzzy stuff.

Or are you saying that some instructions wouldn't
work but some would so you'd get a hodge-podge?

> it uses a CVT that is 2 times (418 UnitsPerEM) that of the outline distance

You're talking about the CVT that controls curve widths I see.

So it's all looking possible, eh?

Now, what would it take to automate this, and tweak the CVTs using data
from the differences between two (outline-compatible) outline fonts?

> You could use embedding bitmaps

I'm actually a big fan of embedded bitmaps, and have a few fonts that way, like Arasan*. But besides the fact that they don't work on MacOS**, the critical thing is that they don't handle grayscale bitmaps. Or actually, I've been told they do, but after trying for a while I had to give up. In my best effort I did get grays, but they were totally off in value. On the other hand, I was using a beta of BitFonter, and maybe the later versions made some fix? I asked the Pyrus boys about this a few times a while back, but never got a convincing reply (which is pretty rare for them).

* http://www.themicrofoundry.com/f_arasan.html

** Not that hints work these days either I guess... :-/

hhp

vinceconnare's picture

>Speaking of fonts detecting things: did I read you mention
>that there’s a way for a font to check if CT is on or not?

You can use VTT functions that were used for grey or binary to do CT delta like hinting. But you have to add to one of the functions and know the settings and add to the function.

CVTs are control values. You use them for heights or stem widths. So you could in theory thicken up all the stems at small sizes for small text use and increase the xheight but then use others for normal text sizes.

>64ths
the Truetype spec measures distances in 64ths of a pixel.

>Or are you saying that some instructions wouldn’t
>work but some would so you’d get a hodge-podge?

none would work or all would. example: Bitstream's Font Fusion has modes so it sometimes might not use the hints. It depends how it's set up.
http://www.bitstream.com/font_rendering/products/font_fusion/ffoverview....

You can't read between fonts. The code in the font is internal. What you want to do is outside of the scope of a font file. It's part of the rasterizer or a state engine.

QuickDraw GX supported morphing images. In 1992 at the Apple Safari Erik and Just showed Trixie being tweeked to be lighter or darker depending if the ribbon was new or old.

I morped a symbol USA font to change into fire krackers. This was done by QuickDraw GX and very useless.

OpenType was to solve more serious problems such as ones in languages. It was decided that solving Asian font issues, for instance was more important than if you could make an 'A' thicker.

hrant's picture

> you could in theory thicken up all the stems
> at small sizes for small text use and ...

Cool. Here's a cruncher:
Could you also vary set-widths?

And if so, what would the consequences be for line-break flows,
correspondences between screen and print, and who knows what else?

What kind of stuff would hit the fan if a
font were hinted to set to a different
width at certain PPEMs?

> What you want to do is outside of the scope of a font file.

Sure. In fact I'd be shocked if a font could like contain
two fonts, take measurements between them, adjust itself, etc.

Like I said at the very beginning, what I'd like is an external
app/utility, but maybe hopefully just Python code, that creates
a new font with its "custom" hinting, based on the input of a
general font and a PPEM-specific font (the two outline-compatible).

So if you think it's doable, what would it take, effort-wise?

hhp

vinceconnare's picture

>And if so, what would the consequences be for line-break flows,
>correspondences between screen and print, and who knows what else?

non linear hinting of widths has been a part of TrueType since the beginning. Bitmaps are often on larger widths at small sizes than they would be if it's width value was calculated for that size linearly.

when we made Tahoma I had to support Matthew Carter and Tom Rickner by giving them (or Matthew) the escapements for some of the core bitmap fonts that were part of Windows, (I made most of the original bitmaps for Tahoma for Windows). The old system bitmap fonts (like all) do not scale linearly ie. the 'space' might be 3 pixels at 9ppem, 4 pixels at 10ppem, then 3 at 11ppem. Often the 'l' or 'i' needs to be more than 1 pixel wide or it crashes with other characters and doesn't centre so you make it's width one bigger.

the 'hdmx' is there to speed up line layout. Also there is always some give and take in page layout the screen is just a representation of the printed page and simulates a point size.

hrant's picture

Sure*, but you're talking about one pixel here, offset by one pixel there, with the overall average about the same.** I'm talking about all the glyphs rendering out 1, 2, or more pixels wider (for smaller sizes) onscreen than their print "originals".

* Although "non-linear" isn't the term I'd use.

** With each app apparently choosing whether to use the integer (hinted) bitmap widths to set a line (like WordPad) or the -cumulative- actual (non-hinted) outline widths (like Word); the latter to ensure linebreak (and justification) consistency with print, but causing the occasional bad spacing (including collisions).

> I made most of the original bitmaps for Tahoma for Windows

Wait a second. And Tahoma came before Verdana (plus their blackbody bitmaps are identical anyway). So you're saying all this time we've been told incorrectly that Carter made the bitmaps (or am I remembering wrong).

hhp

dberlow's picture

Hrant, is looking for the resolution axis of a Variation font. No doubt about it.

hrant's picture

Ideally, yes. Maybe call it a Fidelity axis. With one extreme being
where a person runs off with the best_man/matron_of_honor, and
the other this: http://news.bbc.co.uk/2/hi/europe/4198155.stm

Anyway, I'd actually just be happy to get things like:
1) Traps popping in/out depending on point size.
2) Let's say three gs bitmap sizes "embedded".
And I'd be ecstatic to get optical scaling in there.
Imagine, a fool-proof way to get large type to look
elegant and small to be readable in spite of the setter.
Imagine aaaaall the people, living... Wait, that's another thread.

hhp

vinceconnare's picture

>Wait a second. And Tahoma came before Verdana (plus their blackbody >bitmaps are identical anyway). So you’re saying all this time we’ve >been told incorrectly that Carter made the bitmaps (or am I >remembering wrong).

Tahoma was the regular weight font and was made first, Verdana was the bold. Verdana was originally called Ohana but that got dropped.

We were trying to replace MS Sans as the UI font in Windows 95 to make it look very different than anything out there (at the last minute!). Changing the UI font was the quickest way to do that.

We had to come as close as possible to MS Sans bitmaps that were in Windows. So somebody has to open up all those bitmaps and come up with numbers and in some cases convert the bitmap fonts so Matthew could use them on his Mac and that was me.

Matthew made the bitmaps and in some cases used negative sidebearings (the bitmap went out of the width). Matthew designs on a Mac.

I had to correct the bitmaps and remake them in the Window SDK tool for making fnt's and then we used those in test Versions of Windows 95. The fnt bitmap format didn't support negative lsb or rsb.

We went through many versions and many system tests (many) and eventually it was not accepted because it was not exactly the same as Ms Sans for the escapements. This would cause massive problems for thousands of applications developers developing for Windows. It also was different than what most people were use to seeing so they thought MS Sans was better (mostly because of the 'what you read most, reads best theory').

Matthew made the first bitmaps, I made them work.

Eventually I had to calculate the metrics from the bitmaps for the TrueType font then when Matthew made the outline I embedded the bitmaps into the fonts so Tom Rickner could use them to hint the font to get the exact image as the bitmaps.

There were many people involved in the making of Tahoma, we are generally credited in talks about Tahoma as 'the engineers'. We 'the engineers' were trying to maintain backward compatibility and do something different, not just do something different.

Eventually Tahoma got picked up by Office for its dialogs after Internet Explorer shipped with the bolder font Verdana.

I made Trebuchet after/during the hinting of Tahoma. The way the shapes came out largely is caused by making sure at the small sizes the bitmaps were all different than Tahoma. I made the 'M' angled because Tahoma was straight. I used a serif on the 'l' because Tahoma didn't and made the 'g' 2-story since his was one story. I also made my cap height, x-height and ascenders different. At 10 or 11 ppem there is very little difference between one font and another other than the white space and the Cap height. Matthew made his ascenders bigger than his Caps to separate them visually, and made a big x-height.

hrant's picture

Thanks for the history.

> Ohana

That's keeper trivia right there.
I guess they dumped it because of the potential confusion
in Hawaii: "No, NO, Ohana is one of the fonts in the family!" ;-)

> Matthew made the first bitmaps, I made them work.

Got it.

> I embedded the bitmaps into the fonts

I'm really curious, assuming you can remember/dig_it_up (I hope so)
what the comparative filesize was between your transitional font and
the final superhinted version. I ask because one classic argument in
support of superhinting versus embedded bitmaps (at least before CT :-)
was filesize. The thing is, the hints in the old MS core fonts took up
fully HALF the file size!! So I'm suspicious. Hopefully we can unravel
this once and for all.

> the bolder font Verdana

I didn't say anything the first time :-) but are you sure you mean bolder? I mean, Verdana has 1- and 2-pixel stem Regular and Bold fonts just like Tahoma (and I think they "break" at the same PPEMs). In fact, if anything, Verdana's looser spacing (its [official] raison-d'être vis-a-vis Tahoma) makes it slightly lighter.

> Trebuchet... making sure at the small sizes
> the bitmaps were all different than Tahoma.

I think I'd read that before (but is less detail).
It's an interesting, and to me not invalid, strategy.

hhp

hrant's picture

BTW:
> http://www.bitstream.com/font_rendering/products/font_fusion/ffoverview....

Man, I never get tired of doing this: :-)

Versus Mana-11 Bold:


_

Versus Mana-13 Bold:


_

Versus Mana-16 Regular:


_

FontFusion: Nice algorithm, like most other
things Bitstream does. But not good enough.

hhp

vinceconnare's picture

Actually now that I think about it Ohana was a lot bolder than the final Verdana. It was reworked and expanded when it was made for IE. Anything I was saying about Tahoma and Verdana relates to the original work and not the final families you have now.

The embedded bitmap font was unhinted and removed when Tom finished hinting it.

hrant's picture

> The embedded bitmap font was unhinted
> and removed when Tom finished hinting it.

Yes, I figured as much.
But do you know, or could you please find out, what filesize it was?

hhp

vinceconnare's picture

I had a look at some old data from 09-1994 of Ohana and it was a completely different animal. This was a first draft of one of the faces. I don't think Matthew would like it to be seen since it's very geometric and a work in progress. I do think he has shown this in one of his talks about the face. It looks a bit like his 'Walker' typeface.

The early bitmaps were designed at 8 pixels high (ascender to descender)for the UI font (regular) and 18, 22 pixels height for the test Display font. These really weren't ppem but more cell height of the ascender to descender.

Later there were condensed versions which I embedded into TrueType fonts containing only bitmaps and a single 'missing glyph'. The bitmap fonts only contained A-Z, a-z, 0-9, and a couple of test accents like Aring, and Ccedilla plus basic punctuation so we could test it in the system.

The original font was called MS Sans and compiled into a .fon file with the basic sizes for 96x96 res for testing.

The first use a font named Tahoma was as a bitmap font based on a Display font previously referred to as 'Ohana'. This font was used for Windows 95's start-up screen. It was necessary for it to be a bitmap font since during the install process the operating system is not fully installed and only simple formats could be used. Ohana was a nonsense name made from the two senior leads Virginia Howlett and Dave Ohara.

The first Display test TrueType font; of 299 glyphs (char set 'Win ANSII'; )hinted font with embedded bitmaps for 3 sizes 13, 14, 17 ppem was 77,572 bytes

hrant's picture

Vincent, thanks very much for checking.
I'll see if I can extract anything interesting from your ~78Kb number.

> These really weren’t ppem but more cell height of the ascender to descender.

The only decent way to measure bitmap fonts.

hhp

dberlow's picture

"OpenType was to solve more serious problems such as ones in languages."
;-o. Like they actually "solved" that? And, is drawing a kabillion characters actually more serious than not being able to read them at low res.? :-•

hrant's picture

It's the difference between legibility (where having anything is -naturally- better than nothing) and readability (without which you can still read, just not comfortably), with the former always getting more attention because it's much more obvious. The good news is that you could say this is natural evolution, in that complex scripts acquire the basics first, and then they (and Latin as a consequence) move up to more sophisticated things like optical scaling and good bitmaps. On the other hand, there will always be more money (hence development, at least in a capitalistic framework) in legibility than readability.

hhp

dberlow's picture

Hr: BTW, why such a fine scale? I thought Windows (for one) uses
only 16 shades of gray when rendering gs fonts, which would
mean 1/4 pixels (in each dimension) should be enough, no?

TT is overbuilt, typical of a good long-term standard. There also 72 different rounding states possible.

VC: You can’t read between fonts. The code in the font is internal.

Literally, this is true, but you can however pass info and code from one font to another by including, e.g. a Roman cvt stem value in the CVT of the Bold to make sure they'll always be different, or e.g. an identical function acting upon a cascade of cvts.

Fonts can talk to each other through TT, and as long as all other things in the transformation and rasterization of the fonts is =, all's well. The Barriers that stop more from happening are in my original crit of OT.

Syndicate content Syndicate content