%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 / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{Context Page Macros / Backgrounds}

\unprotect

\startmessages  dutch  library: layouts
      8: achtergronden berekenen
\stopmessages

\startmessages  english  library: layouts
      8: calculating backgrounds
\stopmessages

\startmessages  german  library: layouts
      8: berechne Hintergrund
\stopmessages

\startmessages  czech  library: layouts
      8: pocita se pozadi
\stopmessages

\startmessages  italian  library: layouts
      8: calcolo dello sfondo
\stopmessages

\startmessages  norwegian  library: layouts
      8: beregner bakgrunn
\stopmessages

\startmessages  romanian  library: layouts
      8: se calculeaza fundalurile
\stopmessages

%D \macros
%D   {recalculatebackgrounds}
%D
%D We use a couple of switches so that we can minimize the
%D amount of background calculations. The main switch is set
%D by the recalculate directive.
%D
%D \starttypen
%D \recalculatebackgrounds
%D \stoptypen
%D
%D Other modules may not directly set the switches
%D themselves.

\newif\ifnewbackground
\newif\ifsomebackground

%D For special purposes, users can question the \type
%D {*background} mode. This mode is only available when
%D typesetting the pagebody.
%D
%D \starttypen
%D \startmode[*background] ...
%D \stoptypen

\appendtoks
  \ifsomebackground \ifnewbackground \setsystemmode\v!achtergrond \fi \fi
\to \everybeforepagebody

%D \macros
%D   {addmainbackground, addtextbackground,
%D    addpagebackground, addprintbackground}
%D
%D Apart from the previously mentioned directive, the
%D interface between this module and the other modules
%D is made up by four macros that add background to parts of
%D the layout.
%D
%D \starttypen
%D \addmainbackground  <box>
%D \addtextbackground  <box>
%D \addpagebackground  <box>
%D \addprintbackground <box>
%D \stoptypen

%D To minimize calculations, we keep track of the state of the
%D background of each area. A previous implementation did
%D check each call to the background calculation macro, but
%D using an intermediate usage flag instead of testing each
%D time saves about 3\% on a run with a couple of backgrounds.
%D (On the 824 pages maps bibliography runtime went down from
%D 309 to 299 seconds.)

