geotree 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.txt +4 -2
- data/README.txt +6 -8
- data/lib/geotree/blockfile.rb +0 -28
- data/lib/geotree/geotree.rb +55 -119
- data/lib/geotree/multitree.rb +2 -21
- data/lib/geotree/pswriter.rb +217 -150
- data/lib/geotree/tools.rb +1 -0
- data/test/test_blockfile.rb +1 -1
- data/test/test_externalsort.rb +15 -1
- data/test/test_geotree.rb +24 -7
- data/test/test_ps.rb +1 -1
- metadata +2 -5
- data/lib/fig/geo_tree.pdf +0 -0
- data/lib/fig/multi_tree.pdf +0 -0
data/lib/geotree/multitree.rb
CHANGED
@@ -16,7 +16,7 @@ module GeoTreeModule
|
|
16
16
|
# When querying a MultiTree, the user must specify which level of detail (i.e.,
|
17
17
|
# which of the contained trees) is to be examined.
|
18
18
|
#
|
19
|
-
#
|
19
|
+
# {An animation of a MultiTree in action.}[link:http://www.cs.ubc.ca/~jpsember/multi_tree.ps]
|
20
20
|
#
|
21
21
|
class MultiTree
|
22
22
|
|
@@ -123,9 +123,7 @@ module GeoTreeModule
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def add_buffered_point(data_point)
|
126
|
-
|
127
|
-
# db = true
|
128
|
-
|
126
|
+
|
129
127
|
# Determine which is the lowest detail level at which
|
130
128
|
# this point is to be found
|
131
129
|
|
@@ -137,8 +135,6 @@ module GeoTreeModule
|
|
137
135
|
|
138
136
|
randval = (wt + stretch*rf) / MAX_POINT_WEIGHT
|
139
137
|
|
140
|
-
!db || pr("add pt#%4d wt%2d rf=%6.3f rand=%6.3f: ",data_point.name,wt,rf,randval)
|
141
|
-
|
142
138
|
num_trees.times do |ti|
|
143
139
|
di = num_trees - 1 - ti
|
144
140
|
|
@@ -146,10 +142,8 @@ module GeoTreeModule
|
|
146
142
|
break
|
147
143
|
end
|
148
144
|
|
149
|
-
!db || pr(" ++ #{di} ")
|
150
145
|
tree(di).add_buffered_point(data_point)
|
151
146
|
end
|
152
|
-
!db || pr("\n")
|
153
147
|
end
|
154
148
|
|
155
149
|
private
|
@@ -177,16 +171,3 @@ module GeoTreeModule
|
|
177
171
|
end
|
178
172
|
end
|
179
173
|
|
180
|
-
if main?(__FILE__)
|
181
|
-
include GeoTreeModule
|
182
|
-
newdir = File.join(File.dirname(__FILE__),"../../test/workdir")
|
183
|
-
assert!(File.directory?(newdir))
|
184
|
-
Dir.chdir(newdir)
|
185
|
-
remove_file_or_dir("_multitree_")
|
186
|
-
|
187
|
-
mt = MultiTree.new("_multitree_",3)
|
188
|
-
|
189
|
-
pts = DataPoint.rnd_many(100)
|
190
|
-
pts.each{|x| mt.add(x)}
|
191
|
-
|
192
|
-
end
|
data/lib/geotree/pswriter.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
require_relative 'tools'
|
2
2
|
|
3
3
|
module PS_Private
|
4
|
+
LT_SOLID_ = 1900
|
5
|
+
LT_DASHED_ = 1901
|
6
|
+
LT_DOTTED_ = 1902
|
7
|
+
|
8
|
+
LINEWIDTH_FACTOR_ = 3.0
|
9
|
+
LINETYPE_ = 1
|
10
|
+
LINEWIDTH_ = 2
|
11
|
+
TRANS_ = 3
|
12
|
+
RGB_ = 4
|
13
|
+
FONTHEIGHT_ = 5
|
14
|
+
SCALE_ = 6
|
15
|
+
|
16
|
+
S_START_ = 0
|
17
|
+
S_OPEN_ = 1
|
18
|
+
S_CLOSED_ = 2
|
19
|
+
|
4
20
|
class SOper
|
5
21
|
attr_reader :type
|
6
22
|
def self.null
|
@@ -24,35 +40,40 @@ module PS_Private
|
|
24
40
|
end
|
25
41
|
end
|
26
42
|
|
27
|
-
# A debugging / demonstration utility class that
|
43
|
+
# A debugging / demonstration utility class that
|
28
44
|
# generates postscript images
|
29
45
|
#
|
30
46
|
class PSWriter
|
31
47
|
include PS_Private
|
32
48
|
|
33
|
-
LT_SOLID = 1900
|
34
|
-
LT_DASHED = 1901
|
35
|
-
LT_DOTTED = 1902
|
36
|
-
|
37
|
-
LINEWIDTH_FACTOR = 3.0
|
38
|
-
LINETYPE = 1
|
39
|
-
LINEWIDTH = 2
|
40
|
-
TRANS = 3
|
41
|
-
RGB = 4
|
42
|
-
FONTHEIGHT = 5
|
43
|
-
SCALE = 6
|
44
|
-
|
45
|
-
S_START = 0
|
46
|
-
S_OPEN = 1
|
47
|
-
S_CLOSED = 2
|
48
49
|
# @param path path of file to write (e.g. xxx.ps)
|
49
50
|
def initialize(path)
|
50
51
|
@path = path
|
51
52
|
@line_width = -1
|
52
53
|
@rgb = [-1,0,0]
|
53
54
|
@phys_size = [612,792]
|
54
|
-
@state =
|
55
|
+
@state = S_START_
|
55
56
|
@stack = []
|
57
|
+
@buffer_stack = []
|
58
|
+
@dict = {}
|
59
|
+
@dict_keys = []
|
60
|
+
|
61
|
+
de("A","{arc} bind")
|
62
|
+
de("CP","{closepath} bind")
|
63
|
+
de('F','{fill} bind')
|
64
|
+
de('I','{index} bind')
|
65
|
+
de("L","{lineto} bind")
|
66
|
+
de("M","{moveto} bind")
|
67
|
+
de("NP","{newpath} bind")
|
68
|
+
de('SRGB','{setrgbcolor} bind')
|
69
|
+
de('SLW','{setlinewidth} bind')
|
70
|
+
de('P','{pop} bind')
|
71
|
+
de("R","{rmoveto} bind")
|
72
|
+
de("S","{stroke} bind")
|
73
|
+
de('SCL','{scale} bind')
|
74
|
+
de('TR','{translate} bind')
|
75
|
+
de("V","{rlineto} bind")
|
76
|
+
de("DSH","{setdash} bind")
|
56
77
|
|
57
78
|
set_logical_page_size(1000,1200)
|
58
79
|
|
@@ -65,22 +86,45 @@ class PSWriter
|
|
65
86
|
@s = ''
|
66
87
|
end
|
67
88
|
|
89
|
+
def start_buffer
|
90
|
+
raise IllegalStateException if !@buffer_stack.empty?
|
91
|
+
@buffer_stack << @s
|
92
|
+
@s = ''
|
93
|
+
end
|
94
|
+
|
95
|
+
def stop_buffer
|
96
|
+
raise IllegalStateException if @buffer_stack.empty?
|
97
|
+
ret = @s
|
98
|
+
@s = @buffer_stack.pop
|
99
|
+
ret
|
100
|
+
end
|
101
|
+
|
102
|
+
|
68
103
|
# Close document and write to disk
|
69
104
|
def close
|
70
|
-
if @state <
|
105
|
+
if @state < S_CLOSED_
|
71
106
|
if @stack.size != 0
|
72
107
|
warn("state stack nonempty for #{@path}")
|
73
108
|
end
|
109
|
+
|
74
110
|
flush_page
|
75
|
-
|
76
|
-
|
111
|
+
|
112
|
+
# Construct file by combining header, dictionary, and
|
113
|
+
# the user text
|
114
|
+
|
115
|
+
s = get_doc_header
|
116
|
+
s << get_doc_dictionary
|
117
|
+
s << @s
|
118
|
+
set_state(S_CLOSED_)
|
119
|
+
|
120
|
+
write_text_file(@path, s)
|
77
121
|
end
|
78
122
|
end
|
79
123
|
|
80
124
|
# Set logical page size. Subsequent drawing operations will be scaled
|
81
125
|
# appropriately. Default logical page size is 1000 x 1200 units.
|
82
126
|
def set_logical_page_size( width, height)
|
83
|
-
raise IllegalStateException if @state !=
|
127
|
+
raise IllegalStateException if @state != S_START_
|
84
128
|
@document_size = [width,height]
|
85
129
|
end
|
86
130
|
|
@@ -91,83 +135,103 @@ class PSWriter
|
|
91
135
|
# Draw a rectangle
|
92
136
|
# @param inset distance to inset rectangle boundary (positive: shrink; negative:expand)
|
93
137
|
def draw_rect(x,y,w,h,inset = 0)
|
138
|
+
de("RC","{3 I 3 I M 1 I 0 V 0 1 I V 1 I neg 0 V P P P P CP S }")
|
94
139
|
a(x + inset)
|
95
140
|
a(y + inset)
|
96
141
|
a(w - 2 * inset);
|
97
142
|
a(h - 2 * inset);
|
98
|
-
a("
|
143
|
+
a("RC");
|
144
|
+
cr
|
99
145
|
end
|
100
146
|
|
101
147
|
def set_font_size(height)
|
102
|
-
raise IllegalStateException if @state !=
|
148
|
+
raise IllegalStateException if @state != S_OPEN_
|
103
149
|
|
104
150
|
ret = SOper.null
|
105
151
|
|
106
|
-
if
|
107
|
-
ret = SOper.new(
|
152
|
+
if @font_height != height
|
153
|
+
ret = SOper.new(FONTHEIGHT_, @font_height)
|
108
154
|
@font_height = height;
|
109
155
|
@scaled_font_height = height / @scale;
|
110
156
|
a("/Monaco findfont ");
|
111
157
|
a(@scaled_font_height);
|
112
158
|
a("scalefont setfont\n");
|
159
|
+
cr
|
113
160
|
end
|
114
161
|
ret
|
115
162
|
end
|
116
163
|
|
117
164
|
def draw_string(string, x, y)
|
165
|
+
if @font_height == 0
|
166
|
+
set_font_size(28)
|
167
|
+
end
|
168
|
+
|
169
|
+
# /TEXTL { currentpoint S M 0 0 R show } def
|
170
|
+
# % Right-justified text
|
171
|
+
# /TEXTR { currentpoint S M dup stringwidth pop neg 0 R show } def
|
172
|
+
# % Centered text
|
173
|
+
de("TX", "{currentpoint S M dup stringwidth pop -2 div 0 R show }")
|
174
|
+
|
118
175
|
a(x)
|
119
176
|
a(y - @scaled_font_height / 2);
|
120
|
-
a("M
|
177
|
+
a("M")
|
121
178
|
work = make_eps_safe(string)
|
122
179
|
a(work)
|
123
|
-
a("
|
180
|
+
a("TX")
|
181
|
+
cr
|
124
182
|
end
|
125
183
|
|
126
|
-
def draw_disc(cx,
|
127
|
-
|
184
|
+
def draw_disc(cx,cy,radius)
|
185
|
+
de("CF", "{NP 0 360 A CP F}")
|
128
186
|
a(cx);
|
129
187
|
a(cy);
|
130
188
|
a(radius);
|
131
|
-
a("
|
189
|
+
a("CF")
|
190
|
+
cr
|
132
191
|
end
|
133
192
|
|
134
193
|
def draw_circle(cx, cy, radius)
|
194
|
+
de("CH", "{NP 0 360 A CP S}")
|
135
195
|
a("NP");
|
136
196
|
a(cx);
|
137
197
|
a(cy);
|
138
198
|
a(radius);
|
139
|
-
a("
|
199
|
+
a("CH");
|
200
|
+
cr
|
140
201
|
end
|
141
202
|
|
142
203
|
def draw_line(x1,y1,x2,y2)
|
143
|
-
|
204
|
+
de("LN", "{NP 4 2 roll M L CP S}")
|
205
|
+
|
206
|
+
# a("NP");
|
144
207
|
a(x1);
|
145
208
|
a(y1);
|
146
|
-
a("
|
209
|
+
# a("M");
|
147
210
|
a(x2);
|
148
211
|
a(y2);
|
149
|
-
a("
|
212
|
+
a("LN");
|
213
|
+
cr
|
150
214
|
end
|
151
215
|
|
152
216
|
def set_line_solid
|
153
|
-
set_line_type(
|
217
|
+
set_line_type(LT_SOLID_)
|
154
218
|
end
|
155
219
|
|
156
220
|
def set_line_dashed
|
157
|
-
set_line_type(
|
221
|
+
set_line_type(LT_DASHED_)
|
158
222
|
end
|
159
223
|
|
160
224
|
def set_line_dotted
|
161
|
-
set_line_type(
|
225
|
+
set_line_type(LT_DOTTED_)
|
162
226
|
end
|
163
227
|
|
164
228
|
def set_scale(f)
|
165
229
|
ret = SOper.null
|
166
230
|
if f != 1
|
167
|
-
ret = SOper.new(
|
231
|
+
ret = SOper.new(SCALE_, 1.0 / f)
|
168
232
|
a(f);
|
169
233
|
a(f);
|
170
|
-
a("
|
234
|
+
a("SCL");
|
171
235
|
end
|
172
236
|
ret
|
173
237
|
end
|
@@ -175,24 +239,24 @@ class PSWriter
|
|
175
239
|
def set_line_type(type)
|
176
240
|
ret = SOper.null
|
177
241
|
if @line_type != type
|
178
|
-
ret = SOper.new(
|
242
|
+
ret = SOper.new(LINETYPE_, @line_type)
|
179
243
|
@line_type = type
|
180
244
|
case type
|
181
|
-
when
|
245
|
+
when LT_DASHED_
|
182
246
|
n = (@scale * 30).to_i
|
183
247
|
a("[");
|
184
248
|
a(n);
|
185
249
|
a(n);
|
186
|
-
a("] 0
|
187
|
-
when
|
250
|
+
a("] 0 DSH");
|
251
|
+
when LT_DOTTED_
|
188
252
|
int n = (@scale * 30).to_i
|
189
253
|
n2 = n / 4
|
190
254
|
a("[");
|
191
255
|
a(n2);
|
192
256
|
a(n);
|
193
|
-
a("] 0
|
194
|
-
else #
|
195
|
-
a("[] 0
|
257
|
+
a("] 0 DSH");
|
258
|
+
else # LT_SOLID_
|
259
|
+
a("[] 0 DSH");
|
196
260
|
end
|
197
261
|
end
|
198
262
|
ret
|
@@ -203,38 +267,39 @@ class PSWriter
|
|
203
267
|
# @param x translation to apply to coordinates
|
204
268
|
# @param y
|
205
269
|
def draw_polygon(polygon, x, y)
|
270
|
+
|
206
271
|
push(translate(x, y))
|
207
|
-
a("NP
|
272
|
+
a("NP")
|
208
273
|
i = 0
|
209
274
|
while i < polygon.size
|
210
275
|
a(polygon[i])
|
211
|
-
a(' ');
|
212
276
|
a((polygon[i + 1]))
|
213
277
|
if (i == 0)
|
214
|
-
a("
|
278
|
+
a("M");
|
215
279
|
else
|
216
|
-
a("
|
280
|
+
a("L");
|
217
281
|
end
|
218
282
|
i += 2
|
219
283
|
end
|
220
|
-
|
221
|
-
|
284
|
+
a("CP S")
|
285
|
+
cr
|
222
286
|
pop()
|
223
287
|
end
|
224
288
|
|
225
289
|
# Translate subsequent drawing operations
|
226
290
|
def translate(tx,ty,neg=false)
|
291
|
+
|
227
292
|
ret = SOper.null
|
228
293
|
if (neg)
|
229
294
|
tx = -tx;
|
230
295
|
ty = -ty;
|
231
296
|
end
|
232
297
|
if (tx != 0 || ty != 0)
|
233
|
-
ret = SOper.new(
|
298
|
+
ret = SOper.new(TRANS_, -tx, -ty)
|
234
299
|
|
235
300
|
a(tx);
|
236
301
|
a(ty);
|
237
|
-
a("TR
|
302
|
+
a("TR");
|
238
303
|
end
|
239
304
|
ret
|
240
305
|
end
|
@@ -242,10 +307,11 @@ class PSWriter
|
|
242
307
|
def set_line_width(w)
|
243
308
|
ret = SOper.null
|
244
309
|
if @line_width != w
|
245
|
-
|
310
|
+
|
311
|
+
ret = SOper.new(LINEWIDTH_, @line_width)
|
246
312
|
@line_width = w
|
247
|
-
a(
|
248
|
-
a("SLW
|
313
|
+
a(LINEWIDTH_FACTOR_ * @scale * @line_width)
|
314
|
+
a("SLW");
|
249
315
|
end
|
250
316
|
ret
|
251
317
|
end
|
@@ -253,12 +319,13 @@ class PSWriter
|
|
253
319
|
def set_rgb(r,g,b)
|
254
320
|
ret = SOper.null
|
255
321
|
if (r != @rgb[0] || g != @rgb[1] || b != @rgb[2])
|
256
|
-
|
322
|
+
|
323
|
+
ret = SOper.new(RGB_, @rgb[0], @rgb[1], @rgb[2])
|
257
324
|
a(r)
|
258
325
|
a(g)
|
259
326
|
a(b)
|
260
327
|
@rgb = [r,g,b]
|
261
|
-
a("SRGB
|
328
|
+
a("SRGB");
|
262
329
|
end
|
263
330
|
ret
|
264
331
|
end
|
@@ -270,11 +337,11 @@ class PSWriter
|
|
270
337
|
def set_state( s)
|
271
338
|
if (@state != s)
|
272
339
|
case s
|
273
|
-
when
|
274
|
-
raise IllegalStateException if @state !=
|
340
|
+
when S_OPEN_
|
341
|
+
raise IllegalStateException if @state != S_START_
|
275
342
|
@state = s
|
276
|
-
print_document_header
|
277
|
-
when
|
343
|
+
# print_document_header
|
344
|
+
when S_START_
|
278
345
|
raise IllegalStateException
|
279
346
|
end
|
280
347
|
@state = s
|
@@ -284,7 +351,7 @@ class PSWriter
|
|
284
351
|
# Start a new page
|
285
352
|
# @param page_title title of new page
|
286
353
|
def new_page(page_title)
|
287
|
-
set_state(
|
354
|
+
set_state(S_OPEN_);
|
288
355
|
flush_page
|
289
356
|
|
290
357
|
print_page_header(page_title);
|
@@ -303,39 +370,82 @@ class PSWriter
|
|
303
370
|
n = @stack.size - 1
|
304
371
|
op = @stack.pop
|
305
372
|
case op.type
|
306
|
-
when
|
373
|
+
when RGB_
|
307
374
|
set_rgb(op.arg(0),op.arg(1),op.arg(2))
|
308
|
-
when
|
375
|
+
when LINETYPE_
|
309
376
|
set_line_type(op.arg(0))
|
310
|
-
when
|
377
|
+
when LINEWIDTH_
|
311
378
|
set_line_width(op.arg(0))
|
312
|
-
when
|
379
|
+
when TRANS_
|
313
380
|
translate(op.arg(0),op.arg(1))
|
314
|
-
when
|
381
|
+
when FONTHEIGHT_
|
315
382
|
set_font_size(op.arg(0))
|
316
|
-
when
|
383
|
+
when SCALE_
|
317
384
|
set_scale(op.arg(0))
|
318
385
|
end
|
319
386
|
end
|
320
387
|
end
|
321
388
|
|
389
|
+
# Define an element by placing it in the dictionary
|
390
|
+
def add_element(key,val)
|
391
|
+
de(key,'{'+val+'}')
|
392
|
+
end
|
393
|
+
|
394
|
+
def draw_element(key)
|
395
|
+
val = @dict[key]
|
396
|
+
raise ArgumentError if !@dict.member?(key)
|
397
|
+
a(key)
|
398
|
+
end
|
399
|
+
|
322
400
|
private
|
323
401
|
|
402
|
+
def cr
|
403
|
+
if true
|
404
|
+
if @sp_req
|
405
|
+
@s << ' '
|
406
|
+
@sp_req = false
|
407
|
+
end
|
408
|
+
else
|
409
|
+
@sp_req = false
|
410
|
+
@s << "\n"
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
324
414
|
def a(obj)
|
415
|
+
if @sp_req
|
416
|
+
@s << ' '
|
417
|
+
end
|
325
418
|
if obj.is_a? Numeric
|
326
419
|
if obj.is_a? Float
|
327
|
-
w = sprintf("
|
328
|
-
|
420
|
+
w = sprintf("%.2f",obj)
|
421
|
+
# Trim extraneous leading/trailing zeros
|
422
|
+
|
423
|
+
if w[0,2] == '0.'
|
424
|
+
w = w[1.. -1]
|
425
|
+
elsif w[0,3] == '-0.'
|
426
|
+
w[1,1] = ''
|
427
|
+
end
|
428
|
+
|
429
|
+
j = w.index('.')
|
430
|
+
if j
|
431
|
+
while w[-1] == '0'
|
432
|
+
w = w[0..-2]
|
433
|
+
end
|
434
|
+
if w[-1] == '.'
|
435
|
+
w = w[0..-2]
|
436
|
+
end
|
437
|
+
end
|
438
|
+
@s << w
|
329
439
|
else
|
330
|
-
@s <<
|
440
|
+
@s << obj.to_s
|
331
441
|
end
|
332
442
|
else
|
333
|
-
@s <<
|
443
|
+
@s << obj
|
334
444
|
end
|
445
|
+
@sp_req = true
|
335
446
|
end
|
336
447
|
|
337
448
|
def print_page_header(page_title)
|
338
|
-
|
339
449
|
# set up transformation
|
340
450
|
lMargin = @phys_size[0] * 0.07
|
341
451
|
lWorkX = @phys_size[0] - 2 * lMargin
|
@@ -348,10 +458,10 @@ class PSWriter
|
|
348
458
|
|
349
459
|
a(lcx)
|
350
460
|
a(lcy)
|
351
|
-
a("TR
|
461
|
+
a("TR");
|
352
462
|
a(scl);
|
353
463
|
a(scl);
|
354
|
-
a("SCL
|
464
|
+
a("SCL");
|
355
465
|
set_line_width(1);
|
356
466
|
set_gray(0);
|
357
467
|
|
@@ -366,46 +476,40 @@ class PSWriter
|
|
366
476
|
end
|
367
477
|
end
|
368
478
|
|
369
|
-
def
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
/
|
379
|
-
|
380
|
-
/
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
/M {moveto} bind def
|
385
|
-
/L {lineto} bind def
|
386
|
-
/R {rmoveto} bind def
|
387
|
-
/V {rlineto} bind def
|
388
|
-
% Left-justified text
|
389
|
-
/TEXTL { currentpoint S M 0 0 R show } def
|
390
|
-
% Right-justified text
|
391
|
-
/TEXTR { currentpoint S M dup stringwidth pop neg 0 R show } def
|
392
|
-
% Centered text
|
393
|
-
/TEXTC { currentpoint S M dup stringwidth pop -2 div 0 R show } def
|
394
|
-
|
395
|
-
% Plot rectangle at x,y,w,h
|
396
|
-
/RECT { 3 index 3 index M
|
397
|
-
1 index 0 V
|
398
|
-
0 1 index V
|
399
|
-
1 index neg 0 V
|
400
|
-
pop pop pop pop CP
|
401
|
-
S } def
|
402
|
-
TXT
|
403
|
-
)
|
479
|
+
def get_doc_header
|
480
|
+
h = "%!PS\n"
|
481
|
+
end
|
482
|
+
|
483
|
+
def get_doc_dictionary
|
484
|
+
s = ''
|
485
|
+
@dict_keys.each do |k|
|
486
|
+
v = @dict[k]
|
487
|
+
if v.size
|
488
|
+
s << '/' << k << ' ' << v << " def\n"
|
489
|
+
else
|
490
|
+
s2 << '/' << k << "\n"
|
491
|
+
end
|
492
|
+
end
|
493
|
+
s
|
404
494
|
end
|
405
495
|
|
496
|
+
def de(key,val)
|
497
|
+
if !@dict.member? key
|
498
|
+
@dict_keys << key
|
499
|
+
@dict[key] = val
|
500
|
+
else
|
501
|
+
vexist = @dict[key]
|
502
|
+
if vexist != val
|
503
|
+
raise ArgumentError,"Attempt to change value for key #{key} to #{val}, was #{vexist}"
|
504
|
+
end
|
505
|
+
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
|
406
510
|
def flush_page
|
407
511
|
if @page_used
|
408
|
-
|
512
|
+
a("showpage")
|
409
513
|
@page_used = false
|
410
514
|
end
|
411
515
|
end
|
@@ -432,40 +536,3 @@ TXT
|
|
432
536
|
|
433
537
|
end
|
434
538
|
|
435
|
-
if __FILE__ == $0
|
436
|
-
|
437
|
-
poly = [ 0, 0, 50, 30, 30, 80]
|
438
|
-
|
439
|
-
w = PSWriter.new("_jeff_.ps")
|
440
|
-
|
441
|
-
w.set_logical_page_size(1000, 1000)
|
442
|
-
10.times do |i|
|
443
|
-
|
444
|
-
w.new_page("example page #{i}" )
|
445
|
-
|
446
|
-
w.draw_disc(200, 700, 200 - i * 18)
|
447
|
-
w.draw_circle(700, 220, 10 + i * 5);
|
448
|
-
|
449
|
-
w.push(w.set_gray(0.8));
|
450
|
-
w.draw_disc(500, 500, 30 + i * 10);
|
451
|
-
w.pop();
|
452
|
-
w.push(w.set_line_width(3));
|
453
|
-
w.push(w.set_line_dashed());
|
454
|
-
w.draw_circle(500, 500, 30 + i * 10);
|
455
|
-
w.pop(2);
|
456
|
-
|
457
|
-
w.draw_line(20 + i * 10, 20, 980, 500 + i * 48);
|
458
|
-
w.push(w.set_line_width(1.2 + 0.3 * i));
|
459
|
-
w.push(w.translate(500 - i * 40, 500 - i * 40));
|
460
|
-
w.push(w.set_scale(1 + i * 0.7));
|
461
|
-
w.draw_polygon(poly, 0, 0);
|
462
|
-
w.pop(3);
|
463
|
-
|
464
|
-
w.push(w.set_rgb(1, 0.2, 0.2));
|
465
|
-
w.push(w.set_font_size(10 + i * 3));
|
466
|
-
w.draw_string("Hello", 10 + i * 30, 900 - i * 40);
|
467
|
-
w.pop();
|
468
|
-
w.pop();
|
469
|
-
end
|
470
|
-
w.close();
|
471
|
-
end
|