7

Let's assume I have a TikZ drawing:

  • there are two rectangles of different heights
  • next to each rectangle there is some text to be added (e.g. A and Z)
  • the upper text has to be scalable in the way that it matches the steps of the diagram (here 3 steps or half)
  • the lower text has to match the height of the rectangle it ends up next to exactly
  • all of the text should be left-aligned at exactly the same grid line
  • the whole drawing should be scalable (text and shapes)

My rather clumsy solution was to keep changing the font size until I've reached a result I deemed more or less satisfactory (you can see that it's still far from perfect). Is there any way to calculate this so that I can set a font size of n grid steps so that I can set A to be exactly 6 steps high, for instance?

This is how far I've come:

\documentclass{article}
\RequirePackage{lmodern}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[thick,scale=1, every node/.style={transform shape}]

\draw[step=1cm,gray,thin] (-1,-1) grid (10,10);
\fill[gray] (0,0) -- (4,0) -- (4,2) -- (0,2) -- (0,0);
\draw[red, ultra thick,|<->|] (5,0) -- (5,2);
\node[font={\fontsize{83}{0}\selectfont\bfseries}] at (7,1) {Z};

\fill[gray] (0,3) -- (4,3) -- (4,9) -- (0,9) -- (0,3);
\draw[green, ultra thick,|<->|] (5,3) -- (5,6);
\node[font={\fontsize{124}{0}\selectfont\bfseries}] at (7,4.45) {A};

\end{tikzpicture}

\end{document}

And this is how it looks like:

clumsy font size »by hand«

Update: Further research

Before everything else I'll have to give credit to AndréC for spreading the word and attracting other experts to post comments and answers – thank you!

I have received several very helpful comments which have given me the right key words to further my research.

Apparently, TeX does only know the size of a bounding box of a glyph, but not the size of the glyph itself. I have learned this from a commenter who's opinion I highly regard. I did my due diligence and tried to both confirm and refute her statement. Yet, the more I searched the more it was confirmed (here, here, and there) that there will always be some trial and error involved when it comes to the measurement and exact placement of glyphs/text inside the grid.

10
  • Hi and welcome. I didn't understand what your problem is.
    – AndréC
    Aug 3 '20 at 14:14
  • Hi @AndréC, the problem is the following: at the moment I have to use something like \node[font={\fontsize{124}{0}\selectfont\bfseries}] at (7,4.45) {A};. The problem with this solution: I have to tinker with fontsize and placement until the letter A fits the grid exactly. If I want to resize A to be four grid steps high instead of three like in the picture, I have to start tinkering again. What I wanted to know is whether there is a possibility to set A to be exactly one (or two, or three etc.) grid boxes high. Aug 3 '20 at 14:29
  • 1
    If I understand well your problem is to find the enlargement factor of the letters so that they are exactly 3cm high (they have no depth because they are capital letters). Is that right?
    – AndréC
    Aug 3 '20 at 15:49
  • Yes, exactly, very well put. What I would like to have is the possibility to increase the fontsize by grid line (1cm, or 5cm or 3cm) without having to try dozens of increments (198pt, 199pt, 199.5pt, 199.525pt etc.). Aug 3 '20 at 16:06
  • 2
    tex doesn't know the exact dimensions of the glyph. Add draw,inner sep=0pt, to your nodes, then you will see the bounding box tex is seeing. So some manual fiddling is unavoidable. But you don't have to do it for every size: use anchor=south west or anchor=base west, then you can simply multiple the fontsize by a factor, or use scalebox. Aug 4 '20 at 7:40
3

Finished.

import animate;
settings.tex="pdflatex"; 
settings.outformat="pdf"; 

animation Ani;
size(300);
void grid(pair A, pair B, pen p=currentpen)
{
for (int i=(int) A.x+1; i < B.x; ++i) { draw((i,A.y)--(i,B.y),p); }
for (int j=(int) A.y+1; j < B.y; ++j) { draw((A.x,j)--(B.x,j),p); }
draw(box(A,B),p);
}

grid((-1,-1),(10,10),gray);
fill((0,0) -- (4,0) -- (4,2) -- (0,2)--cycle,gray);
fill((0,3) -- (4,3) -- (4,9) -- (0,9)--cycle,gray);
for(int i=1; i<=10; ++i){
save();
real height=i/10;

path[] checkA=texpath("Asymptote");
int a=4,b=6;
pair minA=min(checkA),maxA=max(checkA);
real le=abs((maxA.x,minA.y)-minA),he=abs((minA.x,maxA.y)-minA);
transform sca=scale(height*a/le,height*b/he);
minA=min(sca*checkA);
maxA=max(sca*checkA);
pair cente=(minA+maxA)/2;
fill(shift((5,3)+(cente-minA))*sca*checkA);

path[] checkZ=texpath("My drawing tool");
int a=4,b=2;
pair minZ=min(checkZ),maxZ=max(checkZ);
real le=abs((maxZ.x,minZ.y)-minZ),he=abs((minZ.x,maxZ.y)-minZ);
transform sca=scale(height*a/le,height*b/he);
minZ=min(sca*checkZ);
maxZ=max(sca*checkZ);
pair cente=(minZ+maxZ)/2;
fill(shift((5,0)+(cente-minZ))*sca*checkZ);
Ani.add();
restore();
}
erase();
Ani.movie(BBox(3mm,Fill(white)));

enter image description here

Asymptote can actually do it!

You can check step by step to understand my code.

The function path[] texpath(Label L) returns the path array that TEX would fill to draw the Label L.

size(300);
void grid(pair A, pair B, pen p=currentpen)
{
for (int i=(int) A.x+1; i < B.x; ++i) { draw((i,A.y)--(i,B.y),p); }
for (int j=(int) A.y+1; j < B.y; ++j) { draw((A.x,j)--(B.x,j),p); }
draw(box(A,B),p);
}

grid((-1,-1),(10,10),gray);
fill((0,0) -- (4,0) -- (4,2) -- (0,2)--cycle,gray);
fill((0,3) -- (4,3) -- (4,9) -- (0,9)--cycle,gray);

path[] checkA=texpath("A");
int a=4,b=6;
pair minA=min(checkA),maxA=max(checkA);
real le=abs((maxA.x,minA.y)-minA),he=abs((minA.x,maxA.y)-minA);
transform sca=scale(a/le,b/he);
minA=min(sca*checkA);
maxA=max(sca*checkA);
pair cente=(minA+maxA)/2;
fill(shift((5,3)+(cente-minA))*sca*checkA);

path[] checkZ=texpath("Z");
int a=4,b=2;
pair minZ=min(checkZ),maxZ=max(checkZ);
real le=abs((maxZ.x,minZ.y)-minZ),he=abs((minZ.x,maxZ.y)-minZ);
transform sca=scale(a/le,b/he);
minZ=min(sca*checkZ);
maxZ=max(sca*checkZ);
pair cente=(minZ+maxZ)/2;
fill(shift((5,0)+(cente-minZ))*sca*checkZ);

enter image description here

8
  • The Z is distorted!
    – AndréC
    Aug 4 '20 at 11:07
  • @AndréC, yes, the Z must be distorted. (with proportional x=4,y=2 for Z and x=4,y=6 for A)
    – user213378
    Aug 4 '20 at 11:12
  • In that case, I misunderstood the problem again.
    – AndréC
    Aug 4 '20 at 11:16
  • @user213378 Wow, thank you! Is there a way to only set the height of a letter and keep the correct aspect ratio? Aug 4 '20 at 12:40
  • @phil-elkabat see edited answer. That is what you want?
    – user213378
    Aug 4 '20 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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