File: components.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 (329 lines) | stat: -rw-r--r-- 9,878 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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
% components.tex
%
% written 2022 by Werner Lemberg <wl@gnu.org>


% This file contains graphics used for the 'FreeType Design' documentation,
% part 1, 'Components and APIs'.


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


\documentclass[tikz,
               svgnames, % for xcolor
               border=3mm]{standalone}

\usepackage{libertinus}

\usetikzlibrary{
  calc,
  decorations.pathreplacing, % for "show path construction"
  fit,
  positioning,
  shapes.geometric
}


% Node styles.
\tikzset{
  % 'Elastic dashes' adapt spaces between dashes to the line length so that
  % the last dash doesn't get cut off partially.
  %
  % Taken from https://github.com/pgf-tikz/pgf/issues/629
  elastic dashes/.code args={on #1 off #2 ends #3}{%
    % 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{max(#1 - #3, 0)}
      \let\dashphase=\pgfmathresult
      \pgfmathparse{\csname pgf@decorate@totalpathlength\endcsname
                    - #1
                    + 2 * \dashphase}
      \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}}{\dashphase pt}}
  },
%
  % Elastic dashes for boxes and the like.
  elastic dashes per segment/.style args={on #1 off #2 ends #3}{
    /utils/exec=\csname tikz@options\endcsname,
    decoration={
      show path construction,
      lineto code={
        \draw [elastic dashes=on #1 off #2 ends #3]
          (\tikzinputsegmentfirst)
          -- (\tikzinputsegmentlast);},
      curveto code={
        \draw [elastic dashes=on #1 off #2 ends #3]
          (\tikzinputsegmentfirst)
          .. controls (\tikzinputsegmentsupporta)
             and (\tikzinputsegmentsupportb)
          .. (\tikzinputsegmentlast);},
      closepath code={
        \draw [elastic dashes=on #1 off #2 ends #3]
          (\tikzinputsegmentfirst)
          -- (\tikzinputsegmentlast);}},
    decorate},
%
  % The distance between 'module' nodes.
  node distance=0.3cm,
%
  % For normal lines.
  line/.style={
    line width=1pt},
%
  % For thin lines.
  thin line/.style={
    line width=0.5pt},
%
  % For arrow lines.
  arrow line/.style={
    thin line,
    -latex},
%
  % For boxes in general.
  box/.style={
    line,
    draw,
    minimum height=1cm,
    line cap=rect},
%
  % For base components.
  base box/.style={
    box,
    minimum width=1.5cm,
    minimum height=0.5cm,
  },
%
  % For optional base components.
  optional base box/.style={
    base box,
    elastic dashes per segment=on 3pt off 3pt ends 2pt
  },
%
  % For module boxes.
  module box/.style={
    box,
    outer sep=0pt,
    minimum width=1.8cm},
%
  % For service boxes.
  service box/.style={
    thin line,
    draw,
    outer sep=0pt,
    anchor=south west,
    font=\tiny},
%
  % Generic triangles.
  triangle/.style={
    thin line,
    isosceles triangle,
    isosceles triangle stretches,
    inner sep=0pt,
    minimum width=0.25cm,
    minimum height=0.2cm,
    draw},
%
  % For triangles pointing upwards.
  triangle up/.style={
    triangle,
    shape border rotate=90,
    fill=#1},
%
  % For triangles pointing downwards.
  triangle down/.style={
    triangle,
    shape border rotate=-90,
    fill=#1},
%
  % For triangle descriptions.
  triangle description/.style args={#1/#2}{
    triangle down=#1,
    label={[label position=south,
            anchor=base west]:\ #2}},
%
  % We use a 'matrix' as a means to get a pre-computed bounding box node of
  % a group of nodes.
  %
  % In particular, we use matrices to center two rows of boxes both
  % horizontally (i.e., to align the center the first row of boxes with the
  % center of the second row).
  container/.style={
    matrix,
    every outer matrix/.style={
      inner sep=0pt,
      outer sep=0pt}}
}


% Locations on top or bottom edges of boxes.
\def\pos#1#2{($ (#1 west) !#2! (#1 east) $)}


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

\begin{document}

% Basic library design.

\begin{tikzpicture}
  \node[module box] (M1) {Module};
  \foreach \x [remember=\x as \lastx (initially 1)] in {2, 3, 4}
    \node[module box] (M\x) [right=of M\lastx] {Module};
  \node[inner sep=0pt,
        outer sep=0pt] (Mdots) [right=of M4] {\ldots};

  \node[inner sep=0pt,
        outer sep=0pt,
        fit=(M1) (Mdots)] (Mboxes) {};
  \node[box,
        minimum width=3.2cm] (B) [above=1cm of Mboxes]
       {Base Layer};
  \node[box,
        minimum width=6cm] (C) [above=1cm of B]
       {Client Application};

  \foreach \i/\x in {1/0.3, 2/0.4, 3/0.5, 4/0.6, 5/0.7}
    \node[triangle down=Aqua] (Btop\i) at \pos{B.north}{\x} {};
  \draw[arrow line] (C.south -| Btop2) -- (Btop2);

  \foreach \i/\x in {1/0.25, 2/0.35, 2/0.45, 3/0.55}
    \node[triangle up=Blue] (Bbottom\i) at \pos{B.south}{\x} {};
  \draw[arrow line] (M2.north -| Bbottom1) -- (Bbottom1);

  \node[triangle down=Fuchsia] (M2top) at \pos{M2.north}{0.6} {};
  \draw[arrow line] (B.south -| M2top) -- (M2top);

  \node[triangle description=Aqua/high-level API] (T1)
    [right=1cm of B.north east] {};
  \node[triangle description=Blue/base API] (T2) [below=2ex of T1] {};
  \node[triangle description=Fuchsia/module API] (T3) [below=2ex of T2] {};
\end{tikzpicture}


% Detailed library design.

\begin{tikzpicture}
      [node distance=0.5cm,
       box/.append style={
         minimum height=1.2cm},
       module box/.append style={
        text depth=0.4cm},
       service box/.append style={
        text depth=0.1cm}]
  \node[container] (module boxes) {
    \node[module box] (M1) {Module};
    \foreach \x [remember=\x as \lastx (initially 1)] in {2, 3, 4}
      \node[module box,
            right=of M\lastx] (M\x) {Module};
    \node[inner sep=0pt,
          outer sep=0pt,
          right=of M4] (Mdots) {\ldots};

    \node[service box] (S1A) at (M1.south west) {Service};
    \node[service box] (S1B) at (S1A.south east) {Service};
    \node[service box] (S2A) at (M2.south west) {Service};
    \node[service box] (S2B) at (S2A.south east) {Service};
    \node[service box] (S4A) at (M4.south west) {Service};
    \\
  };

  \node[container,
        above=1cm of module boxes] (base boxes) {
    \node[box,
          minimum width=3.2cm] (B) {Base Layer};
    \node[base box,
          right=of B.north east,
          anchor=north west] (FI) {ftinit};
    \node[base box,
          right=of B.south east,
          anchor=south west] (FS) {ftsystem};
    \node[optional base box,
          left=of B] (FM) {ftmm};
    \\
  };

  \node[optional base box,
        above=0.6cm of B.north east,
        anchor=south east] (FG) {ftglyph};

  \coordinate[above=0.6cm of FG] (c);
  \node[box,
        minimum width=6cm,
        anchor=south] (C) at (B |- c) {Client Application};

  \node[triangle down=Aqua] (FMtop) at \pos{FM.north}{0.7} {};
  \node[triangle down=Aqua] (FGtop) at \pos{FG.north}{0.5} {};
  \node[triangle down=Aqua] (Btop1) at \pos{B.north}{0.2} {};
  \node[triangle down=Aqua] (Btop2) at \pos{B.north}{0.3} {};
  \node[triangle down=Aqua] (Btop3) at \pos{B.north}{0.7} {};
  \node[triangle down=Blue] (Btop4) at \pos{B.north}{0.9} {};
  \node[triangle up=Blue] (Bbottom1) at \pos{B.south}{0.25} {};
  \node[triangle up=Blue] (Bbottom2) at \pos{B.south}{0.50} {};
  \node[triangle up=Blue] (Bbottom3) at \pos{B.south}{0.75} {};
  \node[triangle down=Aqua] (FItop) at \pos{FI.north}{0.2} {};
  \node[triangle up=Blue] (FSbottom) at \pos{FS.south}{0.3} {};
  \node[triangle down=Fuchsia] (M1top) at \pos{M1.north}{0.8} {};
  \node[triangle down=Fuchsia] (M2top) at \pos{M2.north}{0.6} {};
  \node[triangle down=Fuchsia] (M3top) at \pos{M3.north}{0.2} {};
  \node[triangle down=Fuchsia] (M4top) at \pos{M4.north}{0.8} {};

  \foreach \x in {S1A, S1B, S2A, S2B, S4A}
    \node[triangle up=Gold] (\x bottom) at (\x.south) {};

  \draw[arrow line] (C.south -| FMtop) -- (FMtop);
  \draw[arrow line] (C.south -| Btop2) -- (Btop2);
  \draw[arrow line] (FG.south -| Btop3) -- (Btop3);
  \draw[arrow line] (FG.south -| Btop4) -- (Btop4);
  \draw[arrow line] (M3.north -| Bbottom3) -- (Bbottom3);
  \draw[arrow line] (C.south -| FGtop) -- (FGtop);
  \draw[arrow line] (C.south -| FItop) -- (FItop);
  \draw[arrow line] (M4.north -| FSbottom) -- (FSbottom);
  \draw[arrow line] (FM.south -| M1top) -- (M1top);
  \draw[arrow line] (B.south -| M2top) -- (M2top);
  \draw[arrow line] \pos{M2.north}{0.9} -- +(0,0.4) -| (M3top);

  \coordinate[below=0.6cm of S1Abottom] (m);
  \coordinate (mm) at ($ (M2) !0.5! (M3) $);
  \draw[thin line] (B.south -| mm) -- (m -| mm);
  \draw[thin line] (S1Abottom |- m) -- (S4Abottom |- m);
  \draw[arrow line] (S1Abottom |- m) -- (S1Abottom);
  \draw[arrow line] (S2Abottom |- m) -- (S2Abottom);
  \draw[arrow line] (S4Abottom |- m) -- (S4Abottom);

  \draw[arrow line] (M3.south) -- +(0,-0.4) -| (S1Bbottom);

  \node[triangle description=Aqua/high-level API,
        right=1cm of FI.north east] (T1) {};
  \node[triangle description=Blue/base API,
        below=2ex of T1] (T2) {};
  \node[triangle description=Fuchsia/module API,
        below=2ex of T2] (T3) {};
  \node[triangle description=Gold/service API,
        below=2ex of T3] (T4) {};
\end{tikzpicture}

\end{document}