%:skip
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Part of the ptx2pdf macro package for formatting USFM text
% copyright (c) 2022 by SIL International
% written by David Gardner
%
% Permission is hereby granted, free of charge, to any person obtaining  
% a copy of this software and associated documentation files (the  
% "Software"), to deal in the Software without restriction, including  
% without limitation the rights to use, copy, modify, merge, publish,  
% distribute, sublicense, and/or sell copies of the Software, and to  
% permit persons to whom the Software is furnished to do so, subject to  
% the following conditions:
%
% The above copyright notice and this permission notice shall be  
% included in all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  
% NONINFRINGEMENT. IN NO EVENT SHALL SIL INTERNATIONAL BE LIABLE FOR  
% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  
% CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
% WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
% Except as contained in this notice, the name of SIL International  
% shall not be used in advertising or otherwise to promote the sale,  
% use or other dealings in this Software without prior written  
% authorization from SIL International.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Border processing
\newbox\b@rderbox
\newif\ifhorizb@rder
\newif\ifhasb@rder
\newif\iftextborder % Set by a hook on \id processing, whether textborders are in use or not.
\def\borderstylelist{plain, double}

\let\b@drcol\relax

%Stylesheet 
\def\BorderWidth        #1\relax{\initc@t\setsbp@ram{borderwidth}{#1}}
\def\BorderColour       #1\relax{\initc@t\x@\checkh@x #1\end\setsbp@ram{bordercolour}{\rgb@out}}
\def\BorderStyle        #1\relax{\initc@t\ifcsname mkb@rder@#1\endcsname\setsbp@ram{borderstyle}{#1}\else\BorderRef #1\relax\fi}
\def\BorderStyleExtra   #1\relax{\initc@t\setsbp@ram{borderstyleextra}{#1}}
\def\BorderLPadding #1\relax{\initc@t\setsbp@ram{borderlpadding}{#1}}
\def\BorderRPadding #1\relax{\initc@t\setsbp@ram{borderrpadding}{#1}}
\def\BorderTPadding #1\relax{\initc@t\setsbp@ram{bordertpadding}{#1}}
\def\BorderBPadding #1\relax{\initc@t\setsbp@ram{borderbpadding}{#1}}
\def\BorderHPadding #1\relax{\initc@t\setsbp@ram{borderlpadding}{#1}\setsbp@ram{borderrpadding}{#1}}
\def\BorderVPadding #1\relax{\initc@t\setsbp@ram{bordertpadding}{#1}\setsbp@ram{borderbpadding}{#1}}
\def\BorderPadding #1\relax{\initc@t\setsbp@ram{bordertpadding}{#1}\setsbp@ram{borderbpadding}{#1}\setsbp@ram{borderlpadding}{#1}\setsbp@ram{borderrpadding}{#1}}
\def\BorderPaddingInnerOuter #1\relax{\initc@t\uppercase{\def\t@st{#1}}\setsbp@ram{borderpadinnerouter}{\t@st}}
\def\BorderLMargin #1\relax{\initc@t\setsbp@ram{borderlmargin}{#1}}
\def\BorderRMargin #1\relax{\initc@t\setsbp@ram{borderrmargin}{#1}}
\def\BorderTMargin #1\relax{\initc@t\setsbp@ram{bordertmargin}{#1}}
\def\BorderBMargin #1\relax{\initc@t\setsbp@ram{borderbmargin}{#1}}
\def\BorderHMargin #1\relax{\initc@t\setsbp@ram{borderlmargin}{#1}\setsbp@ram{borderrmargin}{#1}}
\def\BorderVMargin #1\relax{\initc@t\setsbp@ram{bordertmargin}{#1}\setsbp@ram{borderbmargin}{#1}}
\def\BorderMargin #1\relax{\initc@t\setsbp@ram{bordertmargin}{#1}\setsbp@ram{borderbmargin}{#1}\setsbp@ram{borderlmargin}{#1}\setsbp@ram{borderrmargin}{#1}}
\def\BorderMarginInnerOuter #1\relax{\initc@t\uppercase{\def\t@st{#1}}\setsbp@ram{bordermarginnerouter}{\t@st}}
\let\BorderColor=\BorderColour%for Americans
\def\Border	#1\relax{\initc@t\x@\p@rseBorder#1 \relax \relax}
\def\BorderFillColour #1\relax{\initc@t\x@\checkh@x #1\end\setsbp@ram{borderfillcolour}{\rgb@out}}
\let\BorderFillColor\BorderFillColour
\def\BorderLineWidth #1\relax{\initc@t\setsbp@ram{borderlinewidth}{#1}} % linewidth for double border (or ornament)
\def\BorderRef #1\relax{\initc@t\setsbp@ram{borderref}{#1}\xdef\dep@ndlist{\ifx\empty\dep@ndlist\else\dep@ndlist,\fi\c@tprefix\m@rker[\ds@ffix]}}%\x@\xdef\csname border@deps-#1\endcsname{\ifcsname border@deps-#1\endcsname\csname border@deps\endcsname,\fi\m@rker}}
\def\SetBorder #1\relax{\Marker bdr-#1\relax}

\def\bc@lsetup{%
  \ifx\b@drcol\relax
    \def\bc@l{}\def\endbc@l{}%
    \let\thinlinest@ndard\tls@black
  \else
    \ifx\b@drcol\fill@none
      \def\bc@l{}\def\endbc@l{}%
      \let\thinlinest@ndard\tls@nochk
    \else
      \x@\chk@colortype\b@drcol\E
      \def\bc@l{\special{color push rgb \b@drcol}}\def\endbc@l{\special{color pop}}%
    \fi
  \fi
}

