File: glyph-metrics.tex

package info (click to toggle)
freetype 2.13.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,384 kB
  • sloc: ansic: 153,848; cpp: 13,981; python: 5,909; sh: 4,486; xml: 1,439; makefile: 676; perl: 340; awk: 142; javascript: 82
file content (309 lines) | stat: -rw-r--r-- 9,078 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
% glyph-metrics.tex
%
% written 2022 by Werner Lemberg <wl@gnu.org>


% This file contains graphics used for the 'FreeType Glyph Conventions'
% tutorial, part 3, 'Glyph Metrics'.


% Here is one possibility to convert this LaTeX file to both PNG and SVG
% formats.
%
%   xelatex glyph-metrics.tex
%
%   pdftoppm -png -f 1 -l 4 -r 120 glyph-metrics.pdf glyph-metrics
%   optipng glyph-metrics-*.png
%
%   for i in 1 2 3 4; do
%     pdf2svg glyph-metrics.pdf glyph-metrics-$i.svg $i
%   done


\documentclass[tikz, border=3mm]{standalone}

\usepackage{libertinus}

\usetikzlibrary{
  calc,
  decorations,
  positioning
}


% Node styles.
\tikzset{
  % For dimensionless point nodes.
  dummy/.style={
    inner sep=0pt,
    outer sep=0pt},
%
  % For thick curves with one arrow.
  axis/.style={
    line width=4pt,
    -latex},
%
  % For fat dots.
  dot/.style={
    minimum size=14pt,
    circle,
    fill},
%
  % 'Elastic dashes' adapt spaces between dashes to the line length so that
  % the last dash doesn't get cut off partially.
  %
  % Taken from
  % https://tex.stackexchange.com/questions/133271/can-tikz-dashed-lines-emulate-pstricks-dashed-lines
  elastic dash/.code args={on #1 off #2}{
    % Use csname so catcode of @ doesn't have do be changed.
    \csname tikz@addoption\endcsname{%
      \pgfgetpath\currentpath
      \pgfprocessround{\currentpath}{\currentpath}%
      \csname pgf@decorate@parsesoftpath\endcsname
        {\currentpath}{\currentpath}%
      \pgfmathparse{\csname pgf@decorate@totalpathlength\endcsname-#1}%
      \let\rest=\pgfmathresult
      \pgfmathparse{#1+#2}%
      \let\onoff=\pgfmathresult
      \pgfmathparse{max(floor(\rest/\onoff), 1)}%
      \let\nfullonoff=\pgfmathresult
      \pgfmathparse{max((\rest-\onoff*\nfullonoff)/\nfullonoff+#2, #2)}%
      \let\offexpand=\pgfmathresult
      \pgfsetdash{{#1}{\offexpand}}{0pt}}},
%
  % For main curves.
  line/.style={
    line width=2pt},
%
  % For auxiliary, dashed curves.
  dashed line/.style={
    elastic dash=on 6pt off 6pt,
    line},
%
  % For displaying node coordinates.
  coordinate/.style={
    font=\Huge},
%
  % For explanations.
  description/.style={
    font=\Huge\itshape},
%
  % For curves with one arrow.
  direction/.style={
    line,
    -latex},
  % For curves with two arrows.
  span/.style={
    line,
    latex-latex},
%
  % For (invisible) boxes displaying advances.
  box/.style={
    inner sep=0pt,
    font=\fontsize{150pt}{0pt}\selectfont},
%
  % For displaying horizontal advances.
  hbox/.style={
    box,
    outer sep=0pt,
    anchor=base west},
%
  % For displaying vertical advances.
  vbox/.style={
    box,
    outer sep=10pt,
    anchor=north},
%
  % We want to draw a tight bounding box around the ink of glyph 'g', which
  % needs some manual work.  We use `inner xsep` with a negative value to
  % remove the glyph's side bearings.  Since the left and the right side
  % bearings are not equal, we need `\hspace` as an additional compensation.
  % For the top and bottom side bearings, adjusting `inner ysep` is
  % sufficient.
  glyph g/.style={
    draw,
    line,
    inner xsep=-6pt,
    inner ysep=0pt,
    outer sep=0pt,
    font=\fontsize{300pt}{0pt}\selectfont,
    execute at end node={\hspace{-3pt}g}},
%
  % For filled squares
  %
  % Taken from
  % https://tex.stackexchange.com/questions/300098/draw-a-node-as-a-square-with-tikz
  square/.style={
    fill,
    minimum size=9pt,
    inner sep=0pt}
}


\newcommand*{\LastLoopValue}{No value}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

% Horizontal advance widths.

\begin{tikzpicture}
  % Put dummy node 'glyph0' at the left edge.
  \node[dummy] (glyph0) {};
  \node[square] (square0) at (glyph0.base west) {};
  \draw[line] (glyph0.base west) -- +(-1.5,0);
  \draw[dashed line] (square0) -- +(0,-2);

  % Loop over all characters; the nodes have the name 'glyph1', 'glyph2',
  % etc.
  \foreach \g [count=\i, remember=\i as \lasti] in {A, b, s, t, r, a, c, t}
    {\node[hbox] (glyph\i) at (glyph\lasti.base east) {\g};
     \node[square] (square\i) at (glyph\i.base east) {};

     \draw[dashed line] (square\i) -- +(0,-2);
     \draw[direction]
       let
         \p{offset}=(0,{-0.7 * mod(\i, 2) - 0.7})
       in
         ($(glyph\i.base west) + (\p{offset})$)
           -- ($(glyph\i.base east) + (\p{offset})$);

     \draw [line] (glyph\i.base west) -- (glyph\i.base east);

     \xdef\LastLoopValue{\i}
    }

  \draw[direction] (glyph\LastLoopValue.base east) -- +(1.5,0);
\end{tikzpicture}


% Vertical advance widths.

\begin{tikzpicture}
  \node[dummy] (glyph0) {};
  \node[square] (square0) at (glyph0.north) {};
  \draw[line] (glyph0.south) -- +(0,1.5);
  \draw[dashed line] (square0) -- +(-3.5,0);

  \foreach \g [count=\i, remember=\i as \lasti] in {A, b, s}
    {\node[vbox] (glyph\i) at (glyph\lasti.south) {\g};
     \node[square] (square\i) at (glyph\i.south) {};

     \draw[dashed line] (square\i) -- +(-3.5,0);
     \draw[direction]
       let
         \p{offset}=({-0.7 * mod(\i, 2) - 2.3},0)
       in
         ($(glyph\i.north) + (\p{offset})$)
           -- ($(glyph\i.south) + (\p{offset})$);

     \draw [line] (glyph\i.north) -- (glyph\i.south);

     \xdef\LastLoopValue{\i}
    }

  \draw[direction] (glyph\LastLoopValue.south) -- +(0,-1.5);
\end{tikzpicture}


% Horizontal metrics.

\begin{tikzpicture}
  \node [glyph g,
         anchor=base west] (glyph) at (1,0) {};

  \draw[axis] (-2,0) -- ($(glyph.base east) + (4,0)$);

  \node (bottom edge) at ($(glyph.south west) + (-1,-2)$) {};
  \draw[axis] (bottom edge.center) -- ($(glyph.north west) + (-1,2)$);

  \node[dot, label={[coordinate] below left:(0,0)}] at (0,0) {};
  \node[dot] (advance width) at ($(glyph.base east) + (2,0)$) {};

  \node[description] (xMin) at ($(glyph.north west) + (0,3)$) {xMin};
  \draw[dashed line] (glyph.north west) -- (xMin);

  \node[description] (xMax) at ($(glyph.north east) + (0,3)$) {xMax};
  \draw[dashed line] (glyph.north east) -- (xMax);

  \draw[span] ($(glyph.north west) + (0,1)$)
                -- ($(glyph.north east) + (0,1)$)
              node [midway, above, description] {width};
  \draw[direction] ($(glyph.north west) + (-1,-1)$) -- +(1,0)
                   node [anchor=east, pos=0, description] {bearingX\/};

  \draw[dashed line] (advance width) -- (bottom edge -| advance width);
  \draw[direction] ($(bottom edge) + (0,1)$)
                     -- ($(bottom edge -| advance width) + (0,1)$)
                   node [midway, below, description] {advance};

  \node[description,
        anchor=west] (yMax) at ($(glyph.north east) + (6,0)$) {yMax};
  \draw[dashed line] (glyph.north east) -- (yMax);

  \node[description,
        anchor=west] (yMin) at ($(glyph.south east) + (6,0)$) {yMin};
  \draw[dashed line] (glyph.south east) -- (yMin);

  \draw[direction] ($(glyph.base east) + (1,0)$)
                     -- ($(glyph.north east) + (1,0)$)
                   node [midway, right, description] {bearingY};
  \draw[span] ($(glyph.south east) + (5,0)$)
                -- ($(glyph.north east) + (5,0)$)
              node [midway, right, description] {height};
\end{tikzpicture}


% Vertical metrics.

\begin{tikzpicture}
  \node [glyph g,
         anchor=north] (glyph) at (0,-2) {};

  \node (right edge) at ($(glyph.north east) + (6,2)$) {};
  \draw[axis] ($(glyph.north west) + (-1,2)$) -- (right edge);

  \draw[axis] (0,2) -- ($(glyph.south) + (0,-3)$);

  \node[dot, label={[coordinate] above right:(0,0)}] at (0,0) {};
  \node[dot] (advance height) at ($(glyph.south) + (0,-1)$) {};

  \node[description] (yMax) at ($(glyph.north west) + (-3,0)$) {yMax};
  \draw[dashed line] (glyph.north west) -- (yMax);

  \node[description] (yMin) at ($(glyph.south west) + (-3,0)$) {yMin};
  \draw[dashed line] (glyph.south west) -- (yMin);

  \draw[span] ($(glyph.north west) + (-1,0)$)
                -- ($(glyph.south west) + (-1,0)$)
              node [midway, left, description] {height\/};

  \draw[direction] ($(glyph.north east) + (-1.5,2)$) -- +(0,-2)
                   node [midway, right, description] {bearingY};

  \draw[dashed line] (advance height)
                       -- ($(right edge |- advance height) + (-2,0)$);
  \draw[direction] ($(right edge) + (-3.5,0)$)
                     -- ($(right edge |- advance height) + (-3.5,0)$)
                   node [midway, right, description] {advance};

  \node[description,
        anchor=north] (xMin) at ($(glyph.south west) + (0,-3)$) {xMin};
  \draw[dashed line] (glyph.south west) -- (xMin);

  \node[description,
        anchor=north] (xMax) at ($(glyph.south east) + (0,-3)$) {xMax};
  \draw[dashed line] (glyph.south east) -- (xMax);

  \draw[span] ($(glyph.south west) + (0,-2)$)
                -- ($(glyph.south east) + (0,-2)$)
              node [anchor=east, pos=0, description] {width\/};

  \draw[dashed line] (glyph.north west) -- +(0,4);
  \draw[direction] (0,1.5) -- (glyph.north west |- 0,1.5)
                   node [left, description] {bearingX\/};
\end{tikzpicture}

\end{document}