tikz.dev / TikZpingus Manual

The TikZpingus package

Internals

C.2 How a Penguin is Drawn

\pingu is the only command that draws, and it does so part by part, from the back to the front. Each part is drawn within a scope whose style /pingu/@<part> is empty by default, so that the sets of Section C (for example /pingu/:mix or /pingu/:ghost) can change a single part. The parts of a penguin which are behind or in front of the rest (very-background, background, main, middle, foreground, in this order) are drawn in six layers which are put one above the other when the penguin is finished, so a penguin which is drawn later is above a penguin which is drawn earlier, wings included. The package option manual-layers lets all penguins of a picture share the layers instead.

The helpers.

Every shape is drawn with one of three helpers: \pingu@path (a path), \pingu@block (a filled shape) and \pingu@draw (a line). They take a color, and draw nothing if it is \@pingu@none. This is the mechanism that lets you hide any part by giving it that color.

\long\def\pingu@path{\@dblarg\pingu@path@}
\def\pingu@path@[#1]#2#3;{\protected@edef\@tmp{#2}\ifx\@tmp\@pingu@none\else\path[#1,#2] #3;\fi}
\long\def\pingu@block{\@dblarg\pingu@block@}
\def\pingu@block@[#1]#2#3;{\protected@edef\@tmp{#2}\ifx\@tmp\@pingu@none\else\path[#1,/pingu/@block=#2] #3;\fi}
\long\def\pingu@draw{\@dblarg\pingu@draw@}
\def\pingu@draw@[#1]#2#3;{\protected@edef\@tmp{#2}\ifx\@tmp\@pingu@none\else\path[#1,/pingu/@draw=#2] #3;\fi}
The setup.

The group is opened and /pingu/defaults followed by the given keys are executed. This is why a key never depends on a former penguin. Then the silhouette (\pingu@bbox@update) and the shift of /pingu/anchor are calculated, and the outer anchors are placed (\pingu@place@anchors).

\newcommand*\pingu[1][]{%
\ifpengu@setup@manual@layers@\pgfsetlayers{background,main,middle,foreground}\fi\begingroup
\@pingu@do@back@false
\pgfqkeys{/pingu}{defaults, #1}%
\pingu@mixall@hook
\let\pingu@path@lowerpingu\pingu@default@path@lowerpingu\relax
\let\pingu@path@upperpingu\pingu@default@path@upperpingu\relax
\ifdim\pingu@side@h@half<10.33mm \PackageWarning{\tikzpingus@filename}{Penguins with a height below 10.33mm may have unwanted artifacts.}\fi
\pingu@bbox@update
\pingu@anchor@shift\pingu@anchor@dx\pingu@anchor@x
\pingu@anchor@shift\pingu@anchor@dy\pingu@anchor@y
\scope[/pingu/@pingu@place,shift={(\pingu@anchor@dx,\pingu@anchor@dy)}]
\pingu@place@anchors
\ifpengu@setup@manual@layers@\else\pingu@layers@open\fi
The body and the face.

The body is drawn by the selected body type (\@pingu@drawer@bodytype@), and the belly is clipped to the white of the body. The eyes follow.

\scope[/pingu/@pingu,/pingu/@pingu@main]
\scope[/pingu/@body]
\@pingu@drawer@bodytype@
\pingu@body@app
\endscope
\path(\pingu@name-head-center)++(0,-.05mm-\pingu@outer@off) coordinate (\pingu@name-bill);
\scope[shift=(\pingu@name-belly-center),/pingu/@belly]
\clip[use path=\pingu@whitepingu]; \pingu@belly@raw
\endscope
\coordinate(\pingu@name-head) at (\pingu@w@half,.7375cm);
\scope[/pingu/@eyes]
\@pingu@drawer@lefteye@ \@pingu@drawer@righteye@
\endscope
Everything behind the wings.

The clothes behind the penguin (shirts and the back of the cloak), the extras below the head (implementation (lines 1467–1576)) and the hair come next. The feet are drawn on the background layer unless /pingu/feet front is set.

\pingu@layer{background}[]\pingu@draw@clothing@behind\endpingu@layer
\pingu@draw@clothing@middle
\scope[/pingu/@extras,/pingu/@extras@below]
\pingu@draw@extras@below
\endscope

\scope[/pingu/@hair]
\@pingu@drawer@hairstyle@
\endscope

\if@pingu@feet@front\else\pingu@layer{background}[]\fi
\scope[/pingu/@feet]
\@pingu@drawer@leftfoot@ \@pingu@drawer@rightfoot@
\endscope
\pingu@xif@eb{flipflop}{flipflopstraps}%
\if@pingu@feet@front\else\endpingu@layer\fi
The wings.

The wings are drawn after the body. Afterwards the coordinates for the items of the wings are calculated from the position of the wings, and the front of the clothes follows (implementation (lines 1770–1788)).

\scope[/pingu/@wings]
\@pingu@drawer@leftwing@ \@pingu@drawer@rightwing@
\endscope

\path (\pingu@name-wing-left-start) -- (\pingu@name-wing-left) --
([turn]\csname @pingu@wingdown@\@pingu@select@leftwing@ @\endcsname:2.45mm)
coordinate (\pingu@name-wing-left-low) -- ([turn]180:4.9mm)
coordinate (\pingu@name-wing-left-up);
\path (\pingu@name-wing-left-start) -- (\pingu@name-wing-left) --
(\pingu@name-wing-left-start) --
([turn]-180+\csname @pingu@wingdown@\@pingu@select@leftwing@ @\endcsname:3.45mm)
coordinate (\pingu@name-wing-left-start-low) -- ([turn]180:6.9mm)
coordinate (\pingu@name-wing-left-start-up);
\path (\pingu@name-wing-right-start) -- (\pingu@name-wing-right) --
([turn]-\csname @pingu@wingdown@\@pingu@select@rightwing@ @\endcsname:2.45mm)
coordinate (\pingu@name-wing-right-low) -- ([turn]180:4.9mm)
coordinate (\pingu@name-wing-right-up);
% double path to fix turn
\path (\pingu@name-wing-right-start) -- (\pingu@name-wing-right) --
(\pingu@name-wing-right-start) --
([turn]180-\csname @pingu@wingdown@\@pingu@select@rightwing@ @\endcsname:3.45mm)
coordinate (\pingu@name-wing-right-start-low) -- ([turn]180:6.9mm)
coordinate (\pingu@name-wing-right-start-up);
\pingu@draw@clothing@main
The front.

The bill, the extras above the head (implementation (lines 1580–1674)) and the items of the wings are the last parts. At last the meta dots (/pingu/meta-dots) and the code of /pingu/@post are drawn.

\if@pingu@bill@above\pgfonlayer{\pingu@L@foreground}\fi
\scope[/pingu/@bill]
\@pingu@drawer@bill@
\endscope
\if@pingu@bill@above\endpgfonlayer\fi

\scope[/pingu/@extras,/pingu/@extras@above]
\pingu@draw@extras@above
\endscope
\scope[/pingu/@wingitems]
\pingu@draw@wing@items
\endscope
\endscope
\if@pingu@draw@metadots \@pingu@draw@dots \fi
\pingu@post
\ifpengu@setup@manual@layers@\else\pingu@layers@close\fi
\endscope
\endgroup
\ifpengu@setup@manual@layers@\else\pingu@layers@commit\fi
\pingu@back@init@call
}