summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/metapost/textpath/textpath.mp
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/metapost/textpath/textpath.mp')
-rw-r--r--Master/texmf-dist/metapost/textpath/textpath.mp472
1 files changed, 278 insertions, 194 deletions
diff --git a/Master/texmf-dist/metapost/textpath/textpath.mp b/Master/texmf-dist/metapost/textpath/textpath.mp
index 03df35cd8f0..2da8387927e 100644
--- a/Master/texmf-dist/metapost/textpath/textpath.mp
+++ b/Master/texmf-dist/metapost/textpath/textpath.mp
@@ -1,3 +1,18 @@
+%%% textpath.mp
+%%% Copyright 2007 Stephan Hennig <stephanhennig@arcor.de>
+%
+% This work may be distributed and/or modified under the conditions of
+% the LaTeX Project Public License, either version 1.3 of this license
+% or (at your option) any later version. The latest version of this
+% license is in http://www.latex-project.org/lppl.txt
+%
+
+if known textpath_fileversion: endinput fi;
+string textpath_fileversion;
+textpath_fileversion := "v1.6 (2007/02/11)";
+message "Loading textpath " & textpath_fileversion;
+
+
%%% Global variables.
%%% Global variable.
@@ -9,7 +24,7 @@
%%% should be omitted. Variable textpathClip can be either one (omit)
%%% or zero (don't omit).
newinternal textpathClip;
-textpathClip := 1;
+textpathClip := 0;
%%% Global variable.
%%% Variable textpathLetterSpace determines the amount of space that
@@ -52,11 +67,17 @@ textpathStrokePrecision := 10;
newinternal textpathCureSqrt;
textpathCureSqrt := 1;
+newinternal textpathAutoScale;
+textpathAutoScale := 0;
+
+newinternal textpathDraft;
+textpathDraft := 0;
+
newinternal textpathDebug;
-textpathDebug := 0;
+textpathDebug := 1;
pair textpathHookCoord, textpathHookPoint;
-newinternal textpathHookRoot;
+newinternal textpathHookRot;
textpathHookCoord := origin;
textpathHookPoint := origin;
textpathHookRot := 0;
@@ -104,7 +125,7 @@ save pre, post;
string pre, post;
pre := f & "\spaced{";
post := "}";
- textpathPic(strToPic(pre & t & post), p, j, "")
+ textpathToPic(strToPic(pre & t & post), p, j)
enddef;
@@ -123,17 +144,11 @@ enddef;
%%% Return value:
%%% * a picture variable containing text following a path.
vardef textpathRaw(expr t, p, j)=
-save temp, pic, pre, post;
-numeric temp;
-picture pic;
+save pre, post;
string pre, post;
pre := "\rule[-30bp]{0pt}{30bp}";
post := "";
- temp := textpathSoulLetterSpace;
- textpathSoulLetterSpace := 0bp;
- pic := textpathPicRaw(strToPic(pre & t & post), p, j, "");
- textpathSoulLetterSpace := temp;
- pic
+ textpathRawToPic(strToPic(pre & t & post), p, j)
enddef;
@@ -147,82 +162,258 @@ enddef;
%%% Return value:
%%% * a picture variable.
vardef strToPic(expr s)=
-save loffset, pic;
-numeric loffset;
-picture pic;
- loffset := labeloffset;
- labeloffset := 0bp;
- pic := thelabel.urt(textext(s), origin);
- labeloffset := loffset;
- pic
+interim labeloffset := 0bp;
+ thelabel.urt(textext(s), origin)
enddef;
-%%% Internal working macro.
-%%% Set text from picture variable along a path with justification j.
-%%% Parameters:
-%%% * a picture that contains the text that has to be transformed onto a path,
-%%% * a path p the text should follow,
-%%% * a numeric variable that controls justification,
-%%% * a string: "debug" indicates debug mode.
-%%% Return value:
-%%% * a picture variable containing text following a path.
-vardef textpathPic(expr textpic, p, j, debug)=
-save tb, db, pic, item, bitem, banker, k, i, lenp, lenpic, bx, cx, ltextpathHSpace;
-numeric tb, db, k, i, lenp, lenpic, ltextpathHSpace, bx, cx;
-picture pic, item, bitem;
-pair banker;
- pic := nullpicture;
- lenp := arclength(p);
+%%% Internal macro.
+%%% Computes the length of a textual picture, thereby correcting
+%%% for textpathSoulLetterSpace and textpathLetterSpace
+vardef getPictureWidth(expr textpic, scale)=
+save lenpic, k, w;
+numeric lenpic, k, w;
lenpic := 0;
k := 0;
for item within textpic:
if textual item:
- bitem := item shifted (-k*textpathSoulLetterSpace, 0bp) shifted (k*textpathLetterSpace, 0bp);
- x := xpart lrcorner bitem;
- if x > lenpic:
- lenpic := x;
+ w := xpart lrcorner ( item shifted (scale*k*(textpathLetterSpace-textpathSoulLetterSpace), 0bp) );
+ if w > lenpic:
+ lenpic := w;
fi
k := k + 1;
fi
endfor
- if textpathStretch=1:
+ lenpic
+enddef;
+
+
+%%% Internal macro.
+%%% Does pre-processing for macros textpath(Raw)ToPic, such as
+%%% calculating variables startOffset, autoScale, ltextpathHSpace etc.
+def preprocessTextPic(expr rawMode, atextpic, p, j)=
+ save textpic, pic, lenp, lenpic, startOffset, ltextpathHSpace, autoScale, overfullPath;
+ interim bboxmargin := 0bp;
+ numeric lenp, lenpic, startOffset, ltextpathHSpace, autoScale;
+ picture textpic, pic;
+ boolean overfullPath;
+
+ textpic := atextpic;
+ pic := nullpicture;
+%%% Compute path length.
+ lenp := arclength(p);
+%%% Compute picture length, i.e., correct plain picture dimensions
+%%% for soul and textpath letter spacing.
+ if rawMode:%%% Called from textpathRawToPic.
+ lenpic := xpart (lrcorner textpic - llcorner textpic);
+ else:%%% Called from textpathToPic.
+ lenpic := getPictureWidth(textpic, 1);%%% Get corrected picture with scale = 1.
+ fi
+%%% Compute inter-copy space (for textpathRepeat > 1).
+ if textpathStretch = 0:
+ ltextpathHSpace := textpathHSpace;
+ else:
ltextpathHSpace := lenp/textpathRepeat - lenpic;
+ fi
+%%% Compute startOffset as j * remaining space.
+ startOffset := j * (lenp - textpathRepeat*lenpic - (textpathRepeat-1)*ltextpathHSpace);
+%%% By default, assume path isn't overfull.
+ overfullPath := false;
+ autoScale := 1;
+%%% Overfull path?
+ if startOffset < 0:
+ overfullPath := true;
+ if textpathAutoScale <> 0:%%% Calculate scaling factor.
+ if textpathStretch <> 0:
+ ltextpathHSpace := 0;%%% No inter-copy space when stretching allowed.
+ fi
+ autoScale := lenp/(textpathRepeat*lenpic + (textpathRepeat-1)*ltextpathHSpace1);
+ startOffset := 0;
+ if textpathDraft = 0:
+ textpic := atextpic scaled autoScale;
+ else:
+ textpic := atextpic xscaled autoScale;%%% Don't scale y in draft mode.
+ fi
+ lenpic := getPictureWidth(textpic, autoScale);
+%%% Compute inter-copy space (for textpathRepeat > 1).
+ if textpathStretch = 0:
+ ltextpathHSpace := textpathHSpace*autoScale;
+ else:
+ ltextpathHSpace := lenp/textpathRepeat - lenpic;%%% Should be equal to zero.
+ fi
+%%% Finally, output a warning.
+ message "Package textpath warning: Overfull path! Scaled to " & decimal autoScale & ".";
+ else:%%% No scaling.
+ autoScale := 1;
+ if textpathClip = 0:%%% Warn the user about overfull paths.
+ message "Package textpath warning: Overfull path! Not clipped.";
+ else:
+ message "Package textpath warning: Overfull path! Clipped.";
+ fi
+ fi
+ fi
+enddef;
+
+
+
+%%% Internal macro.
+def transformSimpleItem(expr rawMode, item, p)=
+%%% bitem is a character or straight rule to transform.
+%%% banker is its original anchor position.
+ if rawMode:
+ bitem := item;
+ banker := (xpart center bitem, autoScale*30bp);%%% Why 30bp?
else:
- ltextpathHSpace := textpathHSpace;
+ bitem := item shifted (k*autoScale*(textpathLetterSpace-textpathSoulLetterSpace), 0bp);
+ banker := (xpart center bitem, ypart item);
fi
- k := 0;
- for item within textpic:
- if textual item:
- bitem := item shifted (-k*textpathSoulLetterSpace, 0bp) shifted (k*textpathLetterSpace, textpathShift);
- banker := (xpart center bitem, ypart item);
- if textpathStretch=1:
- bx := (xpart banker) + j*ltextpathHSpace;
+%%% bx is the anchor position of a first item copy.
+ bx := (xpart banker) + startOffset;
+%%% Shift anchor to origin and raise baseline.
+ bitem := bitem shifted -banker shifted (0bp, textpathShift);
+%%% Iterate over all copies of an item.
+ for i=1 upto textpathRepeat:
+%%% cx is the anchor position of an item copy.
+ cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
+%%% Draw items with valid positions or if no clipping.
+ if ((cx>=0) and (cx<=lenp)) or (textpathClip=0):
+%%% Compute path time value.
+ tb := arctime cx of p;
+%%% Compute rotation angle.
+ if textpathAbsRotation=0:
+ db := textpathRotation + angle direction tb of p;
else:
- bx := (xpart banker) + j*(lenp - textpathRepeat*lenpic - (textpathRepeat-1)*ltextpathHSpace);
+ db := textpathRotation;
fi
- bitem := bitem shifted -banker;
- for i:= 1 upto textpathRepeat:
- cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
- if (textpathClip=0) or ((cx>=0) and (cx<=lenp)):
- tb := arctime cx of p;
- if textpathAbsRotation=0:
- db := textpathRotation + angle direction tb of p;
- else:
- db := textpathRotation;
- fi
- if not (debug="debug"):
- addto pic also bitem rotated db shifted point tb of p;
- else:
- addto pic contour fullcircle scaled 2bp shifted point tb of p;
- fi
- fi
- endfor
+%%% Draw item's bounding box?
+ if odd (textpathDebug div 2):
+ addto pic doublepath bbox bitem rotated db shifted point tb of p withpen currentpen;
+ fi
+%%% Draw item?
+ if odd (textpathDebug div 1):
+%%% In draft mode fill bounding box if path is overfull.
+ if overfullPath and (textpathDraft<>0):
+ addto pic contour bbox bitem rotated db shifted point tb of p;
+ else:
+ addto pic also bitem rotated db shifted point tb of p;
+ fi
+ fi
+%%% Draw item's anchor point?
+ if odd (textpathDebug div 4):
+ addto pic contour fullcircle scaled 3bp shifted point tb of p;
+ fi
+ fi
+ endfor
+%%% Save top right corner of supported square root glyphs in variable textpathHookCoord.
+ if rawMode and (textpathCureSqrt <> 0):
+ if ((fontpart item="cmex10") and ((ASCII textpart item>=112) and (ASCII textpart item<=116))) or
+ ((fontpart item="cmsy5") and (ASCII textpart item=112)) or
+ ((fontpart item="cmsy6") and (ASCII textpart item=112)) or
+ ((fontpart item="cmsy7") and (ASCII textpart item=112)) or
+ ((fontpart item="cmsy8") and (ASCII textpart item=112)) or
+ ((fontpart item="cmsy9") and (ASCII textpart item=112)) or
+ ((fontpart item="cmsy10") and (ASCII textpart item=112)) or
+ ((fontpart item="cmbsy10") and (ASCII textpart item=112)) or
+ ((fontpart item="fourier-mex") and (ASCII textpart item=114)) or
+ ((fontpart item="fourier-ms") and (ASCII textpart item=112)) or
+ ((fontpart item="MnSymbolE5") and (ASCII textpart item=186)) or
+ ((fontpart item="MnSymbolE5") and (ASCII textpart item=189)) or
+ ((fontpart item="MnSymbolE10") and (ASCII textpart item=186)):%%% \sqrt glyph?
+ textpathHookCoord := urcorner item shifted (-xpart center item, -autoScale*30bp + textpathShift);
+ textpathHookRot := db;
+ textpathHookPoint := point tb of p;
+% addto pic contour fullcircle scaled 2bp shifted textpathHookCoord rotated db shifted point tb of p withcolor green;
+ else:
+ textpathHookCoord := origin;
+ fi
+ fi
+enddef;
+
+
+%%% Internal macro.
+def transformStrokedItem(expr rawMode, item, p)=
+ if textpathFancyStrokes = 0:
+ transformSimpleItem(true, item, p);
+ else:
+ pp := pathpart item;
+ for i=1 upto textpathRepeat:
+ if (textpathHookCoord=origin) or (textpathCureSqrt=0):
+ banker := (0, ypart point 0 of pp - autoScale*30bp + textpathShift);
+ bx := (xpart point 0 of pp) + startOffset;
+ dpp := angle direction 0 of pp;
+ cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
+ tb := arctime cx of p;
+ if textpathAbsRotation=0:
+ db := textpathRotation + angle direction tb of p;
+ else:
+ db := textpathRotation;
+ fi
+ np := banker rotated db shifted point tb of p%{dir (dpp+db)}
+ elseif textpathCureSqrt=1:
+ np := textpathHookCoord shifted (dir(-90)*xpart point 0 of makepath penpart item);
+ np := np rotated textpathHookRot shifted textpathHookPoint%{dir textpathHookRot}
+ fi
+ for h=1 upto textpathStrokePrecision:
+ hide(
+ banker := (0, ypart point (h/textpathStrokePrecision) of pp - autoScale*30bp + textpathShift);
+ bx := (xpart point (h/textpathStrokePrecision) of pp) + startOffset;
+ cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
+ dpp := angle direction (h/textpathStrokePrecision) of pp;
+ tb := arctime cx of p;
+ if textpathAbsRotation=0:
+ db := textpathRotation + angle direction tb of p;
+ else:
+ db := textpathRotation;
+ fi
+ )
+ ..banker rotated db shifted point tb of p%{dir (dpp+db)}
+ endfor;
+ if odd (textpathDebug div 2):
+ addto pic doublepath bbox np withpen currentpen;
+ fi
+ if odd (textpathDebug div 1):
+ addto pic doublepath np withpen penpart item;
+ fi
+ if odd (textpathDebug div 4):
+%%% Doesn't work.
+% addto pic contour fullcircle scaled 3bp shifted point tb of p;
+ fi
+ endfor
+ fi
+enddef;
+
+
+
+
+%%% Internal working macro.
+%%% Set text from picture variable along a path with justification j.
+%%% Parameters:
+%%% * a picture that contains the text that has to be transformed onto a path,
+%%% * a path p the text should follow,
+%%% * a numeric variable that controls justification,
+%%% Return value:
+%%% * a picture variable containing text following a path.
+vardef textpathToPic(expr atextpic, p, j)=
+ save bitem, banker, k, bx, cx, tb, db;
+ numeric k, bx, cx, tb, db;
+ picture bitem;
+ pair banker;
+
+ %%% Calculate variables such as startOffset, autoScale, ltextpathHSpace etc.
+ preprocessTextPic(false, atextpic, p, j);
+ %%%
+ %%% Now iterate over all picture elements.
+ %%%
+ k := 0;
+ for item within textpic:
+ if textual item:%%% Process textual elements.
+ transformSimpleItem(false, item, p);
k := k + 1;
else:
- show "Warning! Unsupported picture element found!";
+ message "Package textpath warning: Unsupported picture element found!";
fi
endfor
+ %%% Return pic.
pic
enddef;
@@ -234,136 +425,29 @@ enddef;
%%% * a picture that contains the text that has to be transformed onto a path,
%%% * a path p the text should follow,
%%% * a numeric variable that controls justification,
-%%% * a string: "debug" indicates debug mode.
%%% Return value:
%%% * a picture variable containing text following a path.
-vardef textpathPicRaw(expr textpic, p, j, debug)=
-save tb, db, pic, item, bitem, banker, i, lenp, lenpic, bx, cx, ltextpathHSpace, pp, np, dpp;
-numeric tb, db, dpp, i, h, lenp, lenpic, ltextpathHSpace, bx, cx;
-picture pic, item, bitem;
-pair banker;
-path pp, np;
- show textpic;
- pic := nullpicture;
- lenp := arclength(p);
- lenpic := xpart (lrcorner textpic - llcorner textpic);
- if textpathStretch=1:
- ltextpathHSpace := lenp/textpathRepeat - lenpic;
- else:
- ltextpathHSpace := textpathHSpace;
- fi
+vardef textpathRawToPic(expr atextpic, p, j)=
+ save bitem, banker, bx, cx, tb, db, pp, np, dpp;
+ numeric bx, cx, tb, db, dpp;
+ picture bitem;
+ pair banker;
+ path pp, np;
+
+ %%% Calculate variables such as startOffset, autoScale, ltextpathHSpace etc.
+ preprocessTextPic(true, atextpic, p, j);
+%%% Reset last sqrt glyph's top right bounding box corner.
+ textpathHookCoord := origin;
+ %%%
+ %%% Now iterate over all picture elements.
+ %%%
for item within textpic:
- if textual item:
-% show "t=" & textpart item & " ASCII=" & decimal ASCII textpart item & " font=" & fontpart item;
- bitem := item shifted (0, textpathShift);
- banker := (xpart center bitem, 30bp);
- if textpathStretch=1:
- bx := (xpart banker) + j*ltextpathHSpace;
- else:
- bx := (xpart banker) + j*(lenp - textpathRepeat*lenpic - (textpathRepeat-1)*ltextpathHSpace);
- fi
- bitem := bitem shifted -banker;
- for i:=1 upto textpathRepeat:
- cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
- if (textpathClip=0) or ((cx>=0) and (cx<=lenp)):
- tb := arctime cx of p;
- if textpathAbsRotation=0:
- db := textpathRotation + angle direction tb of p;
- else:
- db := textpathRotation;
- fi
- addto pic also bitem rotated db shifted point tb of p;
- fi
- endfor
- if ((fontpart item="cmex10") and ((ASCII textpart item>=112) and (ASCII textpart item<=116))) or
- ((fontpart item="cmsy5") and (ASCII textpart item=112)) or
- ((fontpart item="cmsy6") and (ASCII textpart item=112)) or
- ((fontpart item="cmsy7") and (ASCII textpart item=112)) or
- ((fontpart item="cmsy8") and (ASCII textpart item=112)) or
- ((fontpart item="cmsy9") and (ASCII textpart item=112)) or
- ((fontpart item="cmsy10") and (ASCII textpart item=112)) or
- ((fontpart item="cmbsy10") and (ASCII textpart item=112)) or
- ((fontpart item="fourier-mex") and (ASCII textpart item=114)) or
- ((fontpart item="fourier-ms") and (ASCII textpart item=112)) or
- ((fontpart item="MnSymbolE5") and (ASCII textpart item=186)) or
- ((fontpart item="MnSymbolE5") and (ASCII textpart item=189)) or
- ((fontpart item="MnSymbolE10") and (ASCII textpart item=186)):
- textpathHookCoord := urcorner item shifted (-xpart center item, -30bp + textpathShift);
- textpathHookRot := db;
- textpathHookPoint := point tb of p;
-% addto pic contour fullcircle scaled 2bp shifted textpathHookCoord rotated db shifted point tb of p withcolor green;
- else:
- textpathHookCoord := origin;
- fi
- elseif stroked item:
- if textpathFancyStrokes=0:
- bitem := item shifted (0, textpathShift);
- banker := (xpart center bitem, 30bp);
- if textpathStretch=1:
- bx := (xpart banker) + j*ltextpathHSpace;
- else:
- bx := (xpart banker) + j*(lenp - textpathRepeat*lenpic - (textpathRepeat-1)*ltextpathHSpace);
- fi
- bitem := bitem shifted -banker;
- for i:=1 upto textpathRepeat:
- cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
- if (textpathClip=0) or ((cx>=0) and (cx<=lenp)):
- tb := arctime cx of p;
- if textpathAbsRotation=0:
- db := textpathRotation + angle direction tb of p;
- else:
- db := textpathRotation;
- fi
- addto pic also bitem rotated db shifted point tb of p;
- fi
- endfor
- else:
- pp := pathpart item;
- for i=1 upto textpathRepeat:
- if (textpathHookCoord=origin) or (textpathCureSqrt=0):
- banker := (0, ypart point 0 of pp - 30bp + textpathShift);
- if textpathStretch=1:
- bx := (xpart point 0 of pp) + j*ltextpathHSpace;
- else:
- bx := (xpart point 0 of pp) + j*(lenp - textpathRepeat*lenpic - (textpathRepeat-1)*ltextpathHSpace);
- fi
- dpp := angle direction 0 of pp;
- cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
- tb := arctime cx of p;
- if textpathAbsRotation=0:
- db := textpathRotation + angle direction tb of p;
- else:
- db := textpathRotation;
- fi
- np := banker rotated db shifted point tb of p%{dir (dpp+db)}
- elseif textpathCureSqrt=1:
- np := textpathHookCoord shifted (dir(-90)*xpart point 0 of makepath penpart item);
- np := np rotated textpathHookRot shifted textpathHookPoint%{dir textpathHookRot}
- fi
- for h:=1 upto textpathStrokePrecision:
- hide(
- banker := (0, ypart point (h/textpathStrokePrecision) of pp - 30bp + textpathShift);
- if textpathStretch=1:
- bx := (xpart point (h/textpathStrokePrecision) of pp) + j*ltextpathHSpace;
- else:
- bx := (xpart point (h/textpathStrokePrecision) of pp) + j*(lenp - textpathRepeat*lenpic - (textpathRepeat-1)*ltextpathHSpace);
- fi
- cx := (i-1)*(lenpic + ltextpathHSpace) + bx;
- dpp := angle direction (h/textpathStrokePrecision) of pp;
- tb := arctime cx of p;
- if textpathAbsRotation=0:
- db := textpathRotation + angle direction tb of p;
- else:
- db := textpathRotation;
- fi
- )
- ..banker rotated db shifted point tb of p%{dir (dpp+db)}
- endfor;
- addto pic doublepath np withpen penpart item;
- endfor
- fi
+ if textual item:%%% Process textual elements.
+ transformSimpleItem(true, item, p);
+ elseif stroked item:%%% Process stroked elements.
+ transformStrokedItem(true, item, p);
else:
- show "Warning! Unsupported picture element found!";
+ message "Package textpath warning: Unsupported picture element found!";
fi
endfor
pic