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 | 2729 |
1 files changed, 0 insertions, 2729 deletions
diff --git a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex deleted file mode 100644 index afe6fd823..000000000 --- a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex +++ /dev/null @@ -1,2729 +0,0 @@ -% language=uk - -\startcomponent fonts-extensions - -\environment fonts-environment - -\startchapter[title=Extensions][color=darkorange] - -\startsection[title=Introduction] - -One of the benefits of using \TEX\ is that you can add your own features and try -to optimize the look and feel. Of course this can also go wrong and output can -look pretty awful when you don't know what you're doing, but on the average it -works out well. In many aspects the move to an \UNICODE\ data path and \OPENTYPE\ -fonts is a good one and solves a lot of problems with traditional \TEX\ engines -and helps us to avoid complex and ugly hacks. But, if you look into the source -code of \CONTEXT\ you will notice that there's still quite some complex coding -needed. This is because we want to control mechanisms, even if it's only for -dealing with some border cases. It's also the reason why \LUATEX\ is what it is: -an extensible engine, building on tradition. - -As always with \TEX, fonts are an area where many tuning happens and this is also -true in \CONTEXT. In this chapter some of the extensions will be discussed. Some -extensions run on top of the (rather generic) feature mechanism and some are -using dedicated code. - -\stopsection - -\startsection[title=Italics] - -Although \OPENTYPE\ fonts are more rich in features than traditional \TEX\ and -\TYPEONE\ fonts, one important feature is missing: italic correction. This might -sound strange but you need to keep in mind that in practice it's a feature that -needs to be applied manually. - -\starttyping -test {\it test\/} test -\stoptyping - -It is possible to automate this mechanism and this is what the \type {\em} command -does in \MKII: - -\starttyping -test {\em test} test -\stoptyping - -This command knows that it switches to italic (or slanted) and when used nested it -knows to switch back. It also knows if a bold italic or slanted font is used. Therefore -it can add italic correction between an italic and upright shape. - -An italic correction is bound to a glyph and bound to a font. In \in {figure} -[latinmodern-italic] we see how an italic shape extends out of the bounding box. -This is not the case in Dejavu: watch \in {figure} [dejavu-italic]. - -\startplacefigure[reference=latinmodern-italic,title={Italic overshoot in Latin Modern.}] - \startcombination - \startcontent - \backgroundline[gray]{\color[maincolor]{\definedfont[lmroman10-regular*default sa 8]test}} - \stopcontent - \startcaption - Latin Modern Roman Regular - \stopcaption - \startcontent - \backgroundline[gray]{\color[maincolor]{\definedfont[lmroman10-italic*default sa 8]test}} - \stopcontent - \startcaption - Latin Modern Roman Italic - \stopcaption - \stopcombination -\stopplacefigure - -\startplacefigure[reference=dejavu-italic,title={Italic overshoot in Dejavu Serif.}] - \startcombination - \startcontent - \backgroundline[gray]{\color[maincolor]{\definedfont[dejavuserif*default sa 8]test}} - \stopcontent - \startcaption - Dejavu Regular - \stopcaption - \startcontent - \backgroundline[gray]{\color[maincolor]{\definedfont[dejavuserifitalic*default sa 8]test}} - \stopcontent - \startcaption - Dejavu Italic - \stopcaption - \stopcombination -\stopplacefigure - -This means that the application of italic correction should never been applied without -knowing the font. In \in {figure} [italic-upright] we see an upright word following -an italic. The space is determined by the upright one. - -\startplacefigure[reference=italic-upright,title={Italic followed by upright.}] - \startcombination - \startcontent - \backgroundline - [gray] - {\color[maincolor]{\definedfont[lmroman10-italic*default sa 4]test} - \color[maincolor]{\definedfont[lmroman10-regular*default sa 4]\space test}} - \stopcontent - \startcaption - Latin Modern - \stopcaption - \startcontent - \backgroundline - [gray] - {\color[maincolor]{\definedfont[dejavuserifitalic*default sa 4]test}% - \color[maincolor]{\definedfont[dejavuserif*default sa 4]\space test}} - \stopcontent - \startcaption - Dejavu - \stopcaption - \stopcombination -\stopplacefigure - -Because it is to be used with care you need to enable this feature per font, You -also need to explicitly enable the application of this correction. in \in {figure} -[italic-one] we see italic correction in action. - -\startbuffer -\definefontfeature - [italic] - [default] - [itlc=yes] -\stopbuffer - -\typebuffer - -\getbuffer - -\startplacefigure[reference=italic-one,title={Italic correction.}] - \startcombination - \startcontent - \backgroundline - [maincolor] - {\color[white]{\definedfont[lmroman10-italic*default sa 4]test} - \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}} - \stopcontent - \startcaption - \backgroundline - [maincolor] - {\setupitaliccorrection[text]% - \color[white]{\definedfont[lmroman10-italic*italic sa 4]test} - \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}} - \stopcaption - \startcontent - \backgroundline - [maincolor] - {\color[white]{\definedfont[dejavuserifitalic*default sa 4]test} - \color[white]{\definedfont[dejavuserif*default sa 4]\space test}} - \stopcontent - \startcaption - \backgroundline - [maincolor] - {\setupitaliccorrection[text]% - \color[white]{\definedfont[dejavuserifitalic*italic sa 4]test} - \color[white]{\definedfont[dejavuserif*default sa 4]\space test}} - \stopcaption - \stopcombination -\stopplacefigure - -This only signals the font constructor that additional italic information has -to be added to the font metrics. As we already mentioned, the application of -correction is driven by the \type {\/} primitive and that one consults the -font metrics. Because the correction is not part of the original font -metrics it is calculated automatically by adding a small value to the -width. This value is calculated as follows: - -\starttyping -factor * (parameters.uwidth or 40) / 2 -\stoptyping - -The \type {uwidth} parameter is sometimes part of the specification but if not, we -take a reasonable default. The factor is under user control: - -\startbuffer -\definefontfeature - [moreitalic] - [default] - [itlc=5] -\stopbuffer - -\typebuffer - -\getbuffer - -This is demonstrated in \in {figure} [italic-two]. You will notice that for Latin -Modern (any) correction makes sense, but for Dejavu it probably makes things look -worse. This is why italic correction is disabled by default. When enabled there -are several variants: - -\starttabulate[|Bl|l|] -\NC global \NC always apply correction \NC \NR -\NC text \NC only apply correction to text \NC \NR -\NC always \NC apply correction between text and boxes \NC \NR -\NC none \NC forget about correction \NC \NR -\stoptabulate - -We keep track of the state using attributes but that comes at a (small) price in terms -of extra memory and runtime. The \type {global} option simply assumes that we always -need to check for correction (of course only for fonts that have this feature enables). -In the given example we used: - -\starttyping -\setupitaliccorrection - [text] -\stoptyping - -You can combine keys: - -\starttyping -\setupitaliccorrection - [global,always] -\stoptyping - -\startplacefigure[reference=italic-two,title={Italic correction (factor 5).}] - \startcombination - \startcontent - \backgroundline - [maincolor] - {\color[white]{\definedfont[lmroman10-italic*default sa 4]test} - \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}} - \stopcontent - \startcaption - \backgroundline - [maincolor] - {\setupitaliccorrection[text]% - \color[white]{\definedfont[lmroman10-italic*italic sa 4]test} - \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}} - \stopcaption - \startcontent - \backgroundline - [maincolor] - {\color[white]{\definedfont[dejavuserifitalic*default sa 4]test} - \color[white]{\definedfont[dejavuserif*default sa 4]\space test}} - \stopcontent - \startcaption - \backgroundline - [maincolor] - {\setupitaliccorrection[text]% - \color[white]{\definedfont[dejavuserifitalic*italic sa 4]test} - \color[white]{\definedfont[dejavuserif*default sa 4]\space test}} - \stopcaption - \stopcombination -\stopplacefigure - -The \type {itlc} feature controls if a font gets italic correction applied. In -principle this is all that the user needs to do, given that the mechanism is -enabled. These is an extra feature that controls the implementation: - -\starttabulate[|T|T|p|] -\NC itlc \NC no \NC don't apply italic correction (default) \NC \NR -\NC \NC yes \NC apply italic correction \NC \NR -\NC textitalics \NC no \NC precalculate italic corrections (permit engine usage) \NC \NR -\NC \NC yes \NC precalculate italic corrections (inhibit engine) \NC \NR -\NC \NC delay \NC delay calculation of corrections \NC \NR -\stoptabulate - -When \type {textitalics} is set to \type {yes} or \type {delay} the mechanism -built into the engine is completely disabled. When set to \type {no} the engine -can kick in but normally the alternative method takes precedence so that the -engine sees no reason for further action. You can trace italic corrections with: - -\starttyping -\enabletrackers[typesetters.italics] -\stoptyping - -\stopsection - -\startsection[title=Bounding boxes] - -\startbuffer -\definefontfeature - [withbbox] - [boundingbox=yes] - -\definefont - [FontWithBB] - [Normal*withbbox] -\stopbuffer - -\start \getbuffer \FontWithBB - -There are some features that are rather useless and only make sense when figuring out -issues. An example of such a feature is the following: - -\typebuffer - -This feature adds a background to each character in a font. In some fonts a glyph -has a tight bounding box, while on other fonts some extra space is put on the left -and right. Keep in mind that this feature blocks colored text. - -\par \stop - -\stopsection - -\startsection[title=Math italics] - -In the traditional \TEX\ fonts the width of a glyph was not the real width because -one had to add the italic correction to it. The engine then juggles a bit with -these properties. If you run into fonts that are designed this way, you can do this: - -\starttyping -\definefontfeature[mathextra][italicwidths=yes] % fix latin modern -\stoptyping - -This might make \type {$\left|V\right| = \left|W\right|$} look better for such -fonts. Of course there can be side effects because these fonts assume a -traditional engine. - -\stopsection - -\startsection[title=Slanting] - -This features (as well as the one described in the next section) are seldom used -but provided because they were introduced in \PDFTEX. - -\startbuffer[define] -\definefontfeature - [abitslanted] - [default] - [slant=.1] - -\definefontfeature - [abitmoreslanted] - [default] - [slant=.2] -\stopbuffer - -\startbuffer[sample] -\definedfont[Normal*abitslanted]This is a bit slanted. -\definedfont[Normal*abitmoreslanted]And this is a bit more slanted. -\stopbuffer - -\typebuffer[define,sample] - -The result is: - -\getbuffer[define] - -\startlines -\getbuffer[sample] -\stoplines - -\stopsection - -\startsection[title=Extending] - -The second manipulation is extending the shapes horizontally: - -\startbuffer[define] -\definefontfeature - [abitbolder] - [default] - [extend=1.3] - -\definefontfeature - [abitnarrower] - [default] - [extend=0.7] -\stopbuffer - -\startbuffer[sample] -\definedfont[Normal*abitbolder]This looks a bit bolder. -\definedfont[Normal*abitnarrower]And this is a bit narrower. -\stopbuffer - -\typebuffer[define,sample] - -The result is: - -\getbuffer[define] - -\startlines -\getbuffer[sample] -\stoplines - -We can also combine slanting and extending: - -\startbuffer[define] -\definefontfeature - [abitofboth] - [default] - [extend=1.3, - slant=.1] -\stopbuffer - -\startbuffer[sample] -\definedfont[Normal*abitofboth]This is a bit bolder but also slanted. -\stopbuffer - -\typebuffer[define,sample] - -If you remember those first needle matrix printers you might recognize the -next rendering: - -\getbuffer[define] - -\startlines -\getbuffer[sample] -\stoplines - -\stopsection - -\startsection[title=Fixing] % dimensions - -This is a rather special one. First we show a couple of definitions: - -\startbuffer -\definefontfeature - [dimensions-a] - [default] - [dimensions={1,1,1}] - -\definefontfeature - [dimensions-b] - [default] - [dimensions={1,2,3}] - -\definefontfeature - [dimensions-c] - [default] - [dimensions={1,3,2}] - -\definefontfeature - [dimensions-d] - [default] - [dimensions={3,3,3}] -\stopbuffer - -\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 -\definefont[MyFont][Serif*dimensions-a sa 2] -\stoptyping - -Alternatively you can use such a feature on its own: - -\starttyping -\definefontfeature - [dimensions-333] - [dimensions={3,3,3}] -\definefont[MyFont][Serif*default,dimensions-333 sa 2] -\stoptyping - -In \in {figure} [dimensions-side-by-side] you see these four definitions in -action. The leftmost rendering is the default rendering. The three numbers in the -definitions represent the width (in em), height and depth (in ex). - -\startplacefigure[reference={dimensions-side-by-side},title={Freezing dimensions of glyphs.}] - \startcombination[5*1] - \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*default sa 2]g}\hss}\stopcontent \startcaption default \stopcaption - \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-a sa 2]g}\hss}\stopcontent \startcaption \hbox{1em 1ex 1ex} \stopcaption - \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-b sa 2]g}\hss}\stopcontent \startcaption \hbox{1em 2ex 3ex} \stopcaption - \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-c sa 2]g}\hss}\stopcontent \startcaption \hbox{1em 3ex 2ex} \stopcaption - \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-d sa 2]g}\hss}\stopcontent \startcaption \hbox{3em 3ex 3ex} \stopcaption - \stopcombination -\stopplacefigure - -This feature only makes sense for fonts that need a fixed width, like the -\CJK\ fonts that are used for asian scripts. Normally those fonts already -have fixed dimensions, but this feature can be used to fix problematic -fonts or add some more space. However, for such large fonts this also brings a -larger memory footprint. - -A special case is the following: - -\startbuffer -\definefontfeature - [dimensions-e] - [dimensions=strut] -\stopbuffer - -\typebuffer \getbuffer - -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} -\ruledhbox{\definedfont[Serif*default,dimensions-e at 12pt]clipped} -\ruledhbox{\definedfont[Serif*default,dimensions-e at 24pt]clipped} -\stopbuffer - -\typebuffer - -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] - -Nowadays we will mostly use fonts that ship with a \UNICODE\ aware encoding. And -in \CONTEXT, even if we use a \TYPEONE\ font, it gets mapped onto \UNICODE. -However, there are some exceptions, for instance the Zapf Dingbats in \TYPEONE\ -format. These have a rather obscure private encoding and the glyph names run from -\type {a1} upto \type {a206} and have no relation to what the glyph represents. - -In the case of Dingbats we're somewhat lucky that they ended up in \UNICODE, so -we can relocate the glyphs to match their rightful place. This is done by means -of a goodies file. We already discussed this in \in {section} [goodies] so we -only repeat the usage. - -\startbuffer -\definefontfeature - [dingbats] - [mode=base, - goodies=dingbats, - unicoding=yes] - -\definefontsynonym - [ZapfDingbats] - [file:uzdr.afm] - [features=dingbats] -\stopbuffer - -\typebuffer \getbuffer - -I tend to qualify the Dingbat font in \TEX\ distributions as rather unstable -because of name changes and them either or not being included. Therefore it's best to -use the hard coded name because that triggers the most visible error message when -the font is not found. - -A font like this can for instance be used with the glyph placement macros as is -demonstrated below. In the last line we see that a direct \UTF\ input also works -out well. - -\starttabulate[|||T|] -\HL -\NC \type{\getglyphdirect {ZapfDingbats*dingbats}{\number"2701}} \NC \getglyphdirect {ZapfDingbats*dingbats}{\number"2701} \NC \NC \NR -\NC \type{\getglyphdirect {ZapfDingbats*dingbats}{\char"2701}} \NC \getglyphdirect {ZapfDingbats*dingbats}{\char"2701} \NC \NC \NR -\NC \type{\getnamedglyphdirect{ZapfDingbats*dingbats}{a1}} \NC \getnamedglyphdirect{ZapfDingbats*dingbats}{a1} \NC \NC \NR -\NC \type{\getnamedglyphdirect{ZapfDingbats*dingbats}{a11}} \NC \getnamedglyphdirect{ZapfDingbats*dingbats}{a11} \NC \NC \NR -\HL -\NC \type{\getglyphdirect {ZapfDingbats}{\number"2701}} \NC \getglyphdirect {ZapfDingbats}{\number"2701} \NC unknown \NC \NR -\NC \type{\getglyphdirect {ZapfDingbats}{\char"2701}} \NC \getglyphdirect {ZapfDingbats}{\char"2701} \NC unknown \NC \NR -\NC \type{\getnamedglyphdirect{ZapfDingbats}{a1}} \NC \getnamedglyphdirect{ZapfDingbats}{a1} \NC \NC \NR -\NC \type{\getnamedglyphdirect{ZapfDingbats}{a11}} \NC \getnamedglyphdirect{ZapfDingbats}{a11} \NC \NC \NR -\HL -\NC \type{\definedfont[ZapfDingbats*dingbats]✁} \NC \definedfont[ZapfDingbats*dingbats]✁ \NC \NC \NR -\HL -\stoptabulate - -Keep in mind that fonts like Dejavu (that we use here as document font) already -has these characters which is why it shows up in the verbose part of the table. - -\stopsection - -\startsection[title=Protrusion] - -Protrusion is a feature that \LUATEX\ inherits from \PDFTEX. It is sometimes -referred to as hanging punctuation but in our case any character qualifies. Also, -hanging is not frozen but can be tuned in detail. Currently the engine defines -protrusion in terms of the emwidth which is unfortunate and likely to change. -\footnote {In general the low level implementation can be optimized as there are -better mechanisms in \LUATEX.} - -It is sometimes believed that protrusion improves for instance narrower columns, -but I'm pretty sure that this is not the case. It is true that it is taken into -account when breaking a paragraph into lines, and that we then have a little bit -more width available, but at the same time it is an extra constraint: if we -protrude we have to do it for each line (and the whole main body of text) so it's -just a different solution space. The main reason for applying this feature is -{\em not} that the lines look better or that we get better looking narrow lines -but that the right and left margins look nicer. Personally I don't like half -protrusion of punctuation and hyphens. Best is to have small values for regular -characters to improve the visual appearance and use full protrusion for hyphens -(and maybe punctuation). - -\startsubsubject[title=protrusion classes] - -In \CONTEXT\ we've always defined protrusion as a percentage of the width of a -glyph. From \MKII\ we inherit the level of control as well as the ability to -define vectors. The shared properties are collected in so called classes and the -character specific properties in vectors. The following classes are predefined: - -\showprotrusionclass - -The names are used in the definitions: - -\starttyping -\definefontfeature[default][protrusion=quality] -\stoptyping - -Currently adding a class only has a \LUA\ interface. - -\startbuffer -\startluacode -fonts.protrusions.classes.myown = { - vector = 'myown', - factor = 1, -} -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -\stopsubsubject - -\startsubsubject[title=protrusion vectors] - -Vectors are larger but not as large as you might expect. Only a subset of -characters needs to be defined. This is because in practice only latin scripts -are candidates and these scripts have glyphs that look a lot like each other. As -we only operate on the horizontal direction characters like \quote -{aàáâãäå} look the same from the left and right so we only have to define -the protrusion for \quote {a}. - -As with classes, you can define your own vectors: - -\startbuffer -\startluacode -fonts.protrusions.vectors.myown = table.merged ( - fonts.protrusions.vectors.quality, - { - [0x002C] = { 0, 2 }, -- comma - } -) -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -\stopsubsubject - -\startsubsubject[title=protrusion vector pure] - \showprotrusionvector[name=pure] -\stopsubsubject - -\startsubsubject[title=protrusion vector punctuation] - \showprotrusionvector[name=punctuation] -\stopsubsubject - -\startsubsubject[title=protrusion vector alpha] - \showprotrusionvector[name=alpha] -\stopsubsubject - -\startsubsubject[title=protrusion vector quality] - \showprotrusionvector[name=quality] -\stopsubsubject - -\startsubsubject[title=examples of protrusion] - -Next we show the quality protrusion. For this we use \type {tufte.tex} as -this one for sure will result in punctuation and other candidates for -protrusion. - -\startbuffer[define] -\definefontfeature - [whatever] - [default] - [protrusion=quality] - -\definefont[MyTestA][Serif*default at 10pt] -\definefont[MyTestB][Serif*whatever at 10pt] -\stopbuffer - -\startbuffer[example] -\startoverlay - {\ruledvbox \bgroup - \hsize\textwidth - \MyTestA - \setupalign[normal] - \input{tufte} - \egroup} - {\ruledvbox \bgroup - \hsize\textwidth - \MyTestB - \setupalign[hanging,normal] - \maincolor - \input{tufte} - \egroup} -\stopoverlay -\stopbuffer - -\typebuffer[define] -\getbuffer [define] - -We use the following example. The results are shown in \in {figure} -[protrusion:quality]. The colored text is the protruding one. - -\typebuffer[example] - -\startplacefigure[reference=protrusion:quality,title=The difference between no protrusion and quality protrusion.] - \getbuffer [example] -\stopplacefigure - -The previously defined own class and vector is somewhat more extreme: - -\startbuffer[define] -\definefontfeature - [whatever] - [default] - [protrusion=myown] - -\definefont[MyTestA][Serif*default at 10pt] -\definefont[MyTestB][Serif*whatever at 10pt] -\stopbuffer - -\typebuffer[define] -\getbuffer [define] - -In \in {figure} [protrusion:myown] we see that the somewhat extreem definition of -the comma also pulls the preceding character into the margin. - -\startplacefigure[reference=protrusion:myown,title=The influence of extreme protrusion on preceding characters.] - \getbuffer [example] -\stopplacefigure - -\stopsubsubject - -\stopsection - -\startsection[title=Expansion] - -Expansion is also an inheritance of \PDFTEX. \footnote {As with protrusion the -implementation in the engine is somewhat suboptimal and inefficient and will be -upgraded to a more \LUATEX-ish way.} This mechanism selectively expands -characters, normally upto 5\%. One reason for applying it is that we have less -visually incompatible spacing, especially when we have underfull or cramped -lines. For each (broken) line the badness is reconsidered with either shrink or -stretch applied to all characters in that line. So, in the worst case a shrunken -line is followed by a stretched one and that can be visible when the scaling -factors are chosen wrong. - -As with protrusion, the solution space is larger but so are the constraints. But -contrary to protrusion here the look and feel of the whole line can be made -better but at the cost of much more runtime and larger (\PDF) files. - -\startsubsubject[title=protrusion classes] - -The amount of expansion depends in the shape of the character. Vertical strokes -are more sensitive for expansion then horizontal ones. So an \quote {o} can -get a different scaling than an \quote {m}. As with protrusion we have collected -the properties in classes: - -\showexpansionclass - -The smaller the step, the more instances of a font we get, the better it -looks, and the larger the files become. it's best not to use too many stretch -and shrink steps. A stretch of 2 and shrink of 2 and step of .25 results in -upto 8~instances plus the regular sized one. - -\stopsubsubject - -\startsubsubject[title=expansion vectors] - -We only have one vector: \type {quality}: - -\showexpansionvector[name=quality] - -\stopsubsubject - -\startsubsubject[title=an example of expansion] - -We use \type {zapf.tex} as example text, if only because Hermann Zapf introduced -this optimization. Keep in mind that you can combine expansion and protrusion. - -\startbuffer[define] -\definefontfeature - [whatever] - [default] - [expansion=quality] - -\definefont[MyTestA][Serif*default at 10pt] -\definefont[MyTestB][Serif*whatever at 10pt] -\stopbuffer - -\startbuffer[example] -\startoverlay - {\ruledvbox \bgroup - \hsize\textwidth - \MyTestA - \setupalign[normal] - \input{tufte} - \egroup} - {\ruledvbox \bgroup - \hsize\textwidth - \MyTestB - \setupalign[hz,normal] - \maincolor - \input{tufte} - \egroup} -\stopoverlay -\stopbuffer - -\typebuffer[define] -\getbuffer [define] - -We use the following example. The results are shown in \in {figure} -[expansion:quality]. The colored text is the protruding one. - -\typebuffer[example] - -\startplacefigure[reference=expansion:quality,title=The difference between no expansion and quality expansion.] - \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 - -\stopsubsubject - -\startsubsubject[title=Expansion and kerning] - -When we expand glyphs we also need to look at the font kerns between them. In the -original implementation taken from \PDFTEX\ expansion was implemented using pseudo -fonts (with expanded glyph widths) and expansion of inter|-|character kerns was -based on font information. In \LUATEX\ we have expansion factors in glyph nodes -instead which is more efficient and gives a cleaner separation between front- and -backend as the backend has no need to consult the font. - -For the font kerns we set the kern compensation directly and for that we use the -average expansion factors of the neighbouring fonts so technically we support -kerns between different fonts). This also has the advantage that kerns injected -in node mode are treated well, given that they are tagged as font kern. - -So what is the effect (and need) of scaling font kerns? Let's look at an example. -Kerns can be positive but also negative: - -\startlinecorrection -\startcombination - {\vbox { - \forgetall - \hpack to 3cm{\hss\ruledhbox{\maincolor V\kern-1ptA}\hss} - \hpack to 3cm{\hss\ruledhbox{\maincolor V\kern 0ptA}\hss} - }} {negative} - {\vbox { - \forgetall - \hpack to 3cm{\hss\ruledhbox{\maincolor I\kern.25ptI}\hss} - \hpack to 3cm{\hss\ruledhbox{\maincolor I\kern 0ptI}\hss} - }} {positive} -\stopcombination -\stoplinecorrection - -If we use a rediculous amount of stretch we get the following. In the top line we -scale the kern, in the bottom line we don't. - -\startlinecorrection -\startcombination - {\vbox { - \definedfont[file:texgyrepagella-regular.otf at 12pt]% - \forgetall - \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{V}\kern-5pt\scale[xscale=5000]{A}\hss} - \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{V}\kern-1pt\scale[xscale=5000]{A}\hss} - }} {negative} - {\vbox { - \definedfont[file:texgyrepagella-regular.otf at 12pt]% - \forgetall - \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{I}\kern1.25pt\scale[xscale=5000]{I}\hss} - \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{I}\kern0.25pt\scale[xscale=5000]{I}\hss} - }} {positive} -\stopcombination -\stoplinecorrection - -The reason that we mention this is that when we apply \OPENTYPE\ features, -positioning not necessarily result in font kerns. For instance ligatures can be -the result of careful applied kerns and in some scripts kerns are used to connect -glyphs. This means that we best cannot expand kerns by default. How bad is -that? By looking at the examples above one would say \quotation {real bad}. - -But say that we have about 1pt of font kerns, then a 5\% expansion (which is -already a lot) amounts to 0.05pt so to \blackrule [width=1pt, height=max, -depth=max] we add \blackrule [width=.05pt, height=max, depth=max] which is so -little that it probably goes unnoticed. Even if we use extreme kerns, as between -VA, in practice the small amount of stretch or shrink added to a font kern goes -unnoticed. - -In \in {figure} [hz:natural] we have overlayed the different strategies. The -sample and width is chosen such that we see something. On a display you can -scale up these examples and inspect if there is really something to see, -but on paper zooming in helps, as in \in {figure} [hz:zoomed]. Even then the -effect of expanded kerns is invisible. The used definitions are: - -\definecolor[hz:test:tr][r=1,a=1,t=.5] -\definecolor[hz:test:tg][g=1,a=1,t=.5] -\definecolor[hz:test:tb][b=1,a=1,t=.5] - -\startbuffer -\setupfontexpansion - [extremehz] - [stretch=5,shrink=5,step=.5,vector=default,factor=1] -\setupfontexpansion - [regularhz] - [stretch=2,shrink=2,step=.5,vector=default,factor=1] -\setupfontexpansion - [minimalhz] - [stretch=2,shrink=2,step=.5,vector=default,factor=.5] - -\definefontfeature - [extremehz] [default] - [mode=node,expansion=extremehz] -\definefontfeature - [regularhz] [default] - [mode=node,expansion=regularhz] -\definefontfeature [minimalhz] [default] - [mode=node,expansion=minimalhz] - -\definefont - [ExtremeHzFont] - [file:texgyrepagella-regular.otf*extremehz at 10pt] -\definefont - [RegularHzFont] - [file:texgyrepagella-regular.otf*regularhz at 10pt] -\definefont - [MinimalHzFont] - [file:texgyrepagella-regular.otf*minimalhz at 10pt] -\stopbuffer - -\typebuffer \getbuffer - -\edef\HzSampleText{\cldloadfile{ward}} - -\def\NoHzSample {\vbox{\hsize 10cm \color[hz:test:tr]{\setupalign [nohz]\HzSampleText\par}}} -\def\HzSample {\vbox{\hsize 10cm \color[hz:test:tg]{\setupalign [hz]\HzSampleText\par}}} -\def\FullHzSample{\vbox{\hsize 10cm \color[hz:test:tb]{\setupalign[fullhz]\HzSampleText\par}}} - -\startplacefigure[reference=hz:natural,title={The two expansion methods compared.}] - \showfontkerns - \dontcomplain - \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 -\stopplacefigure - -\startplacefigure[reference=hz:zoomed,title={The two expansion methods compared (zoomed in).}] - \showfontkerns - \dontcomplain - \startcombination[3*3] - - {\ExtremeHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\HzSample } \stopoverlay}} {extreme: no hz \& hz} - {\ExtremeHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {extreme: no hz \& full hz} - {\ExtremeHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample } {\FullHzSample} \stopoverlay}} {extreme: hz \& full hz} - - {\RegularHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\HzSample } \stopoverlay}} {regular: no hz \& hz} - {\RegularHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {regular: no hz \& full hz} - {\RegularHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample } {\FullHzSample} \stopoverlay}} {regular: hz \& full hz} - - {\MinimalHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\HzSample } \stopoverlay}} {minimal: no hz \& hz} - {\MinimalHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {minimal: no hz \& full hz} - {\MinimalHzFont - \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample } {\FullHzSample} \stopoverlay}} {minimal: hz \& full hz} - - \stopcombination -\stopplacefigure - -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 - -\stopsection - -\startsection[title=Composing] - -This feature is seldom needed but can come in handy for old fonts or when -some special language is to be supported. When writing this section I tested -this feature with Dejavu and only two additional characters were added: - -\definefontfeature - [default-plus-compose] - [compose=yes] - -\definefont - [MyComposedSerif] - [Serif*default-plus-compose] - -% we need to cheat a bit as we don't have the main character in mono - -\startlines \MyComposedSerif -\type{fonts > combining > }\hbox to .5em{\hss Ѷ\hss}\type{ (U+00476) = }\hbox to .5em{\hss Ѵ\hss}\type{ (U+00474) + ̏ (U+0030F)} -\type{fonts > combining > }\hbox to .5em{\hss ѷ\hss}\type{ (U+00477) = }\hbox to .5em{\hss ѵ\hss}\type{ (U+00475) + ̏ (U+0030F)} -\stoplines - -This trace showed up after giving: - -\starttyping -\enabletrackers - [fonts.composing.define] - -\definefontfeature - [default-plus-compose] - [compose=yes] - -\definefont - [MyFont] - [Serif*default-plus-compose] -\stoptyping - -Fonts like Latin Modern have lots of glyphs but still lack some. Although the -composer can add some of the missing, some of those new virtual glyphs probably -will never look real good. For instance, putting additional accents on top of -already accented uppercase characters will fail when that character has a rather -tight (or even clipped) boundingbox in order not to spoil the lineheight. You can -get some more insight in the process by turning on tracing: - -\starttyping -\enabletrackers[fonts.composing.visualize] -\stoptyping - -One reason why composing can be suboptimal is that it uses the boundingbox of the -characters that are combined. If you really depend on a specific font and need -some of the missing characters it makes sense to spend some time on optimizing -the rendering. This can be done via the goodies mechanism. As an example we've -added \type {lm-compose-test.lfg} to the distribution. First we show how it -looks at the \TEX\ end: - -\startbuffer -\enabletrackers[fonts.composing.visualize] - -\definefontfeature - [default-plus-compose] - [compose=yes] - -\loadfontgoodies - [lm-compose-test] % playground - -\definefont - [MyComposedSerif] - [file:lmroman10regular*default-plus-compose at 48pt] -\stopbuffer - -\typebuffer \getbuffer - -\blank -\backgroundline - [halfcolor] - {\MyComposedSerif B\quad\char"1E02\quad\char"1E04} -\blank - -The positions of the dot accents on top and below the capital B is defined -in a goodie file: - -\starttyping -return { - name = "lm-compose-test", - version = "1.00", - comment = "Goodies that demonstrate composition.", - author = "Hans and Mojca", - copyright = "ConTeXt development team", - compositions = { - ["lmroman12-regular"] = compose, - } -} -\stoptyping - -As this is an experimental feature there are several ways to deal with -this. For instance: - -\starttyping -local defaultfraction = 10.0 - -local compose = { - dy = defaultfraction, - [0x1E02] = { -- B dot above - dy = 150 - }, - [0x1E04] = { -- B dot below - dy = 150 - }, -} -\stoptyping - -Here the fraction is relative to the difference between the height of the -accentee and the accent. A better solution is the following: - -\starttyping -local compose = { - [0x1E02] = { -- B dot above - anchored = "top", - }, - [0x1E04] = { -- B dot below - anchored = "bottom", - }, - [0x0042] = { -- B - anchors = { - top = { - x = 300, y = 700, - }, - bottom = { - x = 300, y = -30, - }, - }, - }, - [0x0307] = { - anchors = { - top = { - x = -250, y = 550, - }, - }, - }, - [0x0323] = { - anchors = { - bottom = { - x = -250, y = -80, - }, - }, - }, -} -\stoptyping - -This approach is more or less the same as \OPENTYPE\ anchoring. It takes a bit -more effort to define these tables but the result is better. - -\stopsection - -\startsection[title=Kerning] - -Inter|-|character kerning is not supported at the font level and with good -reason. The fact that something is conceptually possible doesn't mean that we -should use or support it. Normally proper kerning (or the lack of it) is part -of a font design and for some scripts different kerning is not even an option. - -On the average \TEX\ does a proper job on justification but not all programs -are that capable. As a consequence designers (at least we ran into it) tend to -stick to flush left rendering because they don't trust their system to do a -proper job otherwise. On the other hand they seem to have no problem with -messing up the inter|-|character spacing and even combine that with excessive -inter|-|word spacing {\em if} they want to achieve justification (without -hyphenation). And it can become even worse when extreme glyph expansion (like -hz) is applied. - -Anyhow, it will be clear that consider messing with properties like kerning that -are part of the font design is to be done careful. - -\definecharacterkerning [extremekerning] [factor=.125] - -\start \setcharacterkerning[extremekerning] - -For running text additional kerning makes no sense. It not only looks -bad, it also spoils the grayness of a text. When it is applied we need -to deal with special cases. For instance ligatures make no sense so they -should be disabled. Additional kerning should relate to already present -kerning and interword spacing should be adapted accordingly. Embedded -non|-|characters also need to be treated well. - -\par \stop - -This paragraph was typeset as follows: - -\starttyping -\definecharacterkerning [extremekerning] [factor=.125] - -\setcharacterkerning[extremekerning] ... text ... -\stoptyping - -Where additional kerning can make sense, is in titles. The previous -command can do that job. In addition we have a mechanism that -fills a given space. This mechanism uses the following definition: - -\starttyping -\setupcharacterkerning - [stretched] - [factor=max, - width=\availablehsize] -\stoptyping - -\startbuffer -\stretched{\bfd to the limit} -\stopbuffer - -\typebuffer - -\blank \start \color[maincolor]{\getbuffer} \stop \blank - -The following does not work: - -\startbuffer -\ruledhbox to 5cm{\stretched{\bfd to the limit}} -\stopbuffer - -\typebuffer - -\blank \start \color[maincolor]{\getbuffer} \stop \blank - -But this works ok: - -\startbuffer -\setupcharacterkerning - [stretched] - [width=] - -\stretched{\bfd to the limit} -\stopbuffer - -\typebuffer - -\blank \start \color[maincolor]{\getbuffer} \stop \blank - -You can also say this: - -\startbuffer -\stretched[width=]{\bfd to the limit} -\stopbuffer - -\typebuffer - -\blank \start \color[maincolor]{\getbuffer} \stop \blank - -or: - -\startbuffer -\ruledhbox{\stretched[width=10cm]{\bfd to the limit}} -\stopbuffer - -\typebuffer - -\blank \start \color[maincolor]{\getbuffer} \stop \blank - -You can get some insight in what kerning does to your font by the following -command: - -\startbuffer -\usemodule[typesetting-kerning] - -\starttext - \showcharacterkerningsteps - [style=Bold, - sample=how to violate a proper font design, - text=rubish, - first=0, - last=45, - step=5] -\stoptext -\stopbuffer - -\typebuffer - -\blank \getbuffer \blank - -\stopsection - -\startsection[title=Extra font kerns] - -Fonts are processed independent of each other. Sometimes that is unfortunate for -kerning, although in practice it won't happen that often. We can enable an -additional kerning mechanism to deal with these cases. The \type -{\setextrafontkerns} command takes one argument between square brackets. The -effect can be seen below: - -\startbuffer - VA {\smallcaps va} V{\smallcaps a} - VA {\bf VA} V{\bf A} {\bf V}A - V{\it A} -\stopbuffer - -\starttabulate[|Tl|l|p|] -\HL -\BC key \BC result \BC logic \NC \NR -\HL -\NC no kerns \NC \showfontkerns\setextrafontkerns[reset]\subff{f:kern}\inlinebuffer \NC no kerns at all \NC \NR -\NC kerns \NC \showfontkerns\setextrafontkerns[reset]\inlinebuffer \NC kerns within a font (feature) run \NC \NR -\HL -\NC none \NC \showfontkerns\setextrafontkerns [none]\inlinebuffer \NC only extra kerns within fonts \NC \NR -\NC min \NC \showfontkerns\setextrafontkerns [min]\inlinebuffer \NC minimal kerns within and across fonts \NC \NR -\NC max \NC \showfontkerns\setextrafontkerns [max]\inlinebuffer \NC maximum kerns within and across fonts \NC \NR -\NC mixed \NC \showfontkerns\setextrafontkerns[mixed]\inlinebuffer \NC averaged kerns within and across fonts \NC \NR -\HL -\stoptabulate - -The content is defined as: - -\typebuffer - -This mechanism obeys grouping so you have complete control over where and when -it gets applied. The \type {\showfontkerns} command can be used to trace the -injection of (font) kerns. - -\stopsection - -\startsection[title=Ligatures] - -For some Latin fonts ligature building is quite advanced, take Unifraktur. I have no -problem admitting that I find fraktur hard to read, but this one actually is sort of -an exception. It's also a good candidate for a screen presentation where you mainly -made notes for yourself: no one has to read it, but it looks great, especially if -you consider it to be drawn by a pen. - -Anyway, we will use the following code as example (based on some remarks on the -fonts website). - -\startbuffer[sample] -sitzen / ſitzen / effe fietsen / ch ck ſt tz ſi fi -\stopbuffer - -\typebuffer[sample] - -Some ligatures are implemented in the usual way, using the \type {liga} and \type {dlig} -features, others kick in thanks to \type {ccmp}. This fact alone is an illustration that -the low level \OPENTYPE\ ligature feature is not related to ligatures at all but a more -generic mechanism: you can basically combine multiple shapes into one in all features -exposed to the user. - -We define a bunch of specific feature sets: - -\startbuffer -\definefontfeature - [unifraktur-a] - [default] -\definefontfeature - [unifraktur-b] - [default] - [goodies=unifraktur,keepligatures=yes] -\definefontfeature - [unifraktur-c] - [default] - [ccmp=yes] -\definefontfeature - [unifraktur-d] - [default] - [ccmp=yes,goodies=unifraktur,keepligatures=yes] -\definefontfeature - [unifraktur-e] - [default] - [liga=no,rlig=no,clig=no,dlig=no,ccmp=yes,keepligatures=auto] -\stopbuffer - -\getbuffer \typebuffer - -and also some fonts: - -\startbuffer -\definefont[TestA][UnifrakturCook*unifraktur-a sa 0.9] -\definefont[TestB][UnifrakturCook*unifraktur-b sa 0.9] -\definefont[TestC][UnifrakturCook*unifraktur-c sa 0.9] -\definefont[TestD][UnifrakturCook*unifraktur-d sa 0.9] -\definefont[TestE][UnifrakturCook*unifraktur-e sa 0.9] -\stopbuffer - -\getbuffer \typebuffer - -We show these five alternatives here: - -\starttabulate[|T||] -\NC liga \NC \TestA\getbuffer[sample] \NC \NR -\NC liga + keepligatures \NC \TestB\getbuffer[sample] \NC \NR -\NC liga + ccmp \NC \TestC\getbuffer[sample] \NC \NR -\NC liga + ccmp + keepligatures \NC \TestD\getbuffer[sample] \NC \NR -\NC ccmp + keepligatures \NC \TestE\getbuffer[sample] \NC \NR -\stoptabulate - -The real fun starts when we want to add extra spacing between characters. Some -ligatures need to get broken and some kept. - -\startbuffer -\setupcharacterkerning[kerncharacters][factor=0.5] -\setupcharacterkerning[letterspacing] [factor=0.5] -\stopbuffer - -\getbuffer \typebuffer - -\enabletrackers[typesetters.kerns.ligatures] - -Next we will see how ligatures behave depending on how the mechanisms are set -up. The colors indicate what trickery is used: - -\starttabulate[|T||] -\NC \color[darkred] {red} \NC kept by dynamic feature \NC \NR -\NC \color[darkgreen]{green} \NC kept by static feature \NC \NR -\NC \color[darkblue] {blue} \NC keep by goodie \NC \NR -\stoptabulate - -First we use \type {\kerncharacters}: - -\starttabulate[|T||] -\NC liga \NC \kerncharacters {\TestA\getbuffer[sample]} \NC \NR -\NC liga + keepligatures \NC \kerncharacters {\TestB\getbuffer[sample]} \NC \NR -\NC liga + ccmp \NC \kerncharacters {\TestC\getbuffer[sample]} \NC \NR -\NC liga + ccmp + keepligatures \NC \kerncharacters {\TestD\getbuffer[sample]} \NC \NR -\NC ccmp + keepligatures \NC \kerncharacters {\TestE\getbuffer[sample]} \NC \NR -\stoptabulate - -In the next example we use \type {\letterspacing}: - -\starttabulate[|T||] -\NC liga \NC \letterspacing {\TestA\getbuffer[sample]} \NC \NR -\NC liga + keepligatures \NC \letterspacing {\TestB\getbuffer[sample]} \NC \NR -\NC liga + ccmp \NC \letterspacing {\TestC\getbuffer[sample]} \NC \NR -\NC liga + ccmp + keepligatures \NC \letterspacing {\TestD\getbuffer[sample]} \NC \NR -\NC ccmp + keepligatures \NC \letterspacing {\TestE\getbuffer[sample]} \NC \NR -\stoptabulate - -\disabletrackers[typesetters.kerns.ligatures] - -The difference is that the letterspacing variant dynamically adds the predefined -featureset \type {letterspacing} which is defined in a similar way as \type -{unifraktur-e}. In the case of this font, this variant is the better one to use. -In fact, this variant probably works okay with most fonts. However, by not hard -coding this behaviour we keep control, as one never knows what the demands are. -When no features are used, information from the (given) goodie file \type -{unifraktur.lfg} is consulted: - -\starttyping -letterspacing = { - -- watch it: zwnj's are used (in the tounicodes too) - keptligatures = { - ["c_afii301_k.ccmp"] = true, -- ck - ["c_afii301_h.ccmp"] = true, -- ch - ["t_afii301_z.ccmp"] = true, -- tz - ["uniFB05"] = true, -- ſt - }, -} -\stoptyping - -These kick in when we don't disable ligatures by setting features (case~e). - -There are two pseudo features that can help us out when a font doesn't provide -the wanted ligatures but has the right glyphs for building them. The \UNICODE\ -database has some information about how characters can be (de)composed and we can -use that information to create virtual glyphs: - -\starttyping -\definefontfeature - [default] [default] - [char-ligatures=yes,mode=node] -\stoptyping - -and: - -\starttyping -\definefontfeature - [default] [default] - [compat-ligatures=yes,mode=node] -\stoptyping - -This feature was added after some discussion on the \CONTEXT\ mailing list about -the following use case. - -\startbuffer -\definefontfeature - [default-l] [default] - [char-ligatures=yes, - compat-ligatures=yes, - mode=node] - -\definefont[LigCd][cambria*default] -\definefont[LigPd][texgyrepagellaregular*default] -\definefont[LigCl][cambria*default-l] -\definefont[LigPl][texgyrepagellaregular*default-l] -\stopbuffer - -\typebuffer \getbuffer - -These definitions result in: - -\starttabulate[|l|l|l|l|l|] -\NC \NC \type {\LigCd} \NC \type {\LigPd} \NC \type {\LigCl} \NC \type {\LigPl} \NC \NR -\NC \type{PEL·LÍCULES} \NC \LigCd PEL·LÍCULES \NC \LigPd PEL·LÍCULES \NC \LigCl PEL·LÍCULES \NC \LigPl PEL·LÍCULES \NC \NR -\NC \type{pel·lícules} \NC \LigCd pel·lícules \NC \LigPd pel·lícules \NC \LigCl pel·lícules \NC \LigPl pel·lícules \NC \NR -\NC \type{PEĿLÍCULES} \NC \LigCd PEĿLÍCULES \NC \LigPd PEĿLÍCULES \NC \LigCl PEĿLÍCULES \NC \LigPl PEĿLÍCULES \NC \NR -\NC \type{peŀlícules} \NC \LigCd peŀlícules \NC \LigPd peŀlícules \NC \LigCl peŀlícules \NC \LigPl peŀlícules \NC \NR -\stoptabulate - -Of course one can wonder is this is the right approach and if it's not better to -use a font that provides the needed characters in the first place. - -\stopsection - -\startsection[title=New features] - -\startsubsection[title=Substitution] - -It is possible to add new features via \LUA. Here is an example of a single -substitution: - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "stest", - type = "substitution", - data = { - a = "X", - b = "P", - } - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -We show an overview at the end of this section, but here is a simple example -already. You need to define the feature before defining a font because otherwise -the font will not know about it. - -\startbuffer -\definefontfeature[stest][stest=yes] -\definedfont[file:dejavu-serifbold.ttf*default] -abracadabra: \addff{stest}abracadabra -\stopbuffer - -\typebuffer \start \blank \maincolor \getbuffer \blank \stop - -Instead of (more readable) glyph names you can also give \UNICODE\ numbers: - -\starttyping -\startluacode - fonts.handlers.otf.addfeature { - name = "stest", - type = "substitution", - data = { - [0x61] = 0x58 - [0x62] = 0x50 - } - } -\stopluacode -\stoptyping - -The definition is quite simple: we just map glyph names (or unicodes) onto -other ones. An alternate is also possible: - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "atest", - type = "alternate", - data = { - a = { "X", "Y" }, - b = { "P", "Q" }, - } - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -Less useful is a multiple substitution. Normally this one is part of a chain of -replacements. - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "mtest", - type = "multiple", - data = { - a = { "X", "Y" }, - b = { "P", "Q" }, - } - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -A ligature (or multiple to one) is also possible but normally only makes sense when -there is indeed a ligature. We use a similar definition for mapping the \TEX\ input -sequence \type {---} onto an \emdash. - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "ltest", - type = "ligature", - data = { - ['1'] = { "a", "b" }, - ['2'] = { "d", "a" }, - } - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -\stopsubsection - -\startsubsection[title=Positioning] - -You can define a kern feature too but when doing so you need to use measures in -font units. - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "ktest", - type = "kern", - data = { - a = { b = -500 }, - } - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -Pairwise positioning is more complex and involves two (optional) arrays -that specify \type {{dx dy wd ht}} for each of the two glyphs. In the next -example we only displace the second glyph. - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "ptest", - type = "pair", - data = { - ["a"] = { ["b"] = { false, { -1000, 1200, 0, 0 } } }, - } - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -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] - -We didn't show usage yet. This is because we need to define a feature before we -define a font. New features will be added to a font when it gets defined. - -\startbuffer -\definefontfeature[stest][stest=yes] -\definefontfeature[atest][atest=2] -\definefontfeature[mtest][mtest=yes] -\definefontfeature[ltest][ltest=yes] -\definefontfeature[ktest][ktest=yes] -\definefontfeature[ptest][ptest=yes] -\definefontfeature[ctest][ctest=yes] - -\definedfont[file:dejavu-serif.ttf*default] - -\starttabulate[|l|l|l|] -\NC operation \NC feature \NC abracadabra \NC \NR -\HL -\NC substitution \NC \type {stest} \NC \addff{stest}abracadabra \NC \NR -\NC alternate \NC \type {atest} \NC \addff{atest}abracadabra \NC \NR -\NC multiple \NC \type {mtest} \NC \addff{mtest}abracadabra \NC \NR -\NC ligature \NC \type {ltest} \NC \addff{ltest}abracadabra \NC \NR -\NC kern \NC \type {ktest} \NC \addff{ktest}abracadabra \NC \NR -\NC pair \NC \type {ptest} \NC \addff{ptest}abracadabra \NC \NR -\NC chain sub \NC \type {ctest} \NC \addff{ctest}abracadabra \NC \NR -\stoptabulate -\stopbuffer - -\typebuffer \getbuffer - -\stopsubsection - -\startsubsection[title=Contexts] - -A more complex substitution is the following: - -\startbuffer -\startluacode - fonts.handlers.otf.addfeature { - name = "ytest", - type = "chainsubstitution", - lookups = { - { - type = "substitution", - data = { - ["b"] = "B", - ["c"] = "C", - }, - }, - }, - data = { - rules = { - { - before = { { "a" } }, - current = { { "b", "c" } }, - lookups = { 1 }, - }, - }, - }, - } -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -Here the dataset is a sequence of rules. There can be a \type {before}, \type -{current} and \type {after} match. The replacements are specified with the \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}] - -When \OPENTYPE\ was not around we only had to deal with ligatures, smallcaps and -oldstyle and of course kerns. Their number was so small that the term \quote -{features} was not even used. In practice one just loaded a font that had -oldstyle or smallcaps or none of that and was done. There were different fonts and -sold separately. - -In \OPENTYPE\ we have more variation and although these fonts can be much more -advanced the lack of standardization (for instance what gets initialized, or what -shapes are in the default slots) can lead to messy setups. Some fonts bind -features to scripts, some don't, which means that: - -\starttyping -\definefontfeature[smallcaps][smcp=yes,script=dflt] -\definefontfeature[smallcaps][smcp=yes,script=latn] -\definefontfeature[smallcaps][smcp=yes,script=cyrl] -\stoptyping - -are in fact different and you don't know in advance if you need to specify \type -{dflt} or \type {latn}. In practice for a feature like smallcaps there is no -difference between languages, but for ligatures there can be. - -When we extend an existing feature we can think of: - -\starttyping -\definefontfeature[smallcaps][default][smcp=yes,script=auto] -\definefontfeature[smallcaps][default][smcp=yes,script=*] -\stoptyping - -but that can have side effects too (for instance disabling language specific -features). The easiest way to explore this language dependency is to make -a feature of our own. - -\startbuffer -\startluacode -fonts.handlers.otf.addfeature { - name = "simplify", - type = "multiple", - prepend = true, - features = { - ["*"] = { - ["deu"] = true - } - }, - data = { - [utf.byte("ä")] = { "a", "e" }, - [utf.byte("Ä")] = { "A", "E" }, - [utf.byte("ü")] = { "u", "e" }, - [utf.byte("Ü")] = { "U", "E" }, - [utf.byte("ö")] = { "o", "e" }, - [utf.byte("Ö")] = { "O", "E" }, - [utf.byte("ß")] = { "s", "z" }, - [utf.byte("ẞ")] = { "S", "Z" }, - }, -} -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -Here we implement a language specific feature that we use at the \TEX\ end: - -\startbuffer -\definefontfeature - [simplify-de] - [simplify=yes, - language=deu] -\stopbuffer - -\typebuffer \getbuffer - -that we can use as: - -\startbuffer -\definedfont[Serif*default,simplify-de]% -äüöß -{\de äüöß} -{\nl äüöß} -\stopbuffer - -\typebuffer - -and get: \start \maincolor \inlinebuffer \stop, but as you see, both German and -Dutch get the same treatment, which might not be what you want, because in Dutch -the diearesis has a different meaning. - -\startbuffer -\definedfont[Serif*default]% - äüöß -{\de\addff{simplify-de}äüöß} -{\nl äüöß} -\stopbuffer - -\typebuffer - -The above is restricts the usage so now we get: \start \maincolor \inlinebuffer -\stop, which is more language bound. You don't need much imagination for -extending this: - -\startbuffer -\definefontfeature - [simplify] - [simplify=yes, - language=deu] -\stopbuffer - -\typebuffer \getbuffer - -\startbuffer -\definedfont[Serif*default]% - äüöß -{\de\addff{simplify}äüöß} -{\nl\addff{simplify}äüöß} -\stopbuffer - -So what do we expect with the next? - -\typebuffer - -We get: \start \maincolor \inlinebuffer \stop, and we see that the language -setting is not taken into account! This is because the font already has been set -up with a script and language combination. The solution is to temporary set the -font related language explicitly: - -\definefontfeature - [simplify] - [simplify=yes] - -\startbuffer -\definedfont[Serif*default]% - äüöß -{\de\addfflanguage\addff{simplify}äüöß} -{\nl\addfflanguage\addff{simplify}äüöß} -\stopbuffer - -\typebuffer - -So we can automatically switch to language specific features if we want to: -\start \maincolor \inlinebuffer \stop. - -Let's now move to another level of complexity: support for more than one language -as in fact this example was made for Dutch in the first place, but the German -outcome is a bit more visible. - -\startbuffer -\startluacode -fonts.handlers.otf.addfeature { - name = "simplify", - type = "multiple", - prepend = true, - -- prepend = "smcp", - dataset = - { - { - features = { - ["*"] = { - ["nld"] = true - } - }, - data = { - -- [utf.byte("ä")] = { "a" }, - -- [utf.byte("Ä")] = { "A" }, - -- [utf.byte("ü")] = { "u" }, - -- [utf.byte("Ü")] = { "U" }, - -- [utf.byte("ö")] = { "o" }, - -- [utf.byte("Ö")] = { "O" }, - [utf.byte("ij")] = { "i", "j" }, - [utf.byte("IJ")] = { "I", "J" }, - [utf.byte("æ")] = { "a", "e" }, - [utf.byte("Æ")] = { "A", "E" }, - }, - }, - { - -- type = "multiple", -- local values possible - features = { - ["*"] = { - ["deu"] = true - } - }, - data = { - [utf.byte("ä")] = { "a", "e" }, - [utf.byte("Ä")] = { "A", "E" }, - [utf.byte("ü")] = { "u", "e" }, - [utf.byte("Ü")] = { "U", "E" }, - [utf.byte("ö")] = { "o", "e" }, - [utf.byte("Ö")] = { "O", "E" }, - [utf.byte("ß")] = { "s", "z" }, - [utf.byte("ẞ")] = { "S", "Z" }, - }, - } - } -} -\stopluacode -\stopbuffer - -\typebuffer \getbuffer - -For this we use the following example: - -\startbuffer -\definedfont[Serif*default,simplify]% - äüöß ijæ -{\de\addfflanguage äüöß ijæ} -{\nl\addfflanguage äüöß ijæ} -\stopbuffer - -\typebuffer - -Because the Dutch is hard to check we use an \type {æ} replacement too and -commented the similarities with German: \start \maincolor \inlinebuffer \stop. -But still we're not done, say that we want smallcaps too: - -\startbuffer -\definefontfeature[alwayssmcp][smcp=always]% -\definedfont[Serif*default,simplify,alwayssmcp]% - äüöß ijæ -{\de\addfflanguage äüöß ijæ} -{\nl\addfflanguage äüöß ijæ} -\stopbuffer - -\typebuffer - -This comes out as: \start \maincolor \inlinebuffer \stop. - -The reason for specifying \type{smcp} as \type {always} is that otherwise we -get language specific smallcaps while often they are not bound to a language -but to the defaults. The good news is that we can do this automatically: - -\startbuffer -\setupfonts[language=auto]% -\definefontfeature[alwayssmcp][smcp=always]% -\definedfont[Serif*default,simplify,alwayssmcp]% - äüöß ijæ -{\de äüöß ijæ} -{\nl äüöß ijæ} -\stopbuffer - -\typebuffer - -But be aware that this applies to all situations. Here we get: \start \maincolor -\inlinebuffer \stop. - -\stopsubsection - -\startsubsection[title=Syntax summary] - -In the examples we have seen several ways to define features. One of the -differences is that you either set a \type {data} field directly, or that you -specify a dataset. The fields in a dataset entry overload the ones given at the -top level or when not set the top level value will be taken. There is a bit -of (downward compatibility) tolerance built in, but best not depend on that. - -\starttyping -fonts.handlers.otf.addfeature { - name = "demo", - features = { - [<script>] = { - [<language>] = true - } - }, - prepend = true | featurename | position, - dataset = { - { - type = "substitution", - data = { - [<char|code>] = <char|code>, - } - }, - { - type = "alternate", - data = { - [<char|code>] = { <char|code>, <char|code>, ... }, - } - }, - { - type = "multiple", - data = { - [<char|code>] = { <char|code>, <char|code>, ... }, - } - }, - { - type = "ligature", - data = { - [<char|code>] = { <char|code>, <char|code>, ... }, - } - }, - { - type = "kern", - data = { - [<char|code>] = { [<char|code>] = <value> }, - } - }, - { - type = "pair", - data = { - [<char|code>] = { - [<char|code>] = { - false | { <value>, <value>, <value>, <value> }, - false | { <value>, <value>, <value>, <value> } - } - } - } - }, - { - type = "chainsubstitution", - lookups = { - { - type = <typename>, - data = <mapping>, - }, - }, - data = { - rules = { - { - before = { { [<char|code>], ... } }, - current = { { [<char|code>], ... } }, - after = { { [<char|code>], ... } }, - lookups = { <index>, ... }, - }, - }, - }, - }, - }, -} -\stoptyping - -\stopsubsection - -\startsubsection[title=Extra characters] - -\startbuffer[hyphenchars] -\startluacode - - local privateslots = fonts.constructors.privateslots - - local function addspecialhyphen(tfmdata) - - local exheight = tfmdata.parameters.xheight - local emwidth = tfmdata.parameters.quad - local width = emwidth / 4 - local height = exheight / 10 - local depth = exheight / 2 - local offset = emwidth / 6 - - tfmdata.characters[privateslots.righthyphenchar] = { - -- no dimensions - commands = { - - { "right", offset }, - - { "push" }, - { "right", -width }, - { "down", depth }, - { "rule", height, width }, - { "pop" }, - - { "right", -width/5 }, - { "down", depth + height }, - { "rule", 3*height, width/5 }, - - } - } - - tfmdata.characters[privateslots.lefthyphenchar] = { - -- no dimensions - commands = { - - { "right", -offset }, - - { "push" }, - { "down", depth + height }, - { "rule", 3*height, width/5 }, - { "pop" }, - - { "down", depth }, - { "rule", height, width }, - - } - } - - end - - fonts.constructors.features.otf.register { - name = "specialhyphen", - description = "special hyphen", - manipulators = { - base = addspecialhyphen, - node = addspecialhyphen, - } - } - -\stopluacode -\stopbuffer - -You can add virtual characters to fonts. Here we give an example that is derived -from an example posted on the mailing list. By default, when we hyphenated a word, -we get this: - -\definefont[DemoFont] [Serif*default] - -\blank \start \DemoFont \maincolor \hsize 1mm averylongword \par \stop \blank - -The default character that is appended at the end and beginning of a line -can be specified as follows: - -\startbuffer -\setuplanguage - [en] - [righthyphenchar=45, - lefthyphenchar=45] -\stopbuffer - -\typebuffer - -So now we get: - -\blank \start \getbuffer \DemoFont \maincolor \hsize 1mm averylongword \par \stop \blank - -Say that we want a different signal, for instance some rule. Here is how that can -be done: - -\typebuffer[hyphenchars] - -\getbuffer[hyphenchars] - -Watch the way we use private slots. You can best use a unique glyph name as these -numbers are shared between fonts. With: - -\startbuffer -\definefontfeature - [default] - [default] - [specialhyphen=yes] -\definefont - [DemoFont] - [Serif*default at 24pt] -\setuplanguage - [en] - [righthyphenchar=\getprivateglyphslot{righthyphenchar}, - lefthyphenchar=\getprivateglyphslot{lefthyphenchar}] -\stopbuffer - -\typebuffer - -We get: - -\startlinecorrection[blank] -\getbuffer -\framed - [foregroundstyle=\DemoFont \setupinterlinespace, - offset=none, - frame=no, - width=1mm, - align={flushleft}] - {\hsize 1mm \maincolor averylongword\par} -\stoplinecorrection - -You need to keep in mind that some of these settings are global but in practice that is -not a real problem. Here is how you reset: - -\startbuffer -\definefontfeature - [default] - [default] - [specialhyphen=no] -\setuplanguage - [en] - [righthyphenchar=45, - lefthyphenchar=0] -\stopbuffer - -\typebuffer \getbuffer - -\stopsubsection - -\startsubsection[title=Goodies] - -The examples above extend a font in the \TEX\ document (normally a style) but you -can use a goodies file too, for instance \type {cambria.lfg}. - -\starttyping -return { - name = "cambria", - version = "1.00", - comment = "Goodies that complement cambria.", - author = "Hans Hagen", - copyright = "ConTeXt development team", - extensions = { - { - name = "kern", -- adds to kerns - type = "pair", - data = { - [0x0153] = { -- combining acute - [0x0301] = { -- aeligature - false, - { -500, 0, 0, 0 } - } - }, - } - } - } -} -\stoptyping - -Here we use the feature name \type {kern} and therefore we don't have to define a -specific (new) feature for it. Such a goodie is then used as follows: - -\starttyping -\definefontsynonym - [Serif] - [cambria] - [features=default, - goodies=cambria] -\stoptyping - -You can find such definitions in the \type {type-imp-*.mkiv} files. - -\stopsubsection - -\stopsection - -\startsection[title=Spacing] - -% By default the font loader deduces the spacing from the space character or -% other font properties. You can influence this by the \type {space} feature. -% -% \starttyping -% \definefontfeature -% [korean] -% [default] -% [script=hang, -% language=kor, -% space=local] % or locl -% \stoptyping -% -% Instead of the usual \type {yes} (which means: use character 32), \type {local} -% or \type {locl} (which means: use a replacement provided by the \type{locl} -% feature), you can also pass a character, so -% -% \starttyping -% \definefontfeature -% [spacy] -% [default] -% [space=A] -% \stoptyping -% -% is valid. - -As you probably know, \TEX\ has no space character. When the input is read, -characters tagged as space are intercepted and become glue. Compare this: - -\startlinecorrection[blank] - \startcombination - {\framed - [width=3cm,height=15mm,align={middle,lohi},foregroundcolor=maincolor] - {\dorecurse{5}{test }}} - {\type{text test...}} - {\framed - [width=3cm,height=15mm,align={middle,lohi},foregroundcolor=maincolor] - {\dorecurse{5}{test\char32\relax}}} - {\type{text\char32test...}} - \stopcombination -\stoplinecorrection - -Most fonts have a space character and you can actually use it and indeed a space -character will be injected but as it is not glue, the line break algorithm will -not see it as space. - -Al the magic done with space characters other than the native space character -(decimal 32) are at some point translated into glue. - -\starttabulate[||T|p|] -\NC \bf command \NC \UNICODE \NC width \NC \NR - -\NC \type{\nobreakspace} - \type{\nbsp} \NC U+00A0 \NC space \NC \NR -\NC \type{\ideographicspace} \NC U+2000 \NC quad/2 \NC \NR -\NC \type{\ideographichalffillspace} \NC U+2001 \NC quad \NC \NR -\NC \type{\twoperemspace} - \type{\enspace} \NC U+2002 \NC quad/2 \NC \NR -\NC \type{\emspace} - \type{\quad} \NC U+2003 \NC quad \NC \NR -\NC \type{\threeperemspace} \NC U+2004 \NC quad/3 \NC \NR -\NC \type{\fourperemspace} \NC U+2005 \NC quad/4 \NC \NR -\NC \type{\fiveperemspace} \NC \NC quad/5 \NC \NR -\NC \type{\sixperemspace} \NC U+2006 \NC quad/6 \NC \NR -\NC \type{\figurespace} \NC U+2007 \NC width of zero \NC \NR -\NC \type{\punctuationspace} \NC U+2008 \NC width of period \NC \NR -\NC \type{\breakablethinspace} \NC U+2009 \NC quad/8 \NC \NR -\NC \type{\hairspace} \NC U+200A \NC quad/8 \NC \NR -\NC \type{\zerowidthspace} \NC U+200B \NC 0 \NC \NR -\NC \type{\zerowidthnonjoiner} - \type{\zwnj} \NC U+200C \NC 0 \NC \NR -\NC \type{\zerowidthjoiner} - \type{\zwj} \NC U+200D \NC 0 \NC \NR -\NC \type{\narrownobreakspace} \NC U+202F \NC quad/8 \NC \NR -\NC \type{\zerowidthnobreakspace} \NC U+FEFF \NC \NC \NR -\NC \type{\optionalspace} \NC \NC space when not followed by punctuation \NC \NR -\stoptabulate - -% "205F % space/8 (math) - -The last one is not un \UNICODE\ and the fifths of an emspace is not in \UNICODE\ -either. This emspace (or quad in \TEX\ speak) is a font property. The width of -the space used by \CONTEXT\ is dreived form this value. In case of a monospace -fonts, the following logic is applied: - -\startitemize - \startitem - When there is a space character, the width of that character is used. - \stopitem - \startitem - Otherwise, when there is an emdash present, the width if that character - is used. - \stopitem - \startitem - Otherwise, when there is an \type {charwidth} property available (the - average width), that valua is used. - \stopitem -\stopitemize - -When a proportional font is used, we do as follows: - -\startitemize - \startitem - When there is a space character, the width of that character is used. - \stopitem - \startitem - Otherwise, when there is an emdash present, the width of that character - divided by two is used. - \stopitem - \startitem - Otherwise, when there is an \type {charwidth} property available (the - average width), that value is used. - \stopitem -\stopitemize - -In both cases, when no value is set we use the units of the font (often 1000 or -2048). In \TEX\ a space glue also has stretch and shrink. Here we follow the -traditional \TEX\ logic: - -\startitemize - \startitem - The stretch is set to half the width of a space but to zero with a mono - spaced font. - \stopitem - \startitem - The shrink is set to one third of the width of a space but to zero with a - mono spaced font. - \stopitem -\stopitemize - -The xheight is set to the values specified by the font and when this is unset the -height of the character \type {x} will be used but when this character is not in -the font, we use two fifths of the font's units (normally the same as the -emwidth). The italic angle is also taken from the font (and is of course zero for -a not italic font). Most fonts have these properties set so we seldom have to -fall back to a guess. - -\stopsection - -\startsection[title=Ligatures] - -Not all fonts provide ligature control (normally related to languages), so here is a -trick. - -\starttyping -\blockligatures[fi,ff] -\blockligatures[fl] - -\definefontfeature - [default] - [default] - [blockligatures=yes] - -\setupbodyfont[pagella] - -... -\stoptyping - -This way it works globally. Of course you can also bind it to a font instance: - -\startbuffer -\blockligatures[fi,fl] - -\definefontfeature - [default:blockligs] - [default] - [blockligatures=yes] - -\definefont[DemoBlockY][Serif*default:blockligs at 20pt] -\definefont[DemoBlockN][Serif*default at 20pt] - -Here we have no ligatures: {\DemoBlockY fi ff fl}, while here we get -them: {\DemoBlockN fi ff fl}. Of course it also depends on the font. -\stopbuffer - -\typebuffer \start \showfontkerns \getbuffer \par \stop - -There is one limitation: you need to specify the blocked ligatures before a font -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] - - {\em Todo.} - -\stopsection - -\stopchapter |