summaryrefslogtreecommitdiff
path: root/graphics/pgf/contrib/fancyqr/fancyqr.sty
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/contrib/fancyqr/fancyqr.sty')
-rw-r--r--graphics/pgf/contrib/fancyqr/fancyqr.sty235
1 files changed, 235 insertions, 0 deletions
diff --git a/graphics/pgf/contrib/fancyqr/fancyqr.sty b/graphics/pgf/contrib/fancyqr/fancyqr.sty
new file mode 100644
index 0000000000..e727b5e039
--- /dev/null
+++ b/graphics/pgf/contrib/fancyqr/fancyqr.sty
@@ -0,0 +1,235 @@
+% Florian Sihler, 2022
+% Licensed under GNU General Public License version 3
+% https://opensource.org/licenses/gpl-3.0.html
+\def\filename{fancyqr}
+\ProvidesPackage{\filename}[2022/08/18 version v1.0 Fancy QR-Codes]
+\RequirePackage{tikz, qrcode}
+
+% element
+% x: {\the\j}; y: {\the\i} | \@max@x \@max@y
+\def\FancyQrColor#1{\if@fancyqr@gradient
+\pgfmathsetmacro\angle{Mod(\fancyqr@gradient@angle+225,360)}% rotate to align 0 to the right
+\pgfmathsetmacro\gradient{%
+ % we do rotate the x and y points before color drawing by
+ % Mod(\fancyqr@gradient@angle,360) with the shifted origin
+ % Old: #3/2 #4/2
+ ((\the\j-\@max@x/2)*cos(\angle) - (\the\i-\@max@y/2)*sin(\angle) + \@max@x/2)/\@max@x * 50% rel x [0,1]
+ + ((\the\j-\@max@x/2)*sin(\angle) + (\the\i-\@max@y/2)*cos(\angle) + \@max@y/2)/\@max@y * 50% rel y [0,1]
+ }\@declaredcolor{qr@fancy@gradient@br!\gradient!qr@fancy@gradient@tl}\else\@declaredcolor{qr@fancy@gradient@tl}\fi{#1}}
+
+% O 1 O
+% 2 X 3
+% O 4 O
+% uses \@up\@left\@right\@down
+\def\GetPattern{%
+\ifcsname qcc\@up\@left\@right\@down\endcsname
+ \csname qcc\@up\@left\@right\@down\endcsname
+\else\rule\qr@modulesize\z@\fi}
+
+\tikzset{qrrc/.style={rounded corners=.5\qr@modulesize},qrrd/.style={fill}}
+
+% is larger to be compensated by overlaps
+\def\qrm{\dimexpr\qr@modulesize+.15\p@\relax}
+\long\def\qr@newpattern#1#2#3#4#5{%
+\expandafter\def\csname qcc#1#2#3#4\endcsname{%
+ \parbox[b][\qr@modulesize]\qr@modulesize{\kern-.075\p@\smash{\clap{\tikz[x=\qrm,y=\qrm,inner sep=\z@,outer sep=\z@]{\path[qrrd]#5;}}}}%
+}}
+
+\def\FancyLoadDefault{%
+% .
+\qr@newpattern0000{[qrrc](0,0)rectangle(\qrm,\qrm)}%
+% | | - -
+\qr@newpattern1000{(0,\qrm)[qrrc]--(0,0)--(\qrm,0)[sharp corners]--(\qrm,\qrm)--cycle}%
+\qr@newpattern0001{(0,0)[qrrc]--(0,\qrm)--(\qrm,\qrm)[sharp corners]--(\qrm,0)--cycle}%
+\qr@newpattern0100{(0,0)[qrrc]--(\qrm,0)--(\qrm,\qrm)[sharp corners]--(0,\qrm)--cycle}%
+\qr@newpattern0010{(\qrm,0)[qrrc]--(0,0)--(0,\qrm)[sharp corners]--(\qrm,\qrm)--cycle}%
+% corners
+\qr@newpattern1100{(\qrm,\qrm)[qrrc]--(\qrm,0)[sharp corners]--(0,0)--(0,\qrm)--cycle}% top left
+\qr@newpattern1010{(0,\qrm)[qrrc]--(0,0)[sharp corners]--(\qrm,0)--(\qrm,\qrm)--cycle}% top right
+\qr@newpattern0101{(0,\qrm)[qrrc]--(\qrm,\qrm)[sharp corners]--(\qrm,0)--(0,0)--cycle}% bottom left
+\qr@newpattern0011{(0,0)[qrrc]--(0,\qrm)[sharp corners]--(\qrm,\qrm)--(\qrm,0)--cycle}% bottom right
+% straights | --
+\qr@newpattern1001{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern0110{(0,0)rectangle(\qrm,\qrm)}%
+% enclosed
+\qr@newpattern1111{(0,0)rectangle(\qrm,\qrm)}%
+% t's
+\qr@newpattern0111{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern1011{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern1101{(0,0)rectangle(\qrm,\qrm)}%
+\qr@newpattern1110{(0,0)rectangle(\qrm,\qrm)}%
+}
+\FancyLoadDefault % allows to reset the style after other loads
+\def\@fancy@qr@default@name{default}
+
+\def\FancyQrLoad#1{\let\@tmp\newpattern\let\newpattern\qr@newpattern\@bsphack\def\@@tmp{#1}\ifx\@@tmp\@fancy@qr@default@name\FancyLoadDefault\else
+\expandafter\edef\csname pingu@lib@#1@atcode\endcsname{\the\catcode`\@}%
+\catcode`\@=11\relax
+\input{fancyqr-style-#1.code}
+\catcode`\@=\csname pingu@lib@#1@atcode\endcsname
+\fi\@esphack\let\newpattern\@tmp\let\@tmp\relax}
+
+
+% modify the getter so everything that is not defined is white:
+\def\fancy@qr@matrixentry#1#2#3{%
+ \ifcsname #1@#2@#3\endcsname
+ % #1 = matrix name
+ % #2 = row number
+ % #3 = column number
+ \csname #1@#2@#3\endcsname
+ \else\qr@white@format\fi
+}%
+
+\def\FancyQrDoNotPrintSquare#1#2{\def\fancy@qr@donotprint@center@x{#1}\def\fancy@qr@donotprint@center@y{#2}}
+\FancyQrDoNotPrintSquare00
+
+\newif\iffancy@qr@do@print@
+\def\qr@fancy@updateif#1#2{\fancy@qr@do@print@true
+\ifnum#1>\@do@y@min\relax \ifnum#1<\@do@y@max\relax \ifnum#2>\@do@x@min\relax \ifnum#2<\@do@x@max\relax \fancy@qr@do@print@false \fi\fi\fi\fi}
+
+\newif\iffancy@qr@roundcut@
+\fancy@qr@roundcut@true
+\let\FancyQrHardCut\fancy@qr@roundcut@false
+\let\FancyQrRoundCut\fancy@qr@roundcut@true
+
+% clear plus if not to be printed
+\def\qr@fancy@clear@surround#1#2#3{%
+ \qr@fancy@updateif{\the\numexpr#2-1}{#3}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@\the\numexpr#2-1 @#3\endcsname\@undefined \fi
+ \qr@fancy@updateif{\the\numexpr#2+1}{#3}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@\the\numexpr#2+1 @#3\endcsname\@undefined \fi
+ \qr@fancy@updateif{#2}{\the\numexpr#3-1}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@#2@\the\numexpr#3-1\endcsname\@undefined \fi
+ \qr@fancy@updateif{#2}{\the\numexpr#3+1}%
+ \iffancy@qr@do@print@\else \expandafter\let\csname #1@#2@\the\numexpr#3+1\endcsname\@undefined \fi
+}
+
+\newif\if@fancyqr@image@
+
+\def\fancy@qr@printmatrix#1{%
+ \def\qr@white{0}\def\qr@black{1}%
+ \let\qr@black@fixed\qr@black
+ \let\qr@white@fixed\qr@white
+ \let\qr@black@format\qr@black
+ \let\qr@white@format\qr@white
+ %Set module size
+ \qr@modulesize=\qr@desiredheight
+ \divide\qr@modulesize by \qr@size\relax
+ \qr@minipagewidth=\qr@modulesize
+ \if@fancyqr@image@% image is in \fancyqr@imgbox
+ \pgfmathsetmacro\@x{int(ceil((.5\wd\fancyqr@imgbox)/\qr@modulesize)+\fancyqr@img@padding@x)}%
+ \pgfmathsetmacro\@y{int(ceil((.5\ht\fancyqr@imgbox+.5\dp\fancyqr@imgbox)/\qr@modulesize)+\fancyqr@img@padding@y)}%
+ \FancyQrDoNotPrintSquare\@x\@y
+ \fi
+ \multiply\qr@minipagewidth by \qr@size\relax
+ \ifqr@tight \else \advance\qr@minipagewidth by 8\qr@modulesize \fi
+ \minipage\qr@minipagewidth
+ \baselineskip=\qr@modulesize
+ \ifqr@tight\else\rule\z@{4\qr@modulesize}\par\fi% %Blank space at top.
+ \edef\@max@x{\qr@numberofrowsinmatrix{#1}}%
+ \edef\@max@y{\qr@numberofcolsinmatrix{#1}}%
+ \edef\@do@x@min{\the\numexpr\@max@x/2-\fancy@qr@donotprint@center@x-1}%
+ \edef\@do@x@max{\the\numexpr\@max@x/2+\fancy@qr@donotprint@center@x+1}%
+ \edef\@do@y@min{\the\numexpr\@max@y/2-\fancy@qr@donotprint@center@y-1}%
+ \edef\@do@y@max{\the\numexpr\@max@y/2+\fancy@qr@donotprint@center@y+1}%
+ \qr@for \i=1 to \@max@y by 1{%
+ \ifqr@tight\else\rule{4\qr@modulesize}\z@\fi% %Blank space at left.
+ \qr@for \j=1 to \@max@x by 1{%
+ \qr@fancy@updateif\i\j
+ \iffancy@qr@do@print@
+ \edef\@mid{\qr@matrixentry{#1}{\the\i}{\the\j}}%
+ \ifnum\@mid=\qr@white
+ \rule\qr@modulesize\z@
+ \else% if not white, get its pattern
+ \iffancy@qr@roundcut@\qr@fancy@clear@surround{#1}{\the\i}{\the\j}\fi
+ \edef\@up{\qr@matrixentry{#1}{\the\numexpr\the\i-1}{\the\j}}%
+ \edef\@left{\qr@matrixentry{#1}{\the\i}{\the\numexpr\the\j-1}}%
+ \edef\@right{\qr@matrixentry{#1}{\the\i}{\the\numexpr\the\j+1}}%
+ \edef\@down{\qr@matrixentry{#1}{\the\numexpr\the\i+1}{\the\j}}%
+ \FancyQrColor{\GetPattern}%
+ \fi\else \rule\qr@modulesize\z@\fi
+ }\par}%
+ \ifqr@tight\else\rule\z@{4\qr@modulesize}\par\fi
+ \endminipage
+ \if@fancyqr@image@\nobreak
+ \llap{\parbox\qr@minipagewidth{\centering\usebox\fancyqr@imgbox}}\fi
+}%
+
+\def\fancy@qr@setup#1{%
+ \qr@creatematrix{#1}%
+ \expandafter\gdef\csname #1@numrows\endcsname{\qr@size}%
+ \expandafter\gdef\csname #1@numcols\endcsname{\qr@size}%
+ % we do not need to create blank because we store all
+ \qr@placefinderpatterns{#1}%
+ \qr@placetimingpatterns{#1}%
+ \qr@placealignmentpatterns{#1}%
+}
+
+\newcount\c@fancy@a \newcount\c@fancy@b
+% the normal data is... well...
+\def\fancy@qr@writedata#1#2{%
+ % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc.
+ % #2 = a string consisting of 0's and 1's to write into the matrix.
+ \expandafter\c@fancy@a\the\numexpr\qr@numberofrowsinmatrix{#1}\relax
+ \expandafter\c@fancy@b\the\numexpr\qr@numberofcolsinmatrix{#1}\relax
+ \edef\qr@datatowrite{#2\relax}%
+ \c@qr@i0\relax
+ \@whilenum\c@qr@i<\c@fancy@a\do{%
+ \c@qr@j0 \advance\c@qr@i\@ne
+ \@whilenum\c@qr@j<\c@fancy@b\do{%
+ \advance\c@qr@j\@ne
+ \expandafter\fancy@qr@writebit\qr@datatowrite:{#1}%
+ }%
+ }%
+}
+
+\def\fancy@qr@writebit#1#2:#3{%
+ % #3 = matrix name
+ % (qr@i,qr@j) = position to write in (LaTeX counters)
+ % #1 = bit to be written
+ % #2 = remaining bits plus '\relax' as an end-of-file marker
+ \edef\qr@datatowrite{#2}%
+ \ifnum#1=1
+ \qr@storetomatrix{#3}{\number\c@qr@i}{\number\c@qr@j}{\qr@black}%
+ \else
+ \qr@storetomatrix{#3}{\number\c@qr@i}{\number\c@qr@j}{\qr@white}%
+ \fi
+}%
+
+
+\def\fancy@qr@printsavedbinarymatrix#1{%
+ \def\qr@binarystring{#1\relax\relax}%
+ \fancy@qr@setup{@tmp}%
+ \fancy@qr@writedata{@tmp}{\qr@binarystring}%
+ \fancy@qr@printmatrix{@tmp}%
+}%
+
+\newsavebox\fancyqr@imgbox
+\define@key{fancyqr}{image x padding}{\def\fancyqr@img@padding@x{#1}}
+\define@key{fancyqr}{image y padding}{\def\fancyqr@img@padding@y{#1}}
+\define@key{fancyqr}{image padding}{\def\fancyqr@img@padding@x{#1}\def\fancyqr@img@padding@y{#1}}
+\define@key{fancyqr}{image}{\@fancyqr@image@true\savebox\fancyqr@imgbox{#1}}
+\define@key{fancyqr}{color}{\@fancyqr@gradientfalse\colorlet{qr@fancy@gradient@tl}{#1}}
+\define@key{fancyqr}{left color}{\colorlet{qr@fancy@gradient@br}{#1}}
+\define@key{fancyqr}{l color}{\colorlet{qr@fancy@gradient@br}{#1}}
+\define@key{fancyqr}{right color}{\colorlet{qr@fancy@gradient@tl}{#1}}
+\define@key{fancyqr}{r color}{\colorlet{qr@fancy@gradient@tl}{#1}}
+\define@key{fancyqr}{gradient angle}{\def\fancyqr@gradient@angle{#1}}
+\define@boolkey{fancyqr}[@fancyqr@]{gradient}[true]{}% if@fancyqr@gradient
+
+\def\fancyqrset#1{\setkeys{qr,fancyqr}{#1}}
+\fancyqrset{image padding=0,gradient=true,gradient angle=135,r color=teal,l color=purple}
+
+\def\@fancyqr@init{\let\qr@printsavedbinarymatrix\fancy@qr@printsavedbinarymatrix\let\qr@matrixentry\fancy@qr@matrixentry\let\qr@printmatrix\fancy@qr@printmatrix}
+\def\fancyqr{\@ifstar\s@fancyqr\ns@fancyqr}
+% we rebuild some parts of qrcode to allow this macro to extend the keys while keeping the wrapper
+\def\s@fancyqr{\qr@starinvokedtrue\@@fancyqr}
+\def\ns@fancyqr{\qr@starinvokedfalse\@@fancyqr}
+\newcommand\@@fancyqr[1][]{\begingroup\@fancyqr@init
+\ifqr@starinvoked\qr@hyperlinkfalse\fi
+\setkeys{qr,fancyqr}{#1}\bgroup
+\qr@verbatimcatcodes\qr@setescapedspecials\qrcode@in}
+\endinput
+
+% TODO: NEGATIVE PATTERNS IF MIDDLE IS 0
+% => make rounded negative corners \ No newline at end of file