1. ustrokepath

Converts a user path stroke to an outline path.

1.1. Syntax

userpath ustrokepath → -
userpath matrix ustrokepath → -

1.2. Stack Effects

Table 1. First form (no matrix)
Level Object

0

userpath (array, packed array, or string)

Table 2. Second form (with matrix)
Level Object

1

matrix (array)

0

userpath (array, packed array, or string)

Table 3. After (both forms)
Level Object

(empty)

No results (current path is set to outline)

1.3. Description

ustrokepath replaces the current path with one enclosing the shape that would result if the ustroke operator were applied to the same operands. The path resulting from ustrokepath is suitable as the implicit operand to a subsequent fill, clip, or pathbbox.

In general, this path is not suitable for stroke, as it may contain interior segments or disconnected subpaths produced by ustrokepath's stroke-to-outline conversion process.

In the first form, ustrokepath is equivalent to:

newpath uappend strokepath

In the second form, ustrokepath is equivalent to:

newpath
exch uappend           % Interpret userpath
matrix currentmatrix   % Save CTM
exch concat            % Concat matrix to CTM
strokepath             % Compute outline of stroke
setmatrix              % Restore original CTM

The matrix parameter allows compensation for non-uniform scaling in the CTM, affecting line width and dash pattern but not the path coordinates.

1.4. PostScript Level

Level 2 and later

1.5. Examples

Converting user path stroke to outline
5 setlinewidth
[
  50 50 250 250 setbbox
  100 100 moveto
  200 100 lineto
  200 200 lineto
  100 200 lineto
  closepath
] ustrokepath

% Now current path is the stroke outline
fill
Creating offset paths
/createOffset {
  % userpath width createOffset
  setlinewidth
  ustrokepath
} def

[
  0 0 200 200 setbbox
  100 100 moveto
  100 150 lineto
  150 150 lineto
  closepath
] 5 createOffset

0.7 setgray
fill
Using matrix for uniform outline
2 1 scale  % Non-uniform scale

[
  0 0 100 100 setbbox
  50 50 moveto
  90 50 lineto
]
[0.5 0 0 1 0 0]  % Compensate for x scale
ustrokepath

fill  % Uniform thickness outline

1.6. Common Use Cases

1.6.1. Creating Outlined Text Effects

/outlineText {
  % string width outlineText
  /w exch def
  /s exch def

  /Helvetica-Bold findfont 72 scalefont setfont

  % Create text path as user path
  /textPath [
    newpath
    100 100 moveto
    s true charpath
    pathbbox
    setbbox
    100 100 moveto
    s true charpath
  ] cvx def

  w setlinewidth
  textPath ustrokepath

  fill
} def

(OUTLINE) 3 outlineText

1.6.2. Double Outline Effect

/doubleLine [
  ucache
  50 50 250 250 setbbox
  100 150 moveto
  200 150 lineto
] def

% Outer outline
10 setlinewidth
doubleLine ustrokepath
gsave
  0.9 setgray
  fill
grestore

% Inner outline
4 setlinewidth
doubleLine ustrokepath
0.3 setgray
fill

1.6.3. Advanced Clipping

% Use stroke outline as clip path
[
  50 50 250 250 setbbox
  150 150 75 0 360 arc
  closepath
]
10 setlinewidth
ustrokepath

clip
newpath

% Draw clipped content within stroke outline
% ...

1.7. Common Pitfalls

Result Not Suitable for Stroking - The outline path may contain interior segments and is meant for filling or clipping.
[
  0 0 100 100 setbbox
  50 50 moveto
  90 50 lineto
]
5 setlinewidth
ustrokepath

% Don't do this
stroke  % Unpredictable results

% Do this instead
fill    % Correct usage
Current Path Is Modified - Unlike ustroke, the current path is replaced with the outline.
[
  0 0 100 100 setbbox
  50 50 moveto
  90 50 lineto
]
ustrokepath
% Current path is now the stroke outline
% Original user path is gone
Matrix Affects Stroke, Not Path Coordinates - The optional matrix only affects stroke rendering parameters.
[
  0 0 100 100 setbbox
  50 50 moveto
  90 50 lineto
]
[2 0 0 2 0 0]  % Does NOT scale path coordinates
ustrokepath      % Only affects line width calculation
Use for Path Analysis - ustrokepath makes stroke boundaries explicit for analysis:
[
  0 0 100 100 setbbox
  50 50 moveto
  90 50 lineto
]
5 setlinewidth
ustrokepath

