summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/longfbox
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-12-06 23:50:41 +0000
committerKarl Berry <karl@freefriends.org>2015-12-06 23:50:41 +0000
commitcf5dbf70c6bd40b1959580618f178b3f3fee09a0 (patch)
tree38650bf9d9145a14d82b9166d119b4cf49bea5a1 /Master/texmf-dist/tex/latex/longfbox
parent8b958843c92e1dc188620b20cd04a85abe4f7fbc (diff)
longfbox (6dec15)
git-svn-id: svn://tug.org/texlive/trunk@39028 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/longfbox')
-rw-r--r--Master/texmf-dist/tex/latex/longfbox/longbox.sty853
-rw-r--r--Master/texmf-dist/tex/latex/longfbox/longfbox.sty1344
2 files changed, 2197 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/longfbox/longbox.sty b/Master/texmf-dist/tex/latex/longfbox/longbox.sty
new file mode 100644
index 00000000000..9d373895f2b
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/longfbox/longbox.sty
@@ -0,0 +1,853 @@
+%---------------------------------------------------------------------------
+% Copyright 2015 Daan Leijen, Microsoft Corporation.
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%---------------------------------------------------------------------------
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+\ProvidesPackage{longbox}[2015/12/01, Daan Leijen, Provides basic longbox that can break over pages]
+\RequirePackage{options}
+
+\@ifclassloaded{beamer}{%
+ \newcommand\lb@savefootnotes{}%
+ \newcommand\lb@restorefootnotes{}%
+}%
+{\RequirePackage{footnote}%
+ \newcommand\lb@savefootnotes{\savenotes}%
+ \newcommand\lb@restorefootnotes{\spewnotes}%
+}
+
+
+% --------------------------------------------------------
+% Debugging
+% --------------------------------------------------------
+
+\newcommand*\lb@debug[1]{%
+ \ontoggle{lb@debug}{\typeout{longbox debug: #1}}%
+}
+\newcommand*\lb@typeout[1]{%
+ \ontoggle{lb@verbose}{\typeout{longbox: #1}}%
+}
+\newcommand*\lb@warncannotsplit{%
+ \PackageWarning{longbox}{Cannot split box; it seems you are using a non-splittable contents}%
+}
+\newcommand*\lb@warnbadsplit[1]{%
+ \PackageWarning{longbox}{Bad split (underful vbox by \the#1)}%
+}
+
+
+% --------------------------------------------------------
+% Utilities for LaTeX internals
+% --------------------------------------------------------
+
+% Suppress the indentation on the following paragraph
+\providecommand\nofirstindent{\@afterindentfalse\@afterheading}
+
+% Suppress the paragraph skip on the following paragraph
+\providecommand\nofirstparskip{\addvskip{-\parskip}}
+
+% In contrast to addvspace, addvskip is not suppressed in a minipage
+\providecommand\addvskip[1]{%
+ \ifvmode
+ \ifdim\lastskip=\z@
+ \vskip #1\relax
+ \else
+ \@tempskipb#1\relax\@xaddvskip
+ \fi
+ \else\@noitemerr\fi
+}
+
+
+% Skip to 0.3\baselineskip multiple taking prevdepth into account.
+\newskip\lb@prevdepth
+\newcommand\lb@skiptobaseline{%
+ \global\lb@prevdepth=-\@m\p@\relax
+ \ifvmode
+ \ifdim\lastskip=\z@\relax
+ \ifdim\prevdepth=-\@m\p@\else
+ \dimen@\prevdepth
+ % Calculate the modulus of the previous depth with 0.3|\baselineskip| in |\dimen@|.
+ \@tempcnta\prevdepth
+ \@tempskipa=0.3\baselineskip\relax
+ \@tempcntb=\@tempskipa\relax
+ \divide \@tempcnta by \@tempcntb
+ \dimen@\prevdepth
+ \advance\dimen@ -\@tempcnta\@tempskipa
+ % Skip back by that amount, and then skip by 0.3|\baselineskip|.
+ \vskip -\dimen@
+ \vskip \@tempskipa\relax
+ \global\lb@prevdepth=\@tempskipa\relax
+ \fi
+ \fi
+ \fi
+}
+
+% unvbox a box, and return a vbox with a given background color
+% \unvcolorbox{<colorspec>}{<vboxname>}
+\newcommand\unvcolorbox[2]{%
+ \ifoptionblank{#1}{\vbox{\unvbox#2}}{%
+ \lb@debug{vcolorbox: #1}%
+ \vbox{\offinterlineskip
+ \hbox to \z@{\vbox to \z@{\optioncolor{#1}\hrule\@width\wd#2\@height\ht#2\@depth\dp#2\vss}\hss}%
+ \unvbox#2%
+ }%
+ }%
+}
+
+% create a vbox with a given background color
+\newcommand\vcolorbox[2]{%
+ \eifblank{#1}{\vbox{#2}}{%
+ \setbox\z@=\vbox{#2}\relax
+ \unvcolorbox{#1}{\z@}%
+ }%
+}%
+
+% --------------------------------------------------------
+% The following macros come from mdframed
+% --------------------------------------------------------
+
+% Determine the amount of free space left on the current page
+\newlength\lb@freevspace
+\newcommand*\lb@setfreevspace@page{%
+ \lb@debug{ determine free space}%
+ \bgroup\@nobreakfalse\addpenalty\z@\egroup%
+ \penalty\@M\relax\vskip 2\baselineskip\relax%
+ \penalty9999\relax\vskip -2\baselineskip\relax%
+ \penalty9999%
+ \ifdim\pagegoal=\maxdimen\relax%
+ \lb@freevspace=\vsize%
+ \else
+ \lb@freevspace=\dimexpr\pagegoal-\pagetotal-\parskip\relax%
+ \fi
+ \lb@debug{free space: \the\lb@freevspace, in page: \the\textheight, vsize=\the\vsize}%
+}
+
+\newcommand*\lb@shiftdim[2]{%
+ %\letoption{#1}\lb@list
+ \expandafter\lb@setheadtail@#1,\relax
+ \eifblank{\lb@head}{}{\option@invoke{/longbox/@breakat-previous}{\lb@head}}%
+ #2\option{/longbox/@breakat-previous}%
+ \eifblank{\lb@tail}{}{\let#1\lb@tail}% push back tail
+}
+\def\lb@comma{,}%
+\def\lb@setheadtail@#1,#2\relax{%
+ \def\lb@head{#1}%
+ \def\lb@tail{#2}% adds commas!
+}
+
+\newcommand*\lb@setfreevspace{%
+ \eifblank{\lb@breakat}{\lb@setfreevspace@page}{%
+ \def\lb@eject{\par}%no eject
+ \lb@extrasplit=\z@\relax%
+ \lb@shiftdim{\lb@breakat}\lb@freevspace
+ \ifdim\lb@freevspace>\z@\else\lb@setfreevspace@page\fi
+ }%
+}
+
+
+% Suppress overfull-underfull vbox messages
+\newcommand*\lb@ignorevbadness{%
+ \edef\lb@currentvbadness{\the\vbadness}%
+ \edef\lb@currentvfuzz{\the\vfuzz}%
+ \vbadness=\@M\relax%
+ \vfuzz=\maxdimen\relax%
+ \afterassignment\lb@restorevbadness
+}
+\newcommand*\lb@restorevbadness{%
+ \vbadness=\lb@currentvbadness\relax
+ \vfuzz=\lb@currentvfuzz\relax
+}
+
+
+% --------------------------------------------------------
+% The 'long vbox' (lvbox) environment collects long material
+% into a long \vbox, instead of a \hbox like a lrbox in latex.
+% The collected box can contain any box, minipage, lrbox, fbox etc,
+% but not outer-par material like a figure. Footnotes can be
+% dealt with useing lb@savefootnotes.
+%
+% The material is typeset in a \vbox according to a given width.
+% inside the environment, the boolean 'inlvbox' is true.
+%
+% \begin{lvbox}{<boxname>}{<width>}
+% --------------------------------------------------------
+
+\newif\ifinlvbox
+\newcommand\lvbox[4]{%
+ \setbox#1\vbox\bgroup
+ \begingroup
+ \inlvboxtrue
+ % reset defaults
+ \let\if@nobreak\iffalse
+ \let\if@noskipsec\iffalse
+ \let\par\@@par
+ \let\-\@dischyph
+ \let\'\@acci\let\`\@accii\let\=\@acciii
+ % set margin and linewidth
+ \leftmargin=#2\relax\rightmargin=#4\relax
+ \@totalleftmargin=\leftmargin%
+ %\leftskip=#2\relax\rightskip=#4\relax\@rightskip=#4\relax
+ \linewidth=#3\relax
+ % set primitive tex margins
+ \leftskip=\@totalleftmargin%
+ \rightskip=\rightmargin%
+ \@rightskip=\rightmargin%
+ \hsize=\dimexpr\@totalleftmargin+\linewidth+\rightmargin\relax
+ \columnwidth\hsize
+ \textwidth\hsize
+ \nofirstindent
+ %\nofirstparskip
+}
+\def\endlvbox{\endgroup\egroup}
+
+
+
+% --------------------------------------------------------
+%
+% --------------------------------------------------------
+
+
+\newsavebox\lb@headbox
+\newsavebox\lb@savebox
+\newsavebox\lb@mainbox
+
+% --------------------------------------------------------
+%
+% --------------------------------------------------------
+
+\newcommand\lb@setbaseline[1]{%
+ %\typeout{ set baseline, \the\dp#1,\the\ht#1}%
+ \ifcase\lb@baseline%
+ \relax%bottom
+ \or%middle
+ \setbox#1=\vbox{\hbox{\lower \dimexpr(\dp#1 + \ht#1)/2 - \dp#1\relax\vbox{\unvbox#1}}}%
+ \or%top
+ \setbox#1=\vtop{\unvbox#1}%
+ \fi
+ %\typeout{ .new dim: \the\dp#1, \the\ht#1}%
+}
+
+
+\@ifundefined{define@key}{}%
+ {\define@key{longbox}{options}{\options{#1}\option{/longbox/adjust-options}}}%
+
+\newcommand*\lb@render@breakbox{%
+ %\typeout{render breakbox entry (in output routine), height=\the\bb@height}%
+ \bb@restorekeys{longbox}%
+ \lb@skiptop=\ifbb@isfirst\option{/longbox/skip-top}\else\option{/longbox/skip-break-top}\fi\relax
+ \lb@skipbottom=\ifbb@islast\option{/longbox/skip-bottom}\else\option{/longbox/skip-break-bottom}\fi\relax
+ \lb@skipbreaktop=\ifbb@isfirst 0pt\else\option{/longbox/skip-break-top}\fi
+ \lb@skipbreakbottom=\ifbb@islast 0pt\else\option{/longbox/skip-break-bottom}\fi
+ %\typeout{ render: skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom, break-top=\the\dimexpr\option{/longbox/skip-bottom}}%
+ \options{%
+ /longbox/@part-height=\bb@height + \lb@skipbreaktop + \lb@skipbreakbottom,
+ /longbox/@part-width=\option{/longbox/width} + \option{/longbox/skip-left} + \option{/longbox/skip-right},%\bb@width,
+ /longbox/@part-depth=0pt,
+ /longbox/@part-needtop=\ifbb@isfirst true\else false\fi,
+ /longbox/@part-needbottom=\ifbb@islast true\else false\fi,
+ /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom,
+ /longbox/@content-box-width=\option{/longbox/width},
+ /longbox/@content-box-depth=\option{/longbox/@part-depth},
+ }%
+ %\typeout{breakbox: width=\expandafter\the\option{/longbox/width}, \the\bb@width, \the\dimexpr\option{/longbox/@part-width}}%
+ \vbox{%
+ \kern -\lb@skipbreaktop% todo: move to breakbox?
+ \option{/longbox/render}%
+ \kern -\lb@skipbreakbottom
+ }%
+}
+
+\newcommand*\lb@render@vbox[1]{%
+ \lb@debug{render vbox entry}%
+ \lb@restoreoptions
+ \lb@skiptop=\dimexpr\iftoggle{/longbox/@part-needtop}{\option{/longbox/skip-top}}{\option{/longbox/skip-break-top}}\relax
+ \lb@skipbottom=\dimexpr\iftoggle{/longbox/@part-needbottom}{\option{/longbox/skip-bottom}}{\option{/longbox/skip-break-bottom}}\relax
+ %\typeout{ skip top=\the\lb@skiptop, bottom=\the\lb@skipbottom}%
+ % add top skip while maintaining the baseline.
+ \ifdim\lb@skiptop=\z@\relax\else
+ \setbox\z@=\vtop{\unvcopy#1}%
+ \dimen@=\ht\z@
+ \setbox#1=\vbox{\offinterlineskip
+ \hrule width \z@ height \dimexpr\dimen@ + \lb@skiptop\relax depth -\dimen@
+ \unvbox#1%
+ }%
+ \fi
+ % add bottom skip while maintaining the baseline.
+ \ifdim\lb@skipbottom=\z@\relax\else
+ \dimen@=\dp#1%
+ \setbox#1=\vbox{\offinterlineskip\unvbox#1\hrule width \z@ height -\dimen@ depth \dimexpr\dimen@ + \lb@skipbottom\relax}%
+ \fi
+ \lb@setbaseline{#1}%
+ \options{%
+ /longbox/@part-height=\dimexpr\ht#1 + \dp#1\relax,
+ /longbox/@part-width=\dimexpr\wd#1 + \option{/longbox/skip-left} + \option{/longbox/skip-right}\relax,
+ /longbox/@part-depth=\dp#1,
+ /longbox/@content-box-width=\option{/longbox/width},
+ /longbox/@content-box-height=\option{/longbox/@part-height} - \lb@skiptop - \lb@skipbottom,
+ /longbox/@content-box-depth=\option{/longbox/@part-depth} - \lb@skipbottom,
+ }%
+ %\typeout{ longbox: height=\the\dimexpr\option{/longbox/@content-box-height}, outer height=\the\dimexpr\option{/longbox/@part-height}\relax}%
+ % lower the box depending on vertical alignment
+ \ifcase\option{/longbox/vertical-align/@ord}\relax
+ \@tempdima\z@
+ \or
+ %bottom
+ \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax
+ \or%middle
+ \@tempdima\dimexpr0.5\option{/longbox/@part-height} - \option{/longbox/@part-depth}\relax
+ \or%top
+ \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax
+ \or%text-bottom
+ \@tempdima\dimexpr0.3\baselineskip - \option{/longbox/@part-depth}\relax
+ \or%text-top
+ \@tempdima\dimexpr\option{/longbox/@part-height}-\option{/longbox/@part-depth}-0.7\baselineskip\relax
+ \or%super
+ \@tempdima=-0.9ex%
+ \or%sub
+ \@tempdima=0.7ex%
+ \else
+ \@tempdima\z@
+ \fi
+ \advance\@tempdima by -\option{/longbox/raise}%
+ \option@invoke{/longbox/@lower}{\@tempdima}%
+ \noindent\hbox{\lower \@tempdima\vbox{\offinterlineskip
+ \hbox to \z@{%
+ \vbox to \z@{%
+ \hbox{\lower \option{/longbox/@part-height}\vbox{\offinterlineskip{\option{/longbox/render}}}}%
+ \vss}%
+ \hss
+ }%
+ \hbox{%
+ \ifdim\option{/longbox/skip-left}=\z@\else\hskip\option{/longbox/skip-left}\fi
+ \box#1%
+ \ifdim\option{/longbox/skip-right}=\z@\else\hskip\option{/longbox/skip-right}\fi
+ %$\box#1%
+ }%
+ }}%
+}
+
+\newcommand*\lb@single@[1]{%
+ \begingroup
+ \toggletrue{/longbox/@part-needtop}%
+ \toggletrue{/longbox/@part-needbottom}%
+ \lb@render@vbox{#1}%
+ \endgroup
+}
+\newcommand*\lb@first@[1]{%
+ \begingroup
+ \toggletrue{/longbox/@part-needtop}%
+ \togglefalse{/longbox/@part-needbottom}%
+ \lb@render@vbox{#1}%
+ \lb@eject
+ \endgroup
+}
+\newcommand*\lb@middle@[1]{%
+ \begingroup
+ \togglefalse{/longbox/@part-needtop}%
+ \togglefalse{/longbox/@part-needbottom}%
+ \lb@render@vbox{#1}%
+ \lb@eject
+ \endgroup
+}
+\newcommand*\lb@last@[1]{%
+ \begingroup
+ \togglefalse{/longbox/@part-needtop}%
+ \toggletrue{/longbox/@part-needbottom}%
+ \lb@render@vbox{#1}%
+ \endgroup
+}
+
+% --------------------------------------------------------
+%
+% --------------------------------------------------------
+
+\newcommand*\lb@env@start{%
+ \ifcase\lb@textalign\relax
+ %default
+ \or\raggedright
+ \or\centering
+ \or\raggedleft
+ \else\relax% justify=default
+ \fi
+ \lb@insertbefore
+}
+
+\newcount\lb@usevbox
+\newlength\lb@width
+\newlength\lb@height
+\newlength\lb@skiptop
+\newlength\lb@skipright
+\newlength\lb@skipbottom
+\newlength\lb@skipleft
+\newlength\lb@skipbreaktop
+\newlength\lb@skipbreakbottom
+\newlength\lb@outerwidth
+\newlength\lb@extrasplit
+\newcount\lb@textalign
+\newcount\lb@baseline
+\newtoggle{lb@baselineskip}%
+\newtoggle{lb@breakable}%
+\newtoggle{lb@debug}%
+\newtoggle{lb@verbose}%
+\def\lb@breakat{}%
+\def\lb@halign{}%
+\def\lb@eject{}%
+\def\lb@insertafter{}
+\def\lb@insertbefore{}
+
+\newcommand*\lb@peekoptions[1]{%
+ % process options inside a group and just set necessary parameters
+ % this way, nested boxes don't influence each other's parameters
+ \begingroup
+ \options{#1}%
+ \option{/longbox/adjust-options}%
+ \protected@edef\lb@temp{\endgroup
+ \lb@width=\the\dimexpr\option{/longbox/width}\relax
+ \lb@height=\the\dimexpr\option{/longbox/height}\relax
+ \lb@textalign=\the\numexpr\option{/longbox/text-align/@ord}\relax
+ \lb@baseline=\the\numexpr\option{/longbox/baseline/@ord}\relax
+ \lb@skiptop=\the\dimexpr\option{/longbox/skip-top}\relax
+ \lb@skipright=\the\dimexpr\option{/longbox/skip-right}\relax
+ \lb@skipbottom=\the\dimexpr\option{/longbox/skip-bottom}\relax
+ \lb@skipleft=\the\dimexpr\option{/longbox/skip-left}\relax
+ \lb@skipbreaktop=\the\dimexpr\option{/longbox/skip-break-top}\relax
+ \lb@skipbreakbottom=\the\dimexpr\option{/longbox/skip-break-bottom}\relax
+ \lb@usevbox=\iftoggle{/longbox/use-vbox}{1}{0}\relax
+ \lb@outerwidth=\the\dimexpr\option{/longbox/outer-width}\relax
+ \lb@extrasplit=\the\dimexpr\option{/longbox/split-minimum}\relax
+ \def\noexpand\lb@insertafter{\option{/longbox/insert-after}}%
+ \def\noexpand\lb@insertbefore{\option{/longbox/insert-before}}%
+ \def\noexpand\lb@breakat{\option{/longbox/breakat}}%
+ \def\noexpand\lb@halign{\option{/longbox/height-align}}%
+ \def\noexpand\lb@eject{\option{/longbox/eject}}%
+ \noexpand\csname toggle\iftoggle{/longbox/baseline-skip}{true}{false}\endcsname{lb@baselineskip}%
+ \noexpand\csname toggle\iftoggle{/longbox/breakable}{true}{false}\endcsname{lb@breakable}%
+ \noexpand\csname toggle\iftoggle{/longbox/debug}{true}{false}\endcsname{lb@debug}%
+ \noexpand\csname toggle\iftoggle{/longbox/verbose}{true}{false}\endcsname{lb@verbose}%
+ }%
+ \lb@temp
+}
+
+\newenvironment{longbox@env}[2]{%
+ % save options
+ \lb@peekoptions{#1,#2}%
+ %
+ \ifnum\lb@usevbox=0\relax
+ \lb@debug{start breakbox}%
+ \let\bb@render\lb@render@breakbox
+ \bb@savekeys{longbox}{options={#1,#2,outer-width=\the\lb@outerwidth}}%
+ \iftoggle{lb@baselineskip}{\typeout{**insert bskip}}{\typeout{**suppress bskip}\vskip 1pt}%
+ \begin{breakbox}%
+ \ifdim\lb@skiptop=\z@\relax\else\vspace{\lb@skiptop}\fi%
+ \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax
+ \begin{bb@margins}{\lb@skipleft}{\dimen@}%
+ \else
+ \lb@debug{start vbox}%
+ \def\lb@restoreoptions{\options{#1,#2}\option{/longbox/adjust-options}}%
+ \lb@savefootnotes
+ \dimen@=\dimexpr\linewidth-\lb@skipleft-\lb@width\relax
+ \lb@debug{ width=\the\lb@width, linewidth=\the\linewidth, skipleft=\the\lb@skipleft, right=\the\lb@skipright, total right=\the\dimen@}%
+ \iftoggle{lb@baselineskip}{\lb@skiptobaseline}{\lb@prevdepth=-\@m pt}%
+ \lvbox{\lb@mainbox}{0pt}{\lb@width}{0pt}%{\lb@skipleft}{\lb@width}{\lb@skipright}%
+ \prevdepth=\lb@prevdepth
+ \fi
+ \ifcase\lb@textalign\relax
+ %default
+ \or\raggedright
+ \or\centering
+ \or\raggedleft
+ \else\relax% justify=default
+ \fi
+ \lb@insertbefore
+ \begingroup
+}{%
+ \par\unskip
+ \endgroup
+ \lb@insertafter
+ %\ifdim\lb@skipbottom=\z@\relax\else\vskip\lb@skipbottom\fi%
+ \ifnum\lb@usevbox=0\relax
+ \end{bb@margins}%
+ \ifdim\lb@skipbottom=\z@\relax\else\hrule width \z@ height \lb@skipbottom\fi%\vspace{\lb@skipbottom}\fi%
+ \iftoggle{lb@baselineskip}{}{\vskip 1sp}%
+ \end{breakbox}%
+ \lb@debug{end breakbox}%
+ \else
+ \ontoggle{lb@baselineskip}{\lb@skiptobaseline}%
+ \endlvbox%
+ \lb@debug{initial lvbox: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}%
+ \lb@processbox
+ %\setbox\lb@mainbox=\hbox{\lower \lb@skipbottom\vbox{\offinterlineskip\unvbox\lb@mainbox}}%
+ \lb@restorefootnotes
+ \lb@debug{end vbox}%
+ \fi
+}
+
+\newcommand\longbox@cmd[3]{%
+ \begingroup
+ %\options{/options/collectunknown,/longbox/scoped,#2}% set scoped options first
+ %\option{/longbox/scoped/@adjust-options}%
+ \lb@peekoptions{#1,#2}%
+ \leavevmode
+ %\setbox\lb@mainbox=\hbox{%
+ % \begingroup
+ % #3%
+ % \endgroup
+ %}%
+ \setbox\lb@mainbox=\hbox{%
+ \begingroup
+ \ifcase\lb@textalign\relax
+ %default=left
+ \or%left
+ \or\hss%center
+ \or\hss%right
+ \else%justify
+ \fi
+ \lb@insertbefore
+ #3%
+ \lb@insertafter
+ \ifnum\lb@textalign<3\relax\hss\fi% default,left,center
+ \endgroup
+ }%
+ \options{#1,#2}%
+ \ifdim\option{/longbox/width}=-1sp\relax
+ \options{/longbox/width=\wd\lb@mainbox}%set to natural width
+ \fi
+ \option{/longbox/adjust-options}%
+ % make it a vbox
+ \setbox\lb@mainbox=\vbox{\offinterlineskip%
+ \hbox to \option{/longbox/width}{%
+ \unhbox\lb@mainbox
+ }%
+ }%
+ \def\lb@restoreoptions{}%
+ \letoption{/longbox/height-align}\lb@halign
+ \lb@height=\option{/longbox/height}\relax
+ \lb@baseline=\option{/longbox/baseline/@ord}\relax
+ \lb@processbox
+ \endgroup
+}
+
+\newcommand\lb@processbox{%
+ \ifdim\lb@height<0pt\relax
+ \lb@setbaseline{\lb@mainbox}%
+ \else
+ \lb@restrictheight
+ \fi
+ \lb@typesetbox
+}
+
+\newcommand\lb@typesetbox{%
+ \ifinlvbox
+ \iftoggle{lb@breakable}{%
+ %\lb@debug{disable breakable due to nesting of long-boxes}%
+ \togglefalse{lb@breakable}%
+ }{}%
+ \fi
+ \ifhmode\lb@single@{\lb@mainbox}\else\lb@typeset\fi
+}
+
+% --------------------------------------------------------
+%
+% --------------------------------------------------------
+
+\newcommand\lb@restrictheight{%
+ \lb@typeout{restrict height to \the\lb@height}%
+ \lb@splitheight=\lb@height%
+ %lb@debug{before height split: \the\dp\lb@mainbox, \the\ht\lb@mainbox, \the\wd\lb@mainbox}%
+ \lb@splitbox
+ \ifdim\ht\lb@headbox=0pt\relax
+ %split failed.. do nothing
+ \lb@debug{could not restrict height}%
+ \else
+ % store splitted off content in the mainbox (and discard the rest)
+ \setbox\lb@mainbox\vbox{\unvbox\lb@headbox}%
+ \lb@debug{restricted height to \the\ht\lb@mainbox}%
+ \fi
+ % set baseline
+ \lb@setbaseline{\lb@mainbox}%
+ % height align
+ %\letoption{/longbox/height-align}\lb@halign
+ \eifstrequal{\lb@halign}{bottom}%
+ {\setbox\lb@mainbox=\vbox{\hbox{\vbox to \lb@splitheight{\vss\unvbox\lb@mainbox}}}}%
+ {\eifstrequal{\lb@halign}{middle}%
+ {\dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax
+ \setbox\lb@mainbox=\vbox{\hbox{%
+ \lower \dimexpr0.5\dimen@ + \dp\lb@mainbox\relax%
+ \vbox to \lb@splitheight{\vss\unvbox\lb@mainbox\vss}}}}%
+ {% default is top
+ \dimen@=\dimexpr\lb@splitheight-\ht\lb@mainbox-\dp\lb@mainbox\relax
+ \setbox\lb@mainbox=\vbox{\vtop to \lb@splitheight{\box\lb@mainbox\vss}}%
+ }%
+ }%
+}
+
+% --------------------------------------------------------
+%
+% --------------------------------------------------------
+
+\newlength\lb@neededvspace
+\newcommand\lb@typeset[1][0pt]{%
+ \iftoggle{lb@breakable}{%
+ \lb@setfreevspace
+ \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skiptop+\lb@skipbottom\relax}%
+ \lb@debug{needed: \the\lb@neededvspace, available: \the\lb@freevspace}%
+ \ifdim\lb@neededvspace<\lb@freevspace\relax
+ \lb@single@{\lb@mainbox}%
+ \else
+ \lb@typeout{longbox needs splitting}%
+ \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skiptop-\lb@skipbreakbottom\relax}%
+ \lb@splitbox
+ \ifdim\ht\lb@headbox=0pt\relax
+ % failed to split
+ \ifdim\dimexpr\lb@freevspace + #1\relax<\textheight\relax % test if we were at a fresh page.. (and prevent infinite recursion)
+ \lb@debug{failed to split the box, inserting a page break}%
+ \hrule \@height\z@ \@width\hsize
+ \lb@eject%
+ \lb@typeset[\textheight]% try again, but pass \textheight to guard against infinite recursion
+ \else
+ % on a fresh page we should not fail anymore.. just output as is..
+ % lb@warncannotsplit
+ \lb@single@{\lb@mainbox}%
+ \fi
+ \else
+ % first part success
+ \lb@typeout{first part splitted}%
+ \lb@first@{\lb@headbox}%
+ \expandafter\expandafter\expandafter\lb@typesetrest
+ \fi
+ \fi
+ }{%\else
+ \lb@debug{unbreakable box}%
+ \lb@single@{\lb@mainbox}% always directly output an unbreakable box
+ }%
+}
+
+\newcommand\lb@typesetrest{%
+ \lb@setfreevspace%
+ \setlength\lb@neededvspace{\dimexpr\ht\lb@mainbox+\dp\lb@mainbox+\lb@skipbottom+\lb@skipbreaktop\relax}%
+ \ifdim\lb@neededvspace<\lb@freevspace\relax
+ \lb@typeout{output last part of box}%
+ \lb@last@{\lb@mainbox}%
+ \else
+ \lb@debug{split box further}%
+ \setlength\lb@splitheight{\dimexpr\lb@freevspace-\lb@skipbreaktop-\lb@skipbreakbottom\relax}%
+ \lb@splitbox
+ \ifdim\ht\lb@headbox=0pt\relax
+ % failed to split
+ \lb@typeout{failed to split box!}%
+ \lb@last@{\lb@mainbox}%
+ \else
+ % middle part success
+ \lb@typeout{output middle part of box}%
+ \lb@middle@{\lb@headbox}%
+ \expandafter\expandafter\expandafter\lb@typesetrest% continue the iteration...
+ \fi
+ \fi
+}
+
+% --------------------------------------------------------
+% Split a long vbox over multiple pages.
+% This code is based on similar code in the mdframed package
+% --------------------------------------------------------
+
+\newlength\lb@splitheight
+\newlength\lb@insurance % tiny extra space to ensure our box will really fit
+\setlength\lb@insurance{1pt}
+
+% expects split target height in lb@splitheight, and splits off the start of lb@mainbox to lb@headbox
+\newcommand\lb@splitbox{%
+ \ifdim\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax>\lb@splitheight\relax
+ % the main box is larger than our target split height..
+ \ifdim\lb@extrasplit>\lb@splitheight\relax
+ % not enough space to bother
+ \lb@typeout{not enough space on page for a split}%
+ \setbox\lb@headbox=\vbox{}% empty head
+ \else
+ % try a split; lower the split height a bit so we are sure to fit
+ \advance\lb@splitheight -\lb@insurance\relax
+ \lb@debug{split: \the\lb@splitheight, from \the\dimexpr\ht\lb@mainbox + \dp\lb@mainbox\relax}%
+ \setbox\lb@savebox=\vbox{\unvcopy\lb@mainbox}% save original
+ \lb@trysplit{\lb@splitheight}%
+ \ifdim\dimexpr\ht\lb@headbox + \dp\lb@headbox>\lb@splitheight\relax
+ % too big, bad split. Try other splits.. iterate N times with 1 or 5pt less before giving up
+ \dimen@=\lb@splitheight\relax
+ \@tempcnta=\z@\relax
+ \loop
+ \ifdim\dimexpr\ht\lb@headbox+\dp\lb@headbox\relax>\lb@splitheight\relax
+ \ifnum\@tempcnta<50%
+ \advance\dimen@ by -\p@\relax% try a slightly smaller height..
+ \else
+ \advance\dimen@ by -5\p@\relax% try larger increase after 50pt..
+ \fi
+ \advance\@tempcnta by \@ne\relax
+ \lb@ignorevbadness
+ \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore
+ \lb@trysplit{\dimen@}%
+ \ifdim\lb@extrasplit<\dimen@\relax\else\lb@splitstop\fi % don't try to split too small
+ \ifnum\@tempcnta<100\relax\else\lb@splitstop\fi % and not more than N attempts
+ \repeat%
+ \ifnum\@tempcnta<100\relax
+ \dimen@=\dimexpr\lb@splitheight - \ht\lb@headbox - \dp\lb@headbox\relax
+ \ifdim\dimen@>\option{/longbox/split-badness}\relax
+ \lb@warnbadsplit{\dimen@}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \else
+ % mainbox fits in our target lb@splitheight
+ \setbox\lb@headbox=\vbox{\unvbox\lb@mainbox}%
+ \setbox\lb@mainbox=\vbox{}%
+ \fi
+}
+
+\newcommand\lb@splitstop{%
+ \lb@typeout{cannot find a good split}%
+ \let\iterate\relax
+ \lb@warncannotsplit
+ \setbox\lb@mainbox=\vbox{\unvcopy\lb@savebox}% restore
+ \setbox\lb@headbox=\vbox{}% empty head
+ \@tempcnta=\@M\relax
+}
+
+\newcommand\lb@trysplit[1]{% try to split at given height
+ \lb@typeout{try to split at: \the\dimexpr #1\relax}%
+ \lb@ignorevbadness
+ \setbox\lb@headbox=\vsplit\lb@mainbox to #1\relax%
+ \setbox\lb@headbox=\vbox{\unvbox\lb@headbox}%
+ \setbox\lb@mainbox=\vbox{\unvbox\lb@mainbox}%
+}
+
+% --------------------------------------------------------
+% The longbox environment uses options to set its options
+% --------------------------------------------------------
+
+
+% keys and styles that can be set once globally
+\options{%
+ /longbox/.new family,
+}%
+
+\options{/longbox,%
+ % computed
+ @part-needtop/.new toggle,
+ @part-needbottom/.new toggle,
+ @part-height/.new length,
+ @part-width/.new length,
+ @part-depth/.new length,
+ @content-box-height/.new length,
+ @content-box-width/.new length,
+ @content-box-depth/.new length,
+ @breakat-previous/.new length,
+ @lower/.new length,
+ %
+ debug/.new toggle,
+ verbose/.new toggle,
+ render/.new value =\lb@render@fbox,
+ adjust-options/.new value = {\longbox@adjustoptions},
+ eject/.new value = {\protect\vfill\protect\eject},
+ use-vbox/.new toggle = true,
+ split-minimum/.new length = {1.5\baselineskip},
+ split-badness/.new length = \baselineskip,
+ %
+ height-align/.new choice= {top,middle,bottom},
+ baseline/.new choice = {bottom,middle,top},
+ text-align/.new choice = {default,left,center,right,justify},
+ vertical-align/.new choice = {baseline,bottom,middle,top,text-bottom,text-top,super,sub},
+ raise/.new length = {0pt},
+ baseline-skip/.new toggle =true,
+ %
+ height/.new length = -1sp,
+ width/.new length = -1sp,
+ outer-height/.new length= -1sp,
+ outer-width/.new length = -1sp,
+ insert-before/.new value= {},
+ insert-after/.new value = {},
+ breakat/.new value = {},
+ breakable/.new toggle = false,
+ skip/.new style = {skip-top=#1,skip-right=#1,skip-bottom=#1,skip-left=#1},
+ skip-top/.new length,
+ skip-right/.new length,
+ skip-bottom/.new length,
+ skip-left/.new length,
+ skip-break-bottom/.new length,
+ skip-break-top/.new length,
+}
+
+\newcommand\longbox@adjustoptions{%
+ %\typeout{ standard longbox adjustoptions}%
+ \lb@debug{ current width=\the\dimexpr\option{/longbox/width}, outer=\the\dimexpr\option{/longbox/outer-width}, linewidth=\the\linewidth}%
+ \ontoggle{/longbox/debug}{\option@invoke{/longbox/verbose}{true}}%
+ % adjust height
+ \ifdim\option{/longbox/height}=-1sp\relax
+ \ifdim\option{/longbox/outer-height}=-1sp\else
+ \option@invoke{/longbox/height}%
+ {\option{/longbox/outer-height}-\option{/longbox/skip-top}-\option{/longbox/skip-bottom}}%
+ \fi
+ \fi
+ % set width
+ \ifdim\option{/longbox/width}=-1sp\relax
+ \ifdim\option{/longbox/outer-width}=-1sp\relax
+ \option@invoke{/longbox/outer-width}{\linewidth}%
+ \fi
+ \dimen@=\dimexpr\option{/longbox/outer-width}-\option{/longbox/skip-left}-\option{/longbox/skip-right}\relax
+ \ifdim\dimen@<\z@\relax\dimen@=\z@\fi
+ \option@invoke{/longbox/width}{\dimen@}%
+ \fi
+ % use a breakbox whenever we are in external vertical mode and not width or height restricted.
+ \iftoggle{/longbox/use-vbox}{}{%
+ \ifinner\toggletrue{/longbox/use-vbox}\else
+ \ifhmode\toggletrue{/longbox/use-vbox}\else
+ \ifdim\option{/longbox/height}>-1sp\toggletrue{/longbox/use-vbox}\else
+ \iftoggle{/longbox/breakable}{}{\toggletrue{/longbox/use-vbox}}%
+ \ifoptionblank{/longbox/breakat}{}{\toggletrue{/longbox/use-vbox}}%
+ \fi\fi\fi
+ }%
+}
+
+\newenvironment{longbox}[1][]{%
+ %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}%
+ \begin{longbox@env}{/longbox}{#1}%
+}{\end{longbox@env}}
+
+\newcommand\lbox[1][]{%
+ %\bb@savekeys{bfbox}{fboxrule=\the\fboxrule,fboxsep=\the\fboxsep,bgcolor={\bb@bgcolor},rulecolor={\bb@rulecolor},stickout={\bb@stickout}}%
+ \longbox@cmd{/longbox}{#1}%
+}
+
+\newcommand*\lb@render@fbox{%
+ %\typeout{render defaultbox: bgcolor=\bb@bgcolor, needtop=\iftoggle{/longbox/@part-needtop}{true}{false}}%
+ \@ovdx=\dimexpr\option{/longbox/@part-width} - 2\fboxrule\relax%
+ \@ovdy=\dimexpr\option{/longbox/@part-height}\relax%
+ \iftoggle{/longbox/@part-needbottom}%
+ {\@tempdima=0pt\relax\advance\@ovdy by -\fboxrule}%
+ {\@tempdima=\dimexpr\fboxrule + \bb@stickout\relax
+ \advance\bb@height by \@tempdima
+ \advance\@ovdy by \@tempdima}%
+ \iftoggle{/longbox/@part-needtop}%
+ {\@tempdimb=0pt\relax\advance\@ovdy by -\fboxrule}%
+ {\@tempdimb=\dimexpr\bb@stickout\relax
+ \advance\bb@height by \@tempdimb
+ \advance\@ovdy by \@tempdimb}%
+ %
+ \hbox{\lower \@tempdima\vbox{%
+ \vskip -\@tempdimb
+ \ontoggle{/longbox/@part-needtop}{\lb@debug{toprule wd=\expandafter\the\option{/longbox/width}}\hrule width \option{/longbox/@part-width} height \fboxrule}%
+ \hbox{%
+ \vrule width \fboxrule height \@ovdy%
+ \ifx\bb@bgcolor\@empty
+ \vrule width \@ovdx height \z@\relax
+ \else
+ {\color{\bb@bgcolor}\vrule width \@ovdx height \@ovdy}%
+ \fi
+ \vrule width \fboxrule height \@ovdy%
+ }%
+ \ontoggle{/longbox/@part-needbottom}{\hrule width \option{/longbox/@part-width} height \fboxrule}%
+ }}%
+} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/longfbox/longfbox.sty b/Master/texmf-dist/tex/latex/longfbox/longfbox.sty
new file mode 100644
index 00000000000..9627964199d
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/longfbox/longfbox.sty
@@ -0,0 +1,1344 @@
+%---------------------------------------------------------------------------
+% Copyright 2015 Daan Leijen, Microsoft Corporation.
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%---------------------------------------------------------------------------
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+\ProvidesPackage{longfbox}[2015/12/01, Daan Leijen, Provides long fbox that can break over pages]
+
+\RequirePackage{options}
+\RequirePackage{longbox}
+\RequirePackage{pict2e}
+\RequirePackage{ellipse}
+
+% --------------------------------------------------------
+% Dimension calulations
+% --------------------------------------------------------
+
+% dimmin/dimmax return minimum or maximum dimension
+\providecommand\dim@min[2]{\ifdim#1>#2#2\else #1\fi}
+\providecommand\dim@max[2]{\ifdim#1>#2#1\else #2\fi}
+
+\newcommand*\option@dimmin[2]{\dim@min{\option{#1}}{\option{#2}}}
+\newcommand*\option@dimmax[2]{\dim@max{\option{#1}}{\option{#2}}}
+
+
+% --------------------------------------------------------
+% Add a new 'sides' option type
+% --------------------------------------------------------
+
+\options{
+ /handlers/new sides/.new handler = []{
+ \ifblank{#2}%
+ {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#1-top={##1}, #1-right={##2}, #1-bottom={##3}, #1-left={##4}}}}%
+ {\option@def{#1/@cmd@sides}##1##2##3##4{\optionsalso{#2}}}%
+ \optionsalso{
+ #1/.new cmdx = {##1,##2,##3,##4,##5\relax}{,,,,\relax}{%
+ \ifblank{##2##3##4}{\option{#1/@cmd@sides}{##1}{##1}{##1}{##1}}%
+ {\ifblank{##3##4}{\option{#1/@cmd@sides}{##1}{##2}{##1}{##2}}%
+ {\ifblank{##4}{\option{#1/@cmd@sides}{##1}{##2}{##3}{##2}}%
+ {\option{#1/@cmd@sides}{##1}{##2}{##3}{##4}}%
+ }%
+ }%
+ },
+ #1/.type = sides,
+ }%
+ },%
+}
+
+\newcommand*\optionlengthlimit[3]{% len, min, max
+ \letoption{#1}\opt@temp
+ \ifdim\opt@temp<\dimexpr#2\relax
+ \option@invoke{#1}{#2}%
+ \else\ifdim\opt@temp>\dimexpr#3\relax
+ \option@invoke{#1}{#3}%
+ \fi\fi
+}
+
+\newcommand*\optionradiuslimit[4]{% r1, r2, min, max
+ \letoption{#1}\opt@tempa
+ \letoption{#2}\opt@tempb
+ \ifdim\opt@tempa<\dimexpr#3\relax\option@invoke{#1}{#3}\fi
+ \ifdim\opt@tempb<\dimexpr#3\relax\option@invoke{#2}{#3}\fi
+ \ifdim\dimexpr\opt@tempa + \opt@tempb\relax=\z@\relax\else
+ \ifdim\dimexpr\opt@tempa+\opt@tempb\relax>\dimexpr#4\relax
+ \edef\opt@perc{\the\numexpr(\number\dimexpr#4\relax)/%
+ (\number\dimexpr(\opt@tempa+\opt@tempb)/100\relax)}%
+ %\typeout{scale:\the\opt@tempa,\the\opt@tempb, by \opt@perc percent to make \the\dimexpr#4\relax}%
+ \edef\opt@temp{\dimexpr\opt@perc\dimexpr\the\opt@tempa\relax / 100\relax}%
+ \option@einvoke{#1}{\opt@temp}%
+ \option@einvoke{#2}{\dimexpr#4 - \opt@temp\relax}%
+ %\typeout{ scaled to: \the\opt@temp,\the\dimexpr#4 - \opt@temp\relax}%
+ \fi
+ \fi
+}
+
+
+% \begin{macro}{\trig@atantan}
+% \marg{a}\marg{b}\marg{$\alpha$}{dimen$_\mathit{reg}$}\\
+% Assigns $\atan_2(\frac{\sin(\alpha)}{b},\frac{\cos(\alpha)}{a})$ to dimension register \textit{dimen$_\mathit{reg}$},
+% where $a$ and $b$ are dimensions.
+% Returns $\alpha$ when $a = b$, or when $a=0$ or $b=0$.
+% \begin{macrocode}
+\newcommand*\trig@atantan[4]{%
+ %\typeout{ atantan:(\the#1,\the#2,\the#3, #4)}%
+ \@tempdima\dimexpr#1\relax
+ \@tempdimb\dimexpr#2\relax
+% \end{macrocode}
+% If $a = b$, we have a circle and the result is $\alpha$.
+% \begin{macrocode}
+ \ifdim\@tempdima=\@tempdimb
+ #4\dimexpr#3\relax
+ \else\ifdim\@tempdima=\z@
+ #4\dimexpr#3\relax
+ \else\ifdim\@tempdimb=\z@
+ #4\dimexpr#3\relax
+ \else
+ \edef\trig@temp{\strip@pt\dimexpr#3\relax}%
+ \CalculateSin{\trig@temp}\CalculateCos{\trig@temp}%
+ \@tempdimc\dimexpr1\p@ * \dimexpr\UseSin{\trig@temp}\p@\relax/\@tempdimb\relax
+ \@tempdimd\dimexpr1\p@ * \dimexpr\UseCos{\trig@temp}\p@\relax/\@tempdima\relax
+ \pIIe@atantwo{\@tempdimc}{\@tempdimd}\dimen@
+ \ifdim\dimen@<\z@
+ \ifdim\dimexpr#3\relax<\z@\else\advance\dimen@360\p@\fi
+ \fi
+ \@tempdima\dimexpr#3 - \dimen@\relax
+ \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi
+ \ifdim\@tempdima<360\p@\else\advance\dimen@360\p@\fi
+ %\typeout{atan: \the\dimexpr#3\relax versus. \the\dimen@ }%
+ #4\dimen@
+ \fi\fi\fi
+}
+% \end{macrocode}
+% \end{macro}
+
+% rough approximation of the perimeter;
+% if |radius-x == radius-y| = 0 (a circle), the approximation is precise.
+% otherwise, works best when |angle2-angle1| <= 45 and gets worse from there on.
+\newcommand*\ellip@letarcperimeter[5]{% 'radius-x', 'radius-y', 'angle-1', 'angle-2', '\result'
+ \@tempdima\dimexpr#3\relax
+ \@tempdimb\dimexpr#4\relax
+ \@tempdimc\dimexpr\@tempdima - \@tempdimb\relax
+ \ifdim\@tempdimc<\z@\@tempdimc-\@tempdimc\fi
+ \ifdim#1=#2\relax% circle?
+ \edef\@tempa{\strip@pt\@tempdimc}% angle difference delta as factor
+ \dimen@\@tempa\dimexpr#1\relax% r*delta
+ \dimen@0.017453\dimen@% (2*pi/360) * r * delta = 2*pi*r * (delta/360)
+ \else% ellipse: take the distance between the points on the ellipse, works pretty good if delta <= 45, and ok'ish for delta <= 90
+ \@ovro\dimexpr#1\relax
+ \@ovri\dimexpr#2\relax
+ \edef\fbox@tempa{\strip@pt\@tempdima}%
+ \edef\fbox@tempb{\strip@pt\@tempdimb}%
+ \pIIe@ellip@sincost{\fbox@tempa}{\fbox@tempb}%
+ \@tempdima\@ellipcosone\@ovro
+ \@tempdimb\@ellipsinone\@ovri
+ \@tempdimc\@ellipcostwo\@ovro
+ \@tempdimd\@ellipsintwo\@ovri
+ \advance\@tempdimc by -\@tempdima%
+ \advance\@tempdimd by -\@tempdimb%
+ \pIIe@ellip@csqrt{\@tempdimc}{\@tempdimd}{\dimen@}%
+ %\typeout{ distance: \the\dimen@, from (x,y)=(\the\@tempdimc,\the\@tempdimd), radii=(\the#1,\the#2), angles=(\the#3,\the#4)}%
+ \fi
+ \edef#5{\the\dimen@}%
+}
+
+
+% ------------------------------------------------------------------------------
+% Borders using the picture environment
+% ------------------------------------------------------------------------------
+
+\newcommand*\fbox@border@pict{%
+ \ifnum\option{/fbox/render/@ord}=2\relax%
+ \begingroup
+ \hbox{%
+ \unitlength\p@
+ \begin{picture}(0,0)(0,\optionunit{/fbox/@border-box-height})% bottom-left is origin
+ % markers
+ \ontoggle{/fbox/show-markers}{%
+ \linethickness{\option{/fbox/marker-width}}%
+ \optioncolor{/fbox/marker-color}%
+ \fbox@rect{0pt}{0pt}{\option{/fbox/@border-box-width}}{\option{/fbox/@border-box-height}}%
+ \fbox@rect{\option{/fbox/border-left-width}}{\option{/fbox/border-\fbox@bottom-width}}%
+ {\option{/fbox/@border-box-width}-\option{/fbox/border-right-width}}%
+ {\option{/fbox/@border-box-height}-\option{/fbox/border-\fbox@top-width}}%S
+ }%
+ %compute corner coordinates
+ \fbox@border@calccorners
+ %put down the background color
+ \fbox@border@colorbackground
+ \option{/fbox/picture-insert-before}%
+ %put down the sides
+ \fbox@border@side{3}{-2}{0}%top
+ \fbox@border@side{5}{-4}{3}%left
+ \fbox@border@side{-6}{7}{2}%bottom
+ \fbox@border@side{-8}{1}{1}%right
+ \end{picture}%
+ }%
+ \endgroup
+ \fi
+}
+
+\newcommand*\fbox@border@pict@after{%
+ \ifnum\option{/fbox/render/@ord}=2\relax%
+ \letoption{/fbox/picture-insert-after}\fbox@insertafter
+ \eifblank{\fbox@insertafter}{}{%
+ \begingroup
+ \hbox{%
+ \begin{picture}(0,0)(0,0)% bottom-left is origin
+ \fbox@insertafter
+ \end{picture}%
+ }%
+ \endgroup
+ }%
+ \fi
+}
+
+\newcommand*\fbox@border@side[3]{%
+ \fbox@setoct@angles{#1}%
+ \edef\fbox@style{\option{/fbox/border-\fbox@side-style}}%
+ \optioncolor{/fbox/border-\fbox@side-color}%
+ \option{/fbox/picture-side-insert-before}%
+ \ifcsdef{fbox@border@pict@\fbox@style}%
+ {\csuse{fbox@border@pict@\fbox@style}{#1}{#2}{#3}}%
+ {\PackageWarning{longfbox}{Unknown style "\fbox@style". Using "solid" instead.}%
+ \fbox@border@pict@solid{#1}{#2}{#3}}%
+ \option{/fbox/picture-side-insert-after}%
+}
+
+% ------------------------------------------------------------------------------
+% Define standard border styles for the picture environment
+%
+% a style has the form \fbox@border@pict@<style>{<octant1>}{<octant2>}{<side no>}
+% where <side> is the border side no: top=0, right=1, bottom=2, left=3
+
+
+\newcommand*\fbox@border@pict@none[3]{%
+ % do nothing
+}
+\newcommand*\fbox@border@pict@hidden[3]{%
+ % do nothing
+}
+
+% --------------------------------------------------------
+% Background color
+% --------------------------------------------------------
+
+% Lay down background color
+\newcommand*\fbox@border@colorbackground{%
+ \ifcase\option{/fbox/background-clip/@ord}\relax
+ \fbox@border@colorbackground@border
+ \edefoption{/fbox/background-border-color}\@tempa
+ \edefoption{/fbox/background-padding-color}\@tempb
+ \ifx\@tempa\@tempb\relax\else
+ \fbox@border@colorbackground@padding
+ \fi
+ \or
+ \fbox@border@colorbackground@padding
+ \or
+ \fbox@border@colorbackground@content
+ \fi
+}
+
+\newcommand*\fbox@border@colorbackground@padding{%
+ \ifoptionblank{/fbox/background-padding-color}{}{%
+ \optioncolor{/fbox/background-padding-color}%
+ \moveto(\optionunit{/fbox/@border-bottom-left-ix},\optionunit{/fbox/border-\fbox@bottom-width})%
+ \fbox@cornerarc{bottom-left}{i}{270}{180}%
+ \fbox@cornerarc{top-left}{i}{180}{90}%
+ \fbox@cornerarc{top-right}{i}{90}{0}%
+ \fbox@cornerarc{bottom-right}{i}{0}{-90}%
+ \closepath
+ \fillpath
+ \edefoption{/fbox/background-padding-color}\@tempa
+ \edefoption{/fbox/background-color}\@tempb
+ \ifx\@tempa\@tempb\relax\else
+ \fbox@border@colorbackground@content
+ \fi
+ }%
+}
+
+\newcommand*\fbox@border@colorbackground@content{%
+ \ifoptionblank{/fbox/background-color}{}{%
+ \optioncolor{/fbox/background-color}%
+ \@ovxx=\dimexpr\option{/fbox/border-left-width} + \option{/fbox/padding-left}\relax
+ \@ovyy=\dimexpr\option{/fbox/border-\fbox@bottom-width} + \option{/fbox/padding-\fbox@bottom}\relax
+ \fbox@rect*{\@ovxx}{\@ovyy}%
+ {\@ovxx + \option{/fbox/@content-box-width}}%
+ {\@ovyy + \option{/fbox/@content-box-height}}%
+ }%
+}
+
+\newcommand*\fbox@border@colorbackground@border{%
+ \ifoptionblank{/fbox/background-border-color}{}{%
+ \optioncolor{/fbox/background-border-color}%
+ \moveto(0,0)%
+ \fbox@cornerarc{bottom-left}{}{270}{180}%
+ \fbox@cornerarc{top-left}{}{180}{90}%
+ \fbox@cornerarc{top-right}{}{90}{0}%
+ \fbox@cornerarc{bottom-right}{}{0}{-90}%
+ \closepath
+ \fillpath
+ }%
+}
+
+\newcommand*\fbox@cornerarc[4]{% {'top-left'}{'i'?}{'start angle'}{'end angle'}
+ \elliparc{\optionunit{/fbox/@border-#1-#2x}}%
+ {\optionunit{/fbox/@border-#1-#2y}}%
+ {\optionunit{/fbox/@border-#1-#2radius-x}}%
+ {\optionunit{/fbox/@border-#1-#2radius-y}}{#3}{#4}%
+}
+
+
+
+% --------------------------------------------------------
+% Compute corner coordinates
+% --------------------------------------------------------
+
+% Calculate all corner coordinates
+\newcommand*\fbox@border@calccorners{%
+ \fbox@border@calccorner{top}{left}{\fbox@top}%
+ \fbox@border@calccorner{top}{right}{\fbox@top}%
+ \fbox@border@calccorner{bottom}{left}{\fbox@bottom}%
+ \fbox@border@calccorner{bottom}{right}{\fbox@bottom}%
+}
+
+% calculate for each corner
+% the /fbox/@border-#1-#2-
+% -iradius-x/y: inner corner radius
+% -ix/iy: inner corner center point
+\newcommand*\fbox@border@calccorner[3]{% {'top'}{'left'}{'break-top'}
+ \option@invoke{/fbox/@border-#1-#2-iradius-x}{\dimexpr0pt\relax}%
+ \option@invoke{/fbox/@border-#1-#2-iradius-y}{\dimexpr0pt\relax}%
+ % only give positive inner radius if the center lays outside the border
+ \ifdim\dimexpr\option{/fbox/@border-#1-#2-radius-x} - \option{/fbox/border-#2-width}\relax>0pt\relax
+ \ifdim\dimexpr\option{/fbox/@border-#1-#2-radius-y} - \option{/fbox/border-#3-width}\relax>0pt\relax
+ \option@invoke{/fbox/@border-#1-#2-iradius-x}%
+ {\option{/fbox/@border-#1-#2-radius-x} - \option{/fbox/border-#2-width}}%
+ \option@invoke{/fbox/@border-#1-#2-iradius-y}%
+ {\option{/fbox/@border-#1-#2-radius-y} - \option{/fbox/border-#3-width}}%
+ \fi
+ \fi
+ % assign inner (ix,iy) and outer (x,y)
+ \option@invoke{/fbox/@border-#1-#2-ix}{\option{/fbox/border-#2-width} + \option{/fbox/@border-#1-#2-iradius-x}}%
+ \option@invoke{/fbox/@border-#1-#2-iy}{\option{/fbox/border-#3-width} + \option{/fbox/@border-#1-#2-iradius-y}}%
+ \ifstrequal{#2}{left}{}{%
+ \option@invoke{/fbox/@border-#1-#2-ix}{\option{/fbox/@border-box-width} - \option{/fbox/@border-#1-#2-ix}}%
+ }%
+ \ifstrequal{#1}{bottom}{}{%
+ \option@invoke{/fbox/@border-#1-#2-iy}{\option{/fbox/@border-box-height} - \option{/fbox/@border-#1-#2-iy}}%
+ }%
+ % assign dividing angle based on the width ratio 90 * (b / (a+b))
+ \ifdim\option{/fbox/border-#3-width}=\z@\relax
+ \@tempdima=90pt\relax
+ \else
+ \@tempdima90\dimexpr1pt * \option{/fbox/border-#2-width}/(\option{/fbox/border-#3-width} + \option{/fbox/border-#2-width})\relax
+ \fi
+ %\trig@atantwo{\option{/fbox/border-#2-width}}{\option{/fbox/border-#1-width}}\@tempdima
+ \ifstrequal{#2}{left}{\@tempdima\dimexpr180\p@-\@tempdima\relax}{}%
+ \ifstrequal{#1}{bottom}{\@tempdima\dimexpr360\p@-\@tempdima\relax}{}%
+ \option@invoke{/fbox/@border-#1-#2-phi}{\@tempdima}%
+ %\typeout{ corner angle #1-#2: \the\option{/fbox/@border-#1-#2-phi}}%
+}
+
+% --------------------------------------------------------
+% Helper coordinates
+% There are all just definitions of 'dimexpr's
+% --------------------------------------------------------
+
+\options{
+ /fbox/@border-top-left-x/.new dim = \option{/fbox/@border-top-left-radius-x},
+ /fbox/@border-top-left-y/.new dim = \option{/fbox/@border-box-height} - \option{/fbox/@border-top-left-radius-y},
+ /fbox/@border-top-right-x/.new dim = \option{/fbox/@border-box-width} - \option{/fbox/@border-top-right-radius-x},
+ /fbox/@border-top-right-y/.new dim = \option{/fbox/@border-box-height} - \option{/fbox/@border-top-right-radius-y},
+ /fbox/@border-bottom-left-x/.new dim = \option{/fbox/@border-bottom-left-radius-x},
+ /fbox/@border-bottom-left-y/.new dim = \option{/fbox/@border-bottom-left-radius-y},
+ /fbox/@border-bottom-right-x/.new dim = \option{/fbox/@border-box-width} - \option{/fbox/@border-bottom-right-radius-x},
+ /fbox/@border-bottom-right-y/.new dim = \option{/fbox/@border-bottom-right-radius-y},
+ % the following ones are only used for sharp corner filling; perhaps we can optimize this better?
+ /fbox/@border-top-y/.new dim = \option{/fbox/@border-box-height},
+ /fbox/@border-top-iy/.new dim = \option{/fbox/@border-box-height} - \option{/fbox/border-\fbox@top-width},
+ /fbox/@border-bottom-y/.new dim = 0pt,
+ /fbox/@border-bottom-iy/.new dim = \option{/fbox/border-\fbox@bottom-width},
+ /fbox/@border-right-x/.new dim = \option{/fbox/@border-box-width},
+ /fbox/@border-right-ix/.new dim = \option{/fbox/@border-box-width} - \option{/fbox/border-right-width},
+ /fbox/@border-left-x/.new dim = 0pt,
+ /fbox/@border-left-ix/.new dim = \option{/fbox/border-left-width},
+ /fbox/@border-top-left-ox/.new dim = \option@dimmax{/fbox/@border-top-left-x}{/fbox/@border-top-left-ix},
+ /fbox/@border-top-left-oy/.new dim = \option@dimmin{/fbox/@border-top-left-y}{/fbox/@border-top-left-iy},
+ /fbox/@border-top-right-ox/.new dim = \option@dimmin{/fbox/@border-top-right-x}{/fbox/@border-top-right-ix},
+ /fbox/@border-top-right-oy/.new dim = \option@dimmin{/fbox/@border-top-right-y}{/fbox/@border-top-right-iy},
+ /fbox/@border-bottom-left-ox/.new dim = \option@dimmax{/fbox/@border-bottom-left-x}{/fbox/@border-bottom-left-ix},
+ /fbox/@border-bottom-left-oy/.new dim = \option@dimmax{/fbox/@border-bottom-left-y}{/fbox/@border-bottom-left-iy},
+ /fbox/@border-bottom-right-ox/.new dim= \option@dimmin{/fbox/@border-bottom-right-x}{/fbox/@border-bottom-right-ix},
+ /fbox/@border-bottom-right-oy/.new dim= \option@dimmax{/fbox/@border-bottom-right-y}{/fbox/@border-bottom-right-iy},
+}
+
+
+% --------------------------------------------------------
+% setoct: Set various macros based on the octant
+% --------------------------------------------------------
+
+
+\newcount\fbox@oct
+\newcount\fbox@quad
+\newcount\fbox@diaq
+\newcount\fbox@sign
+
+%fbox@corner
+\newcommand*\fbox@setoct[2][]{% [i (inner)]{octant}}
+ \fbox@sign1\relax
+ \fbox@oct#2\relax
+ \ifnum\fbox@oct<\z@\fbox@oct-\fbox@oct\fbox@sign-\fbox@sign\fi
+ \fbox@quad\fbox@oct
+ \advance\fbox@quad by 1\relax
+ \divide\fbox@quad by 2\relax% quadrant 1-4
+ \ifcase\fbox@quad\relax%\@tempa\relax
+ \or\def\fbox@corner{top-right}%
+ \or\def\fbox@corner{top-left}%
+ \or\def\fbox@corner{bottom-left}%
+ \or\def\fbox@corner{bottom-right}%
+ \fi
+ \letcs\fbox@adjustx{fbox@adjustx@\fbox@corner}%
+ \letcs\fbox@adjusty{fbox@adjusty@\fbox@corner}%
+ \fbox@diaq\fbox@oct
+ \divide\fbox@diaq by 2\relax% 'diamond quadrant' 0 -4
+ \ifodd\fbox@diaq\toggletrue{/fbox/@side-horizontal}\def\fbox@axis{x}\else\togglefalse{/fbox/@side-horizontal}\def\fbox@axis{y}\fi
+ \ifcase\fbox@diaq\relax
+ \def\fbox@side{right}%
+ \or\iftoggle{/longbox/@part-needtop}{\def\fbox@side{top}}{\def\fbox@side{break-top}}%
+ \or\def\fbox@side{left}%
+ \or\iftoggle{/longbox/@part-needbottom}{\def\fbox@side{bottom}}{\def\fbox@side{break-bottom}}%
+ \or\def\fbox@side{right}%
+ \fi
+ \option@invoke{/fbox/@side}{\fbox@side}%
+ %\typeout{setoct(#1,#2): \fbox@corner: \iftoggle{/fbox/@side-horizontal}{hor}{ver} diaq=\the\fbox@diaq, quad=\the\fbox@quad, oct=\the\fbox@oct, direction=\the\fbox@sign}%
+}
+
+\newcommand*\fbox@setotherside{%
+ \ifcase\fbox@diaq\relax
+ \def\fbox@otherside{top}%
+ \or\ifodd\fbox@oct\relax\def\fbox@otherside{left}\else\def\fbox@otherside{right}\fi%
+ \or\ifodd\fbox@oct\relax\def\fbox@otherside{bottom}\else\def\fbox@otherside{top}\fi
+ \or\ifodd\fbox@oct\relax\def\fbox@otherside{right}\else\def\fbox@otherside{left}\fi
+ \or\def\fbox@otherside{bottom}%
+ \fi
+}
+
+\csdef{fbox@adjustx@top-right}#1{\dimexpr\option{/fbox/@border-box-width} - #1\relax}%
+\csdef{fbox@adjusty@top-right}#1{\dimexpr\option{/fbox/@border-box-height} - #1\relax}%
+
+\csdef{fbox@adjustx@top-left}#1{#1}%
+\csdef{fbox@adjusty@top-left}#1{\dimexpr\option{/fbox/@border-box-height} - #1\relax}%
+
+\csdef{fbox@adjustx@bottom-left}#1{#1}%
+\csdef{fbox@adjusty@bottom-left}#1{#1}%
+
+\csdef{fbox@adjustx@bottom-right}#1{\dimexpr\option{/fbox/@border-box-width} - #1\relax}%
+\csdef{fbox@adjusty@bottom-right}#1{#1}%
+
+
+\newlength\fbox@anglestart
+\newlength\fbox@angleend
+\newcommand*\fbox@setoct@angles[2][]{%
+ \fbox@setoct[#1]{#2}%
+ \fbox@anglestart\dimexpr90\p@ * \fbox@diaq\relax
+ \fbox@angleend\option{/fbox/@border-\fbox@corner-phi}%
+ \ifnum\fbox@sign<\z@
+ \ifodd\fbox@oct\relax\else
+ \@tempdima\fbox@anglestart
+ \fbox@anglestart\fbox@angleend
+ \fbox@angleend\@tempdima
+ \fi
+ \else
+ \ifodd\fbox@oct\relax
+ \@tempdima\fbox@anglestart
+ \fbox@anglestart\fbox@angleend
+ \fbox@angleend\@tempdima
+ \fi
+ \fi
+ %\typeout{ angles=\the\fbox@anglestart, to \the\fbox@angleend}%
+}
+
+
+% --------------------------------------------------------
+% Solid border
+% --------------------------------------------------------
+
+\newcommand*\fbox@border@pict@solid[3]{% octant1, octant2, side no.
+ %\fbox@setoct@angles[]{#1}%
+ %\optioncolor{/fbox/border-\fbox@side-color}%
+ \fbox@border@hcornerarc[1]{}{#1}%
+ \fbox@setoct@angles{-#2}%
+ \fbox@border@hcornerarc{}{-#2}%
+ \fbox@setoct@angles[i]{#2}%
+ \fbox@border@hcornerarc{i}{#2}%
+ \fbox@setoct@angles[i]{-#1}%
+ \fbox@border@hcornerarc{i}{-#1}%
+ \closepath
+ \fillpath
+}
+
+% a half corner arc; assumes zero radius will just draw a line to the center point
+\newcommand*\fbox@border@hcornerarc[3][0]{% [lmn], i(nner), octant
+ \elliparc[#1]{\optionunit{/fbox/@border-\fbox@corner-#2x}}%
+ {\optionunit{/fbox/@border-\fbox@corner-#2y}}%
+ {\optionunit{/fbox/@border-\fbox@corner-#2radius-x}}%
+ {\optionunit{/fbox/@border-\fbox@corner-#2radius-y}}{\strip@pt\fbox@anglestart}{\strip@pt\fbox@angleend}%
+}
+
+% --------------------------------------------------------
+% Double border
+% --------------------------------------------------------
+
+\newcommand*\fbox@border@pict@double[3]{% octant1, octant2, side no
+ \fbox@setoct@angles{#1}%
+ \fbox@border@hcornerarc@[1]{}{#1}{0}%
+ \fbox@setoct@angles{-#2}%
+ \fbox@border@hcornerarc@{}{-#2}{0}%
+ \fbox@setoct@angles[i]{#2}%
+ \fbox@border@hcornerarc@{}{#2}{0.33}%
+ \fbox@setoct@angles[i]{-#1}%
+ \fbox@border@hcornerarc@{}{-#1}{0.33}%
+ \closepath
+ \fillpath
+ %
+ \fbox@setoct@angles{#1}%
+ \fbox@border@hcornerarc@[1]{}{#1}{0.66}%
+ \fbox@setoct@angles{-#2}%
+ \fbox@border@hcornerarc@{}{-#2}{0.66}%
+ \fbox@setoct@angles[i]{#2}%
+ \fbox@border@hcornerarc@{}{#2}{1}%
+ \fbox@setoct@angles[i]{-#1}%
+ \fbox@border@hcornerarc@{}{-#1}{1}%
+ \closepath
+ \fillpath
+}
+
+% a half corner arc; but only over 'fraction' of the border width
+% assumes zero radius will just draw a line to the center point
+\newcommand*\fbox@border@hcornerarc@[4][0]{% [lmn], i(nner), octant, width fraction
+ % determine radius and center point for the width fraction
+ \fbox@setotherside
+ \iftoggle{/fbox/@side-horizontal}%
+ {\@tempdima#4\option{/fbox/border-\fbox@otherside-width}%
+ \@tempdimb#4\option{/fbox/border-\fbox@side-width}}%
+ {\@tempdimb#4\option{/fbox/border-\fbox@otherside-width}%
+ \@tempdima#4\option{/fbox/border-\fbox@side-width}}%
+ \@tempdimc\fbox@adjustx{\@tempdima}%
+ \@tempdima\dimexpr\option{/fbox/@border-\fbox@corner-radius-x} - \@tempdima\relax
+ \ifdim\@tempdima<\z@
+ \@tempdima\z@
+ \else
+ \@tempdimc\option{/fbox/@border-\fbox@corner-x}%
+ \fi
+ \@tempdimd\fbox@adjusty{\@tempdimb}%
+ \@tempdimb\dimexpr\option{/fbox/@border-\fbox@corner-radius-y} - \@tempdimb\relax
+ \ifdim\@tempdimb<\z@
+ \@tempdimb\z@
+ \else
+ \@tempdimd\option{/fbox/@border-\fbox@corner-y}%
+ \fi
+ \edef\fbox@radiusx{\strip@pt\@tempdima}%
+ \edef\fbox@radiusy{\strip@pt\@tempdimb}%
+ \edef\fbox@x{\strip@pt\@tempdimc}%
+ \edef\fbox@y{\strip@pt\@tempdimd}%
+ %\typeout{radius:\fbox@radiusx,\fbox@radiusy}%
+ \elliparc[#1]{\fbox@x}{\fbox@y}%
+ {\fbox@radiusx}{\fbox@radiusy}%
+ {\strip@pt\fbox@anglestart}{\strip@pt\fbox@angleend}%
+}
+
+% --------------------------------------------------------
+% Groove and Ridge border
+% --------------------------------------------------------
+
+% draw a side border
+\newtoggle{fbox@innerdark}%
+\newcommand*\fbox@border@pict@groove{% octant1, octant2, side no
+ \ifnum\fbox@oct>5\toggletrue{fbox@innerdark}\else\togglefalse{fbox@innerdark}\fi
+ \fbox@border@pict@grooved%
+}
+\newcommand*\fbox@border@pict@ridge{% octant1, octant2, side no
+ \ifnum\fbox@oct<6\toggletrue{fbox@innerdark}\else\togglefalse{fbox@innerdark}\fi
+ \fbox@border@pict@grooved%
+}
+
+\newcommand*\fbox@border@pict@grooved[3]{% octant, octant, side no
+ \iftoggle{fbox@innerdark}{}%
+ {\color{\option{/fbox/border-\fbox@side-color}\option{/fbox/border-dark-mix}}}%
+ \fbox@setoct@angles{#1}%
+ \fbox@border@hcornerarc@[1]{}{#1}{0}%
+ \fbox@setoct@angles{-#2}%
+ \fbox@border@hcornerarc@{}{-#2}{0}%
+ \fbox@setoct@angles[i]{#2}%
+ \fbox@border@hcornerarc@{}{#2}{0.5}%
+ \fbox@setoct@angles[i]{-#1}%
+ \fbox@border@hcornerarc@{}{-#1}{0.5}%
+ \closepath
+ \fillpath
+ %
+ \iftoggle{fbox@innerdark}%
+ {\color{\option{/fbox/border-\fbox@side-color}\option{/fbox/border-dark-mix}}}%
+ {\optioncolor{/fbox/border-\fbox@side-color}}%
+ \fbox@setoct@angles{#1}%
+ \fbox@border@hcornerarc@[1]{}{#1}{0.5}%
+ \fbox@setoct@angles{-#2}%
+ \fbox@border@hcornerarc@{}{-#2}{0.5}%
+ \fbox@setoct@angles[i]{#2}%
+ \fbox@border@hcornerarc@{}{#2}{1}%
+ \fbox@setoct@angles[i]{-#1}%
+ \fbox@border@hcornerarc@{}{-#1}{1}%
+ \closepath
+ \fillpath
+}
+
+% --------------------------------------------------------
+% Inset and outset border
+% --------------------------------------------------------
+
+\newcommand*\fbox@border@pict@inset{% octant1, octant2, side no
+ \ifnum\fbox@oct<6\relax\color{\option{/fbox/border-\fbox@side-color}\option{/fbox/border-dark-mix}}\fi
+ \fbox@border@pict@inoutset
+}
+\newcommand*\fbox@border@pict@outset{% octant1, octant2, side no
+ \ifnum\fbox@oct>5\relax\color{\option{/fbox/border-\fbox@side-color}\option{/fbox/border-dark-mix}}\fi
+ \fbox@border@pict@inoutset
+}
+\newcommand*\fbox@border@pict@inoutset[3]{% octant1, octant2, side no
+ \fbox@border@hcornerarc[1]{}{#1}%
+ \fbox@setoct@angles{-#2}%
+ \fbox@border@hcornerarc{}{-#2}%
+ \fbox@setoct@angles[i]{#2}%
+ \fbox@border@hcornerarc{i}{#2}%
+ \fbox@setoct@angles[i]{-#1}%
+ \fbox@border@hcornerarc{i}{-#1}%
+ \closepath
+ \fillpath
+}
+
+
+
+% --------------------------------------------------------
+% Dashed & Dotted
+% --------------------------------------------------------
+\newtoggle{fbox@dotted}
+\newlength\fbox@dash
+\newlength\fbox@dashskip
+
+
+\newcommand*\fbox@border@pict@dotted{% octant1, octant2, side no
+ \toggletrue{fbox@dotted}%
+ \fbox@border@pict@dashed@%
+}
+
+\newcommand*\fbox@border@pict@dashed{% octant1, octant2, side no
+ \togglefalse{fbox@dotted}%
+ \fbox@border@pict@dashed@%
+}
+
+\newcommand*\fbox@border@pict@dashed@[3]{% octant1, octant2; side no; (shared between dotted and dashed
+ % calculate corner lengths
+ \fbox@setoct@angles{#2}%
+ \edef\fbox@cornerb{\fbox@corner}%%
+ \iftoggle{fbox@dotted}
+ {\fbox@dash\option{/fbox/border-\fbox@side-width}%
+ \fbox@dashskip\option{/fbox/border-\fbox@side-dotskip}}%
+ {\fbox@dash\option{/fbox/border-\fbox@side-dash}%
+ \fbox@dashskip\option{/fbox/border-\fbox@side-dashskip}}%
+ \fbox@let@cornerlen\fbox@blen%
+ %
+ \fbox@setoct@angles{#1}%
+ \edef\fbox@cornera{\fbox@corner}%
+ \fbox@let@cornerlen\fbox@alen%
+ %\typeout{dashed \fbox@side: alen:\fbox@alen, blen:\fbox@blen }%
+ %
+ % calculate dash skip
+ \dimen@\dimexpr\option{/fbox/@border-\fbox@cornera-o\fbox@axis} - \option{/fbox/@border-\fbox@cornerb-o\fbox@axis}\relax
+ \ifdim\dimen@<0pt\relax\dimen@-\dimen@\fi
+ \advance\dimen@ by \dimexpr\fbox@alen + \fbox@blen\relax% total outer border length
+ \@tempdima\dimexpr\fbox@dash + \fbox@dashskip\relax% initial estimate of full dash
+ \@tempcnta\number\dimen@
+ \divide\@tempcnta by \number\@tempdima% full dashes that fit in the total
+ \@tempdimb\dimexpr\dimen@ - \the\@tempcnta\fbox@dash\relax% total skip space
+ \fbox@dashskip\dimexpr\@tempdimb/\the\@tempcnta\relax% final dashskip such that it fits nicely
+ \edef\fbox@dashfull{\the\dimexpr \fbox@dash + \fbox@dashskip\relax}%
+ %\typeout{ dash \fbox@side: \the\dimexpr\fbox@dash\relax, skip:\fbox@dashskip}%
+ %
+ \optioncolor{/fbox/border-\fbox@side-color}%
+ \fbox@dashcorner{\fbox@alen}%
+ \dimen@\dimexpr\fbox@alen - (\fbox@dashskip/2)\relax
+ \@tempcnta\number\dimen@
+ \divide\@tempcnta by \number\dimexpr\fbox@dashfull\relax
+ \advance\dimen@ by -\dimexpr\fbox@dashfull * \@tempcnta\relax
+ %\typeout{ delta \fbox@side - \fbox@corner: \the\fbox@delta, versus \the\dimen@}%
+ \fbox@delta\dimen@
+ \fbox@dashside%
+ \fbox@setoct@angles{#2}% again :(
+ \fbox@dashcorner{\fbox@blen}%
+}
+
+\newcommand*\fbox@dashside{% ',
+ %\typeout{** dash: \iftoggle{/fbox/@side-horizontal}{hor}{ver}, \fbox@side, diaq=\the\fbox@diaq}%
+ \dimen@\dimexpr\option@dimmax{/fbox/@border-\fbox@cornera-o\fbox@axis}{/fbox/@border-\fbox@cornera-i\fbox@axis}\relax%
+ \@tempdima\dimexpr\option@dimmin{/fbox/@border-\fbox@cornerb-o\fbox@axis}{/fbox/@border-\fbox@cornerb-i\fbox@axis}\relax%
+ \ifdim\fbox@delta>\z@\relax
+ \ifdim\fbox@delta<\fbox@dash\relax
+ %\rule{\dimexpr\fbox@dash - #2}{#3}%
+ \fbox@dashdraw{\dimexpr\dimen@\relax}{\dimexpr\fbox@dash - \fbox@delta\relax}%
+ %\typeout{- add small rule and skip: \the\dimexpr\fbox@dash - \fbox@delta\relax, \fbox@dashskip}%
+ \else
+ %\typeout{- add just skip: \the\dimexpr\fbox@dashfull - \fbox@delta}%
+ \fi
+ \advance\dimen@ by \dimexpr\fbox@dashfull - \fbox@delta\relax%
+ \fi
+ \@whiledim\dimen@<\@tempdima\do{%
+ \advance\dimen@\fbox@dash\relax%
+ \ifdim\dimen@>\@tempdima\relax%
+ %\typeout{final dash: \the\dimen@, \fbox@dash, \the\dimexpr\fbox@dash + \@tempdima - \dimen@\relax}%
+ \fbox@dashdraw{\dimexpr\dimen@ - \fbox@dash\relax}{\dimexpr\fbox@dash + \@tempdima - \dimen@ + 0.1\p@\relax}%
+ \else
+ \fbox@dashdraw{\dimen@}{-\fbox@dash}%
+ \fi
+ \advance\dimen@\fbox@dashskip\relax%
+ }%
+}
+
+\newcommand*\fbox@dashdraw[2]{% x/y dash-len
+ \iftoggle{fbox@dotted}%
+ {\fbox@from\option{/fbox/border-\fbox@side-width}%%
+ \@tempdimb\dimexpr#2\relax%
+ \ifdim\@tempdimb=-\fbox@dash\relax
+ \iftoggle{/fbox/@side-horizontal}%
+ {\put(\strip@pt\dimexpr#1 + #2/2\relax,\strip@pt\dimexpr\fbox@adjusty{0.5\fbox@from}\relax){\circle*{\strip@pt\fbox@from}}}%
+ {\put(\strip@pt\dimexpr\fbox@adjustx{0.5\fbox@from}\relax,\strip@pt\dimexpr#1 + #2/2\relax){\circle*{\strip@pt\fbox@from}}}%
+ \fi
+ }%
+ {\iftoggle{/fbox/@side-horizontal}%
+ {\fbox@rect*{#1}{\fbox@adjusty{0pt}}{\dimexpr#1 + #2\relax}{\fbox@adjusty{\option{/fbox/border-\fbox@side-width}}}}%
+ {\fbox@rect*{\fbox@adjustx{0pt}}{#1}{\fbox@adjustx{\option{/fbox/border-\fbox@side-width}}}{\dimexpr #1 + #2}}%
+ }%
+}
+
+\newcommand*\fbox@rect{\@ifstar{\@tempswatrue\fbox@rect@}{\@tempswafalse\fbox@rect@}}%
+\newcommand*\fbox@rect@[4]{%
+ %\typeout{rect: #1,#2 - #3,#4}%
+ \edef\fbox@tempa{\opt@unit{#1}}%
+ \edef\fbox@tempb{\opt@unit{#2}}%
+ \edef\fbox@tempc{\opt@unit{#3}}%
+ \edef\fbox@tempd{\opt@unit{#4}}%
+ \moveto(\fbox@tempa,\fbox@tempb)%
+ \lineto(\fbox@tempa,\fbox@tempd)%
+ \lineto(\fbox@tempc,\fbox@tempd)%
+ \lineto(\fbox@tempc,\fbox@tempb)%
+ \closepath
+ \if@tempswa\fillpath\else\strokepath\fi
+}
+
+% --------------------------------------------------------
+% dashed corner
+% --------------------------------------------------------
+
+\newcommand*\fbox@let@cornerlen[1]{% \resultlen
+ \ellip@letarcperimeter{\option{/fbox/@border-\fbox@corner-radius-x}}{\option{/fbox/@border-\fbox@corner-radius-y}}%
+ {\fbox@anglestart}{\fbox@angleend}#1%
+ \ifdim\option{/fbox/@border-\fbox@corner-iradius-\fbox@axis}>\z@\relax\else
+ % add abs|ix-x| to the calculated alen
+ %\typeout{ sharp corner \fbox@corner: adjust}%
+ \iftoggle{fbox@dotted}%
+ {\dimen@\dimexpr\fbox@dash\relax}%
+ {\dimen@\dimexpr\option{/fbox/@border-\fbox@corner-i\fbox@axis}-\option{/fbox/@border-\fbox@corner-\fbox@axis}\relax%
+ \ifdim\dimen@<\z@\relax \dimen@-\dimen@\fi
+ \advance\dimen@ by \dimexpr#1\relax
+ %\typeout{ unadjust len: \the\dimen@}%
+ % now adjust to look good later on since we will always fill a sharp corner
+ \ifdim\dimen@>\fbox@dash\relax\dimen@\fbox@dash\fi
+ }%
+ \edef#1{\the\dimexpr\dimen@ + (\fbox@dashskip/2)\relax}%
+ \fi
+ %\typeout{ corner length: \fbox@side - \fbox@corner: #1}%
+}%
+
+\newcommand*\fbox@dashcorner[1]{%'\corner length ''
+ \ifdim\option{/fbox/@border-\fbox@corner-iradius-x}>\z@%\fbox@dashfull\relax
+ % draw rounded dashes
+ \fbox@dash@roundedcorner{#1}%
+ \else
+ \iftoggle{fbox@dotted}%
+ {% get mininum width
+ \@tempdima\dimexpr\option{/fbox/@border-\fbox@corner-ix}-\option{/fbox/@border-\fbox@corner-x}\relax
+ \ifdim\@tempdima<\z@\@tempdima-\@tempdima\fi
+ \@tempdimb\dimexpr\option{/fbox/@border-\fbox@corner-iy}-\option{/fbox/@border-\fbox@corner-y}\relax
+ \ifdim\@tempdimb<\z@\@tempdimb-\@tempdimb\fi
+ \ifdim\@tempdimb<\@tempdima\@tempdima\@tempdimb\fi
+ % radius of corner circle is half
+ \@tempdima0.5\@tempdima
+ \edef\fbox@radius{\strip@pt\@tempdima}%
+ % determine center
+ \ifnum\fbox@quad>2
+ \@tempdimb\dimexpr\option{/fbox/@border-\fbox@corner-iy} - \@tempdima\relax
+ \else
+ \@tempdimb\dimexpr\option{/fbox/@border-\fbox@corner-iy} + \@tempdima\relax
+ \fi
+ \ifnum\fbox@quad=2
+ \@tempdima\dimexpr\option{/fbox/@border-\fbox@corner-ix} - \@tempdima\relax
+ \else\ifnum\fbox@quad=3
+ \@tempdima\dimexpr\option{/fbox/@border-\fbox@corner-ix} - \@tempdima\relax
+ \else
+ \@tempdima\dimexpr\option{/fbox/@border-\fbox@corner-ix} + \@tempdima\relax
+ \fi\fi
+ % determine angles
+ \@tempdimc\numexpr(\fbox@quad - 1) * 90 + 45\relax\p@
+ \@tempdimd\dimexpr\@tempdimc + 180\p@\relax
+ \edef\fbox@temp{\number\fbox@oct}%
+ \ifodd\fbox@temp
+ \advance\@tempdimc by -180\p@
+ \advance\@tempdimd by -180\p@
+ \fi
+ %\typeout{ half circle: \fbox@side - \fbox@corner, \the\@tempdimc -> \the\@tempdimd}%
+ \edef\fbox@anglea{\strip@pt\@tempdimc}%
+ \edef\fbox@angleb{\strip@pt\@tempdimd}%
+ \put(\strip@pt\@tempdima,\strip@pt\@tempdimb){\arc*[\fbox@anglea,\fbox@angleb]{\fbox@radius}}%
+ }%
+ {\ifdim\option{/fbox/@border-\fbox@corner-radius-x}>\z@%
+ % an inside sharp corner, fill.
+ %\typeout{draw sharp }%
+ \moveto(\optionunit{/fbox/@border-\fbox@corner-ix},\optionunit{/fbox/@border-\fbox@corner-iy})% inner corner
+ \iftoggle{/fbox/@side-horizontal}%
+ {\lineto(\optionunit{/fbox/@border-\fbox@corner-ox},\optionunit{/fbox/@border-\fbox@side-iy})
+ \lineto(\optionunit{/fbox/@border-\fbox@corner-ox},\optionunit{/fbox/@border-\fbox@side-y})}
+ {\lineto(\optionunit{/fbox/@border-\fbox@side-ix},\optionunit{/fbox/@border-\fbox@corner-oy})
+ \lineto(\optionunit{/fbox/@border-\fbox@side-x},\optionunit{/fbox/@border-\fbox@corner-oy})}
+ %\fbox@border@hcornerarc{}{}{#3}{}%
+ \elliparc{\optionunit{/fbox/@border-\fbox@corner-x}}%
+ {\optionunit{/fbox/@border-\fbox@corner-y}}%
+ {\optionunit{/fbox/@border-\fbox@corner-radius-x}}%
+ {\optionunit{/fbox/@border-\fbox@corner-radius-y}}{\strip@pt\fbox@angleend}{\strip@pt\fbox@anglestart}%
+ \closepath\fillpath
+ \else
+ % a non-rounded corner, draw a triangle
+ %\typeout{draw sharp - \fbox@corner, axis=\fbox@axis}
+ \moveto(\optionunit{/fbox/@border-\fbox@corner-ix},\optionunit{/fbox/@border-\fbox@corner-iy})% inner corner
+ \lineto(\optionunit{/fbox/@border-\fbox@corner-x},\optionunit{/fbox/@border-\fbox@corner-y})% outer corner
+ \iftoggle{/fbox/@side-horizontal}%
+ {\lineto(\optionunit{/fbox/@border-\fbox@corner-ix},\optionunit{/fbox/@border-\fbox@corner-y})}% outside opposite inner corner
+ {\lineto(\optionunit{/fbox/@border-\fbox@corner-x},\optionunit{/fbox/@border-\fbox@corner-iy})}% outside opposite inner corner
+ \closepath
+ \fillpath
+ \fi
+ }%
+ \fi
+}
+
+% --------------------------------------------------------
+% Dashed rounded corner
+% --------------------------------------------------------
+
+\newlength\fbox@anglecur
+%\newlength\fbox@angleend
+\newlength\fbox@dashangle
+\newlength\fbox@dashskipangle
+\newlength\fbox@delta
+\newlength\fbox@from
+\newlength\fbox@to
+
+\newcommand*\fbox@dash@roundedcorner[1]{% 'corner len'
+ %\typeout{ dash corner: \fbox@side - \fbox@corner, len=#1, start,end=\the\fbox@anglestart,\the\fbox@angleend}%
+ \trig@atantan{\option{/fbox/@border-\fbox@corner-radius-x}}{\option{/fbox/@border-\fbox@corner-radius-y}}{\fbox@anglestart}\fbox@anglestart%
+ \trig@atantan{\option{/fbox/@border-\fbox@corner-radius-x}}{\option{/fbox/@border-\fbox@corner-radius-y}}{\fbox@angleend}\fbox@angleend%
+ %
+ \fbox@delta\dimexpr\fbox@angleend - \fbox@anglestart\relax%
+ \fbox@dashangle\dimexpr \fbox@delta * \dimexpr\fbox@dash\relax / \dimexpr#1\relax%
+ \fbox@dashskipangle\dimexpr \fbox@delta * \dimexpr\fbox@dashskip\relax / \dimexpr#1\relax%
+ %\typeout{ delta=\the\fbox@delta, dash angle=\the\fbox@dashangle, skip angle=\the\fbox@dashskipangle}%
+ \advance\fbox@anglestart by 0.5\fbox@dashskipangle% start with skip
+ \ifdim\fbox@dashangle<\z@\relax\edef\fbox@cmp{>}\else\edef\fbox@cmp{<}\fi
+ \@whiledim\fbox@anglestart\fbox@cmp\fbox@angleend\do\fbox@dash@roundedcornerdash%
+}
+
+\newcommand*\fbox@dash@roundedcornerdash{%
+ \fbox@from\fbox@anglestart
+ \advance\fbox@anglestart by \fbox@dashangle
+ \ifdim\fbox@angleend\fbox@cmp\fbox@anglestart\relax
+ %\typeout{too much? \the\fbox@anglestart, and \the\fbox@angleend}%
+ \fbox@to\fbox@angleend
+ \else
+ \fbox@to\fbox@anglestart
+ \fi
+ \iftoggle{fbox@dotted}%
+ {% take mid angle
+ \fbox@to\fbox@anglestart
+ \advance\fbox@to\fbox@from
+ \divide\fbox@to by 2
+ \edef\fbox@angle{\strip@pt\fbox@to}%
+ \CalculateSin{\fbox@angle}\CalculateCos{\fbox@angle}%
+ % calculate inner and middle point on the ellipse
+ \fbox@from\UseCos{\fbox@angle}\option{/fbox/@border-\fbox@corner-iradius-x}%
+ \fbox@to\UseSin{\fbox@angle}\option{/fbox/@border-\fbox@corner-iradius-y}%
+ \@tempdima0.5\dimexpr\option{/fbox/@border-\fbox@corner-radius-x} + \option{/fbox/@border-\fbox@corner-iradius-x}\relax
+ \@tempdimb0.5\dimexpr\option{/fbox/@border-\fbox@corner-radius-y} + \option{/fbox/@border-\fbox@corner-iradius-y}\relax
+ \@tempdima\UseCos{\fbox@angle}\@tempdima
+ \@tempdimb\UseSin{\fbox@angle}\@tempdimb
+ % use circle radius of distance between inner and middle point
+ \advance\fbox@from by -\@tempdima
+ \advance\fbox@to by -\@tempdimb
+ \pIIe@ellip@csqrt{\fbox@from}{\fbox@to}\dimen@% cache csqrt since for fixed width this is always the same
+ \edef\fbox@temp{\strip@pt\dimexpr2\dimen@\relax}%
+ %\typeout{ (a,b)=(\the\@tempdima,\the\@tempdimb), (c,d)=(\the\fbox@from,\the\fbox@to), distance=\the\dimen@}%
+ % move to center and draw
+ \advance\@tempdima by \dimexpr\option{/fbox/@border-\fbox@corner-x}\relax%
+ \advance\@tempdimb by \dimexpr\option{/fbox/@border-\fbox@corner-y}\relax%
+ \put(\strip@pt\@tempdima,\strip@pt\@tempdimb){\circle*{\fbox@temp}}%
+ }%
+ {\edef\fbox@from@{\strip@pt\fbox@from}%
+ \edef\fbox@to@{\strip@pt\fbox@to}%
+ % draw a rounded dash
+ \@ovro\option{/fbox/@border-\fbox@corner-radius-x}%
+ \@ovri\option{/fbox/@border-\fbox@corner-radius-y}%
+ \pIIe@elliparc@t{1}{\option{/fbox/@border-\fbox@corner-x}}{\option{/fbox/@border-\fbox@corner-y}}%
+ {\fbox@from@}{\fbox@to@}%
+ % and for the inner circle
+ \@ovro\option{/fbox/@border-\fbox@corner-iradius-x}%
+ \@ovri\option{/fbox/@border-\fbox@corner-iradius-y}%
+ \pIIe@elliparc@t{0}{\option{/fbox/@border-\fbox@corner-ix}}{\option{/fbox/@border-\fbox@corner-iy}}%
+ {\fbox@to@}{\fbox@from@}%
+
+ \closepath
+ \fillpath
+ }%
+ \advance\fbox@anglestart by \fbox@dashskipangle%
+}
+
+
+
+% ------------------------------------------------------------------------------
+% Define standard border styles
+%
+% a style has the form \fbox@border@plain@<style>{<side-name>}{<border-width>}{<total length>}
+% where <side> is the border side
+% <direction> is either "h" or "v" (horizontal or vertical)
+% <borderwidth> the width of the rule
+%
+% predefined styles: none, hidden, solid, transparent, and dashed
+
+\newcommand*\fbox@border@plain@none[3]{}
+\newcommand*\fbox@border@plain@hidden[3]{}
+
+\newcommand*\fbox@border@plain@transparent[3]{%
+ \iftoggle{/fbox/@side-horizontal}%
+ {\hrule width #3 height \z@\relax}%
+ {\vrule width \z@ height #3\relax}%
+}
+
+\newcommand*\fbox@border@plain@solid[3]{%
+ \iftoggle{/fbox/@side-horizontal}%
+ {\hrule width #3 height #2\relax}%
+ {\vrule width #2 height #3\relax}%
+}
+
+\newcommand*\fbox@border@plain@dashed[3]{%
+ \iftoggle{/fbox/@side-horizontal}%
+ {\edef\fbox@dash{\vrule width \option{/fbox/border-#1-dash} height #2}%
+ \edef\fbox@dashskip{\hskip \option{/fbox/border-#1-dashskip} plus 0.25ex minus 0.25ex}%
+ \hbox to #3{\fbox@dash\fbox@dashskip\xleaders\hbox{\fbox@dash\fbox@dashskip}\hfill\fbox@dash}}%
+ {\edef\fbox@dash{\hrule height \option{/fbox/border-#1-dash} width #2}%
+ \edef\fbox@dashskip{\vskip \option{/fbox/border-#1-dashskip} plus 0.25ex minus 0.25ex}%
+ \vbox to #3{\offinterlineskip\fbox@dash\fbox@dashskip\xleaders\vbox{\fbox@dash\fbox@dashskip}\vfill\fbox@dash}}%
+}
+
+\newcommand*\fbox@border@plain@dotted[3]{%
+ \iftoggle{/fbox/@side-horizontal}%
+ {\edef\fbox@dot{\vrule width #2 height #2}%
+ \edef\fbox@dotskip{\hskip \option{/fbox/border-#1-dotskip} plus 0.5ex minus 0.1ex}%
+ \hbox to #3{\xleaders\hbox{\fbox@dot\fbox@dotskip}\hfill\hbox{\fbox@dot}}}%
+ {\edef\fbox@dot{\hrule height #2 width #2}%
+ \edef\fbox@dotskip{\vskip \option{/fbox/border-#1-dotskip} plus 0.5ex minus 0.1ex}%
+ \vbox to #3{\fbox@dotskip\offinterlineskip\cleaders\vbox{\fbox@dot\fbox@dotskip}\vfill}}%
+}
+
+% --------------------------------------------------------
+%
+% --------------------------------------------------------
+\newcommand\fbox@setdim{%
+ %\typeout{ set dim}%
+ \iftoggle{/longbox/@part-needtop}{\def\fbox@top{top}}{\def\fbox@top{break-top}}%
+ \iftoggle{/longbox/@part-needbottom}{\def\fbox@bottom{bottom}}{\def\fbox@bottom{break-bottom}}%
+ \options{%
+ /fbox/@padding-box-height=\option{/fbox/@content-box-height}% full height (including depth)
+ +\option{/fbox/padding-\fbox@top} +\option{/fbox/padding-\fbox@bottom},%
+ /fbox/@padding-box-depth=\option{/fbox/@content-box-depth} + \option{/fbox/padding-\fbox@bottom},%
+ /fbox/@padding-box-width=\option{/fbox/@content-box-width}%
+ +\option{/fbox/padding-left}+\option{/fbox/padding-right},
+ /fbox/@border-box-width=\option{/fbox/@padding-box-width}%
+ +\option{/fbox/border-left-width}+\option{/fbox/border-right-width},%
+ /fbox/@border-box-height=\option{/fbox/@padding-box-height}% full height
+ +\option{/fbox/border-\fbox@top-width}%
+ +\option{/fbox/border-\fbox@bottom-width},%
+ /fbox/@border-box-depth=\option{/fbox/@padding-box-depth}%
+ +\option{/fbox/border-\fbox@bottom-width},%
+ }%
+ % lower/raise for break boxes
+ %\@tempdima=\z@\relax
+ %\advance\@tempdima by \dimexpr\option{/fbox/padding-\fbox@bottom} + \option{/fbox/margin-\fbox@bottom} + \option{/fbox/border-\fbox@bottom-width}\relax%
+ %\advance\@tempdima by -\dimexpr\option{/fbox/padding-\fbox@top} + \option{/fbox/margin-\fbox@top} + \option{/fbox/border-\fbox@top-width}\relax%
+ %\option@invoke{/fbox/@lower}{\@tempdima}%
+ % limit radius
+ \optionradiuslimit{/fbox/@border-top-left-radius-y}{/fbox/@border-bottom-left-radius-y}%
+ {0pt}{\option{/fbox/@border-box-height}}%
+ \optionradiuslimit{/fbox/@border-top-right-radius-y}{/fbox/@border-bottom-right-radius-y}%
+ {0pt}{\option{/fbox/@border-box-height}}%
+ \optionradiuslimit{/fbox/@border-top-left-radius-x}{/fbox/@border-top-right-radius-x}%
+ {0pt}{\option{/fbox/@border-box-width}}%
+ \optionradiuslimit{/fbox/@border-bottom-left-radius-x}{/fbox/@border-bottom-right-radius-x}%
+ {0pt}{\option{/fbox/@border-box-width}}%\
+ % switch to plain mode if this is a simple box; todo: is it worth to do this test?
+ \ifnum\option{/fbox/render/@ord}=0\relax
+ \option@invoke{/fbox/render}{plain}%
+ \def\fbox@stylex{}%
+ \def\fbox@colorx{}%
+ \def\do##1{%
+ \letoption{/fbox/border-##1-style}\fbox@style
+ \eifstrequal{\fbox@style}{none}{}{%
+ \option@ifanyof{\fbox@style}{solid,dashed}{%
+ \eifblank{\fbox@stylex}{\let\fbox@stylex\fbox@style}{%
+ \ifx\fbox@style\fbox@stylex\else\option@invoke{/fbox/render}{picture}\expandafter\listbreak\fi
+ }%
+ }{\option@invoke{/fbox/render}{picture}\listbreak}%
+ }%
+ \letoption{/fbox/border-##1-color}\fbox@color
+ \eifblank{\fbox@colorx}{\let\fbox@colorx\fbox@color}{%
+ \ifx\fbox@color\fbox@colorx\else\option@invoke{/fbox/render}{picture}\expandafter\listbreak\fi
+ }%
+ }%
+ \docsvlist{top,left,bottom,right,break-top,break-bottom}%
+ \ifnum\option{/fbox/render/@ord}=1\relax
+ \def\do##1{%
+ \ifdim\option{/fbox/@border-##1-radius-x}=\z@\relax\else\option@invoke{/fbox/render}{picture}\expandafter\listbreak\fi
+ \ifdim\option{/fbox/@border-##1-radius-y}=\z@\relax\else\option@invoke{/fbox/render}{picture}\expandafter\listbreak\fi
+ }%
+ \docsvlist{top-left,top-right,bottom-left,bottom-right}%
+ \fi
+ \ifnum\option{/fbox/render/@ord}=1\relax
+ \def\do##1{%
+ \letoption{/fbox/picture-##1}\fbox@temp
+ \eifblank{\fbox@temp}{}{\option@invoke{/fbox/render}{picture}\listbreak}%
+ }%
+ \docsvlist{insert-before,insert-after,side-insert-before,side-insert-after}%
+ \fi
+ \fi
+}
+
+\newrobustcmd*\fbox@border@plain[2]{%
+ \ifnum\option{/fbox/render/@ord}<2\relax
+ \begingroup
+ \option@invoke{/fbox/@side}{#1}%
+ \ifx#2h\relax
+ \toggletrue{/fbox/@side-horizontal}%
+ \def\fbox@length{\option{/fbox/@border-box-width}}%
+ \else
+ \togglefalse{/fbox/@side-horizontal}%
+ \def\fbox@length{\option{/fbox/@padding-box-height}}%
+ \fi%
+ \edef\fbox@rendername{fbox@border@plain@\option{/fbox/border-#1-style}}%
+ \optioncolor{/fbox/border-#1-color}% set color already
+ \option{/fbox/plain-side-insert-before}%
+ \ifcsdef{\fbox@rendername}%
+ {\csuse{\fbox@rendername}{#1}{\option{/fbox/border-#1-width}}{\fbox@length}}%
+ {\PackageWarning{longfbox}{Unknown (plain) border style "\option{/fbox/border-#1-style}": using "solid" instead}{}%
+ \fbox@border@plain@solid{#1}{\option{/fbox/border-#1-width}}{\fbox@length}}%
+ \option{/fbox/plain-side-insert-after}%
+ \endgroup
+ \else
+ \kern\option{/fbox/border-#1-width}%
+ \fi
+}
+
+\newrobustcmd*\fbox@kern[3][]{%
+ \iftoggle{/fbox/show-markers}{%
+ \begingroup
+ \optioncolor{/fbox/marker-color}%
+ \ifx#2v\relax
+ \def\fbox@marker{\vrule width \option{/fbox/marker-width} height \option{#3}}%
+ \eifblank{#1}{\hbox{\fbox@marker}}{\vbox{\hbox to \option{#1}{\fbox@marker\hfill\hfill\fbox@marker}}}%
+ \else
+ \def\fbox@marker{\vrule height \option{/fbox/marker-width} width \option{#3}}%
+ \setlength\dimen@{\option{/fbox/marker-width}}%
+ \eifblank{#1}{}{\advance\dimen@ \dimexpr -\option{#1}\relax\relax}%
+ \lower \dimen@\hbox{\fbox@marker}%
+ \fi
+ \endgroup
+ }%
+ {\kern\option{#3}}%
+}
+
+\newrobustcmd*\fbox@plain@bgcolor[1]{%
+ \ifnum\option{/fbox/render/@ord}<2\relax
+ \ifoptionblank{/fbox/background-#1-color}{}{%
+ \vtop to 0pt{%
+ \hbox to 0pt{%
+ \optioncolor{/fbox/background-#1-color}%
+ \rule{\option{/fbox/@#1-box-width}}{\option{/fbox/@#1-box-height}}%
+ \hss
+ }%
+ \vss
+ }%
+ }%
+ \fi
+}
+
+\newrobustcmd*\fbox@render{%
+ \begingroup
+ \fbox@setdim
+ %\typeout{render: height:\the\dimexpr\option{/fbox/@content-box-height}, lower=\the\dimexpr\option{/fbox/@lower}}%
+ \hbox{%
+ \fbox@kern{h}{/fbox/margin-left}%
+ \option{/fbox/render-insert-before}%
+ \lower \option{/fbox/@lower}%
+ \vbox{\offinterlineskip
+ \fbox@kern{v}{/fbox/margin-\fbox@top}%
+ \ifnum\option{/fbox/background-clip/@ord}=0\relax\fbox@plain@bgcolor{border}\fi
+ \fbox@border@pict%
+ \fbox@border@plain{\fbox@top}{h}%
+ \hbox{%
+ \fbox@border@plain{left}{v}%
+ \ifnum\option{/fbox/background-clip/@ord}=1\relax\fbox@plain@bgcolor{padding}\fi
+ \fbox@kern[/fbox/@padding-box-depth]{h}{/fbox/padding-left}%
+ \vbox{\offinterlineskip
+ \fbox@kern[/fbox/@content-box-width]{v}{/fbox/padding-\fbox@top}%
+ \ifnum\option{/fbox/background-clip/@ord}=2\relax\fbox@plain@bgcolor{content}\fi
+ \kern \option{/fbox/@content-box-height}%
+ \hrule height \z@ width \option{/fbox/@content-box-width}\relax
+ \fbox@kern[/fbox/@content-box-width]{v}{/fbox/padding-\fbox@bottom}%
+ }%
+ \fbox@kern[/fbox/@padding-box-depth]{h}{/fbox/padding-right}%
+ \fbox@border@plain{right}{v}%
+ }%
+ \fbox@border@plain{\fbox@bottom}{h}%
+ \fbox@border@pict@after%
+ \fbox@kern{v}{/fbox/margin-\fbox@bottom}%
+ }%
+ \option{/fbox/render-insert-after}%
+ \fbox@kern{h}{/fbox/margin-right}%
+ }%
+ \endgroup
+}
+
+\options{%
+ /fbox/.new family = {/longbox},
+}
+\options{/fbox,
+ % compatability
+ sep/.new style = {/fbox/padding=#1},
+ rule/.new style = {/fbox/border-width=#1},
+ % styles
+ margin/.new sides,
+ padding/.new sides,
+ border-width/.new sides = {/fbox/border-top-width=#1,/fbox/border-right-width=#2,%
+ /fbox/border-bottom-width=#3,/fbox/border-left-width=#4,%
+ /fbox/border-break-top-width=#1,/fbox/border-break-bottom-width=#3},
+ border-color/.new sides = {/fbox/border-top-color=#1,/fbox/border-right-color=#2,%
+ /fbox/border-bottom-color=#3,/fbox/border-left-color=#4,%
+ /fbox/border-break-top-color=#1,/fbox/border-break-bottom-color=#3},
+ border-style/.new sides = {/fbox/border-top-style=#1,/fbox/border-right-style=#2,%
+ /fbox/border-bottom-style=#3,/fbox/border-left-style=#4},
+ border-break-style/.new style = {/fbox/border-break-top-style=#1,/fbox/border-break-bottom-style=#1},
+ border-break-width/.new style = {/fbox/border-break-top-width=#1,/fbox/border-break-bottom-width=#1},
+ border-break-color/.new style = {/fbox/border-break-top-color=#1,/fbox/border-break-bottom-color=#1},
+ padding-break/.new style = {/fbox/padding-break-top=#1,/fbox/padding-break-bottom=#1},
+ margin-break/.new style = {/fbox/margin-break-top=#1,/fbox/margin-break-bottom=#1},
+ % background
+ background-clip/.new choice={border-box,padding-box,content-box},
+ background-color/.new color = {},
+ background-padding-color/.new color expr = \option{/fbox/background-color},
+ background-border-color/.new color expr = \option{/fbox/background-color},
+ background-content-color/.new color expr = \option{/fbox/background-color},
+ % various
+ show-markers/.new toggle,
+ marker-color/.new color = gray,
+ marker-width/.new dim = 0.1pt,
+ render/.new choice = {default, plain, picture},
+ render-insert-before/.new value,
+ render-insert-after/.new value,
+ plain-side-insert-before/.new value,
+ plain-side-insert-after/.new value,
+ picture-insert-before/.new value,
+ picture-insert-after/.new value,
+ picture-side-insert-before/.new value,
+ picture-side-insert-after/.new value,
+ % scoped (init) keys; these are reinitialized for nested scopes.
+ padding-top/.new length = {\fboxsep},
+ padding-right/.new length = {\fboxsep},
+ padding-bottom/.new length = {\fboxsep},
+ padding-left/.new length = {\fboxsep},
+ padding-break-top/.new length = {2pt},
+ padding-break-bottom/.new length = {2pt},
+ margin-top/.new length,
+ margin-right/.new length,
+ margin-bottom/.new length,
+ margin-left/.new length,
+ margin-break-top/.new length,
+ margin-break-bottom/.new length,
+ % borders: width
+ border-top-width/.new length = {\fboxrule},
+ border-right-width/.new length = {\fboxrule},
+ border-bottom-width/.new length = {\fboxrule},
+ border-left-width/.new length = {\fboxrule},
+ border-break-top-width/.new length = {\fboxrule},
+ border-break-bottom-width/.new length = {\fboxrule},
+ % borders: color
+ border-top-color/.new color = {.},
+ border-right-color/.new color = {.},
+ border-bottom-color/.new color = {.},
+ border-break-top-color/.new color = {.},
+ border-break-bottom-color/.new color = {.},
+ border-left-color/.new color = {.},
+ border-dark-mix/.new value = {!70!black},
+ % borders: style
+ border-top-style/.new value=solid,
+ border-right-style/.new value=solid,
+ border-bottom-style/.new value=solid,
+ border-left-style/.new value=solid,
+ border-break-top-style/.new value=none,
+ border-break-bottom-style/.new value=none,
+ % corner radius
+ border-radius/.new cmd tuple = \optionsalso{
+ /fbox/border-top-left-radius={#1,#2},/fbox/border-top-right-radius={#1,#2},
+ /fbox/border-bottom-left-radius={#1,#2}, /fbox/border-bottom-right-radius={#1,#2}},
+ border-top-left-radius/.new cmd tuple
+ = \optionsalso{/fbox/@border-top-left-radius-x=#1,/fbox/@border-top-left-radius-y=#2},
+ border-top-right-radius/.new cmd tuple
+ = \optionsalso{/fbox/@border-top-right-radius-x=#1,/fbox/@border-top-right-radius-y=#2},
+ border-bottom-left-radius/.new cmd tuple
+ = \optionsalso{/fbox/@border-bottom-left-radius-x=#1,/fbox/@border-bottom-left-radius-y=#2},
+ border-bottom-right-radius/.new cmd tuple
+ = \optionsalso{/fbox/@border-bottom-right-radius-x=#1,/fbox/@border-bottom-right-radius-y=#2},
+ % dashes and dots
+ border-dash/.new sides = {/fbox/border-top-dash=#1,/fbox/border-right-dash=#2,%
+ /fbox/border-bottom-dash=#3,/fbox/border-left-dash=#4,%
+ /fbox/border-break-top-dash=#1,/fbox/border-break-bottom-dash=#3},
+ border-dashskip/.new sides= {/fbox/border-top-dashskip=#1,/fbox/border-right-dashskip=#2,%
+ /fbox/border-bottom-dashskip=#3,/fbox/border-left-dashskip=#4,%
+ /fbox/border-break-top-dashskip=#1,/fbox/border-break-bottom-dashskip=#3},
+ border-dotskip/.new sides= {/fbox/border-top-dotskip=#1,/fbox/border-right-dotskip=#2,%
+ /fbox/border-bottom-dotskip=#3,/fbox/border-left-dotskip=#4,%
+ /fbox/border-break-top-dotskip=#1,/fbox/border-break-bottom-dotskip=#3},
+ border-top-dash/.new dim = 0.6ex,%3\option{/fbox/border-top-width},
+ border-bottom-dash/.new dim = 0.6ex,%3\option{/fbox/border-bottom-width},
+ border-left-dash/.new dim = 0.6ex,%3\option{/fbox/border-left-width},
+ border-right-dash/.new dim = 0.6ex,%3\option{/fbox/border-right-width},
+ border-break-top-dash/.new dim = \option{/fbox/border-top-dash},
+ border-break-bottom-dash/.new dim = \option{/fbox/border-bottom-dash},
+ border-top-dashskip/.new dim = 0.7\option{/fbox/border-top-dash},
+ border-bottom-dashskip/.new dim = 0.7\option{/fbox/border-bottom-dash},
+ border-left-dashskip/.new dim = 0.7\option{/fbox/border-left-dash},
+ border-right-dashskip/.new dim = 0.7\option{/fbox/border-right-dash},
+ border-break-top-dashskip/.new dim = \option{/fbox/border-top-dashskip},
+ border-break-bottom-dashskip/.new dim = \option{/fbox/border-bottom-dashskip},
+ border-top-dotskip/.new dim = 2\option{/fbox/border-top-width},
+ border-bottom-dotskip/.new dim = 2\option{/fbox/border-bottom-width},
+ border-left-dotskip/.new dim = 2\option{/fbox/border-left-width},
+ border-right-dotskip/.new dim = 2\option{/fbox/border-right-width},
+ border-break-top-dotskip/.new dim = \option{/fbox/border-top-dotskip},
+ border-break-bottom-dotskip/.new dim = \option{/fbox/border-bottom-dotskip},
+ % computed
+ @lower/.new length,
+ @content-box-width/.new dim = \option{/longbox/@content-box-width},
+ @content-box-height/.new dim = \option{/longbox/@content-box-height},
+ @content-box-depth/.new dim = \option{/longbox/@content-box-depth},
+ @padding-box-height/.new length,
+ @padding-box-depth/.new length,
+ @padding-box-width/.new length,
+ @border-box-width/.new length,
+ @border-box-height/.new length,
+ @border-box-depth/.new length,
+ % computed: not for the user
+ @border-top-left-radius-x/.new length,
+ @border-top-right-radius-x/.new length,
+ @border-bottom-left-radius-x/.new length,
+ @border-bottom-right-radius-x/.new length,
+ @border-top-left-radius-y/.new length,
+ @border-top-right-radius-y/.new length,
+ @border-bottom-left-radius-y/.new length,
+ @border-bottom-right-radius-y/.new length,
+ % computed inner radius; zero if border radius center is inside the borders
+ @border-top-left-iradius-x/.new dim,
+ @border-top-right-iradius-x/.new dim,
+ @border-bottom-left-iradius-x/.new dim,
+ @border-bottom-right-iradius-x/.new dim,
+ @border-top-left-iradius-y/.new dim,
+ @border-top-right-iradius-y/.new dim,
+ @border-bottom-left-iradius-y/.new dim,
+ @border-bottom-right-iradius-y/.new dim,
+ % computed inner corner coordinates (center of inner-radius) (where 0,0 is bottom-left)
+ @border-top-left-ix/.new length,
+ @border-top-left-iy/.new length,
+ @border-top-right-ix/.new length,
+ @border-top-right-iy/.new length,
+ @border-bottom-left-ix/.new length,
+ @border-bottom-left-iy/.new length,
+ @border-bottom-right-ix/.new length,
+ @border-bottom-right-iy/.new length,
+ % computed corner division angle
+ @border-top-left-phi/.new length,
+ @border-top-right-phi/.new length,
+ @border-bottom-left-phi/.new length,
+ @border-bottom-right-phi/.new length,
+ % computed various
+ @side/.new choice = {top,right,bottom,left,break-bottom,break-top},
+ @side-horizontal/.new toggle,
+}
+
+\newcommand\fbox@adjustoptions{%
+ %\typeout{ regular fbox adjustoptions}%
+ % set width of borders with style none to 0
+ \def\do##1{%
+ \ifoptionequal{/fbox/border-##1-style}{hidden}{\option@invoke{/fbox/border-##1-style}{none}}{}%
+ \ifoptionequal{/fbox/border-##1-style}{none}{%
+ \options{/fbox/border-##1-width=0pt}%
+ }{}%
+ }%
+ \docsvlist{top,right,bottom,left,break-bottom,break-top}%
+ \options{%
+ /longbox/skip-left=
+ \option{/fbox/border-left-width} + \option{/fbox/padding-left} + \option{/fbox/margin-left},
+ /longbox/skip-right=
+ \option{/fbox/border-right-width} + \option{/fbox/padding-right} + \option{/fbox/margin-right},
+ /longbox/skip-top=
+ \option{/fbox/border-top-width} + \option{/fbox/padding-top} + \option{/fbox/margin-top},
+ /longbox/skip-bottom=
+ \option{/fbox/border-bottom-width}+\option{/fbox/padding-bottom}+\option{/fbox/margin-bottom},
+ /longbox/skip-break-top=
+ \option{/fbox/border-break-top-width} + \option{/fbox/padding-break-top} + \option{/fbox/margin-break-top},
+ /longbox/skip-break-bottom=
+ \option{/fbox/border-break-bottom-width}+\option{/fbox/padding-break-bottom}+\option{/fbox/margin-break-bottom},
+ }%
+ \longbox@adjustoptions%
+}
+
+\newenvironment{longfbox}[1][]{%
+ \begin{longbox@env}{/fbox}{/longbox/render={\protect\fbox@render},/longbox/adjust-options={\protect\fbox@adjustoptions},#1}%
+}{\end{longbox@env}}
+
+\newcommand\lfbox[2][]{%
+ \begingroup
+ \longbox@cmd{/fbox}{/longbox/render={\protect\fbox@render},/longbox/adjust-options={\protect\fbox@adjustoptions},#1}{#2}%
+ \endgroup
+}
+
+\newcommand*\newfboxstyle[2]{%
+ \options{/fbox,#1/.new style* = {#2}}%
+}
+
+\newfboxstyle{rounded}{border-radius=1ex}
+\newfboxstyle{tight}{padding=0pt,margin=0pt,baseline-skip=false}
+\newfboxstyle{dotted}{border-width=0.8pt,border-style=dotted}
+
+\newcommand*\fboxset[1]{%
+ \options{/fbox,#1}%
+} \ No newline at end of file