我正在尝试在 LaTeX 中绘制带有实线或虚线的圆角矩形以及围绕任意文本的阴影。我希望我的答案是如何用阴影在框周围绘制圆角但是这些对我来说不起作用,因为 tcolorbox 和 mdframed 都需要一个新的环境,并且我想像 \fbox 一样保持圆角矩形内联。
现在我正在使用以下 TikZ 代码:
\newcommand{\solidButton}[1]{\begin{tikzpicture}[baseline=(char.base)]
\node(char)[draw,rounded corners=0.75mm,fill=white,
shape=rectangle, inner ysep=3pt, inner xsep=2pt,
drop shadow={opacity=.6,shadow xshift=2pt, shadow yshift=-1pt},
minimum width=0.6cm, minimum height=0.35cm]
{#1};
\end{tikzpicture}}
\newcommand{\dottedButton}[1]{\begin{tikzpicture}[baseline=(char.base)]
\node(char)[draw,dotted,rounded corners=0.75mm,fill=white,
shape=rectangle, inner ysep=3pt, inner xsep=2pt,
drop shadow={opacity=.6,shadow xshift=2pt, shadow yshift=-1pt},
minimum width=0.6cm, minimum height=0.35cm]
{#1};
\end{tikzpicture}}
这看上去正是我想要的样子:
... 但所有的 TikZ(我每页使用 10-20 次)都让我的文档编译速度非常慢。有没有更有效的方法来实现我想要的效果?
答案1
这个解决方案完全没有TikZ,只有pict2e
,几乎纯LaTeX图片模式。
如果这不是超速行驶,那就没有希望了。
PS=大卫卡莱尔会为我感到骄傲。
\documentclass{book}
\usepackage{xcolor}
\usepackage{graphicx}
\usepackage{pict2e}
\newlength{\myww}
\newlength{\mystep}
\setlength{\mystep}{1.8pt}
\newcommand{\solidButton}[1]{%
\settowidth{\myww}{#1}%
\addtolength{\myww}{4pt}%
\begin{picture}(\myww,14)%
\def\mypath{\moveto(2,-3)
\circlearc{2}{-1}{2}{-90}{-180}
\lineto(0,8)
\circlearc{2}{8}{2}{180}{90}
\lineto(\myww-2,10)
\circlearc{\myww-2}{8}{2}{90}{0}
\lineto(\myww,0)
\circlearc{\myww-2}{-1}{2}{0}{-90}
\lineto(2,-3)}%
\hspace{2pt}\raisebox{-1pt}{\color{lightgray}\mypath%
\fillpath}%
\hspace{-2pt}{\color{white}\mypath%
\fillpath}%
{\color{black}%
\mypath\strokepath%
\put(2,0){#1}}%
\end{picture}%
}
\newcommand{\dottedButton}[1]{%
\settowidth{\myww}{#1}%
\addtolength{\myww}{4pt}%
\begin{picture}(\myww,14)%
\def\mypath{\moveto(2,-3)
\circlearc{2}{-1}{2}{-90}{-180}
\lineto(0,8)
\circlearc{2}{8}{2}{180}{90}
\lineto(\myww-2,10)
\circlearc{\myww-2}{8}{2}{90}{0}
\lineto(\myww,0)
\circlearc{\myww-2}{-1}{2}{0}{-90}
\lineto(2,-3)}%
\hspace{2pt}\raisebox{-1pt}{\color{lightgray}\mypath%
\fillpath}%
\hspace{-2pt}{\color{white}\mypath%
\fillpath}%
\color{black}%
\put(0.6,-2.4){\circle{.3}}
\put(0.6,9.4){\circle{.3}}
\put(\myww-.6,-2.4){\circle{.3}}
\put(\myww-.6,9.4){\circle{.3}}
\multiput(0,-1)(0,\mystep){6}{\circle{.3}}
\multiput(\myww,-1)(0,\mystep){6}{\circle{.3}}
\multiput(2,10)(\mystep,0){\numexpr\myww/\mystep-1\relax}{\circle{.3}}
\multiput(2,-3)(\mystep,0){\numexpr\myww/\mystep-1\relax}{\circle{.3}}
\put(2,0){#1}%
\end{picture}%
}
\begin{document}
This is a solid box
\solidButton{Solid Button}
This is a solid box
\solidButton{ppp}
This is a solid box
\solidButton{vvv}
This is a solid box
\solidButton{ddd}
This is a solid box
This is a dotted box
\dottedButton{Dotted Button}
This is a dotted box
\dottedButton{ppp}
This is a dotted box
\dottedButton{vvv}
This is a dotted box
\dottedButton{ddd}
This is a dotted box
\end{document}
答案2
您可以使用pgf
。由于pgf
是的子层tikz
,因此速度会更快。
\documentclass{book}
\usepackage{pgf}
\newcommand{\solidButton}[1]{%
\setbox0\hbox{#1}%
\begin{pgfpicture}
\pgfset{inner ysep=3pt, inner xsep=2pt, minimum height = 0.35cm, minimum width=0.6cm }
\pgfsetbaseline{0pt}
\pgfsetcornersarced{\pgfpoint{0.75mm}{0.75mm}}
\pgftransformshift{\pgfpoint{2pt}{-1pt}}
\pgfsetfillcolor{gray!60}
\pgfnode{rectangle}{base}{\copy0}{}{\pgfusepath{fill}}
\pgftransformshift{\pgfpoint{-2pt}{1pt}}
\pgfpathmoveto{\pgfpointorigin}
\pgfsetfillcolor{white}
\pgfnode{rectangle}{base}{\box0}{}{\pgfusepath{fill,stroke}}
\end{pgfpicture}%
}
\newcommand{\dottedButton}[1]{%
\setbox0\hbox{#1}%
\begin{pgfpicture}
\pgfset{inner ysep=3pt, inner xsep=2pt, minimum height = 0.35cm, minimum width=0.6cm }
\pgfsetbaseline{0pt}
\pgfsetcornersarced{\pgfpoint{0.75mm}{0.75mm}}
\pgftransformshift{\pgfpoint{2pt}{-1pt}}
\pgfsetfillcolor{gray!60}
\pgfnode{rectangle}{base}{\copy0}{}{\pgfusepath{fill}}
\pgftransformshift{\pgfpoint{-2pt}{1pt}}
\pgfpathmoveto{\pgfpointorigin}
\pgfsetfillcolor{white}
\pgfsetdash{{0.1mm}{0.2mm}}{0cm}% line added
\pgfnode{rectangle}{base}{\box0}{}{\pgfusepath{fill,stroke}}
\end{pgfpicture}%
}
\begin{document}
This is a solid box
\solidButton{Solid Button}
This is a solid box
This is a solid box
This is a solid box
This is a solid box
This is a solid box
This is a dotted box
\dottedButton{Dotted Button}
This is a dotted box
This is a dotted box
This is a dotted box
This is a dotted box
\end{document}
答案3
使用tcolorbox
,您可以定义自己的盒子。
不幸的是,正如 user3486184 所评论的,这并不比 TikZ 更快。
\documentclass{book}
\usepackage{tcolorbox}
\tcbuselibrary{skins}
\tcbset{
enhanced,
tcbox raise base,
nobeforeafter,
colback=white,
top=0pt,
bottom=0pt,
left=0pt,
right=0pt,
arc=2pt,
}
\newtcbox{\solidButton}{
colframe=black,
boxrule=.5pt,
shadow={1.6pt}{-.8pt}{0pt}{lightgray},
}
\newtcbox{\dottedButton}{
colframe=white,
boxrule=0pt,
borderline={.6pt}{0pt}{black, dotted},
shadow={1.8pt}{-.8pt}{0pt}{lightgray},
}
\begin{document}
This is a solid box
\solidButton{Solid Button}
This is a solid box
This is a solid box
This is a solid box
This is a solid box
This is a solid box
This is a dotted box
\dottedButton{Dotted Button}
This is a dotted box
This is a dotted box
This is a dotted box
This is a dotted box
\end{document}
答案4
这更像是一个扩展的评论,而不是一个答案。
我能想到三种方法来解决这个问题。
简化路径生成。您在另一个答案中建议直接使用 pgf 代码而不是 tikz,但即使这样也可以进一步简化。您不需要节点的完整结构,只需测量包含文本的 hbox 并使用它来绘制路径。更极端的是,您甚至可以让代码直接生成 PDF 文字。
每次只生成一次路径。有多种方法可以做到这一点。一种极端情况是,你可以将每个单独的框(及其内容)外部化。另一种情况是,你只需在创建每个路径后将其保存到辅助文件中(我的
spath3
库可以做到这一点),因此你仍然需要花费渲染的代价,但不需要进行任何计算。仅在文档完成后才渲染方框。因此,在编写文档时,您可以使用草稿模式,其中不会绘制方框,并且仅在文档本身到位时才打开它们。这遵循了 TeX 分离样式和内容的范例。这可能是最简单的解决方案,当然,如果它只适用于一个文档,那么简单性也是一个重要因素。