\def\checkbackground#1%
  {\edef\!!stringe{\??ma#1}%
   \doifelsevaluenothing{\!!stringe\c!achtergrond   }
  {\doifelsevaluenothing{\!!stringe\c!voorgrondkleur}
         {\doifelsevalue{\!!stringe\c!kader       }\v!aan\!!doneatrue
         {\doifelsevalue{\!!stringe\c!linkerkader }\v!aan\!!doneatrue
         {\doifelsevalue{\!!stringe\c!rechterkader}\v!aan\!!doneatrue
         {\doifelsevalue{\!!stringe\c!bovenkader  }\v!aan\!!doneatrue
         {\doifelsevalue{\!!stringe\c!onderkader  }\v!aan\!!doneatrue
                                                         \!!doneafalse}}}}}
                                                         \!!doneatrue}
                                                         \!!doneatrue
   \if!!donea
     \expandafter\setusage\else\expandafter\resetusage
   \fi{\??ma#1}}

\def\ifsomebackgroundfound#1%
  {\ifusage{\??ma#1}}

% \def\doifsomebackgroundelse#1#2#3%
%   {\ifusage{\??ma#1}#2\else#3\fi}

\def\doifsomebackgroundelse#1%
  {\ifusage{\??ma#1}%
     \expandafter\firstoftwoarguments
   \else
     \expandafter\secondoftwoarguments
   \fi}

%D The background mechanism falls back on the \type {\framed}
%D macro. This means that all normal frame and overlay
%D features can be used.

\def\addsomebackground#1#2#3#4% area box width height / zero test added
  {\ifsomebackgroundfound#1\ifdim#3>\zeropoint\ifdim#4>\zeropoint
     \setbox#2\vbox\localframed
       [\??ma#1]
       [\c!component=#1,
        \c!strut=\v!nee,\c!offset=\v!overlay,
        \c!breedte=#3,\c!hoogte=#4]
       {\dp#2\zeropoint\box#2}%
   \fi\fi\fi}

%D There are quite some backgrounds. At the bottom layer,
%D there is the {\em paper} background. This one is only
%D used for special purposes, like annotations to documents.

\def\addprintbackground#1%
  {\addsomebackground
     \v!papier#1\printpapierbreedte\printpapierhoogte}

%D The page backgrounds can be put behind the {\em left
%D page}, the {\em right page} or {\em each page}. As with
%D the paper background, these are calculated on each page.

\def\addpagebackground#1%
  {\doifbothsidesoverruled
     \addsomebackground\v!rechterpagina#1\papierbreedte\papierhoogte
   \orsideone
     \addsomebackground\v!rechterpagina#1\papierbreedte\papierhoogte
   \orsidetwo
     \addsomebackground\v!linkerpagina #1\papierbreedte\papierhoogte
   \od
     \addsomebackground\v!pagina       #1\papierbreedte\papierhoogte}

%D Then there are the 25 areas that make up the layout: {\em
%D top, header, text, footer, bottom} times {\em left edge,
%D left margin, text, right margin, right edge}. These are
%D only recalculated when they change or when the \type
%D {status} is set to \type {repeat}.

\newbox\leftbackground
\newbox\rightbackground

\def\addmainbackground#1% todo: dimension spec
  {\ifsomebackground
     \ifnewbackground \setbackgroundboxes \fi
     \setbox#1\vbox
       {\offinterlineskip
        \doifmarginswapelse
          {\copy\leftbackground}{\copy\rightbackground}%
        \box#1}%
   \fi}

%D Finaly there is an aditional {\em text} background, again
%D useful for special purposes only. This one is calculated
%D each time. The hidden backgrounds are not meant for users!

\newconditional\hiddenbackgroundenabled

\def\addtextbackground#1%
  {\ifconditional\hiddenbackgroundenabled
     \addsomebackground\v!verborgen#1\zetbreedte\teksthoogte % mine ! 
   \fi 
   \addsomebackground\v!tekst#1\zetbreedte\teksthoogte}

% \def\addtextbackground#1%
%   {\ifconditional\hiddenbackgroundenabled
%      \addsomebackground\v!verborgen   #1\zetbreedte\teksthoogte % mine ! 
%    \fi 
%    \doifbothsidesoverruled
%      \addsomebackground\v!rechtertekst#1\zetbreedte\teksthoogte
%    \orsideone
%      \addsomebackground\v!rechtertekst#1\zetbreedte\teksthoogte
%    \orsidetwo
%      \addsomebackground\v!linkertekst #1\zetbreedte\teksthoogte
%    \od
%      \addsomebackground\v!tekst       #1\zetbreedte\teksthoogte}

%D The next couple of macros implement the area backgrounds.
%D As said, these are cached in dedicated boxes. The offsets
%D and depth of the page are used for alignment purposes.

\newdimen\pageoffset % bleed 
\newdimen\pagedepth  

\let\pagebackgroundhoffset = \!!zeropoint
\let\pagebackgroundvoffset = \!!zeropoint
\let\pagebackgrounddepth   = \!!zeropoint

% \def\setbackgroundboxes
%   {\showmessage\m!layouts8\empty
%    \setbackgroundbox\leftbackground\relax
%    \ifdubbelzijdig
%      \setbackgroundbox\rightbackground\doswapmargins
%    \fi
%    \doifnot\@@mastatus\v!herhaal{\global\newbackgroundfalse}}

%D We need a bit more clever mechanism in order to handle
%D layers well. This means that we cannot calculate both
%D background at the same time since something may have
%D changed halfway a page. 

\chardef\newrightbackground0
\chardef\newleftbackground 0

\def\recalculatebackgrounds
  {\global\newbackgroundtrue}

\def\setbackgroundboxes
  {\ifnewbackground
     \global\chardef\newrightbackground\plusone
     \global\chardef\newleftbackground\plusone
     \global\setbox\leftbackground\emptybox
     \global\setbox\rightbackground\emptybox
   \fi 
   \doifbothsides
     \ifcase\newleftbackground \else
       \showmessage\m!layouts8\empty
       \setbackgroundbox\leftbackground\relax
       \global\chardef\newleftbackground\zerocount
       \global\chardef\newrightbackground\zerocount
     \fi
   \orsideone
     \ifcase\newleftbackground \else
       \showmessage\m!layouts8\empty
       \setbackgroundbox\leftbackground\relax
       \global\chardef\newleftbackground\zerocount
      %\global\chardef\newrightbackground\zerocount
     \fi
   \orsidetwo
     \ifcase\newrightbackground \else
       \showmessage\m!layouts8\empty
       \setbackgroundbox\rightbackground\doswapmargins
       \global\chardef\newrightbackground\zerocount
     \fi
   \od
   \ifx\@@mastatus\v!herhaal\else\global\newbackgroundfalse\fi}

\def\addmainbackground#1% todo: dimension spec
  {\ifsomebackground
     \setbackgroundboxes 
     \setbox#1\vbox
       {\offinterlineskip
        \doifmarginswapelse
          {\copy\leftbackground}
          {\copy\rightbackground}
        \box#1}%
   \fi}

\def\setbackgroundoffsets
  {\ifsomebackground \ifnewbackground 
     \global\let\pagebackgroundhoffset\!!zeropoint
     \global\let\pagebackgroundvoffset\!!zeropoint
     \global\let\pagebackgrounddepth  \!!zeropoint
     \doifsomebackgroundelse{\v!tekst\v!tekst}\donetrue\donefalse
     \ifdone\else\doifsomebackgroundelse\v!tekst\donetrue\donothing\fi
     \ifdone
       \bgroup
       \scratchdimen\getvalue{\??ma\v!pagina\c!offset}%
       \doifsomebackgroundelse{\v!boven\v!tekst}\donothing
         {\doifsomebackgroundelse{\v!onder\v!tekst}\donothing
            {\xdef\pagebackgroundhoffset{\the\scratchdimen}}}%
       \doifsomebackgroundelse{\v!tekst\v!rechterrand}\donothing
         {\doifsomebackgroundelse{\v!tekst\v!linkerrand}\donothing
            {\xdef\pagebackgroundvoffset{\the\scratchdimen}%
             \scratchdimen\getvalue{\??ma\v!pagina\c!diepte}%
             \xdef\pagebackgrounddepth{\the\scratchdimen}}}%
       \egroup
     \fi
   \fi \fi}

\appendtoks \setbackgroundoffsets \to \everybeforepagebody

\def\setbackgroundbox#1#2%
  {\global\setbox#1\vbox
     {\dontcomplain
      \calculatereducedvsizes
      \offinterlineskip
      #2\relax
      \vskip-\bovenhoogte
      \vskip-\bovenafstand
      \dodopagebodybackground\v!boven\bovenhoogte
      \vskip\bovenafstand
      \dodopagebodybackground\v!hoofd\hoofdhoogte
      \vskip\hoofdafstand
      \dodopagebodybackground\v!tekst\teksthoogte
      \vskip\voetafstand
      \dodopagebodybackground\v!voet\voethoogte
      \vskip\onderafstand
      \dodopagebodybackground\v!onder\onderhoogte
      \vfilll}%
  \smashbox#1}

\def\dodopagebodybackground#1#2%
  {\ifdim#2>\zeropoint % added, faster 
     \setbox\scratchbox\vbox to #2
       \bgroup\hbox\bgroup
         \swapmargins
         \goleftonpage
         \dododopagebodybackground\linkerrandbreedte  #2#1\v!linkerrand
         \hskip\linkerrandafstand
         \dododopagebodybackground\linkermargebreedte #2#1\v!linkermarge
         \hskip\linkermargeafstand
         \dododopagebodybackground\zetbreedte         #2#1\v!tekst
         \hskip\rechtermargeafstand
         \dododopagebodybackground\rechtermargebreedte#2#1\v!rechtermarge
         \hskip\rechterrandafstand
         \dododopagebodybackground\rechterrandbreedte #2#1\v!rechterrand
       \egroup\egroup
     \wd\scratchbox\zeropoint
     \box\scratchbox\relax
   \fi}

\def\dododopagebodybackground#1#2#3#4% width height pos pos
  {\ifsomebackgroundfound{#3#4}%
     \ifdim#2>\zeropoint\relax
       \ifdim#1>\zeropoint\relax
         \localframed
           [\??ma#3#4]
           [\c!component=#3-#4,
            \c!breedte=#1,\c!hoogte=#2,\c!offset=\v!overlay]
           {\getvalue{\??ma#3#4\c!commando}}% {\hsize=#1\vsize=#2....}
       \else
         \hskip#1%
       \fi
     \else
       \hskip#1%
     \fi
   \else
     \hskip#1%
   \fi}

%D The background mechanism is quite demanding in terms or
%D resources. We used to delay these definitions till runtime
%D usage, but since today's \TEX's are large, we now do the
%D work on forehand.
%D
%D \starttypen
%D \setupbackgrounds [settings]
%D \setupbackgrounds [paper,page,text,..] [settings]
%D \setupbackgrounds [top,...] [leftedge,...] [settings]
%D \stoptypen
%D
%D \showsetup{\y!setupbackgrounds}
%D
%D Because the number of arguments runs from one to three,
%D we need to check for it.

\def\setupbackgrounds
  {\dotripleempty\dosetupbackgrounds}

\def\dosetupbackgrounds[#1][#2][#3]%
  {\ifthirdargument
     \global\somebackgroundtrue
     \def\docommando##1%
       {\doifinsetelse{##1}{\v!papier,\v!pagina,\v!linkerpagina,\v!rechterpagina}
          {\getparameters[\??ma##1][#3]\checkbackground{##1}}
          {\def\dodocommando####1%
             {\getparameters[\??ma##1####1][#3]\checkbackground{##1####1}}%
           \processcommalist[#2]\dodocommando}}%
     \processcommalist[#1]\docommando
   \else\ifsecondargument
     \global\somebackgroundtrue
     \doifcommonelse{#1}{\v!tekst,\v!verborgen,%
                        %\v!linkertekst,\v!rechtertekst,%
                         \v!papier,\v!pagina,\v!linkerpagina,\v!rechterpagina}
       {\def\docommando##1%
          {\getparameters[\??ma##1][#2]\checkbackground{##1}}%
        \processcommalist[#1]\docommando}%
       {\setupbackgrounds
          [#1]%
          [\v!linkerrand,\v!linkermarge,\v!tekst,\v!rechtermarge,\v!rechterrand]%
          [#2]}%
   \else\iffirstargument
     \getparameters[\??ma][#1]%
   \fi\fi\fi
   \doifelsevalue{\??ma\v!pagina\c!offset}\v!overlay
     {\global\pageoffset\zeropoint}
     {\global\pageoffset\getvalue{\??ma\v!pagina\c!offset}}%
   \global\pagedepth\getvalue{\??ma\v!pagina\c!diepte}%
   \xdef\pagebackgroundoffset{\the\pageoffset}%
   \xdef\pagebackgrounddepth {\the\pagedepth }%
   \doifelse\@@mastatus\v!stop
     {\global\newbackgroundfalse}
     {\global\newbackgroundtrue }}

\let\pagebackgroundoffset\!!zeropoint
\let\pagebackgrounddepth \!!zeropoint

\appendtoks\global\newbackgroundfalse\to\everyjob

%D Each areas (currently there are $1+3+25+1=30$ of them)
%D has its own low level framed object associated.

\presetlocalframed [\??ma\v!papier]
\presetlocalframed [\??ma\v!pagina]
\presetlocalframed [\??ma\v!linkerpagina]
\presetlocalframed [\??ma\v!rechterpagina]

\copyparameters
  [\??ma\v!papier\c!kader][\??ma\v!pagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!papier\c!achtergrond][\??ma\v!pagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!pagina\c!kader][\??ma\v!pagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!pagina\c!achtergrond][\??ma\v!pagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!linkerpagina\c!kader][\??ma\v!linkerpagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!linkerpagina\c!achtergrond][\??ma\v!linkerpagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!rechterpagina\c!kader][\??ma\v!rechterpagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

\copyparameters
  [\??ma\v!rechterpagina\c!achtergrond][\??ma\v!rechterpagina]
  [\c!offset,\c!diepte,\c!straal,\c!hoek,\c!kleur,\c!raster]

%D We save some keying by defining the areas using
%D intermediate commands. The inheritance macro makes sure
%D that copies are efficient.

\def\dodocommando#1#2%
  {\copylocalframed
     [\??ma#1#2][\??ma\v!pagina]%
   \getparameters
     [\??ma#1#2]
     [\c!achtergrond=,\c!kader=,\c!kleur=,\c!raster=\@@rsraster,
      \c!onderkader=,\c!bovenkader=,\c!linkerkader=,\c!rechterkader=]%
   \inheritparameter[\??ma][#1#2\c!kleur][\v!pagina\c!kleur]%
   \inheritparameter[\??ma][#1#2\c!raster][\v!pagina\c!raster]%
   \inheritparameter[\??ma][#1#2\c!kaderkleur][\v!pagina\c!kaderkleur]%
   \inheritparameter[\??ma][#1#2\c!achtergrondkleur][\v!pagina\c!achtergrondkleur]%
   \inheritparameter[\??ma][#1#2\c!achtergrondraster][\v!pagina\c!achtergrondraster]}

%D The stand alone text area inherits from the page too.

\dodocommando\v!tekst       \empty
%dodocommando\v!linkertekst \empty
%dodocommando\v!rechtertekst\empty
\dodocommando\v!verborgen   \empty

%D We now define all 25 main areas in a row.

\def\docommando#1%
  {\dodocommando#1\v!linkerrand
   \dodocommando#1\v!linkermarge
   \dodocommando#1\v!tekst
   \dodocommando#1\v!rechtermarge
   \dodocommando#1\v!rechterrand}

\docommando\v!boven
\docommando\v!hoofd
\docommando\v!tekst
\docommando\v!voet
\docommando\v!onder

%D We need some cleanup now.

\let\dodocommando\relax \let\docommando\relax

%D We now set up the individual areas to use reasonable
%D defaults.

\setupbackgrounds
  [\c!status=\c!start]

\setupbackgrounds
  [\v!papier,\v!pagina,\v!linkerpagina,\v!rechterpagina]
  [\c!kader=\v!uit,
   \c!straal=.5\korpsgrootte,
   \c!hoek=\v!recht,
   \c!achtergrond=,
   \c!raster=\@@rsraster,
   \c!kleur=,
  %\c!kaderoffset=\getvalue{\??ma\v!pagina\c!offset},
  %\c!achtergrondoffset=\getvalue{\??ma\v!pagina\c!offset},
   \c!offset=\!!zeropoint, % later set to \v!overlay, watch out !
   \c!diepte=\!!zeropoint]

\def\docommando#1%
  {\inheritparameter[\??ma][#1\c!kaderoffset][\v!pagina\c!offset]%
   \inheritparameter[\??ma][#1\c!achtergrondoffset][\v!pagina\c!offset]}

\docommando\v!papier
\docommando\v!pagina
\docommando\v!linkerpagina
\docommando\v!rechterpagina

%D Again we clean up temporary macros.

\let\docommando\relax

%D The hidden layer can be populated by extending the 
%D following comma separated list. This only happens in core
%D modules. 

% todo page-2   .. page+2   achter pagina -> bleed 
%      spread-2 .. spread+2 achter spread -> spread (repeat 2 times)

\def\enablehiddenbackground
  {\global\settrue\hiddenbackgroundenabled
   \global\somebackgroundtrue 
   \recalculatebackgrounds}   

\def\disablehiddenbackground
  {\global\setfalse\hiddenbackgroundenabled}

\def\hiddenbackground
  {\v!tekst-2,\v!tekst-1,\v!voorgrond,\v!tekst+1,\v!tekst+2}

\setupbackgrounds
  [\v!verborgen]
  [\c!achtergrond=\hiddenbackground]

% The next series is used in local (for instance floating) 
% backgrounds. 

\presetlocalframed
  [\??ma\v!lokaal]

\def\localbackground
  {\v!lokaal-2,\v!lokaal-1,\v!voorgrond,\v!lokaal+1,\v!lokaal+2}

\defineoverlay[\v!lokaal-2][\positionoverlay{\v!lokaal-2}]
\defineoverlay[\v!lokaal-1][\positionoverlay{\v!lokaal-1}]
\defineoverlay[\v!lokaal+1][\positionoverlay{\v!lokaal+1}]
\defineoverlay[\v!lokaal+2][\positionoverlay{\v!lokaal+2}]

\def\addlocalbackgroundtobox
  {\ifconditional\hiddenbackgroundenabled
     \expandafter\doaddlocalbackground
   \else
     \resetglobal \expandafter\gobbleoneargument
   \fi}

% \def\doaddlocalbackground#1%
%   {\scratchdimen\dp#1%
%    \edef\next
%      {\noexpand\redoglobal\wd#1\the\wd#1%
%       \noexpand\redoglobal\ht#1\the\ht#1%
%       \noexpand\dodoglobal\dp#1\the\dp#1}%
%    \dp#1\zeropoint
%    \redoglobal\setbox#1\hbox
%      {\localframed
%         [\??ma\v!lokaal]
%         [\c!kader=\v!uit,
%          \c!offset=\v!overlay,
%          \c!achtergrond=\localbackground]%
%         {\registerMPlocaltextarea{\box#1}}}%
%    \ifdim\naturalfloatdepth>\zeropoint % maybe take difference 
%      \redoglobal\setbox#1\hbox{\lower\scratchdimen\box#1}%
%    \fi 
%    \doglobal\increment\localpositionnumber % afterwards ! 
%    \next}

\def\doaddlocalbackground#1%
  {\edef\next
     {\noexpand\redoglobal\wd#1\the\wd#1%
      \noexpand\redoglobal\ht#1\the\ht#1%
      \noexpand\dodoglobal\dp#1\the\dp#1}%
   \dodoglobal\setbox#1\hbox
     {\localframed
        [\??ma\v!lokaal]
        [\c!component=local,
         \c!kader=\v!uit,
         \c!offset=\v!overlay,
         \c!achtergrond=\localbackground]%
        {\registerMPlocaltextarea{\box#1}}}%
   \next
   \doglobal\increment\localpositionnumber\relax} % afterwards ! 

% 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

%D Because we haven't really set up backgrounds yet, we set
%D the main efficiency switch to false.

\somebackgroundfalse

\protect \endinput

%D Removed \citeer {features}:
%D
%D \starttypen
%D \startinteractie
%D \doifmarginswapelse
%D   {\copy\leftbackground}
%D   {\copy\rightbackground}%
%D \stopinteractie
%D \stoptypen
%D
%D \starttypen
%D \edef\setpagebackgrounddepth%
%D   {\dp#2=\the\dp#2}%
%D \setbox#2=\vbox\localframed[\??ma#1]{...}
%D \setpagebackgrounddepth
%D \stoptypen
