File: PSL_text.ps

package info (click to toggle)
gmt 5.4.5%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 149,844 kB
  • sloc: ansic: 202,639; sh: 7,742; xml: 149; makefile: 73; fortran: 49; lisp: 41; csh: 5
file content (241 lines) | stat: -rw-r--r-- 8,081 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
%-	$Id$
%-----------------------------------------------------------------------------
%-	P. Wessel, version 1
%-	Text justification for paragraphs.
%-	Kept as separate file until stable.
%-	Knows about flush l,c,r and justified.
%-	Knows about all GMT @ escapes, composites,
%-	and underlining. No hyphenation.  1 page only.
%-----------------------------------------------------------------------------

/PSL_setfont {	% Set Font, size, and color if needed
  /f exch def % Gets word flag from stack
  /k1 exch def % Gets word index from stack
  /fz PSL_size k1 get def	% Get font size
  /fn PSL_fnt k1 get def	% Get font
  fn PSL_lastfn eq fz PSL_lastfz eq and not {
    fz PSL_fontname fn get Y	% Set font and size
    /PSL_lastfn fn def
    /PSL_lastfz fz def
  } if
  /fc PSL_color k1 get def
  fc PSL_lastfc ne {
    /PSL_c fc 3 mul def
    0 1 2 {PSL_c add PSL_rgb exch get} for C	% Get and set color
    /PSL_lastfc fc def
  } if
  f 32 and 32 eq { % Underline
    /PSL_UL fz 0.075 mul def
    fz 0.025 mul W
    /PSL_show {PSL_ushow} def
  }
  {
    /PSL_show {ashow} def
  } ifelse
}!

/PSL_setfont2 {	% Only set font and size
  /f exch def % Gets word flag from stack
  /k1 exch def % Gets word index from stack
  /fz PSL_size k1 get def	% Get font size
  /fn PSL_fnt k1 get def	% Get font
  fn PSL_lastfn eq fz PSL_lastfz eq and not {
    fz PSL_fontname fn get Y	% Set font and size
    /PSL_lastfn fn def
    /PSL_lastfz fz def
  } if
}!

/PSL_wordheight {	% Gets word from stack, and calculates any adjustment to box height
  0 0 M false charpath flattenpath pathbbox /up exch def pop /down exch def pop newpath
  down PSL_ymin lt {/PSL_ymin down def} if
  up PSL_ymax gt {/PSL_ymax up def} if
}!

/PSL_ushow {
  currentpoint /y0 exch def /x0 exch def
  ashow
  currentpoint pop /x1 exch def
  x0 y0 PSL_UL sub M x1 y0 PSL_UL sub L S
  x1 y0 M
}!

% Set font, size, and color.  Adjust baseline if needed. Place space and word

/PSL_placeword {
  /k exch def % Gets word index from stack
  /flag PSL_flag k get def
  k flag PSL_setfont
  /sshow {ashow} def
  PSL_col 0 eq {		% First word on a line
    /PSL_t 0 def			% 0 spaces before this word
    flag 4 and 4 eq {	% Must skip one TAB
      pr_char 0 (    ) ashow
    } if
  }
  {				% Need to find spaces before this word
    /f PSL_flag k 1 sub get def	% f is flag for previous word
    /PSL_t f 3 and def		% PSL_t is index into PSL_spaces and PSL_spacewidths for previous word
    f 32 and 32 eq flag 32 and 32 eq and {/sshow {PSL_ushow} def} if
  } ifelse
  /thisword_bshift PSL_bshift k get def	% The baseline shift
  thisword_bshift 0.0 ne {0 thisword_bshift G} if	% Shift baseline
  flag 8 and 8 eq {	% First composite char
    pr_char 0 PSL_spaces PSL_t get sshow
    k PSL_composite
  } if
  flag 24 and 0 eq {	% Anything but composite chars
    pr_char 0 PSL_spaces PSL_t get sshow pr_char 0 PSL_word k get PSL_show
    PSL_width k get 0 gt {/PSL_col PSL_col 1 add def} if
  } if
  thisword_bshift 0.0 ne {0 thisword_bshift neg G} if	% Shift baseline
}!

/PSL_composite {	% Place a composite character
  /k1 exch def % Get word index from stack
  /k2 k1 1 add def
  /char1 PSL_word k1 get def
  /char2 PSL_word k2 get def
  /w1 char1 stringwidth pop def
  /w2 char2 stringwidth pop def
  /delta w1 w2 sub 2 div PSL_scale mul def
  delta 0.0 gt {
    /dx1 0 def
    /dx2 delta def
  }
  { /dx1 delta neg def
    /dx2 0 def
  } ifelse
  dx1 0 G currentpoint
  pr_char 0 char1 PSL_show M
  delta 0 G
  pr_char 0 char2 ashow
  dx2 0 G
}!

% Determine how much to expand text and also justify left/center/right

