[Tex/LaTex] Rounded corners not working in \mdf@singleextra using mdframed with TikZ

mdframedpage-breakingrounded-cornerstikz-pgf

I am creating new framed environments using the mdframed package (along with TikZ) based on the digression example given in mdframed-example-texsx.tex. My code is the following:

\documentclass{scrartcl}

\usepackage{times}

\usepackage{lipsum}
\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
\usepackage{tikz}
   \usetikzlibrary{calc,arrows,shadows}
\usepackage[framemethod=tikz]{mdframed}


\tikzset{
    title/.style={
      fill=white,
      font=\normalfont,
      text=black,
      anchor=base west,
    },
    contour/.style = {
      line width = 0.6pt,
      draw = black,
      rounded corners = 2ex,
    },
    fakeshadow/.style = {
      line width = 4.5pt,
      draw = white,
    },
}

\newcommand{\definitiontitle}{
  {\scshape \bfseries \Large Definition}
}

\mdfdefinestyle{definition}{%
    singleextra={%
          %% Store (O) in \p1, store (P) in \p2. Now \p1=(\x1,\y1) and \p2=(\x2,\y2). From that, define (Q) = (\x1,\y2).
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path let \p1=(O), \p2=(Q) in (\x1,{(\y1+\y2)/2}) coordinate (M);
          \path[contour] (M) |- (P) |- (O) -- (M);
          \node[title, anchor=west, xshift=18pt - 5pt] at (Q) {\definitiontitle};
    },
    firstextra={%
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path[contour] (O) -- (Q) -- (P) -- (R);
          \node[title, anchor=west, xshift=18pt - 5pt] at (Q) {\definitiontitle};
          \path[fakeshadow] ($(O)+(1pt,-1.5pt)$) -- ($(R)+(-1pt,-1.5pt)$);  %% Hide the bottom shadow
    },
    secondextra={%
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path[contour] (Q) -- (O) -- (R) -- (P);
    },
    middleextra={%
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path[contour] (O) -- (Q);
          \path[contour] (P) -- (R);
          \path[fakeshadow] ($(O)+(1pt,-1.5pt)$) -- ($(R)+(-1pt,-1.5pt)$);  %% Hide the bottom shadow
    },
    align=center,
    backgroundcolor=yellow,
    userdefinedwidth=.9\textwidth,
    middlelinewidth=1.7em,middlelinecolor=white,
    hidealllines=true,topline=true,
    innertopmargin=6pt,
    innerbottommargin=18pt,
    innerleftmargin=18pt,
    innerrightmargin=18pt,
    splitbottomskip=8pt,
    splittopskip=16pt,
    roundcorner=2ex,
    shadow=true,
    shadowsize=5,
    shadowcolor=black!40,
    %% Experimental
    needspace=3em,
    ignorelastdescenders=true,
}



\begin{document}

\lipsum[3]

\vspace{1\baselineskip}
\begin{mdframed}[style=definition]
    \lipsum[1]
\end{mdframed}

\vspace{1\baselineskip}
\lipsum[3]

\vspace{1\baselineskip}
\begin{mdframed}[style=definition]
    \lipsum[1-2]
\end{mdframed}

\vspace{1\baselineskip}
\lipsum[3]

\vspace{1\baselineskip}
\begin{mdframed}[style=definition]
    \lipsum[1-8]
\end{mdframed}

\end{document}

I am currently using TikZ to place a custom title and to draw the frame. This is required in order to use the appropriate middlelinewidth to compensate for the title height, so that mdframed will know where to split. However, I am also using rounded corners, and this is where the overall problem happens.

As pointed out by Marco Daniel in this post, it is important to use the code

    hidealllines=true,topline=true,

However, using hidealllines=true has an unexpected effect in \mdf@singleextra, i.e. the rounded corners disappear and a full box is rendered instead. This does not happen when the frame gets split (or when hidealllines=true is not used, but then the height cannot be calculated properly), as shown in the output:

output

Any idea why this happens only in the \mdf@singleextra and how to fix it?

Best Answer

The problem occurs that the the background is drawn without any rounded corners if you set the option topline=true. However you can hack the test:

