ifmapper 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.txt CHANGED
@@ -1,3 +1,7 @@
1
+ v1.0.9 - Bug fixed crash of cut selection when stubs were present.
2
+ - Added option to automap rooms with all caps.
3
+ - Bug fixed Select All rooms to show the selection.
4
+
1
5
  v1.0.8 - Added option to load a map from command-line.
2
6
  - Bug fixed pdf output of letters near exits.
3
7
  - Added support for comments in each location.
data/IFMapper.gemspec CHANGED
@@ -2,7 +2,7 @@ require "rubygems"
2
2
 
3
3
  spec = Gem::Specification.new do |spec|
4
4
  spec.name = "ifmapper"
5
- spec.version = '1.0.8'
5
+ spec.version = '1.0.9'
6
6
  spec.author = "Gonzalo Garramuno"
7
7
  spec.email = 'ggarra13@gmail.com'
8
8
  spec.homepage = 'http://www.rubyforge.org/projects/ifmapper/'
data/TODO.txt CHANGED
@@ -2,7 +2,5 @@
2
2
  - Make internationalization recognize the OS language directly.
3
3
  - Add SVG output
4
4
  - Do Printing
5
- - Cleanup code
6
- - Improve window scrolling (seems like an FXRuby bug)
7
5
  - Add Undo (at least for delete)
8
6
  - Add configurable hotkeys and mouse
data/docs/en/index.html CHANGED
@@ -16,7 +16,7 @@ Interactive</span> Fiction Mapper</a></font></b></u></p>
16
16
  <p align="center"><a href="images/IFMapper_main.gif">
17
17
  <img border="0" src="../images/IFMapper_main.gif" width="595" height="447"></a></p>
18
18
  <p align="center">
19
- <a href="file:///C:/MyProjects/rubyforge/html/ifmapper/start.html">A Tool for
19
+ <a href="start.html">A Tool for
20
20
  Mapping Interactive Fiction</a></p>
21
21
 
22
22
  </body>
@@ -27,8 +27,8 @@ class FXMap < Map
27
27
  # automapping
28
28
  attr_reader :automap # automapping transcript
29
29
 
30
- attr_reader :complexConnection
31
- attr_reader :mouseButton
30
+ attr_reader :complexConnection # Complex connection in progress
31
+ attr_reader :mouseButton # Mouse button pressed
32
32
 
33
33
 
34
34
  # pmap is a path map (a matrix or grid used for path finding).
@@ -41,6 +41,7 @@ class FXMap < Map
41
41
  @@roomlist = nil # Room List Window
42
42
  @@itemlist = nil # Item List Window
43
43
 
44
+ # Cursors
44
45
  @@tooltip = nil
45
46
  @@cursor_arrow = nil
46
47
  @@cursor_cross = nil
@@ -875,7 +876,7 @@ class FXMap < Map
875
876
  @tooltip_msg = sel.name
876
877
  status "\"#{sel.name}\": #{MSG_CLICK_TO_SELECT_AND_MOVE}"
877
878
  elsif sel.kind_of?(Connection)
878
- status MSG_CLICK_CHANGE_DIR
879
+ status MSG_CLICK_TOGGLE_ONE_WAY_CONNECTION
879
880
  end
880
881
  else
881
882
  if click_type(x, y)
@@ -1427,17 +1428,24 @@ class FXMap < Map
1427
1428
  rooms, conns = _cut_selected
1428
1429
 
1429
1430
  # Remove room exits pointing to any removed connection
1430
- conns.each { |c|
1431
- a = c.roomA
1432
- b = c.roomB
1433
- if not rooms.member?(a)
1434
- a[a.exits.index(c)] = nil
1435
- end
1436
- if not rooms.member?(b)
1437
- idx = b.exits.rindex(c)
1438
- b[idx] = nil if idx
1439
- end
1440
- }
1431
+ if conns
1432
+ conns.each { |c|
1433
+ a = c.roomA
1434
+ b = c.roomB
1435
+ if not rooms.member?(a)
1436
+ a[a.exits.index(c)] = nil
1437
+ end
1438
+ if b and not rooms.member?(b)
1439
+ idx = b.exits.rindex(c)
1440
+ b[idx] = nil if idx
1441
+ end
1442
+ }
1443
+ end
1444
+
1445
+ if @complexConnection
1446
+ @complexConnection = false
1447
+ status MSG_COMPLEX_CONNECTION_STOPPED
1448
+ end
1441
1449
 
