Contextual Spacing GPOS Features: ‘cspc’ & ‘vcsp’

Japanese line layout is very complex, and the first attempt to standardize its rules and principles was in the JIS X 4051 standard, which was first issued in 1993 with the title 日本語文書の行組版方法 (Line Composition Rules for Japanese Documents in English). There was a revision issued in 1995, and the latest version was issued in 2004 with the slightly different title 日本語文書の組版方法 (Formatting rules for Japanese documents). Another important document is the W3C Working Group Note JLREQ (Requirements for Japanese Text Layout), which provides much of what is described in JIS X 4051, but covers additional areas, and is tailored toward web technologies. Although still considered working drafts, W3C is also preparing similar documents for Chinese and Korean as CLREQ (Requirements for Chinese Text Layout) and KLREQ (Requirements for Hangul Text Layout and Typography), respectively.

This article is not about these standards per se, which are intended for apps and environments that implement sophisticated line layout. Rather, this article is about harsher “plain text” or comparable environments that generally do not need such treatment, yet still benefit from a modest amount of context-based spacing adjustment, particularly to get rid of unwanted space between full-width brackets and other punctuation whose glyphs generally fill half of the em-box. App menus, app dialogs, and simple text editors are examples of where such adjustments can improve text layout in these modest ways.

This all started when I met with Koji Ishii (石井宏治) of Google last Friday morning to discuss ways in which fonts can provide a modest amount of contextual metrics for these simpler environments, and while the existing kerning features were discussed as a possible vehicle for such metrics information, there is an obvious conflict for fonts that are intended to supply genuine kerning values versus contextual spacing values that generally used fixed values and affect a much smaller number of glyphs. Some fonts may choose to support both: genuine kerning and associated metrics for more complex environments, and the contextual spacing that is described in this article which is meant for simpler environments.

Our meeting ended with lunch at PHB, along with the idea to register two new OpenType GPOS (Glyph Positioning) features that would be tentatively tagged 'cspc' (“Contextual Spacing”) and 'vcsp' (“Vertical Contextual Spacing”), and which would behave like the 'kern' and 'vkrn' in that they adjust inter-glyph spacing.

I used Friday afternoon to come up with a preliminary set of characters, which include all of the full-width brackets in the U+3000 and U+FF00 blocks. I subsequently organized them into glyph classes. The vertical variants in the U+FE10 and U+FE30 blocks are also included only because their glyphs are mapped from those codes points, but are also specified as vertical variants via the 'vert' GSUB feature.

Saturday morning was spent building an OpenType/CFF font with less than 100 glyphs that is based on Source Han Serif. This font is still considered Pan-CJK in that it supports region-specific forms for some punctuation and one ideograph. As a result, the hani, kana, and latn scripts are supported, as are the JAN, ZHS, and ZHT languages, and the appropriate declarations are specified in both the 'locl' (Localized Forms) and 'vert' GSUB features. In order to be able to test in environments that do not support arbitrary OpenType features, the example font includes the lookups for the 'cspc' and 'vcsp' GPOS features in the 'kern' and 'vkrn' GPOS features, respectively.

The image below is a close re-creation of the seven example strings that are shown in Figure 3.13 of JLREQ that was prepared using the example implementation, whereby the right side shows the glyphs set solid with default full-width metrics, and the left side shows the result when the 'vcsp' GPOS feature is applied:

Not bad, right?

The latest example OpenType/CFF font, SourceHanSerifCSP-Heavy.otf Version 1.004 built on 2018-04-23, includes glyphs for ‘’“” 、。〈〉《》「」『』【】〔〕〖〗〘〙〚〛〝〟あ・好(),.!:;?[]{}⦅⦆ ← you can copy the characters from this paragraph. U+00B7 ·, U+2022 , and U+2027 map to the glyph for U+30FB , and U+2329 and U+232A map to the glyphs for U+3008 and U+3009 , respectively. Vertical forms that are encoded in the U+FE10 and U+FE30 blocks are also mapped from those code points, but are also accessible via the 'vert' GSUB feature.

For those who are interested in this idea, please download and use the example font, and be sure to language-tag the text for languages other than Japanese, specifically Simplified Chinese and Traditional Chinese, as the forms of some punctuation and single ideograph will change as appropriate.

Of course, these GPOS features are not meant as a substitute for implementing proper line layout support based on JIS X 4051 or JLREQ for apps that deserve to provide their customers such support. And, because these are separate GPOS features, it is possible for fonts that include them to continue to function in environments that support more sophisticated line layout, but also in simpler environments that would need to invoke only the 'cspc' or 'vcsp' GPOS feature, as appropriate. Feel free to examine the raw features file that uses Unicode-based glyph names. Any feedback is welcome.

One important caveat for font developers is that all four valuerecord values—xPlacement, yPlacement, xAdvance, and yAdvance—need to be explicitly supplied for each glyph or glyph class pair of the 'vcsp' GPOS feature as specified in the “features” file in order for the spacing adjustments to be applied along the Y-axis, not the X-axis. Most of the pairs use <0 0 0 -500> as the valuerecord, which removes 500 units from the vertical advance of the first glyph in the pair. The AFDKO makeotf tool treats the 'vkrn' GPOS feature special in this regard, which is why only a single adjustment value needs to be supplied.

🐡

5 Responses to Contextual Spacing GPOS Features: ‘cspc’ & ‘vcsp’

  1. With regard to the last paragraph, I just realized that the ‘vcsp’ GPOS feature can be made explicitly vertical, in terms of how the AFDKO makeotf tool treats the feature, by explicitly supplying XPlacement, YPlacement, XAdvance, and YAdvance values for each record. The last paragraph was adjusted accordingly, and the example font and its “features” file were updated as a result.

  2. So the main difference between Proportional Alternate Widths (palt) and Contextual Spacing (cspc) is that the former works on both kana and punctuation, and the later only affects punctuation. Is that right? Thanks.

    • Not exactly. The 'palt' GPOS feature is not contextual, and applies alternate metrics regardless of the surrounding glyphs. The same is true of the related 'halt' GPOS feature, though it generally applies half-width metrics to brackets and other punctuation. The reason why 'halt' and 'vhal' cannot be used is their lack of contextual support. Making all brackets and punctuation half-width regardless of context does not produce the desired effect, and compresses the text far too much. The contextual spacing GPOS features that are described in this article are contextual, hence their names.

  3. James Lockhart says:

    Great! You guys are onto something good, because 'palt' and 'halt' sometimes have undesirable results—e.g., parentheses and brackets look much better but commas (、) and periods (。) get spaced too tightly. I wondered a couple of times whether it might be nice to have parameters for 'palt' and 'halt' that would let you indicate which glyphs or classes of glyphs would or wouldn’t compress, at it were; but your 'cspc' tag might do the trick.

  4. monokano says:

    position @OpeningBracket @Centered ;
    position @Centered @ClosingBracket ;
    position @OpeningBracketVert @CenteredVert ;
    position @CenteredVert @ClosingBracketVert ;

    I think these are excessive.
    Nobody would expect so much.