diff options
Diffstat (limited to 'doc/context/sources/general/fonts/fonts/fonts-extensions.tex')
-rw-r--r-- | doc/context/sources/general/fonts/fonts/fonts-extensions.tex | 347 |
1 files changed, 330 insertions, 17 deletions
diff --git a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex index fcb9746f2..ace0f771e 100644 --- a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex +++ b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex @@ -430,6 +430,9 @@ This is a rather special one. First we show a couple of definitions: \typebuffer \getbuffer +When you don't want a dimension to change you leave an entry empty, so +valid entries are for instance: \type {,3,} and \type {1,,}. + As usual you apply such a feature as follows: \starttyping @@ -475,7 +478,8 @@ A special case is the following: \typebuffer \getbuffer -This will make the height and depth the same as the current strut height and depth: +This will make the height and depth the same as the {\em current} strut height +and depth: \startbuffer \ruledhbox{\definedfont[Serif*default,dimensions-e at 8pt]clipped} @@ -489,6 +493,10 @@ The dimensions are (in this case) limited: \startlinecorrection[blank] \dontleavehmode \hpack{\maincolor\inlinebuffer} \stoplinecorrection +Another special case is \type {dimensions=mono} which will make an characters the +fonts em|-|width. This is handy when you define font fallbacks where glyphs come +from a non monospaced font. + \stopsection \startsection[title=Unicoding] @@ -797,6 +805,23 @@ We use the following example. The results are shown in \in {figure} \getbuffer [example] \stopplacefigure +You can see what happens in \in {figure} [expansion:visualized]. + +\startbuffer[example] + \setupalign[hz] + \enabletrackers[*expansion*] + \definefontfeature[boundingbox][boundingbox={frame,empty}] + \definedfont[Serif*default,quality,boundingbox @ 12.1pt] + \samplefile{sapolsky}\par + \disabletrackers[*expansion*] +\stopbuffer + +\typebuffer[example] + +\startplacefigure[reference=expansion:visualized,title=The injected expansion kerns.] + \getbuffer [example] +\stopplacefigure + \startsubsubject[title=Expansion and kerning] When we expand glyphs we also need to look at the font kerns between them. In the @@ -914,19 +939,16 @@ effect of expanded kerns is invisible. The used definitions are: \startplacefigure[reference=hz:natural,title={The two expansion methods compared.}] \showfontkerns \dontcomplain - \enabledirectives[fonts.injections.fontkern] \startcombination[1*3] {\ExtremeHzFont\ruledhpack{\startoverlay {\NoHzSample} {\HzSample } \stopoverlay}} {no hz \& hz} {\ExtremeHzFont\ruledhpack{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {no hz \& full hz} {\ExtremeHzFont\ruledhpack{\startoverlay {\HzSample } {\FullHzSample} \stopoverlay}} {hz \& full hz} \stopcombination - \disabledirectives[fonts.injections.fontkern] \stopplacefigure \startplacefigure[reference=hz:zoomed,title={The two expansion methods compared (zoomed in).}] \showfontkerns \dontcomplain - \enabledirectives[fonts.injections.fontkern] \startcombination[3*3] {\ExtremeHzFont @@ -951,20 +973,13 @@ effect of expanded kerns is invisible. The used definitions are: \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample } {\FullHzSample} \stopoverlay}} {minimal: hz \& full hz} \stopcombination - \disabledirectives[fonts.injections.fontkern] \stopplacefigure -In \CONTEXT\ the \type {hz} alignment option only enables expansion of glyphs, while \type -{fullhz} also applies it to kerns. However, in the examples here we had to explicitly enable -font kerns in node mode: - -\starttyping -\enabledirectives[fonts.injections.fontkern] -\stoptyping - -It will be clear that you can just stick to using the \type {hz} directive (if -you want expansion at all) because this directive is normally disabled and -because most fonts are processed in node mode. +In \CONTEXT\ the \type {hz} alignment option only enables expansion of glyphs, +while \type {fullhz} also applies it to kerns. It will be clear that you can just +stick to using the \type {hz} directive (if you want expansion at all) because +this directive is normally disabled and because most fonts are processed in node +mode. \stopsubsubject @@ -1621,6 +1636,26 @@ example we only displace the second glyph. Of course you need to know a bit about the metrics of the glyphs involved so in practice this boils down to trial and error. +A single character (glyph) can also be tweaked, although normally this is done +better in a manipulator when loading the font. Anyway: + +\startbuffer +\startluacode + fonts.handlers.otf.addfeature { + name = "stest", + type = "single", + data = { + a = { -30, 0, -50, 0 }, + } + } +\stopluacode +\stopbuffer + +\typebuffer \getbuffer + +This will reduce the left and right edges and make the glyph a pretty tight one. The +values are for Latin Modern. + \stopsubsection \startsubsection[title=Examples] @@ -1694,6 +1729,199 @@ Here the dataset is a sequence of rules. There can be a \type {before}, \type {lookups} entry and the numbers are indices in the provided \type {lookups} table. +Here is another example. This one demonstrates that one can check against spaces +(some fonts kerns against them) and against boundaries as well. The later is +something \CONTEXT\ specific. First we define a feature that create ligatures but +only when we touch a space: + +\startbuffer +\startluacode + fonts.handlers.otf.addfeature { + name = "test-a", + type = "chainsubstitution", + lookups = { + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + before = { { " " } }, + current = { { "a" }, { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" }, { "d" } }, + after = { { " " } }, + lookups = { 1 }, + }, + }, + }, + } + +\stopluacode +\stopbuffer + +\typebuffer \getbuffer + +The next example also checks against whatever boundary we have. + +\startbuffer +\startluacode + fonts.handlers.otf.addfeature { + name = "test-b", + type = "chainsubstitution", + lookups = { + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + before = { { " ", 0xFFFC } }, + current = { { "a" }, { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" }, { "d" } }, + after = { { 0xFFFC, " " } }, + lookups = { 1 }, + }, + }, + }, + } +\stopluacode +\stopbuffer + +\typebuffer \getbuffer + +We can actually simplify this one to: + +\startbuffer +\startluacode + fonts.handlers.otf.addfeature { + name = "test-c", + type = "chainsubstitution", + lookups = { + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + before = { { 0xFFFC } }, + current = { { "a" }, { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" }, { "d" } }, + after = { { 0xFFFC } }, + lookups = { 1 }, + }, + }, + }, + } +\stopluacode +\stopbuffer + +\typebuffer \getbuffer + +As a bonus we show how to do more complex things: + +\startbuffer +\startluacode + fonts.handlers.otf.addfeature { + name = "test-d", + type = "chainsubstitution", + lookups = { + { + type = "substitution", + data = { + ["a"] = "A", + ["b"] = "B", + ["c"] = "C", + ["d"] = "D", + }, + }, + { + type = "ligature", + data = { + ['1'] = { "a", "b" }, + ['2'] = { "c", "d" }, + }, + }, + }, + data = { + rules = { + { + before = { { 0xFFFC } }, + current = { { "a" }, { "b" } }, + lookups = { 2 }, + }, + { + current = { { "c" }, { "d" } }, + after = { { 0xFFFC } }, + lookups = { 2 }, + }, + { + current = { { "a" } }, + after = { { "b" } }, + lookups = { 1 }, + }, + { + current = { { "c" } }, + after = { { "d" } }, + lookups = { 1 }, + }, + }, + }, + } +\stopluacode +\stopbuffer + +\typebuffer \getbuffer + +\definefontfeature[test-a][test-a=yes] +\definefontfeature[test-b][test-b=yes] +\definefontfeature[test-c][test-c=yes] +\definefontfeature[test-d][test-d=yes] + +\startbuffer +abababcdcd abababcdcd abababcdcd +\stopbuffer + +With the test text: + +\typebuffer + +These four result in: + +\blank \start + + \definedfont[file:dejavu-serif.ttf*default] + + \start \addff{test-a} \getbuffer \stop\par + \start \addff{test-b} \getbuffer \stop\par + \start \addff{test-c} \getbuffer \stop\par + \start \addff{test-d} \getbuffer \stop\par + +\stop \blank + \stopsubsection \startsubsection[title={Language dependencies}] @@ -2055,7 +2283,6 @@ fonts.handlers.otf.addfeature { { "down", depth + height }, { "rule", 3*height, width/5 }, - } } @@ -2400,6 +2627,92 @@ gets defined and because we share resources it even has to happen before the first font gets loaded. So, the \type {\blockligatures} commands go before setting up the body font. This is no real problem because it's a hack anyway. +The next example combines several tricks: + +\startbuffer[definitions] +\startluacode + fonts.handlers.otf.addfeature { + name = "kernligatures", + type = "kern", + data = { + f = { i = 50, l = 50 }, + } + } +\stopluacode + +\blockligatures[u:fl:a] + +\definefontfeature[default:b][default][blockligatures=yes] +\definefontfeature[default:k][default][blockligatures=yes,kernligatures=yes] + +\showfontkerns +\stopbuffer + +\startbuffer[demo] +{\definedfont[Brill*default @ 11pt]auflage}\par +{\definedfont[Brill*default:b @ 11pt]auflage}\par +{\definedfont[Brill*default:k @ 11pt]auflage}\par +\stopbuffer + +\typebuffer[definitions,demo] \getbuffer[definitions] + +\startlinecorrection + \externalfigure[demo.buffer][width=4cm] +\stoplinecorrection + +Processing fonts is complicated by the fact that a text can be hyphenated. This +complicates for instance ligature building which can cross the pre, post and|/|or +replace bounds. The current implementation does a decent job although there will +always be border cases. And, figuring out what goes wrong is a pain. There are +several ways to trace what happens and here's one. As mentioned, blocking only +works when we haven't not yet defined a font instance, so we use a funny size +here. + +\startbuffer +\blockligatures[u:fl:a] + +\definefontfeature + [blockligatures] + [default] + [blockligatures=yes] + +\startotfcompositionlist{texgyrepagella-regular*blockligatures @ 14.5pt}{l2r} + \HL + \showotfcompositionsample{auflage} + \showotfcompositionsample{a\discretionary{-}{}{}uflage} + \showotfcompositionsample{au\discretionary{-}{}{}flage} + \showotfcompositionsample{auf\discretionary{-}{}{}lage} + \showotfcompositionsample{aufl\discretionary{-}{}{}age} + \showotfcompositionsample{aufla\discretionary{-}{}{}ge} + \showotfcompositionsample{auflag\discretionary{-}{}{}e} + \HL + \showotfcompositionsample{auflegt} + \showotfcompositionsample{a\discretionary{-}{}{}uflegt} + \showotfcompositionsample{au\discretionary{-}{}{}flegt} + \showotfcompositionsample{auf\discretionary{-}{}{}legt} + \showotfcompositionsample{aufl\discretionary{-}{}{}egt} + \showotfcompositionsample{aufle\discretionary{-}{}{}gt} + \showotfcompositionsample{aufleg\discretionary{-}{}{}t} + \HL +\stopotfcompositionlist +\stopbuffer + +\typebuffer \getbuffer + +Here is another example. This one demonstrates that ligatures can force +collapsing of discretionaries. + +\startbuffer +\startotfcompositionlist{Serif*default @ 11pt}{l2r} + \HL + \showotfcompositionsample{effe} + \showotfcompositionsample{efficient} + \HL +\stopotfcompositionlist +\stopbuffer + +\typebuffer \getbuffer + \stopsection \startsection[title=Collections] |