1442
1450
  modified = true
1443
1451
  create_pathmap
@@ -1452,15 +1460,19 @@ class FXMap < Map
1452
1460
  rooms, conns = _cut_selected
1453
1461
 
1454
1462
  # Remove room exits pointing to any removed connection
1455
- conns.each { |c|
1456
- a = c.roomA
1457
- b = c.roomB
1458
- a[a.exits.index(c)] = nil
1459
- if b
1460
- idx = b.exits.rindex(c)
1461
- b[idx] = nil if idx
1462
- end
1463
- }
1463
+ if conns
1464
+ conns.each { |c|
1465
+ a = c.roomA
1466
+ b = c.roomB
1467
+ if not rooms.member?(a)
1468
+ a[a.exits.index(c)] = nil
1469
+ end
1470
+ if b and not rooms.member?(b)
1471
+ idx = b.exits.rindex(c)
1472
+ b[idx] = nil if idx
1473
+ end
1474
+ }
1475
+ end
1464
1476
 
1465
1477
  if @complexConnection
1466
1478
  @complexConnection = false
@@ -46,7 +46,7 @@ require 'IFMapper/FXWarningBox'
46
46
  class FXMapperWindow < FXMainWindow
47
47
 
48
48
  PROGRAM_NAME = "Interactive Fiction Mapper"
49
- VERSION = '1.0.7'
49
+ VERSION = '1.0.9'
50
50
  AUTHOR = "Gonzalo Garramuño"
51
51
 
52
52
  @@copy_buffer = nil
@@ -909,6 +909,7 @@ class FXMapperWindow < FXMainWindow
909
909
  sect.connections.each { |c|
910
910
  c.selected = true
911
911
  }
912
+ map.draw
912
913
  end
913
914
 
914
915
  def roomlist(sender, sel, event)
