summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/page-bck.mkxl
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/page-bck.mkxl')
-rw-r--r--tex/context/base/mkiv/page-bck.mkxl715
1 files changed, 715 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/page-bck.mkxl b/tex/context/base/mkiv/page-bck.mkxl
new file mode 100644
index 000000000..9f9c5ee03
--- /dev/null
+++ b/tex/context/base/mkiv/page-bck.mkxl
@@ -0,0 +1,715 @@
+%D \module
+%D [ file=page-bck, % copied from main-001
+%D version=1997.03.31,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Backgrounds,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% Currently the text cells are fakes and no (foreground) frames which makes sense
+% as order might matter e.g. is text sticks in other cells. The page, text etc
+% areas do support foreground order change.
+
+\writestatus{loading}{ConTeXt Page Macros / Backgrounds}
+
+\unprotect
+
+% maybe use \currentframedhash here
+
+%D For special purposes, users can question the \type {*background} mode. This mode
+%D is only available when typesetting the pagebody.
+%D
+%D \starttyping
+%D \startmode[*background] ...
+%D \stoptyping
+
+\newconditional\c_page_backgrounds_new
+\newconditional\c_page_backgrounds_new_right
+\newconditional\c_page_backgrounds_new_left
+\newconditional\c_page_backgrounds_some
+
+\appendtoks
+ \ifconditional\c_page_backgrounds_some
+ \ifconditional\c_page_backgrounds_new
+ \setsystemmode\v!background
+ \fi
+ \fi
+\to \everybeforepagebody
+
+\protected\def\initializepagebackgrounds
+ {\setfalse\c_page_backgrounds_new
+ \setfalse\c_page_backgrounds_new_right
+ \setfalse\c_page_backgrounds_new_left
+ \setfalse\c_page_backgrounds_some}
+
+%D We keep calculations and checks to a minimum and also try to minimize
+%D the amount of tracing due to expansion.
+
+\let\currentotrbackground\empty
+
+%D This is the only spot where we have a low level dependency on the way
+%D parent chains are defined but we want the speed.
+
+\protected\def\page_backgrounds_check_background
+ {\ifcsname\??framed\currentotrbackground:\c!background\endcsname
+ %\edef\page_background_temp{\csname\??framed\currentotrbackground:\c!background\endcsname}%
+ \edef\page_background_temp{\lastnamedcs}%
+ \ifx\page_background_temp\empty
+ \expandafter\expandafter\expandafter\page_backgrounds_check_frame
+ \else
+ \page_backgrounds_set_yes
+ \fi
+ \else
+ \expandafter\page_backgrounds_check_frame
+ \fi}
+
+\def\page_backgrounds_check_frame
+ {\ifcsname\??framed\currentotrbackground:\c!frame\endcsname
+ %\edef\page_background_temp{\csname\??framed\currentotrbackground:\c!frame\endcsname}%
+ \edef\page_background_temp{\lastnamedcs}%
+ \ifx\page_background_temp\v!on
+ \page_backgrounds_set_yes
+ \else
+ \expandafter\expandafter\expandafter\page_backgrounds_check_leftframe
+ \fi
+ \else
+ \expandafter\page_backgrounds_check_leftframe
+ \fi}
+
+\def\page_backgrounds_check_leftframe
+ {\ifcsname\??framed\currentotrbackground:\c!leftframe\endcsname
+ %\edef\page_background_temp{\csname\??framed\currentotrbackground:\c!leftframe\endcsname}%
+ \edef\page_background_temp{\lastnamedcs}%
+ \ifx\page_background_temp\v!on
+ \page_backgrounds_set_yes
+ \else
+ \expandafter\expandafter\expandafter\page_backgrounds_check_rightframe
+ \fi
+ \else
+ \expandafter\page_backgrounds_check_rightframe
+ \fi}
+
+\def\page_backgrounds_check_rightframe
+ {\ifcsname\??framed\currentotrbackground:\c!rightframe\endcsname
+ %\edef\page_background_temp{\csname\??framed\currentotrbackground:\c!rightframe\endcsname}%
+ \edef\page_background_temp{\lastnamedcs}%
+ \ifx\page_background_temp\v!on
+ \page_backgrounds_set_yes
+ \else
+ \expandafter\expandafter\expandafter\page_backgrounds_check_topframe
+ \fi
+ \else
+ \expandafter\page_backgrounds_check_topframe
+ \fi}
+
+\def\page_backgrounds_check_topframe
+ {\ifcsname\??framed\currentotrbackground:\c!topframe\endcsname
+ %\edef\page_background_temp{\csname\??framed\currentotrbackground:\c!topframe\endcsname}%
+ \edef\page_background_temp{\lastnamedcs}%
+ \ifx\page_background_temp\v!on
+ \page_backgrounds_set_yes
+ \else
+ \expandafter\expandafter\expandafter\page_backgrounds_check_bottomframe
+ \fi
+ \else
+ \expandafter\page_backgrounds_check_bottomframe
+ \fi}
+
+\def\page_backgrounds_check_bottomframe
+ {\ifcsname\??framed\currentotrbackground:\c!bottomframe\endcsname
+ %\edef\page_background_temp{\csname\??framed\currentotrbackground:\c!bottomframe\endcsname}%
+ \edef\page_background_temp{\lastnamedcs}%
+ \ifx\page_background_temp\v!on
+ \page_backgrounds_set_yes
+ \else
+ \page_backgrounds_set_nop
+ \fi
+ \else
+ \page_backgrounds_set_nop
+ \fi}
+
+%D We don't use the commandhandler code as we want these multitude of backgrounds to be
+%D as fast as possible.
+
+\installcorenamespace{layoutbackgrounds}
+\installcorenamespace{layoutbackgroundcheck} % we need another hash as \??layoutbackgrounds<...> gets defined
+
+\def\page_backgrounds_set_yes{\expandafter\let\csname\currentotrbackground\endcsname\relax }
+\def\page_backgrounds_set_nop{\expandafter\let\csname\currentotrbackground\endcsname\undefined}
+
+\protected\def\page_backgrounds_check#1%
+ {\edef\currentotrbackground{\??layoutbackgrounds#1}%
+ \page_backgrounds_check_background}
+
+\permanent\def\doifelsesomebackground#1%
+ {\ifcsname\??layoutbackgrounds#1\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\aliased\let\doifsomebackgroundelse\doifelsesomebackground
+
+\permanent\def\doifsomebackground#1%
+ {\ifcsname\??layoutbackgrounds#1\endcsname
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+%D The background mechanism falls back on the \type {\framed} macro. This means
+%D that all normal frame and overlay features can be used.
+
+\def\page_backgrounds_add_to_box#1% area
+ {\ifcsname\??layoutbackgrounds#1\endcsname
+ \expandafter\page_backgrounds_add_to_box_indeed
+ \else
+ \expandafter\gobblefourarguments
+ \fi#1}
+
+%D We don't need the dimensions here as this is a real framed but the question is:
+%D do we indeed need a real framed or can we use a fake (i.e. no foreground, only
+%D for hidden).
+
+\def\page_backgrounds_add_to_box_indeed#1#2#3#4% area box width height / always non zero
+ {\edef\p_page_backgrounds_setups{\namedframedparameter{\??layoutbackgrounds#1}\c!setups}%
+ \ifx\p_page_backgrounds_setups\empty \else
+ \doprocesslocalsetups\p_page_backgrounds_setups % should not produce funny spaces !
+ \fi
+ % #2 has the right dimensions already
+ \setbox#2\hpack{\localbackgroundframed{\??layoutbackgrounds#1}#1#2}}% a real framed (including foreground)
+
+
+%D There are quite some backgrounds. At the bottom layer, there is the {\em paper}
+%D background. This one is only used for special purposes, like annotations to
+%D documents.
+
+\def\page_backgrounds_add_to_print#1%
+ {\page_backgrounds_add_to_box\v!paper#1\printpaperwidth\printpaperheight}
+
+%D The page backgrounds can be put behind the {\em left page}, the {\em right page}
+%D or {\em each page}. As with the paper background, these are calculated on each
+%D page.
+
+\def\page_backgrounds_add_to_paper#1%
+ {\doifbothsidesoverruled
+ {\page_backgrounds_add_to_box\v!rightpage#1\paperwidth\paperheight}%
+ {\page_backgrounds_add_to_box\v!rightpage#1\paperwidth\paperheight}%
+ {\page_backgrounds_add_to_box\v!leftpage #1\paperwidth\paperheight}%
+ \page_backgrounds_add_to_box\v!page#1\paperwidth\paperheight}
+
+%D Then there are the 25 areas that make up the layout: {\em top, header, text,
+%D footer, bottom} times {\em left edge, left margin, text, right margin, right
+%D edge}. These are only recalculated when they change or when the \type {status}
+%D is set to \type {repeat}.
+
+\newbox\leftbackground % todo: rename
+\newbox\rightbackground % todo: rename
+
+%D Finaly there is an aditional {\em text} background, again useful for special
+%D purposes only. This one is calculated each time. The hidden backgrounds are not
+%D meant for users!
+
+\newconditional\c_page_backgrounds_hidden_enabled
+
+\def\page_backgrounds_add_to_text#1%
+ {\ifconditional\c_page_backgrounds_hidden_enabled
+ \page_backgrounds_add_to_box\v!hidden#1\makeupwidth\textheight % mine !
+ \fi
+ \page_backgrounds_add_to_box\v!text#1\makeupwidth\textheight}
+
+%D The next couple of macros implement the area backgrounds. As said, these are
+%D cached in dedicated boxes. The offsets and depth of the page are used for
+%D alignment purposes.
+
+%newdimen\pageoffset % bleed
+%newdimen\pagedepth % built-in
+
+%D We need a bit more clever mechanism in order to handle layers well. This means
+%D that we cannot calculate both background at the same time since something may
+%D have changed halfway a page.
+
+%D Margin swapping has been simplified: see mkii code in case of regression.
+%D Calculation is delayed till the page anyway so the state is known.
+
+\def\page_backgrounds_recalculate
+ {\global\settrue\c_page_backgrounds_new}
+
+\def\page_backgrounds_set_boxes
+ {\ifconditional\c_page_backgrounds_new
+ \page_backgrounds_set_boxes_r
+ \fi
+ \doifbothsides
+ \page_backgrounds_set_boxes_a
+ \page_backgrounds_set_boxes_b
+ \page_backgrounds_set_boxes_c
+ \ifx\p_page_backgrounds_state\v!repeat\else
+ \global\setfalse\c_page_backgrounds_new
+ \fi}
+
+\def\page_backgrounds_set_boxes_r
+ {\global\settrue\c_page_backgrounds_new_right
+ \global\settrue\c_page_backgrounds_new_left
+ \global\setbox\leftbackground\emptybox
+ \global\setbox\rightbackground\emptybox}
+
+\def\page_backgrounds_set_boxes_a
+ {\ifconditional\c_page_backgrounds_new_left
+ % \showmessage\m!layouts8\empty
+ \page_backgrounds_set_box\leftbackground % \conditionalfalse
+ \global\setfalse\c_page_backgrounds_new_left
+ \global\setfalse\c_page_backgrounds_new_right
+ \fi}
+
+\def\page_backgrounds_set_boxes_b
+ {\ifconditional\c_page_backgrounds_new_left
+ % \showmessage\m!layouts8\empty
+ \page_backgrounds_set_box\leftbackground
+ \global\setfalse\c_page_backgrounds_new_left
+ \fi}
+
+\def\page_backgrounds_set_boxes_c
+ {\ifconditional\c_page_backgrounds_new_right
+ % \showmessage\m!layouts8\empty
+ \page_backgrounds_set_box\rightbackground
+ \global\setfalse\c_page_backgrounds_new_right
+ \fi}
+
+\def\page_backgrounds_add_to_main#1% todo: dimension spec
+ {\ifconditional\c_page_backgrounds_some
+ \page_backgrounds_set_boxes
+ \setbox#1\vpack
+ {\offinterlineskip
+ \doifelsemarginswap{\copy\leftbackground}{\copy\rightbackground}%
+ \box#1}%
+ \fi}
+
+\newdimen\pagebackgroundhoffset % THESE WILL BECOME OBSOLETE
+\newdimen\pagebackgroundvoffset
+\newdimen\pagebackgroundoffset % used elsewhere
+\newdimen\pagebackgrounddepth
+\newdimen\pagebackgroundcompensation
+
+\def\page_backgrounds_set_offsets % used in menus (we can use ifcsname's here)
+ {\ifconditional\c_page_backgrounds_some \ifconditional\c_page_backgrounds_new
+ \page_backgrounds_set_offsets_indeed % indirect, less tracing
+ \fi \fi}
+
+\def\page_backgrounds_set_offsets_indeed
+ {\ifcsname\??layoutbackgrounds\v!text\v!text\endcsname
+ \page_backgrounds_set_offsets_yes
+ \orelse\ifcsname\??layoutbackgrounds\v!text\endcsname
+ \page_backgrounds_set_offsets_yes
+ \else
+ \page_backgrounds_set_offsets_nop
+ \fi}
+
+\def\page_backgrounds_set_offsets_nop
+ {\global\pagebackgroundhoffset \zeropoint
+ \global\pagebackgroundvoffset \zeropoint
+ \global\pagebackgrounddepth \zeropoint
+ \global\pagebackgroundcompensation\zeropoint}
+
+\def\page_backgrounds_set_offsets_yes
+ {\global\pagebackgroundoffset \d_page_backgrounds_depth
+ \global\pagebackgroundcompensation\d_page_backgrounds_offset\relax
+ \ifzeropt\pagebackgroundcompensation
+ \page_backgrounds_set_offsets_nop
+ \else
+ \ifcsname\??layoutbackgrounds\v!top\v!text\endcsname
+ \global\pagebackgroundhoffset\zeropoint
+ \orelse\ifcsname\??layoutbackgrounds\v!bottom\v!text\endcsname
+ \global\pagebackgroundhoffset\zeropoint
+ \else
+ \global\pagebackgroundhoffset\pagebackgroundcompensation
+ \fi
+ \ifcsname\??layoutbackgrounds\v!text\v!rightedge\endcsname
+ \global\pagebackgroundvoffset\zeropoint
+ \global\pagebackgrounddepth \zeropoint
+ \orelse\ifcsname\??layoutbackgrounds\v!text\v!leftedge\endcsname
+ \global\pagebackgroundvoffset\zeropoint
+ \global\pagebackgrounddepth \zeropoint
+ \else
+ \global\pagebackgroundvoffset\pagebackgroundcompensation
+ \global\pagebackgrounddepth \d_page_backgrounds_depth
+ \fi
+ \fi}
+
+\appendtoks
+ \page_backgrounds_set_offsets
+\to \everybeforepagebody
+
+\newconditional\swapbackgroundmargins \settrue\swapbackgroundmargins
+
+%D The swapping here is pretty nasty! Maybe we should find another way some day but
+%D for now we tweak.
+
+\def\page_backgrounds_set_box#1% #2%
+ {\global\setbox#1\vpack
+ {\dontcomplain
+ \swapmargins
+ \ifconditional\swapbackgroundmargins
+ \doifelsemarginswap \donothing
+ {\enforced\swapcsvalues\v!rightmargin\v!leftmargin
+ \enforced\swapcsvalues\v!rightedge \v!leftedge}%
+ \fi
+ \calculatereducedvsizes
+ \offinterlineskip
+ % \ifconditional#2\relax
+ % \doswapmargins % hm, this one gets nilled in \swapmargins anyway
+ % \fi
+ \ifdim\topheight>\zeropoint
+ \kern\dimexpr-\topheight-\topdistance\relax
+ \page_backgrounds_set_box_row\v!top\topheight
+ \kern\topdistance
+ \fi
+ \ifdim\headerheight>\zeropoint
+ \page_backgrounds_set_box_row\v!header\headerheight
+ \kern\headerdistance
+ \fi
+ \ifdim\textheight>\zeropoint
+ \page_backgrounds_set_box_row\v!text\textheight
+ \fi
+ \ifdim\footerheight>\zeropoint
+ \kern\footerdistance
+ \page_backgrounds_set_box_row\v!footer\footerheight
+ \fi
+ \ifdim\bottomheight>\zeropoint
+ \kern\bottomdistance
+ \page_backgrounds_set_box_row\v!bottom\bottomheight
+ \fi
+ \vfilll}%
+ \smashbox#1}
+
+\def\page_backgrounds_set_box_row#1#2% maybe helper
+ {\setbox\scratchbox\vpack to #2
+ \bgroup\hpack\bgroup
+ \goleftonpage
+ \ifdim\leftedgewidth>\zeropoint
+ \ifcsname\??layoutbackgrounds#1\v!leftedge\endcsname
+ \page_backgrounds_set_box_cell#1\v!leftedge\leftedgewidth#2%
+ \else
+ \kern\leftedgewidth
+ \fi
+ \kern\leftedgedistance
+ \fi
+ \ifdim\leftmarginwidth>\zeropoint
+ \ifcsname\??layoutbackgrounds#1\v!leftmargin\endcsname
+ \page_backgrounds_set_box_cell#1\v!leftmargin\leftmarginwidth#2%
+ \else
+ \kern\leftmarginwidth
+ \fi
+ \kern\leftmargindistance
+ \fi
+ \ifcsname\??layoutbackgrounds#1\v!text\endcsname
+ \page_backgrounds_set_box_cell#1\v!text\makeupwidth#2%
+ \else
+ \kern\makeupwidth
+ \fi
+ \ifdim\rightmarginwidth>\zeropoint
+ \kern\rightmargindistance
+ \ifcsname\??layoutbackgrounds#1\v!rightmargin\endcsname
+ \page_backgrounds_set_box_cell#1\v!rightmargin\rightmarginwidth#2%
+ \else
+ \kern\rightmarginwidth
+ \fi
+ \fi
+ \ifdim\rightedgewidth>\zeropoint
+ \kern\rightedgedistance
+ \ifcsname\??layoutbackgrounds#1\v!rightedge\endcsname
+ \page_backgrounds_set_box_cell#1\v!rightedge\rightedgewidth#2%
+ \else
+ \kern\rightedgewidth
+ \fi
+ \fi
+ \egroup\egroup
+ \wd\scratchbox\zeropoint
+ \box\scratchbox\relax}
+
+% these are fake framed .. maybe it's nicer to honor foreground here as well
+% but it's probably a slow downer
+
+\def\page_backgrounds_set_box_cell#1#2#3#4% pos pos width height
+ {\begingroup
+ \edef\p_page_backgrounds_setups{\namedframedparameter{\??layoutbackgrounds#1#2}\c!setups}%
+ \ifx\p_page_backgrounds_setups\empty \else
+ \doprocesslocalsetups\p_page_backgrounds_setups % should not produce funny spaces !
+ \fi
+ \edef\p_page_backgrounds_command{\namedframedparameter{\??layoutbackgrounds#1#2}\c!command}%
+ \ifx\p_page_backgrounds_command\empty
+ \expandafter\page_backgrounds_set_box_cell_nop
+ \else
+ \expandafter\page_backgrounds_set_box_cell_yes
+ \fi#3#4%
+ \localbackgroundframed{\??layoutbackgrounds#1#2}{#1:#2}\scratchbox
+ \endgroup}
+
+\def\page_backgrounds_set_box_cell_nop#1#2%
+ {\setbox\scratchbox\emptyvbox
+ \wd\scratchbox#1%
+ \ht\scratchbox#2}
+
+\def\page_backgrounds_set_box_cell_yes#1#2%
+ {\setbox\scratchbox\vpack to #2{\vss\hpack to#1{\hss\p_page_backgrounds_command\hss}\vss}%
+ \dp\scratchbox\zeropoint}
+
+%D The background mechanism is quite demanding in terms or resources. We used to
+%D delay these definitions till runtime usage, but since today's \TEX's are large,
+%D we now do the work on forehand.
+%D
+%D \starttyping
+%D \setupbackgrounds [settings]
+%D \setupbackgrounds [paper,page,text,..] [settings]
+%D \setupbackgrounds [top,...] [leftedge,...] [settings]
+%D \stoptyping
+%D
+%D \showsetup{setupbackgrounds}
+%D
+%D Because the number of arguments runs from one to three, we need to check
+%D for it.
+
+\newtoks\everybackgroundssetup
+
+% \permanent\protected\def\setupbackgrounds
+% {\dotripleempty\page_backgrounds_setup}
+%
+% \def\page_backgrounds_setup
+% {\ifthirdargument
+% \expandafter\page_backgrounds_setup_double
+% \orelse\ifsecondargument
+% \expandafter\page_backgrounds_setup_single
+% \orelse\iffirstargument
+% \expandafter\page_backgrounds_setup_basics
+% \fi}
+
+\permanent\tolerant\protected\def\setupbackgrounds[#1]#*[#2]#*[#3]%
+ {\ifarguments
+ \expandafter\gobblethreeoptionals
+ \or
+ \expandafter\page_backgrounds_setup_basics
+ \or
+ \expandafter\page_backgrounds_setup_single
+ \or
+ \expandafter\page_backgrounds_setup_double
+ \fi[#1][#2][#3]}
+
+\newdimen\d_page_backgrounds_offset
+\newdimen\d_page_backgrounds_depth
+
+\appendtoks
+ \edef\p_page_backgrounds_offset{\namedframedparameter{\??layoutbackgrounds\v!page}\c!offset}%
+ \edef\p_page_backgrounds_depth {\namedframedparameter{\??layoutbackgrounds\v!page}\c!depth }%
+ \edef\p_page_backgrounds_state {\namedframedparameter{\??layoutbackgrounds }\c!state }%
+ \global\d_page_backgrounds_offset\ifx\p_offset\empty\zeropoint\else\p_page_backgrounds_offset\fi
+ \global\d_page_backgrounds_depth \ifx\p_depth \empty\zeropoint\else\p_page_backgrounds_depth \fi
+ \global\pagebackgroundoffset\d_page_backgrounds_offset\relax
+ \global\pagebackgrounddepth \d_page_backgrounds_depth \relax
+ \ifx\p_page_backgrounds_state\v!stop
+ \global\setfalse\c_page_backgrounds_new
+ \else
+ \global\settrue \c_page_backgrounds_new
+ \fi
+\to \everybackgroundssetup
+
+\def\v_page_backgrounds_double_set{\v!paper,\v!page,\v!leftpage,\v!rightpage}
+\def\v_page_backgrounds_single_set{\v!text,\v!hidden,\v!paper,\v!page,\v!leftpage,\v!rightpage}
+\def\v_page_backgrounds_common_set{\v!leftedge,\v!leftmargin,\v!text,\v!rightmargin,\v!rightedge}
+
+\protected\def\page_backgrounds_setup_double[#1][#2][#3]% if needed we can speed this up
+ {\global\settrue\c_page_backgrounds_some
+ \def\page_backgrounds_setup_step##1%
+ {\doifelseinset{##1}\v_page_backgrounds_double_set
+ {\page_backgrounds_setup_and_check{##1}{#3}}
+ {\def\page_backgrounds_setup_step_nested####1{\page_backgrounds_setup_and_check{##1####1}{#3}}%
+ \processcommacommand[#2]\page_backgrounds_setup_step_nested}}%
+ \processcommacommand[#1]\page_backgrounds_setup_step
+ \the\everybackgroundssetup}
+
+\protected\def\page_backgrounds_setup_single[#1][#2][#3]%
+ {\global\settrue\c_page_backgrounds_some
+ \doifelsecommon{#1}\v_page_backgrounds_single_set
+ {\def\page_backgrounds_setup_step##1{\page_backgrounds_setup_and_check{##1}{#2}}%
+ \processcommacommand[#1]\page_backgrounds_setup_step
+ \the\everybackgroundssetup}%
+ {\page_backgrounds_setup_double[#1][\v_page_backgrounds_common_set][#2]}}
+
+\protected\def\page_backgrounds_setup_basics[#1][#2][#3]%
+ {\setupframed[\??layoutbackgrounds][#1]%
+ \the\everybackgroundssetup}
+
+\protected\def\page_backgrounds_setup_and_check#1#2% tag settings
+ {\edef\currentotrbackground{\??layoutbackgrounds#1}%
+ \setupframed[\currentotrbackground][#2]%
+ \page_backgrounds_check_background}
+
+%D Each areas (currently there are $1+3+25+1=30$ of them) has its own low level
+%D framed object associated.
+
+\definesimplifiedframed[\??layoutbackgrounds\v!paper]
+\definesimplifiedframed[\??layoutbackgrounds\v!page]
+\definesimplifiedframed[\??layoutbackgrounds\v!leftpage]
+\definesimplifiedframed[\??layoutbackgrounds\v!rightpage]
+
+\definesimplifiedframed[\??layoutbackgrounds\v!text]
+\definesimplifiedframed[\??layoutbackgrounds\v!hidden]
+
+\definesimplifiedframed[\??layoutbackgrounds\v!top\v!leftedge]
+\definesimplifiedframed[\??layoutbackgrounds\v!top\v!leftmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!top\v!text]
+\definesimplifiedframed[\??layoutbackgrounds\v!top\v!rightmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!top\v!rightedge]
+
+\definesimplifiedframed[\??layoutbackgrounds\v!header\v!leftedge]
+\definesimplifiedframed[\??layoutbackgrounds\v!header\v!leftmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!header\v!text]
+\definesimplifiedframed[\??layoutbackgrounds\v!header\v!rightmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!header\v!rightedge]
+
+\definesimplifiedframed[\??layoutbackgrounds\v!text\v!leftedge]
+\definesimplifiedframed[\??layoutbackgrounds\v!text\v!leftmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!text\v!text]
+\definesimplifiedframed[\??layoutbackgrounds\v!text\v!rightmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!text\v!rightedge]
+
+\definesimplifiedframed[\??layoutbackgrounds\v!footer\v!leftedge]
+\definesimplifiedframed[\??layoutbackgrounds\v!footer\v!leftmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!footer\v!text]
+\definesimplifiedframed[\??layoutbackgrounds\v!footer\v!rightmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!footer\v!rightedge]
+
+\definesimplifiedframed[\??layoutbackgrounds\v!bottom\v!leftedge]
+\definesimplifiedframed[\??layoutbackgrounds\v!bottom\v!leftmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!bottom\v!text]
+\definesimplifiedframed[\??layoutbackgrounds\v!bottom\v!rightmargin]
+\definesimplifiedframed[\??layoutbackgrounds\v!bottom\v!rightedge]
+
+\setupbackgrounds
+ [\v!page]
+ [\c!offset=\zeropoint, % hm, so we need to force overlay elsewhere
+ \c!depth=\zeropoint]
+
+%D General setup:
+
+\setupbackgrounds
+ [\c!state=\c!start]
+
+%D The hidden layer can be populated by extending the following comma separated
+%D list. This only happens in core modules.
+
+% todo page-2 .. page+2 achter pagina -> bleed
+% spread-2 .. spread+2 achter spread -> spread (repeat 2 times)
+
+\permanent\protected\def\enablehiddenbackground
+ {\global\settrue\c_page_backgrounds_hidden_enabled
+ \global\settrue\c_page_backgrounds_some
+ \page_backgrounds_recalculate}
+
+\permanent\protected\def\disablehiddenbackground
+ {\global\setfalse\c_page_backgrounds_hidden_enabled}
+
+\def\hiddenbackgroundlist
+ {\v!text-2,\v!text-1,\v!foreground,\v!text+1,\v!text+2}
+
+\defineoverlay[\v!text-2][\positionregionoverlay\textanchor{\v!text-2}] % no new anchor, we share text
+\defineoverlay[\v!text-1][\positionregionoverlay\textanchor{\v!text-1}]
+\defineoverlay[\v!text+1][\positionregionoverlay\textanchor{\v!text+1}]
+\defineoverlay[\v!text+2][\positionregionoverlay\textanchor{\v!text+2}]
+
+\setupbackgrounds
+ [\v!hidden]
+ [\c!background=\hiddenbackgroundlist]
+
+%D Because we haven't really set up backgrounds yet, we set the main efficiency
+%D switch to false.
+
+\setfalse\c_page_backgrounds_some
+
+%D Sometimes you have a document wide (page) background but need to overload it
+%D locally. In such case (at least in my experience) the only values that get set
+%D are the background and backgroundcolor (if set at all). A full inheritance chain
+%D would complicate things because then we need to use named backgrounds which in
+%D turn will make this mechanism slower. I considered independent local backgrounds
+%D but that also complicates the code (not that much) but isolation means that we
+%D need to set more parameters each time. The following simple approach proabbly
+%D suits most usage.
+%D
+%D \starttyping
+%D \starttext
+%D \setupbackgrounds[page][background=color,backgroundcolor=red]
+%D \input tufte \page
+%D \setupbackgrounds[page][background=,backgroundcolor=]
+%D \input tufte \page
+%D \setupbackgrounds[page][background=color,backgroundcolor=red]
+%D \input tufte \page
+%D \pushbackground[page]
+%D \setupbackgrounds[page][background=color,backgroundcolor=green]
+%D \input tufte \page
+%D \popbackground
+%D \input tufte \page
+%D \stoptext
+%D \stoptyping
+
+\permanent\protected\def\pushbackground[#1]%
+ {\pushmacro\popbackground
+ \edef\currentotrbackground{\??layoutbackgrounds#1}%
+ \overloaded\permanent\protected\edef\popbackground
+ {\setupframed
+ [\currentotrbackground]
+ [\c!background=\namedframedparameter{\currentotrbackground}\c!background,
+ \c!backgroundcolor=\namedframedparameter{\currentotrbackground}\c!backgroundcolor]%
+ \page_backgrounds_check_background
+ \popmacro\popbackground}%
+ \setupframed
+ [\currentotrbackground]
+ [\c!background=,\c!backgroundcolor=]%
+ \page_backgrounds_check_background}
+
+\permanent\let\popbackground\relax
+
+\protect \endinput
+
+% %D The next series is used in local (for instance floating) backgrounds.
+%
+% \installsimplifiedframed{\??layoutbackgrounds\v!local}
+%
+% \getparameters
+% [\??layoutbackgrounds\v!local]
+% [\c!component=local,
+% \c!background=\localbackgroundlist]
+%
+% \def\localbackgroundlist
+% {\v!local-2,\v!local-1,\v!foreground,\v!local+1,\v!local+2}
+%
+% \defineoverlay[\v!local-2][\positionoverlay{\v!local-2}] % todo share
+% \defineoverlay[\v!local-1][\positionoverlay{\v!local-1}]
+% \defineoverlay[\v!local+1][\positionoverlay{\v!local+1}]
+% \defineoverlay[\v!local+2][\positionoverlay{\v!local+2}]
+%
+% \def\page_backgrounds_add_local_to_box
+% {\ifconditional\c_page_backgrounds_hidden_enabled
+% \expandafter\page_backgrounds_add_local_to_box_indeed
+% \else
+% \expandafter\gobbleoneargument
+% \fi}
+%
+% \def\page_backgrounds_add_local_to_box_indeed#1%
+% {\setbox#1\hbox{\localbackgroundframed{\??layoutbackgrounds\v!local}\v!local#1}%
+% \global\advance\localpositionnumber\plusone} % afterwards !
+%
+% \let\page_backgrounds_add_local_to_box\gobbleoneargument
+
+% Test how previous macro behaves with depth:
+%
+% \startcolumnset
+% \input tufte
+% \placefigure{none}{\framed[lines=5]{xxx}}
+% \input tufte
+% \placefigure{none}{\starttabulate\NC test\nc test\NC\NR\stoptabulate}
+% \input tufte
+% \stopcolumnset
+