/PSL_expand {
  /k1 exch def % Get word index from stack
  /extra PSL_parwidth previous_linewidth sub comp_width add def
  PSL_CRLF k1 PSL_n1 eq or {/spread 0 def} {/spread extra def} ifelse
  /PSL_scale previous_linewidth 0.0 gt {PSL_parwidth previous_linewidth div} {1.0} ifelse def
  /ndiv lsum ncomp sub def
  ndiv 0 eq {/ndiv 1 def} if
  PSL_parjust 4 eq {/pr_char spread ndiv div def} {/pr_char 0 def} ifelse
  PSL_parjust 2 eq {extra 2 div 0 G} if
  PSL_parjust 3 eq {extra 0 G} if
  /PSL_col 0 def
}!

% Calculate text paragraph height:

/PSL_textjustifier {
  /PSL_mode exch def	% From stack. 0 -> calculate height, no text is placed, 1 -> place text
  /PSL_col 0 def
  /PSL_ybase 0 def
  /PSL_parheight 0 def
  /PSL_ymin 0 def
  /PSL_ymax 0 def
  /PSL_top 0 def
  /PSL_bottom 0 def
  /last_font PSL_fnt 0 get def		% The previous font number
  /last_size PSL_size 0 get def		% The previous font size
  /last_color PSL_color 0 get def	% The previous color index
  /previous_linewidth 0 def
  /stop 0 def
  /start 0 def
  /lsum 0 def
  /line 0 def
  /ncomp 0 def
  /comp_width 0 def
  0 1 PSL_n1 {		% Loop over all the words
    /i exch def		% The current loop index
    /thisflag PSL_flag i get def					% # of space chars to follow this word
    i 0 eq {
      /PSL_t 0 def
      /lastflag 0 def
    }
    { /lastflag PSL_flag i 1 sub get def
      /PSL_t lastflag 3 and def
    } ifelse
    % PSL_t is index into PSL_spaces and PSL_spacewidths
    i thisflag PSL_setfont2							% Get and set font and size
    /thisword_width PSL_width i get def
    /comp_add 0 def
    /compw_add 0 def
    /PSL_tabwidth (    ) stringwidth pop def					% Get width of the TAB
    /PSL_spacewidths PSL_spaces {stringwidth pop} forall 3 array astore def	% and the spaces
    /ccount PSL_count i get def								% # of characters in this word
    thisflag 4 and 4 eq {	% Had leading tab
      /thisword_width thisword_width PSL_tabwidth add def
      /ccount ccount 4 add def
    } if
    lastflag 8 and 8 eq {/PSL_t 0 def /comp_add 1 def /compw_add thisword_width def} if
    /new_linewidth previous_linewidth thisword_width add PSL_spacewidths PSL_t get add def	% Width of line if word added
    /PSL_CRLF thisword_width 0.0 eq thisflag 16 and 0 eq and def
    /special thisflag 16 and 16 eq {true} {thisword_width 0.0 gt} ifelse def
    new_linewidth PSL_parwidth le special and
    { % Word will fit on current line
      PSL_col 0 eq {
        /PSL_ymin 0 def
        /PSL_ymax 0 def
      } if
      /stop stop 1 add def			% Include this word
      /PSL_col PSL_col 1 add def		% Column place of next word
      /previous_linewidth new_linewidth def	% Update the unadjusted line width
      /lsum lsum ccount add PSL_t add def	% Update character count
      /ncomp ncomp comp_add add def
      /comp_width comp_width compw_add add def
    }
    { % Must process current line and move to next
      1 PSL_mode eq {		% Write out the first word on this line
	% Determine how much to expand text and also justify left/center/right
        start PSL_expand
	start PSL_placeword
      }
      {PSL_word start get PSL_wordheight
      } ifelse
      /last stop 1 sub def
      /start start 1 add def
      1 PSL_mode eq {		% Write out the remaining words on this line
        start 1 last {PSL_placeword} for
      }
      {start 1 last {PSL_word exch get PSL_wordheight} for
        line 0 eq { /PSL_top PSL_ymax def} if	% First outputline
      } ifelse

      /start stop def
      /PSL_ybase PSL_ybase PSL_linespace sub def
      1 PSL_mode eq {0 PSL_ybase M} if	% CR/LF
      /stop stop 1 add def				% Include this word
      /previous_linewidth thisword_width def
      /lsum ccount def
      /ncomp comp_add def
      /comp_width compw_add def
      /PSL_col 0 def
      /line line 1 add def
    } ifelse
  } for
  /last stop 1 sub def
  last PSL_n lt {	% One or more words left hanging on last line
    /PSL_CRLF true def
    1 PSL_mode eq {
      % Determine how much to expand text and also justify left/center/right
      start PSL_expand
      start PSL_placeword
      /start start 1 add def
      start 1 last {PSL_placeword} for
    }
    { /PSL_ymin 0 def
      PSL_word start get PSL_wordheight
      /start start 1 add def
      start 1 last {PSL_word exch get PSL_wordheight} for
      line 0 eq {	% First outputline
        /PSL_top PSL_ymax def
      } if
    } ifelse
  } if
  /PSL_bottom PSL_ymin def
  /PSL_parheight PSL_ybase neg PSL_top add PSL_bottom sub def
} def % PSL_textjustifier