From 76df758cd9cc786136accd3ba690e2f8986abb6b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 11 Feb 2007 22:54:17 +0000 Subject: textpath 1.6 for Stephan git-svn-id: svn://tug.org/texlive/trunk@3968 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/metapost/textpath/textpath.mp | 472 ++++++++++++++---------- 1 file changed, 278 insertions(+), 194 deletions(-) (limited to 'Master/texmf-dist/metapost/textpath') 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 +% +% 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 -- cgit v1.2.3