| 1 |
lars |
1 |
% $Header: /cvsroot/html2ps/postscript/array.ps,v 1.1 2005/12/18 07:21:36 Konstantin Exp $
|
|
|
2 |
|
|
|
3 |
% Actually, array-append and array-prepend should have names exchanged;
|
|
|
4 |
% nevertheless, I don't want to track down renames all over ps files, so I've decided to
|
|
|
5 |
% keep this as is
|
|
|
6 |
%
|
|
|
7 |
% Prepends item to array
|
|
|
8 |
%
|
|
|
9 |
% @param Item item value
|
|
|
10 |
% @param Array source array
|
|
|
11 |
% @return A copy of source array with Item prepended as a first element
|
|
|
12 |
%
|
|
|
13 |
/array-append { % => Item Array
|
|
|
14 |
aload length
|
|
|
15 |
1 add
|
|
|
16 |
array astore
|
|
|
17 |
} def
|
|
|
18 |
|
|
|
19 |
/in-array-find { % => Array Value Pos
|
|
|
20 |
2 index length 0 eq {
|
|
|
21 |
pop pop pop -1
|
|
|
22 |
} {
|
|
|
23 |
2 index 0 get % => Array Value Pos A0
|
|
|
24 |
2 index eq { % => Array Value Pos
|
|
|
25 |
3 1 roll % => Pos Array Value
|
|
|
26 |
pop pop % => Pos
|
|
|
27 |
} {
|
|
|
28 |
1 add % => Array Value Pos+1
|
|
|
29 |
2 index
|
|
|
30 |
array-pop-first % => Array Value Pos+1 Array'
|
|
|
31 |
4 3 roll pop % => Value Pos+1 Array'
|
|
|
32 |
3 1 roll % => Array' Value Pos+1
|
|
|
33 |
in-array-find
|
|
|
34 |
} ifelse
|
|
|
35 |
} ifelse
|
|
|
36 |
} def
|
|
|
37 |
|
|
|
38 |
/array-find { % => Array Value
|
|
|
39 |
|
|
|
40 |
} def
|
|
|
41 |
|
|
|
42 |
/array-insert { % => Index Value Data
|
|
|
43 |
aload length % => Index Value A1 .. AN N
|
|
|
44 |
1 add % => Index Value A1 .. AN N+1
|
|
|
45 |
dup 2 add % => Index Value A1 .. AN N+1 N+3
|
|
|
46 |
dup index % => Index Value A1 .. AN N+1 N+3 Index
|
|
|
47 |
exch % => Index Value A1 .. AN N+1 Index N+3
|
|
|
48 |
1 sub % => Index Value A1 .. AN N+1 Index N+2
|
|
|
49 |
index % => Index Value A1 .. AN N+1 Index Value
|
|
|
50 |
exch % => Index Value A1 .. AN N+1 Value Index
|
|
|
51 |
2 index % => Index Value A1 .. AN N+1 Value Index N+1
|
|
|
52 |
1 add % => Index Value A1 .. AN N+1 Value Index N+2
|
|
|
53 |
exch sub % => Index Value A1 .. AN N+1 Value N-Index+2
|
|
|
54 |
1 % => Index Value A1 .. AN N+1 Value N-Index+2 1
|
|
|
55 |
roll % => Index Value A1 .. AINDEX-1 Value AINDEX .. AN N+1
|
|
|
56 |
array astore % => Index Value Array
|
|
|
57 |
3 1 roll % => Array Index Value
|
|
|
58 |
pop pop
|
|
|
59 |
} def % => Data'
|
|
|
60 |
|
|
|
61 |
/array-last { % => Array
|
|
|
62 |
dup length % => Array Length
|
|
|
63 |
1 sub % => Array Length-1
|
|
|
64 |
get % => Last
|
|
|
65 |
} def
|
|
|
66 |
|
|
|
67 |
/array-merge { % => A1 A2
|
|
|
68 |
{ % => A1 A2[i]
|
|
|
69 |
exch array-prepend % => A1'
|
|
|
70 |
} forall % => A1'
|
|
|
71 |
} def
|
|
|
72 |
|
|
|
73 |
/array-pop-last { % => Array
|
|
|
74 |
aload length % => A1 .. AN N
|
|
|
75 |
1 sub % => A1 .. AN N-1
|
|
|
76 |
exch pop % => A1 .. AN-1 N-1
|
|
|
77 |
array astore % => Array'
|
|
|
78 |
} def
|
|
|
79 |
|
|
|
80 |
/array-pop-first { % => Array
|
|
|
81 |
aload length % => A1 .. AN N
|
|
|
82 |
1 sub % => A1 .. AN N-1
|
|
|
83 |
array astore % => A1 Array'
|
|
|
84 |
exch pop % => Array'
|
|
|
85 |
} def
|
|
|
86 |
|
|
|
87 |
% Appends item to array
|
|
|
88 |
%
|
|
|
89 |
% @param Item item value
|
|
|
90 |
% @param Array source array
|
|
|
91 |
% @return A copy of source array with Item appended as a last element
|
|
|
92 |
%
|
|
|
93 |
/array-prepend { % => Item Array
|
|
|
94 |
aload length % => Item Item1 .. ItemN N
|
|
|
95 |
1 add % => Item Item1 .. ItemN N+1
|
|
|
96 |
dup 1 add % => Item Item1 .. ItemN N+1 N+2
|
|
|
97 |
1 index roll % => Item1 .. ItemN N+1 Item
|
|
|
98 |
exch % => Item1 .. ItemN Item N+1
|
|
|
99 |
array astore % => Array
|
|
|
100 |
} def
|
|
|
101 |
|
|
|
102 |
/array-remove { % => Array Index(ZeroBased)
|
|
|
103 |
exch % => Index Array
|
|
|
104 |
aload length % => Index A1 .. AN N
|
|
|
105 |
1 sub % => Index A1 .. AN N-1
|
|
|
106 |
dup 2 add % => Index A1 .. AN N-1 N+2
|
|
|
107 |
index % => Index A1 .. AN N-1 Index
|
|
|
108 |
1 index % => Index A1 .. AN N-1 Index N-1
|
|
|
109 |
2 add % => Index A1 .. AN N-1 Index N+1
|
|
|
110 |
exch sub % => Index A1 .. AN N-1 N-Index+1
|
|
|
111 |
dup 1 sub % => Index A1 .. AN N-1 N-Index+1 N-Index
|
|
|
112 |
roll % => Index A1 .. AINDEX-1 AINDEX+1 .. AN N-1 AINDEX
|
|
|
113 |
pop % => Index A1 .. AINDEX-1 AINDEX+1 .. AN N-1
|
|
|
114 |
array astore % => Index Array
|
|
|
115 |
exch pop % => Array
|
|
|
116 |
} def
|
|
|
117 |
|
|
|
118 |
% Basic insertions algorithm; we're working with small arrays
|
|
|
119 |
% and these arrays are have "good" natural order of elements, so
|
|
|
120 |
% more complicated algorithms are not needed here
|
|
|
121 |
%
|
|
|
122 |
/array-sort { % => Data GtFun
|
|
|
123 |
[] % => Data GtFun SortedData
|
|
|
124 |
array-sort-rec % => SortedData
|
|
|
125 |
} def
|
|
|
126 |
|
|
|
127 |
/array-sort-rec { % => Data GtFun SortedData
|
|
|
128 |
2 index length 0 gt {
|
|
|
129 |
2 index 2 index
|
|
|
130 |
array-sort-rec-select-max % => Data GtFun SortedData Data' MaxValue
|
|
|
131 |
|
|
|
132 |
5 4 roll pop % => GtFun SortedData Data' MaxValue
|
|
|
133 |
2 index array-prepend % => GtFun SortedData Data' SortedData'
|
|
|
134 |
|
|
|
135 |
3 2 roll pop % => GtFun Data' SortedData'
|
|
|
136 |
exch % => GtFun SortedData' Data'
|
|
|
137 |
3 1 roll % => Data' GtFun SortedData'
|
|
|
138 |
array-sort-rec
|
|
|
139 |
} {
|
|
|
140 |
exch pop
|
|
|
141 |
exch pop % => SortedData
|
|
|
142 |
} ifelse
|
|
|
143 |
} def
|
|
|
144 |
|
|
|
145 |
/array-sort-rec-select-max { % => Data GtFun
|
|
|
146 |
1 index 0 get % => Data GtFun E0
|
|
|
147 |
|
|
|
148 |
array-sort-rec-select-max-rec % => Data GtFun EMax EMaxIndex
|
|
|
149 |
|
|
|
150 |
% remove element found from source array
|
|
|
151 |
3 index exch array-remove % => Data GtFun EMax Data'
|
|
|
152 |
|
|
|
153 |
4 2 roll pop pop % => EMax Data
|
|
|
154 |
exch % => Data EMax
|
|
|
155 |
} def
|
|
|
156 |
|
|
|
157 |
/array-sort-rec-select-max-rec { % => Data GtFun EMax EMaxIndex ECurIndex
|
|
|
158 |
% Check if we're out of source array bounds
|
|
|
159 |
4 index length 1 index gt { % => Data GtFun EMax EMaxIndex ECurIndex
|
|
|
160 |
4 index 1 index get % => Data GtFun EMax EMaxIndex ECurIndex ECur
|
|
|
161 |
3 index % => Data GtFun EMax EMaxIndex ECurIndex ECur EMax
|
|
|
162 |
5 index exec % => Data GtFun EMax EMaxIndex ECurIndex ECur>EMax
|
|
|
163 |
{ % => Data GtFun EMax EMaxIndex ECurIndex
|
|
|
164 |
exch pop dup % => Data GtFun EMax EMaxIndex' ECurIndex
|
|
|
165 |
4 index 1 index get % => Data GtFun EMax EMaxIndex' ECurIndex EMax'
|
|
|
166 |
4 3 roll pop % => Data GtFun EMaxIndex' ECurIndex EMax'
|
|
|
167 |
3 1 roll % => Data GtFun EMax' EMaxIndex' ECurIndex
|
|
|
168 |
} if % => Data GtFun EMax' EMaxIndex' ECurIndex
|
|
|
169 |
1 add
|
|
|
170 |
array-sort-rec-select-max-rec
|
|
|
171 |
} {
|
|
|
172 |
pop
|
|
|
173 |
} ifelse
|
|
|
174 |
} def % => Data GtFun EMax EMaxIndex
|
|
|
175 |
|
|
|
176 |
/expand-to { % => Size Array
|
|
|
177 |
% if array have no elements - return immediately
|
|
|
178 |
dup length 0 eq {
|
|
|
179 |
[] % => Size Array Flags []
|
|
|
180 |
} {
|
|
|
181 |
dup sum % => Size Array ASize
|
|
|
182 |
dup 0 gt { % => Size Array ASize
|
|
|
183 |
dup % => Size Array ASize ASize
|
|
|
184 |
3 index lt % => Size Array ASize
|
|
|
185 |
{ % => Size Array ASize
|
|
|
186 |
2 index % => Size Array ASize Size
|
|
|
187 |
exch div % => Size Array Size/ASize
|
|
|
188 |
map-scale % => Size Array'
|
|
|
189 |
exch pop % => Array'
|
|
|
190 |
} { % => Size Array ASize
|
|
|
191 |
pop exch % => Array Size
|
|
|
192 |
pop % => Array
|
|
|
193 |
} ifelse % => Array
|
|
|
194 |
} { % => Size Array ASize
|
|
|
195 |
% No content found in some colspan columns
|
|
|
196 |
pop % => Size Array
|
|
|
197 |
array-pop-first
|
|
|
198 |
array-append % => Array
|
|
|
199 |
} ifelse
|
|
|
200 |
} ifelse
|
|
|
201 |
} def
|
|
|
202 |
|
|
|
203 |
/expand-to-with-flags { % => Size Array Flags
|
|
|
204 |
% if array have no elements - return immediately
|
|
|
205 |
1 index length 0 eq {
|
|
|
206 |
[] % => Size Array Flags []
|
|
|
207 |
} {
|
|
|
208 |
% Never decrease exising values
|
|
|
209 |
1 index sum % => Size Array Flags ASum
|
|
|
210 |
3 index % => Size Array Flags ASum Size
|
|
|
211 |
gt {
|
|
|
212 |
1 index % => Size Array Flags Expanded
|
|
|
213 |
} { % => Size Array Flags
|
|
|
214 |
% Subtract non-modifiable values from target value
|
|
|
215 |
2 copy {
|
|
|
216 |
dup not { pop } { pop pop 0 } ifelse
|
|
|
217 |
} zip-with
|
|
|
218 |
sum % => Size Array Flags Non-modSum
|
|
|
219 |
4 3 roll exch sub 3 1 roll % => Size' Array Flags
|
|
|
220 |
% Check if there's any expandable columns
|
|
|
221 |
2 copy {
|
|
|
222 |
dup { pop } { pop pop 0 } ifelse
|
|
|
223 |
} zip-with
|
|
|
224 |
sum % => Size Array Flags ModSum
|
|
|
225 |
|
|
|
226 |
dup 0 eq { % => Size Array Flags ModSum
|
|
|
227 |
pop % => Size Array Flags
|
|
|
228 |
1 index % => Size Array Flags Array
|
|
|
229 |
|
|
|
230 |
2 index exch
|
|
|
231 |
|
|
|
232 |
1 index
|
|
|
233 |
} { % => Size Array Flags ModSum
|
|
|
234 |
% Calculate scale koeff
|
|
|
235 |
3 index exch div % => Size Array Flags Koeff
|
|
|
236 |
% Apply scale koeff
|
|
|
237 |
|
|
|
238 |
2 index 1 index get {
|
|
|
239 |
3 index
|
|
|
240 |
1 index get % => Size Array Flags Koeff I A[i]
|
|
|
241 |
2 index mul % => Size Array Flags Koeff I A[i]*Koeff
|
|
|
242 |
4 index exch
|
|
|
243 |
2 index exch put % => Size Array Flags Koeff I
|
|
|
244 |
} if
|
|
|
245 |
pop
|
|
|
246 |
} for % => Size Array Flags Koeff
|
|
|
247 |
pop % => Size Array Flags
|
|
|
248 |
1 index
|
|
|
249 |
} ifelse % => Size Array Flags Expanded
|
|
|
250 |
} ifelse
|
|
|
251 |
} ifelse % => Size Array Flags Expanded
|
|
|
252 |
|
|
|
253 |
exch pop
|
|
|
254 |
exch pop
|
|
|
255 |
exch pop
|
|
|
256 |
} def
|
|
|
257 |
|
|
|
258 |
/in-reduce { % => A1 .. AN N Fun StartValue
|
|
|
259 |
2 index 0 gt {
|
|
|
260 |
4 3 roll % => A1 .. AN-1 N Fun StartValue AN
|
|
|
261 |
2 index exec % => A1 .. AN-1 N Fun (StartValue Fun AN)
|
|
|
262 |
3 2 roll % => A1 .. AN-1 Fun (StartValue Fun AN) N
|
|
|
263 |
1 sub % => A1 .. AN-1 Fun (StartValue Fun AN) N-1
|
|
|
264 |
3 1 roll % => A1 .. AN-1 N-1 Fun (StartValue Fun AN)
|
|
|
265 |
in-reduce
|
|
|
266 |
} { % => N Fun Value
|
|
|
267 |
3 1 roll % => Value N Fun
|
|
|
268 |
pop pop % => Value
|
|
|
269 |
} ifelse
|
|
|
270 |
} def
|
|
|
271 |
|
|
|
272 |
/reduce { % => Fun StartValue Array
|
|
|
273 |
aload length % => Fun StartValue A1 .. AN N
|
|
|
274 |
dup 3 add % => Fun StartValue A1 .. AN N N+3
|
|
|
275 |
1 index 1 add % => Fun StartValue A1 .. AN N N+3 N+1
|
|
|
276 |
roll % => A1 .. AN N Fun StartValue
|
|
|
277 |
in-reduce
|
|
|
278 |
} def
|
|
|
279 |
|
|
|
280 |
/sum { % => Array
|
|
|
281 |
{add} 0 % => Array {add} 0
|
|
|
282 |
3 2 roll % => {add} 0 Array
|
|
|
283 |
reduce % => Sum
|
|
|
284 |
} def
|