Re: [css3-fonts] subscript/superscript variants

Christoph Päper <[email protected]> Thu, 10 May 2012 13:41:51 +0200
Newsgroups gmane.comp.web.fonts,gmane.comp.web.css.general
Message-ID <[email protected]>
John Daggett:
> I'd like to propose that:
>=20
>  * fallback occurs across a given text run rather than per-character

This seems reasonable at first, but it differs from other font =
fallbacks: When some character is missing from a font (i.e. there=E2=80=99=
s not even a related glyph to synthesize from), a substitute may betaken =
from a different font, but the surrounding glyphs still use the nominal =
font (if supported of course).

What cases do we actually want and need to support with this property?

>  * the 'font-variant-position' property is defined independent of=20
>    the existing use of the font-size/vertical-align properties to
>    synthesize subscripts/superscripts

It would be great if that was possible.

> There are, however, a couple downsides to this model.  Fonts typically
> only define these glyphs for a small subset of characters available in
> the font.  The numbers 0-9 are supported but lowercase and punctuation
> characters are frequently not.

Has someone researched whether OT fonts that cover the related Unicode =
code points =E2=80=93 see incomplete table below =E2=80=93 are more =
likely to support the font features =E2=80=98subs=E2=80=99 and =
=E2=80=98sups=E2=80=99 (or vice versa)? Synthesis might be improved if =
that wasn=E2=80=99t the case.

      sup-lower  sup-upper  sub-lower  sub-upper
  0           2070                  2080
  1           00B9                  2081
  2           00B2                  2082
  3           00B3                  2083
  4           2074                  2084
  5           2075                  2085
  6           2076                  2086
  7           2077                  2087
  8           2078                  2088
  9           2079                  2089
  +           207A                  208A
  -           207B                  208B
  =3D           207C                  208C
  (           207D                  208D
  )           207E                  208E
  a     1D43       1D2C       2090
  b     1D47       1D2E
  c     1D9C
  d     1D48       1D30
  e     1D48       1D31       2091
  f     1DA0
  g     1D4D       1D33
  h     02B0       1D34=20
  i     2071       1D35       1D62
  j     02B2       1D36       2C7C
  k     1D4F       1D37
  l     02E1       1D38
  m     1D50       1D39
  n     207F       1D3A
  o     1D52       1D3C       2092
  p     1D56       1D3E=20
  q =20
  r     02B3       1D3F       1D63
  s     02E2
  t     1D57       1D40
  u     1D58       1D41       1D64
  v     1D5B       2C7D       1D65
  w     02B7       1D42
  x     02E3                  2093
  y     02B8
  z     1DBB

> This gives three alternates for subscripts/superscripts:
>=20
>  (1) the subscript/superscript variant glyph
>  (2) a synthesized glyph using the subscript/superscript
>      metrics from the font
>  (3) a synthesized glyph using fixed size/offset values
>      (i.e. what user agents do today)
>=20
>  http://people.mozilla.org/~jdaggett/tests/subsupermetrics.png

Judging from that sample, (1) always looks better than (2) and (2) never =
looks worse than (3), which is not surprising at all.

> This may lead to inconsistencies between subscript/superscript
> placement depending upon the content but it's better than having the
> position of glyphs vary within a given subscript/superscript.

For something like =E2=80=9Ca<sub>1</sub> + =E2=80=A6 + =
a<sub>n-1</sub>=E2=80=9D I=E2=80=99m not sure people would want to have =
(only) the latter part fall back, because the font supported subscript =
digits, but not roman letters. I certainly would expect the one-digits =
to look the same.

> The use of subscript/superscript variants is basically typographic,
> there's no manipulation of the linebox.

That=E2=80=99s why it=E2=80=99s possible most of the time to apply them =
algorithmically, without explicit markup (i.e. =E2=80=98sup=E2=80=99 and =
=E2=80=98sub=E2=80=99), but implicit markup (e.g. =E2=80=98abbr=E2=80=99, =
=E2=80=98math=E2=80=99 and =E2=80=98lang=E2=80=99) can help a lot.

  Mme. =E2=87=90 M<sup>me</sup>
  Acme(TM) =E2=87=90 Acme<sup>TM</sup>    (Acme=E2=84=A2)
  1st, 2nd, 3rd, 4th =E2=87=90 1<sup>st</sup>, 2<sup>nd</sup>, =
3<sup>rd</sup>, 4<sup>th</sup>
  H2O =E2=87=90 H<sub>2</sub>O
  NOx =E2=87=90 NO<sub>x</sub>
  YCbCr =E2=87=90 YC<sub>B</sub>C<sub>R</sub>
  2 Cl- + Ca2+ =E2=87=90 2 Cl<sup>=E2=88=92</sup> + Ca<sup>2+</sup>
  E =3D mc^2 =E2=87=90 E =3D m=E2=81=A2c<sup>2</sup>   (E =3D mc=C2=B2)
  9.80665 kg=C2=B7m=C2=B7s^-2 =E2=87=90 9.80665=E2=80=AFkg=C2=B7m=C2=B7s<s=
