From e2658addf306f729945c184e46f98df39dd7026c Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 29 May 2019 21:10:47 +0200 Subject: 2019-05-29 19:20:00 --- .../sources/general/fonts/fonts/fonts-appendix.tex | 483 ---- .../general/fonts/fonts/fonts-demo-rule.lua | 47 - .../general/fonts/fonts/fonts-environment.tex | 74 - .../general/fonts/fonts/fonts-extensions.tex | 2729 ------------------- .../sources/general/fonts/fonts/fonts-features.tex | 2742 -------------------- .../sources/general/fonts/fonts/fonts-formats.tex | 896 ------- .../sources/general/fonts/fonts/fonts-hooks.tex | 917 ------- .../general/fonts/fonts/fonts-introduction.tex | 95 - .../sources/general/fonts/fonts/fonts-lookups.tex | 410 --- .../sources/general/fonts/fonts/fonts-math.tex | 1093 -------- .../sources/general/fonts/fonts/fonts-methods.tex | 376 --- .../sources/general/fonts/fonts/fonts-mkiv.tex | 76 - .../sources/general/fonts/fonts/fonts-modes.tex | 817 ------ .../sources/general/fonts/fonts/fonts-scripts.tex | 18 - .../sources/general/fonts/fonts/fonts-tricks.tex | 390 --- .../general/fonts/manuals-explaining-contents.tex | 11 - .../general/fonts/manuals-explaining-cover.tex | 199 -- .../fonts/manuals-explaining-environment.tex | 325 --- 18 files changed, 11698 deletions(-) delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-appendix.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-demo-rule.lua delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-environment.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-extensions.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-features.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-formats.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-hooks.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-introduction.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-lookups.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-math.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-methods.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-mkiv.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-modes.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-scripts.tex delete mode 100644 doc/context/sources/general/fonts/fonts/fonts-tricks.tex delete mode 100644 doc/context/sources/general/fonts/manuals-explaining-contents.tex delete mode 100644 doc/context/sources/general/fonts/manuals-explaining-cover.tex delete mode 100644 doc/context/sources/general/fonts/manuals-explaining-environment.tex (limited to 'doc/context/sources/general/fonts') diff --git a/doc/context/sources/general/fonts/fonts/fonts-appendix.tex b/doc/context/sources/general/fonts/fonts/fonts-appendix.tex deleted file mode 100644 index 2eab26a93..000000000 --- a/doc/context/sources/general/fonts/fonts/fonts-appendix.tex +++ /dev/null @@ -1,483 +0,0 @@ -% language=uk - -\startcomponent fonts-appendix - -\environment fonts-environment - -\startchapter[title=Appendix][color=darkgray] - -\startsection[title=The \type {tfm} file,reference=fontdata:tfm] - -The (binary) \type {tfm} file is not human readable but can be turned into a -verbose property list which is not that hard to understand. - -\starttyping -tftopl texnansi-lmr10.tfm -\stoptyping - -Here is an excerpt from the data file. It starts with some general properties of -the font. The \type {O} means that the value is in octal while the \type {R} is a -real. Keep in mind that \TEX\ has no datatype \quote {real} so internally it is -just integers representing scaled points. - -\startnarrowtyping -(FAMILY LMROMAN10) -(FACE O 352) -(CODINGSCHEME LY1 ENCODING /TEX'N'ANSI, Y&Y/) -(DESIGNSIZE R 10.0) -(COMMENT DESIGNSIZE IS IN POINTS) -(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE) -(CHECKSUM O 4720464277) -\stopnarrowtyping - -A text font has the following font dimensions: - -\startnarrowtyping -(FONTDIMEN - (SLANT R 0.0) - (SPACE R 0.333333) - (STRETCH R 0.166667) - (SHRINK R 0.111112) - (XHEIGHT R 0.43055) - (QUAD R 1.0) - (EXTRASPACE R 0.111112) - ... -) -\stopnarrowtyping - -Kerns and ligatures are packed into a table that is basically a sequence of -labelled entries. Here we see the entry for the character \type {f} which has -three ligatures: \type {ff}, \type {fi} and \type {fl}. Because ligatures can be -chained, octal slot 13 will have ligature entries for \type {ffl} and \type -{ffi}. - -\startnarrowtyping -(LIGTABLE - ... - (LABEL C f) - (LIG C f O 13) - (LIG C i O 14) - (LIG C l O 10) - (KRN O 135 R 0.027779) - (KRN O 41 R 0.027779) - (KRN O 51 R 0.027779) - (KRN O 77 R 0.027779) - (KRN O 223 R 0.027779) - (KRN O 224 R 0.027779) - (KRN O 140 R 0.027779) - (KRN O 47 R 0.027779) - (STOP) - ... -) -\stopnarrowtyping - -Each character gets its own entry. In this case there is no depth involved so it -is not shown. The comment is just a repetition of the entry in the ligtable. - -\startnarrowtyping -(CHARACTER C f - (CHARWD R 0.30555) - (CHARHT R 0.688875) - (CHARIC R 0.079222) - (COMMENT - (LIG C f O 13) - (LIG C i O 14) - (LIG C l O 10) - (KRN O 135 R 0.027779) - (KRN O 41 R 0.027779) - (KRN O 51 R 0.027779) - (KRN O 77 R 0.027779) - (KRN O 223 R 0.027779) - (KRN O 224 R 0.027779) - (KRN O 140 R 0.027779) - (KRN O 47 R 0.027779) - ) -) -\stopnarrowtyping - -\stopsection - -\startsection[title=The \type {vf} file,reference=fontdata:vf] - -A virtual font specification file can be converted to a more readable format with -\type {vftovp}, for instance: - -\starttyping -vftovp eurm10.vf -\stoptyping - -The information in a \type {vf} file will be combined with the data in the -accompanying \type {tfm} file so the output looks similar: - -\startnarrowtyping -(VTITLE ) -(FAMILY UNSPECIFIED) -(FACE F MRR) -(CODINGSCHEME TEX MATH ITALIC) -(DESIGNSIZE R 10.0) -(COMMENT DESIGNSIZE IS IN POINTS) -(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE) -(CHECKSUM O 24401046203) -(SEVENBITSAFEFLAG TRUE) -\stopnarrowtyping - -Because this font is a math font there is no space defined. - -\startnarrowtyping -(FONTDIMEN - (SLANT R 0.0) - (SPACE R 0.0) - (STRETCH R 0.0) - (SHRINK R 0.0) - (XHEIGHT R 0.459) - (QUAD R 1.0) - (EXTRASPACE R 0.0) -) -\stopnarrowtyping - -A virtual font will take glyphs from another font and therefore there are entries -that refer to these fonts. In the following definition index \type {0} is created -(the \type {D} specifies a decimal entry). - -\startnarrowtyping -(MAPFONT D 0 - (FONTNAME eurm10) - (FONTCHECKSUM O 4276740471) - (FONTAT R 1.0) - (FONTDSIZE R 10.0) -) -(MAPFONT D 1 - (FONTNAME cmmi10) - (FONTCHECKSUM O 1350061076) - (FONTAT R 1.0) - (FONTDSIZE R 10.0) -) -\stopnarrowtyping - -The zero indexed font is the default, so in the following entry this font is -taken: - -\startnarrowtyping -(CHARACTER C W - (CHARWD R 0.986) - (CHARHT R 0.691) - (CHARIC R 0.056) - (COMMENT - (KRN O 177 R 0.056) - (KRN O 75 R -0.056) - (KRN O 73 R -0.083) - (KRN O 72 R -0.083) - ) - (MAP - (SETCHAR C W) - ) -) -\stopnarrowtyping - -The next specification is a combination of two other glyphs becoming a new -glyph. We see here that the \type {MAP} table is actually a sort of program: - -\startnarrowtyping -(CHARACTER O 200 - (CHARWD R 0.622) - (CHARHT R 0.691) - (MAP - (PUSH) - (MOVEDOWN R -0.18) - (MOVERIGHT R 0.015) - (SELECTFONT D 2) - (SETCHAR O 40) - (POP) - (SELECTFONT D 0) - (SETCHAR C h) - ) -) -\stopnarrowtyping - -The character information is also in the \type {tfm} companion and that is what -\TEX\ uses. The virtual information kicks in when the backend is creating the -page stream and embedding the fonts. - -\stopsection - -\startsection[title=The \type {map} file,reference=fontdata:map] - -In a map file each line maps a font name onto a file that contains the font -shapes in bitmap or outline format. For instance in the file \type -{lm-texnansi.map} we find the line: - -\startnarrowtyping -texnansi-lmr10 LMRoman10-Regular "enclmtexnansi ReEncodeFont" 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 = { - [