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
data/lib/IFMapper/IFMWriter.rb
CHANGED
@@ -72,8 +72,7 @@ class IFMWriter
|
|
72
72
|
|
73
73
|
tag = t.dup
|
74
74
|
|
75
|
-
|
76
|
-
if (version <=> [1,9,0]) < 0
|
75
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
|
77
76
|
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
78
77
|
tag = utf.iconv( tag )
|
79
78
|
else
|
@@ -211,7 +211,7 @@ class Inform7Writer
|
|
211
211
|
tag = str.dup
|
212
212
|
|
213
213
|
# Take text from Unicode utf-8 to iso-8859-1
|
214
|
-
if RUBY_VERSION < 1.9
|
214
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
|
215
215
|
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
216
216
|
tag = utf.iconv( tag )
|
217
217
|
else
|
@@ -322,7 +322,7 @@ class Inform7Writer
|
|
322
322
|
str = text.dup
|
323
323
|
|
324
324
|
# Take text from Unicode utf-8 to iso-8859-1859-1
|
325
|
-
if RUBY_VERSION < 1.9
|
325
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
|
326
326
|
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
327
327
|
str = utf.iconv( str )
|
328
328
|
else
|
@@ -35,7 +35,7 @@ class InformWriter
|
|
35
35
|
|
36
36
|
def new_tag(elem, str)
|
37
37
|
tag = str.dup
|
38
|
-
if RUBY_VERSION < 1.9
|
38
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
|
39
39
|
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
40
40
|
tag = utf.iconv( tag )
|
41
41
|
else
|
@@ -112,7 +112,7 @@ class InformWriter
|
|
112
112
|
str = text.dup
|
113
113
|
|
114
114
|
# Take text from Unicode utf-8 to iso-8859-1
|
115
|
-
if RUBY_VERSION < 1.9
|
115
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
|
116
116
|
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
117
117
|
str = utf.iconv( str )
|
118
118
|
else
|
data/lib/IFMapper/MapPrinting.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# Default constants
|
2
|
+
FIG_NONE = false
|
3
|
+
FIG_PORTRAIT = :portrait
|
4
|
+
FIG_LANDSCAPE = :landscape
|
1
5
|
|
2
6
|
# Common printing add-ons
|
3
7
|
class FXSection
|
@@ -14,7 +18,7 @@ class Page
|
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
17
|
-
class Map
|
21
|
+
class Map
|
18
22
|
#
|
19
23
|
# This code section is largely a copy of similar code used in
|
20
24
|
# IFM's C code.
|
@@ -31,8 +35,8 @@ class Map
|
|
31
35
|
sect.yoff = 0.0
|
32
36
|
|
33
37
|
page = Page.new(xlen+2, ylen+2)
|
34
|
-
pages.push page
|
35
38
|
page.sections << sect
|
39
|
+
pages << page
|
36
40
|
}
|
37
41
|
|
38
42
|
ratio = xmax.to_f / ymax
|
@@ -42,100 +46,100 @@ class Map
|
|
42
46
|
newpages = []
|
43
47
|
pos = packed = 0
|
44
48
|
while pos < pages.size
|
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
|
-
|
49
|
+
p1 = pages[pos]
|
50
|
+
x1 = p1.xlen
|
51
|
+
y1 = p1.ylen
|
52
|
+
|
53
|
+
# Check if it's better off rotated
|
54
|
+
p1.rotate = ((x1 < y1 and xmax > ymax) or
|
55
|
+
(x1 > y1 and xmax < ymax))
|
56
|
+
|
57
|
+
# Check if this is the last page
|
58
|
+
if pos + 1 == pages.size
|
59
|
+
newpages.push p1
|
60
|
+
break
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get following page
|
64
|
+
p2 = pages[pos+1]
|
65
|
+
x2 = p2.xlen
|
66
|
+
y2 = p2.ylen
|
67
|
+
|
68
|
+
# Try combining pages in X direction
|
69
|
+
xc1 = x1 + x2 + spacing
|
70
|
+
yc1 = [y1, y2].max
|
71
|
+
v1 = (xc1 <= xmax and yc1 <= ymax)
|
72
|
+
r1 = xc1.to_f / yc1
|
73
|
+
|
74
|
+
# Try combining pages in Y direction
|
75
|
+
xc2 = [x1, x2].max
|
76
|
+
yc2 = y1 + y2 + spacing
|
77
|
+
v2 = (xc2 <= xmax and yc2 <= ymax)
|
78
|
+
r2 = xc2.to_f / yc2
|
79
|
+
|
80
|
+
# See which is best
|
81
|
+
if v1 and v2
|
82
|
+
if (ratio - r1).abs < (ratio - r2).abs
|
83
|
+
v2 = false
|
84
|
+
else
|
85
|
+
v1 = false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Just copy page if nothing can be done
|
90
|
+
if not v1 and not v2
|
91
|
+
newpages.push(p1)
|
92
|
+
pos += 1
|
93
|
+
next
|
94
|
+
end
|
95
|
+
|
96
|
+
# Create merged page
|
97
|
+
page = Page.new
|
98
|
+
xo1 = yo1 = xo2 = yo2 = 0
|
99
|
+
|
100
|
+
if v1
|
101
|
+
page.xlen = xc1
|
102
|
+
page.ylen = yc1
|
103
|
+
xo2 = x1 + spacing
|
104
|
+
|
105
|
+
if y1 < y2
|
106
|
+
yo1 = (yc1 - y1) / 2
|
107
|
+
else
|
108
|
+
yo2 = (yc1 - y2) / 2
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
if v2
|
113
|
+
page.xlen = xc2
|
114
|
+
page.ylen = yc2
|
115
|
+
yo1 = y2 + spacing
|
116
|
+
|
117
|
+
if x1 < x2
|
118
|
+
xo1 = (xc2 - x1) / 2
|
119
|
+
else
|
120
|
+
xo2 = (xc2 - x2) / 2
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Copy sections to new page, updating offsets
|
125
|
+
opsects = p1.sections
|
126
|
+
opsects.each { |sect|
|
127
|
+
page.sections.push sect
|
128
|
+
sect.xoff += xo1
|
129
|
+
sect.yoff += yo1
|
130
|
+
}
|
131
|
+
|
132
|
+
opsects = p2.sections
|
133
|
+
opsects.each { |sect|
|
134
|
+
page.sections.push sect
|
135
|
+
sect.xoff += xo2
|
136
|
+
sect.yoff += yo2
|
137
|
+
}
|
138
|
+
|
139
|
+
# Add merged page to list and go to next page pair
|
140
|
+
newpages.push page
|
141
|
+
pos += 2
|
142
|
+
packed += 1
|
139
143
|
end
|
140
144
|
pages = newpages
|
141
145
|
end
|
@@ -150,13 +154,12 @@ class Map
|
|
150
154
|
|
151
155
|
num += 1
|
152
156
|
psects.each { |sect|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
+
sect.page = num
|
158
|
+
sect.pxlen = xlen
|
159
|
+
sect.pylen = ylen
|
160
|
+
sect.rotate = rflag
|
157
161
|
}
|
158
162
|
}
|
159
163
|
return num
|
160
164
|
end
|
161
165
|
end
|
162
|
-
|
@@ -1,526 +1,7 @@
|
|
1
|
-
|
2
1
|
require 'tmpdir'
|
3
2
|
|
4
3
|
begin
|
5
|
-
require '
|
4
|
+
require 'IFMapper/PDFMapExporter_pdfwriter'
|
6
5
|
rescue LoadError => e
|
7
|
-
|
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
|
6
|
+
raise LoadError, e
|
526
7
|
end
|