James Clark wrote:
> So I would suggest that the spec should say that a UA must determine
> whether an OpenType font provides an appropriate rotated glyph for a
> Tr character by testing whether applying the 'locl' and 'vert' GSUB
> features together to a glyph string consisting of the single glyph
> id to which the character is mapped results in a change to the glyph
> string. This would ensure all OpenType-based implementatons behave
> consistently with each other and with UTR#50. I can't see this
> having a performance impact: there are relatively few Tr characters
> and you can do this test up-front, once per font.
That's a simplification of OpenType layout. Would that work most of
the time for existing fonts? Yes. Would it be correct in all
situations? No. OpenType defines a set of default features and
authors can apply extra features via properties like 'font-variant'
and 'font-feature-settings'. In the general, non-script specific
case, substitution features are applied in the order specified in the
font, followed by positioning features in a similar manner.
Simple case:
cmap vert
codepoint ====> glyph id A ====> glyph id B
When a feature isn't supported no change occurs to the glyph id, so if
a font doesn't have a 'vert' substitution defined for A, you'll see A
in the output instead of B. So in this case you're running layout
twice, once to determine the default glyph (A) and then to see if
there's a substitution to (B).
Complex case:
cmap feat1 vert feat2
codepoint ====> glyph id A ====> glyph id B ====> glyph id C ====> glyph id D
In this case it's considerably harder to determine whether a given
codepoint has a vertical alternate or not because of the influence of
other features. You'd need to actually determine where the 'vert'
feature is applied and test at that point whether a substitution
occurs or not. Simply running the pipeline with and without 'vert'
enabled isn't going to tell you that.
Another thing to point out here is that substitution rules in OpenType
can be contextual. A contextual substitution, for example, might
require that gidA is transformed to gidB only when preceded by gidC or
gidD. So shaping characters in isolation isn't a good idea because it
breaks the ability to use contextual shaping rules like this.
Japanese fonts today generally don't use features at this complexity
level but you're starting to see more complexity in fonts such as
Kazuraki from Adobe. Which is why for future use I think it's
important for layout engines not to encumber text shaping with
fallback rules like the optional one described in the Writing Modes
spec.
Looping back to the question of how 'Tr' codepoints should be handled,
I think it's important to point out that there are 47 of these
codepoints in all of Unicode and the Japanese fonts I tested supply
vertical alternates for almost all of the characters supported within
the font. The missing ones I found were:
Kozuka Mincho Pr6N
3030 cid12218 vert: [] WAVY DASH
ff1b cid00640 vert: [] FULLWIDTH SEMICOLON
MS Mincho
ff1b uniFF1B vert: [] FULLWIDTH SEMICOLON
So that's what all this complexity boils down to -- fallback for these
two codepoints. This doesn't seem like a worthwhile tradeoff,
especially given that the lack of vertical alternates in a font like
Kozuka Mincho, which includes over 20,000 glyphs, suggests that the
rotated form of these characters is not actually used a whole lot in
practice.
Regards,
John Daggett