ifmapper 2.0.9 → 2.2.4
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/HISTORY.txt +89 -76
- data/IFMapper.gemspec +32 -28
- data/IFMapper.rbw +1 -2
- data/bin/IFMapper +4 -3
- data/docs/en/index.html +45 -24
- data/docs/en/start.html +729 -517
- data/docs/es/start.html +808 -1191
- data/docs/images/svg_export.gif +0 -0
- data/lib/IFMapper/FXMapperSettings.rb +1 -1
- data/lib/IFMapper/FXMapperWindow.rb +211 -217
- data/lib/IFMapper/FXSVGMapExporterOptionsDialogBox.rb +335 -107
- data/lib/IFMapper/IFMWriter.rb +1 -2
- data/lib/IFMapper/Inform7Writer.rb +2 -2
- data/lib/IFMapper/InformWriter.rb +2 -2
- data/lib/IFMapper/MapPrinting.rb +104 -101
- data/lib/IFMapper/PDFMapExporter.rb +2 -521
- data/lib/IFMapper/PDFMapExporter_prawn.rb +132 -103
- data/lib/IFMapper/SVGMapAppend.rb +155 -0
- data/lib/IFMapper/SVGMapExporter.rb +1303 -1091
- data/lib/IFMapper/TADSWriter.rb +4 -3
- data/lib/IFMapper/locales/en/Messages.rb +84 -39
- data/lib/IFMapper/locales/es/Messages.rb +94 -29
- data/lib/IFMapper/locales/es/Messages_iso-8859-1.rb +69 -15
- data/maps/CityOfSecrets.map +0 -0
- metadata +32 -10
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'tmpdir'
|
3
2
|
|
4
3
|
begin
|
@@ -16,12 +15,14 @@ end
|
|
16
15
|
require 'IFMapper/MapPrinting'
|
17
16
|
|
18
17
|
PDF_ZOOM = 0.5
|
19
|
-
PDF_ROOM_WIDTH = W * PDF_ZOOM
|
20
|
-
PDF_ROOM_HEIGHT = H * PDF_ZOOM
|
18
|
+
PDF_ROOM_WIDTH = W * PDF_ZOOM
|
19
|
+
PDF_ROOM_HEIGHT = H * PDF_ZOOM
|
21
20
|
PDF_ROOM_WS = WS * PDF_ZOOM
|
22
21
|
PDF_ROOM_HS = HS * PDF_ZOOM
|
23
22
|
PDF_MARGIN = 20.0
|
24
23
|
|
24
|
+
|
25
|
+
|
25
26
|
#
|
26
27
|
# Open all the map class and add all pdf methods there
|
27
28
|
# Gotta love Ruby's flexibility to just inject in new methods.
|
@@ -37,14 +38,14 @@ class FXConnection
|
|
37
38
|
|
38
39
|
def pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
|
39
40
|
return if @dir == BOTH
|
40
|
-
|
41
|
+
|
41
42
|
pt1, d = _arrow_info( x1, y1, x2, y2, 0.5 )
|
42
|
-
|
43
|
+
|
43
44
|
pdf.stroke_color '000000'
|
44
45
|
pdf.fill_color '000000'
|
45
|
-
pdf.fill_polygon( [ pt1[0], pt1[1] ],
|
46
|
-
[ pt1[0] + d[0], pt1[1] - d[1] ],
|
47
|
-
[ pt1[0] + d[
|
46
|
+
pdf.fill_polygon( [ pt1[0], pt1[1] ],
|
47
|
+
[ pt1[0] + d[0], pt1[1] - d[1] ],
|
48
|
+
[ pt1[0] + d[1], pt1[1] + d[0] ] )
|
48
49
|
end
|
49
50
|
|
50
51
|
def pdf_draw_complex_as_bspline( pdf, opts )
|
@@ -61,11 +62,11 @@ class FXConnection
|
|
61
62
|
return FXSpline::bspline(p)
|
62
63
|
end
|
63
64
|
|
64
|
-
# PRE: If it's a loop exit that comes back to the same place, let's move
|
65
|
+
# PRE: If it's a loop exit that comes back to the same place, let's move
|
65
66
|
# it up and right
|
66
67
|
def pdf_draw_complex_as_lines( pdf, opts )
|
67
68
|
p = []
|
68
|
-
maxy = opts['height'] * opts['hh'] + opts['hs_2'] + opts['margin_2']
|
69
|
+
maxy = opts['height'] * opts['hh'] + opts['hs_2'] + opts['margin_2']
|
69
70
|
@pts.each { |pt|
|
70
71
|
if loop? == true
|
71
72
|
p << [ pt[0] * PDF_ZOOM + 10, maxy - pt[1] * PDF_ZOOM + 48 ]
|
@@ -88,6 +89,7 @@ class FXConnection
|
|
88
89
|
if @type == LOCKED_DOOR
|
89
90
|
pdf.move_to(x1, y1)
|
90
91
|
pdf.line_to(x2, y2)
|
92
|
+
pdf.stroke
|
91
93
|
else
|
92
94
|
pdf.cap_style = :butt
|
93
95
|
pdf.join_style = :miter
|
@@ -99,6 +101,7 @@ class FXConnection
|
|
99
101
|
pdf.line_to(x2 + v[0], y2 + v[1])
|
100
102
|
pdf.line_to(x2 - v[0], y2 - v[1])
|
101
103
|
pdf.line_to(x1 - v[0], y1 - v[1])
|
104
|
+
pdf.stroke
|
102
105
|
|
103
106
|
pdf.cap_style = :butt
|
104
107
|
pdf.join_style = :miter
|
@@ -107,27 +110,24 @@ class FXConnection
|
|
107
110
|
end
|
108
111
|
|
109
112
|
def pdf_draw_complex( pdf, opts )
|
110
|
-
pdf.stroke_color '000000'
|
111
|
-
pdf.fill_color '000000'
|
112
113
|
if opts['Paths as Curves']
|
113
114
|
if @room[0] == @room[1]
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
dirA, dirB = dirs
|
116
|
+
if dirA == dirB
|
117
|
+
p = pdf_draw_complex_as_lines( pdf, opts )
|
118
|
+
else
|
119
|
+
p = pdf_draw_complex_as_bspline( pdf, opts )
|
120
|
+
end
|
120
121
|
else
|
121
|
-
|
122
|
+
p = pdf_draw_complex_as_bspline( pdf, opts )
|
122
123
|
end
|
123
124
|
else
|
124
125
|
p = pdf_draw_complex_as_lines( pdf, opts )
|
125
126
|
end
|
126
|
-
|
127
|
-
pdf.stroke_color '000000'
|
128
|
-
pdf.fill_color '000000'
|
127
|
+
|
129
128
|
pdf.move_to( p[0][0], p[0][1] )
|
130
129
|
p.each { |pt| pdf.line_to( pt[0], pt[1] ) }
|
130
|
+
pdf.stroke
|
131
131
|
|
132
132
|
x1, y1 = [p[0][0], p[0][1]]
|
133
133
|
x2, y2 = [p[-1][0], p[-1][1]]
|
@@ -147,10 +147,9 @@ class FXConnection
|
|
147
147
|
dir = @room[0].exits.index(self)
|
148
148
|
x1, y1 = @room[0].pdf_corner(opts, self, dir)
|
149
149
|
x2, y2 = @room[1].pdf_corner(opts, self)
|
150
|
-
pdf.stroke_color '000000'
|
151
|
-
pdf.fill_color '000000'
|
152
150
|
pdf.move_to(x1, y1)
|
153
151
|
pdf.line_to(x2, y2)
|
152
|
+
pdf.stroke
|
154
153
|
pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
|
155
154
|
if @type == LOCKED_DOOR or @type == CLOSED_DOOR
|
156
155
|
pdf_draw_door(pdf, x1, y1, x2, y2)
|
@@ -163,22 +162,22 @@ class FXConnection
|
|
163
162
|
def pdf_draw_text(pdf, x, y, dir, text, arrow)
|
164
163
|
if dir == 7 or dir < 6 and dir != 1
|
165
164
|
if arrow and (dir == 0 or dir == 4)
|
166
|
-
|
165
|
+
x += 5
|
167
166
|
end
|
168
167
|
x += 2.5
|
169
168
|
elsif dir == 6 or dir == 1
|
170
169
|
x -= 7.5
|
171
170
|
end
|
172
|
-
|
171
|
+
|
173
172
|
if dir > 5 or dir < 4
|
174
173
|
if arrow and (dir == 6 or dir == 2)
|
175
|
-
|
174
|
+
y += 5
|
176
175
|
end
|
177
176
|
y += 2.5
|
178
177
|
elsif dir == 4 or dir == 5
|
179
178
|
y -= 7.5
|
180
179
|
end
|
181
|
-
|
180
|
+
|
182
181
|
font_size = 8
|
183
182
|
pdf.text_box text, :at => [x, y], :size => font_size
|
184
183
|
end
|
@@ -189,20 +188,24 @@ class FXConnection
|
|
189
188
|
dir = @room[0].exits.index(self)
|
190
189
|
x, y = @room[0].pdf_corner(opts, self, dir)
|
191
190
|
pdf.move_to(x, y)
|
192
|
-
|
191
|
+
# WAS: y+4 below
|
192
|
+
pdf_draw_text( pdf, x, y, dir,
|
193
193
|
EXIT_TEXT[@exitText[0]], @dir == BtoA)
|
194
194
|
end
|
195
195
|
|
196
196
|
if @exitText[1] != 0
|
197
197
|
dir = @room[1].exits.rindex(self)
|
198
198
|
x, y = @room[1].pdf_corner(opts, self, dir)
|
199
|
-
|
200
|
-
|
199
|
+
# WAS: y+4 below
|
200
|
+
pdf_draw_text( pdf, x, y, dir,
|
201
|
+
EXIT_TEXT[@exitText[1]], @dir == AtoB)
|
201
202
|
end
|
202
203
|
end
|
203
204
|
|
204
205
|
def pdf_draw(pdf, opts)
|
205
206
|
pdf_draw_exit_text(pdf, opts)
|
207
|
+
pdf.stroke_color '000000'
|
208
|
+
pdf.fill_color '000000'
|
206
209
|
if @type == SPECIAL
|
207
210
|
pdf.dash 4
|
208
211
|
else
|
@@ -210,8 +213,6 @@ class FXConnection
|
|
210
213
|
pdf.join_style = :miter
|
211
214
|
pdf.undash
|
212
215
|
end
|
213
|
-
pdf.stroke_color '000000'
|
214
|
-
pdf.fill_color '000000'
|
215
216
|
if @pts.size > 0
|
216
217
|
pdf_draw_complex(pdf, opts)
|
217
218
|
else
|
@@ -245,10 +246,12 @@ class FXRoom
|
|
245
246
|
pdf.cap_style = :butt
|
246
247
|
pdf.join_style = :miter
|
247
248
|
pdf.line_width 1
|
249
|
+
pdf.undash
|
248
250
|
|
249
251
|
if @darkness
|
250
252
|
pdf.fill_color '808080'
|
251
253
|
pdf.stroke_color '000000'
|
254
|
+
pdf.fill_rectangle [x, y], opts['w'], -opts['h']
|
252
255
|
else
|
253
256
|
pdf.fill_color 'ffffff'
|
254
257
|
pdf.stroke_color '000000'
|
@@ -256,11 +259,12 @@ class FXRoom
|
|
256
259
|
|
257
260
|
pdf.stroke_rectangle [x, y], opts['w'], -opts['h']
|
258
261
|
|
262
|
+
|
259
263
|
if pdflocationnos == 1
|
260
264
|
# PRE: Draw a rectangle for the location number
|
261
|
-
pdf.stroke_rectangle( [x+opts['w']-opts['w']/4, y],
|
265
|
+
pdf.stroke_rectangle( [x+opts['w']-opts['w']/4, y],
|
262
266
|
opts['w']/4, -opts['h']/4 )
|
263
|
-
|
267
|
+
|
264
268
|
# PRE: Pad out the number so it is three chars long
|
265
269
|
locationno = (idx+1).to_s
|
266
270
|
if (idx+1) < 10
|
@@ -273,18 +277,31 @@ class FXRoom
|
|
273
277
|
pdf.stroke_color '000000'
|
274
278
|
pdf.fill_color '000000'
|
275
279
|
|
276
|
-
|
277
|
-
|
280
|
+
# WAS: y+7
|
281
|
+
pdf.text_box locationno,
|
282
|
+
:at => [(x+((opts['w']/4)*3)+2), y+2], :size => 8
|
278
283
|
end
|
279
|
-
|
284
|
+
|
280
285
|
end
|
281
286
|
|
282
287
|
def pdf_draw_text( pdf, opts, x, y, text, font_size, pdflocationnos )
|
283
|
-
miny = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] +
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
+
miny = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] +
|
289
|
+
opts['margin_2']
|
290
|
+
while text != ''
|
291
|
+
# PRE: Wrap the text to avoid the location number box
|
292
|
+
if (y >= miny) and (y <= (miny+font_size)) and (pdflocationnos == 1)
|
293
|
+
wrapwidthmodifier = 15
|
294
|
+
else
|
295
|
+
wrapwidthmodifier = 2
|
296
|
+
end
|
297
|
+
text = pdf.text_box text, :at => [x, y+6], :size => font_size,
|
298
|
+
:width => opts['w'] - wrapwidthmodifier,
|
299
|
+
:height => opts['h'], :valign => :top,
|
300
|
+
:align => :left, :overflow => :shrink_to_fit
|
301
|
+
y -= font_size
|
302
|
+
break if y <= miny
|
303
|
+
end
|
304
|
+
|
288
305
|
return [x, y]
|
289
306
|
end
|
290
307
|
|
@@ -292,7 +309,7 @@ class FXRoom
|
|
292
309
|
font_size = 6
|
293
310
|
objs = @objects.split("\n")
|
294
311
|
objs = objs.join(', ')
|
295
|
-
return pdf_draw_text( pdf, opts, x, y
|
312
|
+
return pdf_draw_text( pdf, opts, x, y,
|
296
313
|
objs, font_size, pdflocationnos )
|
297
314
|
end
|
298
315
|
|
@@ -301,7 +318,7 @@ class FXRoom
|
|
301
318
|
x = @x * opts['ww'] + opts['margin_2'] + opts['ws_2'] + 2
|
302
319
|
y = opts['height'] - @y
|
303
320
|
font_size = 8
|
304
|
-
y = y * opts['hh'] + opts['margin_2'] + opts['hs_2'] + opts['h'] -
|
321
|
+
y = y * opts['hh'] + opts['margin_2'] + opts['hs_2'] + opts['h'] -
|
305
322
|
(font_size + 2)
|
306
323
|
pdf.stroke_color '000000'
|
307
324
|
pdf.fill_color '000000'
|
@@ -324,9 +341,9 @@ class FXSection
|
|
324
341
|
def pdf_draw_grid(pdf, opts, w, h )
|
325
342
|
(0...w).each { |xx|
|
326
343
|
(0...h).each { |yy|
|
327
|
-
|
328
|
-
|
329
|
-
|
344
|
+
x = xx * opts['ww'] + opts['ws_2'] + opts['margin_2']
|
345
|
+
y = yy * opts['hh'] + opts['hs_2'] + opts['margin_2']
|
346
|
+
pdf.rectangle([x, y], opts['w'], opts['h'])
|
330
347
|
}
|
331
348
|
}
|
332
349
|
end
|
@@ -357,8 +374,8 @@ class FXSection
|
|
357
374
|
pdf.save_graphics_state
|
358
375
|
|
359
376
|
if rotate
|
360
|
-
|
361
|
-
|
377
|
+
pdf.rotate 90.0
|
378
|
+
pdf.translate( 0, -pdf.margin_box.height )
|
362
379
|
end
|
363
380
|
|
364
381
|
# Move section to its position in page
|
@@ -377,42 +394,42 @@ class FXSection
|
|
377
394
|
tx2 = -(xymin[0]) * opts['ww'] - x * opts['ww']
|
378
395
|
ty2 = (xymin[1]) * opts['hh'] - 60 + (y - (y > 0? 1 : 0)) * opts['hh']
|
379
396
|
pdf.translate( tx2, ty2 )
|
380
|
-
|
381
|
-
|
397
|
+
|
398
|
+
|
382
399
|
# For testing purposes only, draw grid of boxes
|
383
400
|
# pdf_draw_grid( pdf, opts, w, h )
|
384
|
-
@connections.each { |c|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
401
|
+
@connections.each { |c|
|
402
|
+
a = c.roomA
|
403
|
+
b = c.roomB
|
404
|
+
next if a.y < y and b and b.y < y
|
405
|
+
c.pdf_draw( pdf, opts )
|
389
406
|
}
|
390
|
-
@rooms.each_with_index { |r, idx|
|
391
|
-
|
392
|
-
|
407
|
+
@rooms.each_with_index { |r, idx|
|
408
|
+
next if r.y < y
|
409
|
+
r.pdf_draw( pdf, opts, idx, pdflocationnos)
|
393
410
|
}
|
394
|
-
|
411
|
+
|
395
412
|
# Reset axis
|
396
413
|
pdf.translate(-tx2, -ty2)
|
397
414
|
pdf.translate(-tx1, -ty1)
|
398
|
-
|
415
|
+
|
399
416
|
xi = opts['width']
|
400
417
|
yi = opts['height']
|
401
418
|
if rotate
|
402
|
-
|
403
|
-
|
419
|
+
xi = (pdf.margin_box.height / opts['ww']).to_i - 1
|
420
|
+
yi = (pdf.margin_box.width / opts['hh']).to_i - 1
|
404
421
|
end
|
405
422
|
|
406
423
|
x += xi
|
407
424
|
if x >= w
|
408
|
-
|
409
|
-
|
410
|
-
|
425
|
+
x = 0
|
426
|
+
y += yi
|
427
|
+
break if y >= h
|
411
428
|
end
|
412
429
|
|
413
430
|
if rotate
|
414
|
-
|
415
|
-
|
431
|
+
pdf.rotate(-90.0)
|
432
|
+
pdf.translate( 0, pdf.page_height )
|
416
433
|
end
|
417
434
|
|
418
435
|
pdf.restore_graphics_state
|
@@ -429,13 +446,13 @@ class FXMap
|
|
429
446
|
attr_accessor :pdfpapersize
|
430
447
|
# boolean value indicating whether the user wants to see location nos
|
431
448
|
attr_accessor :pdflocationnos
|
432
|
-
|
449
|
+
|
433
450
|
def pdf_draw_mapname( pdf, opts )
|
434
451
|
return if not @name or @name == ''
|
435
452
|
pdf.text( @name,
|
436
|
-
|
437
|
-
|
438
|
-
|
453
|
+
:font_size => 24,
|
454
|
+
:justification => :center
|
455
|
+
)
|
439
456
|
end
|
440
457
|
|
441
458
|
def pdf_draw_sections( pdf, opts )
|
@@ -443,9 +460,9 @@ class FXMap
|
|
443
460
|
page = -1
|
444
461
|
@sections.each_with_index { |sect, idx|
|
445
462
|
if page != sect.page
|
446
|
-
|
447
|
-
|
448
|
-
|
463
|
+
page = sect.page
|
464
|
+
pdf.start_new_page if page > 1
|
465
|
+
pdf_draw_mapname( pdf, opts )
|
449
466
|
end
|
450
467
|
@section = idx
|
451
468
|
# For each page, we need to regenerate the pathmap so that complex
|
@@ -462,27 +479,26 @@ class FXMap
|
|
462
479
|
|
463
480
|
|
464
481
|
def pdf_export(pdffile = Dir::tmpdir + "/ifmap.pdf", printer = nil)
|
465
|
-
|
482
|
+
|
466
483
|
# PRE: Let's set the PDF paper size to user's choice
|
467
484
|
paper = BOX_PDF_PAGE_SIZE_TEXT[pdfpapersize]
|
468
485
|
if printer
|
469
486
|
case printer.mediasize
|
470
487
|
when FXPrinter::MEDIA_LETTER
|
471
|
-
|
488
|
+
paper = 'LETTER'
|
472
489
|
when FXPrinter::MEDIA_LEGAL
|
473
|
-
|
490
|
+
paper = 'LEGAL'
|
474
491
|
when FXPrinter::MEDIA_A4
|
475
|
-
|
492
|
+
paper = 'A4'
|
476
493
|
when FXPrinter::MEDIA_ENVELOPE
|
477
|
-
|
494
|
+
paper = 'ENVELOPE'
|
478
495
|
when FXPrinter::MEDIA_CUSTOM
|
479
|
-
|
496
|
+
raise "Sorry, custom paper not supported"
|
480
497
|
end
|
481
498
|
end
|
482
499
|
|
483
500
|
# Open a new PDF writer with paper selected
|
484
|
-
|
485
|
-
|
501
|
+
|
486
502
|
pdf = Prawn::Document.new :page_size => paper
|
487
503
|
|
488
504
|
pdf_options = @options.dup
|
@@ -490,32 +506,45 @@ class FXMap
|
|
490
506
|
ww = PDF_ROOM_WIDTH + PDF_ROOM_WS
|
491
507
|
hh = PDF_ROOM_HEIGHT + PDF_ROOM_HS
|
492
508
|
|
493
|
-
pdf_options.merge!(
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
+
pdf_options.merge!(
|
510
|
+
{
|
511
|
+
'ww' => ww,
|
512
|
+
'hh' => hh,
|
513
|
+
'w' => PDF_ROOM_WIDTH,
|
514
|
+
'h' => PDF_ROOM_HEIGHT,
|
515
|
+
'ws' => PDF_ROOM_WS,
|
516
|
+
'hs' => PDF_ROOM_HS,
|
517
|
+
'ws_2' => PDF_ROOM_WS / 2.0,
|
518
|
+
'hs_2' => PDF_ROOM_HS / 2.0,
|
519
|
+
'margin' => PDF_MARGIN,
|
520
|
+
'margin_2' => PDF_MARGIN / 2.0,
|
521
|
+
'width' => (pdf.margin_box.width / ww).to_i - 1,
|
522
|
+
'height' => (pdf.margin_box.height / hh).to_i - 1,
|
523
|
+
}
|
524
|
+
)
|
509
525
|
|
510
526
|
|
511
527
|
begin
|
528
|
+
ratio = pdf.margin_box.height / pdf.margin_box.width.to_f;
|
512
529
|
# See if it is possible to pack several map sections (sections) into
|
513
530
|
# a single print page.
|
514
|
-
|
515
|
-
|
531
|
+
loop do
|
532
|
+
|
533
|
+
num = pack_sections( pdf_options['width'],
|
534
|
+
pdf_options['height'] )
|
535
|
+
|
536
|
+
if num > 0
|
537
|
+
break
|
538
|
+
end
|
539
|
+
|
540
|
+
width += 1
|
541
|
+
height = (width * ratio).to_i + 1;
|
542
|
+
end
|
543
|
+
|
544
|
+
|
516
545
|
pdf_draw_sections(pdf, pdf_options)
|
517
546
|
if pdffile !~ /\.pdf$/
|
518
|
-
|
547
|
+
pdffile << ".pdf"
|
519
548
|
end
|
520
549
|
status "Exporting PDF file '#{pdffile}'"
|
521
550
|
pdf.render_file pdffile
|