summaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-01-17 03:02:33 +0000
committerNorbert Preining <norbert@preining.info>2021-01-17 03:02:33 +0000
commit8591b56496b93eed20f638ee1ce46b11c3f7be58 (patch)
treeb2afe58ae1a4b7b138a752410d3d7232485a4f9d /graphics
parent07a2495c5aecc2f871625ae63d25ee1cc18b2ca5 (diff)
CTAN sync 202101170302
Diffstat (limited to 'graphics')
-rw-r--r--graphics/pgf/contrib/tikz-bbox/README.txt24
-rw-r--r--graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex120
-rw-r--r--graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex181
-rw-r--r--graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdfbin0 -> 234562 bytes
-rw-r--r--graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex26
-rw-r--r--graphics/pxpic/README.md2
-rw-r--r--graphics/pxpic/pxpic.dtx342
-rw-r--r--graphics/pxpic/pxpic.pdfbin295341 -> 309853 bytes
8 files changed, 645 insertions, 50 deletions
diff --git a/graphics/pgf/contrib/tikz-bbox/README.txt b/graphics/pgf/contrib/tikz-bbox/README.txt
new file mode 100644
index 0000000000..077f3aabab
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-bbox/README.txt
@@ -0,0 +1,24 @@
+tikz-bbox
+=========
+
+Copyright 2021 by marmotghost.
+v0.1
+
+This file may be distributed and/or modified under the
+LaTeX project public license (LPPL), version 1.3c
+see
+https://www.latex-project.org/lppl/lppl-1-3c/
+
+
+The built-in determination of the bounding box in TikZ is not entirely accurate.
+This is because, for Bezier curves, it is the smallest box that contains all
+control points, which is in general larger than the box that just contains the
+curve. This library determines the exact bounding box of the curve.
+
+In order to load this library in a LaTeX document, you need to add
+
+\usetikzlibrary{bbox}
+
+to the preamble after loading the tikz package. While this library might
+possibly work with TeX or ConTeXt, this has never been tested. This library
+loads and uses the fpu library.
diff --git a/graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex b/graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex
new file mode 100644
index 0000000000..a9e887f809
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex
@@ -0,0 +1,120 @@
+% Copyright 2021 by marmotghost
+% v0.1
+%
+% This file may be distributed and/or modified under the
+% LaTeX project public license (LPPL), version 1.3c
+% see
+% https://www.latex-project.org/lppl/lppl-1-3c/
+
+
+\usepgflibrary{fpu}
+\global\let\pgf@bbox@lt@curveto@normal\pgf@lt@curveto
+\global\let\pgf@bbox@nlt@curveto@normal\pgf@nlt@curveto
+
+\pgfqkeys{/pgf}{bezier bounding box/.is if=pgf@bbox@switch@}
+
+
+\def\pgf@bbox@switch@false{%
+ \let\pgf@lt@curveto \pgf@bbox@lt@curveto@normal
+ \let\pgf@nlt@curveto\pgf@bbox@nlt@curveto@normal
+}
+
+\def\pgf@bbox@switch@true{%
+ \let\pgf@lt@curveto \pgf@bbox@curveto
+ \let\pgf@nlt@curveto\pgf@bbox@curveto
+}
+\def\pgf@bbox@curveto#1#2#3#4#5#6{%
+\begingroup
+\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
+ % extrema in x
+ % first discriminant d1, must be \ne 0
+ \pgfmathsetmacro{\pgf@temp@a}{(\pgf@path@lastx)-(#5)-3*(#1)+3*(#3)}%
+ \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@a)>0.1?1:0)}%
+ \ifnum\pgf@temp@c=1\relax
+ % second discriminant d2, must be \ge 0
+ \pgfmathsetmacro{\pgf@temp@b}{(\pgf@path@lastx)*(#5)-(#5)*(#1)+(#1)*(#1)-(\pgf@path@lastx)*(#3)-(#1)*(#3)+(#3)*(#3)}%
+ \pgfmathtruncatemacro{\pgf@temp@c}{sign(\pgf@temp@b)}%
+ \ifnum\pgf@temp@c<0
+ \else
+ \pgfmathsetmacro{\pgf@temp@b}{sqrt(abs(\pgf@temp@b))}%
+ \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lastx)-2*(#1)+(#3)-\pgf@temp@b)/\pgf@temp@a))}%
+ \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
+ \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lastx)-2*(#1)+(#3)+\pgf@temp@b)/\pgf@temp@a))}%
+ \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
+ \fi
+ \else
+ % third discriminant d3, must be \ne 0
+ \pgfmathsetmacro{\pgf@temp@b}{abs((#5)+(#1)-2*(#3))}%
+ \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@b)>0.1?1:0)}%
+ \ifnum\pgf@temp@c=1\relax
+ \pgfmathsetmacro{\pgf@temp@c}{((#5)+2*(#1)-3*(#3))/((#5)+(#1)-2*(#3))}%
+ \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
+ \fi
+ \fi
+ % 0/0
+ \pgfmathsetmacro{\pgf@temp@a}{(#5)+(#1)-2*(#3)}%
+ \pgfmathtruncatemacro{\pgf@temp@b}{(abs(\pgf@temp@a)>0.1?1:0)}%
+ \ifnum\pgf@temp@b=1\relax
+ \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((#5)+2*(#1)-3*(#3))/(2*\pgf@temp@a)))}%
+ \else
+ \pgfmathsetmacro{\pgf@temp@c}{0.5}%
+ \fi
+ \pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
+%
+% y code
+ % first discriminant d1, must be \ne 0
+ \pgfmathsetmacro{\pgf@temp@a}{(\pgf@path@lasty)-(#6)-3*(#2)+3*(#4)}%
+ \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@a)>0.1?1:0)}%
+ \ifnum\pgf@temp@c=1\relax
+ % second discriminant d2, must be \ge 0
+ \pgfmathsetmacro{\pgf@temp@b}{(\pgf@path@lasty)*(#6)-(#6)*(#2)+(#2)*(#2)-(\pgf@path@lasty)*(#4)-(#2)*(#4)+(#4)*(#4)}%
+ \pgfmathtruncatemacro{\pgf@temp@c}{sign(\pgf@temp@b)}%
+ \ifnum\pgf@temp@c<0
+ \else
+ \pgfmathsetmacro{\pgf@temp@b}{sqrt(abs(\pgf@temp@b))}%
+ \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lasty)-2*(#2)+(#4)-\pgf@temp@b)/\pgf@temp@a))}%
+ \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
+ \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lasty)-2*(#2)+(#4)+\pgf@temp@b)/\pgf@temp@a))}%
+ \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
+ \fi
+ \else
+ % third discriminant d3, must be \ne 0
+ \pgfmathsetmacro{\pgf@temp@b}{abs((#6)+(#2)-2*(#4))}%
+ \pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@b)>0.1?1:0)}%
+ \ifnum\pgf@temp@c=1\relax
+ \pgfmathsetmacro{\pgf@temp@c}{((#6)+2*(#2)-3*(#4))/((#6)+(#2)-2*(#4))}%
+ \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
+ \fi
+ \fi
+ % 0/0
+ \pgfmathsetmacro{\pgf@temp@a}{(#6)+(#2)-2*(#4)}%
+ \pgfmathtruncatemacro{\pgf@temp@b}{(abs(\pgf@temp@a)>0.1?1:0)}%
+ \ifnum\pgf@temp@b=1\relax
+ \pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((#6)+2*(#2)-3*(#4))/(2*\pgf@temp@a)))}%
+ \else
+ \pgfmathsetmacro{\pgf@temp@c}{0.5}%
+ \fi
+ \pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
+ \pgfutil@tempdimb=\pgfmathresult pt\relax%
+ \pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
+%
+ \pgf@protocolsizes{\pgf@path@lastx}{\pgf@path@lasty}%
+ \pgf@protocolsizes{#5}{#6}%
+ \endgroup
+ \pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}%
+}
+\endinput
diff --git a/graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex b/graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex
new file mode 100644
index 0000000000..9d42ae0dd5
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex
@@ -0,0 +1,181 @@
+% Copyright 2021 by marmotghost
+% v0.1
+%
+% This file may be distributed and/or modified under the
+% LaTeX project public license (LPPL), version 1.3c
+% see
+% https://www.latex-project.org/lppl/lppl-1-3c/
+%
+% It has been claimed that the license of this library had been changed so that this
+% library is no longer part of pgf. This claim is a lie. There was no license change
+% at all. Now, in 2021, the license got changed to LaTeX project public license
+% (LPPL), version 1.3c.
+
+\section{Bounding Boxes for B\'ezier Curves}
+
+
+\begin{pgflibrary}{bbox}
+ This library provides methods to determine tight bounding boxes for
+ B\'ezier curves. This library loads and uses the
+ |fpu| library. While this library might
+ possibly work with |TeX| or |ConTeXt|, this has never been tested.
+\end{pgflibrary}
+
+\subsection{Bounding box without the library}
+
+\tikzname\ determines the bounding box of (cubic) Bezier curves by establishing the
+smallest rectangle that contains the end point and the two control points of the
+curve.
+
+\begin{codeexample}[width=5cm]
+\begin{tikzpicture}[%
+ bullet/.style={circle,fill,
+ inner sep=1pt}]
+ \draw (0,0) .. controls (-1,1)
+ and (1,2) .. (2,0);
+ \draw (current bounding box.south west)
+ rectangle
+ (current bounding box.north east);
+ \draw[red,dashed]
+ (0,0) -- (-1,1)
+ node[bullet,label=above:{$(x_a,y_a)$}]{}
+ (2,0) -- (1,2)
+ node[bullet,label=above:{$(x_b,y_b)$}]{};
+ \path (0,0)
+ node[bullet,label=below:{$(x_0,y_0)$}]{}
+ (2,0)
+ node[bullet,label=below:{$(x_1,y_1)$}]{};
+\end{tikzpicture}
+\end{codeexample}
+
+As one can see from this illustration, this may lead to drastic overestimates of
+the bounding box.
+
+\subsection{Computing the bounding box}
+
+Establishing the precise bounding box has been discussed in various places, the
+following discussion uses in part the results from
+\url{https://pomax.github.io/bezierinfo/}. What is a cubic B\'ezier curve? A
+cubic B\'ezier curve running from $(x_0,y_0)$ to $(x_1,y_1)$ with control points
+$(x_a,y_a)$ and $(x_b,y_b)$ can be parametrized by
+\begin{equation}
+ \gamma(t)~=~
+ \begin{pmatrix} x(t)\\ y(t) \end{pmatrix}~=~
+ \begin{pmatrix}t^3 x_{1}+3 t^2 (1-t) x_{b}+(1-t)^3
+ x_{0}+3 t (1-t)^2 x_{a}\\
+ t^3 y_{1}+3
+ t^2 (1-t) y_{b}+(1-t)^3 y_{0}+3 t (1-t)^2
+ y_{a}\end{pmatrix}\;,\label{eq:gammaBezier}
+\end{equation}
+where $t$ runs from $0$ to $1$ (and $\gamma(0)=(x_0,y_0)$ and
+$\gamma(1)=(x_1,y_1)$). Surely, the bounding box has to contain
+$(x_0,y_0)$ and $(x_1,y_1)$. If the functions $x(t)$ and $y(t)$ have extrema in
+the interval $[0,1]$, then the bounding box will in general be larger than that.
+In order to determine the extrema of the curve, all
+we need to find the extrema of the functions $x(t)$ and $y(t)$ for $0\le t\le
+1$. That is, we need to find the solutions of the quadratic equations
+\begin{equation}
+ \frac{\mathrm{d}x}{\mathrm{d}t}(t)~=~0\quad\text{and}\quad
+ \frac{\mathrm{d}y}{\mathrm{d}t}(t)~=~0\;.
+\end{equation}
+% (*parametrization of x:*)
+% myx = x0 (1 - t)^3 + 3 xa (1 - t)^2 t + 3 xb (1 - t) t^2 + x1 t^3
+% (*d1\ne0 condition for t1 and t2 to exist*)
+% === (*case d1\ne0*) ==
+% d1 = x0 - x1 - 3 xa + 3 xb
+% (*square root, d2=0 \[Rule] only one solution,d2<0 \[Rule] no solution*)
+% d2 = x0*x1 - x1*xa + xa*xa - x0*xb - xa xb + xb*xb
+% (*first t*)
+% t1 = (x0 - 2*xa + xb - sqrt(d2))/(x0 - x1 - 3*xa + 3*xb)
+% = (x0 - 2*xa + xb - sqrt(d2))/d1
+% (*second t*)
+% t2 = (x0 - 2*xa + xb + sqrt(d2))/(x0 - x1 - 3*xa + 3*xb)
+% = (x0 - 2*xa + xb + sqrt(d2))/d1
+% === (*case d1=0*) ==
+% (*2nd condition for extra condition: d3\ne0*)
+% d3 = x1 + xa - 2 xb
+% (*third t*)
+% t3 = (x1 + 2*xa - 3*xb)/(2*d3)% d3 = x1 + 3 xa - 3 xb - x0
+Let's discuss $x$ first. If the discriminant
+\begin{equation}
+ d~:=~x_0\,x_1 - x_1\,x_a + x_a\,x_a - x_0\,x_b - x_a x_b + x_b\,x_b
+\end{equation}
+is greater than 0, there are two solutions
+\begin{equation}
+ t_\pm~=~\frac{x_{0}-2x_{a}+x_{b}\pm\sqrt{d}}{%
+ x_{0}-x_{1}-3(x_{a}- x_{b})} \;.
+\end{equation}
+If the denominator $x_{0}-x_{1}-3(x_{a}- x_{b})$ vanishes, one may use the
+l'Hospital rule to determine the solutions.
+In this case, we need to make sure that the bounding box contains, say
+$(x(t_-),y_0)$ and $(x(t_+),y_0)$. If $d\le0$, the bounding box does not need to
+be increased in the $x$ direction. On the other hand, if there are solutions,
+one needs include the points $\bigl(x(t_\pm),y_0\bigr)$ with $x(t)$ from
+\eqref{eq:gammaBezier} in the bounding box.
+
+The analogous statements apply to $y(t)$.
+
+\subsection{Using the library}
+
+\begin{key}{/pgf/bezier bounding box=\meta{boolean} (default true)}
+ Turn the tight bounding box algorithm on and off. The initial value is
+ |false|.
+
+ \emph{Caveat:} As can be seen from the derivations, the necessary
+ computations involve the squaring of lengths and taking ratios of lengths,
+ which can easily lead to |dimension too large| errors. The library uses
+ |fpu| to account for that, but errors may still occur.
+\end{key}
+
+
+\begin{codeexample}[width=5cm]
+\begin{tikzpicture}[bezier bounding box,%
+ bullet/.style={circle,fill,
+ inner sep=1pt}]
+ \draw (0,0) .. controls (-1,1)
+ and (1,2) .. (2,0);
+ \draw (current bounding box.south west)
+ rectangle
+ (current bounding box.north east);
+ \draw[red,dashed]
+ (0,0) -- (-1,1)
+ node[bullet,label=above:{$(x_a,y_a)$}]{}
+ (2,0) -- (1,2)
+ node[bullet,label=above:{$(x_b,y_b)$}]{};
+ \path (0,0)
+ node[bullet,label=below:{$(x_0,y_0)$}]{}
+ (2,0)
+ node[bullet,label=below:{$(x_1,y_1)$}]{};
+\end{tikzpicture}
+\end{codeexample}
+
+A few comments are in order.
+\begin{enumerate}
+\item For paths with arrow heads one may need to load the \texttt{bending}
+ library. This is because otherwise the quick arrow head distorts the path, and
+ this happens after the bounding box has been computed. Even worse, arrow heads
+ could get deformed.
+\item If you shorten a path by some negative length, the bounding box will not
+ be accurate either. However, this has nothing to do with curves, it also
+ applies to straight lines. So this is not specific to the |bbox| library but
+ something that one may want to keep in mind.
+\item Let us also note that the computations can lead to |Dimension too large|
+ errors. These errors do not come directly from the computations done by the
+ library, which uses |fpu| for its computations, but from the aftermath. Many of
+ these problems can be avoided by using the |fpu| library also for computing
+ reciprocals, which can be achieved using the key
+ |/pgf/fpu/install only={reciprocal}|. This allows one to fix many
+ |Dimension too large| errors in other libraries, which are not related to the
+ present one, and also fixes inaccuracies of (inverse) transformations when the
+ scale factors are not integer.
+\end{enumerate}
+
+\subsection{Reporting a bug}
+
+This library is maintained at the GitHub repository
+\href{https://github.com/marmotghost/tikz-bbox}{tikz-bbox}, where issues can get
+reported. The author is also active on the noncommercial \TeX\ Q\,\&\,A site
+\href{https://topanswers.xyz/tex}{topanswers.xyz/tex}, where requests that are not
+issues in the strict sense can be discussed.
+
+\endinput
diff --git a/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf
new file mode 100644
index 0000000000..69630c5964
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex
new file mode 100644
index 0000000000..465bc22bea
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex
@@ -0,0 +1,26 @@
+\documentclass[a4paper]{ltxdoc}
+\usepackage[version=latest]{pgf}
+\usepackage{xkeyval,calc,listings,tikz,fp,amsmath,amssymb}
+\usepackage[T1]{fontenc}%
+\usepackage{makeidx}
+\makeindex
+\usepackage{hyperref}
+\hypersetup{%
+ colorlinks=true,
+ linkcolor=blue,
+ filecolor=blue,
+ urlcolor=blue,
+ citecolor=blue,
+ pdfborder=0 0 0,
+}
+\makeatletter % see https://tex.stackexchange.com/q/33946
+\input{pgfmanual.code} %
+\makeatother %
+\input{pgfmanual-en-macros.tex} % link from
+% /usr/local/texlive/2019/texmf-dist/doc/generic/pgf/macros/pgfmanual-en-macros.tex
+% or the equivalent on your installation
+\def\pgfautoxrefs{1}
+\usetikzlibrary{bbox}
+\begin{document}
+\input{pgfmanual-en-library-bbox.tex}
+\end{document}
diff --git a/graphics/pxpic/README.md b/graphics/pxpic/README.md
index e4e78efbb4..32e7cd516a 100644
--- a/graphics/pxpic/README.md
+++ b/graphics/pxpic/README.md
@@ -2,7 +2,7 @@
-------------------------------------------------------------------------------
# pxpic -- draw pixel pictures
-Version 2021-01-13 v1.1
+Version 2021-01-16 v1.2
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
diff --git a/graphics/pxpic/pxpic.dtx b/graphics/pxpic/pxpic.dtx
index f06454e842..9bb8f81097 100644
--- a/graphics/pxpic/pxpic.dtx
+++ b/graphics/pxpic/pxpic.dtx
@@ -54,7 +54,7 @@ and the derived files pxpic.pdf
\expandafter\endgroup
\fi
%
-\ProvidesFile{pxpic.dtx}[2021-01-13 v1.1 draw pixel pictures]
+\ProvidesFile{pxpic.dtx}[2021-01-16 v1.2 draw pixel pictures]
\PassOptionsToPackage{full}{textcomp}
\documentclass{l3doc}
\RequirePackage[oldstylenums,nott]{kpfonts}
@@ -78,7 +78,9 @@ and the derived files pxpic.pdf
,basicstyle=\fontfamily{jkp}\itshape
,morekeywords=^^A
{^^A
- \pxpic,\pxpicsetup
+ \pxpic,\pxpicsetup,\pxpicnewmode,\pxpicsetmode,\pxpicnewcolorlist,
+ \pxpicsetcolorlist,\pxpicaddcolorlist,\pxpicforget,\px,\pxskip,\pxpicHT,
+ \pxpicWD,\pxpiclogo
}
,morecomment=[l]\%
,commentstyle=\color[gray]{0.4}
@@ -132,20 +134,23 @@ and the derived files pxpic.pdf
{expkv}^^A
}
\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
+\DoNotIndex{\advance}
\DoNotIndex{\baselineskip,\begingroup,\bgroup}
\DoNotIndex{\csname}
\DoNotIndex{\def,\detokenize,\dimexpr}
-\DoNotIndex{\egroup,\ekvdef,\ekvdefNoVal,\ekvifdefinedNoVal,\ekvletkv,\ekvparse}
-\DoNotIndex{\ekvsetdef,\endcsname,\endgroup,\expandafter}
+\DoNotIndex{\edef,\egroup,\ekvdef,\ekvdefNoVal,\ekvifdefinedNoVal,\ekvletkv}
+\DoNotIndex{\ekvparse,\ekvsetdef,\endcsname,\endgroup,\expandafter}
\DoNotIndex{\hbox,\hskip}
+\DoNotIndex{\iffalse,\fi}
\DoNotIndex{\kern}
\DoNotIndex{\leavevmode,\let,\long,\lower}
\DoNotIndex{\newcommand,\newdimen}
\DoNotIndex{\PackageError,\protected,\ProvidesPackage}
\DoNotIndex{\relax,\RequirePackage}
-\DoNotIndex{\@depth,\@height,\@ifdefinable,\@ifnextchar,\@ifundefined,\@width}
+\DoNotIndex{\@declaredcolor,\@firstofone,\@gobble,\@ifdefinable,\@ifnextchar}
+\DoNotIndex{\@ifundefined,\@undeclaredcolor}
\DoNotIndex{\ekv@ifempty,\ekv@name,\z@}
-\DoNotIndex{\color}
+\DoNotIndex{\unexpanded}
\DoNotIndex{\vbox,\vrule}
\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
\makeatother
@@ -207,7 +212,7 @@ and the derived files pxpic.pdf
\Large draw pixel pictures^^A
}{pxpic - draw pixel pictures}^^A
}
- \date{2021-01-13 v1.1}
+ \date{2021-01-16 v1.2}
\author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
\DocInput{pxpic.dtx}
\end{document}
@@ -570,24 +575,37 @@ and the derived files pxpic.pdf
% The available options are
%
% \begin{options}
-% \item[colors] Define pixel colours for |mode=px|, see \autoref{sec:colours}
-% for a description of the value's syntax. No pixel definitions are made by
-% the package.
-% \item[colours] \emph{see \texttt{colors}.}
-% \item[gap-hack] To fix the issues with visible gaps in \textsc{pdf} viewers
-% you can introduce some negative kerns to make the pixels overlap (lines
-% overlap to the top, pixels to the left). This option expects a dimension
-% as its value. A positive value will (maybe) close the gaps, a negative
-% value will introduce real gaps. In any case the outermost pixels' borders
-% still coincide with the borders of the surrounding \CS{hbox}. Take a look
-% at my babbling about this issue in \autoref{sec:misc}.
-% \item[ht] Set the height of the pixels.
-% \item[mode] Set the used mode, see \autoref{sec:modes} for available modes.
-% Initial value is |px|.
-% \item[size] Set both |ht| and |wd|. Initial value is \the\pxpicHT.
-% \item[skip] Define the value to be a skip (an empty space of width |wd|) in
-% |mode=px|. No skip definitions are made by the package.
-% \item[wd] Set the width of the pixels.
+% \item[colors=\meta{colour list}]
+% Define pixel colours for |mode=px|, see \autoref{sec:colours} for a
+% description of the value's syntax. No pixel definitions are made by the
+% package.
+% \item[colours]
+% \emph{see \texttt{colors}.}
+% \item[color-list=\meta{choice}]
+% loads a previously through \CS{pxpicnewcolorlist} defined colour list. No
+% colour lists are defined by the package.
+% \item[colour-list]
+% \emph{see \texttt{color-list}.}
+% \item[gap-hack=\meta{dimen}]
+% To fix the issues with visible gaps in \textsc{pdf} viewers you can
+% introduce some negative kerns to make the pixels overlap (lines overlap to
+% the top, pixels to the left). This option expects a dimension as its
+% value. A positive value will (maybe) close the gaps, a negative value will
+% introduce real gaps. In any case the outermost pixels' borders still
+% coincide with the borders of the surrounding \CS{hbox}. Take a look at my
+% babbling about this issue in \autoref{sec:misc}.
+% \item[ht=\meta{dimen}]
+% Set the height of the pixels.
+% \item[mode=\meta{choice}]
+% Set the used mode, see \autoref{sec:modes} for available modes. Initial
+% value is |px|.
+% \item[size=\meta{dimen}]
+% Set both |ht| and |wd|. Initial value is \the\pxpicHT.
+% \item[skip=\meta{dimen}]
+% Define the value to be a skip (an empty space of width |wd|) in |mode=px|.
+% No skip definitions are made by the package.
+% \item[wd=\meta{dimen}]
+% Set the width of the pixels.
% \end{options}
%
% \subsubsection{Colour syntax}\label{sec:colours}
@@ -649,6 +667,28 @@ and the derived files pxpic.pdf
% already exists, \cs{pxpicsetmode} has no checks on the name.
% \end{function}
%
+% \begin{function}{\pxpicnewcolorlist,\pxpicsetcolorlist,\pxpicaddcolorlist}
+% \begin{syntax}
+% \cs{pxpicnewcolorlist}\marg{name}\marg{colour list}
+% \end{syntax}
+% This defines a colour list (to be used with the |colour-list| option). The
+% syntax of \meta{colour list} is the same as for the |colours| option. The
+% pixels aren't directly defined, but only by the use of
+% |colour-list=|\meta{name}. So
+% \begin{lstlisting}
+% \pxpicnewcolorlist{example}{r=red,b=blue,g=green,k=black,w=white}
+% \pxpicsetup{colour-list=example}
+% \end{lstlisting}
+% would have the same effect as
+% \begin{lstlisting}
+% \pxpicsetup{colours={r=red,b=blue,g=green,k=black,w=white}}
+% \end{lstlisting}
+% but a |colour-list| is more efficient if used multiple times. The |new|
+% variant will only throw an error if the colour list \meta{name} is already
+% defined. The |set| variant has no such tests, and the |add| variant will add
+% additional colours to an existing list.
+% \end{function}
+%
% \begin{function}{\pxpicforget}
% \begin{syntax}
% \cs{pxpicforget}\marg{px}
@@ -695,14 +735,77 @@ and the derived files pxpic.pdf
% \textsc{pdf} viewers and tools will display such a gap. To make things even
% worse, the effect depends on the viewers current magnification.
% \pxpicname\ has the |gap-hack| option to provide some crude hack that might
-% fix the issue, at the cost that the pixels are smaller than they were
-% specified to be, except for the pixels at the right and bottom border. Also
-% pixels next to skipped pixels have a different size (skipped pixels don't
-% cover pixels to their left or top as they are transparent). You'll want to
-% find a good trade-off value if you want to use |gap-hack|, that mitigates the
-% effect but isn't too big (to make the errors less obvious). You can play with
-% the value and decide for yourself what's the lesser evil. Or you do like me,
-% don't use |gap-hack| and blame the viewers.
+% fix the issue, at the cost that the pixels on the far right and bottom are
+% bigger than they were specified to be. Also pixels next to skipped pixels have
+% a different size (skipped pixels don't cover pixels to their left or top as
+% they are transparent). You'll want to find a good trade-off value if you want
+% to use |gap-hack|, that mitigates the effect but isn't too big (to make the
+% errors less obvious). You can play with the value and decide for yourself
+% what's the lesser evil. Or you do like me, don't use |gap-hack| and blame the
+% viewers. Here are examples in which you can compare (the |gap-hack| is chosen
+% way too big in this example and skips are used close to white pixels on
+% purpose, but it illustrates the effects; the third output, not shown in the
+% code, uses a more reasonable |gap-hack=.2pt|):\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpicsetup
+% {
+% colours={k=black,g=green,w=white}
+% ,skip=.
+% ,size=10pt
+% }
+% \pxpic[gap-hack=2pt]
+% {
+% {kkkkk}
+% {kgggk}
+% {kwg.k}
+% {kg.gk}
+% {kgwk}
+% {kkkw}
+% }
+% \raise2pt\pxpic
+% {
+% {kkkkk}
+% {kgggk}
+% {kwg.k}
+% {kg.gk}
+% {kgwk}
+% {kkkw}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \pxpicsetup{colours={k=black,g=green,w=white},skip=.,size=10pt}
+% \leavevmode
+% \pxpic[gap-hack=2pt]
+% {
+% {kkkkk}
+% {kgggk}
+% {kwg.k}
+% {kg.gk}
+% {kgwk}
+% {kkkw}
+% }
+% \raise2pt\pxpic
+% {
+% {kkkkk}
+% {kgggk}
+% {kwg.k}
+% {kg.gk}
+% {kgwk}
+% {kkkw}
+% }
+% \raise1.8pt\pxpic[gap-hack=.2pt]
+% {
+% {kkkkk}
+% {kgggk}
+% {kwg.k}
+% {kg.gk}
+% {kgwk}
+% {kkkw}
+% }
+% \end{minipage}
%
%
% \end{documentation}^^A=<<
@@ -718,7 +821,7 @@ and the derived files pxpic.pdf
%
% Report who we are
% \begin{macrocode}
-\ProvidesPackage{pxpic}[2021-01-13 v1.1 draw pixel pictures]
+\ProvidesPackage{pxpic}[2021-01-16 v1.2 draw pixel pictures]
% \end{macrocode}
% and load dependencies
% \begin{macrocode}
@@ -764,7 +867,7 @@ and the derived files pxpic.pdf
% \end{macrocode}
% The |colours| option is parsed using \CS{ekvparse} and \CS{pxpic@setcolor}.
% \begin{macrocode}
-\protected\ekvdef{pxpic}{colors}{\ekvparse\pxpic@noval\pxpic@setcolor{#1}}
+\protected\ekvdef{pxpic}{colors}{\ekvparse\pxpic@err@noval\pxpic@setcolor{#1}}
\ekvletkv{pxpic}{colours}{pxpic}{colors}
% \end{macrocode}
% And the |mode| just checks whether the |mode| macro is defined and lets the
@@ -773,13 +876,23 @@ and the derived files pxpic.pdf
\protected\ekvdef{pxpic}{mode}
{%
\@ifundefined{pxpic@parse@px@#1}%
- {\pxpic@unknown@mode{#1}}%
+ {\pxpic@err@unknown@mode{#1}}%
{%
\expandafter\let\expandafter\pxpic@parse@px
\csname pxpic@parse@px@#1\endcsname
}%
}
% \end{macrocode}
+% A similar check is done for the |colour-list| option.
+% \begin{macrocode}
+\protected\ekvdef{pxpic}{color-list}
+ {%
+ \@ifundefined{pxpic@colorlist@#1}%
+ {\pxpic@err@unknown@colorlist{#1}}
+ {\csname pxpic@colorlist@#1\endcsname}%
+ }
+\ekvletkv{pxpic}{colour-list}{pxpic}{color-list}
+% \end{macrocode}
%
%
% \subsection{User macros}\label{sec:implementation:pxpiclogo}
@@ -795,7 +908,7 @@ and the derived files pxpic.pdf
% pixel row will be wrapped inside an \CS{hbox}. The \CS{kern} negates a
% negative \CS{kern} in \CS{pxpic@parse} so that the first line isn't moved.
% \begin{macrocode}
-\newcommand*\pxpic{\hbox\bgroup\pxpic@}
+\@ifdefinable\pxpic{\protected\def\pxpic{\hbox\bgroup\pxpic@}}
\newcommand\pxpic@[2][]
{%
\vbox
@@ -803,6 +916,8 @@ and the derived files pxpic.pdf
\pxpicsetup{#1}%
\let\px\pxpic@px
\let\pxskip\pxpic@skip
+ \advance\pxpicHT\pxpic@kern
+ \advance\pxpicWD\pxpic@kern
\baselineskip\pxpicHT
\kern\pxpic@kern
\pxpic@parse#2\pxpic@end
@@ -832,6 +947,7 @@ and the derived files pxpic.pdf
\begingroup
\pxpicHT\dimexpr#1\relax
\pxpicWD\pxpicHT
+ \pxpic@kern\z@
\leavevmode
\lower3.2\pxpicHT\pxpic
[mode=px,colours={o=[HTML]{9F393D},g=black!75},skip=.]
@@ -869,13 +985,64 @@ and the derived files pxpic.pdf
% These are pretty simple as well, the |new| variant will use \CS{newcommand}
% which will do the testing for us, the |set| variant uses \CS{def}.
% \begin{macrocode}
-\protected\def\pxpicnewmode#1#2%
+\protected\long\def\pxpicnewmode#1#2%
{\expandafter\newcommand\csname pxpic@parse@px@#1\endcsname[1]{#2}}
-\protected\def\pxpicsetmode#1#2%
+\protected\long\def\pxpicsetmode#1#2%
{\long\expandafter\def\csname pxpic@parse@px@#1\endcsname##1{#2}}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\pxpicnewcolorlist,\pxpicsetcolorlist,\pxpicaddcolorlist}
+% \begin{macro}[internal]{\pxpicsetcolorlist@,\pxpicaddcolorlist@}
+% The colour list is first parsed with \CS{ekvparse} inside an \CS{edef}.
+% \CS{ekvparse} will prevent the parsed list from further expanding, leaving
+% each list element and \CS{pxpic@experr@noval} or
+% \CS{pxpic@setcolor@colorlist} before it. In a second \CS{edef} these will be
+% expanded, \CS{pxpic@experr@noval} throwing an error for each element missing
+% a colour definition, and \CS{pxpic@setcolor@colorlist} testing for an
+% opening bracket (which we do expandably) and leaving the correct definition
+% protected against further expansion. The |add| variant uses a temporary
+% macro for the parsing part and adds the result to the list holding macro.
+% The second expansion step in |set| and both in |add| are done inside a group
+% to revert any definition (also those letting tokens to \CS{relax} by
+% \CS{csname}) made at this point except for the list macro itself.
+% \begin{macrocode}
+\protected\def\pxpicnewcolorlist#1%
+ {%
+ \@ifundefined{pxpic@colorlist@#1}
+ {\pxpicsetcolorlist{#1}}
+ {\pxpic@err@defined@colorlist{#1}\@gobble}%
+ }
+\protected\def\pxpicsetcolorlist#1%
+ {\expandafter\pxpicsetcolorlist@\csname pxpic@colorlist@#1\endcsname}
+\protected\long\def\pxpicsetcolorlist@#1#2%
+ {%
+ \edef#1{\ekvparse\pxpic@experr@noval\pxpic@setcolor@colorlist{#2}}%
+ \begingroup\edef#1{\endgroup\protected\def\unexpanded{#1}{#1}}%
+ #1%
+ }
+\protected\def\pxpicaddcolorlist#1%
+ {%
+ \@ifundefined{pxpic@colorlist@#1}
+ {\pxpic@err@unknown@colorlist{#1}\@gobble}
+ {\expandafter\pxpicaddcolorlist@\csname pxpic@colorlist@#1\endcsname}%
+ }
+\protected\long\def\pxpicaddcolorlist@#1#2%
+ {%
+ \begingroup
+ \edef\pxpic@tmp
+ {\ekvparse\pxpic@experr@noval\pxpic@setcolor@colorlist{#2}}%
+ \edef\pxpic@tmp
+ {%
+ \endgroup
+ \protected\def\unexpanded{#1}{\unexpanded\expandafter{#1}\pxpic@tmp}%
+ }%
+ \pxpic@tmp
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
%
% \subsection{Parser}
%
@@ -892,6 +1059,15 @@ and the derived files pxpic.pdf
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[internal]{\pxpic@openbrace}
+% For some weirder \TeX\ programming it is sometimes necessary to insert an
+% unmatched opening brace. This code does exactly that if it's expanded twice.
+% It is put into a single macro so that one can \CS{expandafter} it easier.
+% \begin{macrocode}
+\newcommand*\pxpic@openbrace{\expandafter{\iffalse}\fi}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[internal]{\pxpic@parse,\pxpic@done}
% The parsing loop is pretty simple, first check whether we're done, else open
% a new \CS{hbox} (which will form a row in the \CS{vbox} placed by
@@ -949,7 +1125,7 @@ and the derived files pxpic.pdf
\ekvifdefinedNoVal{pxpic@px}{#1}
{\csname\ekv@name{pxpic@px}{#1}N\endcsname}%
{%
- \pxpic@unknown@px{#1}%
+ \pxpic@err@unknown@px{#1}%
\pxskip
}%
}
@@ -965,7 +1141,7 @@ and the derived files pxpic.pdf
{%
\pxpic@ifempty{#1}
{\pxskip}
- {{\color{#1}\px}}%
+ {{\@declaredcolor{#1}\px}}%
}
% \end{macrocode}
% \end{macro}
@@ -996,7 +1172,7 @@ and the derived files pxpic.pdf
{%
\pxpic@ifempty{##1}
{\pxskip}
- {{\color[#1]{##1}\px}}%
+ {{\@undeclaredcolor[#1]{##1}\px}}%
}%
}
\pxpic@tmp{rgb}
@@ -1022,7 +1198,7 @@ and the derived files pxpic.pdf
% The actual definition of pixels and skips is stored in macros to which the
% frontend macros \CS{px} and \CS{pxskip} will be let inside of \CS{pxpic}.
% \begin{macrocode}
-\newcommand\pxpic@px{\vrule\@height\pxpicHT\@width\pxpicWD\@depth\z@}
+\newcommand\pxpic@px{\vrule height\pxpicHT width\pxpicWD depth\z@}
\newcommand\pxpic@skip{\hskip\pxpicWD}
% \end{macrocode}
% \end{macro}
@@ -1046,24 +1222,92 @@ and the derived files pxpic.pdf
{#1}{#2}%
}
\newcommand\pxpic@setcolor@a[2]
- {\ekvdefNoVal{pxpic@px}{#1}{{\color{#2}\px}}}
+ {%
+ \expandafter\def\csname\ekv@name{pxpic@px}{#1}N\endcsname
+ {{\@declaredcolor{#2}\px}}%
+ }
\newcommand\pxpic@setcolor@b[2]
- {\ekvdefNoVal{pxpic@px}{#1}{{\color#2\px}}}
+ {%
+ \expandafter\def\csname\ekv@name{pxpic@px}{#1}N\endcsname
+ {{\@undeclaredcolor#2\px}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\pxpic@setcolor@colorlist}
+% This macro should leave the correct code in the input stream to define a
+% single pixel. It is to be used inside of \CS{edef}, hence using
+% \CS{unexpanded}, which doesn't have an opening brace directly after it
+% so that the \CS{pxpic@ifbracket} test is fully expanded. Next we expand
+% \CS{pxpic@setcolor@a}/|b| twice (which will expand the \CS{csname}
+% contained in it) and then leave the opening bracket for \CS{unexpanded} in
+% the input stream. The code should be used inside a group so that all the
+% implicit definitions to \CS{relax} done by \CS{csname} are reverted.
+% \begin{macrocode}
+\newcommand\pxpic@setcolor@colorlist[2]
+ {%
+ \unexpanded\iffalse{\fi
+ \pxpic@ifbracket\pxpic@end#2.\pxpic@end[]\pxpic@end
+ {\expandafter\expandafter\expandafter\pxpic@openbrace\pxpic@setcolor@a}
+ {\expandafter\expandafter\expandafter\pxpic@openbrace\pxpic@setcolor@b}
+ {#1}{#2}%
+ }%
+ }
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Messages}
%
-% \begin{macro}[internal]{\pxpic@noval,\pxpic@unknown@px,\pxpic@unknown@mode}
+% \begin{macro}[internal]
+% {
+% \pxpic@err@noval,\pxpic@err@unknown@px,\pxpic@err@unknown@mode,
+% \pxpic@err@unknown@colorlist,\pxpic@err@defined@colorlist
+% }
% These are just some macros throwing errors, nothing special here.
% \begin{macrocode}
-\newcommand\pxpic@noval[1]
+\newcommand\pxpic@err@noval[1]
{\PackageError{pxpic}{Missing colour definition for name `\detokenize{#1}'}{}}
-\newcommand\pxpic@unknown@px[1]
+\newcommand\pxpic@err@unknown@px[1]
{\PackageError{pxpic}{Unknown pixel `\detokenize{#1}'. Skipping}{}}
-\newcommand\pxpic@unknown@mode[1]
+\newcommand\pxpic@err@unknown@mode[1]
{\PackageError{pxpic}{Unknown mode `#1'}{}}
+\newcommand\pxpic@err@unknown@colorlist[1]
+ {\PackageError{pxpic}{Unknown colour list `#1'}{}}
+\newcommand\pxpic@err@defined@colorlist[1]
+ {\PackageError{pxpic}{Colour list `#1' already defined}{}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\pxpic@experr}
+% This macro can be used to throw an error expandably. For this an undefined
+% control sequence \verb*|\pxpic Error:| is used. The group containing
+% \CS{expandafter} keeps the definition of \verb*|\pxpic Error:| local (it is
+% \CS{relax} after the \CS{csname}) so that it is undefined when it's used.
+% The \CS{@firstofone} is needed to get the readable output (now the undefined
+% macro and actual message are always the same argument).
+% \begin{macrocode}
+\def\pxpic@experr#1%
+ {%
+ \long\def\pxpic@experr##1%
+ {%
+ \expandafter\expandafter\expandafter
+ \pxpic@ifend
+ \@firstofone{#1##1}%
+ \pxpic@end
+ }%
+ }
+\begingroup\expandafter\endgroup
+\expandafter\pxpic@experr\csname pxpic Error:\endcsname
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\pxpic@experr@noval}
+% With the expandable error throwing mechanism out of the way, the following
+% is straight forward again.
+% \begin{macrocode}
+\newcommand\pxpic@experr@noval[1]
+ {\pxpic@experr{Missing colour definition for `#1'}}
% \end{macrocode}
% \end{macro}
%
diff --git a/graphics/pxpic/pxpic.pdf b/graphics/pxpic/pxpic.pdf
index 2148303a47..075ce07723 100644
--- a/graphics/pxpic/pxpic.pdf
+++ b/graphics/pxpic/pxpic.pdf
Binary files differ