up>-2</sup>    (kg=C2=B7m=C2=B7s=E2=81=BB=C2=B2)
  1 lbf. =E2=87=90 1 lb<sub><i>F</i></sub>
  10bin + 10_10 + Ah =E2=87=90 10<sub>bin</sub> + 10<sub>10</sub> + =
A<sub>h</sub>
  log_e(a), log10(a) =E2=87=90 log<sub>e</sub>a =3D ln a, =
log<sub>10</sub>a =3D lg a
  a<sup>-</>b<sup>*</>c<sup>+</>d<sup>?</>e<sup>!</> =3D =
a{0}b{0,}c{1,}d{,1}e{1}
  n/a =E2=87=90 NP<sub>Nom, Sg, f</sub>
  n/a or lim_(n=E2=86=920) =E2=87=90 lim<sub>n=E2=86=920</sub>
  n/a or =E2=88=8F_(i=E2=88=88=E2=84=99) =E2=87=90 =E2=88=8F<sub>i=E2=88=88=
=E2=84=99</sub>
  n/a =E2=87=90 =E2=88=91<sub>i=3D1</sub><sup>=E2=88=9E</sup> =3D =
=E2=88=91<sup>=E2=88=9E</sup><sub>i=3D1</sub>=20
  n/a or C14, C-14 =E2=87=90 <sup>14</sup>C   ?
  n/a =E2=87=90 <sup>235</sup><sub>92</sub>U
 =20
It=E2=80=99s usually the font developer=E2=80=99s job to create complex =
substitution tables for that (although maybe for =E2=80=98calt=E2=80=99 =
or the like rather than =E2=80=98subs=E2=80=99 and =E2=80=98sups=E2=80=99)=
, but I don=E2=80=99t think it=E2=80=99s totally unreasonable for CSS to =
prescribe some on the higher level =E2=80=93 or introduce something akin =
=E2=80=98@text-transform=E2=80=99.

  math, abbr {font-variant-position: auto;}

would then be all most authors needed, except when they use =E2=80=98sub=E2=
=80=99 and =E2=80=98sup=E2=80=99 elements:

CSS1, CSS2

  <foo>H<sub>2</sub>O</foo>
  H<sub>2</sub>O
=E2=87=A9
  foo {}
  sub {
    vertical-align: sub; font-size: smaller; line-height: normal;
  }

CSS3 Etemad/Baron

  <foo>H<sub>2</sub>O</foo>
  H<sub>2</sub>O
=E2=87=A9
  foo {}
  sub {
    vertical-align: sub; font-size: smaller; line-height: normal;
    font-variant-position: sub; /* magic */
  }

CSS3 Daggett

  <foo>H<sub>2</sub>O</foo>
  H<sub>2</sub>O
=E2=87=A9
  foo {}
  sub {
    vertical-align: sub; font-size: smaller; line-height: normal;
  }
  @supports ( font-variant-position: sub ) /* module dependency */ {
    sub {
      vertical-align: inherit; font-size: 100%; line-height: inherit;
      font-variant-position: sub;
    }
  }

CSS3 P=C3=A4per

  <foo>H<sub>2</sub>O</foo>
=E2=87=A9
  foo {
    font-variant-position: auto; /* magic */
  }
  sub {=20
    /* backwards compatibile, possibly ugly: */
    vertical-align: sub; font-size: smaller; line-height: normal;
    font-variant-position: none; /* do nothing */
  }
  sub {
    /* not backwards compatible, nicer looking */
    font-variant-position: sub; /* optional: forces subscript if =
=E2=80=98auto=E2=80=99 fails */
  }

  H<sub>2</sub>O
=E2=87=A9
  :root {
    font-variant-position: auto;
  }
  sub {/* same as above */}

  <foo>H2O</foo>
=E2=87=A9
  foo {
    font-variant-position: auto;
  }

My point is, an author should not need to enable =E2=80=98subs=E2=80=99 =
and =E2=80=98sups=E2=80=99 (and other character-centric OT features, see =
=E2=80=98font-variant-alternates=E2=80=99) manually except where =
semantically absolutely necessary; they should be applied automatically =
where reasonable, either by the font or by the typesetting software. =
This is one area (of several) where the Open Type (or Open Font) Format =
isn=E2=80=99t user-friendly, so we shouldn=E2=80=99t copy it verbatim.

Nevertheless, authors should still be able to apply these features =
manually.

PS: I have the feeling this feature is primarily intended for bicameral =
(and primarily horizontal) scripts, especially the roman one, so I =
ignored others for the sake of simplicity.=