1. widthshow

Show text with selective character width adjustment.

1.1. Syntax

cx cy char string widthshow → -

1.2. Stack Effects

Before:

cx cy char string

After:

(empty)

1.3. Description

widthshow paints the characters of string in a manner similar to show. But while doing so, widthshow adjusts the width of each occurrence of the character char by adding cx to its x width and cy to its y width, thus modifying the spacing between it and the next character.

The char parameter is an integer used as a character code. This operator enables fitting a string of text to a specific width by adjusting the width of all occurrences of some specific character, such as the space character.

1.4. Parameters

cx (number) : Amount to add to x width of target character

cy (number) : Amount to add to y width of target character

char (integer) : Character code to adjust (typically space = 32 or 8#040)

string (string) : The text to display

1.5. Character Code Interpretation

For base fonts: : char is simply an integer in the range 0-255 compared to successive elements of string

For composite fonts: : char is compared to an integer computed from the font mapping algorithm. The font number f and character code c selected by the algorithm are combined: - For FMapType 4 and 5: (f × 128) + c - For other FMapType values: (f × 256) + c

1.6. Examples

1.6.1. Adjusting Space Character Width

/Helvetica findfont 12 scalefont setfont

14 60 moveto (Normal spacing) show
14 46 moveto 6 0 32 (Wide word spacing) widthshow
% 32 is ASCII code for space

1.6.2. Using Octal Character Code

/Helvetica findfont 12 scalefont setfont

100 700 moveto
6 0 8#040 (Wide word spacing) widthshow
% 8#040 is octal for space (32 decimal)

1.6.3. Justified Text with Space Adjustment

/justifyWithSpaces {  % string targetWidth justifyWithSpaces -
  % Count spaces in string
  0 exch
  { dup 32 eq { pop 1 add } { pop } ifelse } forall
  % Stack: targetWidth spaceCount

  dup 0 eq {
    % No spaces, just show
    pop pop show
  } {
    % Calculate space adjustment
    3 -1 roll              % spaceCount targetWidth string
    1 index stringwidth pop % Get current width
    sub exch div           % (targetWidth - currentWidth) / spaceCount
    0 exch 32              % cx=adjustment, cy=0, char=32
    4 -1 roll widthshow    % Apply
  } ifelse
} def

100 700 moveto
(This text will be justified) 400 justifyWithSpaces

1.6.4. Adjusting Multiple Character Types

% Adjust spaces first
100 100 moveto
3 0 32 (Text with wide spaces) widthshow

% For multiple character adjustments, cascade:
currentpoint moveto
2 0 65 (Adjust A character) widthshow  % Adjust 'A'

1.7. Errors

invalidaccess : Font or string has restricted access

invalidfont : Current font is not valid

nocurrentpoint : Current point is not defined

stackunderflow : Fewer than four operands on stack

typecheck : cx/cy not numbers, char not integer, or string not string

rangecheck : Character mapping goes out of bounds

1.8. Width Adjustment Formula

For each character c in the string:

if c == char:
  effectiveWidth(c) = characterWidth(c) + (cx, cy)
else:
  effectiveWidth(c) = characterWidth(c)

1.9. Common Character Codes

Character Decimal Octal

Space

32

8#040

Tab

9

8#011

Newline

10

8#012

Hyphen

45

8#055

Period

46

8#056

1.10. Use Cases

1.10.1. Word Spacing for Justification

/adjustSpaces {  % adjustment string adjustSpaces -
  0 exch 32 4 -1 roll widthshow
} def

100 700 moveto
5 (Widely spaced words) adjustSpaces

1.10.2. Em-Dash Adjustment

% Reduce space around em-dash (character 208 in some encodings)
/Helvetica findfont 12 scalefont setfont
100 100 moveto
-2 0 208 (Text—with—em-dashes) widthshow

1.10.3. Compensating for Printer Resolution

% Fine-tune spacing for specific output device
/deviceAdjust {
  % Get device resolution
  matrix defaultmatrix dtransform
  dup mul exch dup mul add sqrt  % Calculate DPI

  300 div  % Normalize to 300 DPI
  0 exch 32 4 -1 roll widthshow
} def

(Device-adjusted text) deviceAdjust

1.11. Advanced Techniques

1.11.1. Conditional Spacing

/conditionalSpacing {  % string conditionalSpacing -
  % Only adjust if string contains target character
  dup 32 search {
    % Contains space
    pop pop pop
    3 0 32 4 -1 roll widthshow
  } {
    % No spaces, use normal show
    show
  } ifelse
} def

1.11.2. Tracking (Typography)

% Letter spacing control for display type
/looseTracking {  % string looseTracking -
  % Add space to every character (including spaces)
  % This requires combining techniques
  dup stringwidth pop  % Original width
  1 index length 1 add 10 mul add  % Add 10 units per char
  2 div                % Center
  neg 0 rmoveto        % Adjust position
  1.5 0 32 4 -1 roll widthshow  % Wider spaces
} def

1.12. Performance Considerations

  • Slightly slower than show due to conditional width adjustment

  • Still benefits from font caching

  • More efficient than kshow for simple spacing needs

  • Character matching is done by simple integer comparison (fast)

1.13. Comparison with Other Spacing Operators

Operator Spacing Adjustment

show

None (uses character widths as-is)

ashow

Uniform adjustment to all characters

widthshow

Adjustment to specific character only

awidthshow

Both uniform and character-specific

kshow

Procedural control between each pair

1.14. See Also

  • show - Basic text painting

  • ashow - Show with uniform character spacing

  • awidthshow - Combine ashow and widthshow

  • kshow - Show with kerning procedure

  • cshow - Show with procedure per character

  • stringwidth - Calculate text width


Back to top

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