cld-goodies.tex /size: 16 Kb    last modification: 2021-10-28 13:50
1% language=us runpath=texruns:manuals/cld
2
3\startcomponent cld-macros
4
5% \usemodule[man-01]
6% \setvariables[document][title=Font Goodies, author=Hans Hagen]
7% \setups[titlepage]
8
9\environment cld-environment
10
11\startchapter[title=Font goodies]
12
13\startsection[title=Introduction]
14
15One of the interesting aspects of \TEX\ is that it provides control over fonts
16and \LUATEX\ provides quite some. In \CONTEXT\ we support basic functionality,
17like \OPENTYPE\ features, as well as some extra functionality. We also have a
18mechanism for making virtual fonts which is mostly used for the transition from
19\TYPEONE\ math fonts to \OPENTYPE\ math fonts. Instead of hard coding specific
20details in the core \LUA\ code, we use so called \LUA\ Font Goodies to control
21them. These goodies are collected in tables and live in files. When a font is
22loaded, one or more such goodie files can be loaded alongside.
23
24In the following typescript we load a goodies file that defines a virtual Lucida
25math font. The goodie file is loaded immediately and some information in the
26table is turned into a form that permits access later on: the virtual font id
27\type {lucida-math} that is used as part of the font specification.
28
29\starttyping
30\starttypescript [math] [lucida]
31    \loadfontgoodies[lucida-math]
32    \definefontsynonym[MathRoman][lucidamath@lucida-math]
33\stoptypescript
34\stoptyping
35
36Not all information is to be used directly. Some can be accessed when needed. In
37the following case the file \type {dingbats.lfg} gets loaded (only once) when the
38font is actually used. In that file, there is information that is used by the
39\type {unicoding} feature.
40
41\starttyping
42\definefontfeature
43  [dingbats]
44  [mode=base,
45   goodies=dingbats,
46   unicoding=yes]
47
48\definefont[dingbats][file:dingbats][features=dingbats]
49\stoptyping
50
51In the following sections some aspects of goodies are discussed. We don't go into
52details of what these goodies are, but just stick to the \LUA\ side of the
53specification.
54
55\stopsection
56
57\startsection[title=Virtual math fonts]
58
59A virtual font is defined using the \type {virtuals} entry in the \type
60{mathematics} subtable. As \TYPEONE\ fonts are used, an additional table \type
61{mapfiles} is needed to specify the files that map filenames onto real files.
62
63\startsmalltyping
64return {
65  name = "px-math",
66  version = "1.00",
67  comment = "Goodies that complement px math.",
68  author = "Hans Hagen",
69  copyright = "ConTeXt development team",
70  mathematics = {
71    mapfiles = {
72        "mkiv-px.map",
73    },
74    virtuals = {
75      ["px-math"] = {
76        { name = "texgyrepagella-regular.otf", features = "virtualmath", main = true },
77        { name = "rpxr.tfm", vector = "tex-mr" } ,
78        { name = "rpxmi.tfm", vector = "tex-mi", skewchar=0x7F },
79        { name = "rpxpplri.tfm", vector = "tex-it", skewchar=0x7F },
80        { name = "pxsy.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
81        { name = "pxex.tfm", vector = "tex-ex", extension = true } ,
82        { name = "pxsya.tfm", vector = "tex-ma" },
83        { name = "pxsyb.tfm", vector = "tex-mb" },
84        { name = "texgyrepagella-bold.otf", vector = "tex-bf" } ,
85        { name = "texgyrepagella-bolditalic.otf", vector = "tex-bi" } ,
86        { name = "lmsans10-regular.otf", vector = "tex-ss", optional=true },
87        { name = "lmmono10-regular.otf", vector = "tex-tt", optional=true },
88      },
89    }
90  }
91}
92\stopsmalltyping
93
94Here the \type {px-math} virtual font is defined. A series of fonts is loaded and
95combined into one. The \type {vector} entry is used to tell the builder how to
96map the glyphs onto \UNICODE. Additional vectors can be defined, for instance:
97
98\starttyping
99fonts.encodings.math["mine"] = {
100    [0x1234] = 0x56,
101}
102\stoptyping
103
104Eventually these specifications wil be replaced by real \OPENTYPE\ fonts, but
105even then we will keep the virtual definitions around.
106
107\startsection[title=Math alternates]
108
109In addition to the official \type {ssty} feature for enforcing usage of script
110and scriptscript glyphs, some stylistic alternates can be present.
111
112\startsmalltyping
113return {
114  name = "xits-math",
115  version = "1.00",
116  comment = "Goodies that complement xits (by Khaled Hosny).",
117  author = "Hans Hagen",
118  copyright = "ConTeXt development team",
119  mathematics = {
120    alternates = {
121      cal       = {
122        feature = 'ss01',
123        value   = 1,
124        comment = "Mathematical Calligraphic Alphabet"
125      },
126      greekssup = {
127        feature = 'ss02',
128        value   = 1,
129        comment = "Mathematical Greek Sans Serif Alphabet"
130      },
131      greekssit = {
132        feature = 'ss03',
133        value   = 1,
134        comment = "Mathematical Italic Sans Serif Digits"
135      },
136      monobfnum = {
137        feature = 'ss04',
138        value   = 1,
139        comment = "Mathematical Bold Monospace Digits"
140      },
141      mathbbbf  = {
142        feature = 'ss05',
143        value   = 1,
144        comment = "Mathematical Bold Double-Struck Alphabet"
145      },
146      mathbbit  = {
147        feature = 'ss06',
148        value   = 1,
149        comment = "Mathematical Italic Double-Struck Alphabet"
150      },
151      mathbbbi  = {
152        feature = 'ss07',
153        value   = 1,
154        comment = "Mathematical Bold Italic Double-Struck Alphabet"
155      },
156      upint     = {
157        feature = 'ss08',
158        value   = 1,
159        comment = "Upright Integrals"
160      },
161    }
162  }
163}
164\stopsmalltyping
165
166These can be activated (in math mode) with the \type {\mathalternate} command
167like:
168
169\starttyping
170$\mathalternate{cal}Z$
171\stoptyping
172
173\stopsection
174
175\startsection[title=Math parameters]
176
177Another goodie related to math is the overload of some parameters (part of the
178font itself) and variables (used in making virtual shapes).
179
180\startsmalltyping
181return {
182  name = "lm-math",
183  version = "1.00",
184  comment = "Goodies that complement latin modern math.",
185  author = "Hans Hagen",
186  copyright = "ConTeXt development team",
187  mathematics = {
188    mapfiles = {
189      "lm-math.map",
190      "lm-rm.map",
191      "mkiv-base.map",
192    },
193    virtuals = {
194      ["lmroman5-math"]      = five,
195      ["lmroman6-math"]      = six,
196      ["lmroman7-math"]      = seven,
197      ["lmroman8-math"]      = eight,
198      ["lmroman9-math"]      = nine,
199      ["lmroman10-math"]     = ten,
200      ["lmroman10-boldmath"] = ten_bold,
201      ["lmroman12-math"]     = twelve,
202      ["lmroman17-math"]     = seventeen,
203    },
204    variables = {
205      joinrelfactor = 3, -- default anyway
206    },
207    parameters = { -- test values
208  --  FactorA = 123.456,
209  --  FactorB = false,
210  --  FactorC = function(value,target,original) return 7.89 * target.factor end,
211  --  FactorD = "Hi There!",
212    },
213  }
214}
215\stopsmalltyping
216
217In this example you see several virtuals defined which is due to the fact that
218Latin Modern has design sizes. The values (like \type {twelve} are tables defined
219before the return happens and are not shown here. The variables are rather
220\CONTEXT\ specific, and the parameters are those that come with regular
221\OPENTYPE\ math fonts (so the example names are invalid).
222
223In the following example we show two wasy to change parameters. In this case we
224have a regular \OPENTYPE\ math font. First we install a patch to the font itself.
225That change will be cached. We could also have changed that parameter using the
226goodies table. The first method is the oldest.
227
228\startsmalltyping
229local patches = fonts.handlers.otf.enhancers.patches
230
231local function patch(data,filename,threshold)
232  local m = data.metadata.math
233  if m then
234    local d = m.DisplayOperatorMinHeight or 0
235    if d < threshold then
236      patches.report("DisplayOperatorMinHeight(%s -> %s)",d,threshold)
237      m.DisplayOperatorMinHeight = threshold
238    end
239  end
240end
241
242patches.register(
243  "after",
244  "check math parameters",
245  "asana",
246  function(data,filename)
247    patch(data,filename,1350)
248  end
249)
250
251local function less(value,target,original)
252  return 0.25 * value
253end
254
255return {
256  name = "asana-math",
257  version = "1.00",
258  comment = "Goodies that complement asana.",
259  author = "Hans Hagen",
260  copyright = "ConTeXt development team",
261  mathematics = {
262    parameters = {
263      StackBottomDisplayStyleShiftDown = less,
264      StackBottomShiftDown             = less,
265      StackDisplayStyleGapMin          = less,
266      StackGapMin                      = less,
267      StackTopDisplayStyleShiftUp      = less,
268      StackTopShiftUp                  = less,
269      StretchStackBottomShiftDown      = less,
270      StretchStackGapAboveMin          = less,
271      StretchStackGapBelowMin          = less,
272      StretchStackTopShiftUp           = less,
273    }
274  }
275}
276\stopsmalltyping
277
278We use a function so that the scaling is taken into account as the values passed
279are those resulting from the scaling of the font to the requested size.
280
281\stopsection
282
283\startsection[title=Unicoding]
284
285We still have to deal with existing \TYPEONE\ fonts, and some of them have an
286encoding that is hard to map onto \UNICODE\ without additional information. The
287following goodie does that. The keys in the \type {unicodes} table are the glyph
288names. Keep in mind that this only works with simple fonts. The \CONTEXT\ code
289takes care of kerns but that's about it.
290
291\startsmalltyping
292return {
293  name = "dingbats",
294  version = "1.00",
295  comment = "Goodies that complement dingbats (funny names).",
296  author = "Hans Hagen",
297  copyright = "ConTeXt development team",
298  remapping = {
299    tounicode = true,
300    unicodes = {
301      a1   = 0x2701,
302      a10  = 0x2721,
303      a100 = 0x275E,
304      a101 = 0x2761,
305      .............
306      a98  = 0x275C,
307      a99  = 0x275D,
308    },
309  },
310}
311\stopsmalltyping
312
313The \type {tounicode} option makes sure that additional information ends ip in
314the output so that cut|-|and|-|paste becomes more trustworthy.
315
316\stopsection
317
318\startsection[title=Typescripts]
319
320Some font collections, like antykwa, come with so many variants that defining
321them all in typescripts becomes somewhat of a nuisance. While a regular font has
322a typescript of a few lines, antykwa needs way more lines. This is why we provide
323a nother way as well, using goodies.
324
325\startsmalltyping
326return {
327  name = "antykwapoltawskiego",
328  version = "1.00",
329  comment = "Goodies that complement Antykwa Poltawskiego",
330  author = "Hans & Mojca",
331  copyright = "ConTeXt development team",
332  files = {
333    name = "antykwapoltawskiego", -- shared
334    list = {
335      ["AntPoltLtCond-Regular.otf"] = {
336     -- name   = "antykwapoltawskiego",
337        weight = "light",
338        style  = "regular",
339        width  = "condensed",
340      },
341      ["AntPoltLtCond-Italic.otf"] = {
342        weight = "light",
343        style  = "italic",
344        width  = "condensed",
345      },
346      ["AntPoltCond-Regular.otf"] = {
347        weight = "normal",
348        style  = "regular",
349        width  = "condensed",
350      },
351
352      .......
353
354
355      ["AntPoltExpd-BoldItalic.otf"] = {
356        weight = "bold",
357        style  = "italic",
358        width  = "expanded",
359      },
360    },
361  },
362  typefaces = { -- for Mojca (experiment, names might change)
363    ["antykwapoltawskiego-light"] = {
364      shortcut     = "rm",
365      shape        = "serif",
366      fontname     = "antykwapoltawskiego",
367      normalweight = "light",
368      boldweight   = "medium",
369      width        = "normal",
370      size         = "default",
371      features     = "default",
372    },
373
374    .......
375
376  },
377}
378\stopsmalltyping
379
380This is a typical example of when a goodies file is loaded directly:
381
382\starttyping
383\loadfontgoodies[antykwapoltawskiego]
384\stoptyping
385
386A bodyfont is now defined by choosing from the defined combinations:
387
388\starttyping
389\definetypeface
390  [name=mojcasfavourite,
391   preset=antykwapoltawskiego,
392   normalweight=light,
393   boldweight=bold,
394   width=expanded]
395
396\setupbodyfont
397  [mojcasfavourite]
398\stoptyping
399
400This mechanism is a follow up on a discussion at a \CONTEXT\ conference, still
401somewhat experimental, and a playground for Mojca.
402
403\stopsection
404
405\startsection[title=Font strategies]
406
407This goodie is closely related to the Oriental \TEX\ project where a dedicated
408paragraph optimizer can be used. A rather advanced font is used (husayni) and its
409associated goodie file is rather extensive. It defines stylistic features,
410implements a couple of feature sets, provides colorschemes and most of all,
411defines some strategies for making paragraphs look better. Some of the goodie
412file is shown here.
413
414\startsmalltyping
415local yes = "yes"
416
417local basics = {
418  analyze  = yes,
419  mode     = "node",
420  language = "dflt",
421  script   = "arab",
422}
423
424local analysis = {
425  ccmp = yes,
426  init = yes, medi = yes, fina = yes,
427}
428
429local regular = {
430  rlig = yes, calt = yes, salt = yes, anum = yes,
431  ss01 = yes, ss03 = yes, ss07 = yes, ss10 = yes, ss12 = yes, ss15 = yes, ss16 = yes,
432  ss19 = yes, ss24 = yes, ss25 = yes, ss26 = yes, ss27 = yes, ss31 = yes, ss34 = yes,
433  ss35 = yes, ss36 = yes, ss37 = yes, ss38 = yes, ss41 = yes, ss42 = yes, ss43 = yes,
434  js16 = yes,
435}
436
437local positioning = {
438  kern = yes, curs = yes, mark = yes, mkmk = yes,
439}
440
441local minimal_stretching = {
442  js11 = yes, js03 = yes,
443}
444
445local medium_stretching = {
446  js12=yes, js05=yes,
447}
448
449local maximal_stretching= {
450  js13 = yes, js05 = yes, js09 = yes,
451}
452
453local wide_all = {
454  js11 = yes, js12 = yes, js13 = yes, js05 = yes, js09 = yes,
455}
456
457local shrink = {
458  flts = yes, js17 = yes, ss05 = yes, ss11 = yes, ss06 = yes, ss09 = yes,
459}
460
461local default = {
462  basics, analysis, regular, positioning, -- xxxx = yes, yyyy = 2,
463}
464
465return {
466  name = "husayni",
467  version = "1.00",
468  comment = "Goodies that complement the Husayni font by Idris Samawi Hamid.",
469  author = "Idris Samawi Hamid and Hans Hagen",
470  featuresets = { -- here we don't have references to featuresets
471    default = {
472      default,
473    },
474    minimal_stretching = {
475      default,
476      js11 = yes, js03 = yes,
477    },
478    medium_stretching = {
479      default,
480      js12=yes, js05=yes,
481    },
482    maximal_stretching= {
483      default,
484      js13 = yes, js05 = yes, js09 = yes,
485    },
486    wide_all = {
487      default,
488      js11 = yes, js12 = yes, js13 = yes, js05 = yes, js09 = yes,
489    },
490    shrink = {
491      default,
492      flts = yes, js17 = yes, ss05 = yes, ss11 = yes, ss06 = yes, ss09 = yes,
493    },
494  },
495  solutions = { -- here we have references to featuresets, so we use strings!
496    experimental = {
497      less = {
498        "shrink"
499      },
500      more = {
501        "minimal_stretching",
502        "medium_stretching",
503        "maximal_stretching",
504        "wide_all"
505      },
506    },
507  },
508  stylistics = {
509    ......
510    ss03 = "level-1 stack over Jiim, initial entry only",
511    ss04 = "level-1 stack over Jiim, initial/medial entry",
512    ......
513    ss54 = "chopped finals",
514    ss55 = "idgham-tanwin",
515    ......
516    js11 = "level-1 stretching",
517    js12 = "level-2 stretching",
518    ......
519    js21 = "Haa.final_alt2",
520  },
521  colorschemes = {
522    default = {
523      [1] = {
524        "Onedotabove", "Onedotbelow", ...
525      },
526      [2] = {
527        "Fathah", "Dammah", "Kasrah", ...
528      },
529      [3] = {
530        "Ttaa.waqf", "SsLY.waqf", "QLY.waqf", ...
531      },
532      [4] = {
533        "ZeroArabic.ayah", "OneArabic.ayah", "TwoArabic.ayah", ...
534      },
535      [5] = {
536        "Ayah", "Ayah.alt1", "Ayah.alt2", ...
537      }
538    }
539  }
540}
541\stopmalltyping
542
543Discussion of these goodies is beyond this document and happens elsewhere.
544
545\stopsection
546
547\startsection[title=Composition]
548
549The \type {compose} features extends a font with additional (virtual) shapes.
550This is mostly used with \TYPEONE\ fonts that lack support for eastern european
551languages. The type {compositions} subtable is used to control placement of
552accents. This can be done per font.
553
554\startmalltyping
555local defaultunits = 193 - 30
556
557-- local compose = {
558--                DY = defaultunits,
559--   [0x010C] = { DY = defaultunits }, -- Ccaron
560--   [0x02C7] = { DY = defaultunits }, -- textcaron
561-- }
562
563-- fractions relative to delta(X_height - x_height)
564
565local defaultfraction = 0.85
566
567local compose = {
568  DY = defaultfraction, -- uppercase compensation
569}
570
571return {
572  name = "lucida-one",
573  version = "1.00",
574  comment = "Goodies that complement lucida.",
575  author = "Hans and Mojca",
576  copyright = "ConTeXt development team",
577  compositions = {
578    ["lbr"]  = compose,
579    ["lbi"]  = compose,
580    ["lbd"]  = compose,
581    ["lbdi"] = compose,
582  }
583}
584\stopsmalltyping
585
586\stopsection
587
588\startsection[title=Postprocessing]
589
590You can hook postprocessors into the scaler. Future versions might provide more
591control over where this happens.
592
593\startsmalltyping
594local function statistics(tfmdata)
595    commands.showfontparameters(tfmdata)
596end
597
598local function squeeze(tfmdata)
599  for k, v in next, tfmdata.characters do
600    v.height = 0.75 * (v.height or 0)
601    v.depth  = 0.75 * (v.depth  or 0)
602  end
603end
604
605return {
606  name = "demo",
607  version = "1.00",
608  comment = "An example of goodies.",
609  author = "Hans Hagen",
610  postprocessors = {
611    statistics = statistics,
612    squeeze    = squeeze,
613  },
614}
615\stopsmalltyping
616
617\stopsection
618
619\stopchapter
620
621\stopcomponent
622