\makeatletter
\let\mdf@putbox@single@orig\mdf@putbox@single
\mdfapptodefinestyle{definition}{%
  settings={%
        \def\mdf@putbox@single{%
                   \let\mdf@test@t\@gobbletwo
                   \let\mdf@test@noline\@firstoftwo
                 \mdf@putbox@single@orig
            }%
   }%
}
\makeatother

After the hack you must expand the option singlextra by the following line:

\path[draw=white,line width=1.7em,overlay] (O|-P) -- (P);

to draw a white background of your title.

The odd corner of the second page a can't reproduce.

Here the output:

enter image description here

Here the complete code:

\documentclass{scrartcl}

\usepackage{times}

\usepackage{lipsum}
\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
\usepackage{tikz}
   \usetikzlibrary{calc,arrows,shadows}
\usepackage[framemethod=tikz]{mdframed}


\tikzset{
    title/.style={
      fill=white,
      font=\normalfont,
      text=black,
      anchor=base west,
    },
    contour/.style = {
      line width = 0.6pt,
      draw = black,
      rounded corners = 2ex,
    },
    fakeshadow/.style = {
      line width = 4.5pt,
      draw = white,
    },
}

\newcommand{\definitiontitle}{
  {\scshape \bfseries \Large Definition}
}

\mdfdefinestyle{definition}{%
    singleextra={%
          %% Store (O) in \p1, store (P) in \p2. Now \p1=(\x1,\y1) and \p2=(\x2,\y2). From that, define (Q) = (\x1,\y2).
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path let \p1=(O), \p2=(Q) in (\x1,{(\y1+\y2)/2}) coordinate (M);
         \path[draw=white,line width=1.7em,overlay] (O|-P) -- (P);
          \path[contour,] (M) |- (P) |- (O) -- (M);
          \node[title, anchor=west, xshift=18pt - 5pt] at (Q) {\definitiontitle};
    },
    firstextra={%
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path[contour] (O) -- (Q) -- (P) -- (R);
          \node[title, anchor=west, xshift=18pt - 5pt] at (Q) {\definitiontitle};
          \path[fakeshadow] ($(O)+(1pt,-1.5pt)$) -- ($(R)+(-1pt,-1.5pt)$);  %% Hide the bottom shadow
    },
    secondextra={%
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path[contour] (Q) -- (O) -- (R) -- (P);
    },
    middleextra={%
          \path let \p1=(O), \p2=(P) in (\x1,\y2) coordinate (Q);
          \path let \p1=(O), \p2=(P) in (\x2,\y1) coordinate (R);
          \path[contour] (O) -- (Q);
          \path[contour] (P) -- (R);
          \path[fakeshadow] ($(O)+(1pt,-1.5pt)$) -- ($(R)+(-1pt,-1.5pt)$);  %% Hide the bottom shadow
    },
    align=center,
    backgroundcolor=yellow,
    userdefinedwidth=.9\textwidth,
    middlelinewidth=1.7em,middlelinecolor=white,
    hidealllines=true,topline=true,
    innertopmargin=6pt,
    innerbottommargin=18pt,
    innerleftmargin=18pt,
    innerrightmargin=18pt,
    splitbottomskip=8pt,
    splittopskip=16pt,
    roundcorner=2ex,
%    shadow=true,
    shadowsize=5,
    shadowcolor=black!40,
    %% Experimental
    needspace=3em,
    ignorelastdescenders=true,
}




\makeatletter
\let\mdf@putbox@single@orig\mdf@putbox@single
\mdfapptodefinestyle{definition}{%
  settings={%
        \def\mdf@putbox@single{%
                   \let\mdf@test@t\@gobbletwo
                   \let\mdf@test@noline\@firstoftwo
                 \mdf@putbox@single@orig
            }%
   }%
}
\makeatother


\begin{document}

\lipsum[3]

\vspace{1\baselineskip}
\begin{mdframed}[style=definition]
    \lipsum[1]
\end{mdframed}

\vspace{1\baselineskip}
\lipsum[3]

\vspace{1\baselineskip}
\begin{mdframed}[style=definition]
    \lipsum[1-2]
\end{mdframed}

\vspace{1\baselineskip}
\lipsum[3]

\vspace{1\baselineskip}
\begin{mdframed}[style=definition]
    \lipsum[1-8]
\end{mdframed}

\end{document}