summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2021-01-11 18:09:53 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2021-01-11 18:09:53 +0100
commit980ad5b78d69aa8abfb093c7e6729b0024ce0b49 (patch)
treecc3ff7b95fe9e334f11dc97f04587914321fca6d
parent3a048d406386e8b8eb5c1315e57d271237da89be (diff)
downloadcontext-980ad5b78d69aa8abfb093c7e6729b0024ce0b49.tar.gz
2021-01-11 16:30:00
-rw-r--r--doc/context/documents/general/manuals/luametatex.pdfbin1383227 -> 1383078 bytes
-rw-r--r--doc/context/sources/general/manuals/followingup/followingup-fonts.tex593
-rw-r--r--doc/context/sources/general/manuals/followingup/followingup-style.tex2
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex.tex2
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-cs.mkii1
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26128 -> 26131 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin253881 -> 254409 bytes
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/driv-shp.lmt13
-rw-r--r--tex/context/base/mkxl/font-col.lmt6
-rw-r--r--tex/context/base/mkxl/font-ctx.lmt14
-rw-r--r--tex/context/base/mkxl/font-glf.mklx4
-rw-r--r--tex/context/base/mkxl/font-imp-math.lmt6
-rw-r--r--tex/context/base/mkxl/font-ini.mklx26
-rw-r--r--tex/context/base/mkxl/font-otj.lmt1320
-rw-r--r--tex/context/base/mkxl/lang-hyp.lmt8
-rw-r--r--tex/context/base/mkxl/node-nut.lmt8
-rw-r--r--tex/context/base/mkxl/trac-vis.lmt27
-rw-r--r--tex/context/interface/mkii/keys-cs.xml1
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
25 files changed, 1574 insertions, 471 deletions
diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf
index 52c93219f..635e56000 100644
--- a/doc/context/documents/general/manuals/luametatex.pdf
+++ b/doc/context/documents/general/manuals/luametatex.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/followingup/followingup-fonts.tex b/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
index a3059847e..2f7320b12 100644
--- a/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
+++ b/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
@@ -6,104 +6,376 @@
\startchapter[title={Scaled fonts}]
-Although \CONTEXT\ is quite efficient with fonts there is always room for
-improvement. However, after years of fine tuning the font mechanisms there was
-not that much room left. On the average, given that \TEX\ is mostly about fonts,
-what we have is quite okay, but for some scripts, like \CJK\ the demands on
-resources can be rather high. This made me think of a different approach to
-scaling. Nowadays fonts seldom come in design sizes. Also, in \CONTEXT\ \MKIV\
-and therefore \LMTX\ we always had so called dynamic features: apply additional
-features locally, although that comes with a small penalty in performance, it
-saves additional font instances. It is a good approach for the occasional small
-stretch of glyphs, like small capped logos and such.
-
-Using a font at a larger size means that we need to provide \TEX\ with the right
-dimensions: it needs them for instance for for braking paragraph into lines or
-wrapping text in boxes. The amount of information that \TEX\ needs is small: only
-dimensions. Of course there are ligatures and kerns but in so called base mode we
-seldom have many. The data needed for node mode (used for more complex \OPENTYPE\
-fonts) can be shared and lives at the \LUA\ end. But even then the character
-table is copied and scaled. Actually, we seldom need that information but it is
-good to have it and in the case of virtual fonts it is needed. But, when a font
-is used at a different size, and al the features are the same, we can think of
-a different approach.
-
-That approach is tagged as \quote {dynamic font scaling}, which means that we
-don't need to define a new font instance when the same feature set is used. Or
-course in addition to this features one can still use the dynamic features. This
-means that for instance chapter titling can use the bodyfont instance and just
-apply additional scaling. Although for a normal run the number of loaded fonts is
-normally small, and the number of instances also isn't that impressive it can
-happen in a large document that you end up with a few dozen. That number can now
-be reduced to half a dozen.
-
-Of course there can be side effects, which is why it's currently tagged as
-experimental. There is also a small performance hit because we now need to track
-it but that is gained back because we load less fonts and have less glyph runs.
-
-So how does it work? Here is an example:
+\startsection[title={History}]
+
+The infrastructure for fonts makes for a large part of the code of any \TEX\
+macro package. We have to go back in time to understand why. When \TEX\ showed
+up, fonts were collections of bitmaps and measures. There were at most 256 glyphs
+in a font and in order to do its job, \TEX\ needed to know (and still needs to
+know) the width, height and depth of glyphs. If you want ligatures it also needs
+to know how to construct them from the input and when you want kerning there has
+to be additional information about what neighboring glyphs need a kern in
+between. Math is yet another subtask that demands extra information, like chains
+of glyphs that grow in size and if needed even recipes of how to construct large
+shapes from smaller ones.
+
+Fonts come in sizes, and for instance Latin Modern has quite a few variants where
+the shapes are adapted to the size. This means that when you need a 9pt regular
+shape alongside a 12pt one, two fonts have to be loaded. This is quite visible in
+math where we have three related sizes: text, script and scriptscript, grouped in
+so called families.
+
+Plenty has been written (in various documents that come with \CONTEXT) about how
+this all works together and how it impacts the design of the system, so here I
+just give a short summary of what a font system has to deal with.
+
+\startitemize
+\startitem
+ In a bodyfont setup different sizes (9pt, 10pt, 12pt) can have their own
+ specific set of fonts. This can result in quite some definitions that relate
+ to the style, like regular, bold, italic, bolditalic, slanted and
+ boldslanted, etc. When possible loading the fonts is delayed.
+\stopitem
+\startitem
+ Some font designs have different shapes per bodyfont size. A minor
+ complication is that when one is missing some heuristic best match choice
+ might be needed.
+\stopitem
+\startitem
+ Within a bodyfont size we distinguish size variants. We can go smaller (x and
+ xx), for instance when we use sub- and superscripts in text, or we can go
+ larger, for instance in titling (a, b, c, d, \unknown). Fortunately most of
+ the loading of these can be delayed too.
+\stopitem
+\startitem
+ When instances are not available, scaling can be used, as happens for
+ instance with 11pt in Computer Modern. Actually, this is why in \CONTEXT\ we
+ default to 12pt, because the scaled versions didn't look as nice as the
+ others.
+\stopitem
+\startitem
+ Special features, like smallcaps or oldstyle numerals, can demand their own
+ definitions. More loading and automatic definitions can be triggered by sizes
+ needed in for instance scripts and titling.
+\stopitem
+\startitem
+ A document can have a mixed setup, that is: use different font designs in one
+ document, so some kind of namespace subsystem is needed.
+\stopitem
+\startitem
+ In traditional eight bit engine the dependency of hyphenation on the encoding
+ of a font can result in the necessity to load a font multiple times in
+ different encodings, something that depends on the language mix used.
+\stopitem
+\startitem
+ In the more modern \OPENTYPE\ fonts combinations of features can demand
+ additional instances (one can thing of language|/|script combinations,
+ substitutions in base mode, special effects like boldening, color fonts,
+ etc.).
+\stopitem
+\startitem
+ Math is complicated by the fact that alphabets come from different fonts
+ (sometimes a font has several alphabets which means that some mapping can be
+ needed). Operating on the size, shape, encoding and style axes puts some
+ demands on the font system. Add to this (often) partial (due to lack of
+ fonts) bold support and it gets even more complicated.
+\stopitem
+\startitem
+ There is additional math auto|-|definition and loading code for the sizes
+ used in text scripts and titling.
+\stopitem
+\stopitemize
+
+All this has resulted in a pretty complex subsystem. Although going \OPENTYPE\
+(and emulated \OPENTYPE\ with \TYPEONE\ fonts as we do in \MKIV) removes some
+complications, like encodings, it does also add complexity because of the many
+possible font features, either or not dependent on script and language.
+
+Also, in order to let a font subsystem not impact performance to much, let alone
+extensive memory usage, the \CONTEXT\ font subsystem is rather optimized. The
+biggest burden comes from fonts that have a dynamic (adaptive) definition because
+then we need to do quite a bit of testing per font switch, but even that has
+always been rather fast.
+
+\stopsection
+
+\startsection[title={Reality}]
+
+In \MKIV\ and therefore also in \LMTX\ more font magic happens. The initial node
+lists that makes up a box or paragraph can get manipulated in several ways and
+often fonts are involved. The mentioned font features can be defines static (as
+part of the definition) or dynamic (resolved on the spot at the cost of some
+overhead). Characters can be remapped, fonts can be replaced. The math subsystem
+in \MKIV\ was different right from the start: we use a limited number of families
+(regular, bold, l2r and r2l), and stay abstract till the moment we need to deal
+with the specific alphabets. But still, in \MKIV, we have the families with three
+fonts.
+
+In the \LUAMETATEX\ manual we show some math magic and we do so for different
+fonts. As a side effect, we set up half a dozen bodyfont collections. Even with
+delayed and shared font loading, we end up with 158 instances but quite a bit of
+them are math fonts, at least six per bodyfont size: regular and bold (boldened)
+text, script and scriptscript. Of course most are just copies with different
+scaling that reuse already loaded resources.
+
+If we look at the math fonts that we use today, there is however quite some
+overlap. It starts with a text font. From that script and scriptscript variants
+are derived, but often these variants use many text size related shapes too. Some
+shapes get alternatives (from the \type {ssty} feature), and the whole clone get
+scaled. But, much of the logic of for instance extensibles is the same.
+
+A similar situation happens with for instance large \CJK\ fonts: there are hardly
+any advanced features involved there, so any size is basically a copy with scaled
+dimensions, and these fonts can be real huge!
+
+Actually, when we talk about features, in many cases in \CONTEXT\ you don't
+define them as part of the font. For instance small caps can best be triggered by
+using a dynamic feature: applied to a specific stretch of text. When the font
+handler does its work there are actually four cases: no features get applied,
+something that for instance happens with most monospaced fonts, base mode is
+used, which means that the \TEX\ machinery takes care of constructing ligatures
+and injecting kerns, and node mode, where \LUA\ handles the features. The fourth
+case is a special case of node mode where a different features set is applied.
+\footnote {We also have so called plug mode where an external rendered can do the
+work but that one is only around for some experiments during Idris' font
+development.} At the cost of some extra overhead (for each node mode run) dynamic
+features are quite powerful and save quite some memory and definitions. The
+overhead comes from much more testing regarding the font we deal with because
+suddenly the same font can demand different treatments, depending on what dynamic
+features is active.
+
+Although the font handling is responsible for much of the time spent in \LUA, it is
+still reasonable given what has to be done. Actually, because we have an extensible
+system, it's often the extensions that takes additional runtime. Flexibility comes
+at a price.
+
+\stopsection
+
+\startsection[title={Progress}]
+
+At some point I started playing with realtime glyph scaling. Here realtime means that
+it doesn't depend on the font definition. To get an idea, here is an example:
\startbuffer
-\definescaledfont[MyLargerFontA][scale=2000,style=bold]
-
-test {\MyLargerFontA test} test
+test {\glyphxscale 2500 test} test
\stopbuffer
\typebuffer
-This gives:
-
\getbuffer
-You can also say:
+The glyphs in the current font get scaled horizontally without the need for an extra
+font instance. Now, this kind of trickery puts some constraints on the font handling,
+as is demonstrated in the next example. We use Latin Modern because that font has
+all these ligatures:
\startbuffer
-\definescaledfont[MyLargerFontB][xscale=1200,yscale=2000,style=bold]
-
-test {\MyLargerFontB test} test
+\definedfont[lmroman-regular*default]%
+e{\glyphxscale 2500 ff}icient
+ef{\glyphxscale 2500 f}icient
+ef{\glyphxscale 2500 fi}cient
+e{\glyphxscale 2500 ffi}cient
\stopbuffer
\typebuffer
-Which scaled the over two axis:
+{\getbuffer}
+
+So, in order to deal with this kind of scaling, we now operate not only on the
+font (id) and dynamic feature axes, but also on the scales of which we have three
+variants: glyph scale, glyph xscale and glyph y scale). There is actually also a
+state dimension but we leave that for now. Think of flagging glyphs as initial or
+final. This brings the number of axis to six. It is important to stress that in
+these examples the same font instance is used!
+
+Just for the record: there are several approaches to switching fonts possible but
+for now we stick to a simple font id switch plus glyph scale settings at the
+\TEX\ end. A variant would be to introduce a new mechanism where id's and scales
+go together but for now I see no real gain in that.
+
+\stopsection
+
+\startsection[title={Math}]
+
+Given what is written in the previous sections, a logical question is if we can
+apply scaling to math and the answer is \quotation {yes, we can}. But we actually
+go a bit further and that is partly due to some other properties of the engine.
+
+From \PDFTEX\ the \LUATEX\ engines inherited character protrusion and glyph
+expansions, aka hz. However, where in \PDFTEX\ copies of the font are made that
+carry the expanded dimensions, in \LUATEX\ at some point this was replaced by an
+expansion field in the glyph and kern nodes. So, instead of changing the font id
+of expanded glyphs, the same id is used but with the applied expansion factor set
+in the glyph. A side effect was that in places where dimensions are needed, calls
+to functions that calculate the expanded widths on request (as these can change
+during linebreak calculations) in combination with accessing font dimensions
+directly, we now always use accessor functions. This level of abstraction is even
+more present in \LUAMETATEX. This means that we have an uniform interface to
+fonts and as a side effect scaling is to be dealt with in only a few places in
+the code.
+
+Now, in math we have a few more complications. First of all, we have three sizes
+to consider and we also have lots of parameters that depend on the size. But, as
+I wanted to be able to apply scaling to math, the whole machinery was also
+abstracted in a way that, at the cost of some extra overhead, made it easier to
+work with scaled glyph properties. This means that we can stick to loading only
+one bodyfont size of math (note that each math family has three sizes, where the
+script and script sizes can have different, fine tuned, shapes) and just scale
+that on demand.
+
+Once all that was in place it was a logical next step to see if we could actually
+stick to one instance. Because in \LUAMETATEX\ we try to load fonts efficiently
+we store only the minimally needed information at the \TEX\ end. A font with no
+math therefore has less data per glyph. Again, this brings some abstraction that
+actually helped to implement the one instance mechanism. A math glyph has
+optional lists of increasing sizes and vertical or horizontal extensibles. So
+what got added was an optional chain of smaller sizes. If a character has 3
+different glyphs for the three sizes, the text glyph has a pointer to the script
+glyph which in turn has a pointer to the scriptscript glyph. This means that when
+the math engine needs a specific character at a given size (text, script,
+scriptscript) we just follow that chain.
+
+In an \OPENTYPE\ math font the script and scriptscript sizes are specified as
+percentages of the text size. So, when the dimensions of a glyph are needed, we
+just scale on the fly. Again this adds some overhead but I'm pretty sure that no
+user will notice this.
+
+So, to summarize: if we need a character at scriptscript size, we access the text
+size glyph, check for a pointer to a script size, go there, and again check for a
+smaller size. We just use what fits the bill. And, when we need dimensions we
+just scale. In order to scale we need the relative size, so we need to set that
+up when we load the font. Because in \CONTEXT\ we also can assemble a virtual
+\OPENTYPE\ font from \TYPEONE\ fonts, it was actually that (old) compatibility
+feature that took most time to adapt, not so much because it is complicates but
+because in \LMTX\ we have to bypass some advanced loading mechanisms.
+
+The end result is that for math we now only need to define two fonts per bodyfont
+setup: regular and bold at the natural scale (normally 10pt) and we share these
+for all sizes. It is because of this and what we describe in the next section
+that the 158 instances for the \LUAMETATEX\ manual can now be brought down to 30.
+
+\stopsection
+
+\startsection[title={Text}]
+
+Sharing instances in text mode is relatively simple, although we do have to keep
+in mind that these are extra axis when dealing with font features: two
+neighboring glyphs with the same font id and dynamics but with different scales
+are effectively from different fonts.
+
+Another complication is that when we use font fallbacks (read: take missing
+glyphs from another font) we no longer have a dedicated instance but use a shared
+one. This in itself if not a problem but we do need to handle specified relative
+scales. This was not that hard to patch in \CONTEXT\ \LMTX.
+
+We can enforce aggressive font sharing with:
-\getbuffer
+\starttyping
+\enableexperiments[fonts.compact]
+\stoptyping
+
+After that we often use less instances. Just to give an idea, on the \LUAMETATEX\
+manual we get these stats:
+
+\starttyping
+290 pages, 10.8 sec, 292M lua, 99M tex, 158 instances
+290 pages, 9.5 sec, 149M lua, 35M tex, 30 instances
+\stoptyping
-The low level implementation uses the two variables \type {\glyphxscale} and
-\type {\glyphyscale} that take a number. As with other \TEX\ scaling related
-variables, a value of 1000 represents 1.0 so we have three digits precision.
+So, we win on all fronts when we use this glyph scale mechanism. The magic
+primitive that deals with this is \type {\glyphscale} which accepts a number,
+where \type {1200} and \type {1.2} both mean scaling to 20\percent\ more than
+normal. But one can best not use this primitive directly.
-Because we just scale, the next also works:
+A specific font can be defined using the \type {\definefont} command. In \LMTX\ a
+regular scaler can be followed by two scale factors. The nest example
+demonstrates this:
\startbuffer
-test {\MyLargerFontB test {\em test} test} test
+\definefont[FooA][Serif*default @ 12pt 1800 500]
+\definefont[FooB][Serif*default @ 12pt 0.85 0.4]
+\definefont[FooC][Serif*default @ 12pt]
+
+\definetweakedfont[runwider] [xscale=1.5]
+\definetweakedfont[runtaller][yscale=2.5,xscale=.8,yoffset=-.2ex]
+
+{\FooA test test \runwider test test \runtaller test test}\par
+{\FooB test test \runwider test test \runtaller test test}\par
+{\FooC test test \runwider test test \runtaller test test}\par
\stopbuffer
\typebuffer
-The nested emphasis still works:
+We also use the new \type {\definetweakedfont} command here. This example not
+only shows the two scales but also introduces the offset.
\getbuffer
-For now we only have a simple user interface but it might eventually be more
-integrated. For instance, we can consider defining \type {\tfa} and friends this
-way.
+Here is another one:
+
+\startbuffer
+\definetweakedfont[squeezed] [xscale=0.9]
+\definetweakedfont[squeezed] [xscale=0.9]
+
+\startlines
+$a = b^2 + \sqrt{c}$
+{\squeezed $a = b^2 + \sqrt{c}$}
+\stoplines
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
-In order to make it useful, math is also supported:
+Watch this:
\startbuffer
-\definescaledfont[MyLargerFontC][xscale=1200,yscale=2000]
+\startcombination[4*1]
+ {\bTABLE
+ \bTR \bTD foo \eTD \bTD[style=\squeezed] $x = 1$ \eTD \eTR
+ \bTR \bTD oof \eTD \bTD[style=\squeezed] $x = 2$ \eTD \eTR
+ \eTABLE}
+ {local}
+ {\bTABLE[style=squeezed]
+ \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
+ \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
+ \eTABLE}
+ {global}
+ {\bTABLE[style=\squeezed\squeezed]
+ \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
+ \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
+ \eTABLE}
+ {multiple}
+\stopcombination
+\stopbuffer
-test {\MyLargerFontC test $\sqrt{x}$ test} test
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+An additional style parameter is also honored:
+
+\startbuffer
+\definetweakedfont[MyLargerFontA][scale=2000,style=bold]
+test {\MyLargerFontA test} test
\stopbuffer
\typebuffer
-gives:
+This gives:
\getbuffer
-You can actually use negative values, as is demonstrated in the following
+Just for the record: the Latin Modern fonts, when set up to use design sizes, will
+still use the specific size related files.
+
+\stopsection
+
+\startsection[title={Hackery}]
+
+You can actually use negative scale values, as is demonstrated in the following
code:
\startbuffer
@@ -131,45 +403,8 @@ gives:
\getbuffer
\stoplinecorrection
-Because loading and switching fonts in \CONTEXT\ is rather efficient, the gain in
-performance is less than you expect. After all, not all time is spent on fonts. Of
-course for huge \CJK\ fonts it does make a difference. But, when we do a massive switch
-to a different body font, we can save a little more. Think of definitions like:
-
-\starttyping
-\definescaledfontbody[BigBodyFont] [1.200]
-\definescaledfontbody[VeryBigBodyFont] [1.440]
-\definescaledfont [MyLargerFont] [xscale=1.200,yscale=2.000]
-\stoptyping
-
-And then:
-
-\starttyping
-\setuphead[title][style=\MyLargerFont\bf]
-\stoptyping
-
-The savings in runtime can be quite noticeable now, for instance this:
-
-\starttyping
-\dorecurse {100} {
- \starttitle[title={Test #1]
- \samplefile{ward}\par
- \start \bf
- \samplefile{ward}\par
- \stop
- \start \BigBodyFont \bf
- \samplefile{ward}\par
- \stop
- \stoptitle
-}
-\stoptyping
-
-Speeds up a bit for Pagella and even more when we use Cambria. Keep in mind that
-that a body font switch also involves setting up some math. Anyway, as a proof of
-concept it worked out well.
-
-Glyphs can have offsets and these are used for implementing \OPENTYPE\ features. However,
-they are also available at the \TEX\ end. Take this
+Glyphs can have offsets and these are used for implementing \OPENTYPE\ features.
+However, they are also available at the \TEX\ end. Take this
\startbuffer
\ruledhbox{
@@ -225,57 +460,136 @@ Both these lines produce the same integer:
\getbuffer
\stoplines
-When there is a fraction, the value is multiplied by 1000.
-
-So how should this be further integrated? If we drop design sizes at the file
-definition level the whole font mechanism could be simplified a lot, but we cannot
-do that. Another approach is to let users use the previously mentioned more low
-level commands. A but of help can be provided with a command like
-
-\starttyping
-\enableautoglyphscaling
-\stoptyping
-
-which pays of when it is issues before \type {\starttext} and before a body fonts
-gets defined because it does some overloading of defining commands. At the brink
-of 2021 I'm not sure yet what is best. One reason is that a compatibility layer
-is not really compatible because glyph scaling gives slightly different scaled in
-practice (which relates to some old time accuracy hackery). This sounds worse
-that it is because in practice scaling is done for sections heads and so, which
-are less present and don't interfere with the running text.
-
-Let me stress once more: if you need this kind of scaling it pays off. If you
-load multiple instances of large (e.g.\ \CJK) fonts, it makes sense too. But, for
-instance on a document like the \LUAMETATEX\ manual it only saves 2 instances on
-158, and those are the few bold fonts used for titling.
-
-That said, here is another example:
+You can do strange things with these primitives but keep in mind that you can
+also waste the defaults.
-\startbuffer
+\startbuffer[definition]
\def\UnKernedTeX
{T%
{\glyph xoffset -.2ex yoffset -.4ex `E}%
{\glyph xoffset -.4ex options "60 `X}}
+\stopbuffer
+\startbuffer[example]
We use \UnKernedTeX\ and {\bf \UnKernedTeX} and {\bs \UnKernedTeX}:
the slanted version could use some more left shifting of the E.
\stopbuffer
-\typebuffer
+\typebuffer[definition,example]
This gives is the \TEX\ logos (but of course we normally use the real ones
instead).
-\getbuffer
+\startnarrower
+ \darkred \getbuffer[definition,example]
+\stopnarrower
+
+Because offsets are (also) used for handling font features like mark and cursive
+placement as well as special inter|-|character positioning, the above is
+suboptimal. Here is a better alternative:
+
+\startbuffer[definition]
+\def\UnKernedTeX
+ {T\glyph left .2ex raise -.4ex `E\glyph left .4ex `X\relax}
+\stopbuffer
+
+\typebuffer[definition]
+
+The result is the same:
+
+\startnarrower
+ \darkgreen \getbuffer[definition,example]
+\stopnarrower
+
+But anyway: don't over|-|do it. We could deal with such cases for decades without
+these fancy new features. The next example show margins in action:
+
+\startlinecorrection
+\bTABLE[align=middle,width=.33\textwidth]
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise -3pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf \eTD
+ \bTD \tttf raise 3pt \eTD
+ \bTD \tttf raise -3pt \eTD
+ \eTR
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right 2pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf left 3pt \eTD
+ \bTD \tttf right 2pt\eTD
+ \bTD \tttf left 3pt right 2pt\eTD
+ \eTR
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right -2pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt right -2pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf left -3pt \eTD
+ \bTD \tttf right -2pt \eTD
+ \bTD \tttf left -3pt right -2pt \eTD
+ \eTR
+\eTABLE
+\stoplinecorrection
+
+Here is another way of looking at it:
+
+\startbuffer
+\glyphscale 4000
+\vl\glyph `M\vl\quad
+\vl\glyph raise .2em `M\vl\quad
+\vl\glyph left .3em `M\vl\quad
+\vl\glyph right .2em`M\vl\quad
+\vl\glyph left -.2em right -.2em`M\vl\quad
+\vl\glyph raise -.2em right .4em`M\vl
+\stopbuffer
+
+\typebuffer
+
+The raise as well as left and right margins are taken into account when calculating the
+dimensions of a glyph.
+
+{\getbuffer}
+
+
+\stopsection
+
+\startsection[title={Implementation}]
+
+Discussing the implementation in the engine makes no sense here, also because
+details might change. However, it is good to know that quite some properties
+travel with the glyph nodes, for instance the scales and offsets. The dimensions
+(width, height and depth) are not stored in the glyph node but calculated from
+the font, scales and optionally the offsets and expansion factor. One problem is
+that the more clever (and nice) solutions we cook up, the more it might impact
+performance. So, I will delay some experiments till I have a more powerful
+machine.
+
+One reason for {\em not} storing the dimensions in a glyph node is that we often
+copy those nodes or change character fields in the font handler and we definitely
+don't want the wrong dimensions there. At that moment, offsets and margin fields
+don't reflect features yet, so copying them is no big deal. However, dimensions
+are rather character bound so every time a character is set, we also would have
+to set the dimensions. Even worse, when we can set them, the question arises if
+they actually were already set explicitly. So, this is a can of worms we're not
+going to open: the basic width, height and depth of the glyph as specified in the
+font is used and combines with actual dimensions (likely already scaled according
+the glyph scales) in offset and margin fields.
+
+Now, I have to admit that especially playing with using margins to glyphs instead
+of font kerns is more of an experiment to see what the consequences are than a
+necessity, but what would be the joy of \TEX\ without such experiments. And as
+usual, in \CONTEXT\ these will become options in the font handler that one can
+either or not enable.
-After doing this with text, I wondered if we can avoid multiple sizes of an
-otherwise same math font. Currently text, script and script script styles all use
-the same font, but scaled. And, indeed, experiments show that this can be done,
-although the math renderer had to be adapted to it. So, for now it's an
-experiment. Users have to check if things are okay. Also, we have slightly
-different rounding than with normal scaling. Of course the big advantage is that
-we have less instances (math can add up more than text as every size has in fact
-three instances).
+\stopsection
\stopchapter
@@ -294,7 +608,7 @@ three instances).
\starttext
\startbuffer
-\definescaledfont[bfe][xscale=2000,yscale=6000,style=bf]
+\definetweakedfont[bfe][xscale=2000,yscale=6000,style=bf]
\setuphead[chapter][style=\bfe]
@@ -332,3 +646,8 @@ three instances).
% anything) on YT. Both examples of where (imo extensive) practicing real
% instruments can bring you with todays diverse equipment. These are interesting
% times (it's now last days of 2020).
+%
+% The initial \definescaledfont was replaced by \definetweakedfont in the first
+% week of Januari 2021, when I watched the joyful covers of Peter Gabriels
+% "Steam" by Yoyoka which shows that the future belongs to the real young kids
+% (so much explosive creativity!) and not to the old folks.
diff --git a/doc/context/sources/general/manuals/followingup/followingup-style.tex b/doc/context/sources/general/manuals/followingup/followingup-style.tex
index 68b52043c..51519f137 100644
--- a/doc/context/sources/general/manuals/followingup/followingup-style.tex
+++ b/doc/context/sources/general/manuals/followingup/followingup-style.tex
@@ -3,6 +3,8 @@
\startenvironment followingup-style
+\enableexperiments[fonts.compact] % needed for font chapter
+
\usemodule[abbreviations-smallcaps]
\logo [LUAMETATEX] {LuaMeta\TeXsuffix}
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex.tex b/doc/context/sources/general/manuals/luametatex/luametatex.tex
index 588cc8952..1327ea3a1 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex.tex
@@ -79,7 +79,7 @@
% 290 pages, 9.5 sec, 149M lua, 35M tex, 30 instances
\enableexperiments[fonts.compact]
-\enabledirectives[fonts.injections.method=advance]
+% \enabledirectives[fonts.injections.method=advance] % tricky ... not all xoffsets are advance robust
\pushoverloadmode \unprotect
% test code
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index ea233b8d2..d06fbe463 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2021.01.08 11:44}
+\newcontextversion{2021.01.11 16:28}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index ea64e263e..c36274955 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.01.08 11:44}
+\edef\contextversion{2021.01.11 16:28}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii
index d2a51a8ab..d4b39ad3b 100644
--- a/tex/context/base/mkii/mult-cs.mkii
+++ b/tex/context/base/mkii/mult-cs.mkii
@@ -1131,6 +1131,7 @@
\setinterfaceconstant{reference}{odkaz}
\setinterfaceconstant{referencemethod}{referencemethod}
\setinterfaceconstant{referenceprefix}{referenceprefix}
+\setinterfaceconstant{referencetext}{referencetext}
\setinterfaceconstant{referencing}{odkazujici}
\setinterfaceconstant{region}{region}
\setinterfaceconstant{regionin}{oblastuvnitr}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index da0388cf0..49c850c9b 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.01.08 11:44}
+\newcontextversion{2021.01.11 16:28}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 23eabed71..93744dfda 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.01.08 11:44}
+\edef\contextversion{2021.01.11 16:28}
%D Kind of special:
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 74deffd1f..d55bfa411 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 27cd2367e..78ade839c 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 376101d29..31dbd327a 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.01.08 11:44}
+\newcontextversion{2021.01.11 16:28}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 10674b4ee..751712225 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.01.08 11:44}
+\immutable\edef\contextversion{2021.01.11 16:28}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index 57ac9e294..9747ba82d 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -627,7 +627,7 @@ local hlist_out, vlist_out do
for current, id, subtype in nextnode, current do
if id == glyph_code then
local char, font = isglyph(current)
- local x_offset, y_offset = getoffsets(current) -- todo: also get scales here
+ local x_offset, y_offset, left, right, raise = getoffsets(current)
if x_offset ~= 0 or y_offset ~= 0 then
if pos_r == righttoleft_code then
pos_h = ref_h - (cur_h + x_offset)
@@ -637,8 +637,10 @@ local hlist_out, vlist_out do
pos_v = ref_v - (cur_v - y_offset)
-- synced
end
+ pos_v = pos_v + raise
+ pos_h = pos_h - left
local wd = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r)
- cur_h = cur_h + wd
+ cur_h = cur_h + wd - right
elseif id == glue_code then
local gluewidth = effectiveglue(current,this_box)
if gluewidth ~= 0 then
@@ -834,8 +836,8 @@ local hlist_out, vlist_out do
if total > 0 then
local xoffset, yoffset, left, right = getoffsets(current) -- top bottom
if left ~= 0 then
- pos_v = pos_v + left
- total = total - left
+ pos_v = pos_v + left
+ total = total - left
end
if right ~= 0 then
depth = depth - right
@@ -995,8 +997,7 @@ local hlist_out, vlist_out do
local total = height + depth
if getid(leader) == rule_code then
depth = 0 -- hm
--- forgotten ... needs testing
-total = glueheight
+ total = glueheight -- forgotten ... needs testing
if total > 0 then
if width == running then
width = boxwidth
diff --git a/tex/context/base/mkxl/font-col.lmt b/tex/context/base/mkxl/font-col.lmt
index 200551099..21c731946 100644
--- a/tex/context/base/mkxl/font-col.lmt
+++ b/tex/context/base/mkxl/font-col.lmt
@@ -33,6 +33,8 @@ local trace_collecting = false trackers.register("fonts.collecting", function
local report_fonts = logs.reporter("fonts","collections")
+local texconditionals = tex.conditionals
+
local enableaction = nodes.tasks.enableaction
local disableaction = nodes.tasks.disableaction
@@ -236,7 +238,7 @@ function collections.clonevector(name)
if factor then
vector.factor = factor
end
-if tex.conditionals["c_font_compact"] then
+if texconditionals["c_font_compact"] then
if rscale then
vector.rscale = rscale
end
@@ -342,7 +344,7 @@ function collections.prepare(name) -- we can do this in lua now .. todo
local f = d[i]
local name = f.font
local scale = f.rscale or 1
-if tex.conditionals["c_font_compact"] then
+if texconditionals["c_font_compact"] then
scale = 1
end
if fontpatternhassize(name) then
diff --git a/tex/context/base/mkxl/font-ctx.lmt b/tex/context/base/mkxl/font-ctx.lmt
index 3dbf7bbbd..b307f8f5d 100644
--- a/tex/context/base/mkxl/font-ctx.lmt
+++ b/tex/context/base/mkxl/font-ctx.lmt
@@ -1095,13 +1095,14 @@ local specifiers = { }
do -- else too many locals
- local starttiming = statistics.starttiming
- local stoptiming = statistics.stoptiming
+ local starttiming = statistics.starttiming
+ local stoptiming = statistics.stoptiming
- local setmacro = tokens.setters.macro
- local ctxcatcodes = tex.ctxcatcodes
+ local setmacro = tokens.setters.macro
+ local ctxcatcodes = tex.ctxcatcodes
+ local texconditionals = tex.conditionals
- local reported = setmetatableindex(function(t,k)
+ local reported = setmetatableindex(function(t,k)
local v = setmetatableindex(function(t,k)
t[k] = true
return false
@@ -1226,6 +1227,9 @@ do -- else too many locals
name = o_name
sub = o_sub
end
+if texconditionals["c_font_compact"] then
+ size = 655360
+end
-- so far
-- some settings can have been overloaded
if lookup and lookup ~= "" then
diff --git a/tex/context/base/mkxl/font-glf.mklx b/tex/context/base/mkxl/font-glf.mklx
index 023c632dc..2c23f226e 100644
--- a/tex/context/base/mkxl/font-glf.mklx
+++ b/tex/context/base/mkxl/font-glf.mklx
@@ -25,8 +25,8 @@
% we can optimize for zero and 1000 .. maybe also options?
\overloaded\frozen\protected\edefcsname\currenttweakedfont\endcsname
{\begincsname\tweakedfontparameter\c!style\endcsname
- \glyphxscale \numexpr\glyphxscale *\numericscale\tweakedfontparameter\c!xscale /\plusthousand\relax
- \glyphyscale \numexpr\glyphyscale *\numericscale\tweakedfontparameter\c!yscale /\plusthousand\relax
+ \glyphxscale \numexpr\numericscale\tweakedfontparameter\c!xscale*\glyphxscale/\plusthousand\relax
+ \glyphyscale \numexpr\numericscale\tweakedfontparameter\c!yscale*\glyphyscale/\plusthousand\relax
\glyphxoffset\dimexpr\glyphxoffset+\tweakedfontparameter\c!xoffset\relax
\glyphyoffset\dimexpr\glyphyoffset+\tweakedfontparameter\c!yoffset\relax}%
\to \everydefinetweakedfont
diff --git a/tex/context/base/mkxl/font-imp-math.lmt b/tex/context/base/mkxl/font-imp-math.lmt
index 47fcf344c..079c867e2 100644
--- a/tex/context/base/mkxl/font-imp-math.lmt
+++ b/tex/context/base/mkxl/font-imp-math.lmt
@@ -14,6 +14,8 @@ local registerotffeature = fonts.handlers.otf.features.register
local setmetatableindex = table.setmetatableindex
+local texconditionals = tex.conditionals
+
-- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0
local splitter = lpeg.splitat(",",tonumber)
@@ -69,7 +71,7 @@ registerotffeature {
-- A quick and dirty and low level implementation but okay for testing:
local function manipulate(tfmdata,key,value)
- if tex.conditionals["c_font_compact"] then
+ if texconditionals["c_font_compact"] then
local rawdata = tfmdata.shared.rawdata
local rawresources = rawdata and rawdata.resources
local rawfeatures = rawresources and rawresources.features
@@ -110,7 +112,7 @@ local function manipulate(tfmdata,key,value)
end
local function initialize(tfmdata,key,value)
- if tex.conditionals["c_font_compact"] then
+ if texconditionals["c_font_compact"] then
local rawdata = tfmdata.shared.rawdata
local rawresources = rawdata and rawdata.resources
local mathconstants = rawresources.mathconstants
diff --git a/tex/context/base/mkxl/font-ini.mklx b/tex/context/base/mkxl/font-ini.mklx
index 764fbfdab..0a158e69d 100644
--- a/tex/context/base/mkxl/font-ini.mklx
+++ b/tex/context/base/mkxl/font-ini.mklx
@@ -884,9 +884,8 @@
\fi
\c_font_future_glyph_scale\numexpr\plushundred*\d_font_scaled_font_size/\maxcard\relax
\glyphscale\numexpr\plushundred*\d_font_scaled_font_size/\maxcard\relax % needed ? for math i guess
-% \glyphscale\plusthousand
- \d_font_scaled_font_size\d_font_scaled_default
- \d_font_scaled_text_face\d_font_scaled_default
+ % \d_font_scaled_font_size\d_font_scaled_default
+ % \d_font_scaled_text_face\d_font_scaled_default
%
\edef\somefontspec{at \number\d_font_scaled_font_size sp}%
% this has to happen at the tex end ...
@@ -898,23 +897,6 @@
\font_helpers_update_font_class_parameters
% ... till here
%\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}%
-% \clf_definefont_two
-% \ifempty\fontclass\s!false\else\s!true\fi
-% {#csname}%
-% {\somefontfile}%
-% \d_font_scaled_font_size
-% \c_font_feature_inheritance_mode
-% {\m_font_class_features}%
-% {\m_font_features}%
-% {\m_font_class_fallbacks}%
-% {\m_font_fallbacks}%
-% \fontface
-% \d_font_scaled_text_face
-% {\m_font_class_goodies}%
-% {\m_font_goodies}%
-% {\m_font_class_designsize}%
-% {\m_font_designsize}%
-% \scaledfontmode
\clf_definefont_two
\ifempty\fontclass\s!false\else\s!true\fi
{#csname}%
@@ -926,7 +908,7 @@
\m_font_class_fallbacks
\m_font_fallbacks
\fontface
- \d_font_scaled_text_face
+ \d_font_scaled_default
\m_font_class_goodies
\m_font_goodies
\m_font_class_designsize
@@ -943,7 +925,7 @@
%
\glyphscale
\ifnum\c_font_scaled_font_mode_saved>\plusfour
- \numexpr\plusthousand*\dimexpr\d_font_scaled_font_size\relax/\c_font_scaled_points\relax
+ \numexpr\plusthousand*\dimexpr\d_font_scaled_default\relax/\c_font_scaled_points\relax
\else
\c_font_future_glyph_scale
\fi
diff --git a/tex/context/base/mkxl/font-otj.lmt b/tex/context/base/mkxl/font-otj.lmt
index 15a78d122..e9e9d524e 100644
--- a/tex/context/base/mkxl/font-otj.lmt
+++ b/tex/context/base/mkxl/font-otj.lmt
@@ -25,11 +25,13 @@ if not modules then modules = { } end modules ['font-otj'] = {
-- An alternative is to have a list per base of all marks and then do a run over the node
-- list that resolves the accumulated l/r/x/y and then do an inject pass.
--- if needed we can flag a kern node as immutable
-
-- The thing with these positioning options is that it is not clear what Uniscribe does with
-- the 2rl flag and we keep oscillating a between experiments.
+-- Beware: combining advance with cursive and marks can be a problem because marks have no
+-- dimensions .. maybe we need a special field for that ... the advance also sets the apply
+-- x offset flag!
+
if not nodes.properties then return end
local next, rawget, tonumber = next, rawget, tonumber
@@ -80,19 +82,26 @@ local nodepool = nuts.pool
local tonode = nuts.tonode
local tonut = nuts.tonut
-local setfield = nuts.setfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
local getfont = nuts.getfont
local getchar = nuts.getchar
+local setchar = nuts.setchar
+----- getxoffset = nuts.getxoffset
+----- getyoffset = nuts.getyoffset
local getoffsets = nuts.getoffsets
local getxscale = nuts.getxscale
local getyscale = nuts.getyscale
+local getxyscales = nuts.getxyscales
+local xscaled = nuts.xscaled
+local yscaled = nuts.yscaled
local getboth = nuts.getboth
local getdisc = nuts.getdisc
local setdisc = nuts.setdisc
local setoffsets = nuts.setoffsets
+local addxoffset = nuts.addxoffset
+local addyoffset = nuts.addyoffset
local ischar = nuts.ischar
local isnextchar = nuts.isnextchar
local getkern = nuts.getkern
@@ -100,7 +109,8 @@ local setkern = nuts.setkern
local setlink = nuts.setlink
local setwidth = nuts.setwidth
local getwidth = nuts.getwidth
-local setadvance = nuts.setadvance
+local addxymargins = nuts.addxymargins -- we delegate scaling
+local copynode = nuts.copy
local nextchar = nuts.traversers.char
local nextglue = nuts.traversers.glue
@@ -113,8 +123,9 @@ local properties = nodes.properties.data
local fontkern = nuts.pool and nuts.pool.fontkern
local italickern = nuts.pool and nuts.pool.italickern
-local useitalickerns = false -- context only
+local useitalickerns = false
local useadvance = false
+local usezwjkerns = true -- when useadvance
directives.register("fonts.injections.useitalics", function(v)
if v then
@@ -618,21 +629,206 @@ end
-- D-post +D-post
-- +D-replace +D-replace
-local function inject_kerns_only(head,where)
+-- Beware! pre/post/replace can have non glyphs too
+
+-- local function inject_kerns_only(head,where)
+-- if trace_injections then
+-- trace(head,"kerns")
+-- end
+-- local current = head
+-- local prev -- = nil
+-- local prevdisc -- = nil
+-- local pre -- = nil -- saves a lookup
+-- local post -- = nil -- saves a lookup
+-- local replace -- = nil -- saves a lookup
+-- local pretail -- = nil -- saves a lookup
+-- local posttail -- = nil -- saves a lookup
+-- local replacetail -- = nil -- saves a lookup
+-- while current do
+-- local next, char, id = isnextchar(current)
+-- if char then
+-- local p = rawget(properties,current)
+-- if p then
+-- local i = p.injections
+-- if i then
+-- -- left|glyph|right
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- if useadvance then
+-- addmargins(current,-leftkern)
+-- elseif prev and getid(prev) == glue_code then
+-- if useitalickerns then
+-- head = insert_node_before(head,current,italickern(leftkern))
+-- else
+-- setwidth(prev, getwidth(prev) + leftkern)
+-- end
+-- else
+-- head = insert_node_before(head,current,fontkern(leftkern))
+-- end
+-- end
+-- end
+-- if prevdisc then
+-- local done = false
+-- if post then
+-- local i = p.postinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- if useadvance then
+-- addmargins(posttail,false,-leftkern)
+-- else
+-- setlink(posttail,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- if replace then
+-- local i = p.replaceinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- if useadvance then
+-- addmargins(replacetail,false,-leftkern)
+-- else
+-- setlink(replacetail,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- else
+-- local i = p.emptyinjections
+-- if i then
+-- -- glyph|disc|glyph (special case)
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- -- if useadvance then
+-- -- add zwj with offset
+-- -- else
+-- replace = fontkern(leftkern)
+-- done = true
+-- -- end
+-- end
+-- end
+-- end
+-- if done then
+-- setdisc(prevdisc,pre,post,replace)
+-- end
+-- end
+-- end
+-- prevdisc = nil
+-- -- prevglyph = current
+-- elseif char == false then
+-- -- other font
+-- prevdisc = nil
+-- -- prevglyph = current
+-- elseif id == disc_code then
+-- pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+-- local done = false
+-- if pre then
+-- -- left|pre glyphs|right
+-- for n in nextchar, pre do
+-- local p = rawget(properties,n)
+-- if p then
+-- local i = p.injections or p.preinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(n,leftkern)
+-- if useadvance then
+-- addmargins(n,-leftkern)
+-- else
+-- pre = insert_node_before(pre,n,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if post then
+-- -- left|post glyphs|right
+-- for n in nextchar, post do
+-- local p = rawget(properties,n)
+-- if p then
+-- local i = p.injections or p.postinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(n,leftkern)
+-- if useadvance then
+-- addmargins(n,-leftkern)
+-- else
+-- post = insert_node_before(post,n,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if replace then
+-- -- left|replace glyphs|right
+-- for n in nextchar, replace do
+-- local p = rawget(properties,n)
+-- if p then
+-- local i = p.injections or p.replaceinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(n,leftkern)
+-- if useadvance then
+-- addmargins(n,-leftkern)
+-- else
+-- replace = insert_node_before(replace,n,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if done then
+-- setdisc(current,pre,post,replace)
+-- end
+-- -- prevglyph = nil
+-- prevdisc = current
+-- else
+-- -- prevglyph = nil
+-- prevdisc = nil
+-- end
+-- prev = current
+-- current = next
+-- end
+-- --
+-- if keepregisteredcounts then
+-- keepregisteredcounts = false
+-- else
+-- nofregisteredkerns = 0
+-- end
+-- if trace_injections then
+-- show_result(head)
+-- end
+-- return head
+-- end
+
+local function inject_kerns_only_kerns(head,where)
if trace_injections then
trace(head,"kerns")
end
- local current = head
- local prev = nil
- local next = nil
- local prevdisc = nil
--- local prevglyph = nil
- local pre = nil -- saves a lookup
- local post = nil -- saves a lookup
- local replace = nil -- saves a lookup
- local pretail = nil -- saves a lookup
- local posttail = nil -- saves a lookup
- local replacetail = nil -- saves a lookup
+ local current = head
+ local prev -- = nil
+ local prevdisc -- = nil
+ local pre -- = nil -- saves a lookup
+ local post -- = nil -- saves a lookup
+ local replace -- = nil -- saves a lookup
+ local pretail -- = nil -- saves a lookup
+ local posttail -- = nil -- saves a lookup
+ local replacetail -- = nil -- saves a lookup
while current do
local next, char, id = isnextchar(current)
if char then
@@ -643,19 +839,15 @@ local function inject_kerns_only(head,where)
-- left|glyph|right
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if useadvance then
- setadvance(current,leftkern,0)
- else
- leftkern = leftkern * getxscale(current)
- if prev and getid(prev) == glue_code then
- if useitalickerns then
- head = insert_node_before(head,current,italickern(leftkern))
- else
- setwidth(prev, getwidth(prev) + leftkern)
- end
+ leftkern = xscaled(current,leftkern)
+ if prev and getid(prev) == glue_code then
+ if useitalickerns then
+ head = insert_node_before(head,current,italickern(leftkern))
else
- head = insert_node_before(head,current,fontkern(leftkern))
+ setwidth(prev,getwidth(prev) + leftkern)
end
+ else
+ head = insert_node_before(head,current,fontkern(leftkern))
end
end
end
@@ -666,13 +858,8 @@ local function inject_kerns_only(head,where)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if useadvance then
- setadvance(posttail,0,leftkern)
- else
- leftkern = leftkern * getxscale(current)
- setlink(posttail,fontkern(leftkern))
- done = true
- end
+ setlink(posttail,fontkern(xscaled(current,leftkern)))
+ done = true
end
end
end
@@ -681,13 +868,8 @@ local function inject_kerns_only(head,where)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if useadvance then
- setadvance(replacetail,0,leftkern)
- else
- leftkern = leftkern * getxscale(current)
- setlink(replacetail,fontkern(leftkern))
- done = true
- end
+ setlink(replacetail,fontkern(xscaled(current,leftkern)))
+ done = true
end
end
else
@@ -696,13 +878,8 @@ local function inject_kerns_only(head,where)
-- glyph|disc|glyph (special case)
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- -- if useadvance then
- -- add zwj with offset
- -- else
- leftkern = leftkern * getxscale(current)
- replace = fontkern(leftkern)
- done = true
- -- end
+ replace = fontkern(xscaled(current,leftkern))
+ done = true
end
end
end
@@ -712,11 +889,11 @@ local function inject_kerns_only(head,where)
end
end
prevdisc = nil
- -- prevglyph = current
+ -- prevglyph = current
elseif char == false then
-- other font
prevdisc = nil
- -- prevglyph = current
+ -- prevglyph = current
elseif id == disc_code then
pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
local done = false
@@ -729,13 +906,8 @@ local function inject_kerns_only(head,where)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if useadvance then
- setadvance(n,leftkern,0)
- else
- leftkern = leftkern * getxscale(n)
- pre = insert_node_before(pre,n,fontkern(leftkern))
- done = true
- end
+ pre = insert_node_before(pre,n,fontkern(xscaled(n,leftkern)))
+ done = true
end
end
end
@@ -750,13 +922,8 @@ local function inject_kerns_only(head,where)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if useadvance then
- setadvance(n,leftkern,0)
- else
- leftkern = leftkern * getxscale(n)
- post = insert_node_before(post,n,fontkern(leftkern))
- done = true
- end
+ post = insert_node_before(post,n,fontkern(xscaled(n,leftkern)))
+ done = true
end
end
end
@@ -771,13 +938,8 @@ local function inject_kerns_only(head,where)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- if useadvance then
- setadvance(n,leftkern,0)
- else
- leftkern = leftkern * getxscale(n)
- replace = insert_node_before(replace,n,fontkern(leftkern))
- done = true
- end
+ replace = insert_node_before(replace,n,fontkern(xscaled(n,leftkern)))
+ done = true
end
end
end
@@ -786,10 +948,10 @@ local function inject_kerns_only(head,where)
if done then
setdisc(current,pre,post,replace)
end
- -- prevglyph = nil
+ -- prevglyph = nil
prevdisc = current
else
- -- prevglyph = nil
+ -- prevglyph = nil
prevdisc = nil
end
prev = current
@@ -807,7 +969,450 @@ local function inject_kerns_only(head,where)
return head
end
-local function inject_positions_only(head,where)
+local function inject_kerns_only_margins(head,where)
+ if trace_injections then
+ trace(head,"kerns")
+ end
+ local current = head
+ local prevdisc -- = nil
+ local pre -- = nil -- saves a lookup
+ local post -- = nil -- saves a lookup
+ local replace -- = nil -- saves a lookup
+ local pretail -- = nil -- saves a lookup
+ local posttail -- = nil -- saves a lookup
+ local replacetail -- = nil -- saves a lookup
+ while current do
+ local next, char, id = isnextchar(current)
+ if char then
+ local p = rawget(properties,current)
+ if p then
+ if prevdisc then
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(posttail,false,-leftkern)
+ end
+ end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(replacetail,false,-leftkern)
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ if usezwjkerns then
+ replace = copynode(current)
+ setchar(replace,0x200D) -- zwj
+ addxymargins(replace,-leftkern)
+ else
+ replace = fontkern(xscaled(current,leftkern))
+ end
+ setdisc(prevdisc,pre,post,replace) -- setreplace
+ end
+ end
+ end
+ end
+ -- moved down so we can copy zwj
+ local i = p.injections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(current,-leftkern)
+ end
+ end
+ end
+ prevdisc = nil
+ elseif char == false then
+ prevdisc = nil
+ elseif id == disc_code then
+ pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+ if pre then
+ for n in nextchar, pre do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.preinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(n,-leftkern)
+ end
+ end
+ end
+ end
+ end
+ if post then
+ for n in nextchar, post do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(n,-leftkern)
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ for n in nextchar, replace do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(n,-leftkern)
+ end
+ end
+ end
+ end
+ end
+ prevdisc = current
+ else
+ prevdisc = nil
+ end
+ current = next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts = false
+ else
+ nofregisteredkerns = 0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+
+-- local function inject_positions_only(head,where)
+-- if trace_injections then
+-- trace(head,"positions")
+-- end
+-- local current = head
+-- local prev = nil
+-- local next = nil
+-- local prevdisc = nil
+-- local prevglyph = nil
+-- local pre = nil -- saves a lookup
+-- local post = nil -- saves a lookup
+-- local replace = nil -- saves a lookup
+-- local pretail = nil -- saves a lookup
+-- local posttail = nil -- saves a lookup
+-- local replacetail = nil -- saves a lookup
+-- while current do
+-- local next, char, id = isnextchar(current)
+-- if char then
+-- local p = rawget(properties,current)
+-- if p then
+-- local i = p.injections
+-- if i then
+-- -- left|glyph|right
+-- local yoffset = i.yoffset
+-- if yoffset and yoffset ~= 0 then
+-- -- use raise when advance
+-- addyoffset(current,yscaled(current,yoffset))
+-- end
+-- local leftkern = i.leftkern or 0
+-- local rightkern = i.rightkern or 0
+-- if leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- end
+-- if rightkern ~= 0 then
+-- rightkern = xscaled(current,rightkern)
+-- end
+-- if useadvance then
+-- if leftkern ~= 0 or rightkern ~= 0 then
+-- addmargins(current,-leftkern,-rightkern)
+-- end
+-- else
+-- if leftkern ~= 0 then
+-- if leftkern == -rightkern then
+-- addxoffset(current,leftkern)
+-- rightkern = 0
+-- elseif prev and getid(prev) == glue_code then
+-- if useitalickerns then
+-- head = insert_node_before(head,current,italickern(leftkern))
+-- else
+-- setwidth(prev,getwidth(prev)+leftkern)
+-- end
+-- else
+-- head = insert_node_before(head,current,fontkern(leftkern))
+-- end
+-- end
+-- if rightkern ~= 0 then
+-- if next and getid(next) == glue_code then
+-- if useitalickerns then
+-- insert_node_after(head,current,italickern(rightkern))
+-- else
+-- setwidth(next, getwidth(next)+rightkern)
+-- end
+-- else
+-- insert_node_after(head,current,fontkern(rightkern))
+-- end
+-- end
+-- end
+-- else
+-- local i = p.emptyinjections
+-- if i then
+-- -- glyph|disc|glyph (special case)
+-- local rightkern = i.rightkern
+-- if rightkern and rightkern ~= 0 then
+-- if next and getid(next) == disc_code then
+-- if replace then
+-- -- error, we expect an empty one
+-- else
+-- rightkern = xscaled(current,rightkern)
+-- replace = fontkern(rightkern) -- maybe also leftkern
+-- done = true --KE
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if prevdisc then
+-- local done = false
+-- if post then
+-- local i = p.postinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- if useadvance then
+-- addmargins(posttail,-leftkern)
+-- else
+-- setlink(posttail,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- if replace then
+-- local i = p.replaceinjections
+-- if i then
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- leftkern = xscaled(current,leftkern)
+-- if useadvance then
+-- addmargins(replacetail,-leftkern)
+-- else
+-- setlink(replacetail,fontkern(leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- else
+-- local i = p.emptyinjections
+-- if i then
+-- -- new .. okay?
+-- local leftkern = i.leftkern
+-- if leftkern and leftkern ~= 0 then
+-- replace = fontkern(xscaled(current,leftkern))
+-- done = true
+-- end
+-- end
+-- end
+-- if done then
+-- setdisc(prevdisc,pre,post,replace)
+-- end
+-- end
+-- end
+-- prevdisc = nil
+-- prevglyph = current
+-- elseif char == false then
+-- prevdisc = nil
+-- prevglyph = current
+-- elseif id == disc_code then
+-- pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+-- local done = false
+-- if pre then
+-- -- left|pre glyphs|right
+-- for n in nextchar, pre do
+-- local p = rawget(properties,n)
+-- if p then
+-- local i = p.injections or p.preinjections
+-- if i then
+-- local yoffset = i.yoffset
+-- local leftkern = i.leftkern or 0
+-- local rightkern = i.rightkern or 0
+-- if yoffset and yoffset ~= 0 then
+-- -- use raise when advance
+-- addyoffset(n,yscaled(n,yoffset))
+-- end
+-- if leftkern ~= 0 then
+-- leftkern = xscaled(n,leftkern)
+-- end
+-- if rightkern ~= 0 then
+-- rightkern = xscaled(n,rightkern)
+-- end
+-- if useadvance then
+-- if leftkern ~= 0 or rightkern ~= 0 then
+-- addmargins(pre,-leftkern,-rightkern)
+-- end
+-- else
+-- if leftkern ~= 0 then
+-- pre = insert_node_before(pre,n,fontkern(leftkern))
+-- done = true
+-- end
+-- if rightkern ~= 0 then
+-- insert_node_after(pre,n,fontkern(rightkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if post then
+-- -- left|post glyphs|right
+-- for n in nextchar, post do
+-- local p = rawget(properties,n)
+-- if p then
+-- local i = p.injections or p.postinjections
+-- if i then
+-- local yoffset = i.yoffset
+-- local leftkern = i.leftkern or 0
+-- local rightkern = i.rightkern or 0
+-- if yoffset and yoffset ~= 0 then
+-- -- use raise when advance
+-- addyoffset(n,yscaled(n,yoffset))
+-- end
+-- if leftkern ~= 0 then
+-- leftkern = xscaled(n,leftkern)
+-- end
+-- if rightkern ~= 0 then
+-- rightkern = xscaled(n,rightkern)
+-- end
+-- if useadvance then
+-- if leftkern ~= 0 or rightkern ~= 0 then
+-- addmargins(post,-leftkern,-rightkern)
+-- end
+-- else
+-- if leftkern ~= 0 then
+-- post = insert_node_before(post,n,fontkern(leftkern))
+-- done = true
+-- end
+-- if rightkern ~= 0 then
+-- insert_node_after(post,n,fontkern(rightkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if replace then
+-- -- left|replace glyphs|right
+-- for n in nextchar, replace do
+-- local p = rawget(properties,n)
+-- if p then
+-- local i = p.injections or p.replaceinjections
+-- if i then
+-- local yoffset = i.yoffset
+-- local leftkern = i.leftkern or 0
+-- local rightkern = i.rightkern or 0
+-- if yoffset and yoffset ~= 0 then
+-- -- use raise when advance
+-- addyoffset(n,yscaled(n,yoffset))
+-- end
+-- if leftkern ~= 0 then
+-- leftkern = xscaled(n,leftkern)
+-- end
+-- if rightkern ~= 0 then
+-- rightkern = xscaled(n,rightkern)
+-- end
+-- if useadvance then
+-- if leftkern ~= 0 or rightkern ~= 0 then
+-- addmargins(replace,-leftkern,-rightkern)
+-- end
+-- else
+-- if leftkern ~= 0 then
+-- replace = insert_node_before(replace,n,fontkern(leftkern))
+-- done = true
+-- end
+-- if rightkern ~= 0 then
+-- insert_node_after(replace,n,fontkern(rightkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if prevglyph then
+-- if pre then
+-- local p = rawget(properties,prevglyph)
+-- if p then
+-- local i = p.preinjections
+-- if i then
+-- -- glyph|pre glyphs
+-- local rightkern = i.rightkern
+-- if rightkern and rightkern ~= 0 then
+-- rightkern = xscaled(prevglyph,rightkern)
+-- if useadvance then
+-- addmargins(pre,-rightkern)
+-- else
+-- pre = insert_node_before(pre,pre,fontkern(rightkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if replace then
+-- local p = rawget(properties,prevglyph)
+-- if p then
+-- local i = p.replaceinjections
+-- if i then
+-- -- glyph|replace glyphs
+-- local rightkern = i.rightkern
+-- if rightkern and rightkern ~= 0 then
+-- rightkern = xscaled(prevglyph,rightkern)
+-- if useadvance then
+-- addmargins(replace,-rightkern)
+-- else
+-- replace = insert_node_before(replace,replace,fontkern(rightkern))
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- if done then
+-- setdisc(current,pre,post,replace)
+-- end
+-- prevglyph = nil
+-- prevdisc = current
+-- else
+-- prevglyph = nil
+-- prevdisc = nil
+-- end
+-- prev = current
+-- current = next
+-- end
+-- --
+-- if keepregisteredcounts then
+-- keepregisteredcounts = false
+-- else
+-- nofregisteredpositions = 0
+-- end
+-- if trace_injections then
+-- show_result(head)
+-- end
+-- return head
+-- end
+
+local function inject_positions_only_kerns(head,where)
if trace_injections then
trace(head,"positions")
end
@@ -832,33 +1437,37 @@ local function inject_positions_only(head,where)
-- left|glyph|right
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
-yoffset = yoffset * getxscale(current)
- setoffsets(current,false,yoffset)
+ -- use raise when advance
+ addyoffset(current,yscaled(current,yoffset))
end
- local leftkern = i.leftkern
- local rightkern = i.rightkern
- if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- if rightkern and leftkern == -rightkern then
- setoffsets(current,leftkern,false)
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ if leftkern ~= 0 then
+ leftkern = xscaled(current,leftkern)
+ end
+ if rightkern ~= 0 then
+ rightkern = xscaled(current,rightkern)
+ end
+ if leftkern ~= 0 then
+ if leftkern == -rightkern then
+ addxoffset(current,leftkern)
rightkern = 0
elseif prev and getid(prev) == glue_code then
if useitalickerns then
head = insert_node_before(head,current,italickern(leftkern))
else
- setwidth(prev, getwidth(prev) + leftkern)
+ setwidth(prev,getwidth(prev)+leftkern)
end
else
head = insert_node_before(head,current,fontkern(leftkern))
end
end
- if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(current)
+ if rightkern ~= 0 then
if next and getid(next) == glue_code then
if useitalickerns then
insert_node_after(head,current,italickern(rightkern))
else
- setwidth(next, getwidth(next) + rightkern)
+ setwidth(next, getwidth(next)+rightkern)
end
else
insert_node_after(head,current,fontkern(rightkern))
@@ -874,10 +1483,8 @@ rightkern = rightkern * getxscale(current)
if replace then
-- error, we expect an empty one
else
- -- KE setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern
-rightkern = rightkern * getxscale(current)
- replace = fontkern(rightkern) -- maybe also leftkern
- done = true --KE
+ replace = fontkern(xscaled(current,rightkern)) -- maybe also leftkern
+ done = true --KE
end
end
end
@@ -890,8 +1497,7 @@ rightkern = rightkern * getxscale(current)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- setlink(posttail,fontkern(leftkern))
+ setlink(posttail,fontkern(xscaled(current,leftkern)))
done = true
end
end
@@ -901,8 +1507,7 @@ leftkern = leftkern * getxscale(current)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- setlink(replacetail,fontkern(leftkern))
+ setlink(replacetail,fontkern(xscaled(current,leftkern)))
done = true
end
end
@@ -912,8 +1517,7 @@ leftkern = leftkern * getxscale(current)
-- new .. okay?
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- replace = fontkern(leftkern)
+ replace = fontkern(xscaled(current,leftkern))
done = true
end
end
@@ -942,17 +1546,14 @@ leftkern = leftkern * getxscale(current)
local leftkern = i.leftkern
local rightkern = i.rightkern
if yoffset and yoffset ~= 0 then
-yoffset = yoffset * getyscale(current)
- setoffsets(n,false,yoffset)
+ addyoffset(n,yscaled(n,yoffset))
end
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
- pre = insert_node_before(pre,n,fontkern(leftkern))
+ pre = insert_node_before(pre,n,fontkern(xscaled(n,leftkern)))
done = true
end
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(n)
- insert_node_after(pre,n,fontkern(rightkern))
+ insert_node_after(pre,n,fontkern(xscaled(n,rightkern)))
done = true
end
end
@@ -970,17 +1571,14 @@ rightkern = rightkern * getxscale(n)
local leftkern = i.leftkern
local rightkern = i.rightkern
if yoffset and yoffset ~= 0 then
-yoffset = yoffset * getyscale(current)
- setoffsets(n,false,yoffset)
+ addyoffset(n,yscaled(n,yoffset))
end
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
- post = insert_node_before(post,n,fontkern(leftkern))
+ post = insert_node_before(post,n,fontkern(xscaled(n,leftkern)))
done = true
end
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(n)
- insert_node_after(post,n,fontkern(rightkern))
+ insert_node_after(post,n,fontkern(xscaled(n,rightkern)))
done = true
end
end
@@ -998,17 +1596,14 @@ rightkern = rightkern * getxscale(n)
local leftkern = i.leftkern
local rightkern = i.rightkern
if yoffset and yoffset ~= 0 then
-yoffset = yoffset * getyscale(current)
- setoffsets(n,false,yoffset)
+ addyoffset(n,yscaled(n,yoffset))
end
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
- replace = insert_node_before(replace,n,fontkern(leftkern))
+ replace = insert_node_before(replace,n,fontkern(xscaled(n,leftkern)))
done = true
end
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(n)
- insert_node_after(replace,n,fontkern(rightkern))
+ insert_node_after(replace,n,fontkern(xscaled(n,rightkern)))
done = true
end
end
@@ -1016,6 +1611,7 @@ rightkern = rightkern * getxscale(n)
end
end
if prevglyph then
+ -- there can only be useful properties when pre/replace start with a glyph
if pre then
local p = rawget(properties,prevglyph)
if p then
@@ -1024,8 +1620,7 @@ rightkern = rightkern * getxscale(n)
-- glyph|pre glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(prevglyph)
- pre = insert_node_before(pre,pre,fontkern(rightkern))
+ pre = insert_node_before(pre,pre,fontkern(xscaled(prevglyph,rightkern)))
done = true
end
end
@@ -1039,8 +1634,7 @@ rightkern = rightkern * getxscale(prevglyph)
-- glyph|replace glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(prevglyph)
- replace = insert_node_before(replace,replace,fontkern(rightkern))
+ replace = insert_node_before(replace,replace,fontkern(xscaled(prevglyph,rightkern)))
done = true
end
end
@@ -1071,6 +1665,202 @@ rightkern = rightkern * getxscale(prevglyph)
return head
end
+local function inject_positions_only_margins(head,where)
+ if trace_injections then
+ trace(head,"positions")
+ end
+ local current = head
+ local prev = nil
+ local next = nil
+ local prevdisc = nil
+ local prevglyph = nil
+ local pre = nil -- saves a lookup
+ local post = nil -- saves a lookup
+ local replace = nil -- saves a lookup
+ local pretail = nil -- saves a lookup
+ local posttail = nil -- saves a lookup
+ local replacetail = nil -- saves a lookup
+ while current do
+ local next, char, id = isnextchar(current)
+ if char then
+ local p = rawget(properties,current)
+ if p then
+ local i = p.injections
+ if i then
+ -- left|glyph|right
+ local yoffset = i.yoffset or 0
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then
+ addxymargins(n,-leftkern,-rightkern,yoffset) -- also scales
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- glyph|disc|glyph (special case)
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ if next and getid(next) == disc_code then
+ if replace then
+ -- error, we expect an empty one
+ else
+ if usezwjkerns then
+ replace = copynode(current)
+ setchar(replace,0x200D) -- zwj
+ addxymargins(replace,false,-rightkern)
+ else
+ replace = fontkern(xscaled(current,rightkern)) -- maybe also leftkern
+ end
+ done = true --KE
+ end
+ end
+ end
+ end
+ end
+ if prevdisc then
+ if post then
+ local i = p.postinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(posttail,-leftkern)
+ end
+ end
+ end
+ if replace then
+ local i = p.replaceinjections
+ if i then
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ addxymargins(replacetail,-leftkern)
+ end
+ end
+ else
+ local i = p.emptyinjections
+ if i then
+ -- new .. okay?
+ local leftkern = i.leftkern
+ if leftkern and leftkern ~= 0 then
+ if usezwjkerns then
+ replace = copynode(current)
+ setchar(replace,0x200D) -- zwj
+ addxymargins(replace,-leftkern)
+ else
+ replace = fontkern(xscaled(current,leftkern))
+ end
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ end
+ end
+ prevdisc = nil
+ prevglyph = current
+ elseif char == false then
+ prevdisc = nil
+ prevglyph = current
+ elseif id == disc_code then
+ pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
+ if pre then
+ -- left|pre glyphs|right
+ for n in nextchar, pre do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.preinjections
+ if i then
+ local yoffset = i.yoffset or 0
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then
+ addxymargins(n,-leftkern,-rightkern,yoffset) -- also scales
+ end
+ end
+ end
+ end
+ end
+ if post then
+ -- left|post glyphs|right
+ for n in nextchar, post do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.postinjections
+ if i then
+ local yoffset = i.yoffset or 0
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then
+ addxymargins(n,-leftkern,-rightkern,yoffset) -- also scales
+ end
+ end
+ end
+ end
+ end
+ if replace then
+ -- left|replace glyphs|right
+ for n in nextchar, replace do
+ local p = rawget(properties,n)
+ if p then
+ local i = p.injections or p.replaceinjections
+ if i then
+ local yoffset = i.yoffset or 0
+ local leftkern = i.leftkern or 0
+ local rightkern = i.rightkern or 0
+ if leftkern ~= 0 or rightkern ~= 0 or yoffset ~= 0 then
+ addxymargins(n,-leftkern,-rightkern,yoffset) -- also scales
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p = rawget(properties,prevglyph)
+ if p then
+ local i = p.preinjections
+ if i then
+ -- glyph|pre glyphs
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ addxymargins(pre,-rightkern,0,0)
+ end
+ end
+ end
+ end
+ if replace then
+ local p = rawget(properties,prevglyph)
+ if p then
+ local i = p.replaceinjections
+ if i then
+ -- glyph|replace glyphs
+ local rightkern = i.rightkern
+ if rightkern and rightkern ~= 0 then
+ addxymargins(replace,-rightkern,0,0)
+ end
+ end
+ end
+ end
+ end
+ prevglyph = nil
+ prevdisc = current
+ else
+ prevglyph = nil
+ prevdisc = nil
+ end
+ prev = current
+ current = next
+ end
+ --
+ if keepregisteredcounts then
+ keepregisteredcounts = false
+ else
+ nofregisteredpositions = 0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
+end
+
local function showoffset(n,flag)
local x, y = getoffsets(n)
if x ~= 0 or y ~= 0 then
@@ -1078,6 +1868,90 @@ local function showoffset(n,flag)
end
end
+local function processmark(p,n,pn) -- p = basenode
+ local px, py = getoffsets(p)
+ local nx, ny = getoffsets(n)
+ local sx, sy = getxyscales(n) -- we assume n and p to have equal scales
+ local ox = 0
+ local rightkern = nil
+ local pp = rawget(properties,p)
+ if pp then
+ pp = pp.injections
+ if pp then
+ rightkern = pp.rightkern
+ end
+ end
+ local markdir = pn.markdir
+ if rightkern then -- x and w ~= 0
+ ox = px - sx * (pn.markx or 0) - rightkern
+ if markdir and markdir < 0 then
+ -- kern(w-x) glyph(p) kern(x) mark(n)
+ if not pn.markmark then
+ ox = ox + sx * (pn.leftkern or 0)
+ end
+ else
+ -- kern(x) glyph(p) kern(w-x) mark(n)
+ --
+ -- According to Kai we don't need to handle leftkern here but I'm
+ -- pretty sure I've run into a case where it was needed so maybe
+ -- some day we need something more clever here.
+ --
+ -- maybe we need to apply both then
+ --
+ if false then
+ -- a mark with kerning (maybe husayni needs it )
+ local leftkern = pp.leftkern
+ if leftkern then
+ ox = ox - sx * leftkern
+ end
+ end
+ end
+ else
+ ox = px - sx * (pn.markx or 0)
+ if markdir and markdir < 0 then
+ if not pn.markmark then
+ local leftkern = pn.leftkern
+ if leftkern then
+ ox = ox + sx * leftkern -- husayni needs it
+ end
+ end
+ end
+ if pn.checkmark then
+ local wn = getwidth(n) -- in arial marks have widths
+ if wn and wn ~= 0 then
+ wn = wn/2
+ if trace_injections then
+ report_injections("correcting non zero width mark %C",getchar(n))
+ end
+ -- -- bad: we should center
+ --
+ -- pn.leftkern = -wn
+ -- pn.rightkern = -wn
+ --
+ -- -- we're too late anyway as kerns are already injected so we do it the
+ -- -- ugly way (no checking if the previous is already a kern) .. maybe we
+ -- -- should fix the font instead
+ --
+ -- todo: head and check for prev / next kern
+ --
+ insert_node_before(n,n,fontkern(-wn))
+ insert_node_after(n,n,fontkern(-wn))
+ end
+ end
+ end
+ local oy = ny + py + sy * (pn.marky or 0)
+ if not pn.markmark then
+ local yoffset = pn.yoffset
+ if yoffset then
+ oy = oy + sy * yoffset -- husayni needs it
+ end
+ end
+ setoffsets(n,ox,oy)
+ if trace_marks then
+ showoffset(n,true)
+ end
+end
+
local function inject_everything(head,where)
if trace_injections then
trace(head,"everything")
@@ -1105,92 +1979,6 @@ local function inject_everything(head,where)
local marks = { }
local nofmarks = 0
--
- -- move out
- --
- local function processmark(p,n,pn) -- p = basenode
- local px, py = getoffsets(p)
- local nx, ny = getoffsets(n)
- local ox = 0
- local rightkern = nil
- local pp = rawget(properties,p)
- if pp then
- pp = pp.injections
- if pp then
- rightkern = pp.rightkern
- end
- end
- local markdir = pn.markdir
- if rightkern then -- x and w ~= 0
- ox = px - (pn.markx or 0) - rightkern
- if markdir and markdir < 0 then
- -- kern(w-x) glyph(p) kern(x) mark(n)
- if not pn.markmark then
- ox = ox + (pn.leftkern or 0)
- end
- else
- -- kern(x) glyph(p) kern(w-x) mark(n)
- --
- -- According to Kai we don't need to handle leftkern here but I'm
- -- pretty sure I've run into a case where it was needed so maybe
- -- some day we need something more clever here.
- --
- -- maybe we need to apply both then
- --
- if false then
- -- a mark with kerning (maybe husayni needs it )
- local leftkern = pp.leftkern
- if leftkern then
- ox = ox - leftkern
- end
- end
- end
- else
- ox = px - (pn.markx or 0)
- if markdir and markdir < 0 then
- if not pn.markmark then
- local leftkern = pn.leftkern
- if leftkern then
- ox = ox + leftkern -- husayni needs it
- end
- end
- end
- if pn.checkmark then
- local wn = getwidth(n) -- in arial marks have widths
- if wn and wn ~= 0 then
- wn = wn/2
- if trace_injections then
- report_injections("correcting non zero width mark %C",getchar(n))
- end
- -- -- bad: we should center
- --
- -- pn.leftkern = -wn
- -- pn.rightkern = -wn
- --
- -- -- we're too late anyway as kerns are already injected so we do it the
- -- -- ugly way (no checking if the previous is already a kern) .. maybe we
- -- -- should fix the font instead
- --
- -- todo: head and check for prev / next kern
- --
- insert_node_before(n,n,fontkern(-wn))
- insert_node_after(n,n,fontkern(-wn))
- end
- end
- end
- local oy = ny + py + (pn.marky or 0)
- if not pn.markmark then
- local yoffset = pn.yoffset
- if yoffset then
- oy = oy + yoffset -- husayni needs it
- end
- end
-ox = ox * getxscale(p)
-oy = oy * getyscale(p)
- setoffsets(n,ox,oy)
- if trace_marks then
- showoffset(n,true)
- end
- end
while current do
local next, char, id = isnextchar(current)
if char then
@@ -1205,8 +1993,7 @@ oy = oy * getyscale(p)
else
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
-yoffset = yoffset * getyscale(current)
- setoffsets(current,false,yoffset)
+ addyoffset(current,yscaled(current,yoffset)) -- or just * sy
end
if hascursives then
local cursivex = i.cursivex
@@ -1232,9 +2019,8 @@ yoffset = yoffset * getyscale(current)
local nx, ny = getoffsets(current)
for i=maxc,minc,-1 do
local ti = glyphs[i]
- ny = ny + properties[ti].cursivedy
-* getyscale(current)
- setoffsets(ti,false,ny) -- why not add ?
+ ny = ny + yscaled(current,properties[ti].cursivedy) -- stepwise increment
+ setoffsets(ti,false,ny)
if trace_cursive then
showoffset(ti)
end
@@ -1249,9 +2035,8 @@ yoffset = yoffset * getyscale(current)
local nx, ny = getoffsets(current)
for i=maxc,minc,-1 do
local ti = glyphs[i]
- ny = ny + properties[ti].cursivedy
-* getyscale(current)
- setoffsets(ti,false,ny) -- why not add ?
+ ny = ny + yscaled(current,properties[ti].cursivedy) -- stepwise increment
+ setoffsets(ti,false,ny)
if trace_cursive then
showoffset(ti)
end
@@ -1265,9 +2050,10 @@ yoffset = yoffset * getyscale(current)
local leftkern = i.leftkern
local rightkern = i.rightkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- if rightkern and leftkern == -rightkern then
- setoffsets(current,leftkern,false)
+ local opposite = rightkern and leftkern == -rightkern
+ leftkern = xscaled(current,leftkern)
+ if opposite then
+ addxoffset(current,leftkern)
rightkern = 0
elseif prev and getid(prev) == glue_code then
if useitalickerns then
@@ -1280,7 +2066,7 @@ leftkern = leftkern * getxscale(current)
end
end
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(current)
+ rightkern = xscaled(current,rightkern)
if next and getid(next) == glue_code then
if useitalickerns then
insert_node_after(head,current,italickern(rightkern))
@@ -1302,8 +2088,7 @@ rightkern = rightkern * getxscale(current)
if replace then
-- error, we expect an empty one
else
-rightkern = rightkern * getxscale(current)
- replace = fontkern(rightkern)
+ replace = fontkern(xscaled(current,rightkern))
done = true
end
end
@@ -1318,8 +2103,7 @@ rightkern = rightkern * getxscale(current)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- setlink(posttail,fontkern(leftkern))
+ setlink(posttail,fontkern(xscaled(current,leftkern)))
done = true
end
end
@@ -1329,8 +2113,7 @@ leftkern = leftkern * getxscale(current)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- setlink(replacetail,fontkern(leftkern))
+ setlink(replacetail,fontkern(xscaled(current,leftkern)))
done = true
end
end
@@ -1339,8 +2122,7 @@ leftkern = leftkern * getxscale(current)
if i then
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
- replace = fontkern(leftkern)
+ replace = fontkern(xscaled(current,leftkern))
done = true
end
end
@@ -1356,10 +2138,8 @@ leftkern = leftkern * getxscale(current)
local nx, ny = getoffsets(current)
for i=maxc,minc,-1 do
local ti = glyphs[i]
- ny = ny + properties[ti].cursivedy
-* getyscale(current)
- local xi, yi = getoffsets(ti)
- setoffsets(ti,xi,yi + ny) -- can be mark, we could use properties
+ ny = ny + yscaled(current,properties[ti].cursivedy)
+ setoffsets(ti,false,ny) -- can be mark, we could use properties
end
maxc = 0
cursiveanchor = nil
@@ -1384,18 +2164,16 @@ leftkern = leftkern * getxscale(current)
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setoffsets(n,false,yoffset)
+ addyoffset(n,yscaled(n,yoffset))
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
- pre = insert_node_before(pre,n,fontkern(leftkern))
+ pre = insert_node_before(pre,n,fontkern(xscaled(n,leftkern)))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(n)
- insert_node_after(pre,n,fontkern(rightkern))
+ insert_node_after(pre,n,fontkern(xscaled(n,rightkern)))
done = true
end
if hasmarks then
@@ -1417,19 +2195,17 @@ rightkern = rightkern * getxscale(n)
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setoffsets(n,false,yoffset)
+ addyoffset(n,yscaled(n,yoffset))
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getsxcale(n)
- post = insert_node_before(post,n,fontkern(leftkern))
+ post = insert_node_before(post,n,fontkern(xscaled(n,leftkern)))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getsxcale(n)
- insert_node_after(post,n,fontkern(rightkern))
done = true
+ insert_node_after(post,n,fontkern(xscaled(n,rightkern)))
end
if hasmarks then
local pm = i.markbasenode
@@ -1450,18 +2226,16 @@ rightkern = rightkern * getsxcale(n)
if i then
local yoffset = i.yoffset
if yoffset and yoffset ~= 0 then
- setoffsets(n,false,yoffset)
+ addyoffset(n,yscaled(n,yoffset))
end
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
- replace = insert_node_before(replace,n,fontkern(leftkern))
+ replace = insert_node_before(replace,n,fontkern(xscaled(n,leftkern)))
done = true
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(n)
- insert_node_after(replace,n,fontkern(rightkern))
+ insert_node_after(replace,n,fontkern(xscaled(n,rightkern)))
done = true
end
if hasmarks then
@@ -1483,8 +2257,7 @@ rightkern = rightkern * getxscale(n)
-- glyph|pre glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(prevglyph)
- pre = insert_node_before(pre,pre,fontkern(rightkern))
+ pre = insert_node_before(pre,pre,fontkern(xscaled(prevglyph,rightkern)))
done = true
end
end
@@ -1498,8 +2271,7 @@ rightkern = rightkern * getxscale(prevglyph)
-- glyph|replace glyphs
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
-rightkern = rightkern * getxscale(prevglyph)
- replace = insert_node_before(replace,replace,fontkern(rightkern))
+ replace = insert_node_before(replace,replace,fontkern(xscaled(prevglyph,rightkern)))
done = true
end
end
@@ -1524,8 +2296,8 @@ rightkern = rightkern * getxscale(prevglyph)
local nx, ny = getoffsets(last)
for i=maxc,minc,-1 do
local ti = glyphs[i]
- ny = ny + properties[ti].cursivedy
- setoffsets(ti,false,ny) -- why not add ?
+ ny = ny + yscaled(properties[ti].cursivedy)
+ setoffsets(ti,false,ny)
if trace_cursive then
showoffset(ti)
end
@@ -1635,8 +2407,7 @@ local function injectspaces(head)
local threshold = 0
local leftkern = false
local rightkern = false
-
-local xscale = 1
+ local xscale = 1
local function updatefont(font,trig)
leftkerns = trig.left
@@ -1660,7 +2431,7 @@ local xscale = 1
if rightkerns then
rightkern = rightkerns[nextchar]
end
-xscale = getxscale(next)
+ xscale = getxscale(next)
end
end
if prevchar then
@@ -1673,7 +2444,7 @@ xscale = getxscale(next)
if leftkerns then
leftkern = leftkerns[prevchar]
end
-xscale = getxscale(prev)
+ xscale = getxscale(prev)
end
end
if leftkern then
@@ -1686,8 +2457,8 @@ xscale = getxscale(prev)
if trace_spaces then
report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
end
-lnew = lnew * xscale
-rnew = rnew * xscale
+ lnew = lnew * xscale
+ rnew = rnew * xscale
head = insert_node_before(head,n,italickern(lnew))
insert_node_after(head,n,italickern(rnew))
else
@@ -1704,11 +2475,10 @@ rnew = rnew * xscale
if trace_spaces then
report_spaces("%C [%p + %p]",prevchar,old,new)
end
-new = new * xscale
+ new = new * xscale
insert_node_after(head,n,italickern(new)) -- tricky with traverse but ok
else
--- local new = old + leftkern * factor
-local new = old + leftkern * factor * xscale
+ local new = old + leftkern * factor * xscale
if trace_spaces then
report_spaces("%C [%p -> %p]",prevchar,old,new)
end
@@ -1720,16 +2490,14 @@ local new = old + leftkern * factor * xscale
elseif rightkern then
local old = getwidth(n)
if old > threshold then
+ local new = rightkern * factor * xscale
if useitalickerns then
- local new = rightkern * factor
-new = new * xscale
if trace_spaces then
report_spaces("[%p + %p] %C",old,new,nextchar)
end
insert_node_after(head,n,italickern(new))
else
--- local new = old + rightkern * factor
-local new = old + rightkern * factor * xscale
+ new = old + new
if trace_spaces then
report_spaces("[%p -> %p] %C",old,new,nextchar)
end
@@ -1747,28 +2515,40 @@ local new = old + rightkern * factor * xscale
return head
end
---
+-- When advance is found to be okay there will be split functions (which is abit
+-- more efficient) but first we need to have scales done (we can also have addoffset
+-- and alike then)
function injections.handler(head,where)
if triggers then
head = injectspaces(head)
end
- -- todo: marks only run too
if nofregisteredmarks > 0 or nofregisteredcursives > 0 then
if trace_injections then
- report_injections("injection variant %a","everything")
+ report_injections("injection variant %a (%s)","everything","kerns")
end
+ -- I will do useadvance here when I am playing with fonts that follow this
+ -- injection routem, which is seldom.
return inject_everything(head,where)
elseif nofregisteredpositions > 0 then
if trace_injections then
- report_injections("injection variant %a","positions")
+ report_injections("injection variant %a (%s)","positions",useadvance and "margins" or "kerns")
+ end
+ if useadvance then
+ return inject_positions_only_margins(head,where)
+ else
+ return inject_positions_only_kerns(head,where)
end
- return inject_positions_only(head,where)
elseif nofregisteredkerns > 0 then
if trace_injections then
- report_injections("injection variant %a","kerns")
+ report_injections("injection variant %a (%s)","kerns",useadvance and "margins" or "kerns")
+ end
+ if useadvance then
+ return inject_kerns_only_margins(head,where)
+-- return inject_positions_only_margins(head,where)
+ else
+ return inject_kerns_only_kerns(head,where)
end
- return inject_kerns_only(head,where)
else
return head
end
diff --git a/tex/context/base/mkxl/lang-hyp.lmt b/tex/context/base/mkxl/lang-hyp.lmt
index c2862f536..c356dbf3c 100644
--- a/tex/context/base/mkxl/lang-hyp.lmt
+++ b/tex/context/base/mkxl/lang-hyp.lmt
@@ -1438,8 +1438,8 @@ featureset.hyphenonly = hyphenonly == v_yes
rightchar = rightchar or (instance and prehyphenchar (instance)) -- efficient if needed
leftexchar = (instance and preexhyphenchar (instance))
rightexchar = (instance and postexhyphenchar(instance))
- leftmin = leftcharmin or getfield(current,"left")
- rightmin = rightcharmin or getfield(current,"right")
+ leftmin = leftcharmin or getfield(current,"lhmin")
+ rightmin = rightcharmin or getfield(current,"rhmin")
if not leftchar or leftchar < 0 then
leftchar = false
end
@@ -1516,8 +1516,8 @@ featureset.hyphenonly = hyphenonly == v_yes
rightchar = rightchar or (instance and prehyphenchar (instance)) -- efficient if needed
leftexchar = (instance and preexhyphenchar (instance))
rightexchar = (instance and postexhyphenchar(instance))
- leftmin = leftcharmin or getfield(current,"left")
- rightmin = rightcharmin or getfield(current,"right")
+ leftmin = leftcharmin or getfield(current,"lhmin")
+ rightmin = rightcharmin or getfield(current,"rhmin")
if not leftchar or leftchar < 0 then
leftchar = false
end
diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt
index dbd5c7ef2..296f6f446 100644
--- a/tex/context/base/mkxl/node-nut.lmt
+++ b/tex/context/base/mkxl/node-nut.lmt
@@ -97,9 +97,12 @@ local nuts = {
getnormalizedline = direct.getnormalizedline,
getnucleus = direct.getnucleus,
getoffsets = direct.getoffsets,
+ -- getxyoffsets = direct.getxyoffsets,
getscales = direct.getscales,
getxscale = direct.getxscale,
getyscale = direct.getyscale,
+ xscaled = direct.xscaled,
+ yscaled = direct.yscaled,
getxyscales = direct.getxyscales,
getorientation = direct.getorientation,
getoptions = direct.getoptions,
@@ -156,7 +159,8 @@ local nuts = {
remove = d_remove_node,
reverse = direct.reverse,
set_attribute = direct.set_attribute,
- setadvance = direct.setadvance,
+ addmargins = direct.addmargins,
+ addxymargins = direct.addxymargins,
setattr = direct.set_attribute,
setattrs = direct.set_attributes,
setattributelist = direct.setattributelist,
@@ -189,6 +193,8 @@ local nuts = {
setnucleus = direct.setnucleus,
setscales = direct.setscales,
setoffsets = direct.setoffsets,
+ addxoffset = direct.addxoffset,
+ addyoffset = direct.addyoffset,
setorientation = direct.setorientation,
setoptions = direct.setoptions,
setpenalty = direct.setpenalty,
diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt
index 2be9529a9..8c04a0372 100644
--- a/tex/context/base/mkxl/trac-vis.lmt
+++ b/tex/context/base/mkxl/trac-vis.lmt
@@ -57,6 +57,7 @@ local getwidth = nuts.getwidth
local getdepth = nuts.getdepth
local getexpansion = nuts.getexpansion
local getstate = nuts.getstate
+local getoffsets = nuts.getoffsets
local isglyph = nuts.isglyph
@@ -878,18 +879,20 @@ local ruledglyph do
local prev = previous
setboth(current)
local linewidth = emwidth/(2*fraction)
- local info
- --
- info = setlink(
- (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
- width = wd,
- height = ht,
- depth = dp,
- line = linewidth,
- type = "box",
- },
- new_kern(-wd)
- )
+ local x_offset, y_offset, l_margin, r_margin, raise = getoffsets(current)
+ wd = wd - l_margin - r_margin
+ local info = (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
+ width = wd,
+ height = ht,
+ depth = dp,
+ line = linewidth,
+ type = "box",
+ }
+ if l_margin == 0 then
+ info = setlink(info,new_kern(-wd))
+ else
+ info = setlink(new_kern(-l_margin),info,new_kern(-wd+l_margin))
+ end
--
local c, f = isglyph(current)
local char = chardata[f][c]
diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml
index eddd75da9..9765bf47f 100644
--- a/tex/context/interface/mkii/keys-cs.xml
+++ b/tex/context/interface/mkii/keys-cs.xml
@@ -1137,6 +1137,7 @@
<cd:constant name='reference' value='odkaz'/>
<cd:constant name='referencemethod' value='referencemethod'/>
<cd:constant name='referenceprefix' value='referenceprefix'/>
+ <cd:constant name='referencetext' value='referencetext'/>
<cd:constant name='referencing' value='odkazujici'/>
<cd:constant name='region' value='region'/>
<cd:constant name='regionin' value='oblastuvnitr'/>
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index f987a7c06..c1300a71b 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2021-01-08 11:44
+-- merge date : 2021-01-11 16:28
do -- begin closure to overcome local limits and interference