summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/ontarget/ontarget-anchoring.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/ontarget/ontarget-anchoring.tex')
-rw-r--r--doc/context/sources/general/manuals/ontarget/ontarget-anchoring.tex280
1 files changed, 280 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/ontarget/ontarget-anchoring.tex b/doc/context/sources/general/manuals/ontarget/ontarget-anchoring.tex
new file mode 100644
index 000000000..090c6ba0c
--- /dev/null
+++ b/doc/context/sources/general/manuals/ontarget/ontarget-anchoring.tex
@@ -0,0 +1,280 @@
+% language=us runpath=texruns:manuals/ontarget
+
+\startcomponent ontarget-eventually
+
+\environment ontarget-style
+
+\startchapter[title={Anchoring}]
+
+\startsection[title=Introduction]
+
+It is valid to question what functionality should be in the engine and what can
+best be implemented using callbacks and postprocessing of lists (and boxes)
+relying for instance on attributes as signals. In \LUATEX\ we are rather strict
+in this and assume that the second method is used. In \LUAMETATEX\ we still
+promote this but at the same time some (lightweight) functionality has been added
+to the engine that helps implementing some features more efficiently. Reasons are
+that it can be handy to carry (fundamental) properties around that are bound to
+nodes and that we can set them using primitives, especially for glyphs and boxes.
+That way they become part of the formal functionality that one can argue should
+be present in a modern engine. Examples for glyph nodes are scales, offsets and
+hyphenation, detailed ligature and kerning control. For box nodes we have for
+instance offsets and orientation. Most of these are always taken into account by
+core mechanisms like breaking paragraphs into lines, where dimensions matter in
+which case it really makes sense for them to be part of the engine design.
+
+Some properties are just passed on to for instance a font handler or the backend
+but still they belong to the core functionality. An example of the later is a
+(new) simple mechanism for anchoring boxes. This is not really a fundamental
+feature, because one can just move content around using a combination of kerning
+and boxing, either or not with offsets. But because we already have features like
+offsets to boxes it was not that much work to add anchoring as a more fundamental
+property. The frontend is agnostic to this feature because dimensions are kind of
+virtual here: the backend however carries the real burden. Because backends are
+written in \LUA\ it might have a performance hit simply because at least we need
+to check if this feature is used. Normally that can compensated when this feature
+{\em is} used because less work and shuffling around happens in the frontend. And
+when this feature is no longer experimental (and stays) we can gain some back by
+using it in existing scenarios. It sounds worse than it is because for
+orientations we already have to do some usage checking and we can share that
+check; in most situations nothing needs to be done anyway.
+
+\stopsection
+
+\startsection[title=The low level approach]
+
+When we anchor, a box can be a source and|/|or a target. Both are represented by
+a number and can be assigned via a keyword. These numbers can be picked up by the
+backend. Here is an example:
+
+\startbuffer
+\def\TestMe#1{%
+ \setbox \scratchbox \ruledvbox
+ source 123
+ orientation #1
+ \bgroup
+ \hsize7cm
+ \samplefile{zapf}
+ \hbox to 0pt
+ source 124 target 123
+ xoffset 20pt yoffset -30pt
+ {\darkred \bfc TEST1}%
+ \hbox to 0pt
+ source 125 target 124
+ xoffset 10pt yoffset -20pt
+ {\darkblue \bfc TEST2}%
+ \egroup
+ \box \scratchbox
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This example also uses a few offsets. The \quote {origin} is at the left edge of
+the baseline. Now, we could have passed the source and target as attribute and
+intercepting an attribute in the backend can work pretty well. However, the code
+that deals with the final result of the typesetting and thereby flushes it to for
+instance a \PDF\ file is, at least that is the setup we use in \CONTEXT,
+attribute agnostic. Mixing in attributes at that stage, except for user nodes and
+whatsits that are effectively plugins, is counter intuitive and all is already
+pretty complex so a clear separation of functionality makes a lot of sense. Of
+course the \CONTEXT\ approach is not the only one when it comes to generic engine
+functionality. Not that many fundamental (conceptual) extensions showed up over
+the last few decades so no one will bother if in \LUAMETATEX\ we have new stuff
+that is only used by \CONTEXT. The example code shown here gives:
+
+\startbuffer[four]
+\startcombination[4*1]
+ {\scale[sx=.4,sy=.4]{\TestMe{0}}} {\type {orientation 0}}
+ {\scale[sx=.4,sy=.4]{\TestMe{1}}} {\type {orientation 1}}
+ {\scale[sx=.4,sy=.4]{\TestMe{2}}} {\type {orientation 2}}
+ {\scale[sx=.4,sy=.4]{\TestMe{3}}} {\type {orientation 3}}
+\stopcombination
+\stopbuffer
+
+\startlinecorrection
+\dontcomplain\getbuffer[four]
+\stoplinecorrection
+
+In order to avoid additional shifting around, which then might involve copying
+and injecting boxes as well as repackaging, two additional keys are available
+and these deal with the way boxes get anchored.
+
+\startbuffer
+\vbox
+ source 123
+ \bgroup
+ \offinterlineskip
+ \blackrule[width=4cm,height=2cm,depth=0cm,color=darkred]\par
+ \blackrule[width=4cm,height=0cm,depth=1cm,color=darkblue]\par
+ \setbox\scratchboxtwo\hbox
+ anchors "0004 "0001
+ % anchor "00040001
+ target 123
+ orientation 1
+ {\blackrule[width=2cm,height=1cm,depth=0cm,color=darkgreen]%
+ \hskip-2cm
+ \blackrule[width=2cm,height=0cm,depth=1cm,color=darkyellow]}%
+ %
+ \smash{\box\scratchboxtwo}%
+ \egroup
+\stopbuffer
+
+\typebuffer
+
+The anchor is just an number but with the plural keyword we can scan it as two
+because that is a bit easier on usage. The two numbers four byte numbers control
+the source to target anchoring and there is plenty room for future extensions
+because not all bits are used.
+
+\starttabulate[|lT|lT|]
+\NC 0x00\uchexnumber\leftoriginlistanchorcode \NC left origin \NC \NR
+\NC 0x00\uchexnumber\leftheightlistanchorcode \NC left height \NC \NR
+\NC 0x00\uchexnumber\leftdepthlistanchorcode \NC left depth \NC \NR
+\NC 0x00\uchexnumber\rightoriginlistanchorcode \NC right origin \NC \NR
+\NC 0x00\uchexnumber\rightheightlistanchorcode \NC right height \NC \NR
+\NC 0x00\uchexnumber\rightdepthlistanchorcode \NC right depth \NC \NR
+\NC 0x00\uchexnumber\centeroriginlistanchorcode \NC center origin \NC \NR
+\NC 0x00\uchexnumber\centerheightlistanchorcode \NC center height \NC \NR
+\NC 0x00\uchexnumber\centerdepthlistanchorcode \NC center depth \NC \NR
+\NC 0x00\uchexnumber\halfwaytotallistanchorcode \NC halfway total \NC \NR
+\NC 0x00\uchexnumber\halfwayheightlistanchorcode \NC halfway height \NC \NR
+\NC 0x00\uchexnumber\halfwaydepthlistanchorcode \NC halfway depth \NC \NR
+\NC 0x00\uchexnumber\halfwayleftlistanchorcode \NC halfway left \NC \NR
+\NC 0x00\uchexnumber\halfwayrightlistanchorcode \NC halfway right \NC \NR
+\stoptabulate
+
+The target and source are handled in a way that sort of naturally binds them
+which involves a little juggling with dimensions in the backend. There is some
+additional control over this but usage is not advertized here because it might
+change.
+
+% \negatexlistsigncode \negateylistsigncode \negatelistsigncode
+
+One can set these anchoring related properties with keywords but there are also
+primitive box manipulators: \type {\boxanchor}, \type {\boxanchors}, \type
+{\boxsource} and \type {\boxtarget} that take a box number and value.
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+There are some helpers at the \LUA\ end but I haven't completely made up my mind
+about them. Normally that evolves with usage.
+
+\stopsection
+
+\startsection[title={A first higher level interface}]
+
+Exploring this here in more detail makes no sense because it is still
+experimental and also rather \CONTEXT\ specific. As a teaser an interface that
+hooks into layers is shown:
+
+\startbuffer
+\defineanchorboxoverlay[framed]
+
+\def\DemoAnchor#1#2#3#4%
+ {\setanchorbox
+ [#1]%
+ [target={#3},source={#4}]%
+ \hbox{\backgroundline[#2]{\white\smallinfofont\setstrut\strut target=#3 source=#4}}}
+
+\def\DemoAnchorX#1#2%
+ {\DemoAnchor{#1}{darkred} {#2}{left,top}%
+ \DemoAnchor{#1}{darkblue} {#2}{left,bottom}%
+ \DemoAnchor{#1}{darkgreen} {#2}{right,bottom}%
+ \DemoAnchor{#1}{darkyellow}{#2}{right,top}}%
+
+\startsetups framed:demo
+ \DemoAnchorX{framed:background}{left,top}%
+ \DemoAnchorX{framed:background}{right,top}%
+ \DemoAnchorX{framed:background}{left,bottom}%
+ \DemoAnchorX{framed:background}{right,bottom}%
+ \DemoAnchorX{framed:foreground}{middle}%
+\stopsetups
+
+\midaligned\bgroup
+ \framed
+ [align=normal,
+ width=.7\textwidth,
+ backgroundcolor=gray,
+ background={color,framed:background,foreground,framed:foreground}]
+ \bgroup
+ \samplefile{zapf}\par
+ \directsetup{framed:demo}%
+ \samplefile{zapf}%
+ \egroup
+\egroup
+\stopbuffer
+
+\typebuffer
+
+Those familiar with \CONTEXT\ will recognize the approach. This one basically is
+a more low level variant of layers and a high level variant of the primitives.
+Performance wise (in terms of memory usage and runtime) it sits in a sweet spot.
+
+\startlinecorrection[2*big]
+ \getbuffer
+\stoplinecorrection
+
+I played a bit with a mechanism that can store the embedded (to be anchored)
+content in a more independent way and it actually works okay. However, I'm not
+entirely sure if that solution is the best so for now it's commented. As usual it
+is also up to users to come up with demands.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% \defineanchorbox[page:background]
+% \defineanchorbox[page:foreground]
+% \defineoverlay[page:background][\overlayanchorbox{page:background}]
+% \defineoverlay[page:foreground][\overlayanchorbox{page:foreground}]
+%
+% \defineanchorboxoverlay[page]
+%
+% \setupbackgrounds[page][background={page:background,foreground,page:foreground}]
+%
+% test
+%
+% \setanchorbox[page:background]\ruledhbox
+% xoffset 200pt
+% yoffset 100pt
+% % anchors \halfwayleftlistanchorcode \halfwayrightlistanchorcode
+% {\blue DOES IT WORK}
+%
+% \setanchorbox[page:foreground]\ruledhbox
+% orientation 2
+% % anchors \halfwayleftlistanchorcode \halfwayrightlistanchorcode
+% {\red DOES IT WORK}
+%
+
+% \registeranchorbox[demo][before]\ruledhbox
+% \registeranchorbox[demo][after]\ruledhbox
+%
+% \defineanchorbox[demo]
+%
+% \startbuffer
+% \vbox
+% source 123
+% \bgroup
+% \offinterlineskip
+% \blackrule[width=4cm,height=2cm,depth=0cm,color=darkred]\par
+% \blackrule[width=4cm,height=0cm,depth=1cm,color=darkblue]\par
+% \registeranchorbox[demo][before]\ruledhbox
+% % \registeranchorbox[demo][after]\ruledhbox
+% anchors "0004 "0001
+% % anchor "00040001
+% target 123
+% orientation 1
+% {\blackrule[width=2cm,height=1cm,depth=0cm,color=darkgreen]%
+% \hskip-2cm
+% \blackrule[width=2cm,height=0cm,depth=1cm,color=darkyellow]}%
+% %
+% \smash{\box\scratchboxtwo}%
+% \egroup
+% \stopbuffer
+%
+% \typebuffer