Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The below MWE draws a number of rectangles using low-level pgf commands, each specified with a different unit that Latex understands. However, pgf doesn't seem to be able to determine the relative units ex, em and sp. Is there a reason for that?

By way of context, I was trying to declare a new shape with a size relative to the current text. As the shape isn't meant to contain any text, it seemed a better approach than making it relative to a non-existent \pgfnodeparttextbox. If pgf can't cope with relative units in this context, is there a better approach to setting the initial size of a shape?

Boxes drawn with different units in pgf

\documentclass[a4paper]{article}
\usepackage{tikz}

\begin{document}

\newdimen\ptdim
\newdimen\pcdim
\newdimen\indim
\newdimen\bpdim
\newdimen\cmdim
\newdimen\mmdim
\newdimen\dddim
\newdimen\ccdim
\newdimen\spdim
\newdimen\exdim
\newdimen\emdim

\begin{tikzpicture}
  \ptdim=12pt
  \pcdim=2pc
  \indim=2in
  \bpdim=100bp
  \cmdim=3cm
  \mmdim=20mm
  \dddim=40dd
  \ccdim=10cc
  \spdim=500sp
  \exdim=5ex
  \emdim=5em
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\ptdim}{\ptdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\pcdim}{\pcdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\indim}{\indim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\bpdim}{\bpdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\cmdim}{\cmdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\mmdim}{\mmdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\dddim}{\dddim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\ccdim}{\ccdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\spdim}{\spdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\exdim}{\exdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\emdim}{\emdim}}
  \pgfusepath{stroke}
  \node[below] at (\ptdim,0) {pt};
  \node[below] at (\pcdim,0) {pc};
  \node[below] at (\indim,0) {in};
  \node[below] at (\bpdim,0) {bp};
  \node[below] at (\cmdim,0) {cm};
  \node[below] at (\mmdim,0) {mm};
  \node[below] at (\dddim,0) {dd};
  \node[below] at (\ccdim,0) {cc};
  \node[below] at (\spdim,0) {sp};
  \node[below] at (\exdim,0) {ex};
  \node[below] at (\emdim,0) {em};
\end{tikzpicture}
\end{document}
share|improve this question

2 Answers 2

In a TikZ picture, the current font is set to \nullfont, generally, in order to avoid casual typesetting; this font has all parameters equal to zero, so 1em = 1ex = 0pt when the font is \nullfont. On the other hand, 1sp is very small, because 65536sp=1pt, so it's almost impossible to appreciate a displacement by 500sp.

Just set the lengths before entering the picture:

\documentclass[a4paper]{article}
\usepackage{tikz}

\begin{document}

\newdimen\ptdim
\newdimen\pcdim
\newdimen\indim
\newdimen\bpdim
\newdimen\cmdim
\newdimen\mmdim
\newdimen\dddim
\newdimen\ccdim
\newdimen\spdim
\newdimen\exdim
\newdimen\emdim

  \ptdim=12pt
  \pcdim=2pc
  \indim=2in
  \bpdim=100bp
  \cmdim=3cm
  \mmdim=20mm
  \dddim=40dd
  \ccdim=10cc
%  \spdim=500sp
  \exdim=5ex
  \emdim=5em
\begin{tikzpicture}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\ptdim}{\ptdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\pcdim}{\pcdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\indim}{\indim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\bpdim}{\bpdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\cmdim}{\cmdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\mmdim}{\mmdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\dddim}{\dddim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\ccdim}{\ccdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\spdim}{\spdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\exdim}{\exdim}}
  \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{\emdim}{\emdim}}
  \pgfusepath{stroke}
  \node[below] at (\ptdim,0) {pt\vphantom{pb}};
  \node[below] at (\pcdim,0) {pc\vphantom{pb}};
  \node[below] at (\indim,0) {in\vphantom{pb}};
  \node[below] at (\bpdim,0) {bp\vphantom{pb}};
  \node[below] at (\cmdim,0) {cm\vphantom{pb}};
  \node[below] at (\mmdim,0) {mm\vphantom{pb}};
  \node[below] at (\dddim,0) {dd\vphantom{pb}};
  \node[below] at (\ccdim,0) {cc\vphantom{pb}};
%  \node[below] at (\spdim,0) {sp};
  \node[below] at (\exdim,-0.5) {ex\vphantom{pb}};
  \node[below] at (\emdim,-0.5) {em\vphantom{pb}};
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
+1 for the in-depth explanation. I misread sp in Stefan's answer, it seems. I thought it's 65.536 sp = 1 pt, not 65000 ... –  ThomasH Mar 27 '13 at 21:19
    
@ThomasH I removed the misleading comma from that answer. –  egreg Mar 27 '13 at 21:25
2  
Just to note: it would be alright to put the lengths in directly (\pgfpathrectangle{\pgfpointorigin}{\pgfpoint{1em}{1em}}) or to use PGFMath to set the lengths (\pgfmathsetlength\emdim{1em}) because when PGF computes a length itself then it restores the current font to get such lengths right. The problem with the original post is that it doesn't use PGF's methods for setting lengths but uses TeX's methods directly and so PGF doesn't get a chance to undo the \nullfont declaration. –  Loop Space Mar 27 '13 at 22:53

Try doing the following

\setlength{\exdim}{5ex}
\setlength{\emdim}{5em}

It seems to work for me.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.