1
2
3\startcomponent ontargeteventually
4
5\environment ontargetstyle
6
7\startchapter[title={Anchoring}]
8
9\startsection[title=Introduction]
10
11It is valid to question what functionality should be in the engine and what can
12best be implemented using callbacks and postprocessing of lists (and boxes)
13relying for instance on attributes as signals. In \LUATEX\ we are rather strict
14in this and assume that the second method is used. In \LUAMETATEX\ we still
15promote this but at the same time some (lightweight) functionality has been added
16to the engine that helps implementing some features more efficiently. Reasons are
17that it can be handy to carry (fundamental) properties around that are bound to
18nodes and that we can set them using primitives, especially for glyphs and boxes.
19That way they become part of the formal functionality that one can argue should
20be present in a modern engine. Examples for glyph nodes are scales, offsets and
21hyphenation, detailed ligature and kerning control. For box nodes we have for
22instance offsets and orientation. Most of these are always taken into account by
23core mechanisms like breaking paragraphs into lines, where dimensions matter in
24which case it really makes sense for them to be part of the engine design.
25
26Some properties are just passed on to for instance a font handler or the backend
27but still they belong to the core functionality. An example of the later is a
28(new) simple mechanism for anchoring boxes. This is not really a fundamental
29feature, because one can just move content around using a combination of kerning
30and boxing, either or not with offsets. But because we already have features like
31offsets to boxes it was not that much work to add anchoring as a more fundamental
32property. The frontend is agnostic to this feature because dimensions are kind of
33virtual here: the backend however carries the real burden. Because backends are
34written in \LUA\ it might have a performance hit simply because at least we need
35to check if this feature is used. Normally that can compensated when this feature
36{\em is} used because less work and shuffling around happens in the frontend. And
37when this feature is no longer experimental (and stays) we can gain some back by
38using it in existing scenarios. It sounds worse than it is because for
39orientations we already have to do some usage checking and we can share that
40check; in most situations nothing needs to be done anyway.
41
42\stopsection
43
44\startsection[title=The low level approach]
45
46When we anchor, a box can be a source andor a target. Both are represented by
47a number and can be assigned via a keyword. These numbers can be picked up by the
48backend. Here is an example:
49
50\startbuffer
51\def\TestMe#1{
52 \setbox \scratchbox \ruledvbox
53 source 123
54 orientation #1
55 \bgroup
56 \hsize7cm
57 \samplefile{zapf}
58 \hbox to 0pt
59 source 124 target 123
60 xoffset 20pt yoffset 30pt
61 {\darkred \bfc TEST1}
62 \hbox to 0pt
63 source 125 target 124
64 xoffset 10pt yoffset 20pt
65 {\darkblue \bfc TEST2}
66 \egroup
67 \box \scratchbox
68}
69\stopbuffer
70
71\typebuffer \getbuffer
72
73This example also uses a few offsets. The \quote {origin} is at the left edge of
74the baseline. Now, we could have passed the source and target as attribute and
75intercepting an attribute in the backend can work pretty well. However, the code
76that deals with the final result of the typesetting and thereby flushes it to for
77instance a \PDF\ file is, at least that is the setup we use in \CONTEXT,
78attribute agnostic. Mixing in attributes at that stage, except for user nodes and
79whatsits that are effectively plugins, is counter intuitive and all is already
80pretty complex so a clear separation of functionality makes a lot of sense. Of
81course the \CONTEXT\ approach is not the only one when it comes to generic engine
82functionality. Not that many fundamental (conceptual) extensions showed up over
83the last few decades so no one will bother if in \LUAMETATEX\ we have new stuff
84that is only used by \CONTEXT. The example code shown here gives:
85
86\startbuffer[four]
87\startcombination[4*1]
88 {\scale[sx=.4,sy=.4]{\TestMe{0}}} {\type {orientation 0}}
89 {\scale[sx=.4,sy=.4]{\TestMe{1}}} {\type {orientation 1}}
90 {\scale[sx=.4,sy=.4]{\TestMe{2}}} {\type {orientation 2}}
91 {\scale[sx=.4,sy=.4]{\TestMe{3}}} {\type {orientation 3}}
92\stopcombination
93\stopbuffer
94
95\startlinecorrection
96\dontcomplain\getbuffer[four]
97\stoplinecorrection
98
99In order to avoid additional shifting around, which then might involve copying
100and injecting boxes as well as repackaging, two additional keys are available
101and these deal with the way boxes get anchored.
102
103\startbuffer
104\vbox
105 source 123
106 \bgroup
107 \offinterlineskip
108 \blackrule[width=4cm,height=2cm,depth=0cm,color=darkred]\par
109 \blackrule[width=4cm,height=0cm,depth=1cm,color=darkblue]\par
110 \setbox\scratchboxtwo\hbox
111 anchors "0004 "0001
112
113 target 123
114 orientation 1
115 {\blackrule[width=2cm,height=1cm,depth=0cm,color=darkgreen]
116 \hskip2cm
117 \blackrule[width=2cm,height=0cm,depth=1cm,color=darkyellow]}
118
119 \smash{\box\scratchboxtwo}
120 \egroup
121\stopbuffer
122
123\typebuffer
124
125The anchor is just an number but with the plural keyword we can scan it as two
126because that is a bit easier on usage. The two numbers four byte numbers control
127the source to target anchoring and there is plenty room for future extensions
128because not all bits are used.
129
130\starttabulate[lTlT]
131\NC 0x00\uchexnumber\leftoriginlistanchorcode \NC left origin \NC \NR
132\NC 0x00\uchexnumber\leftheightlistanchorcode \NC left height \NC \NR
133\NC 0x00\uchexnumber\leftdepthlistanchorcode \NC left depth \NC \NR
134\NC 0x00\uchexnumber\rightoriginlistanchorcode \NC right origin \NC \NR
135\NC 0x00\uchexnumber\rightheightlistanchorcode \NC right height \NC \NR
136\NC 0x00\uchexnumber\rightdepthlistanchorcode \NC right depth \NC \NR
137\NC 0x00\uchexnumber\centeroriginlistanchorcode \NC center origin \NC \NR
138\NC 0x00\uchexnumber\centerheightlistanchorcode \NC center height \NC \NR
139\NC 0x00\uchexnumber\centerdepthlistanchorcode \NC center depth \NC \NR
140\NC 0x00\uchexnumber\halfwaytotallistanchorcode \NC halfway total \NC \NR
141\NC 0x00\uchexnumber\halfwayheightlistanchorcode \NC halfway height \NC \NR
142\NC 0x00\uchexnumber\halfwaydepthlistanchorcode \NC halfway depth \NC \NR
143\NC 0x00\uchexnumber\halfwayleftlistanchorcode \NC halfway left \NC \NR
144\NC 0x00\uchexnumber\halfwayrightlistanchorcode \NC halfway right \NC \NR
145\stoptabulate
146
147The target and source are handled in a way that sort of naturally binds them
148which involves a little juggling with dimensions in the backend. There is some
149additional control over this but usage is not advertized here because it might
150change.
151
152
153
154One can set these anchoring related properties with keywords but there are also
155primitive box manipulators: \type {\boxanchor}, \type {\boxanchors}, \type
156{\boxsource} and \type {\boxtarget} that take a box number and value.
157
158\startlinecorrection
159\getbuffer
160\stoplinecorrection
161
162There are some helpers at the \LUA\ end but I havent completely made up my mind
163about them. Normally that evolves with usage.
164
165\stopsection
166
167\startsection[title={A first higher level interface}]
168
169Exploring this here in more detail makes no sense because it is still
170experimental and also rather \CONTEXT\ specific. As a teaser an interface that
171hooks into layers is shown:
172
173\startbuffer
174\defineanchorboxoverlay[framed]
175
176\def\DemoAnchor#1#2#3#4
177 {\setanchorbox
178 [#1]
179 [target={#3},source={#4}]
180 \hbox{\backgroundline[#2]{\white\smallinfofont\setstrut\strut target=#3 source=#4}}}
181
182\def\DemoAnchorX#1#2
183 {\DemoAnchor{#1}{darkred} {#2}{left,top}
184 \DemoAnchor{#1}{darkblue} {#2}{left,bottom}
185 \DemoAnchor{#1}{darkgreen} {#2}{right,bottom}
186 \DemoAnchor{#1}{darkyellow}{#2}{right,top}
187 }
188
189\startsetups framed:demo
190 \DemoAnchorX{framed:background}{left,top}
191 \DemoAnchorX{framed:background}{right,top}
192 \DemoAnchorX{framed:background}{left,bottom}
193 \DemoAnchorX{framed:background}{right,bottom}
194 \DemoAnchorX{framed:foreground}{middle}
195\stopsetups
196
197\midaligned\bgroup
198 \framed
199 [align=normal,
200 width=.7\textwidth,
201 backgroundcolor=gray,
202 background={color,framed:background,foreground,framed:foreground}]
203 \bgroup
204 \samplefile{zapf}\par
205 \directsetup{framed:demo}
206 \samplefile{zapf}
207 \egroup
208\egroup
209\stopbuffer
210
211\typebuffer
212
213Those familiar with \CONTEXT\ will recognize the approach. This one basically is
214a more low level variant of layers and a high level variant of the primitives.
215Performance wise (in terms of memory usage and runtime) it sits in a sweet spot.
216
217\startlinecorrection[2*big]
218 \getbuffer
219\stoplinecorrection
220
221I played a bit with a mechanism that can store the embedded (to be anchored)
222content in a more independent way and it actually works okay. However, Im not
223entirely sure if that solution is the best so for now its commented. As usual it
224is also up to users to come up with demands.
225
226\stopsection
227
228\stopchapter
229
230\stopcomponent
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 |