% \iffalse meta-comment % % Copyright (C) 2025 Fabian Fuchs % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % The latest version of the LaTeX Project Public % License can be found under: % % http://www.latex-project.org/lppl.txt % % % \fi % % \iffalse %\NeedsTeXFormat{LaTeX2e}[2023-11-01] %\ProvidesPackage{beamer-varbox} % [2025/09/11 A package providing beamer boxes with variable size corners] % %<*driver> \documentclass{ltxdoc} \usepackage{beamer-varbox} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{beamer-varbox.dtx} \end{document} % % \fi % % \changes{v1.0}{2025-09-11}{Initial version} % % \GetFileInfo{beamer-varbox.sty} % % \DoNotIndex{⟨list of control sequences⟩} % \NewDocElement{Opt}{option} % % \title{The \textsf{beamer-varbox} package\thanks{This document % corresponds to \textsf{beamer-varbox}~\fileversion, % dated \filedate.}} % \author{Fabian Fuchs \\ \texttt{fabian.m.fuchs@gmail.com}} % % \maketitle % % \begin{abstract} % A package providing beamer boxes with variable size corners. % \end{abstract} % % \section{Usage} % Loading the package provides the \texttt{variable rounded} predefined option for % the beamer elements \texttt{block begin}, \texttt{block alerted begin}, % \texttt{block example begin}, \texttt{block end}, \texttt{block alerted end}, and % \texttt{block example end} and sets them as default. (It is assumed that if you include the % package, you want the modified blocks) % % \section{Options} % % \DescribeOpt{cornerpercent} % The package has one option, |cornerpercent|, that describes the scale of corner arc % relative to the standard rounded predefined option provided by the beamer class. % It is a keyword option that takes values between 0 and 1 (inclusive) and can be called either % when including the package as\\ % \vspace{1ex} % |\usepackage| [cornerpercent=⟨\textit{value}⟩] \{beamer-varbox\}\\ % \vspace{1ex} % or when setting the template manually as, e.g.,\\ % \vspace{1ex} % |\setbeamertemplate| \marg{element name} [variable rounded] [cornerpercent=⟨\textit{value}⟩]\\ % \vspace{1ex} % % \MaybeStop{\PrintIndex} % % \section{Implementation} % \begin{macrocode} % Check that beamer class is loaded % \@ifclassloaded{beamer}{}{% \PackageError{beamer-varbox}{% This package needs the beamer class.\MessageBreak To use this package, load the beamer class. }{% The package could not be loaded, because it needs\MessageBreak beamer class to function. }% \endinput } % Require xkeyval to do "modern" package keyval handling \RequirePackage{xkeyval} \DeclareOptionX{cornerpercent}[0.3]{\def\beamer@cornerpercentdefault{#1}} \ExecuteOptionsX{cornerpercent=0.3} \ProcessOptionsX\relax % Define 0 to compare against \def\bmb@zero{0} % % Define used keys % \define@key{beamerboxes}{scheme}{\def\bmb@upper{@scheme upper #1}\def\bmb@lower{@scheme lower #1}} \define@key{beamerboxes}{upper}{\def\bmb@upper{#1}} \define@key{beamerboxes}{lower}{\def\bmb@lower{#1}} \define@key{beamerboxes}{width}{\edef\bmb@width{#1}} \define@key{beamerboxes}{shadow}[true]{\csname bmb@shadow#1\endcsname} \define@key{beamerboxes}{cornerpercent}{\def\bmb@cornerpercent{#1}} % Define neeeded variables \newif\ifbmb@shadow \newbox\bmb@box \newbox\bmb@colorbox \newdimen\bmb@boxwidth \newdimen\bmbboxheight \newdimen\bmb@prevheight \newdimen\bmb@temp \newdimen\bmb@dima \newdimen\bmb@dimb \newdimen\bmb@dimc \newdimen\bmb@prevheight \newdimen\bmb@supportcorner \newdimen\bmb@initstart \newdimen\bmb@advance % % The below is adapted from the beamer package % files beamerbaseboxes.sty and beamerbaseauxtemplates.sty. % Authors of those files are: % Till Tantau, Vedran Mileti\'c, Joseph Wright, % Louis Stuart, and samcarter. % Thanks for the work!! % \newcommand\beamerboxesvariablerounded[2][]{% \global\let\beamer@firstlineitemizeunskip=\relax% \vbox\bgroup% \setkeys{beamerboxes}{upper=block title,lower=block body,width=\textwidth,shadow=false,cornerpercent=\beamer@cornerpercentdefault}% \setkeys{beamerboxes}{#1}% {% \usebeamercolor{\bmb@lower}% \globalcolorstrue% \colorlet{lower.bg}{bg}% }% {% \usebeamercolor{\bmb@upper}% \globalcolorstrue% \colorlet{upper.bg}{bg}% }% % % Typeset head % \vskip4bp \setbox\bmb@box=\hbox{% \begin{minipage}[b]{\bmb@width}% \usebeamercolor[fg]{\bmb@upper}% #2% \end{minipage}}% \ifdim\wd\bmb@box=0pt% \setbox\bmb@box=\hbox{}% \ht\bmb@box=1.5pt% \bmb@prevheight=-4.5pt% \else% \wd\bmb@box=\bmb@width% \bmb@temp=\dp\bmb@box% \ifdim\bmb@temp<1.5pt% \bmb@temp=1.5pt% \fi% \setbox\bmb@box=\hbox{\raise\bmb@temp\hbox{\box\bmb@box}}% \dp\bmb@box=0pt% \bmb@prevheight=\ht\bmb@box% \fi% % % % \ifdim\bmb@cornerpercent pt >1pt \PackageError{beamer-varbox}{% The key cornerpercent is above 1.\MessageBreak The key is allowed to take values in between 0 and 1 (inclusive)% }{% cornerpercent is allowed to be between 0 and 1 (inclusive)% }% \fi % % Check if the corners should be sharp % \if\bmb@cornerpercent\bmb@zero \bmb@temp=\bmb@width% \bmb@dima=\bmb@temp\advance\bmb@dima by8bp% \bmb@dimc=-\ht\bmb@box\advance\bmb@dimc by-2pt% \hbox{% \begin{pgfpicture}{0bp}{+-\ht\bmb@box}{0bp}{+-\ht\bmb@box} \ifdim\wd\bmb@box=0pt% \color{lower.bg}% \pgfsetfillopacity{0} \else% \color{upper.bg}% \fi% \pgfpathqmoveto{-4bp}{\bmb@dimc}% \pgfpathqlineto{-4bp}{3bp}% \pgfpathqlineto{\bmb@dima}{3bp}% \pgfpathqlineto{\bmb@dima}{\bmb@dimc}% \pgfsetlinewidth{1.5pt} \pgfusepath{fill,stroke} \end{pgfpicture}% \copy\bmb@box% }% \else % % Calculate dimensions for adjusted corner % \bmb@supportcorner=\dimexpr\bmb@cornerpercent\dimexpr1.8bp\relax\relax% \bmb@initstart=\dimexpr 4bp-\bmb@cornerpercent\dimexpr4bp\relax\relax% \bmb@advance=\dimexpr \bmb@initstart+\bmb@cornerpercent\dimexpr2.2bp\relax\relax% % Calculate aux sizes \bmb@temp=\bmb@width% \bmb@dima=\bmb@temp\advance\bmb@dima by\bmb@advance% \bmb@dimb=\bmb@temp\advance\bmb@dimb by4bp% \bmb@dimc=-\ht\bmb@box\advance\bmb@dimc by-2pt% \hbox{% \begin{pgfpicture}{0bp}{+-\ht\bmb@box}{0bp}{+-\ht\bmb@box} \ifdim\wd\bmb@box=0pt% \color{lower.bg}% \pgfsetfillopacity{0} \else% \color{upper.bg}% \fi% \pgfpathqmoveto{-4bp}{\bmb@dimc} \pgfpathlineto{\pgfpoint{-4bp}{-1bp+\bmb@initstart}} \pgfpathcurveto% Upper left corner {\pgfpoint{-4bp}{3bp-\bmb@supportcorner}}% {\pgfpoint{-4bp+\bmb@supportcorner}{3bp}}% {\pgfpoint{-\bmb@initstart}{3bp}}% \pgfpathlineto{\pgfpoint{\bmb@temp+\bmb@initstart}{3bp}} \pgfpathcurveto% Upper right corner {\pgfpoint{\bmb@dima}{3bp}}% {\pgfpoint{\bmb@dimb}{3bp-\bmb@supportcorner}}% {\pgfpoint{\bmb@dimb}{-1bp+\bmb@initstart}}% \pgfpathqlineto{\bmb@dimb}{-1bp}% \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dimc}} \pgfsetlinewidth{1.5pt} \pgfusepath{fill,stroke} \end{pgfpicture}% \copy\bmb@box% }% \fi % of sharp corner check \nointerlineskip% \vskip-1pt% \ifdim\wd\bmb@box=0pt% \else% \vskip3pt% \fi% \setbox\bmb@colorbox=\hbox{{\pgfpicturetrue\pgfsetcolor{lower.bg}}}% \setbox\bmb@box=\hbox\bgroup\begin{minipage}[b]{\bmb@width}% \vskip2pt% \usebeamercolor[fg]{\bmb@lower}% \colorlet{beamerstructure}{upper.bg}% \colorlet{structure}{upper.bg}% } \def\endbeamerboxesvariablerounded{% \end{minipage}\egroup% \bmb@temp=\dp\bmb@box% \advance\bmb@temp by.5pt% \setbox\bmb@box=\hbox{\raise\bmb@temp\hbox{\box\bmb@box}}% \dp\bmb@box=0pt% \bmb@boxwidth=\bmb@width% \bmb@boxheight=\ht\bmb@box% \advance\bmb@boxheight by4bp% \advance\bmb@boxheight by\bmb@prevheight% \ifbmb@shadow% \xdef\beamer@storecolorhook{\beamer@colorhook} \xdef\beamer@colorhook{} \pgfdeclareradialshading{bmb@shadowball}{\pgfpointorigin} {% color(0bp)=(pgftransparent!50); color(4bp)=(pgftransparent!100) }% \pgfdeclareradialshading{bmb@shadowballlarge}{\pgfpointorigin} {% color(0bp)=(pgftransparent!0); color(8bp)=(pgftransparent!100) }% \pgfdeclarehorizontalshading{bmb@shadowhorz\the\bmb@boxheight}{\bmb@boxheight-5.5bp} {% color(0bp)=(pgftransparent!0); color(8bp)=(pgftransparent!100) }% \pgfdeclareverticalshading{bmb@shadowvert\the\bmb@boxwidth}{\bmb@boxwidth-4bp} {% color(0bp)=(pgftransparent!100); color(8bp)=(pgftransparent!0) }% \begingroup% \selectcolormodel{gray} \pgfdeclarefading{bmb@shadowmask\the\bmb@boxwidth\the\bmb@boxheight} {% \begin{pgfpicture} \pgftext[at=\pgfpoint{4bp}{4bp}]{\pgfuseshading{bmb@shadowball}}% bottom left shadow \ifdim\bmb@boxheight>9.5bp% \pgftext[at=\pgfpoint{\bmb@boxwidth}{8bp}]{\pgfuseshading{bmb@shadowballlarge}}% bottom right shadow \pgftext[at=\pgfpoint{\bmb@boxwidth+4bp}{\bmb@boxheight+2bp}]{\pgfuseshading{bmb@shadowball}}% top right shadow \pgftext[base, at=\pgfpoint{\bmb@boxwidth+4bp}{7.5bp}]{\pgfuseshading{bmb@shadowhorz\the\bmb@boxheight}}% right edge shadow \else% \pgftext[at=\pgfpoint{\bmb@boxwidth}{4bp}]{\pgfuseshading{bmb@shadowball}}% right shadow \fi% \pgftext[left, at=\pgfpoint{4bp}{4bp}]{\pgfuseshading{bmb@shadowvert\the\bmb@boxwidth}}% bottom edge % % clipping is needed because shadow is typeset on top of box \begin{pgfscope} \pgfsetcolor{beamer@safeblack} \pgfpathrectangle{\pgfpoint{4bp}{8.1bp}}{\pgfpoint{\bmb@boxwidth}{\bmb@boxheight-2bp}} \pgfusepath{fill} \end{pgfscope} \end{pgfpicture}% \hskip4bp% }% \endgroup% \fi% % % Check if the corners should be sharp % \if\bmb@cornerpercent\bmb@zero \bmb@temp=\bmb@width% \bmb@dima=\bmb@temp\advance\bmb@dima by8bp% \bmb@dimc=\ht\bmb@box \hbox{% \begin{pgfpicture}{0bp}{0bp}{0bp}{0bp} \ifbmb@shadow% \begin{pgfscope} \pgfpathrectangle{\pgfpoint{0bp}{-7bp}} {\pgfpoint{\bmb@boxwidth+8bp}{\bmb@boxheight+6bp}} \pgfsetfading{bmb@shadowmask\the\bmb@boxwidth\the\bmb@boxheight}{% \pgftransformshift{\pgfpoint{0.5\bmb@boxwidth+6bp}{0.5\bmb@boxheight-4bp}}} \pgfusepath{fill} \end{pgfscope} \fi% \unhbox\bmb@colorbox% \pgfpathqmoveto{-4bp}{\bmb@dimc}% \pgfpathqlineto{-4bp}{-3bp}% \pgfpathqlineto{\bmb@dima}{-3bp}% \pgfpathqlineto{\bmb@dima}{\bmb@dimc}% \pgfsetlinewidth{1.5pt} \pgfusepath{stroke} \end{pgfpicture}% \box\bmb@box% }% \else \bmb@temp=\bmb@width% \bmb@dima=\bmb@temp\advance\bmb@dima by\bmb@advance% \bmb@dimb=\bmb@temp\advance\bmb@dimb by4bp% \hbox{% \begin{pgfpicture}{0bp}{0bp}{0bp}{0bp} \ifbmb@shadow% \begin{pgfscope} \pgfpathrectangle{\pgfpoint{0bp}{-7bp}} {\pgfpoint{\bmb@boxwidth+8bp}{\bmb@boxheight+6bp}} \pgfsetfading{bmb@shadowmask\the\bmb@boxwidth\the\bmb@boxheight}{% \pgftransformshift{\pgfpoint{0.5\bmb@boxwidth+6bp}{0.5\bmb@boxheight-4bp}}} \pgfusepath{fill} \end{pgfscope} \fi% \unhbox\bmb@colorbox% \bmb@dimc=\ht\bmb@box \pgfpathqmoveto{-4bp}{\bmb@dimc} \pgfpathlineto{\pgfpoint{-4bp}{1bp-\bmb@initstart}} \pgfpathcurveto% Lower left corner {\pgfpoint{-4bp}{-3bp+\bmb@supportcorner}}% {\pgfpoint{-4bp+\bmb@supportcorner}{-3bp}}% {\pgfpoint{-\bmb@initstart}{-3bp}}% \pgfpathlineto{\pgfpoint{\bmb@temp+\bmb@initstart}{-3bp}} \pgfpathcurveto% Lower right corner {\pgfpoint{\bmb@dima}{-3bp}}% {\pgfpoint{\bmb@dimb}{-3bp+\bmb@supportcorner}}% {\pgfpoint{\bmb@dimb}{1bp-\bmb@initstart}}% \pgfpathqlineto{\bmb@dimb}{-1bp}% \pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dimc}} \pgfsetlinewidth{1.5pt} \pgfusepath{stroke} \end{pgfpicture}% \box\bmb@box% }% \fi% of corner check \ifbmb@shadow% \vskip4bp minus 2bp% \else% \vskip2bp% \fi% \egroup% of \vbox\bgroup \ifbmb@shadow% \xdef\beamer@colorhook{\beamer@storecolorhook} \fi } \defbeamertemplate*{block begin}{variable rounded}[1][shadow=false]% {% \par\vskip\medskipamount% \begin{beamerboxesvariablerounded}[upper=block title,lower=block body,#1]% {\raggedright\usebeamerfont*{block title}\insertblocktitle}% \raggedright% \usebeamerfont{block body}% }% \defbeamertemplate*{block end}{variable rounded}% {% \end{beamerboxesvariablerounded}\vskip\smallskipamount }% \defbeamertemplate*{block alerted begin}{variable rounded}[1][shadow=false] {% \par\vskip\medskipamount% \begin{beamerboxesvariablerounded}[upper=block title alerted,lower=block body alerted,#1]% {\raggedright\usebeamerfont*{block title alerted}\insertblocktitle}% \raggedright% \usebeamerfont{block body alerted}% }% \defbeamertemplate*{block alerted end}{variable rounded}[1][] { \end{beamerboxesvariablerounded}\vskip\smallskipamount } \defbeamertemplate*{block example begin}{variable rounded}[1][shadow=false] {% \par\vskip\medskipamount% \begin{beamerboxesvariablerounded}[upper=block title example,lower=block body example,#1] {\raggedright\usebeamerfont*{block title example}\insertblocktitle}% \raggedright% \usebeamerfont{block body example}% }% \defbeamertemplate*{block example end}{variable rounded}[1][] {\end{beamerboxesvariablerounded}\vskip\smallskipamount} % \end{macrocode} % % \Finale \endinput