1. rcurveto

Adds a Bézier cubic curve segment to the current path using relative coordinates.

1.1. Syntax

dx1 dy1 dx2 dy2 dx3 dy3 rcurveto → -

1.2. Stack Effects

Table 1. Before
Level Object

5

dy3 (number - endpoint y displacement)

4

dx3 (number - endpoint x displacement)

3

dy2 (number - second control point y displacement)

2

dx2 (number - second control point x displacement)

1

dy1 (number - first control point y displacement)

0

dx1 (number - first control point x displacement)

Table 2. After
Level Object

(empty)

Stack cleared of operands

1.3. Description

rcurveto (relative curveto) adds a Bézier cubic section to the current path in the same manner as curveto. However, the three number pairs are interpreted as displacements relative to the current point (x0, y0) rather than as absolute coordinates.

That is, rcurveto constructs a curve from (x0, y0) to (x0+dx3, y0+dy3), using (x0+dx1, y0+dy1) and (x0+dx2, y0+dy2) as Bézier control points.

If the current point is undefined because the current path is empty, rcurveto executes the [nocurrentpoint] error.

1.4. PostScript Level

Level 1 and later

1.5. Examples

Simple relative curve
newpath
100 100 moveto
50 100 150 100 200 0 rcurveto    % Curve relative to (100,100)
stroke
Creating a smooth wavy line
newpath
50 150 moveto
5 {
  40 -50 80 -50 120 0 rcurveto   % Wave up
  40 50 80 50 120 0 rcurveto     % Wave down
} repeat
stroke
Drawing connected S-curves
newpath
100 200 moveto
3 {
  30 -60 60 -60 90 0 rcurveto    % S-curve
} repeat
stroke

1.6. Common Use Cases

1.6.1. Creating Repeating Patterns

/drawWave {
  % amplitude wavelength count
  /n exch def
  /wl exch def
  /amp exch def

  n {
    wl 4 div amp
    wl 2 div 0
    wl 4 mul 3 div amp neg
    wl 0
    rcurveto
  } repeat
} def

newpath
50 150 moveto
30 100 5 drawWave
stroke

1.6.2. Building Complex Curves Incrementally

/spiralSegment {
  % Draws one segment of a spiral
  /angle exch def
  /radius exch def

  radius 3 div 0
  radius 2 mul 3 div radius 3 div
  radius radius 3 div
  rcurveto
} def

newpath
200 200 moveto
12 {
  20 30 spiralSegment
  30 rotate
} repeat
stroke

1.6.3. Creating Smooth Font-Like Shapes

/drawScript_e {
  % Draws a script 'e' using relative curves
  newpath
  0 20 moveto

  15 0 25 10 25 25 rcurveto       % Right curve
  0 10 -5 15 -15 15 rcurveto      % Top
  -15 0 -25 -10 -25 -25 rcurveto  % Left curve
  0 -5 2 -8 8 -8 rcurveto         % Bottom loop
  closepath
} def

100 100 translate
drawScript_e
fill

1.7. Common Pitfalls

Requires Current Point - rcurveto needs a current point. Use moveto first.
newpath
50 50 100 50 150 0 rcurveto      % Error: nocurrentpoint
All Coordinates Are Relative - Unlike curveto, all six parameters are displacements from the current point, not absolute positions.
100 100 moveto
50 50 100 100 150 150 rcurveto   % NOT absolute coordinates!
% Actually draws to (250, 250), not (150, 150)
Ideal for Patterns - rcurveto excels at creating repeating curved patterns where each curve relates to the previous position.

1.8. Error Conditions

Error Condition

[limitcheck]

Path becomes too complex for implementation

[nocurrentpoint]

Current path is empty (no current point defined)

[stackunderflow]

Fewer than 6 operands on stack

[typecheck]

Any operand is not a number

[undefinedresult]

Numeric overflow in coordinate calculation

1.9. Implementation Notes

  • All displacements are in user space

  • Control points are calculated relative to current point before CTM transformation

  • Negative displacements move in opposite directions

  • More convenient for iterative curve construction

  • Each curve segment’s endpoint becomes the reference for the next

1.10. Performance Considerations

  • No performance difference from curveto

  • Reduces coordinate calculation in code

  • More maintainable for relative patterns

  • Can accumulate rounding errors in long sequences

1.11. See Also


Back to top

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