\def\chk@colortype#1 #2 #3\E{%
  \ifdim #1 pt = #2pt \ifdim #2 pt = #3 pt \ifdim #1pt=0pt
        \let\thinlinest@ndard\tls@black
      \else\ifdim #1pt=1pt
          \let\thinlinest@ndard\tls@white % 1 1 1 = White
        \else
          \let\thinlinest@ndard\tls@grey % Grey / gray, depending on your spelling preferences
      \fi\fi
    \else
      \let\thinlinest@ndard\tls@colour % Colour
    \fi
  \else
    \let\thinlinest@ndard\tls@colour % Colour
  \fi
} 

\newdimen\minblackline \minblackline=0.25pt
\newdimen\mincolourline \mincolourline=0.5pt
\newdimen\minwhiteline \minwhiteline=0.5pt
\def\OverThinRule{warn}
\def\OverThinCurve{warn}
\newdimen\mingreyline 
\def\thinlinecheck#1#2#3#4{%
  \ifx\thinlinest@ndard\tls@nochk\else\ifdim #1#2 =0pt\else 
    \ifdim #1#2 < \csname min\thinlinest@ndard line\endcsname\relax
      \x@\let\x@\@@rule\csname OverThin\thinlin@type\endcsname
      \ifcsname overthin@\@@rule\endcsname
        \csname overthin@\@@rule\endcsname{#1}{#2}{#3}{#4}%
      \else
        \message{!! Undefined action '\@@rule' wanted by \msl@sh OverThin\thinlin@type. (#3) near \c@rref. (#4 = #1#2 < \the\csname min\thinlinest@ndard line\endcsname - #4) Issue ignored!}%
      \fi
    \fi
  \fi\fi
}

\def\overthin@fix#1#2#3#4{% If #2 is a space, then use = assignment, else use edef, (maybe with units)
  %\tracingassigns=1
  \def\tmp{#2}\ifx\tmp\empty
    \edef#1{\the\csname min\thinlinest@ndard line\endcsname}%
  \else
    \ifx\tmp\space
      #1=\csname min\thinlinest@ndard line\endcsname
    \else\ifx\tmp\@pt@
        \edef#1{\strip@pt{\dimexpr \csname min\thinlinest@ndard line\endcsname \relax}}%
      \else
        % TODO! Generic unit conversion? Fortunately not needed so far
        \message{!! The \thinlinest@ndard\space\thinlin@type\space specified for #3 is thinner than the supplied limit (#4 = #1#2 < \the\csname min\thinlinest@ndard line\endcsname) near \c@rref. Cannot fix because of unexpected units.}%
    \fi\fi
  \fi
  %\tracingassigns=0
}
\gdef\overthin@warn#1#2#3#4{%
  \message{The \thinlinest@ndard\space\thinlin@type\space specified for #3 is thinner than the supplied limit (#4 = #1#2 < \the\csname min\thinlinest@ndard line\endcsname) near \c@rref}%
}
\gdef\overthin@warnfix#1#2#3#4{%
  \overthin@warn{#1}{#2}{#3}{#4}%
  \overthin@fix{#1}{#2}{#3}{#4}%
}
\gdef\overthin@error#1#2#3#4{%
  \errmessage{The \thinlinest@ndard\space\thinlin@type\space specified for #3 is thinner than the supplied limit (#4 = #1#2 < \the\csname min\thinlinest@ndard line\endcsname) near \c@rref}%
}
\def\overthin@ignore#1#2#3#4{}

\def\mkb@rder{%Put a simple border around a box
  \bc@lsetup
  \dimen0=\b@rderbox@height \advance\dimen0 by \dimexpr -\b@drwidth pt  * \b@drvsides\relax
  \dimen1=0pt
  \setbox\b@rderbox\vbox to \b@rderbox@height{\baselineskip=0pt \lineskip=0pt \lineskiplimit=0pt \hsize=\b@rderbox@width\relax\bc@l
    \ifx\b@drtop\tr@e\trace{eb}{Drawing Border:top \b@rderbox@width}\hbox{\vrule height\b@drwidth pt  width \b@rderbox@width}\fi%
    \hbox to \b@rderbox@width{%
      \ifx\b@drleft\tr@e\trace{eb}{Drawing Border:left \the\dimen0+\the\dimen1}%
        \vrule width \b@drwidth pt  height \dimen0 depth \dimen1 
      \fi
    \hss
      \ifx\b@drright\tr@e\trace{eb}{Drawing Border:right \the\dimen0+\the\dimen1}%
        \vrule width \b@drwidth pt  height \dimen0 depth \dimen1
      \fi
    }\vss
    \ifx\b@drbottom\tr@e\trace{eb}{Drawing Border:bottom}\hbox{\vrule height\b@drwidth pt  width \b@rderbox@width}\fi
\endbc@l}%
}

\def\mkb@rder@none{\setbox\b@rderbox\vbox to \b@rderbox@height{}}

\def\ch@ckiftextborderadj{\trace{et}{ch@ckiftextborder \c@rrdstat: \ifm@rksonpage marks\fi, \ifb@dy body\fi, \pretextb@rderskip, \posttextb@rderskip}%
  \tempfalse\ifm@rksonpage
  \ifdim 0pt < \dimexpr \pretextb@rderskip + \posttextb@rderskip\relax
    \temptrue
  \fi
 \fi
}

\xdef\mxpretextb@rderskip{0pt}%
\xdef\mxtextb@dr@top@pad{0pt}%
\def\s@ttextb@rderdims{%Called per book \id, **during processing**
  \trace{et}{s@ttextb@rderdims \c@rrdstat}%
  \let\stb@dstat\c@rrdstat
  \testm@rkerexists{textborder}%
  \iftemp
    \t@stpublishability{textborder}%
    \ifn@npublishable
      \tempfalse
      \ifdiglot\ifx\TextBorderColumns\empty\else\if\c@rrdstat L\relax\else      \def\c@rrdstat{L}%
        \t@stpublishability{textborder}%
        \ifn@npublishable\else
          {\let\ds@ffix\stb@dstat
          \setp@ram{properties}{textborder}{publishable}}% Override normal setting
          \let\c@rrdstat\stb@dstat
          \remember@xists{textborder\stb@dstat}%
          \remember@xists{id:\id@@@|textborder\stb@dstat}%
          \remember@xists{cat:\id@@@|textborder\stb@dstat}%
          \should@xist{cat:\id@@@|}{textborder}%
          \setpossParams{textborder}{textborder}%
          \let\pptmp\p@ssParams
          \setpp@name{cat:\id@@@|textborder}%
          \trace{sC}{Breaking normal parameter rules for \pp@name (\pptmp)}\x@\global\x@\let\csname \pp@name\endcsname\undefined%Invalidate old cache for simple version
          \x@\xdef\csname \pp@name\endcsname{textborder\stb@dstat,textborderL,textborder,\pptmp}%
          \temptrue
        \fi
      \fi\fi\fi
    \fi
  \fi
  \let\c@rrdstat\stb@dstat
  \iftemp\bgroup
      \def\sb@rmarker{textborder}%
      \@get@Vborder@style@params
      \ch@ckhasb@rder
      \@prepVb@rderdims
      \ifhasb@rder
        \global\textbordertrue
        \getsbp@ram{spacebefore}%
        \xdef\pretextb@rderskip{\the\dimexpr \ifx\p@ram\relax 0pt\else \p@ram\verticalsp@ceunit\fi + \b@dr@top@pad\relax}%
        \ifdim\b@dr@bot@pad > \mxtextb@dr@top@pad
          \global\let\mxtextb@dr@top@pad\b@dr@top@pad
        \fi
        \ifdim\pretextb@rderskip > \mxpretextb@rderskip
          \global\let\mxpretextb@rderskip\pretextb@rderskip
        \fi
        \getsbp@ram{spaceafter}%
        \xdef\posttextb@rderskip{\the\dimexpr \ifx\p@ram\relax 0pt\else \p@ram\verticalsp@ceunit\fi + \b@dr@bot@pad\relax}%
        \global\let\textb@dr@bot@pad\b@dr@bot@pad
        \global\let\textb@dr@top@pad\b@dr@top@pad
        \ifx\TextBorderColumns\empty\else %If we're bordering individual columns...
          \@get@Hborder@style@params
          \@prepHb@rderdims
          \let\col@do\ch@ckcol@border
          \x@\each@col\TextBorderColumns \E
        \fi
      \else
        \xdef\pretextb@rderskip{0pt}%
        \xdef\posttextb@rderskip{0pt}%
      \fi
      \trace{et}{Set textborder pre/post dimensions to \pretextb@rderskip / \posttextb@rderskip}%
    \egroup
  \else
    \ifdiglot\else
      \xdef\pretextb@rderskip{0pt}%
      \xdef\posttextb@rderskip{0pt}%
    \fi
    \trace{et}{No textborder (\c@rrdstat). Pre/post dimensions to \pretextb@rderskip / \posttextb@rderskip}%
  \fi
  \let\c@rrdstat\stb@dstat
}
\addtoidhooks{\s@ttextb@rderdims}% 
\newcount\TextBorderMode % 0 old normal. 1. - diglots skip introductions 2. Diglots use full-width introductions
\TextBorderMode=1 % Sane default
\def\doTextB@rder#1{% Put border around box #1
  \testm@rkerexists{textborder}%
  \iftemp
    \trace{et}{textborder style exists \c@rrdstat}%
    \t@stpublishability{textborder}%
    \ifn@npublishable\else
      \ifnum\pageno>0\edef\t@st{\botmark}%
        \trace{et}{Botmark:\t@st, \the\BodyColumns/\the\IntroColumns, m@rksonpage\ifm@rksonpage true\else false\fi}%
        \ifx\t@st\intr@ \tempfalse\fi
        \ifx\t@st\t@tle\ifnum\BodyColumns=\IntroColumns \else \tempfalse\fi\fi
        \ifbeenb@dy\else \tempfalse\fi
        \ifm@rksonpage\else\tempfalse\fi
        \ifx\t@st\empty\tempfalse\fi
        \iftemp
          \bgroup 
            \ifversion{6}{\setbox#1\vbox{\box#1\kern\fb@bpadding}}{}%
            \def\sb@rmarker{textborder}%
            \trace{et}{Making page border for box #1 (page \the\pageno [\t@st]), \the\ht#1+\the\dp#1x\the\wd#1}%
            \S@tCat{\id@@@}%
            \get@border@style@params
            %\let\b@drtop\tr@e\let\b@drbottom\tr@e
            %\let\b@drleft\tr@e\let\b@drright\tr@e
            %\hasb@rdertrue
            \prepb@rderdims
            \prepb@rderbox{#1}%
            \ifhasb@rder
              \dob@rder
              %\vbox to 0pt{\vskip-\b@dr@top@pad\hbox to 0pt{\hskip-\b@dr@left@pad\box\b@rderbox\hss}\vss}%
              \global\setbox#1\vbox to \ht#1{\baselineskip=0pt \lineskiplimit=0pt \kern\pretextb@rderskip\vbox to 0pt{\vskip-\b@dr@top@pad\hbox to 0pt{\hskip-\b@dr@left@pad\box\b@rderbox\hss}\vss}\box#1\vskip\posttextb@rderskip}%
            \fi
          \egroup
        \fi
      \fi
    \fi
  \fi
}

\let\mkb@rder@plain\mkb@rder
\def\d@ublesetup{%
  \bc@lsetup
  \ifx\b@drlinewidth\relax
    \edef\b@drlinewidth{\strip@pt{\dimexpr \b@drwidth pt /3\relax}}% Use pt for division.
    \let\b@drfillwidth\b@drlinewidth
    \edef\@thinlinedesc{BorderLineWidth not supplied. 1/3 of Borderwidth}\let\@thinlinedescF\@thinlinedesc
  \else
    \edef\@thinlinedesc{BorderLineWidth supplied}\def\@thinlinedescF{Remainder of BorderWidth after lines subtracted}%
    \edef\b@drfillwidth{\strip@pt{\dimexpr \b@drwidth pt  - 2\dimexpr \b@drlinewidth pt  \relax\relax}}%
    %\edef\b@drwidth{\strip@pt{\dimexpr \b@drlinewidth pt \relax}}%
  \fi
  \ifdim \b@drfillwidth pt<0pt \let\b@drfillcolour\fill@none\fi
  \temptrue
  \ifx\b@drfillcolour\relax\tempfalse
  \else\ifx\b@drfillcolour\fill@none\tempfalse\fi
  \fi
  \iftemp 
    \def\fc@l{\special{color push rgb \b@drfillcolour}}\def\endfc@l{\special{color pop}}%
  \else \def\fc@l{}\def\endfc@l{}%
  \fi
}
\x@\def\csname drawzrule-double\endcsname{%
  \getp@ram{borderfillcolour}{zrule}{\styst@k}\let\b@drfillcolour\p@ram
  \getp@ram{borderlinewidth}{zrule}{\styst@k}\let\b@drlinewidth\p@ram
  \ifx\b@drfillcolour\relax
    \let\b@drfillcolour\fill@none
  \fi
  \ifx\b@drlinewidth\undefined
    \let\b@drlinewidth\relax
  \fi
  \edef\b@drwidth{\strip@pt{\dimexpr \rule@thk\relax}}%
  %\tracingassigns=1
  \d@ublesetup % this sets b@drlinewidth if it's not been defined yet.
  \let\thinlin@type\tlt@R % Rule, not Curve
  \thinlinecheck{\b@drlinewidth}{pt}{double-rule zrule (outer lines)}{\@thinlinedesc}%
  %\tracingassigns=0
  \hbox{\raise \rule@adjust\hbox to \hsize{\hskip\leftskip\ifx\rule@pos\@lignLeft\else\hfil\fi
    \vbox{\baselineskip=0pt \lineskiplimit=0pt \hbox{\bc@l\vrule height \b@drlinewidth pt  depth 0pt width \rule@wid \endbc@l}%
      \ifx\b@drfillcolour\fill@none\vskip\b@drfillwidth pt \else
        \thinlinecheck{\b@drfillwidth}{pt}{double-rule zrule (fill)}{\@thinlinedescF}%
        \hbox{\fc@l\vrule height \b@drfillwidth pt depth 0pt width \rule@wid \endfc@l}%
      \fi%
      \hbox{\bc@l\vrule height \b@drlinewidth  pt depth 0pt width \rule@wid \endbc@l}}%
    \ifx\rule@pos\@lignRight\else\hfil\fi\hskip\rightskip}}%
    %\showbox0
}
\def\mkb@rder@double{%
  \d@ublesetup
  \let\thinlin@type\tlt@R % Rule, not Curve
  \thinlinecheck{\b@drlinewidth}{pt}{double-rule border (outer line)}{\@thinlinedesc}%
  \thinlinecheck{\b@drfillwidth}{pt}{double-rule border (fill)}{\@thinlinedescF}%
  \dimen0=\b@rderbox@height \advance\dimen0 by \dimexpr -\b@drlinewidth pt  * \b@drvsides\relax %Inner vertical
  \dimen1=\dimen0 \advance\dimen1 by \dimexpr -\b@drfillwidth pt  * \b@drvsides\relax %Fill vertical
  \dimen2=\dimen1 \advance\dimen2 by \dimexpr -\b@drlinewidth pt  * \b@drvsides\relax %Outer vertical
  \dimen3=\b@rderbox@width\advance\dimen3 by \dimexpr -\b@drlinewidth pt  * \b@drhsides\relax % Fill width
  \dimen4=\dimen3\advance\dimen4 by \dimexpr -\b@drfillwidth pt  * \b@drhsides\relax %Inner horiz length
  \trace{eb}{Borders: \b@rderbox@width - \b@drlinewidth pt   =\the\dimen3, \b@rderbox@height - }%
  \dimen5=\dimexpr \b@drfillwidth pt  + \b@drlinewidth pt \relax
  \setbox\b@rderbox\vbox to \b@rderbox@height{\baselineskip=0pt \lineskip=0pt \lineskiplimit=0pt \hsize=\b@rderbox@width
    \ifx\b@drtop\tr@e
      \hbox to \b@rderbox@width{\bc@l\vrule height \b@drlinewidth pt  width \b@rderbox@width \endbc@l}%
      \ifx\b@drfillcolour\fill@none\kern\b@drfillwidth pt \else
        \hbox to \b@rderbox@width{\ifx\b@drleft\tr@e\kern\b@drlinewidth pt \fi
          \fc@l\vrule height \b@drfillwidth pt  width\dimen3\endfc@l
          \ifx\b@drright\tr@e\kern\b@drlinewidth pt \fi}%
      \fi
      \hbox{\ifx\b@drleft\tr@e\kern\dimen5\fi
        \bc@l
        \vrule height\b@drlinewidth pt  width\dimen4\endbc@l}%
      \kern-\dimen5
    \fi
    \hbox to \b@rderbox@width{%   
      \ifx\b@drleft\tr@e
        \bc@l\vrule width \b@drlinewidth pt  height \dimen0 \endbc@l
        \ifx\b@drfillcolour\fill@none\kern\b@drfillwidth pt \else\raise\b@drfillwidth pt \hbox{\fc@l \vrule width \b@drfillwidth pt  height \dimen1 \endfc@l}\fi%
        \raise\dimen5\hbox{\bc@l\vrule width \b@drlinewidth pt  height \dimen2 \endbc@l}%
      \fi
    \hss
      \ifx\b@drright\tr@e
        \raise\dimen5\hbox{\bc@l\vrule width \b@drlinewidth pt  height \dimen2 \endbc@l}%
        \ifx\b@drfillcolour\fill@none\kern\b@drfillwidth pt \else\raise\b@drfillwidth pt \hbox{\fc@l \vrule width \b@drfillwidth pt  height \dimen1 \endfc@l}\fi%
        \bc@l \vrule width \b@drlinewidth pt  height \dimen0 \endbc@l
      \fi
    }%
    \vss
    \ifx\b@drbottom\tr@e
      \kern -\dimen5
      \hbox to \b@rderbox@width{\ifx\b@drleft\tr@e\kern\dimen5\fi\bc@l\vrule height\b@drlinewidth pt  width\dimen4\endbc@l}%
      \ifx\b@drfillcolour\fill@none\kern\b@drfillwidth pt \else
        \hbox to \b@rderbox@width{\ifx\b@drleft\tr@e\kern\b@drlinewidth pt \fi\fc@l\vrule height \b@drfillwidth pt  width\dimen3\endfc@l}%
      \fi
      \hbox{\bc@l\vrule height \b@drlinewidth pt  width \b@rderbox@width \endbc@l}%
    \fi
  }%
}

\def\lble@d{0pt}%Bleed amounts for full pages
\def\rble@d{0pt}
\def\tble@d{0pt}
\def\bble@d{0pt}

\def\@get@Vborder@style@params{%Read the minimal set of border-related parameters for vertical spacing
  \traceifset{@get@Vborder@style@params}%
  \trace{eb}{Reading border vertical params for \c@tprefix\sb@rmarker}%
  \getsbp@ram{borderwidth}\ifx\cp@ram\relax\let\b@drwidth\defaultBorderWidth\else\let\b@drwidth\cp@ram\fi
  \getsbp@ram{bordertpadding}\ifx\cp@ram\relax\xdef\border@tpadding{\the\dimexpr \ifsb@rfillpage -\b@drwidth pt\else 0pt\fi\relax}\else\xdef\border@tpadding{\the\dimexpr \cp@ram pt \relax}\fi
  \getsbp@ram{borderbpadding}\ifx\cp@ram\relax\xdef\border@bpadding{\the\dimexpr \ifsb@rfillpage -\b@drwidth pt\else 0pt\fi\relax}\else\xdef\border@bpadding{\the\dimexpr \cp@ram pt \relax}\fi
  \getsbp@ram{bordertmargin}\ifx\cp@ram\relax\xdef\border@tmargin{0pt}\else\xdef\border@tmargin{\the\dimexpr \cp@ram pt \relax}\fi
  \getsbp@ram{borderbmargin}\ifx\cp@ram\relax\xdef\border@bmargin{0pt}\else\xdef\border@bmargin{\the\dimexpr \cp@ram pt \relax}\fi
  \getsbp@ram{bordertop}\let\b@drtop\cp@ram
  \getsbp@ram{borderbottom}\let\b@drbottom\cp@ram 
  \getsbp@ram{boxtpadding}\xdef\fb@tpadding{\the\dimexpr \ifx\cp@ram\relax \fb@dfltpad \else\cp@ram\fi pt \relax}%
  \global\let\fb@tskip\fb@tpadding
  \trace{cov}{Set fb@tskip to \fb@tskip}%
  \getsbp@ram{boxbpadding}\xdef\fb@bpadding{\the\dimexpr \ifx\cp@ram\relax \fb@dfltpad \else\cp@ram\fi pt  \relax}%
  \getsbp@ram{properties}\let\b@drprop\cp@ram
  \trace{cov}{border@Xpadding: t \border@tpadding, b \border@bpadding. fb@Xpadding: t \fb@tpadding, b \fb@bpadding}%
  \traceifcheck{@get@Vborder@style@params}%
} 

\def\@get@Hborder@style@params{%Read the border-related parameters
  \traceifset{@get@Hborder@style@params}%
  \trace{eb}{Reading border horiz params for \c@tprefix\sb@rmarker (page \the\whichp@ge)}%
  \getsbp@ram{\ifodd\whichp@ge borderoddleft\else borderevenleft\fi}\let\b@drleft\cp@ram
  \getsbp@ram{\ifodd\whichp@ge borderoddright\else borderevenright\fi}\let\b@drright\cp@ram
  \t@mptrue%Left treated as left?
  \getsbp@ram{borderpadinnerouter}\ifx\cp@ram\tr@e\ifodd\whichp@ge\else\t@mpfalse\fi\fi
  \getsbp@ram{\ift@mp borderlpadding\else borderrpadding\fi}\ifx\cp@ram\relax\xdef\border@lpadding{\ifsb@rfillpage \the\dimexpr -\b@drwidth pt\relax\else 0pt\fi}\else\xdef\border@lpadding{\cp@ram pt}\fi
  \getsbp@ram{\ift@mp borderrpadding\else borderlpadding\fi}\ifx\cp@ram\relax\xdef\border@rpadding{\ifsb@rfillpage \the\dimexpr -\b@drwidth pt\relax\else 0pt\fi}\else\xdef\border@rpadding{\cp@ram pt}\fi
  \t@mptrue%Left treated as left?
  \getsbp@ram{boxpadinnerouter}\ifx\cp@ram\tr@e\ifodd\whichp@ge\else\t@mpfalse\fi\fi
  \getsbp@ram{\ift@mp boxlpadding\else boxrpadding\fi}\xdef\fb@lpadding{\the\dimexpr \ifx\cp@ram\relax \fb@dfltpad \else\cp@ram\fi pt \relax}%
  \getsbp@ram{\ift@mp boxrpadding\else boxlpadding\fi}\xdef\fb@rpadding{\the\dimexpr \ifx\cp@ram\relax \fb@dfltpad \else\cp@ram\fi pt \relax}%
  \t@mptrue %Left treated as left?
  \getsbp@ram{bordermarginnerouter}\ifx\cp@ram\tr@e\ifodd\whichp@ge\else\t@mpfalse\fi\fi
  \getsbp@ram{\ift@mp borderlmargin\else borderrmargin\fi}\ifx\cp@ram\relax\xdef\border@lmargin{\ifsb@rfillpage \the\dimexpr -\b@drwidth pt\relax\else 0pt\fi}\else\xdef\border@lmargin{\cp@ram pt}\fi
  \getsbp@ram{\ift@mp borderrmargin\else borderlmargin\fi}\ifx\cp@ram\relax\xdef\border@rmargin{\ifsb@rfillpage \the\dimexpr -\b@drwidth pt\relax\else 0pt\fi}\else\xdef\border@rmargin{\cp@ram pt}\fi
    \trace{eb}{border@Xpadding: l \border@lpadding, r \border@rpadding. fb@Xpadding: l \fb@lpadding, r \fb@rpadding}%
  \traceifcheck{@get@Hborder@style@params}%
}
\def\get@border@style@params{%Read the border-related parameters
  \trace{eb}{Reading border params for \c@tprefix\sb@rmarker}%
  \@get@Hborder@style@params
  %\tracingassigns=1
  \@get@Vborder@style@params
  \getsbp@ram{borderlinewidth}\let\b@drlinewidth\cp@ram
  \getsbp@ram{borderfillcolour}\let\b@drfillcolour\cp@ram
  %\ifx\b@drfillcolour\relax\let\b@drfillcolour\fill@none\fi
  \getsbp@ram{borderstyle}\let\b@drstyle\cp@ram
  \getsbp@ram{bordercolour}\let\b@drcol\cp@ram
  \getsbp@ram{properties}\let\b@drprop\cp@ram
  \trace{eb}{Params finished w:\b@drlinewidth \space lrtb:\b@drleft\b@drright\b@drtop\b@drbottom}%
}
\def\b@rderparameters{borderstyle,borderwidth,borderfillcolour,bordercolour,borderlinewidth,bordertop,borderbottom,borderoddleft,borderoddright,borderevenleft,borderevenright,borderlpadding,borderrpadding,bordertpadding,borderbpadding,boxlpadding,boxrpadding,boxtpadding,boxbpadding,raise,verticalalign,borderpadinnerouter,boxpadinnerouter,borderlmargin,borderrmargin,bordertmargin,borderbmargin,bordermarginnerouter}
%raise and verticalalign are not used by borders, but is by zrules


\def\dob@rder{%
  \ifx\b@drstyle\relax
    \ifx\b@drfillcolour\relax
      \ifx\b@drlinewidth\relax
        \edef\b@drstyle{plain}%
      \else
        \trace{eb}{Border line width defined and style not specified, assume double border}%
        \edef\b@drstyle{double}%
      \fi
    \else
      \trace{eb}{Border fill defined to '\b@drfillcolour', and style not specified, assume double border}%
      \edef\b@drstyle{double}%
    \fi
  \fi
  \ifcsname mkb@rder@\b@drstyle\endcsname 
    \trace{eb}{making box for \b@drstyle: \b@rderbox@height x\b@rderbox@width }%
    \csname mkb@rder@\b@drstyle\endcsname
  \else
    \message{! Unknown borderstyle '\b@drstyle'. Known styles: \borderstylelist}%
  \fi 
}

\def\@prepVb@rderdims{% Minimal set of vertical border dimensions
  \trace{e}{@prepVb@rderdims [\c@tegory]}%
  \ifhasb@rder
    \xdef\b@dr@top@pad{\the\dimexpr \fb@tpadding  +\border@tpadding \ifx\b@drtop\tr@e  + \b@drwidth pt \fi\relax}% Distance to back-skip to insert border
    \xdef\b@dr@bot@pad{\the\dimexpr \fb@bpadding  +\border@bpadding \ifx\b@drbottom\tr@e  + \b@drwidth pt \fi \relax}%
  \else
    \ifBoxLikeBorder
%      \edef\b@dr@top@pad{\the\dimexpr \fb@tpadding  +\border@tpadding\relax}% Distance to skip / backup to insert border
      \edef\b@dr@bot@pad{\the\dimexpr \fb@bpadding  +\border@bpadding\relax}%
      \ifsb@rfillpage
        \edef\b@dr@top@pad{0pt}%
      \else  
        \xdef\b@dr@top@pad{\the\dimexpr \fb@tpadding +\border@tpadding \relax}% Distance to back-skip to insert border
      \fi
    \else
      \edef\b@dr@top@pad{0pt}%
      \edef\b@dr@bot@pad{0pt}%
    \fi
  \fi
}
\def\@prepHb@rderdims{% Minimal set of vertical border dimensions
  \ifnum 1=\ifhasb@rder 1 \else \ifBoxLikeBorder 1 \else 0 \fi\fi
    \xdef\b@dr@left@pad{\the\dimexpr \fb@lpadding  \ifx\b@drleft\tr@e +\border@lpadding + \b@drwidth pt \else \fi\relax}%
    \xdef\b@dr@right@pad{\the\dimexpr \fb@rpadding  \ifx\b@drright\tr@e +\border@rpadding + \b@drwidth pt\else \fi\relax}%
  \else
    \xdef\b@dr@left@pad{0pt}%
    \xdef\b@dr@right@pad{0pt}%
  \fi
}
\def\ch@ckhasb@rder{%
  \hasb@rderfalse\horizb@rderfalse
  \ifx\b@drleft\tr@e\hasb@rdertrue\trace{eb}{Border: left}\fi
  \ifx\b@drright\tr@e\hasb@rdertrue\trace{eb}{Border: right}\fi
  \ifx\b@drtop\tr@e\hasb@rdertrue\horizb@rdertrue\trace{eb}{Border: Top}\fi
  \ifx\b@drbottom\tr@e\hasb@rdertrue\horizb@rdertrue\trace{eb}{Border: Bottom}\fi
  \ifx\b@drprop\N@nPublish@ble\hasb@rderfalse\trace{eb}{Border: nonpublishable}\else\trace{eb}{Border property: \ifcsname b@drprop\endcsname\b@drprop\else undefined\fi}\fi
}
\newif\ifb@dr@t@os
\newif\ifb@dr@b@os
\newif\ifb@dr@l@os
\newif\ifb@dr@r@os
\def\prepb@rderdims{% Prepare all b@rderbox dimensions
  \ch@ckhasb@rder
  \@prepVb@rderdims
  \@prepHb@rderdims
  \global\b@dr@t@osfalse
  \global\b@dr@b@osfalse
  \global\b@dr@l@osfalse
  \global\b@dr@r@osfalse
  \ifhasb@rder
    %Which is on the outside, border or box? (Count equal as false, as this affects bleed)
    \ifdim\b@drwidth pt>0pt
      \ifx\b@drtop\tr@e\ifdim\border@tpadding>-\b@drwidth pt \global\b@dr@t@ostrue\fi\fi
      \ifx\b@drbottom\tr@e\ifdim\border@bpadding>-\b@drwidth pt \global\b@dr@b@ostrue\fi\fi
      \ifx\b@drleft\tr@e\ifdim\border@lpadding>-\b@drwidth pt \global\b@dr@l@ostrue\fi\fi
      \ifx\b@drright\tr@e\ifdim\border@rpadding>-\b@drwidth pt \global\b@dr@r@ostrue\fi\fi
    \fi
    %Where does is the outer-edge of the  border or box,  relative to the contents?
    \edef\b@dr@top@edge{\the\dimexpr \ifb@dr@t@os  \border@tpadding + \b@drwidth pt  \fi  +\fb@tpadding\relax}%
    \edef\b@dr@bot@edge{\the\dimexpr \ifb@dr@b@os  \border@bpadding + \b@drwidth pt \fi  +\fb@bpadding\relax}%
    %Where does the border (inner edge) - somtimes the reference point - go relative to the contents? (Subtliy different to other dims.
    \xdef\b@x@lunpad{\the\dimexpr 0pt  \ifb@dr@l@os +\border@lmargin \else\ifx\b@drleft\tr@e -\b@drwidth pt -\border@lpadding \fi\fi\relax}%
    \xdef\b@x@runpad{\the\dimexpr 0pt \ifb@dr@r@os +\border@rmargin \else\ifx\b@drright\tr@e -\b@drwidth pt -\border@rpadding \fi\fi\relax}%
    \edef\b@drhsides{\the\numexpr \ifx\b@drleft\tr@e 1 +\fi \ifx\b@drright\tr@e 1+\fi 0\relax}%
    \edef\b@drvsides{\the\numexpr \ifx\b@drtop\tr@e 1 +\fi \ifx\b@drbottom\tr@e 1+\fi 0\relax}%
    \edef\b@xintadj{\the\dimexpr \b@dr@top@edge - \b@dr@top@pad\relax}%
    \trace{eb}{BotGap:\b@dr@bot@edge, TopGap:\b@dr@top@edge, hsides:\b@drhsides, vsides:\b@drvsides}%
  \else
    \edef\b@drvsides{0}%
    \edef\b@drhsides{0}%
    \xdef\b@x@lunpad{\the\dimexpr 0pt \ifx\b@drleft\tr@e -\b@drwidth pt -\border@lpadding \else  \fi\relax}%
    \xdef\b@x@runpad{\the\dimexpr 0pt \ifx\b@drright\tr@e -\b@drwidth pt -\border@rpadding \else \fi\relax}%
    \edef\b@dr@top@edge{\fb@tpadding}%
    \edef\b@dr@bot@edge{\fb@bpadding}%
    \xdef\b@dr@left@pad{\fb@lpadding}%
    \xdef\b@dr@right@pad{\fb@rpadding}%
    \xdef\b@xintadj{0pt}%
  \fi
}

\def\prepb@rderbox#1{% Prepare b@rderbox
  \def\tmptbpart{}\def\tmpbbpart{}%
  {\ifx\b@drtop\tr@e
    \ifdim \border@tpadding < -\b@drwidth pt  
      \xdef\tmptbpart{+ \the\dimexpr \border@tpadding + \b@drwidth pt\relax}%
    \fi
  \fi
  \ifx\b@drbottom\tr@e
    \ifdim \border@bpadding < -\b@drwidth pt  
      \xdef\tmpbbpart{+ \the\dimexpr \border@bpadding + \b@drwidth pt\relax}%
    \fi
  \fi}%
  \ifhasb@rder
    \setbox\b@rderbox\vbox to \ht#1{\hsize=\wd#1\hbox to \wd#1{\hss}\vss}%Placeholder
    \dp\b@rderbox=\dp#1\relax
    \edef\b@rderbox@width{\the\dimexpr \wd\b@rderbox +\fb@lpadding+\fb@rpadding +\b@drwidth pt  *\b@drhsides+ \border@lpadding + \border@rpadding \relax}%% Final width of border artwork
    \ifsb@rfillpage 
      \edef\b@rderbox@height{\the\dimexpr\outer@ref@h@ight \tmptbpart \tmpbbpart\relax}% Final height of border artwork 
    \else 
      \edef\b@rderbox@height{\the\dimexpr \ht\b@rderbox + \fb@tpadding +\dp\b@rderbox  +\b@drwidth pt *\b@drvsides + \border@tpadding + \border@bpadding \relax}% Final height of border artwork 
    \fi
    %\edef\b@rderbox@height{\the\dimexpr \ht\b@rderbox +\fb@tpadding +\dp\b@rderbox  +\b@drwidth pt *\b@drvsides + \border@tpadding + \border@bpadding \relax}%
    \edef\b@xextadj{\the\dimexpr 0pt - \ifdim\border@bpadding< -\b@drwidth pt  \ifx\b@drbottom\tr@e\the\dimexpr \b@drwidth pt  +\border@bpadding\relax\else 0pt \fi\else 0pt \fi\relax}% b@xminadj is for inserts, so that the top of the box is at exactly the page top.
    \edef\b@rderbox@depth{\the\dimexpr \dp\b@rderbox  \ifx\b@drbottom\tr@e + \border@bpadding +\b@drwidth pt  \fi \relax}% 
    \trace{eb}{Depth b@drbox=\the\dp\b@rderbox / \the\dp\extchunkb@x }%
    \trace{e}{bbh=\b@rderbox@height, bbd=\b@rderbox@depth, bbp=\border@bpadding, btp=\border@tpadding, b@xextadj=\b@xextadj, b@xintadj=\b@xintadj}%
    %\xdef\b@xintadj{10pt}%
  \else
    \setbox\b@rderbox\box\voidb@x
    \edef\b@xextadj{0pt}%
    \edef\b@xextadj{0pt}%
  \fi
  \trace{eb}{b@rderbox: \the\ht\b@rderbox+\the\dp\b@rderbox x\the\wd\b@rderbox}%
}
\def\c@pyp@rams#1\E{% If the style has no parameter, copy the parent's one in
  \dgetp@r@m{#1}{\m@rker}%
  \ifx\p@ram\relax
    \dgetp@r@m{#1}{bdr-\p@rent}%
    \ifx\relax\p@ram
      \trace{ebi}{Parent has no #1 }%
    \else
      \trace{ebi}{Inheriting #1 (\p@ram) from parent}%
      %\tracingassigns=1
      \setp@ram{#1}{\m@rker}{\p@ram}%
      %\tracingassigns=0
    \fi
  \else
    \trace{ebi}{Keeping own version of #1 (\p@ram)}%
  \fi
}
\def\tryc@pyb@rders#1[#2]\E{%
  \def\m@rker{#1}%
  \let\tcbc@rrdstat\c@rrdstat
  \def\ds@ffix{#2}%
  \let\c@rrdstat\ds@ffix
  \dgetp@r@m{borderref}{\m@rker}%
  \trace{ebi}{Trying to process \m@rker(\ds@ffix) <-\p@ram}%
  \ifx\p@ram\relax\else
    \ifx\p@ram\empty\else
      \let\p@rent\p@ram
      \testm@rkerexists{bdr-\p@rent}%
      \iftemp
        \dgetp@r@m{borderref}{bdr-\p@rent}%
        \trace{ebi}{Has parent got a parent? "\p@ram"}%
        \temptrue
        \ifx\p@ram\empty
          \tempfalse
        \else
          \ifx\p@ram\relax
            \tempfalse
          \fi
        \fi
        \iftemp
          \trace{ebi}{Postponing \m@rker, \p@rent has not been done yet}%
          \xdef\postp@nelist{\ifx\empty\postp@nelist\else\postp@nelist,\fi\m@rker}%
        \else
          \trace{ebi}{Processing \m@rker, inheriting borders from \p@rent}%
          \let\id@\d@
          \let\d@\c@pyp@rams
          \x@\cstackdown\b@rderparameters,\E
          \setp@ram{borderref}{\m@rker}{}%
          \let\d@\id@
        \fi
      \else
        \message{! Parent style "\p@rent" referenced for borders by "\m@rker"  does not exist!}%
      \fi
    \fi
  \fi
  \let\c@rrdstat\tcbc@rrdstat
  \trace{ebi}{END.}%
}
\def\dep@ndlist{}
\def\inheritb@rders{%
  \ifx\empty\dep@ndlist
    \let\n@xt\relax
  \else
    \let\postp@nelist\empty
    \trace{ebi}{Dependency list:\dep@ndlist}%
    \let\d@\tryc@pyb@rders
    \x@\cstackdown\dep@ndlist,\E
    \trace{ebi}{Postponed:\postp@nelist}%
    \ifx\postp@nelist\empty
      \let\n@xt\relax
    \else
      \let\n@xt\inheritb@rders
    \fi
  \fi
}
  

\def\BorderTest{%A test-case for border-sizing.
  {\def\sb@rmarker{textborder}\get@border@style@params\prepb@rderdims\mark{TST:1:1}\hbox{TOP\smash{\raise\baselineskip\hbox{\raise \fb@tpadding\hbox{\vrule height 0.5pt depth 0.5pt width 10pt\raise \border@tpadding\hbox{\vrule height \b@drwidth pt depth 0pt width 2pt}}}}}\p
  \hbox{\setbox0\hbox{Ag}BOTTOM\smash{\raise -\dp0\hbox{\vrule height 0.3pt depth 0.3pt width 5pt\raise -\fb@bpadding\hbox{\vrule height 0.5pt depth 0.5pt width 10pt\raise -\border@bpadding\hbox{\vrule height 0pt depth \b@drwidth pt width 2pt}}}}}}}