@@ -0,0 +1,526 @@
1
+
2
+ require 'tmpdir'
3
+
4
+ begin
5
+ require 'pdf/writer'
6
+ rescue LoadError => e
7
+ err = "PDF-Writer library not found. Please install it.\n"
8
+ if $rubygems
9
+ err += "You can usually do so if you do 'gem install pdf-writer'."
10
+ else
11
+ err += "You can download it from www.rubyforge.net."
12
+ end
13
+ raise LoadError, err
14
+ end
15
+
16
+ require 'IFMapper/MapPrinting'
17
+
18
+ PDF_ZOOM = 0.5
19
+ PDF_ROOM_WIDTH = W * PDF_ZOOM
20
+ PDF_ROOM_HEIGHT = H * PDF_ZOOM
21
+ PDF_ROOM_WS = WS * PDF_ZOOM
22
+ PDF_ROOM_HS = HS * PDF_ZOOM
23
+ PDF_MARGIN = 20.0
24
+
25
+ #
26
+ # Open all the map class and add all pdf methods there
27
+ # Gotta love Ruby's flexibility to just inject in new methods.
28
+ #
29
+ class FXConnection
30
+ def _cvt_pt(p, opts)
31
+ x = (p[0] - WW / 2.0) / WW.to_f
32
+ y = (p[1] - HH / 2.0) / HH.to_f
33
+ x = x * opts['ww'] + opts['ws_2'] + opts['margin_2'] + opts['w'] / 2.0
34
+ y = (opts['height'] - y) * opts['hh'] + opts['hs_2'] + opts['margin_2'] + opts['hs']
35
+ return [x, y]
36
+ end
37
+
38
+ def pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
39
+ return if @dir == BOTH
40
+
41
+ pt1, d = _arrow_info( x1, y1, x2, y2, 0.5 )
42
+
43
+ p = []
44
+ p << PDF::Writer::PolygonPoint.new( pt1[0], pt1[1] )
45
+ p << PDF::Writer::PolygonPoint.new( pt1[0] + d[0], pt1[1] - d[1] )
46
+ p << PDF::Writer::PolygonPoint.new( pt1[0] + d[1], pt1[1] + d[0] )
47
+ pdf.fill_color Color::RGB::Black
48
+ pdf.polygon(p).fill
49
+ end
50
+
51
+ def pdf_draw_complex_as_bspline( pdf, opts )
52
+ p = []
53
+ p << _cvt_pt(@pts[0], opts)
54
+ p << p[0]
55
+ p << p[0]
56
+ @pts.each { |pt|
57
+ p << _cvt_pt(pt, opts)
58
+ }
59
+ p << p[-1]
60
+ p << p[-1]
61
+ p << p[-1]
62
+ return FXSpline::bspline(p)
63
+ end
64
+
65
+ # PRE: If it's a loop exit that comes back to the same place, let's move
66
+ # it up and right
67
+ def pdf_draw_complex_as_lines( pdf, opts )
68
+ p = []
69
+ maxy = opts['height'] * opts['hh'] + opts['hs_2'] + opts['margin_2']
70
+ @pts.each { |pt|
71
+ if loop? == true
72
+ p << [ pt[0] * PDF_ZOOM + 10, maxy - pt[1] * PDF_ZOOM + 48 ]
73
+ else
74
+ p << [ pt[0] * PDF_ZOOM, maxy - pt[1] * PDF_ZOOM ]
75
+ end
76
+ }
77
+ return p
78
+ end
79
+
80
+ def pdf_draw_door( pdf, x1, y1, x2, y2 )
81
+ v = [ (x2-x1), (y2-y1) ]
82
+ t = 10 / Math.sqrt(v[0]*v[0]+v[1]*v[1])
83
+ v = [ v[0]*t, v[1]*t ]
84
+ m = [ (x2+x1)/2, (y2+y1)/2 ]
85
+ x1, y1 = [m[0] + v[1], m[1] - v[0]]
86
+ x2, y2 = [m[0] - v[1], m[1] + v[0]]
87
+ if @type == LOCKED_DOOR
88
+ pdf.move_to(x1, y1)
89
+ pdf.line_to(x2, y2).stroke
90
+ else
91
+ s = PDF::Writer::StrokeStyle.new(1,
92
+ :cap => :butt,
93
+ :join => :miter,
94
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
95
+ pdf.stroke_style(s)
96
+ v = [ v[0] / 3, v[1] / 3]
97
+ pdf.move_to(x1 - v[0], y1 - v[1])
98
+ pdf.line_to(x1 + v[0], y1 + v[1])
99
+ pdf.line_to(x2 + v[0], y2 + v[1])
100
+ pdf.line_to(x2 - v[0], y2 - v[1])
101
+ pdf.line_to(x1 - v[0], y1 - v[1])
102
+ pdf.stroke
103
+ s = PDF::Writer::StrokeStyle.new(2,
104
+ :cap => :butt,
105
+ :join => :miter,
106
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
107
+ pdf.stroke_style(s)
108
+ end
109
+ end
110
+
111
+ def pdf_draw_complex( pdf, opts )
112
+ if opts['Paths as Curves']
113
+ if @room[0] == @room[1]
114
+ dirA, dirB = dirs
115
+ if dirA == dirB
116
+ p = pdf_draw_complex_as_lines( pdf, opts )
117
+ else
118
+ p = pdf_draw_complex_as_bspline( pdf, opts )
119
+ end
120
+ else
121
+ p = pdf_draw_complex_as_bspline( pdf, opts )
122
+ end
123
+ else
124
+ p = pdf_draw_complex_as_lines( pdf, opts )
125
+ end
126
+ pdf.move_to( p[0][0], p[0][1] )
127
+ p.each { |pt| pdf.line_to( pt[0], pt[1] ) }
128
+ pdf.stroke
129
+
130
+ x1, y1 = [p[0][0], p[0][1]]
131
+ x2, y2 = [p[-1][0], p[-1][1]]
132
+ pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
133
+
134
+ if @type == LOCKED_DOOR or @type == CLOSED_DOOR
135
+ t = p.size / 2
136
+ x1, y1 = [ p[t][0], p[t][1] ]
137
+ x2, y2 = [ p[t-2][0], p[t-2][1] ]
138
+ pdf_draw_door(pdf, x1, y1, x2, y2)
139
+ end
140
+ end
141
+
142
+ def pdf_draw_simple(pdf, opts)
143
+ return if not @room[1] # PDF does not print unfinished complex connections
144
+
145
+ dir = @room[0].exits.index(self)
146
+ x1, y1 = @room[0].pdf_corner(opts, self, dir)
147
+ x2, y2 = @room[1].pdf_corner(opts, self)
148
+ pdf.move_to(x1, y1)
149
+ pdf.line_to(x2, y2).stroke
150
+ pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
151
+ if @type == LOCKED_DOOR or @type == CLOSED_DOOR
152
+ pdf_draw_door(pdf, x1, y1, x2, y2)
153
+ end
154
+ end
155
+
156
+ #
157
+ # Draw the connection text next to the arrow ('I', 'O', etc)
158
+ #
159
+ def pdf_draw_text(pdf, x, y, dir, text, arrow)
160
+ if dir == 7 or dir < 6 and dir != 1
161
+ if arrow and (dir == 0 or dir == 4)
162
+ x += 5
163
+ end
164
+ x += 2.5
165
+ elsif dir == 6 or dir == 1
166
+ x -= 7.5
167
+ end
168
+
169
+ if dir > 5 or dir < 4
170
+ if arrow and (dir == 6 or dir == 2)
171
+ y += 5
172
+ end
173
+ y += 2.5
174
+ elsif dir == 4 or dir == 5
175
+ y -= 7.5
176
+ end
177
+
178
+ font_size = 8
179
+ pdf.add_text(x, y, text, font_size)
180
+ end
181
+
182
+ def pdf_draw_exit_text(pdf, opts)
183
+
184
+ if @exitText[0] != 0
185
+ dir = @room[0].exits.index(self)
186
+ x, y = @room[0].pdf_corner(opts, self, dir)
187
+ pdf_draw_text( pdf, x, y, dir,
188
+ EXIT_TEXT[@exitText[0]], @dir == BtoA)
189
+ end
190
+
191
+ if @exitText[1] != 0
192
+ dir = @room[1].exits.rindex(self)
193
+ x, y = @room[1].pdf_corner(opts, self, dir)
194
+ pdf_draw_text( pdf, x, y, dir,
195
+ EXIT_TEXT[@exitText[1]], @dir == AtoB)
196
+ end
197
+ end
198
+
199
+ def pdf_draw(pdf, opts)
200
+ pdf_draw_exit_text(pdf, opts)
201
+ if @type == SPECIAL
202
+ s = PDF::Writer::StrokeStyle.new(2, :dash => {
203
+ :pattern => [2],
204
+ :phase => [1]
205
+ } )
206
+ else
207
+ s = PDF::Writer::StrokeStyle.new(2,
208
+ :cap => :butt,
209
+ :join => :miter,
210
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
211
+ end
212
+ pdf.stroke_style( s )
213
+ pdf.stroke_color Color::RGB::Black
214
+ pdf.fill_color Color::RGB::Black
215
+ if @pts.size > 0
216
+ pdf_draw_complex(pdf, opts)
217
+ else
218
+ pdf_draw_simple(pdf, opts)
219
+ end
220
+ end
221
+ end
222
+
223
+
224
+ class FXRoom
225
+ def pdf_corner( opts, c, idx = nil )
226
+ x, y = _corner(c, idx)
227
+ y = -y
228
+
229
+ ww = opts['ww']
230
+ hh = opts['hh']
231
+ w = opts['w']
232
+ h = opts['h']
233
+
234
+ ry = opts['height'] - @y
235
+ x = @x * ww + opts['ws_2'] + opts['margin_2'] + x * w
236
+ y = ry * hh + opts['hs_2'] + h + opts['margin_2'] + y * h
237
+ return [x, y]
238
+ end
239
+
240
+
241
+ def pdf_draw_box( pdf, opts, idx, pdflocationnos )
242
+ x = @x * opts['ww'] + opts['ws_2'] + opts['margin_2']
243
+ y = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] + opts['margin_2']
244
+
245
+ s = PDF::Writer::StrokeStyle::DEFAULT
246
+ pdf.stroke_style( s )
247
+
248
+ if @darkness
249
+ pdf.fill_color( Color::RGB::Gray )
250
+ else
251
+ pdf.fill_color( Color::RGB::White )
252
+ end
253
+
254
+ pdf.rectangle(x, y, opts['w'], opts['h']).fill_stroke
255
+
256
+ if pdflocationnos == 1
257
+ # PRE: Draw a rectangle for the location number
258
+ pdf.rectangle((x+opts['w']-opts['w']/4), y, opts['w']/4, opts['h']/4).fill_stroke
259
+
260
+ # PRE: Pad out the number so it is three chars long
261
+ locationno = (idx+1).to_s
262
+ if (idx+1) < 10
263
+ locationno = ' '+locationno
264
+ elsif (idx+1) < 100
265
+ locationno = ' '+locationno
266
+ end
267
+
268
+ # PRE: Write the location number
269
+ pdf.fill_color(Color::RGB::Black)
270
+ pdf.add_text((x+((opts['w']/4)*3)+2), y+2, locationno, 8)
271
+ end
272
+
273
+ end
274
+
275
+ def pdf_draw_text( pdf, opts, x, y, text, font_size, pdflocationnos )
276
+ miny = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] +
277
+ opts['margin_2']
278
+ while text != ''
279
+ # PRE: Wrap the text to avoid the location number box
280
+ if (y >= miny) and (y <= (miny+font_size)) and (pdflocationnos == 1)
281
+ wrapwidthmodifier = 15
282
+ else
283
+ wrapwidthmodifier = 2
284
+ end
285
+ text = pdf.add_text_wrap(x, y, opts['w'] - wrapwidthmodifier, text, font_size)
286
+ y -= font_size
287
+ break if y <= miny
288
+ end
289
+ return [x, y]
290
+ end
291
+
292
+ def pdf_draw_objects(pdf, opts, x, y, pdflocationnos)
293
+ font_size = 6
294
+ objs = @objects.split("\n")
295
+ objs = objs.join(', ')
296
+ return pdf_draw_text( pdf, opts, x, y, objs, font_size, pdflocationnos )
297
+ end
298
+
299
+ def pdf_draw_name(pdf, opts, pdflocationnos)
300
+ # We could also use pdf_corner(7) here
301
+ x = @x * opts['ww'] + opts['margin_2'] + opts['ws_2'] + 2
302
+ y = opts['height'] - @y
303
+ font_size = 8
304
+ y = y * opts['hh'] + opts['margin_2'] + opts['hs_2'] + opts['h'] -
305
+ (font_size + 2)
306
+ pdf.stroke_color(Color::RGB::Black)
307
+ pdf.fill_color(Color::RGB::Black)
308
+ return pdf_draw_text( pdf, opts, x, y, @name, font_size, pdflocationnos )
309
+ end
310
+
311
+ # PRE: Send through the index so we can print the location number
312
+ # along with boolean value indicating whether the user wants them
313
+ def pdf_draw( pdf, opts, idx, pdflocationnos )
314
+ pdf_draw_box( pdf, opts, idx, pdflocationnos )
315
+ x, y = pdf_draw_name( pdf, opts, pdflocationnos )
316
+ pdf_draw_objects(pdf, opts, x, y, pdflocationnos)
317
+ end
318
+ end
319
+
320
+
321
+
322
+ class FXSection
323
+
324
+ def pdf_draw_grid(pdf, opts, w, h )
325
+ (0...w).each { |xx|
326
+ (0...h).each { |yy|
327
+ x = xx * opts['ww'] + opts['ws_2'] + opts['margin_2']
328
+ y = yy * opts['hh'] + opts['hs_2'] + opts['margin_2']
329
+ pdf.rectangle(x, y, opts['w'], opts['h']).stroke
330
+ }
331
+ }
332
+ end
333
+
334
+
335
+ def pdf_draw_section_name( pdf, opts, px, py )
336
+ return if not @name or @name == ''
337
+ xymin, xymax = min_max_rooms
338
+ text = @name
339
+ text += " (#{px}, #{py})" if px > 0 or py > 0
340
+ y = (opts['height']) * opts['hh'] + 16
341
+ w = xymax[0]
342
+ w = opts['width'] if w > opts['width']
343
+ x = (w + 2) * opts['ww'] / 2 - text.size / 2 * 16
344
+ x = 0 if x < 0
345
+ pdf.add_text( x, y, text, 16 )
346
+ end
347
+
348
+
349
+ def pdf_draw(pdf, opts, mapname, pdflocationnos )
350
+
351
+
352
+ w, h = rooms_width_height
353
+ x, y = [0, 0]
354
+
355
+ loop do
356
+
357
+ if rotate
358
+ pdf.rotate_axis(90.0)
359
+ pdf.translate_axis( 0, -pdf.page_height )
360
+ end
361
+
362
+ # Move section to its position in page
363
+ tx1, ty1 = [@xoff * opts['ww'], @yoff * -opts['hh']]
364
+ pdf.translate_axis( tx1, ty1 )
365
+
366
+ # Use times-roman as font
367
+ pdf.select_font 'Times-Roman'
368
+ pdf.stroke_color(Color::RGB::Black)
369
+ pdf.fill_color(Color::RGB::Black)
370
+
371
+ pdf_draw_section_name( pdf, opts, x, y )
372
+
373
+ xymin, = min_max_rooms
374
+
375
+ # Move rooms, so that we don't print empty areas
376
+ tx2 = -(xymin[0]) * opts['ww'] - x * opts['ww']
377
+ ty2 = (xymin[1]) * opts['hh'] - 60 + (y - (y > 0? 1 : 0)) * opts['hh']
378
+ pdf.translate_axis( tx2, ty2 )
379
+
380
+
381
+ # For testing purposes only, draw grid of boxes
382
+ # pdf_draw_grid( pdf, opts, w, h )
383
+ @connections.each { |c|
384
+ a = c.roomA
385
+ b = c.roomB
386
+ next if a.y < y and b and b.y < y
387
+ c.pdf_draw( pdf, opts )
388
+ }
389
+ @rooms.each_with_index { |r, idx|
390
+ next if r.y < y
391
+ r.pdf_draw( pdf, opts, idx, pdflocationnos)
392
+ }
393
+
394
+ # Reset axis
395
+ pdf.translate_axis(-tx2, -ty2)
396
+ pdf.translate_axis(-tx1, -ty1)
397
+
398
+ xi = opts['width']
399
+ yi = opts['height']
400
+ if rotate
401
+ xi = (pdf.page_height / opts['ww']).to_i - 1
402
+ yi = (pdf.page_width / opts['hh']).to_i - 1
403
+ end
404
+
405
+ x += xi
406
+ if x >= w
407
+ x = 0
408
+ y += yi
409
+ break if y >= h
410
+ end
411
+
412
+ if rotate
413
+ pdf.rotate_axis(-90.0)
414
+ pdf.translate_axis( 0, pdf.page_height )
415
+ end
416
+
417
+ # We could not fit all rooms in page. Start new page
418
+ pdf.start_new_page
419
+ end
420
+ end
421
+ end
422
+
423
+
424
+ class FXMap
425
+
426
+ attr_accessor :pdfpapersize
427
+ # boolean value indicating whether the user wants to see location nos
428
+ attr_accessor :pdflocationnos
429
+
430
+ def pdf_draw_mapname( pdf, opts )
431
+ return if not @name or @name == ''
432
+ pdf.text( @name,
433
+ :font_size => 24,
434
+ :justification => :center
435
+ )
436
+ end
437
+
438
+ def pdf_draw_sections( pdf, opts )
439
+ old_section = @section
440
+ page = -1
441
+ @sections.each_with_index { |sect, idx|
442
+ if page != sect.page
443
+ page = sect.page
444
+ pdf.start_new_page if page > 1
445
+ pdf_draw_mapname( pdf, opts )
446
+ end
447
+ @section = idx
448
+ # For each page, we need to regenerate the pathmap so that complex
449
+ # paths will come out ok.
450
+ create_pathmap
451
+ # Now, we draw it
452
+ sect.pdf_draw(pdf, opts, @name, pdflocationnos)
453
+ }
454
+
455
+ # Restore original viewing page
456
+ @section = old_section
457
+ create_pathmap
458
+ end
459
+
460
+
461
+ def pdf_export(pdffile = Dir::tmpdir + "/ifmap.pdf", printer = nil)
462
+
463
+ # PRE: Let's set the PDF paper size to user's choice
464
+ paper = BOX_PDF_PAGE_SIZE_TEXT[pdfpapersize]
465
+ if printer
466
+ case printer.mediasize
467
+ when FXPrinter::MEDIA_LETTER
468
+ paper = 'LETTER'
469
+ when FXPrinter::MEDIA_LEGAL
470
+ paper = 'LEGAL'
471
+ when FXPrinter::MEDIA_A4
472
+ paper = 'A4'
473
+ when FXPrinter::MEDIA_ENVELOPE
474
+ paper = 'ENVELOPE'
475
+ when FXPrinter::MEDIA_CUSTOM
476
+ raise "Sorry, custom paper not supported"
477
+ end
478
+ end
479
+
480
+ # Open a new PDF writer with paper selected
481
+ # PRE: Let's also set the paper orientation based on user selection
482
+ pdf = PDF::Writer.new :paper => paper
483
+
484
+ pdf.margins_pt 0
485
+
486
+ pdf_options = @options.dup
487
+
488
+ ww = PDF_ROOM_WIDTH + PDF_ROOM_WS
489
+ hh = PDF_ROOM_HEIGHT + PDF_ROOM_HS
490
+
491
+ pdf_options.merge!(
492
+ {
493
+ 'ww' => ww,
494
+ 'hh' => hh,
495
+ 'w' => PDF_ROOM_WIDTH,
496
+ 'h' => PDF_ROOM_HEIGHT,
497
+ 'ws' => PDF_ROOM_WS,
498
+ 'hs' => PDF_ROOM_HS,
499
+ 'ws_2' => PDF_ROOM_WS / 2.0,
500
+ 'hs_2' => PDF_ROOM_HS / 2.0,
501
+ 'margin' => PDF_MARGIN,
502
+ 'margin_2' => PDF_MARGIN / 2.0,
503
+ 'width' => (pdf.page_width / ww).to_i - 1,
504
+ 'height' => (pdf.page_height / hh).to_i - 1,
505
+ }
506
+ )
507
+
508
+
509
+ begin
510
+ # See if it is possible to pack several map sections (sections) into
511
+ # a single print page.
512
+ num = pack_sections( pdf_options['width'] + 2,
513
+ pdf_options['height'] + 2 )
514
+ pdf_draw_sections(pdf, pdf_options)
515
+ if pdffile !~ /\.pdf$/
516
+ pdffile << ".pdf"
517
+ end
518
+ status "Exporting PDF file '#{pdffile}'"
519
+ pdf.save_as(pdffile)
520
+ rescue => e
521
+ p e
522
+ p e.backtrace
523
+ raise e
524
+ end
525
+ end
526
+ end