% language=us runpath=texruns:manuals/evenmore

\environment evenmore-style

\startcomponent evenmore-expansion

\startchapter[title=Expansion]

Character expansion was introduced in \PDFTEX\ a couple of decades ago. It is a
mechanism that scales glyphs horizontally in order to reduce excessive whitespace
that is needed to properly justify a paragraph. I must admit that I never use it
myself but there are users who do. Although this mechanism evolved a bit, and in
\LUATEX\ is implemented a bit different, the basics remained the same. If you
have no clue what this is about, you can just quite reading here.

A font can be set up to expand characters by a certain amount: they can shrink or
stretch. This is driven by three parameters: \type {step}, \type {stretch} and
\type {shrink}. The values are in thousands because \TEX\ has no float quantity.
Originally these values were percentages of the width of a glyph, later they
became related to the em width but in \LUATEX\ we went back to the former
definition.

In \CONTEXT\ \MKIV\ we have an interface that works as follows:

\startbuffer
\startluacode
    local classes = fonts.expansions.classes

    classes.qualitya = {
        vector  = "default",
        factor  = 1,
        stretch = 4,
        shrink  = 2,
        step    = .5,
    }

    classes.qualityb = {
        vector  = "default",
        factor  = 1,
        stretch = 8,
        shrink  = 4,
        step    = .5,
    }

\stopluacode
\stopbuffer

\typebuffer[option=TEX] \getbuffer

The default vector looks like this:

\starttyping[option=LUA]
vectors['default'] = {
    [0x0041] = 0.5, -- A
    [0x0042] = 0.7, -- B
    -- and some more
}
\stoptyping

The values that we pass to the engine are stretch 40, shrink 20, and step 5 for
\type {qualitya} and stretch 80, shrink 40, and step 5 for \type {qualityb}, so
we multiply by 10. In the engine the step is limited to 100, the stretch to 1000
and the shrink to 500. But these extremes produce quite bad results.

The expansion class is set with the \type {expansion} feature, as in:

\startbuffer
\definefontfeature [basea] [default] [expansion=qualitya]
\definefontfeature [baseb] [default] [expansion=qualityb]

\definefont [FontA] [Serif*basea]
\definefont [FontB] [Serif*baseb]

\stopbuffer

\typebuffer[option=TEX] \getbuffer

\startbuffer[sample]
    \setupalign[verytolerant,stretch,hz] % hz triggers expansion
    \dorecurse {30} {%
        {\FontB \darkred test me #1,} \FontA \dorecurse{#1}{test ##1, }%
    }\par
\stopbuffer

In \in {figure} [hz:1] we see this in action, using the following code:

\typebuffer[sample][option=TEX]

\startplacefigure[reference=hz:1]
    \getbuffer[sample]
\stopplacefigure

There is one drawback with this method, although so far I never heard a user
complain, which can be an indication of how this mechanism is used: you cannot
mix fonts with different step, stretch and|/|or shrink. As we just did this in
the example, this statement is not really true in \LUAMETATEX: there we only need
to keep the step the same. This is compatible in the sense that otherwise we
would quit the run, so at least we carry on: the smallest stretch and shrink is
taken. But, we do issue a warning (once) because there can be side effects! This
is not that pretty a solution anyway because it depends on what font is used
first.

It is for this reason that we have another option: in \CONTEXT\ \LMTX\ you can
define a specific expansion:

\startbuffer
\defineexpansion
  [myexpansion]
  [step=1, % default
   stretch=50,
   shrink=20]
\stopbuffer

\typebuffer[option=TEX] \getbuffer

There is no need to have a different step than~1. In \PDFTEX\ instances are
created per step used, but in \LUATEX\ this is more fluid. There is no gain in
using different steps. We just keep it for compatibility reasons. This specific
expansion is enables with:

\starttyping[option=TEX]
\setexpansion[myexpansion]
\stoptyping

and the result is shown in \in {figure} [hz:2]. This time the set expansion wins
over the one set in the font. All fonts that have the expansion feature set are
treated the same. By using this method you can locally have different values.

\startplacefigure[reference=hz:2]
    \setexpansion[myexpansion]
    \getbuffer[sample]
\stopplacefigure

Deep down we use some new primitives:

\starttyping[option=TEX]
\adjustspacingstep
\adjustspacingstretch
\adjustspacingshrink
\stoptyping

The step is limited to 100 (10\percent) and the stretch and shrink to 500
(50\percent) and the stretch to 1000 (100\percent) but these extremes are only
useful for examples.

\stopchapter

\stopcomponent