% Get bounds of stroked path
pathbbox  % Returns bbox of stroke outline

1.8. Error Conditions

Error Condition

[invalidaccess]

User path array is not executable or has insufficient access

[limitcheck]

Path becomes too complex for implementation

[rangecheck]

User path is malformed (missing setbbox, coordinates out of bounds, invalid matrix)

[stackunderflow]

Insufficient operands on stack

[typecheck]

Operand is not a valid user path or matrix

1.9. Implementation Notes

  • Creates outline paths for each path segment in the user path

  • Line caps create closed paths at endpoints

  • Line joins create appropriate corner fills

  • Dash patterns create separate outline segments

  • Very complex paths may exceed implementation limits

  • The resulting path can be quite complex

1.10. Graphics State Parameters

ustrokepath uses these parameters to create the outline:

The graphics state is not automatically saved/restored (unlike ustroke).

1.11. Comparison with Other Stroke Operators

strokepath
  • Operates on current path

  • Modifies current path in place

  • No automatic state management

  • Traditional path format

ustroke
  • Operates on user path

  • Automatic gsave/grestore

  • No lasting path changes

  • User path format

ustrokepath
  • Operates on user path

  • Sets current path to outline

  • No automatic state management

  • User path format

  • Optional matrix parameter

1.12. Best Practices

1.12.1. Set Line Parameters Before Calling

% Set all stroke parameters first
5 setlinewidth
1 setlinecap
1 setlinejoin
[5 3] 0 setdash

% Then create outline
[
  0 0 100 100 setbbox
  50 50 moveto
  90 50 lineto
] ustrokepath

% Fill or clip the outline
fill

1.12.2. Save State When Needed

gsave
  10 setlinewidth
  1 setlinecap

  [
    0 0 100 100 setbbox
    50 50 moveto
    90 50 lineto
  ] ustrokepath

  0.8 setgray
  fill
grestore

1.12.3. Use Matrix for CTM Compensation

% Save current matrix
matrix currentmatrix /origMatrix exch def

% Apply non-uniform scale
3 1 scale

% Create outline with compensation
/path [
  0 0 100 50 setbbox
  50 25 moveto
  90 25 lineto
] def

% Inverse of the scale
[0.333 0 0 1 0 0]
path exch ustrokepath

fill

% Restore original matrix
origMatrix setmatrix

1.12.4. Combine with Other Operations

/circlePath [
  ucache
  100 100 300 300 setbbox
  200 200 75 0 360 arc
  closepath
] def

% Create stroke outline
8 setlinewidth
circlePath ustrokepath

% Use for clipping
clip
newpath

% Draw clipped content
% ...

1.13. Advanced Techniques

1.13.1. Creating Variable Width Paths

% Simulate variable width
[
  0 0 100 50 setbbox
  10 25 moveto
  40 25 lineto
]
2 setlinewidth
ustrokepath

gsave fill grestore

[
  40 25 moveto
  70 25 lineto
]
6 setlinewidth
ustrokepath

gsave fill grestore

[
  70 25 moveto
  90 25 lineto
]
10 setlinewidth
ustrokepath

fill

1.13.2. Creating Parallel Offset Paths

/parallelPath {
  % userpath offset parallelPath → outlinepath
  2 mul setlinewidth
  ustrokepath
} def

[
  0 0 200 100 setbbox
  10 50 moveto
  190 50 lineto
]
5 parallelPath  % 5-unit offset on each side

% Result is outline suitable for fill
fill

1.14. Performance Considerations

  • More complex than simple ustroke

  • User path format provides some efficiency

  • Dash patterns significantly increase complexity

  • Round caps/joins create more segments

  • Very wide lines create larger outlines

  • Matrix parameter adds minimal overhead

1.15. See Also

  • ustroke - Stroke user path

  • strokepath - Convert stroke to outline (traditional path)

  • ufill - Fill user path

  • fill - Fill path interior

  • clip - Use path for clipping

  • setbbox - Set bounding box

  • ucache - Enable user path caching

  • uappend - Append user path to current path

  • pathbbox - Get path bounding box

  • setlinewidth - Set line width

  • setlinecap - Set line cap

  • setlinejoin - Set line join

  • setdash - Set dash pattern


Back to top

Copyright © 2025 Ribose. PostScript is a trademark of Adobe. Distributed under the MIT License.