% Copyright 2018 by Mark Wibrow % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. \usetikzlibrary{decorations}% \usepgflibrary{decorations.text}% % Code for the `text effects along path' decoration % Some text constants % To do: merge these with existing text constants \def\tikz@lib@dec@te@space@text{space}% \def\tikz@lib@dec@align@left@text{left}% \def\tikz@lib@dec@align@right@text{right}% \def\tikz@lib@dec@align@center@text{center}% \def\tikz@lib@dec@te@none@text{none}% % Some ifs \newif\iftikz@lib@dec@te@pathfromtext% \newif\iftikz@lib@dec@te@segmentfromwidth% \newif\iftikz@lib@dec@te@scaletexttopath% \newif\iftikz@lib@dec@te@fittexttopath% \newif\iftikz@lib@dec@te@wordsep% \newif\iftikz@lib@dec@te@finalletter% % Utility macros % To do: integrate with existing pgf macros \def\tikz@lib@dec@te@addto@macro#1#2{% \expandafter\def\expandafter#1\expandafter{#1#2}% }% \def\tikz@lib@dec@te@namelet#1#2{% \expandafter\expandafter\expandafter\let\expandafter\expandafter\csname\expandafter#1\expandafter\endcsname\expandafter=\csname#2\endcsname% }% \def\tikz@lib@dec@te@advancecountmacro#1#2{% \pgfutil@tempcnta=#1\relax% \advance\pgfutil@tempcnta by#2\relax% \edef#1{\the\pgfutil@tempcnta}% }% \def\tikz@lib@dec@te@advancedimenmacro#1#2{% \pgf@x=#1\relax% \advance\pgf@x by#2\relax% \edef#1{\the\pgf@x}% }% % Macros for defining and updating text parameters \def\tikz@lib@dec@te@start@parameters#1{% \expandafter\let\csname tikz@lib@dec@te@character@#1\endcsname=\pgfutil@empty% }% \def\tikz@lib@dec@te@addto@parameters#1#2{% \expandafter\tikz@lib@dec@te@addto@macro\expandafter% {\csname tikz@lib@dec@te@character@#1\endcsname}{#2}% }% \def\tikz@lib@dec@te@addmacroto@parameters#1#2{% \def\tikz@lib@dec@te@marshal{\expandafter\tikz@lib@dec@te@addto@macro\expandafter% {\csname tikz@lib@dec@te@character@#1\endcsname}}% \expandafter\tikz@lib@dec@te@marshal\expandafter{\expandafter\def\expandafter#2\expandafter{#2}}% }% \def\tikz@lib@dec@te@getparameters#1{\csname tikz@lib@dec@te@character@#1\endcsname}% \let\tikz@lib@dec@te@textoptions=\pgfutil@empty \let\tikz@lib@dec@te@widthoptions=\pgfutil@empty \let\tikz@lib@dec@te@charactercountvar=\pgfutil@empty \let\tikz@lib@dec@te@charactertotalvar=\pgfutil@empty \let\tikz@lib@dec@te@lettercountvar=\pgfutil@empty \let\tikz@lib@dec@te@lettertotalvar=\pgfutil@empty \let\tikz@lib@dec@te@wordcountvar=\pgfutil@empty \let\tikz@lib@dec@te@wordctotalvar=\pgfutil@empty \let\tikz@lib@dec@te@transformtext=\pgfutil@empty% % Keys... lots of them... \pgfkeys{/pgf/decoration/text effects/.cd, .unknown/.code={\let\tikz@lib@dec@te@key@tmp=\pgfkeyscurrentname% \pgfkeysalso{/tikz/\tikz@lib@dec@te@key@tmp={#1}}}, path from text/.is if=tikz@lib@dec@te@pathfromtext, path from text angle/.store in=\tikz@lib@dec@te@pathfromtextangle, path from text angle=0, fit text to path/.is if=tikz@lib@dec@te@fittexttopath, characters/.style={/pgf/decoration/text effects/every character/.style={#1}}, characters/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character/.append style={#1}}}, character widths/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.style={#1}}}, character widths/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.append style={#1}}}, character count/.store in=\tikz@lib@dec@te@charactercountvar, character count=, character total/.store in=\tikz@lib@dec@te@charactertotalvar, character total=, letter count/.store in=\tikz@lib@dec@te@lettercountvar, letter count=, letter total/.store in=\tikz@lib@dec@te@lettertotalvar, letter total=, word count/.store in=\tikz@lib@dec@te@wordcountvar, word count=, word total/.store in=\tikz@lib@dec@te@wordtotalvar, word total=, % style characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@stylecharacters{#1}{#2}}, text along path/.style={ inner xsep=0pt, anchor=base, transform shape }, segment from width/.is if=tikz@lib@dec@te@segmentfromwidth, segment from width=true, word separator/.code={% \def\tikz@lib@dec@te@tmp{#1}% \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@space@text% \let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken% \else% \def\tikz@lib@dec@te@wordsep{#1} \fi}, word separator=space, character command/.code={% \def\tikz@lib@dec@te@tmp{#1}% \ifx\tikz@lib@dec@te@tmp\pgfutil@empty% \def\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@charactertypesetonly}% \else% \def\tikz@lib@dec@te@charactercommand{#1}% \fi% }, character command=, every character width/.style={/pgf/decoration/text effects/every character/.try}, every character/.style={}, reverse text/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% {\tikz@lib@dec@te@reversetext}}, group letters into words/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% {\tikz@lib@dec@te@groupletters}}, group letters/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% {\tikz@lib@dec@te@groupletters}}, replace characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@replacecharacters{#1}{#2}}, scale text to path/.is if=tikz@lib@dec@te@scaletexttopath, fit text to path/.is if=tikz@lib@dec@te@fittexttopath, repeat text/.store in=\tikz@lib@dec@te@repeattext, repeat text/.default=-1, repeat text=0, }% \def\tikz@lib@dec@te@charactertypesetonly#1{#1}% \tikzset{% text effects/.code={\pgfkeysalso{/pgf/decoration/text effects/.cd,#1}}, }% % Prepare the decoration text % % This sets up all the character/letter/word, counts/totals % and calculates the default width of the characters/text % (which may be modified later). % \def\tikz@lib@dec@te@preparetext{% % Step 1: scan all the characters in the decoration text \let\tikz@lib@dec@te@text=\pgfdecorationtext% \tikz@lib@dec@te@scancharacters{% \expandafter\let\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@scancount @token\endcsname=% \tikz@lib@dec@te@character% }% \let\tikz@lib@dec@te@charactertotalcount=\tikz@lib@dec@te@scancount% % Step 2: reverse and/or group characters/letters. \ifx\tikz@lib@dec@te@transformtext\pgfutil@empty% \else% \tikz@lib@dec@te@transformtext% \fi% % Step 3: get the character/letter/word counts \def\tikz@lib@dec@te@charactercount{0}% \def\tikz@lib@dec@te@wordcount{0}% \def\tikz@lib@dec@te@wordsepcount{0}% \def\tikz@lib@dec@te@lettercount{0}% \def\tikz@lib@dec@te@lastcharacter{0}% \pgfmathloop% \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% \ifnum\tikz@lib@dec@te@lettercount>0\relax% \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}% \fi \else% \expandafter\let\expandafter\tikz@lib@dec@te@character\expandafter=\csname tikz@lib@dec@te@character@\pgfmathcounter @token\endcsname% \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@charactercount}{1}% \tikz@lib@dec@te@start@parameters{\tikz@lib@dec@te@charactercount}% \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@charactercount}% \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep% \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@wordsepcount}{1}% \ifnum\tikz@lib@dec@te@lettercount>0\relax% \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}% \fi \def\tikz@lib@dec@te@lettercount{0}% \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordseptrue}% \else \ifnum\tikz@lib@dec@te@lettercount=0\relax% \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@wordcount{1}% \fi% \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@finalletterfalse}% \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@lettercount}{1}% \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordsepfalse}% \expandafter\let\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname=\tikz@lib@dec@te@lettercount% \fi% \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@lettercount}% \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordcount}% \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@character}% \let\tikz@lib@dec@te@lastcharactercount=\pgfmathcounter% \repeatpgfmathloop% \let\tikz@lib@dec@te@wordtotal=\tikz@lib@dec@te@wordcount% % Step 4: add character/letter/word totals \pgfmathloop \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% \else% \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@charactertotalcount}% \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@wordtotal}% \expandafter\let\expandafter\tikz@lib@dec@te@lettertotalcount\expandafter=\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname% \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@lettertotalcount}% \repeatpgfmathloop% % Step 5: calculate the the text and character width % but do not add to the parameters yet. \def\tikz@lib@dec@te@textwidth{0pt}% \pgfmathloop% \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% \else% \def\tikz@lib@dec@te@characterwidth{0pt}% \tikz@lib@dec@te@getcharacterwidth{\pgfmathcounter}% \expandafter\let\csname tikz@lib@dec@te@character@\pgfmathcounter @width\endcsname=\tikz@lib@dec@te@characterwidth% \pgf@x=\tikz@lib@dec@te@characterwidth\relax% \pgf@x=0.5\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% \tikz@lib@dec@te@advancedimenmacro{\tikz@lib@dec@te@textwidth}{\tikz@lib@dec@te@characterwidth}% \repeatpgfmathloop% }% % Does the category code of the space matter? \def\tikz@lib@dec@te@spacetoken{ }% \let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken % Scan and count the characters in \tikz@lib@dec@te@text % % Create macros \tikz@lib@dec@te@character@@token containing % the nth character. % % Total number of characters is store in % \tikz@lib@dec@te@chractertotal@count % \def\tikz@lib@dec@te@scancharacters#1{% \def\tikz@lib@dec@te@@@scancharacters@process{#1}% \def\tikz@lib@dec@te@scancount{0}% \expandafter\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@text\tikz@lib@dec@te@scancharacters}% \def\tikz@lib@dec@te@@scancharacters{% \futurelet\tikz@lib@dec@te@token\tikz@lib@dec@te@@@scancharacters}% \def\tikz@lib@dec@te@@@scancharacters{% \ifx\tikz@lib@dec@te@token\tikz@lib@dec@te@scancharacters% \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@@scancharacters% \else% \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@scancount{1}% \ifx\tikz@lib@dec@te@token\pgfutil@sptoken% \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@space% \else% \ifx\tikz@lib@dec@te@token\bgroup% \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@bgroup% \else% \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@normal% \fi% \fi% \fi% \tikz@lib@dec@te@next% }% \def\tikz@lib@dec@te@@@scancharacters@space{% \let\tikz@lib@dec@te@character=\tikz@lib@dec@te@spacetoken% \tikz@lib@dec@te@@@scancharacters@process% \pgfutil@ifnextchar x\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@@scancharacters% }% \def\tikz@lib@dec@te@@@scancharacters@bgroup#1{% \def\tikz@lib@dec@te@character{{#1}}% \tikz@lib@dec@te@@@scancharacters@process% \tikz@lib@dec@te@@scancharacters% }% \def\tikz@lib@dec@te@@@scancharacters@normal#1{% \def\tikz@lib@dec@te@character{#1}% \tikz@lib@dec@te@@@scancharacters@process% \tikz@lib@dec@te@@scancharacters% }% \def\tikz@lib@dec@te@@@@scancharacters#1\tikz@lib@dec@te@scancharacters{}% % Reverse the order of the scanned characters in the text % (Actually reverse the ordering of the macros containing the characters) \def\tikz@lib@dec@te@reversetext{% \c@pgf@counta=\tikz@lib@dec@te@charactertotalcount% \pgfmathloop% \ifnum\pgfmathcounter>\c@pgf@counta% \else% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\pgfmathcounter @token}{tikz@lib@dec@te@character@\the\c@pgf@counta @token}% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@tmp}% \advance\c@pgf@counta by-1\relax% \repeatpgfmathloop% }% % Group letters (i.e., anything that isn't the word separator) % as single characters (words). \def\tikz@lib@dec@te@groupletters{% \c@pgf@counta=0\relax% \let\tikz@lib@dec@te@tmp=\pgfutil@empty% \let\tikz@lib@dec@te@@tmp=\pgfutil@empty% \pgfmathloop% \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% \ifx\tikz@lib@dec@te@@tmp\pgfutil@empty% \else% \advance\c@pgf@counta by1\relax% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}% \fi% \else% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}% \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@wordsep% \advance\c@pgf@counta by1\relax% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}% \let\tikz@lib@dec@te@@tmp=\pgfutil@empty% \advance\c@pgf@counta by1\relax% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@wordsep}% \else% \expandafter\tikz@lib@dec@te@addto@macro\expandafter{\expandafter\tikz@lib@dec@te@@tmp\expandafter}\expandafter{\tikz@lib@dec@te@tmp}% \fi% \repeatpgfmathloop% \edef\tikz@lib@dec@te@charactertotalcount{\the\c@pgf@counta}% }% % Get width of node containing only the current character. \def\tikz@lib@dec@te@getcharacterwidth#1{% \csname tikz@lib@dec@te@character@#1\endcsname% \tikz@lib@dec@te@getoptions{every character width/.try}% \let\tikz@lib@dec@te@lastcharacterwidth=\tikz@lib@dec@te@characterwidth% \pgfpositionnodelater\tikz@lib@dec@te@@getcharacterwidth% \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{% \expandafter\node\expandafter[\tikz@lib@dec@te@options,scale=\tikz@lib@dec@scaledcharacterwidthfactor]% {\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};% \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@characterwidth@tmp% }{% \tikz@lib@dec@te@getcharacter@replacementwidth{\tikz@lib@dec@te@character}% \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@character@replacementwidth% }% }% % Update the character parameters with the widths. \def\tikz@lib@dec@te@addwidthstoparameters{% \pgfmathloop% \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% \else% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterwidth}{tikz@lib@dec@te@character@\pgfmathcounter @width}% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterprewidth}{tikz@lib@dec@te@character@\pgfmathcounter @prewidth}% \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterpostwidth}{tikz@lib@dec@te@character@\pgfmathcounter @postwidth}% \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterwidth}% \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterprewidth}% \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterpostwidth}% \repeatpgfmathloop% }% % Get the options to applied to a character node. \def\tikz@lib@dec@te@addoptions#1{% \expandafter\def\expandafter\tikz@lib@dec@te@options\expandafter{\tikz@lib@dec@te@options,#1}% }% \def\tikz@lib@dec@te@getoptions#1{% \let\tikz@lib@dec@te@lastcharactercommand=\tikz@lib@dec@te@charactercommand% \def\tikz@lib@dec@te@options{/pgf/decoration/text effects/.cd}% \tikz@lib@dec@te@addoptions{#1}% \let\tikzdecorationcharactercount=\tikz@lib@dec@te@charactercount% \let\tikzdecorationcharactertotal=\tikz@lib@dec@te@charactertotalcount% \let\tikzdecorationlettercount=\tikz@lib@dec@te@lettercount% \let\tikzdecorationlettertotal=\tikz@lib@dec@te@lettertotalcount% \let\tikzdecorationwordcount=\tikz@lib@dec@te@wordcount% \let\tikzdecorationwordtotal=\tikz@lib@dec@te@wordtotal% \let\tikzdecorationcharacter=\tikz@lib@dec@te@character% % % Define the count variables (if required) \ifx\tikz@lib@dec@te@charactercountvar\pgfutil@empty% \else% \expandafter\let\tikz@lib@dec@te@charactercountvar=\tikz@lib@dec@te@charactercount% \fi% % \ifx\tikz@lib@dec@te@charactertotalvar\pgfutil@empty% \else% \expandafter\let\tikz@lib@dec@te@charactertotalvar=\tikz@lib@dec@te@charactertotalcount% \fi% % \ifx\tikz@lib@dec@te@wordcountvar\pgfutil@empty% \else% \expandafter\let\tikz@lib@dec@te@wordcountvar=\tikz@lib@dec@te@wordcount% \fi% % \ifx\tikz@lib@dec@te@wordtotalvar\pgfutil@empty% \else% \expandafter\let\tikz@lib@dec@te@wordtotalvar=\tikz@lib@dec@te@wordtotal% \fi% % \ifx\tikz@lib@dec@te@lettercountvar\pgfutil@empty% \else% \expandafter\let\tikz@lib@dec@te@lettercountvar=\tikz@lib@dec@te@lettercount% \fi% % \ifx\tikz@lib@dec@te@lettertotalvar\pgfutil@empty% \else% \expandafter\let\tikz@lib@dec@te@lettertotalvar=\tikz@lib@dec@te@lettetotal% \fi% % \edef\tikz@lib@dec@te@tmp{character \tikz@lib@dec@te@charactercount/.try,% character {\meaning\tikz@lib@dec@te@character}/.try}% \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep% \tikz@lib@dec@te@addoptions{/pgf/decoration/text effects/every word separator/.try}% \else% \ifnum\tikz@lib@dec@te@wordcount>0\relax% \edef\tikz@lib@dec@te@tmp{every word/.try, word \tikz@lib@dec@te@wordcount/.try}% \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% \ifnum\tikz@lib@dec@te@lettercount>0\relax% \edef\tikz@lib@dec@te@tmp{every letter/.try,every \tikz@lib@dec@te@lettercount\space letter/.try}% \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% \ifnum\tikz@lib@dec@te@lettercount=1\relax% \edef\tikz@lib@dec@te@tmp{every first letter/.try}% \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% \fi% \iftikz@lib@dec@te@finalletter% \tikz@lib@dec@te@addoptions{every final letter/.try}% \fi% \fi% \fi% \fi% }% % Called by `late positioning' of the node % to get the width of the bounding box % of a character. \def\tikz@lib@dec@te@@getcharacterwidth{% \iftikz@lib@dec@te@segmentfromwidth% \pgf@x=\pgfpositionnodelatermaxx\relax% \advance\pgf@x by-\pgfpositionnodelaterminx\relax% \else% \pgf@x=\pgfpositionnodelatermaxy\relax% \advance\pgf@x by-\pgfpositionnodelaterminy\relax% \fi% \xdef\tikz@lib@dec@te@characterwidth@tmp{\the\pgf@x}% }% \def\tikz@lib@dec@te@drawcharacter{% \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname% \tikz@lib@dec@te@getoptions{every character/.try}% \pgfpositionnodelater\relax% \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{% \expandafter\node\expandafter[\tikz@lib@dec@te@options, scale=\tikz@lib@dec@scaledcharacterwidthfactor]{\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};% }{\tikz@lib@dec@te@drawcharacter@replacement{\tikz@lib@dec@te@character}}% }% % Replace the character #1 with a character@replacement % \def\tikz@lib@dec@te@drawcharacter@replacement#1{% \pgfscope% \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}% \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname% \endpgfscope% }% % Get the width of the character@replacement associated with % the character #1 % \newbox\tikz@lib@dec@te@box \def\tikz@lib@dec@te@getcharacter@replacementwidth#1{% \pgfinterruptpicture% \setbox\tikz@lib@dec@te@box=\hbox{% \pgfpicture \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}% \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname% \endpgfpicture}% \xdef\tikz@lib@dec@te@character@replacementwidth{\the\wd\tikz@lib@dec@te@box}% \endpgfinterruptpicture% }% \def\tikz@lib@dec@scaledcharacterwidthfactor{1}% % Set up the decoration \def\tikz@lib@dec@te@state@setup@precomputation{% \def\tikz@lib@te@alignshift{0pt}% \iftikz@lib@dec@te@pathfromtext% % The width of the text and characters has already been calculated. \else% \let\tikz@lib@dec@te@text=\pgfdecorationtext% % Get the character tokens and the total number of characters. \tikz@lib@dec@te@preparetext% \iftikz@lib@dec@te@scaletexttopath% % OK, *scaling* text to path is easy. % Simply divide the path length by the text width to % obtain the scaling factor which will be applied % "at the last minute"... \pgfmathdivide{\pgfdecoratedpathlength}{\tikz@lib@dec@te@textwidth}% \let\tikz@lib@dec@scaledcharacterwidthfactor=\pgfmathresult% \expandafter\pgfkeys\expandafter{\tikz@lib@dec@te@tmp}% % ... and recalculate the (pre and post) widths. \pgfmathloop \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% \else% \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax% \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% % \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax% \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% \repeatpgfmathloop% % Update parameters with thewidths. \tikz@lib@dec@te@addwidthstoparameters% \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength% \else% \iftikz@lib@dec@te@fittexttopath% % *Fitting* text is less easy. % The pre and post width of all except the first and last characters % must be recalculated. % Only the post width of the first character and the pre width % of the final character are scaled as these characters should be % fixed and the start and end of the path, respectively. % % We hope that the decoration engine is accurate enough to position % the last word correctly. \pgf@x=\pgfdecoratedpathlength% \pgf@xa=\csname tikz@lib@dec@te@character@1@postwidth\endcsname\relax% \pgf@xb=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @prewidth\endcsname\relax% \advance\pgf@x by-\pgf@xa% \advance\pgf@x by-\pgf@xb% \pgf@y=\tikz@lib@dec@te@textwidth\relax% \advance\pgf@y by-\pgf@xa% \advance\pgf@y by-\pgf@xb% % \pgfmathdivide{\the\pgf@x}{\the\pgf@y}% \let\tikz@lib@dec@characterwidthscale=\pgfmathresult% \pgfmathloop \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount\relax% \else% \ifnum\pgfmathcounter>1\relax% \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax% \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% \fi% \ifnum\pgfmathcounter<\tikz@lib@dec@te@charactertotalcount\relax% \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax% \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% \fi% \repeatpgfmathloop% % Update parameters with widths. \tikz@lib@dec@te@addwidthstoparameters% \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength% \else% % Calculate the distance to move along the path for alignment. \pgfkeysgetvalue{/pgf/decoration/text align/align}{\tikz@lib@dec@align}% \ifx\tikz@lib@dec@align\tikz@lib@dec@align@center@text% \pgf@x=\pgfdecoratedpathlength\relax% \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax% \ifdim\pgf@x<0pt\relax% \pgf@x=0pt\relax% \fi% \divide\pgf@x by2\relax% % Adjust the pre-width of the first character... \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax% \advance\pgf@xa by\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}% % ...and the post-width of the last character. \pgf@xa=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname\relax% \advance\pgf@xa by\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname{\the\pgf@xa}% \else% \ifx\tikz@lib@dec@align\tikz@lib@dec@align@right@text% \pgf@x=\pgfdecoratedpathlength\relax% \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax% \ifdim\pgf@x<0pt\relax% \pgf@x=0pt\relax% \fi% % Adjust the pre-width of the first character... \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax% \advance\pgf@xa by\pgf@x% \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}% \fi% \fi% \tikz@lib@dec@te@addwidthstoparameters% \fi% \fi% \fi% }% % Evil hack into the decoration code. % % If the path contains single move to and the `path from text' % key is set to true. The width of the text is calculated here % and the (straight line) path automatically calculated. % \def\pgf@decorate@path@check@moveto#1{% \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop}% \def\pgf@decorate@token@stop{\pgf@decorate@stop}% \def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{% \def\pgf@decorate@temp{#4}% \pgf@x=#2\relax% \pgf@y=#3\relax% \ifx\pgf@decorate@temp\pgf@decorate@token@stop% \iftikz@lib@dec@te@pathfromtext% % Get the start position... \pgfextract@process\tikz@lib@dec@te@pathstart{}% \tikz@lib@dec@te@preparetext% \tikz@lib@dec@te@addwidthstoparameters% % ... and create a lineto path of the correct length. \pgfsetpath\pgfutil@empty% \pgfpathmoveto{\tikz@lib@dec@te@pathstart}% \pgfpathlineto{\pgfpointadd{\tikz@lib@dec@te@pathstart}% {\pgfpointpolar{\tikz@lib@dec@te@pathfromtextangle}{\tikz@lib@dec@te@textwidth}}}% \pgfgetpath\pgfdecoratedpath% \pgfsetpath\pgfutil@empty% \else% #5% \fi% \else% \tikz@lib@dec@te@pathfromtextfalse% #6% \fi% }% \pgfdeclaredecoration{text effects along path}{setup}{% \state{setup}[width=+0pt, next state=scan, persistent precomputation={% \tikz@lib@dec@te@state@setup@precomputation% \def\tikz@lib@dec@te@charactercount{0}% }]{}% % \state{scan}[width=+0pt, next state=pre token, persistent precomputation={% \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@charactercount{1}% % Usual switch to final state is based on distance. % Here we also need it to be on the number of the % current character. \ifnum\tikz@lib@dec@te@charactercount>\tikz@lib@dec@te@charactertotalcount\relax% \ifnum\tikz@lib@dec@te@repeattext=0\relax% \def\pgf@decorate@next@state{final}% \else% \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@repeattext{-1}% \def\tikz@lib@dec@te@charactercount{1}% \fi% \fi% % Install parameters for this character. \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname% }]{}% % \state{pre token}[width=+\tikz@lib@dec@te@characterprewidth, next state=token]{}% \state{token}[width=+0pt, next state=post token] {% \tikz@lib@dec@te@drawcharacter% }% \state{post token}[width=+\tikz@lib@dec@te@characterpostwidth, next state=scan]{}% }% % Parse styles for individual characters % #1 a string of characters (e.g., aieou{\"U}{\"a"}) % #2 the options for to apply to each character. % \def\tikz@lib@dec@te@parse@stylecharacters#1#2{% \def\tikz@lib@dec@te@text{#1}% \tikz@lib@dec@te@scancharacters{% \pgfkeysalso{/pgf/decoration/text effects/character {\meaning\tikz@lib@dec@te@character}/.style={#2}}% }% }% % Parse replacement code for for individual characters % #1 a string of characters (e.g., aieou{\"U}{\"a"}) % #2 the code to execute to each character. % \def\tikz@lib@dec@te@parse@replacecharacters#1#2{% \def\tikz@lib@dec@te@text{#1}% \tikz@lib@dec@te@scancharacters{% \expandafter\def\csname tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code\endcsname{#2}% }% }% \endinput