Spaces:
Sleeping
Sleeping
File size: 10,301 Bytes
07c3cdd | 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 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | % $Header: /cvsroot/html2ps/postscript/array.ps,v 1.1 2005/12/18 07:21:36 Konstantin Exp $
% Actually, array-append and array-prepend should have names exchanged;
% nevertheless, I don't want to track down renames all over ps files, so I've decided to
% keep this as is
%
% Prepends item to array
%
% @param Item item value
% @param Array source array
% @return A copy of source array with Item prepended as a first element
%
/array-append { % => Item Array
aload length
1 add
array astore
} def
/in-array-find { % => Array Value Pos
2 index length 0 eq {
pop pop pop -1
} {
2 index 0 get % => Array Value Pos A0
2 index eq { % => Array Value Pos
3 1 roll % => Pos Array Value
pop pop % => Pos
} {
1 add % => Array Value Pos+1
2 index
array-pop-first % => Array Value Pos+1 Array'
4 3 roll pop % => Value Pos+1 Array'
3 1 roll % => Array' Value Pos+1
in-array-find
} ifelse
} ifelse
} def
/array-find { % => Array Value
0 in-array-find
} def
/array-insert { % => Index Value Data
aload length % => Index Value A1 .. AN N
1 add % => Index Value A1 .. AN N+1
dup 2 add % => Index Value A1 .. AN N+1 N+3
dup index % => Index Value A1 .. AN N+1 N+3 Index
exch % => Index Value A1 .. AN N+1 Index N+3
1 sub % => Index Value A1 .. AN N+1 Index N+2
index % => Index Value A1 .. AN N+1 Index Value
exch % => Index Value A1 .. AN N+1 Value Index
2 index % => Index Value A1 .. AN N+1 Value Index N+1
1 add % => Index Value A1 .. AN N+1 Value Index N+2
exch sub % => Index Value A1 .. AN N+1 Value N-Index+2
1 % => Index Value A1 .. AN N+1 Value N-Index+2 1
roll % => Index Value A1 .. AINDEX-1 Value AINDEX .. AN N+1
array astore % => Index Value Array
3 1 roll % => Array Index Value
pop pop
} def % => Data'
/array-last { % => Array
dup length % => Array Length
1 sub % => Array Length-1
get % => Last
} def
/array-merge { % => A1 A2
{ % => A1 A2[i]
exch array-prepend % => A1'
} forall % => A1'
} def
/array-pop-last { % => Array
aload length % => A1 .. AN N
1 sub % => A1 .. AN N-1
exch pop % => A1 .. AN-1 N-1
array astore % => Array'
} def
/array-pop-first { % => Array
aload length % => A1 .. AN N
1 sub % => A1 .. AN N-1
array astore % => A1 Array'
exch pop % => Array'
} def
% Appends item to array
%
% @param Item item value
% @param Array source array
% @return A copy of source array with Item appended as a last element
%
/array-prepend { % => Item Array
aload length % => Item Item1 .. ItemN N
1 add % => Item Item1 .. ItemN N+1
dup 1 add % => Item Item1 .. ItemN N+1 N+2
1 index roll % => Item1 .. ItemN N+1 Item
exch % => Item1 .. ItemN Item N+1
array astore % => Array
} def
/array-remove { % => Array Index(ZeroBased)
exch % => Index Array
aload length % => Index A1 .. AN N
1 sub % => Index A1 .. AN N-1
dup 2 add % => Index A1 .. AN N-1 N+2
index % => Index A1 .. AN N-1 Index
1 index % => Index A1 .. AN N-1 Index N-1
2 add % => Index A1 .. AN N-1 Index N+1
exch sub % => Index A1 .. AN N-1 N-Index+1
dup 1 sub % => Index A1 .. AN N-1 N-Index+1 N-Index
roll % => Index A1 .. AINDEX-1 AINDEX+1 .. AN N-1 AINDEX
pop % => Index A1 .. AINDEX-1 AINDEX+1 .. AN N-1
array astore % => Index Array
exch pop % => Array
} def
% Basic insertions algorithm; we're working with small arrays
% and these arrays are have "good" natural order of elements, so
% more complicated algorithms are not needed here
%
/array-sort { % => Data GtFun
[] % => Data GtFun SortedData
array-sort-rec % => SortedData
} def
/array-sort-rec { % => Data GtFun SortedData
2 index length 0 gt {
2 index 2 index
array-sort-rec-select-max % => Data GtFun SortedData Data' MaxValue
5 4 roll pop % => GtFun SortedData Data' MaxValue
2 index array-prepend % => GtFun SortedData Data' SortedData'
3 2 roll pop % => GtFun Data' SortedData'
exch % => GtFun SortedData' Data'
3 1 roll % => Data' GtFun SortedData'
array-sort-rec
} {
exch pop
exch pop % => SortedData
} ifelse
} def
/array-sort-rec-select-max { % => Data GtFun
1 index 0 get % => Data GtFun E0
0 1 % => Data GtFun EMax EMaxIndex ECurIndex
array-sort-rec-select-max-rec % => Data GtFun EMax EMaxIndex
% remove element found from source array
3 index exch array-remove % => Data GtFun EMax Data'
4 2 roll pop pop % => EMax Data
exch % => Data EMax
} def
/array-sort-rec-select-max-rec { % => Data GtFun EMax EMaxIndex ECurIndex
% Check if we're out of source array bounds
4 index length 1 index gt { % => Data GtFun EMax EMaxIndex ECurIndex
4 index 1 index get % => Data GtFun EMax EMaxIndex ECurIndex ECur
3 index % => Data GtFun EMax EMaxIndex ECurIndex ECur EMax
5 index exec % => Data GtFun EMax EMaxIndex ECurIndex ECur>EMax
{ % => Data GtFun EMax EMaxIndex ECurIndex
exch pop dup % => Data GtFun EMax EMaxIndex' ECurIndex
4 index 1 index get % => Data GtFun EMax EMaxIndex' ECurIndex EMax'
4 3 roll pop % => Data GtFun EMaxIndex' ECurIndex EMax'
3 1 roll % => Data GtFun EMax' EMaxIndex' ECurIndex
} if % => Data GtFun EMax' EMaxIndex' ECurIndex
1 add
array-sort-rec-select-max-rec
} {
pop
} ifelse
} def % => Data GtFun EMax EMaxIndex
/expand-to { % => Size Array
% if array have no elements - return immediately
dup length 0 eq {
[] % => Size Array Flags []
} {
dup sum % => Size Array ASize
dup 0 gt { % => Size Array ASize
dup % => Size Array ASize ASize
3 index lt % => Size Array ASize
{ % => Size Array ASize
2 index % => Size Array ASize Size
exch div % => Size Array Size/ASize
map-scale % => Size Array'
exch pop % => Array'
} { % => Size Array ASize
pop exch % => Array Size
pop % => Array
} ifelse % => Array
} { % => Size Array ASize
% No content found in some colspan columns
pop % => Size Array
array-pop-first
array-append % => Array
} ifelse
} ifelse
} def
/expand-to-with-flags { % => Size Array Flags
% if array have no elements - return immediately
1 index length 0 eq {
[] % => Size Array Flags []
} {
% Never decrease exising values
1 index sum % => Size Array Flags ASum
3 index % => Size Array Flags ASum Size
gt {
1 index % => Size Array Flags Expanded
} { % => Size Array Flags
% Subtract non-modifiable values from target value
2 copy {
dup not { pop } { pop pop 0 } ifelse
} zip-with
sum % => Size Array Flags Non-modSum
4 3 roll exch sub 3 1 roll % => Size' Array Flags
% Check if there's any expandable columns
2 copy {
dup { pop } { pop pop 0 } ifelse
} zip-with
sum % => Size Array Flags ModSum
dup 0 eq { % => Size Array Flags ModSum
pop % => Size Array Flags
1 index % => Size Array Flags Array
0 get 3 index add % => Size Array Flags A0'
2 index exch
0 exch put % => Size Array Flags
1 index
} { % => Size Array Flags ModSum
% Calculate scale koeff
3 index exch div % => Size Array Flags Koeff
% Apply scale koeff
0 1 4 index length 1 sub { % => Size Array Flags Koeff I
2 index 1 index get {
3 index
1 index get % => Size Array Flags Koeff I A[i]
2 index mul % => Size Array Flags Koeff I A[i]*Koeff
4 index exch
2 index exch put % => Size Array Flags Koeff I
} if
pop
} for % => Size Array Flags Koeff
pop % => Size Array Flags
1 index
} ifelse % => Size Array Flags Expanded
} ifelse
} ifelse % => Size Array Flags Expanded
exch pop
exch pop
exch pop
} def
/in-reduce { % => A1 .. AN N Fun StartValue
2 index 0 gt {
4 3 roll % => A1 .. AN-1 N Fun StartValue AN
2 index exec % => A1 .. AN-1 N Fun (StartValue Fun AN)
3 2 roll % => A1 .. AN-1 Fun (StartValue Fun AN) N
1 sub % => A1 .. AN-1 Fun (StartValue Fun AN) N-1
3 1 roll % => A1 .. AN-1 N-1 Fun (StartValue Fun AN)
in-reduce
} { % => N Fun Value
3 1 roll % => Value N Fun
pop pop % => Value
} ifelse
} def
/reduce { % => Fun StartValue Array
aload length % => Fun StartValue A1 .. AN N
dup 3 add % => Fun StartValue A1 .. AN N N+3
1 index 1 add % => Fun StartValue A1 .. AN N N+3 N+1
roll % => A1 .. AN N Fun StartValue
in-reduce
} def
/sum { % => Array
{add} 0 % => Array {add} 0
3 2 roll % => {add} 0 Array
reduce % => Sum
} def
|