% pgfornament.sty (utf8 encoding) % Copyright 2012-2026 Alain Matthes % SPDX-License-Identifier: LPPL-1.3c % Maintainer: Alain Matthes %---------%---------%---------%---------%---------%---------%---------%--------- % First version created by Alain Matthes le 2012-02-22. %---------%---------%---------%---------%---------%---------%---------%--------- % Inspired from psvectorian P Fradin H Voss \NeedsTeXFormat{LaTeX2e} \RequirePackage{tikz,pgfopts} \ProvidesPackage{pgfornament}[2026/10/17 v1.4 vector ornaments] %---------%---------%---------%---------%---------%---------%---------%--------- % family of ornaments (option object, default vectorian) %---------%---------%---------%---------%---------%---------%---------%--------- % v1.4 : the runtime files share the prefix pgfornament- (TeX Live rule): % library pgfornament-lib-.code.tex % ornament pgfornament-.pgf % The old names (pgflibrary.code.tex, .pgf) are still % accepted, for the families created by users with the previous versions. \gdef\OrnamentsFamily{vectorian}% \pgfkeys{% /pgfOrnaments/object/.code = {\gdef\OrnamentsFamily{#1}}% }% \ProcessPgfOptions{/pgfOrnaments}% \usetikzlibrary{calc}% v1.4 : needed by \pgfornamenthline and \pgfornamentvline %---------%---------%---------%---------%---------%---------%---------%--------- % tools %---------%---------%---------%---------%---------%---------%---------%--------- % loading of a family. The library files only define \@pgfornamentDim. \def\pgfornament@loadfamily#1{% \edef\OrnamentsFamily{#1}% \IfFileExists{pgfornament-lib-\OrnamentsFamily.code.tex}{% \xdef\pgfOrnamentsObject{pgfornament-lib-\OrnamentsFamily.code.tex}% \def\pgfornament@prefix{pgfornament-}% }{% family made with a version < 1.4 \xdef\pgfOrnamentsObject{pgflibrary\OrnamentsFamily.code.tex}% \def\pgfornament@prefix{}% }% \input{\pgfOrnamentsObject}% }% \pgfornament@loadfamily{\OrnamentsFamily}% \def\newpgfornamentfamily#1{\pgfornament@loadfamily{#1}}% % the environment is a group : the previous family is restored at the end \newenvironment{newfamily}[1][vectorian]{% \newpgfornamentfamily{#1}% \ignorespaces }{% \ignorespacesafterend }% % v1.4 : common definitions of the short macros used in the .pgf files \def\pgfornament@shortcuts{% \def\ubb{\pgfusepath{use as bounding box}}% \def\i{\pgfusepath{clip}}% \def\k{\pgfusepath{stroke}}% \let\o\pgfpathclose \let\s\pgfusepathqfillstroke \def\p ##1##2{\pgfqpoint{##1bp}{##2bp}}% \def\m ##1 ##2 {\pgfpathmoveto{\p{##1}{##2}}}% \def\l ##1 ##2 {\pgfpathlineto{\p{##1}{##2}}}% \def\r ##1 ##2 ##3 ##4 {\pgfpathrectangle{\p{##1}{##2}}{\p{##3}{##4}}}% \def\c ##1 ##2 ##3 ##4 ##5 ##6 {% \pgfpathcurveto{\p{##1}{##2}}{\p{##3}{##4}}{\p{##5}{##6}}}% }% \def\pgf@@ornament#1{% \begingroup \pgfornament@shortcuts \@@input \pgfornament@prefix\OrnamentsFamily#1.pgf\relax \endgroup }% \newcommand{\callornament}[1]{% \begingroup \pgfornament@shortcuts \IfFileExists{pgfornament-#1}% v1.4 : \callornament{vectorian1.pgf} still works {\@@input pgfornament-#1\relax}% {\@@input #1\relax}% \endgroup }% %---------%---------%---------%---------%---------%---------%---------%--------- % Les options de \pgfornament sont: % % scale : nombre (échelle, 1 par défaut) % width : nombre + unité (largeur, naturelle par défaut) % height : nombre + unité (hauteur, naturelle par défaut) % color : couleur ( par défaut couleur courante ) % symmetry=h : true/false (symétrie horizontale, false par défaut) % symmetry=v : true/false (symétrie verticale, false par défaut) % symmetry=c : true/false (symétrie centrale h+v,false par défaut) %---------%---------%---------%---------%---------%---------%---------%-------- \tikzset{pgfornamentstyle/.style={}}% \pgfkeys{% /ornament/.cd, scale/.code = {\def\pgfornamentscale{#1}}, width/.code = {\def\pgfornamentwidth{#1}}, height/.code = {\def\pgfornamentheight{#1}}, color/.code = {\def\pgfornamentcolor{#1}}, opacity/.code = {\def\pgfornamentopacity{#1}}, anchor/.code = {\def\pgfornamentanchor{#1}}, ydelta/.code = {\def\pgfornamentydelta{#1}}, symmetry/.is choice, symmetry/v/.code = {\tikzset{pgfornamentstyle/.append style={cm={-1,0,0,1,(0,0)}}}}, symmetry/c/.code = {\tikzset{pgfornamentstyle/.append style={cm={-1,0,0,-1,(0,0)}}}}, symmetry/h/.code = {\tikzset{pgfornamentstyle/.append style={cm={1,0,0,-1,(0,0)}}}}, symmetry/none/.code = {\tikzset{pgfornamentstyle/.append style={cm={1,0,0,1,(0,0)}}}}% }% %---------%---------%---------%---------%---------%---------%---------%--------- \def\pgfornament{\pgfutil@ifnextchar[{\pgf@ornament}{\pgf@ornament[]}}% \def\pgf@ornament[#1]#2{% \pgfkeys{% /ornament/.cd, scale = 1, opacity = {}, width = {}, height = {}, color = {}, ydelta = 0 pt, symmetry = none , anchor = center }% \pgfqkeys{/ornament}{#1}% \ifx\pgfornamentcolor\empty\else \tikzset{pgfornamentstyle/.append style={color=\pgfornamentcolor}}% \fi \ifx\pgfornamentopacity\empty\else \tikzset{pgfornamentstyle/.append style={opacity=\pgfornamentopacity}}% \fi \ifx\pgfornamentwidth\empty \else \@pgfornamentDim{#2}% bug correction LianTze \pgfmathsetmacro{\pgfornamentscale}{\pgfornamentwidth/\@pgfornamentX bp}% \fi \ifx\pgfornamentheight\empty \else \@pgfornamentDim{#2}% bug correction LianTze \pgfmathsetmacro{\pgfornamentscale}{\pgfornamentheight/\@pgfornamentY bp}% \fi \begin{tikzpicture}[% baseline={([yshift=\pgfornamentydelta]current bounding box.\pgfornamentanchor)}, pgfornamentstyle] \pgftransformscale{\pgfornamentscale}% \pgf@@ornament{#2}% \end{tikzpicture}% \tikzset{pgfornamentstyle/.style={cm={1,0,0,1,(0,0)}}}% }% end pgfornament \gdef\ornamenttopos{.5} \gdef\ornamenttoanchor{center} \gdef\ornamenttosymmetry{none} \tikzset{options default/.style={anchor=center, sloped, allow upside down, inner sep=0pt}} \tikzset{ornament/at/.code={\def\ornamenttopos{#1}}, options/.style={options default,#1}, ornament symmetry/.code={\def\ornamenttosymmetry{#1}}, node anchor/.code={\def\ornamenttoanchor{#1}}, ornament/.style={% to path={% \pgfextra{% \tikz@scan@one@point\pgfutil@firstofone(\tikztostart)\relax \pgf@xa=\pgf@x \pgf@ya=\pgf@y \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax \pgf@xb=\pgf@x \pgf@yb=\pgf@y \advance\pgf@xa by-\pgf@xb \advance\pgf@ya by-\pgf@yb \pgfmathveclen{\pgf@xa}{\pgf@ya}% \global\let\ornamentlen\pgfmathresult} -- node [pos=\ornamenttopos,options, anchor=\ornamenttoanchor]{% \pgfornament[width = \ornamentlen, symmetry=\ornamenttosymmetry]{#1}} (\tikztotarget)\tikztonodes %end pgfextra }% end to path }% end style }% end \tikzset \def\pgfornamenthline#1#2#3#4{% \pgfextractx{\pgf@x}{\pgfpointanchor{#1}{#3 east}}% \pgf@xa=\pgf@x \pgfextractx{\pgf@x}{\pgfpointanchor{#2}{#3 west}}% \pgf@xb=\pgf@x \advance\pgf@xb by -\pgf@xa \node[inner sep=0pt] at ($(#1.#3 east)!.5!(#2.#3 west)$) {\pgfornament[width=\pgf@xb]{#4}};% }% \def\pgfornamentvline#1#2#3#4{% \pgfextracty{\pgf@y}{\pgfpointanchor{#1}{south #3}}% \pgf@ya=\pgf@y \pgfextracty{\pgf@y}{\pgfpointanchor{#2}{north #3}}% \pgf@yb=\pgf@y \advance\pgf@yb by -\pgf@ya \node[inner sep=0pt,rotate=90] at ($(#1.south #3)!.5!(#2.north #3)$) {\pgfornament[width=\pgf@yb]{#4}};% }% \def\getornamentlength#1#2#3#4{% \pgfpointdiff{\pgfpointanchor{#1}{#2}}% {\pgfpointanchor{#3}{#4}}% \pgf@xa=\pgf@x \pgf@ya=\pgf@y \pgfmathveclen{\pgf@xa}{\pgf@ya}% \global\let\ornamentlen\pgfmathresult }% \def\getornamentangle#1#2#3{% \pgfpointdiff{\pgfpointanchor{#2}{center}}{\pgfpointanchor{#3}{center}}% \pgfmathsetmacro{#1}{atan2(\pgf@x,\pgf@y)}% }% \newcommand{\resetpgfornamentstyle}{\tikzset{pgfornamentstyle/.style={}}}% %---------%---------%---------%---------%---------%---------%---------%--------- % \pgfornamentline[options]{A}{B}{n}{ornament} %---------%---------%---------%---------%---------%---------%---------%--------- \pgfkeys{/ornamentline/.cd, color/.store in = \ornamentcolor, color = black, /ornamentline/.search also = {/tikz}}% \def\pgfornamentline{\pgfutil@ifnextchar[{\pgf@ornamentline}{\pgf@ornamentline[]}}% \def\pgf@ornamentline[#1]#2#3#4#5{% \begingroup \pgfqkeys{/ornamentline}{color=black,#1}% v1.4 : color reset at each call \pgfmathtruncatemacro\pgfornament@nb{#4}% v1.4 : integer \pgfmathtruncatemacro\pgfornament@nbm{\pgfornament@nb-1}% \path (#2) -- (#3) foreach \i in {0,...,\pgfornament@nb} {coordinate[pos=\i/\pgfornament@nb] (p\i)} [color=\ornamentcolor] foreach \i [count=\j] in {0,...,\pgfornament@nbm} {(p\i) to [ornament=#5] (p\j)};% \endgroup }% \endinput