我正在创建一个环境,在其中我可以添加许多 PSTricks 对象(基本上是形状,定义为宏,垂直排列),每个对象都有参数(形状的内容),所以我不知道每个对象的实际高度。
我现在面临两个问题:
为了节省图片周围的空间,我不知道整个图片的尺寸!我可以轻松计算它们,但我不知道如何使用它们。目前,整个图片的尺寸为零(PSTricks 的正常行为)。如果我将图片包装成图片环境,我知道我可以输入坐标,但在绘制所有形状之前我不知道它们......
我希望能够将图片周围文本的基线与某个特定形状的内容的基线对齐。我考虑过使用带形状编号的节点,但没有成功,因为我无法事先知道它们的位置。我还尝试了图片环境,以便使用转移选项,但同样的问题仍然存在:如何指定稍后计算的值...此外,整个图片可能会缩放,因此它会修改基线位置。:(
(我知道我可以用 Ti 轻松实现这一点钾Z 及其基线和规模选项,但我想用 PSTricks 来实现)。
如果您能帮助我,我提前谢谢您。
下面是一段只有两种不同形状的代码,有和没有图片包裝。
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{pstricks}
\usepackage{pstricks-add}
% shapes position
\newdimen\verticalOffset
\verticalOffset=0pt
% space between shapes
\newdimen\verticalSep
\verticalSep=15pt
\newsavebox{\shapebox}
% rectangle shape
\newcommand*{\shapeR}[1]{%
\setbox\shapebox\hbox{\hspace{10pt}\bfseries#1\hspace{10pt}\vrule height20pt depth10pt width0pt\relax}%
\rput[Bl](0,\verticalOffset){%
\psframe(0,0)(\the\dimexpr\wd\shapebox,\the\dimexpr-\ht\shapebox-\dp\shapebox)%
\rput[Bl](0,\the\dimexpr-\ht\shapebox){\copy\shapebox}%
}%
\advance\verticalOffset\dimexpr-\ht\shapebox-\dp\shapebox-\verticalSep\relax%
}
% oval shape
\newcommand*{\shapeO}[1]{%
\setbox\shapebox\hbox{\hspace{15pt}\bfseries#1\hspace{15pt}\vrule height25pt depth15pt width0pt\relax}%
\rput[Bl](0,\verticalOffset){%
\psellipse(\the\dimexpr\wd\shapebox/2,\the\dimexpr-\ht\shapebox/2-\dp\shapebox/2)(\the\dimexpr\wd\shapebox/2,\the\dimexpr\ht\shapebox/2+\dp\shapebox/2)%
\rput[Bl](0,\the\dimexpr-\ht\shapebox){\copy\shapebox}%
}%
\advance\verticalOffset\dimexpr-\ht\shapebox-\dp\shapebox-\verticalSep\relax%
}
\newsavebox{\drawbox}
% drawing env
\newenvironment{drawWithoutPspic}[1]%
{% begin def
\def\drawscalefactor{#1}%
\verticalOffset=0pt%
\begin{lrbox}{\drawbox}%
}
{% end def
\end{lrbox}%
\psscalebox{\drawscalefactor}{\usebox{\drawbox}}%
}
% drawing env, shapes wrapped into a pspicture
\newenvironment{drawWithPspic}[1]%
{% begin def
\def\drawscalefactor{#1}%
\verticalOffset=0pt%
\begin{lrbox}{\drawbox}%
\begin{pspicture}[shift=0](0,0)(0,0)% <---- ??
}
{% end def
\end{pspicture}%
\end{lrbox}%
\psscalebox{\drawscalefactor}{\usebox{\drawbox}}%
}
\begin{document}
Without \emph{pspicture}
\begin{drawWithoutPspic}{0.9}
\shapeR{Hello World!}\shapeO{Foo bar baz}\shapeO{Ooooohhhhhh!}\shapeR{D/L}
\end{drawWithoutPspic}
\vspace{180pt}
With \emph{pspicture}
\begin{drawWithPspic}{0.7}
\shapeR{Hello World!}\shapeO{Foo bar baz}\shapeO{Ooooohhhhhh!}\shapeR{D/L}
\end{drawWithPspic}
\end{document}
这里是图片:
编辑-一个解决方案
好吧,我终于得到了我想要的东西。考虑到我明确地放置了具有精确长度的形状和文本,我决定使用垂直偏移来确定图片的高度,并添加了新的长度和形状编号来确定特定形状的哪些文本将位于基线上。
现在,环境需要两个参数:第一个是比例因子,第二个是基线的形状编号。
这是代码。
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{pstricks}
\usepackage{pstricks-add}
% shapes position
\newdimen\verticalOffset
\verticalOffset=0pt
% space between shapes
\newdimen\verticalSep
\verticalSep=15pt
% baseline position
\newdimen\baselineOffset
\baselineOffset=0pt
% shapes counter
\newcounter{shapeno}
\newsavebox{\shapebox}
% rectangle shape
\newcommand*{\shapeR}[1]{%
\ifdim \verticalOffset = 0pt%
\else%
\global\advance\verticalOffset\dimexpr-\verticalSep\relax%
\fi%
\setbox\shapebox\hbox{\hspace{2pt}\bfseries#1\hspace{2pt}\vrule height14pt depth5pt width0pt\relax}%
\rput[Bl](0,\verticalOffset){%
\psframe(0,0)(\the\dimexpr\wd\shapebox,\the\dimexpr-\ht\shapebox-\dp\shapebox)%
\rput[Bl](0,\the\dimexpr-\ht\shapebox){\copy\shapebox}%
}%
\ifnum\theshapeno = 1%
\global\baselineOffset=\dimexpr\verticalOffset-\ht\shapebox\relax%
\else%
\ifnum\theshapeno = \baselineno%
\global\baselineOffset=\dimexpr\verticalOffset-\ht\shapebox\relax%
\fi%
\fi%
\global\advance\verticalOffset\dimexpr-\ht\shapebox-\dp\shapebox\relax%
\stepcounter{shapeno}%
\ignorespaces
}
% oval shape
\newcommand*{\shapeO}[1]{%
\ifdim \verticalOffset = 0pt%
\else%
\global\advance\verticalOffset\dimexpr-\verticalSep\relax%
\fi%
\setbox\shapebox\hbox{\hspace{2pt}\bfseries#1\hspace{2pt}\vrule height18pt depth10pt width0pt\relax}%
\rput[Bl](0,\verticalOffset){%
\psellipse(\the\dimexpr\wd\shapebox/2,\the\dimexpr-\ht\shapebox/2-\dp\shapebox/2)(\the\dimexpr\wd\shapebox/2,\the\dimexpr\ht\shapebox/2+\dp\shapebox/2)%
\rput[Bl](0,\the\dimexpr-\ht\shapebox){\copy\shapebox}%
}%
\ifnum\theshapeno = 1%
\global\baselineOffset=\dimexpr\verticalOffset-\ht\shapebox\relax%
\else%
\ifnum\theshapeno = \baselineno%
\global\baselineOffset=\dimexpr\verticalOffset-\ht\shapebox\relax%
\fi%
\fi%
\global\advance\verticalOffset\dimexpr-\ht\shapebox-\dp\shapebox\relax%
\stepcounter{shapeno}%
\ignorespaces
}
\newsavebox{\drawbox}
% drawing env, shapes wrapped into a pspicture
\newenvironment{drawWithPspic}[2]%
{% begin def
\def\drawscalefactor{#1}%
\def\baselineno{#2}%
\verticalOffset=0pt%
\baselineOffset=0pt%
\setcounter{shapeno}{1}
\begin{lrbox}{\drawbox}%
}
{% end def
\end{lrbox}%
\begin{pspicture}[shift=\drawscalefactor\dimexpr\noexpand\verticalOffset-\noexpand\baselineOffset](0,\drawscalefactor\noexpand\verticalOffset)(2,0)% <--- last thing to do : calculation of the actual width
\psscalebox{\drawscalefactor}{\usebox{\drawbox}}%
\end{pspicture}%
}
\begin{document}
% Blue baseline
\leavevmode\rlap{\color{blue}\rule{\linewidth}{.1pt}}%
...text before...
% Red baseline
\leavevmode\rlap{\color{orange}\rule{\linewidth}{.1pt}}%
Aligned with 2\textsuperscript{nd} shape :
\begin{drawWithPspic}{0.5}{2}
\shapeR{Hello World!}
\shapeO{Foo bar baz}
\shapeO{Ooooohhhhhh!}
\shapeR{D/L}
\end{drawWithPspic}
\quad
Aligned with 3\textsuperscript{th} shape :
\begin{drawWithPspic}{0.6}{3}
\shapeR{Hello World!}
\shapeO{Foo bar baz}
\shapeO{Ooooohhhhhh!}
\shapeR{D/L}
\shapeO{Hi!}
\end{drawWithPspic}
% Blue baseline
\leavevmode\rlap{\color{blue}\rule{\linewidth}{.1pt}}%
...text after...
\end{document}
答案1
我也不知道如何按照您描述的方式计算边界框,但我不确定您是否需要这样做。所有形状都可以方便地定义为节点,它们有自己的边界框。以下是几个示例:
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{pstricks}
\usepackage{pstricks-add,pst-blur}
% shapes position
\newdimen\verticalOffset
\verticalOffset=0pt
% space between shapes
\newdimen\verticalSep
\verticalSep=15pt
\newcommand{\boxnode}[2]{\rnode[c]{#1}{\psframebox[framearc=0.2]{#2}}}
\begin{document}
Again without \emph{pspicture}:
\begin{flushleft}
\boxnode{A}{Hello World!}\\[0.1cm]
\ovalnode{B}{Foo bar bz}\\[0.1cm]
\ovalnode{C}{Ooooohhhhhh!}\\[0.1cm]
\boxnode{D}{D/L}
\end{flushleft}
\renewcommand{\boxnode}[2]{\rnode[c]{#1}{\psframebox[framearc=0.2,shadow=true,blur=true]{#2}}}
And here we go on.
\begin{flushleft}
\boxnode{E}{Hello World!}\\[0.1cm]
\ovalnode[shadow=true,blur=true]{F}{Foo bar bz}\\[0.1cm]
\ovalnode[shadow=true,blur=true]{G}{Ooooohhhhhh!}\\[0.1cm]
\boxnode{H}{D/L}\ncarc[linecolor=blue]{->}{G}{H}
\end{flushleft}
\begin{tabular}{ll}
&\boxnode{I}{Hello World!}\\[0.1cm]
aligned with the second \rnode[r]{shape}{shape}:&\ovalnode[shadow=true,blur=true]{J}{Foo bar bz}\\[0.1cm]
&\ovalnode[shadow=true,blur=true]{K}{Ooooohhhhhh!}\\[0.1cm]
&\boxnode{L}{D/L}\ncarc[linecolor=blue]{->}{shape}{J}
\end{tabular}
\end{document}
您还可以将这些东西放入比例框中,当然还有表格等。您可以用它们做很多事情,而无需明确启动 pspicture。如图所示,您可以用弧线将它们连接起来,但还有许多其他事情,例如参见 pstricks 手册第 31 节。