summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/fonts/fonts
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/fonts/fonts')
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-appendix.tex3
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-environment.tex42
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-extensions.tex347
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-features.tex201
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-formats.tex47
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-hooks.tex336
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-mkiv.tex3
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-tricks.tex388
8 files changed, 1287 insertions, 80 deletions
diff --git a/doc/context/sources/general/fonts/fonts/fonts-appendix.tex b/doc/context/sources/general/fonts/fonts/fonts-appendix.tex
index ae42b10fa..2eab26a93 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-appendix.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-appendix.tex
@@ -456,7 +456,7 @@ to render this version. Because fonts might have changed in the meantime, some e
might come out other than intended.
\startluacode
-local list = table.load("fonts-mkiv-usedfonts.lua")
+local list = table.load("fonts-mkiv-usedfonts.lua") or { }
local NC, NR = context.NC, context.NR
@@ -473,7 +473,6 @@ for i=1,#list do
NC() context("version") NC() context.type(version) NC() NR()
context.stoptabulate()
end
-
\stopluacode
\stopsection
diff --git a/doc/context/sources/general/fonts/fonts/fonts-environment.tex b/doc/context/sources/general/fonts/fonts/fonts-environment.tex
index a8de89a42..c884d97e5 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-environment.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-environment.tex
@@ -1,6 +1,46 @@
\startenvironment fonts-environment
- \blockligatures[fi,fl,ff] % we need to do this beforehand
+ % we need to do this beforehand
+
+ \blockligatures[fi,fl,ff]
+
+ \startbuffer[extraminus]
+ \startluacode
+ fonts.helpers.addextraprivate("smallminus", function(tfmdata)
+ local hchar = tfmdata.characters[0x002D]
+ local mchar = tfmdata.characters[0x2212]
+ if hchar and mchar then
+ return {
+ width = hchar.width,
+ height = mchar.height,
+ commands = {
+ { "down", hchar.height - mchar.height },
+ { "char", 0x002D },
+ }
+ }
+ end
+ end)
+ fonts.helpers.addextraprivate("highminus", function(tfmdata)
+ local hchar = tfmdata.characters[0x002D]
+ local mchar = tfmdata.characters[0x2212]
+ local xchar = tfmdata.characters[0x0058]
+ if hchar and mchar and xchar then
+ return {
+ width = hchar.width,
+ height = mchar.height,
+ commands = {
+ { "down", - xchar.height + mchar.height },
+ { "char", 0x002D },
+ }
+ }
+ end
+ end)
+ \stopluacode
+ \stopbuffer
+
+ \getbuffer[extraminus]
+
+ % so far for preloading
\environment manuals-explaining-environment
\environment manuals-explaining-cover
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]
diff --git a/doc/context/sources/general/fonts/fonts/fonts-features.tex b/doc/context/sources/general/fonts/fonts/fonts-features.tex
index f6a12c30d..73d1cd96d 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-features.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-features.tex
@@ -1,4 +1,4 @@
-language=uk
+% language=uk
\startcomponent fonts-features
@@ -1074,12 +1074,21 @@ correction of \type {0.025} but for some shapes a different value is used. Again
we have some commands at the \TEX\ end:
\starttyping
-\setupmathematics[italics=1] % fontitalics
-\setupmathematics[italics=2] % fontdata
-\setupmathematics[italics=3] % quad based
+\setupmathematics[italics=1] % apply italics with we have an italic font
+\setupmathematics[italics=2] % apply italics anyway
+\setupmathematics[italics=3] % apply italics only when italic or bolditalic shapes
\setupmathematics[italics=4] % combination of 1 and 3
\stoptyping
+An alternative is this:
+
+\starttyping
+\definefontfeature[mathextra][mathextra][collapseitalics=yes]
+\stoptyping
+
+This extends the \type {mathextra} feature to move the italic correction into
+the character's width. Often this works out ok.
+
Because (definitely at the start of the \LUATEX\ project) we had no
proper \OPENTYPE\ math fonts, but at the same time wanted to move on
to \OPENTYPE\ and \UNICODE\ math and no longer struggle with all
@@ -2534,48 +2543,40 @@ unlikely to show up in future versions of the Latin Modern fonts.
\stopsection
-\startsection[title=Discretionaries]
-
-% speed test:
+% \startsection[title=Discretionaries]
%
-% \edef\tufte{\cldloadfile{tufte}}
-% \enabledirectives[otf.alwaysdisc]
-% \testfeatureonce{100}{\setbox0\hbox{\tufte \smallcaps \tufte}}\elapsedtime\par
-% \disabledirectives[otf.alwaysdisc]
-% \testfeatureonce{100}{\setbox0\hbox{\tufte \smallcaps \tufte}}\elapsedtime\par
-
-\startbuffer
-\definedfont[cambria*default]
-12\discretionary
- {3} {4} {5}%
-67\par
-12{\oldstyle\discretionary
- {3} {4} {5}}%
-67\par
-12\discretionary
- {3{\oldstyle3}} {{\oldstyle4}4} {5{\oldstyle5}5}%
-67\par
-\stopbuffer
-
-The font handler has to do some magick to get features working with and across
-discretionaries. To some extend you can use font switches inside discretionaries
-but for sure border cases are not dealt with. This works:
-
-\startlinecorrection[blank]
-\startcombination[nx=4,ny=1,location=top]
- {\framed[align=normal]{\enabledirectives [otf.alwaysdisc]\setupwhitespace[line]\getbuffer}} {1}
- {\framed[align=normal]{\enabledirectives [otf.alwaysdisc]\hsize1mm\getbuffer}} {2}
- {\framed[align=normal]{\disabledirectives[otf.alwaysdisc]\setupwhitespace[line]\getbuffer}} {3}
- {\framed[align=normal]{\disabledirectives[otf.alwaysdisc]\hsize1mm\getbuffer}} {4}
-\stopcombination
-\stoplinecorrection
-
-The first two examples have \type {otf.alwaysdisk} enabled, the last two have it
-disabled.
-
-\typebuffer
-
-\stopsection
+% \startbuffer
+% \definedfont[cambria*default]
+% 12\discretionary
+% {3} {4} {5}%
+% 67\par
+% 12{\oldstyle\discretionary
+% {3} {4} {5}}%
+% 67\par
+% 12\discretionary
+% {3{\oldstyle3}} {{\oldstyle4}4} {5{\oldstyle5}5}%
+% 67\par
+% \stopbuffer
+%
+% The font handler has to do some magick to get features working with and across
+% discretionaries. To some extend you can use font switches inside discretionaries
+% but for sure border cases are not dealt with. This works:
+%
+% \startlinecorrection[blank]
+% \startcombination[nx=4,ny=1,location=top]
+% {\framed[align=normal]{\enabledirectives [otf.alwaysdisc]\setupwhitespace[line]\getbuffer}} {1}
+% {\framed[align=normal]{\enabledirectives [otf.alwaysdisc]\hsize1mm\getbuffer}} {2}
+% {\framed[align=normal]{\disabledirectives[otf.alwaysdisc]\setupwhitespace[line]\getbuffer}} {3}
+% {\framed[align=normal]{\disabledirectives[otf.alwaysdisc]\hsize1mm\getbuffer}} {4}
+% \stopcombination
+% \stoplinecorrection
+%
+% The first two examples have \type {otf.alwaysdisk} enabled, the last two have it
+% disabled.
+%
+% \typebuffer
+%
+% \stopsection
\startsection[title=Some remarks]
@@ -2626,6 +2627,116 @@ changes in a lifetime than foreseen when \TEX\ showed up.
\stopsection
+\startsection[title=Different spaces]
+
+The width of the space and its stretch and shrink are taken from the font. The so
+called emspace is the reference for much spacing related parameters. It is the
+width of character \type {0x2014}. The regular space width is taken from \type
+{0x0020}, the space character. When there is no space character, in the case of a
+monospaced font we take the emwidth, otherwise we take half the emwidth. As a
+last resort we can take the average width of characters. And of even that fails
+we take half of the font units. When there is no emwidth that one is set to the
+font units.
+
+In the \CONTEXT\ font loader we use a stretch that is 1/2 of the width of a space
+and the shrink is 1/3 the width of a space, so we use values that are quite
+similar to what \TEX\ always used.
+
+You can overload these values when a font is loaded and the overload is
+implemented as a feature. The next example demonstrates how this is done:
+
+\startbuffer
+\definefontfeature[morespace][spacing=0.50 plus 0.50 minus 0.250]
+\definefontfeature[lessspace][spacing=0.25 plus 0.25 minus 0.125]
+
+\definedfont[Serif*default] \samplefile{klein}\blank
+\definedfont[Serif*default,morespace]\samplefile{klein}\blank
+\definedfont[Serif*default,lessspace]\samplefile{klein}\blank
+\definedfont[Serif*default] \samplefile{klein}\blank
+\stopbuffer
+
+\typebuffer \blank \getbuffer \blank
+
+\stopsection
+
+\startsection[title=Dynamic features]
+
+We can enable and disable features any time in the input by using the
+\type {\feature} command. he following example was posted on the list:
+
+\startbuffer
+\definefont
+ [WeirdShapes]
+ [file:linlibertiner*default]
+
+\definefontfeature
+ [hist]
+ [hlig=yes]
+
+\definefontfeature
+ [rare]
+ [dlig=yes]
+
+\setupquotation
+ [style={\feature[+][hist,rare]}]
+
+\startlines
+\WeirdShapes
+strict {\feature[+][hist]strict}
+wurtzite {\feature[+][rare]wurtzite}
+\quotation{strict wurtzite}
+\stoplines
+\stopbuffer
+
+\typebuffer
+
+Or typeset:
+
+\getbuffer
+
+The \type {\feature} command takes as first argument a directive of what
+do do:
+
+\starttabulate[|T||]
+\NC + more \NC add set to previous set and combine with font set \NC \NR
+\NC - less \NC subtract set to previous set and combine with font set \NC \NR
+\NC = new \NC replace font set \NC \NR
+\NC ! < reset \NC forget sets and revert to font set \NC \NR
+\NC > old default \NC make sure the current set is used on top of the font set \NC \NR
+\stoptabulate
+
+\stopsection
+
+\startsection[title=Spacekerns]
+
+Some fonts kern glyphs with spaces. Although \TEX\ doesn't really have spaces we do
+support this. However, it's implemented as part of kerning so when you define such
+kerns you need to hook it into for instance the \type {kern} feature:
+
+\starttyping
+\startluacode
+ local kern = -50
+ local pair = { [32] = kern }
+
+ fonts.handlers.otf.addfeature {
+ name = "kern", -- spacekerns assume kern
+ type = "kern",
+ data = {
+ A = pair, V = pair, W = pair,
+ [32] = {
+ A = kern,
+ V = kern,
+ W = kern,
+ },
+ }
+ }
+\stopluacode
+\stoptyping
+
+Of course this depends on font properties so one can wonder how useful this is.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/fonts/fonts/fonts-formats.tex b/doc/context/sources/general/fonts/fonts/fonts-formats.tex
index dc98ee486..9ad6bc9bd 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-formats.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-formats.tex
@@ -81,7 +81,7 @@ descender. The width of the bounding box is not by definition the width of the
glyph. In \TYPEONE\ and \OPENTYPE\ fonts each shape has a so called advance width
and that is the one that will be used.
-\usemodule[fnt-40]
+\usemodule[fonts-kerns]
\startplacefigure [location=here,reference=fig:glyph-kerns,title={Kerning in Latin Roman, Cambria, Pagella and Dejavu.}]
\scale[width=\textwidth]{\startcombination[1*4]
@@ -844,17 +844,16 @@ to the representation that we need they get cached. You can peek into the cache
which is someplace on your system (depending on the setup):
\starttabulate[|l|p|]
-\NC \type{fonts/afm} \NC type one fonts, converted from \type {afm} and \type
- {pfb} files \NC \NR
-\NC \type{fonts/data} \NC font name databases \NC \NR
-\NC \type{fonts/mp} \NC fonts created using \METAPOST \NC \NR
-\NC \type{fonts/otf} \NC open type fonts, converted from \type {ttf}, \type {otf},
- \type {ttc} and \type {ttx} files loaded using the
- \FONTFORGE\ loader \NC \NR
-\NC \type{fonts/otl} \NC open type fonts, converted from \type {ttf}, \type {otf},
- \type {ttc} and \type {ttx} files loaded using the
- \CONTEXT\ \LUA\ loader \NC \NR
-\NC \type{fonts/shapes} \NC outlines of fonts (for instance for use in \METAFUN) \NC \NR
+\NC \type{fonts/data} \NC font name databases \NC \NR
+\NC \type{fonts/mp} \NC fonts created using \METAPOST \NC \NR
+\NC \type{fonts/one} \NC type one fonts, converted from \type {afm} and \type
+ {pfb} files \NC \NR
+\NC \type{fonts/otl} \NC open type fonts, converted from \type {ttf}, \type {otf},
+ \type {ttc} and \type {ttx} files loaded using the
+ \CONTEXT\ \LUA\ loader \NC \NR
+\NC \type{fonts/pdf} \NC font shapes for color fonts \NC \NR
+\NC \type{fonts/shapes} \NC outlines of fonts (for instance for use in \METAFUN) \NC \NR
+\NC \type{fonts/streams} \NC font programs for variable font instances \NC \NR
\stoptabulate
There can be three types of files there. The \type{tma} files are just \LUA\
@@ -868,6 +867,30 @@ font or when the \CONTEXT\ font loader has been updated.
\stopsection
+\startsection[title=Paths]
+
+The search for fonts happens on paths defined in \type {texmf.cnf}. The information
+in there is used to generate a file database for fast access with priorities based
+on file type. The \TDS\ is starting point. The environment variable driven paths
+\type {OSFONTDIR} (set automatically) and \type {EXTRAFONTDIR} are taken into account.
+
+In addition you can set \type {RUNTIMEFONTS} which is, when set, consulted at
+runtime. You can also add a path in your style:
+
+\starttyping
+\usefontpath[c:/data/projects/myproject/fonts]
+\stoptyping
+
+although in general we recommend to put fonts in
+
+\starttyping
+<texroot>/tex/texmf-fonts/fonts/data]
+\stoptyping
+
+which is more efficient.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/fonts/fonts/fonts-hooks.tex b/doc/context/sources/general/fonts/fonts/fonts-hooks.tex
index 9be69d6b8..7ee5dc198 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-hooks.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-hooks.tex
@@ -572,14 +572,346 @@ version.}
\stopsection
+\startsection[title=Extra characters]
+
+When \TEX\ loads a font it gets stored in an internal format. Although \LUATEX\
+can still load \TFM\ files, normally we will load font data using \LUA\ and then
+pass it to \TEX. When that is done the font is basically frozen. After all, once
+you entered text and that text has been processed to a sequence of glyphs, the
+backend has to be sure that it can include the right data in the result. What
+matters there is:
+
+\startitemize[packed]
+\startitem the width of a glyph \stopitem
+\startitem the index of a glyph in the font \stopitem
+\startitem properties of a font, like its name \stopitem
+\startitem all kind manipulations don't with a virtual glyph\stopitem
+\stopitemize
+
+So, changing an already used glyph is not done. But, adding a new one should not
+be a big deal. So, starting with \LUATEX\ 1.0.5 we can add characters (that
+become glyphs) to a font after it got passed to \TEX.
+
+Of course there are some limitations to this. For instance, when \OPENTYPE\
+features are needed, you also need to extend that bit and it's not that trivial.
+But adding independent special characters is no problem. Also, you can decide to
+replace an already processed glyph by another one newly created with the same
+dimensions but a different rendering.
+
+Here I'll give a few (simple) examples. First we define a helper that creates a
+rule. After that we use all kind of \CONTEXT\ data structures and helpers but the
+general setup is not that complicated.
+
+\startbuffer
+\startluacode
+ function document.MakeGlyph(w)
+ local v = 655360
+ local w = w*v
+ local h = v
+ local d = v/3
+ return {
+ width = w,
+ height = h,
+ depth = d,
+ commands = {
+ { "down", d },
+ { "rule", h + d, w }
+ },
+ }
+ end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Of course, when one defines a font to be passed to \TEX\ it needs to conform to
+the standard. The \LUATEX\ manual describes what parameters and other properties
+have to be set. We cheat and copy the so called null font. We also create a fonts
+sub table. In such a table, a reference to id zero will be resolved to the id of
+the font.
+
+After defining the font table, we pass it to \TEX\ with \type {font,define} watch
+how we also pass an already reserved id. Then we add some characters and we also
+replace character 122 which is no problem because, after all, we haven't used it
+yet. We just use numbers so don't think we're doing \UNICODE\ here.
+
+\startbuffer
+\startluacode
+ local fontdata = fonts.hashes.identifiers
+
+ local id = font.nextid(true) -- true reserves the id
+ local nf = table.copy(fontdata[0])
+
+ local make = document.MakeGlyph
+ local add = font.addcharacters
+
+ nf.name = "foo"
+ nf.type = "virtual"
+ nf.fonts = { { id = 0 } }
+ nf.characters = {
+ [122] = make(1),
+ [123] = make(2),
+ }
+
+ font.define(id,nf)
+
+ fontdata[id] = nf
+
+ local t = make(3)
+ nf.characters[124] = t
+ add(id, {
+ fonts = nf.fonts,
+ characters = { [124] = t }
+ })
+
+ local t = make(4)
+ nf.characters[125] = t
+ add(id, {
+ fonts = nf.fonts,
+ characters = { [125] = t }
+ })
+
+ local t = make(8)
+ nf.characters[122] = t
+ add(id, {
+ fonts = nf.fonts,
+ characters = { [122] = t }
+ })
+
+ interfaces.setmacro("MyDemoFontId",id)
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\def\MyDemoFont{\setfontid\MyDemoFontId}
+\stopbuffer
+
+We also define a command to access this font:
+
+\typebuffer \getbuffer
+
+\startbuffer
+{\MyDemoFont \type{[122=}\char122\type{]}}
+{\MyDemoFont \type{[123=}\char123\type{]}}
+{\MyDemoFont \type{[124=}\char124\type{]}}
+{\MyDemoFont \type{[125=}\char125\type{]}}
+\stopbuffer
+
+and we test this font as follows:
+
+\typebuffer
+
+This gives:
+
+\startlines \getbuffer \stoplines
+
+Next we extend an existing font and demonstrate several methods for extending a
+font. First we define a font that we will patch.
+
+\startbuffer
+\definefontfeature[myextension-one][default][myextension=1]
+
+\definefont[MyDemoOne][Serif*myextension-one]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startluacode
+ local currentfont = font.current()
+ local fontdata = fonts.hashes.identifiers[currentfont]
+ local characters = fontdata.characters
+ local cfonts = fontdata.fonts
+ local addcharacters = font.addcharacters
+
+ local make = document.MakeGlyph
+
+ local function startextension()
+ statistics.starttiming()
+ end
+
+ local function stopextension(n)
+ context.NC() context.formatted.type("\\char%s",n)
+ context.NC() context.char(n)
+ context.NC() context("%0.3f",statistics.stoptiming())
+ context.NC() context.NR()
+ end
+
+ context.starttabulate { "||||" }
+
+ startextension()
+ for i=1000,1999 do
+ local t = make(3)
+ characters[i] = t
+ addcharacters(currentfont, {
+ fonts = cfonts,
+ characters = { [i] = t }
+ })
+ end
+ stopextension(1500)
+
+ startextension()
+ local t = {
+ fonts = cfonts,
+ characters = characters
+ }
+ for i=2000,2999 do
+ characters[i] = make(5)
+ addcharacters(currentfont, t)
+ end
+ stopextension(2500)
+
+ startextension()
+ for i=3000,3999 do
+ characters[i] = make(7)
+ end
+ addcharacters(currentfont, {
+ fonts = cfonts,
+ characters = characters
+ })
+ stopextension(3500)
+
+ startextension()
+ local t = { }
+ for i=4000,4999 do
+ characters[i] = make(9)
+ t[i] = characters[i]
+ end
+ addcharacters(currentfont, {
+ fonts = cfonts,
+ characters = t
+ })
+ stopextension(4500)
+
+ local addcharacters = fonts.constructors.addcharacters
+
+ startextension()
+ local t = { }
+ for i=5000,5999 do
+ t[i] = make(11)
+ end
+ addcharacters(currentfont, {
+ fonts = cfonts,
+ characters = t
+ })
+ stopextension(5500)
+
+ context.stoptabulate()
+\stopluacode
+\stopbuffer
+
+Watch how we only pass the new characters. We also need to make sure that the
+table at the \LUA\ end gets updated, because we might need the data later. You
+can see that not all methods are equally efficient. The last extension uses a
+helper that also makes sure that the main character table at the \LUA\ end gets
+updated.
+
+\typebuffer \start \MyDemoOne \getbuffer \stop
+
+\startbuffer
+\startluacode
+ local addcharacters = fonts.constructors.addcharacters
+ local currentfont = font.current()
+ local parameters = fonts.hashes.parameters[currentfont]
+
+ local m = metapost.simple
+ local f = string.formatters
+ ["draw fullsquare rotated %i scaled %b randomized 2bp withcolor %s"]
+
+ local push = { "push" }
+ local pop = { "pop" }
+
+ function make()
+ local r = parameters.size
+ local o = r/2
+ local p1 = m("metafun",f( 0, r, "red"))
+ local p2 = m("metafun",f(30, r, "green"))
+ local p3 = m("metafun",f(60, r, "blue"))
+ return {
+ width = o + r,
+ height = 2*o,
+ depth = o,
+ commands = {
+ { "down", -o/2 }, { "right", o/2 + o },
+ push, { "pdf", "origin", p1 }, pop,
+ push, { "pdf", "origin", p2 }, pop,
+ push, { "pdf", "origin", p3 }, pop,
+ },
+ }
+ end
+
+ local t = { }
+ for i=6000,6010 do
+ t[i] = make()
+ end
+ addcharacters(currentfont, {
+ fonts = cfonts,
+ characters = t
+ })
+\stopluacode
+\stopbuffer
+
+In this example we use \METAPOST\ to generate a shape. There is some juggling
+with dimensions and we need to shift the image in order to get a proper baseline.
+
+\typebuffer \start \MyDemoOne \showglyphs \getbuffer \stop
+
+These shapes show up as follows. We show the bounding box too:
+
+\startbuffer
+\scale [width=\textwidth] {%
+ \char6000 \space
+ \char6001 \space
+ \char6002 \space
+ \char6003
+}
+\stopbuffer
+
+\typebuffer \startlinecorrection \MyDemoOne \showglyphs \getbuffer \stoplinecorrection
+
+When defining virtual characters you need to keep in mind that there are limits to
+how large a character can be. If you go too far \LUATEX\ will quit with a scale
+related message.
+
+In \CONTEXT\ there are a couple of mechanism that were implemented when \LUATEX\
+came around that can be updated to use the tricks described here. I'm not sure if
+I'll do that. After all, it works now too. The main benefit of the fact that we
+can extend a font within reasonable bounds is that future mechanism can benefit
+from it.
+
+There is one thing to keep in mind. Say that we define a font like this:
+
+\starttyping
+\definefont[MyDemoOneX][Serif*myextension-one]
+\stoptyping
+
+Because we already defined a font with the same size, we automatically get the characters
+\type {6000} upto \type {6003}. If we don't want this and want a fresh instance, we can do:
+
+\starttyping
+\definefontfeature[myextension-two][default][myextension=2]
+\definefont[MyDemoOneX][Serif*myextension-two]
+\stoptyping
+
+or just:
+
+\starttyping
+\definefont[MyDemoOneX][Serif*default]
+\stoptyping
+
+Normally this kind of hackery is not arbitrary and part of a well designed set up
+so one knows what one gets.
+
+\stopsection
+
% - features
% - subfonts
% - outlines
% - math
% - hashes
-\stopsection
-
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex b/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex
index c5283ad41..fa53492f0 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex
@@ -21,7 +21,7 @@
%
% \usemodule[speedtest]
-\enabletrackers[fonts.files]
+\enabletrackers[fonts.usage]
\enablemode[simple] % ,oversized
@@ -66,6 +66,7 @@
\component fonts-math
\component fonts-extensions
\component fonts-hooks
+ \component fonts-tricks
\stopbodymatter
\startappendices
diff --git a/doc/context/sources/general/fonts/fonts/fonts-tricks.tex b/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
new file mode 100644
index 000000000..b8903b5ed
--- /dev/null
+++ b/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
@@ -0,0 +1,388 @@
+% language=uk
+
+\startcomponent fonts-tricks
+
+\environment fonts-environment
+
+\startchapter[title=Tricks][color=middleorange]
+
+\startsection[title=Introduction]
+
+In this chapter topics that don't fit in the previous chapters are
+collected.
+
+\stopsection
+
+\startsection[title=Extra characters]
+
+In one of our projects we need a small (high) minus and here we discuss
+one way of achieving this. An option is to define a new character
+and use a font feature to add it, as in:
+
+\starttyping
+\startluacode
+ local function addextraminus(tfmdata)
+ fonts.helpers.addprivate(tfmdata, "smallminus", ... ) -- see below
+ fonts.helpers.addprivate(tfmdata, "highminus", ... ) -- see below
+ end
+ fonts.constructors.newfeatures.otf.register {
+ name = "extraminus",
+ description = "extra minus symbols",
+ default = true,
+ manipulators = {
+ base = addextraminus,
+ node = addextraminus,
+ }
+ }
+\stopluacode
+\stoptyping
+
+However, why make it an option when we can just add it to any font. So,
+we can end up with just:
+
+\typebuffer[extraminus] % already defined before loading fonts
+
+It is important to do this before fonts get loaded. Next we need to decide how to
+access these characters. A straightforward way is:
+
+\startbuffer
+\def\smallminus{\privatechar{smallminus}}
+\def\highminus {\privatechar{highminus}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+An alternative is:
+
+\starttyping
+\definemathcommand [smallminus] [ord] {\privatechar{smallminus}}
+\definemathcommand [highminus] [ord] {\privatechar{highminus}}
+\stoptyping
+
+but that fails in text mode. So, we can consider:
+
+\starttyping
+\def\smallminus{\mathortext{\mathord{\privatechar{smallminus}}}{\privatechar{smallminus}}}
+\def\highminus {\mathortext{\mathord{\privatechar {highminus}}}{\privatechar {highminus}}}
+\stoptyping
+
+or more compact
+
+\starttyping
+\def\smallminus{\mathortext\mathord\firstofoneargument{\privatechar{smallminus}}}
+\def\highminus {\mathortext\mathord\firstofoneargument{\privatechar {highminus}}}
+\stoptyping
+
+What method you choose depends on usage. With the first, simple definitions we
+get this:
+
+\startbuffer
+[\getprivateslot{smallminus}] [\getprivatechar{smallminus}] [\smallminus] $[\smallminus]$\par
+[\getprivateslot {highminus}] [\getprivatechar {highminus}] [\highminus ] $[\highminus ]$\par
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because we are fully expandable we can even use this in:
+
+\startbuffer
+\bTABLE[aligncharacter=yes,alignmentcharacter={text->\smallminus}]
+ \bTR \bTD \mathminus100\smallminus00+ \eTD \eTR
+ \bTR \bTD 100\smallminus00 \eTD \eTR
+ \bTR \bTD \mathminus 99\smallminus00+ \eTD \eTR
+ \bTR \bTD \mathminus 99\smallminus00 \eTD \eTR
+ \bTR \bTD 100\highminus \eTD \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+With the other definitions the alignment would not work. If you need both then
+you can define different commands for text and math.
+
+\stopsection
+
+\startsection[title=Tabular numbers]
+
+Some font features are meant to be used in controlled situations. An example is
+the \type {tnum} feature that triggers so called \quote {tabular figures} meaning
+numbers that have equal widths. Its opposite feature is \type {lnum} or lining
+figures. We have two predefined \CONTEXT\ font features for this:
+
+\starttyping
+\definefontfeature [inlinenumbers] [lnum=yes,tnum=no]
+\definefontfeature [tabularnumbers] [tnum=yes,lnum=no]
+\stoptyping
+
+Some mechanisms in \CONTEXT\ had better be aware of this and one of them is the
+alignment mechanism in tables.
+
+\startbuffer[demo]
+\startcombination[before=,after=]
+ \startcontent
+ \switchtobodyfont[pagella]\showglyphs%
+ \disabledirectives[typesetters.characteralign.autofont]%
+ \bTABLE[alignmentcharacter=.,aligncharacter=yes]
+ \bTR \bTD 11.111 \eTD \eTR
+ \bTR \bTD 2.2 \eTD \eTR
+ \bTR \bTD 444.444 \eTD \eTR
+ \eTABLE
+ \enabledirectives[typesetters.characteralign.autofont]%
+ \stopcontent
+ \startcaption
+ \small manual \type {tnum}
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[pagella]\showglyphs%
+ \bTABLE[alignmentcharacter=.,aligncharacter=yes]
+ \bTR \bTD 11.111 \eTD \eTR
+ \bTR \bTD 2.2 \eTD \eTR
+ \bTR \bTD 444.444 \eTD \eTR
+ \eTABLE
+ \stopcontent
+ \startcaption
+ \small auto \type {tnum}
+ \stopcaption
+\stopcombination
+\stopbuffer
+
+In the following examples we demonstrate how the automatic font adaption makes
+sure that tabular figures are used. The table is defined as:
+
+\typebuffer[demo]
+
+\startbuffer
+\dontleavehmode\hbox to .3\textwidth \bgroup
+ \hss\getbuffer[demo]\hss
+\egroup
+\stopbuffer
+
+In \in {figure}[fig:tabularnumbers] we see what the features do. We use the \type
+{\feature} or \type {\addfeature} macro for this. For the moment this trickery is
+controlled by a directive (beware: enabling them is global).
+
+\startplacefigure[reference=fig:tabularnumbers,title={Tabular numbers}]
+ \startcombination[nx=3,ny=2]
+ {\getbuffer} {\tt\nohyphens default}
+ {\addfeature [inlinenumbers]\getbuffer} {\tt\nohyphens inlinenumbers}
+ {\addfeature [tabularnumbers]\getbuffer} {\tt\nohyphens tabularnumbers}
+ {\addfeature[oldstylenumbers]\getbuffer} {\tt\nohyphens oldstylenumbers}
+ {\addfeature[oldstylenumbers]%
+ \addfeature [inlinenumbers]\getbuffer} {\tt\nohyphens oldstylenumbers\par inlinenumbers}
+ {\addfeature[oldstylenumbers]%
+ \addfeature [tabularnumbers]\getbuffer} {\tt\nohyphens oldstylenumbers\par tabularnumbers}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Symbols]
+
+You can access glyphs by name but you need to know that name, for example:
+
+\startbuffer
+\definefontsynonym [bends] [file:manfnt.afm]
+
+\startsymbolset [Dangerous Bends]
+ \definesymbol [dbend] [\resolvedglyphdirect{bends}{n:char_7e}]
+ \definesymbol [lhdbend] [\resolvedglyphdirect{bends}{n:char_7f}]
+\stopsymbolset
+
+\setupsymbolset [Dangerous Bends]
+
+Two dangerous bends: \symbol{dbend} and \symbol{lhdbend}.
+\stopbuffer
+
+\typebuffer
+
+You can best save the fonts you use that way in a place that doesn't get
+overwritten because names can change.
+
+\getbuffer
+
+\stopsection
+
+\startsection[title=Alternative styles]
+
+\startbuffer[demo]
+ \start
+ \getbuffer[setup]
+ \subject{[ {\myslanted myslanted} ] [ {\it it} ] [ {\slanted slanted} ] [ $x=1$ ]}
+ [ {\myslanted myslanted} ] [ {\it it} ] [ {\slanted slanted} ] [ $x=1$ ]
+ \typebuffer[setup]
+ \blackrule[width=\hsize,height=1pt,depth=0pt]
+ \stop
+\stopbuffer
+
+In section heads we want a nested style (e.g.\ italic) to adapt to the main font.
+The following definitions shows how you can influence that process. We use the
+following \type {demo} buffer as sample:
+
+\typebuffer[demo]
+
+\startbuffer
+\blackrule[width=\hsize,height=1pt,depth=0pt]
+
+\startbuffer[setup]
+\setuphead[subject][style=\tfb,before=,after=]
+\definealternativestyle [myslanted] [\it] []
+\stopbuffer
+
+\getbuffer[demo]
+
+\startbuffer[setup]
+\setuphead[subject][style=\tfb,before=,after=]
+\definealternativestyle [myslanted] [\it] [\bi]
+\stopbuffer
+
+\getbuffer[demo]
+
+\startbuffer[setup]
+\setuphead[subject][style=\tfb,before=,after=]
+\definealternativestyle [myslanted] [\it] [\tf]
+\stopbuffer
+
+\getbuffer[demo]
+
+\startbuffer[setup]
+\definealternativestyle [myslanted] [\normalitalicface]
+\setuphead[subject][style=bold,before=,after=]
+\stopbuffer
+
+\getbuffer[demo]
+
+\startbuffer[setup]
+\definealternativestyle [myslanted] [\normalitalicface]
+\setuphead[subject][style=\bfd,before=,after=]
+\stopbuffer
+
+\getbuffer[demo]
+
+\startbuffer[setup]
+\definealternativestyle [myslanted] [\slantedface]
+\setuphead[subject][style=boldface,before=,after=]
+\stopbuffer
+
+\getbuffer[demo]
+\stopbuffer
+
+You can influence the main method of operation with:
+
+\starttyping
+\setupalternativestyles[method=normal]
+\setupalternativestyles[method=auto]
+\stoptyping
+
+\startplacefigure[title={Alternative style methods.},reference=fig:alternativestyle]
+ \startcombination
+ {\setupalternativestyles[method=normal]\scale[width=.45\textwidth]{\framed[width=.85\textwidth,align=normal,frame=off,offset=overlay]{\getbuffer}}} {\type{method=normal}}
+ {\setupalternativestyles [method=auto]\scale[width=.45\textwidth]{\framed[width=.85\textwidth,align=normal,frame=off,offset=overlay]{\getbuffer}}} {\type{method=auto}}
+ \stopcombination
+\stopplacefigure
+
+The result is shown in \in {figure} [fig:alternativestyle]. Relevant commands are:
+
+\starttyping
+\emphasistypeface
+\emphasisboldface
+
+\normaltypeface \typeface
+\normalboldface \boldface
+\normalslantedface \slantedface
+\normalitalicface \italicface
+\swaptypeface \swapface
+\stoptyping
+
+\stopsection
+
+\startsection[title={A virtual hack}]
+
+Here is some virtual trickery. A virtual font is just a font but instead of a
+character being a reference to a slot in a font (often via an index) it
+constructs a glyph from whatever characters, rules, displacements, inline \PDF\
+code, etc. We use them a lot deep down in \CONTEXT. The next example defines two
+characters represented by rules. This definition is about as minimalistic as
+reasonable and demonstrates how we can apply expansion (aka hz) to such a font.
+\footnote {You need \LUATEX\ 1.08 or later for this.} We store the font id (a
+number) in a macro. Watch how we don't refer to a glyph in a font. Because we
+don't specify its type as \type {virtual} we can leave out the \type {font}
+table. After all, we don't refer to real glyphs.
+
+\startbuffer
+\startluacode
+local d = 400000 -- just over 6pt
+local a = font.define {
+ characters = {
+ [string.byte("A")] =
+ {
+ width = d,
+ depth = d,
+ commands = { { "down", d }, { "rule", d, d } },
+ expansion_factor = 1000,
+ },
+ [string.byte("B")] =
+ {
+ width = d,
+ height = d,
+ commands = { { "rule", d, d } },
+ expansion_factor = 500,
+ },
+
+ },
+ parameters = {
+ space = 2*d,
+ space_stretch = d,
+ space_shrink = d,
+ },
+ stretch = 8,
+ shrink = 8,
+ step = 2,
+ name = "foo"
+}
+
+tex.count.scratchcounter = a
+\stopluacode
+
+\edef\MyFontID{\the\scratchcounter}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+% \enabletrackers[*expans*]
+
+\startbuffer
+\startoverlay
+ {\vbox \bgroup
+ \setuptolerance[verytolerant,stretch]
+ \setfontid\MyFontID
+ \dorecurse{5}{ABABABABABABABABABABABABABABABABA }
+ \egroup}
+ {\vbox \bgroup
+ \normaladjustspacing2
+ \middlegray
+ \setuptolerance[verytolerant,stretch]
+ \setfontid\MyFontID
+ \dorecurse{5}{ABABABABABABABABABABABABABABABABA }
+ \egroup}
+\stopoverlay
+\stopbuffer
+
+We test this with some rather low level code and show the result in \in {figure}
+[fig:virtualhack]. Of course you will never define a font this way if only
+because we don't set important parameters and this version is not generic in the
+sense that it scales well. You can find better examples elsewhere in the manual
+and in the distribution.
+
+\typebuffer
+
+\startplacefigure[title={A virtual hack.},reference=fig:virtualhack]
+ \getbuffer
+\stopplacefigure
+
+\stopsection
+
+\stopchapter