3

I would like to be able to measure some dimensions while in the tikzpicture environment.

Here is the MWE to demonstrate my intentions:

\documentclass {article}
\RequirePackage [utf8] {inputenc}

\RequirePackage {tikz}
\RequirePackage {expl3}

\begin {document}
    %\begin {tikzpicture}
        \ExplSyntaxOn
            \dim_new:N \height
            \settoheight {\height} {\fontsize {18} {21.6} \selectfont something}
            \dim_log:N \height
        \ExplSyntaxOff
    %\end {tikzpicture}
\end {document}

When tikzpicture is commented out, the height is properly measured.
However, once the tikzpicture environment is enabled, the height has the value 0.0pt.

Judging by the log and similar questions on the internet, this is happening because tikzpicture environment sets the font to nullfont, which doesn't have any character in it.
Therefore, it's impossible to measure the dimensions of the glyphs.

I have tried to change the font inside the tikzpicture environment by adding:

\renewcommand {\encodingdefault} {OT1}
\renewcommand {\familydefault} {\rmdefault}
\renewcommand {\rmdefault} {cmr}
\renewcommand {\seriesdefault} {m}
\renewcommand {\shapedefault} {n}

\fontencoding {\encodingdefault}
\fontfamily {\familydefault}
\fontseries {\seriesdefault}
\fontshape {\shapedefault}
\selectfont

Unfortunately, this didn't change the outcome.

The only thing, that did change the outcome, was adding \font\nullfont=cmr18.
But this approach has downsides:

  1. It really looks like a bad and unsecure code.
  2. height differs between disabled tikzpicture and enabled tikzpicture + new nullfont.
  3. Looks like redefinition of nullfont and also ignores this part of code: \fontsize {18} {21.6}.

How can I change the font to global one, only when performing these measurements inside tikzpicture and change it back to nullfont afterwards?

naphaneal
  • 2,614
Iskustvo
  • 289
  • Inside a tikzpicture the text is gobbled (\nullflont) unless you put in in a node, where you can use font or node font. See here for a very related question. –  Jun 09 '19 at 18:20
  • @marmot I understand that, but then how can I measure dimensions of the text and store it into a variable, if I can only do it inside a node? – Iskustvo Jun 09 '19 at 18:24
  • 1
    \begin{advertizing} See https://tex.stackexchange.com/a/459858/121799 \end{advertizing}. ;-) ? –  Jun 09 '19 at 18:25
  • Thanks for the link! I still have no knowledge of a lot of the things done there, but it seems like it is not sufficient for my use case. I need to just calculate dimension and store it into a variable, while inside tikzpicture. I don't want to draw a node with that value. That value will be used later just for calculating the position of next drawing. Is that even possible? I thought font changing will be easy enough, but it doesn't look like it now :D – Iskustvo Jun 09 '19 at 18:47
  • 2
    The nodes are not necessary. All you need to is to issue an \begin{pgfinterruptpicture}% before you define the box and \end{pgfinterruptpicture}% afterwards. \begin{tikzpicture} \begin{pgfinterruptpicture}% \ExplSyntaxOn \dim_new:N \height \settoheight{\height}{\fontsize{18}{21.6} \selectfont something} \global\height=\height \dim_log:N \height \ExplSyntaxOff \end{pgfinterruptpicture}% \end{tikzpicture} \typeout{\the\height} –  Jun 09 '19 at 18:56
  • Thanks a lot, this is exactly what I needed even though I asked for something else :D – Iskustvo Jun 09 '19 at 19:10

1 Answers1

2

I will be happy to remove this if others feel the current question is too similar to e.g. this question. There are two issues. First and foremost, the text in a tikzpicture (which is not in nodes) will be gobbled. So you need to interrupt the tikzpicture. And then if you measure things inside a group, you somehow need to broadcast the stuff outside. I will use \global here but of course there are alternatives.

\documentclass{article}
\RequirePackage[utf8]{inputenc}

\RequirePackage{tikz}
\RequirePackage{expl3}

\begin{document}
    \begin{tikzpicture}
    \begin{pgfinterruptpicture}%
        \ExplSyntaxOn
            \dim_new:N \height
            \settoheight{\height}{\fontsize{18}{21.6} \selectfont something}
            \global\height=\height
            \dim_log:N \height          
        \ExplSyntaxOff
    \end{pgfinterruptpicture}%  
    %\node{\the\height}; %<- requires that the height is smuggled out of the    group
    \end{tikzpicture}

    The height of the text inside the \texttt{tikzpicture} is \the\height. Note
    that we had to globalize it because otherwise the height would be local.

\end{document}

enter image description here