- 1. ustroke
- 1.1. Syntax
- 1.2. Stack Effects
- 1.3. Description
- 1.4. PostScript Level
- 1.5. Examples
- 1.6. Common Use Cases
- 1.7. Common Pitfalls
- 1.8. Error Conditions
- 1.9. Implementation Notes
- 1.10. Graphics State Interaction
- 1.11. Comparison with Traditional Stroke
- 1.12. Best Practices
- 1.13. Performance Considerations
- 1.14. See Also
1. ustroke
Interprets a user path definition and strokes the resulting path.
1.2. Stack Effects
| Level | Object |
|---|---|
0 |
|
| Level | Object |
|---|---|
1 |
|
0 |
|
| Level | Object |
|---|---|
(empty) |
No results |
1.3. Description
ustroke interprets a user path definition and strokes the resulting path as if by stroke. The entire operation is effectively enclosed by gsave and grestore, so ustroke has no lasting effect on the graphics state.
In the first form (with no matrix operand), ustroke is equivalent to:
gsave newpath uappend stroke grestore
In the second form, ustroke concatenates matrix to the CTM after interpreting userpath, but before executing stroke. The matrix applies to the line width and the dash pattern, if any, but not to the path itself. This form is equivalent to:
gsave
newpath
exch uappend % Interpret userpath
concat % Concat matrix to CTM
stroke
grestore
The main use of the second form is to compensate for variations in line width and dash pattern that occur if the CTM has been scaled by different amounts in x and y.
1.5. Examples
[
50 50 250 250 setbbox
100 100 moveto
200 100 lineto
200 200 lineto
100 200 lineto
closepath
] ustroke
5 setlinewidth
1 setlinecap
1 setlinejoin
[
ucache
50 50 250 250 setbbox
100 150 moveto
200 150 lineto
] ustroke
% Scale coordinate system
2 1 scale % x scaled by 2
% Compensate in stroke
[
0 0 100 100 setbbox
10 50 moveto
90 50 lineto
]
[0.5 0 0 1 0 0] % Inverse of x scaling
ustroke % Line appears uniform width
1.6. Common Use Cases
1.6.1. Efficient Repeated Strokes
/linePath [
ucache
0 0 200 10 setbbox
10 5 moveto
190 5 lineto
] def
% Draw multiple strokes efficiently
2 setlinewidth
0 1 9 {
linePath ustroke
0 20 translate
} for
1.6.2. Dashed User Path Stroke
[5 3] 0 setdash
3 setlinewidth
[
ucache
50 50 250 250 setbbox
100 100 moveto
200 100 lineto
200 200 lineto
100 200 lineto
closepath
] ustroke
[] 0 setdash % Reset
1.6.3. Compensating for Scaled CTM
% Non-uniform scale
3 1 scale
/boxPath [
0 0 100 100 setbbox
10 10 moveto
90 10 lineto
90 90 lineto
10 90 lineto
closepath
] def
2 setlinewidth
% Without compensation - line appears 3x wider horizontally
boxPath ustroke
% With compensation - uniform line width
boxPath
[0.333 0 0 1 0 0] % Inverse of x scale
ustroke
1.7. Common Pitfalls
Graphics State Not Modified - ustroke automatically saves and restores graphics state.
|
2 setlinewidth
[
0 0 100 100 setbbox
10 10 moveto
90 90 lineto
] ustroke
% Line width still 2, path is empty
| Matrix Affects Line Width, Not Path - The optional matrix parameter affects stroke rendering, not path coordinates. |
% Wrong interpretation
[
0 0 100 100 setbbox
50 50 moveto
100 50 lineto
]
[2 0 0 2 0 0] % This does NOT scale the path
ustroke % Path position unchanged, only line rendering affected
Must Include setbbox - User paths require setbbox.
|
% Wrong - no setbbox
[
100 100 moveto
200 200 lineto
] ustroke % Error: rangecheck
% Correct
[
50 50 250 250 setbbox
100 100 moveto
200 200 lineto
] ustroke
| Use Matrix for Uniform Strokes Under Scaling - When CTM has non-uniform scaling, use matrix to maintain consistent line appearance: |
/uniformStroke {
% userpath sx sy uniformStroke
/sy exch def
/sx exch def
[1 sx div 0 0 1 sy div 0 0]
ustroke
} def
2 1 scale % Non-uniform scale
/myPath [
0 0 100 100 setbbox
50 50 moveto
90 50 lineto
] def
myPath 2 1 uniformStroke % Compensates for scale
1.8. Error Conditions
| Error | Condition |
|---|---|
[ |
User path array is not executable or has insufficient access |
[ |
Path becomes too complex for implementation |
[ |
User path is malformed (missing setbbox, coordinates out of bounds, invalid matrix) |
[ |
Insufficient operands on stack |
[ |
Operand is not a valid user path or matrix |
1.9. Implementation Notes
-
User paths provide efficient stroke rendering
-
Cached user paths (with
ucache) improve performance for reuse -
The bounding box enables rendering optimization
-
Matrix parameter allows compensation for CTM scaling
-
Very complex paths may exceed implementation limits
1.10. Graphics State Interaction
ustroke uses these graphics state parameters:
-
Line width - from
setlinewidth -
Line cap - from
setlinecap -
Line join - from
setlinejoin -
Miter limit - from
setmiterlimit -
Dash pattern - from
setdash -
Current color
-
Current clipping path
-
Current transformation matrix (CTM)
The graphics state is automatically saved before and restored after the operation.
1.11. Comparison with Traditional Stroke
gsave
newpath
100 100 moveto
200 100 lineto
200 200 lineto
closepath
2 setlinewidth
stroke
grestore
ustroke)2 setlinewidth
[
50 50 250 250 setbbox
100 100 moveto
200 100 lineto
200 200 lineto
closepath
] ustroke
Benefits of user paths:
-
More compact representation
-
Can be cached for efficiency
-
Automatic graphics state management
-
Optional matrix for stroke compensation
1.12. Best Practices
1.12.1. Set Line Parameters Before ustroke
% Set all stroke parameters first
3 setlinewidth
1 setlinecap
1 setlinejoin
[5 3] 0 setdash
% Then stroke user path
[
0 0 100 100 setbbox
10 50 moveto
90 50 lineto
] ustroke
1.12.2. Use ucache for Repeated Paths
/borderPath [
ucache % Cache for reuse
0 0 120 80 setbbox
5 5 moveto
115 5 lineto
115 75 lineto
5 75 lineto
closepath
] def
% Efficient reuse
2 setlinewidth
10 {
borderPath ustroke
0 90 translate
} repeat
1.12.3. Compensate for Non-Uniform Scaling
% When CTM has non-uniform scale
currentmatrix % Save original CTM
2 1 scale % Non-uniform scale
/path [
0 0 100 50 setbbox
50 25 moveto
90 25 lineto
] def
% Calculate inverse scale matrix
[0.5 0 0 1 0 0] % Inverse of 2,1 scale
path exch ustroke % Uniform line width
setmatrix % Restore CTM
1.13. Performance Considerations
-
User paths are generally faster than traditional path construction
-
Cached user paths (
ucache) provide significant performance improvement -
Matrix parameter adds minimal overhead
-
Dashed lines are slower than solid lines
-
Wide lines are slower than thin lines
-
Complex paths with many segments take longer
1.14. See Also
-
stroke- Traditional stroke operator -
ufill- Fill user path -
ustrokepath- Convert user path stroke to outline -
strokepath- Convert stroke to outline path -
setbbox- Set bounding box -
ucache- Enable user path caching -
uappend- Append user path to current path -
setlinewidth- Set line width -
setlinecap- Set line cap -
setlinejoin- Set line join -
setdash- Set dash pattern -
gsave- Save graphics state -
grestore- Restore graphics state