| Server IP : 88.99.149.37 / Your IP : 216.73.216.141 Web Server : nginx/1.31.2 System : Linux server-88-99-149-37 6.12.0-124.56.5.el10_1.x86_64 #1 SMP PREEMPT_DYNAMIC Fri May 15 06:12:08 EDT 2026 x86_64 User : muralimurth ( 1015) PHP Version : 8.4.23 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/share/doc/freetype-devel/design/ |
Upload File : |
% 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}