我想要设计一个tikz
使用不同背景路径用于不同目的的形状。
考虑以下最小示例,其中simple rectangle
声明了一个名为的新形状。用于填充形状的背景路径与用于其他目的(如绘图或裁剪)的背景路径不同:填充不包括基线以下的文本区域。
\documentclass[tikz]{standalone}
\makeatletter
\pgfdeclareshape{simple rectangle}{
\savedanchor{\upperrightcorner}{
\pgf@x=.5\wd\pgfnodeparttextbox % widht of the box
\pgf@y=.5\ht\pgfnodeparttextbox % height of the box, ignoring the depth
}
\saveddimen{\depth}{
\pgf@x=\dp\pgfnodeparttextbox
}
\anchor{north east}{
\upperrightcorner
}
\anchor{center}{
\pgfpointorigin
}
\anchor{text}{
\upperrightcorner
\pgf@x=-\pgf@x
\pgf@y=-\pgf@y
}
\backgroundpath{
\tikz@mode
\upperrightcorner
\pgf@xa=-\pgf@x
\pgf@ya=-\pgf@y
\iftikz@mode@draw
\advance \pgf@ya by -\depth
\fi
\pgfpathrectanglecorners{\upperrightcorner}{\pgfpoint{\pgf@xa}{\pgf@ya}}
}
}
\makeatother
\begin{document}
\huge
\begin{tikzpicture}
\node at (0,3) [simple rectangle]{This is my test.};
\node at (0,2) [simple rectangle,fill=yellow!40]{This is my test.};
\node at (0,1) [simple rectangle,draw]{This is my test.};
\node at (0,0) [simple rectangle,fill=yellow!40,draw]{This is my test.};
\end{tikzpicture}
\end{document}
正如您所见,此示例仅当填充未与其他操作(如绘图)结合时才有效。
如何解决这个问题?
答案1
这是一种简化,但是一旦您开始填充和绘制路径,路径基本上就是固定的:路径的“形状”与参数(例如,线宽、虚线图案)或应用的操作(例如,填充或绘制等)无关。
因此,根据操作是fill
或来创建不同的路径draw
不受支持,(我认为)在一般情况下实现起来将是一场噩梦,而且我不确定这样做是否合乎逻辑。
但这behind background path
很容易说明:
\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\makeatletter
\pgfkeys{/pgf/.cd,
simple rectangle fill/.store in=\pgf@lib@sh@simplerectangle@fill,
simple rectangle fill=}
\pgfdeclareshape{simple rectangle}{
\saveddimen{\width}{\pgf@x=\wd\pgfnodeparttextbox}
\saveddimen{\height}{\pgf@x=\ht\pgfnodeparttextbox}
\saveddimen{\depth}{\pgf@x=\dp\pgfnodeparttextbox}
\saveddimen{\innerxsep}{\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}}
\saveddimen{\innerysep}{\pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner ysep}}}
\anchor{center}{\pgfpoint{\width/2}{\height-\depth}}
\backgroundpath{
\pgfpathrectanglecorners{\pgfpoint{-\innerxsep}{-\depth-\innerysep}}%
{\pgfpoint{\width+\innerxsep}{\height+\innerysep}}
}
\behindbackgroundpath{%
% Only set the behind background path if
% \pgf@lib@sh@simplerectangle@fill is not empty
\ifx\pgf@lib@sh@simplerectangle@fill\pgfutil@empty%
\else%
\pgfpathrectanglecorners{\pgfpoint{-\innerxsep}{0pt}}%
{\pgfpoint{\width+\innerxsep}{\height+\innerysep}}%
\pgfsetfillcolor{\pgf@lib@sh@simplerectangle@fill}%
\pgfusepath{fill}%
\fi%
}
}
\begin{document}
\begin{tikzpicture}
\node [simple rectangle, draw] at (0,0) {Test 1};
\node [simple rectangle, draw, simple rectangle fill=red!20] at (0,-1) {Test 2};
\end{tikzpicture}
\end{document}