ifmapper 1.0.0 → 1.0.6

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.
Files changed (218) hide show
  1. data/HISTORY.txt +648 -627
  2. data/IFMapper.gemspec +29 -28
  3. data/IFMapper.rbw +31 -31
  4. data/TODO.txt +8 -7
  5. data/bin/IFMapper +31 -31
  6. data/docs/en/index.html +0 -0
  7. data/docs/en/start.html +3 -2
  8. data/docs/en/start.html~ +516 -0
  9. data/docs/es/index.html +0 -0
  10. data/docs/es/start.html +13 -14
  11. data/docs/es/start.html~ +1280 -0
  12. data/docs/images/IFMapper_main.gif +0 -0
  13. data/docs/images/automap.gif +0 -0
  14. data/docs/images/complex_connection.gif +0 -0
  15. data/docs/images/connection.gif +0 -0
  16. data/docs/images/connection_menu.gif +0 -0
  17. data/docs/images/room_description.gif +0 -0
  18. data/docs/images/room_small.gif +0 -0
  19. data/icons/copy.png +0 -0
  20. data/icons/cut.png +0 -0
  21. data/icons/filenew.png +0 -0
  22. data/icons/fileopen.png +0 -0
  23. data/icons/filesave.png +0 -0
  24. data/icons/filesaveas.png +0 -0
  25. data/icons/help.png +0 -0
  26. data/icons/kill.png +0 -0
  27. data/icons/nextpage.png +0 -0
  28. data/icons/paste.png +0 -0
  29. data/icons/prevpage.png +0 -0
  30. data/icons/printicon.png +0 -0
  31. data/icons/redo.png +0 -0
  32. data/icons/room_e.gif +0 -0
  33. data/icons/room_e.xpm +0 -0
  34. data/icons/room_n.gif +0 -0
  35. data/icons/room_n.xpm +0 -0
  36. data/icons/room_ne.gif +0 -0
  37. data/icons/room_ne.xpm +0 -0
  38. data/icons/room_nw.gif +0 -0
  39. data/icons/room_nw.xpm +0 -0
  40. data/icons/room_s.gif +0 -0
  41. data/icons/room_s.xpm +0 -0
  42. data/icons/room_se.gif +0 -0
  43. data/icons/room_se.xpm +0 -0
  44. data/icons/room_sw.gif +0 -0
  45. data/icons/room_sw.xpm +0 -0
  46. data/icons/room_w.gif +0 -0
  47. data/icons/room_w.xpm +0 -0
  48. data/icons/saveas.png +0 -0
  49. data/icons/undo.png +0 -0
  50. data/icons/winapp.png +0 -0
  51. data/icons/zoom.png +0 -0
  52. data/lib/IFMapper/AStar.rb +250 -250
  53. data/lib/IFMapper/Connection.rb +202 -202
  54. data/lib/IFMapper/FXAboutDialogBox.rb +32 -32
  55. data/lib/IFMapper/FXConnection.rb +364 -364
  56. data/lib/IFMapper/FXConnectionDialogBox.rb +124 -124
  57. data/lib/IFMapper/FXDCPostscript.rb +404 -404
  58. data/lib/IFMapper/FXDCPrint.rb +15 -15
  59. data/lib/IFMapper/FXItemList.rb +108 -0
  60. data/lib/IFMapper/FXMap.rb +2147 -2116
  61. data/lib/IFMapper/FXMapColorBox.rb +88 -88
  62. data/lib/IFMapper/FXMapDialogBox.rb +127 -127
  63. data/lib/IFMapper/FXMapFileDialog.rb +34 -34
  64. data/lib/IFMapper/FXMapperSettings.rb +206 -205
  65. data/lib/IFMapper/FXMapperWindow.rb +1592 -1571
  66. data/lib/IFMapper/FXPDFMapExporterOptionsDialogBox.rb +46 -0
  67. data/lib/IFMapper/FXRoom.rb +263 -263
  68. data/lib/IFMapper/FXRoomDialogBox.rb +159 -159
  69. data/lib/IFMapper/FXRoomList.rb +95 -95
  70. data/lib/IFMapper/FXSearchDialogBox.rb +51 -51
  71. data/lib/IFMapper/FXSection.rb +33 -33
  72. data/lib/IFMapper/FXSectionDialogBox.rb +38 -38
  73. data/lib/IFMapper/FXSpline.rb +52 -52
  74. data/lib/IFMapper/FXWarningBox.rb +51 -50
  75. data/lib/IFMapper/GUEReader.rb +445 -445
  76. data/lib/IFMapper/IFMReader.rb +584 -584
  77. data/lib/IFMapper/IFMWriter.rb +245 -227
  78. data/lib/IFMapper/Inform7Writer.rb +579 -573
  79. data/lib/IFMapper/InformReader.rb +478 -478
  80. data/lib/IFMapper/InformWriter.rb +364 -359
  81. data/lib/IFMapper/Map.rb +202 -200
  82. data/lib/IFMapper/MapPrinting.rb +162 -162
  83. data/lib/IFMapper/MapReader.rb +900 -900
  84. data/lib/IFMapper/PDFMapExporter.rb +526 -483
  85. data/lib/IFMapper/Room.rb +153 -151
  86. data/lib/IFMapper/Section.rb +234 -234
  87. data/lib/IFMapper/TADSReader.rb +474 -471
  88. data/lib/IFMapper/TADSWriter.rb +375 -370
  89. data/lib/IFMapper/TranscriptDialogBox.rb +0 -0
  90. data/lib/IFMapper/TranscriptReader.rb +1361 -1359
  91. data/lib/IFMapper/locales/en/Messages.rb +446 -435
  92. data/lib/IFMapper/locales/es/Messages.rb +451 -440
  93. data/lib/IFMapper/locales/es/Messages_iso-8859-1.rb +455 -440
  94. data/lib/IFMapper/locales/es/runme.sh +3 -3
  95. data/maps/A New Life.map b/data/maps/A New → Life.map +0 -0
  96. data/maps/AMFV.map +0 -0
  97. data/maps/AllRoads.map +0 -0
  98. data/maps/Aotearoa.map +0 -0
  99. data/maps/Bronze.map +0 -0
  100. data/maps/Bureaucracy.ifm +0 -0
  101. data/maps/Bureaucracy.map +0 -0
  102. data/maps/CityOfSecrets.map +0 -0
  103. data/maps/DDIV.map +0 -0
  104. data/maps/Following_A_Star.map +0 -0
  105. data/maps/Heated.map +0 -0
  106. data/maps/Heroine.map +0 -0
  107. data/maps/History Repeating.map b/data/maps/History → Repeating.map +0 -0
  108. data/maps/Hollywood_Hijinx.ifm +0 -0
  109. data/maps/Janitor.map +0 -0
  110. data/maps/Jigsaw.ifm +0 -0
  111. data/maps/Jigsaw.map +0 -0
  112. data/maps/LGOP.ifm +0 -0
  113. data/maps/Mercy.ifm +0 -0
  114. data/maps/Ninjas_Fate.map +0 -0
  115. data/maps/Pen_and_Paint.map +0 -0
  116. data/maps/Planetfall.ifm +0 -0
  117. data/maps/Planetfall.map +0 -0
  118. data/maps/Plundered_Hearts.ifm +0 -0
  119. data/maps/QuietEvening.map +0 -0
  120. data/maps/Ralph.ifm +0 -0
  121. data/maps/Reliques_of_Tolti_Alph.map +0 -0
  122. data/maps/Revolution.map +0 -0
  123. data/maps/Robots_of_Dawn.ifm +0 -0
  124. data/maps/SavoirFare.map +0 -0
  125. data/maps/Seastalker.ifm +0 -0
  126. data/maps/Seastalker.map +0 -0
  127. data/maps/Sherlock.ifm +0 -0
  128. data/maps/SoFar.ifm +0 -0
  129. data/maps/Starcross.ifm +0 -0
  130. data/maps/Suspended.ifm +0 -0
  131. data/maps/Tangle.map +0 -0
  132. data/maps/The_Lost_Sheep.map +0 -0
  133. data/maps/Unforgotten.map +0 -0
  134. data/maps/Warbler's Nest.map +0 -0
  135. data/maps/Warbler's_Nest.map +0 -0
  136. data/maps/Westminster_Abbey.map +0 -0
  137. data/maps/WinterWonderland.map +0 -0
  138. data/maps/Wishbringer.ifm +0 -0
  139. data/maps/Wishbringer2.ifm +0 -0
  140. data/maps/Zork1.ifm +0 -0
  141. data/maps/Zork2.ifm +0 -0
  142. data/maps/Zork3.ifm +0 -0
  143. data/maps/Zork_Zero.ifm +0 -0
  144. data/maps/anchor.ifm +0 -0
  145. data/maps/anchor.map +0 -0
  146. data/maps/atrox.ifm +0 -0
  147. data/maps/awaken.ifm +0 -0
  148. data/maps/babel.ifm +0 -0
  149. data/maps/balances.map +0 -0
  150. data/maps/ballerina.map +0 -0
  151. data/maps/bear.map +0 -0
  152. data/maps/bluechairs.map +0 -0
  153. data/maps/break_in.map +0 -0
  154. data/maps/bse.ifm +0 -0
  155. data/maps/building.map +0 -0
  156. data/maps/change.ifm +0 -0
  157. data/maps/christminster.map +0 -0
  158. data/maps/curses.ifm +0 -0
  159. data/maps/curves.ifm +0 -0
  160. data/maps/deadline.map +0 -0
  161. data/maps/delusions.map +0 -0
  162. data/maps/devours.map +0 -0
  163. data/maps/distress.map +0 -0
  164. data/maps/djinni.map +0 -0
  165. data/maps/dreamhold.map +0 -0
  166. data/maps/drift3.map +0 -0
  167. data/maps/eas.map +0 -0
  168. data/maps/eas2.map +0 -0
  169. data/maps/eas3.map +0 -0
  170. data/maps/edifice.ifm +0 -0
  171. data/maps/fallacy.map +0 -0
  172. data/maps/frozen.ifm +0 -0
  173. data/maps/gamlet.map +0 -0
  174. data/maps/glow.ifm +0 -0
  175. data/maps/guilty_bastards.map +0 -0
  176. data/maps/heist.map +0 -0
  177. data/maps/heroes.map +0 -0
  178. data/maps/inhumane.map +0 -0
  179. data/maps/kaged.map +0 -0
  180. data/maps/library.ifm +0 -0
  181. data/maps/lurkinghorror.map +0 -0
  182. data/maps/metamorphoses.map +0 -0
  183. data/maps/mindelec.ifm +0 -0
  184. data/maps/minster.ifm +0 -0
  185. data/maps/mite.map +0 -0
  186. data/maps/moonmist.map +0 -0
  187. data/maps/muldoon_legacy.map +0 -0
  188. data/maps/muse.ifm +0 -0
  189. data/maps/paperchase.ifm +0 -0
  190. data/maps/party.map +0 -0
  191. data/maps/pawn.map +0 -0
  192. data/maps/photograph.map +0 -0
  193. data/maps/pkgirl.map +0 -0
  194. data/maps/pytho.map +0 -0
  195. data/maps/risorgimento.map +0 -0
  196. data/maps/sherbet.map +0 -0
  197. data/maps/simple.map +0 -0
  198. data/maps/slouch.map +0 -0
  199. data/maps/space_st.ifm +0 -0
  200. data/maps/splashdown.map +0 -0
  201. data/maps/spring.map +0 -0
  202. data/maps/squarecircle.map +0 -0
  203. data/maps/stationfall.ifm +0 -0
  204. data/maps/theatre.ifm +0 -0
  205. data/maps/toonesia.ifm +0 -0
  206. data/maps/tortoise.ifm +0 -0
  207. data/maps/trinity.map +0 -0
  208. data/maps/vespers.map +0 -0
  209. data/maps/vgame.ifm +0 -0
  210. data/maps/wasp.map +0 -0
  211. data/maps/weather.ifm +0 -0
  212. data/maps/windhall.ifm +0 -0
  213. data/maps/worlds.map +0 -0
  214. data/maps/xtcontest.map +0 -0
  215. data/maps/zdungeon.map +0 -0
  216. data/maps/zebulon.ifm +0 -0
  217. data/maps/zerosum.map +0 -0
  218. metadata +226 -183
@@ -1,483 +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
- def pdf_draw_complex_as_lines( pdf, opts )
66
- p = []
67
- maxy = opts['height'] * opts['hh'] + opts['hs_2'] + opts['margin_2']
68
- @pts.each { |pt|
69
- p << [ pt[0] * PDF_ZOOM, maxy - pt[1] * PDF_ZOOM ]
70
- }
71
- return p
72
- end
73
-
74
- def pdf_draw_door( pdf, x1, y1, x2, y2 )
75
- v = [ (x2-x1), (y2-y1) ]
76
- t = 10 / Math.sqrt(v[0]*v[0]+v[1]*v[1])
77
- v = [ v[0]*t, v[1]*t ]
78
- m = [ (x2+x1)/2, (y2+y1)/2 ]
79
- x1, y1 = [m[0] + v[1], m[1] - v[0]]
80
- x2, y2 = [m[0] - v[1], m[1] + v[0]]
81
- if @type == LOCKED_DOOR
82
- pdf.move_to(x1, y1)
83
- pdf.line_to(x2, y2).stroke
84
- else
85
- s = PDF::Writer::StrokeStyle.new(1,
86
- :cap => :butt,
87
- :join => :miter,
88
- :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
89
- pdf.stroke_style(s)
90
- v = [ v[0] / 3, v[1] / 3]
91
- pdf.move_to(x1 - v[0], y1 - v[1])
92
- pdf.line_to(x1 + v[0], y1 + v[1])
93
- pdf.line_to(x2 + v[0], y2 + v[1])
94
- pdf.line_to(x2 - v[0], y2 - v[1])
95
- pdf.line_to(x1 - v[0], y1 - v[1])
96
- pdf.stroke
97
- s = PDF::Writer::StrokeStyle.new(2,
98
- :cap => :butt,
99
- :join => :miter,
100
- :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
101
- pdf.stroke_style(s)
102
- end
103
- end
104
-
105
- def pdf_draw_complex( pdf, opts )
106
- if opts['Paths as Curves']
107
- if @room[0] == @room[1]
108
- dirA, dirB = dirs
109
- if dirA == dirB
110
- p = pdf_draw_complex_as_lines( pdf, opts )
111
- else
112
- p = pdf_draw_complex_as_bspline( pdf, opts )
113
- end
114
- else
115
- p = pdf_draw_complex_as_bspline( pdf, opts )
116
- end
117
- else
118
- p = pdf_draw_complex_as_lines( pdf, opts )
119
- end
120
- pdf.move_to( p[0][0], p[0][1] )
121
- p.each { |pt| pdf.line_to( pt[0], pt[1] ) }
122
- pdf.stroke
123
-
124
- x1, y1 = [p[0][0], p[0][1]]
125
- x2, y2 = [p[-1][0], p[-1][1]]
126
- pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
127
-
128
- if @type == LOCKED_DOOR or @type == CLOSED_DOOR
129
- t = p.size / 2
130
- x1, y1 = [ p[t][0], p[t][1] ]
131
- x2, y2 = [ p[t-2][0], p[t-2][1] ]
132
- pdf_draw_door(pdf, x1, y1, x2, y2)
133
- end
134
- end
135
-
136
- def pdf_draw_simple(pdf, opts)
137
- return if not @room[1] # PDF does not print unfinished complex connections
138
-
139
- dir = @room[0].exits.index(self)
140
- x1, y1 = @room[0].pdf_corner(opts, self, dir)
141
- x2, y2 = @room[1].pdf_corner(opts, self)
142
- pdf.move_to(x1, y1)
143
- pdf.line_to(x2, y2).stroke
144
- pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
145
- if @type == LOCKED_DOOR or @type == CLOSED_DOOR
146
- pdf_draw_door(pdf, x1, y1, x2, y2)
147
- end
148
- end
149
-
150
- #
151
- # Draw the connection text next to the arrow ('I', 'O', etc)
152
- #
153
- def pdf_draw_text(pdf, x, y, dir, text, arrow)
154
- if dir == 7 or dir < 6 and dir != 1
155
- if arrow and (dir == 0 or dir == 4)
156
- x += 5
157
- end
158
- x += 2.5
159
- elsif dir == 6 or dir == 1
160
- x -= 7.5
161
- end
162
-
163
- if dir > 5 or dir < 4
164
- if arrow and (dir == 6 or dir == 2)
165
- y += 5
166
- end
167
- y += 2.5
168
- elsif dir == 4 or dir == 5
169
- y -= 7.5
170
- end
171
-
172
- font_size = 8
173
- pdf.add_text(x, y, text, font_size)
174
- end
175
-
176
- def pdf_draw_exit_text(pdf, opts)
177
-
178
- if @exitText[0] != 0
179
- dir = @room[0].exits.index(self)
180
- x, y = @room[0].pdf_corner(opts, self, dir)
181
- pdf_draw_text( pdf, x, y, dir,
182
- EXIT_TEXT[@exitText[0]], @dir == BtoA)
183
- end
184
-
185
- if @exitText[1] != 0
186
- dir = @room[1].exits.rindex(self)
187
- x, y = @room[1].pdf_corner(opts, self, dir)
188
- pdf_draw_text( pdf, x, y, dir,
189
- EXIT_TEXT[@exitText[1]], @dir == AtoB)
190
- end
191
- end
192
-
193
- def pdf_draw(pdf, opts)
194
- pdf_draw_exit_text(pdf, opts)
195
- if @type == SPECIAL
196
- s = PDF::Writer::StrokeStyle.new(2, :dash => {
197
- :pattern => [2],
198
- :phase => [1]
199
- } )
200
- else
201
- s = PDF::Writer::StrokeStyle.new(2,
202
- :cap => :butt,
203
- :join => :miter,
204
- :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
205
- end
206
- pdf.stroke_style( s )
207
- pdf.stroke_color Color::RGB::Black
208
- pdf.fill_color Color::RGB::White
209
- if @pts.size > 0
210
- pdf_draw_complex(pdf, opts)
211
- else
212
- pdf_draw_simple(pdf, opts)
213
- end
214
- end
215
- end
216
-
217
-
218
- class FXRoom
219
- def pdf_corner( opts, c, idx = nil )
220
- x, y = _corner(c, idx)
221
- y = -y
222
-
223
- ww = opts['ww']
224
- hh = opts['hh']
225
- w = opts['w']
226
- h = opts['h']
227
-
228
- ry = opts['height'] - @y
229
- x = @x * ww + opts['ws_2'] + opts['margin_2'] + x * w
230
- y = ry * hh + opts['hs_2'] + h + opts['margin_2'] + y * h
231
- return [x, y]
232
- end
233
-
234
-
235
- def pdf_draw_box( pdf, opts )
236
- x = @x * opts['ww'] + opts['ws_2'] + opts['margin_2']
237
- y = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] + opts['margin_2']
238
-
239
- s = PDF::Writer::StrokeStyle::DEFAULT
240
- pdf.stroke_style( s )
241
-
242
- if @darkness
243
- pdf.fill_color( Color::RGB::Gray )
244
- else
245
- pdf.fill_color( Color::RGB::White )
246
- end
247
-
248
- pdf.rectangle(x, y, opts['w'], opts['h']).fill_stroke
249
- end
250
-
251
- def pdf_draw_text( pdf, opts, x, y, text, font_size )
252
- miny = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] +
253
- opts['margin_2']
254
- while text != ''
255
- text = pdf.add_text_wrap(x, y, opts['w'] - 2, text, font_size)
256
- y -= font_size
257
- break if y <= miny
258
- end
259
- return [x, y]
260
- end
261
-
262
- def pdf_draw_objects(pdf, opts, x, y)
263
- font_size = 6
264
- objs = @objects.split("\n")
265
- objs = objs.join(', ')
266
- return pdf_draw_text( pdf, opts, x, y, objs, font_size )
267
- end
268
-
269
- def pdf_draw_name(pdf, opts)
270
- # We could also use pdf_corner(7) here
271
- x = @x * opts['ww'] + opts['margin_2'] + opts['ws_2'] + 2
272
- y = opts['height'] - @y
273
- font_size = 8
274
- y = y * opts['hh'] + opts['margin_2'] + opts['hs_2'] + opts['h'] -
275
- (font_size + 2)
276
- pdf.stroke_color(Color::RGB::Black)
277
- pdf.fill_color(Color::RGB::Black)
278
- return pdf_draw_text( pdf, opts, x, y, @name, font_size )
279
- end
280
-
281
- def pdf_draw( pdf, opts, idx )
282
- pdf_draw_box( pdf, opts )
283
- x, y = pdf_draw_name( pdf, opts )
284
- pdf_draw_objects(pdf, opts, x, y)
285
- end
286
- end
287
-
288
-
289
-
290
- class FXSection
291
-
292
- def pdf_draw_grid(pdf, opts, w, h )
293
- (0...w).each { |xx|
294
- (0...h).each { |yy|
295
- x = xx * opts['ww'] + opts['ws_2'] + opts['margin_2']
296
- y = yy * opts['hh'] + opts['hs_2'] + opts['margin_2']
297
- pdf.rectangle(x, y, opts['w'], opts['h']).stroke
298
- }
299
- }
300
- end
301
-
302
-
303
- def pdf_draw_section_name( pdf, opts, px, py )
304
- return if not @name or @name == ''
305
- xymin, xymax = min_max_rooms
306
- text = @name
307
- text += " (#{px}, #{py})" if px > 0 or py > 0
308
- y = (opts['height']) * opts['hh'] + 16
309
- w = xymax[0]
310
- w = opts['width'] if w > opts['width']
311
- x = (w + 2) * opts['ww'] / 2 - text.size / 2 * 16
312
- x = 0 if x < 0
313
- pdf.add_text( x, y, text, 16 )
314
- end
315
-
316
-
317
- def pdf_draw(pdf, opts, mapname )
318
-
319
-
320
- w, h = rooms_width_height
321
- x, y = [0, 0]
322
-
323
- loop do
324
-
325
- if rotate
326
- pdf.rotate_axis(90.0)
327
- pdf.translate_axis( 0, -pdf.page_height )
328
- end
329
-
330
- # Move section to its position in page
331
- tx1, ty1 = [@xoff * opts['ww'], @yoff * -opts['hh']]
332
- pdf.translate_axis( tx1, ty1 )
333
-
334
- # Use times-roman as font
335
- pdf.select_font 'Times-Roman'
336
- pdf.stroke_color(Color::RGB::Black)
337
- pdf.fill_color(Color::RGB::Black)
338
-
339
- pdf_draw_section_name( pdf, opts, x, y )
340
-
341
- xymin, = min_max_rooms
342
-
343
- # Move rooms, so that we don't print empty areas
344
- tx2 = -(xymin[0]) * opts['ww'] - x * opts['ww']
345
- ty2 = (xymin[1]) * opts['hh'] - 60 + (y - (y > 0? 1 : 0)) * opts['hh']
346
- pdf.translate_axis( tx2, ty2 )
347
-
348
-
349
- # For testing purposes only, draw grid of boxes
350
- # pdf_draw_grid( pdf, opts, width, height )
351
- @connections.each { |c|
352
- a = c.roomA
353
- b = c.roomB
354
- next if a.y < y and b and b.y < y
355
- c.pdf_draw( pdf, opts )
356
- }
357
- @rooms.each_with_index { |r, idx|
358
- next if r.y < y
359
- r.pdf_draw( pdf, opts, idx)
360
- }
361
-
362
- # Reset axis
363
- pdf.translate_axis(-tx2, -ty2)
364
- pdf.translate_axis(-tx1, -ty1)
365
-
366
- xi = opts['width']
367
- yi = opts['height']
368
- if rotate
369
- xi = (pdf.page_height / opts['ww']).to_i - 1
370
- yi = (pdf.page_width / opts['hh']).to_i - 1
371
- end
372
-
373
- x += xi
374
- if x >= w
375
- x = 0
376
- y += yi
377
- break if y >= h
378
- end
379
-
380
- # We could not fit all rooms in page. Start new page
381
- pdf.start_new_page
382
- end
383
- end
384
- end
385
-
386
-
387
- class FXMap
388
-
389
- def pdf_draw_mapname( pdf, opts )
390
- return if not @name or @name == ''
391
- pdf.text( @name,
392
- :font_size => 24,
393
- :justification => :center
394
- )
395
- end
396
-
397
- def pdf_draw_sections( pdf, opts )
398
- old_section = @section
399
- page = -1
400
- @sections.each_with_index { |sect, idx|
401
- if page != sect.page
402
- page = sect.page
403
- pdf.start_new_page if page > 1
404
- pdf_draw_mapname( pdf, opts )
405
- end
406
- @section = idx
407
- # For each page, we need to regenerate the pathmap so that complex
408
- # paths will come out ok.
409
- create_pathmap
410
- # Now, we draw it
411
- sect.pdf_draw(pdf, opts, @name)
412
- }
413
-
414
- # Restore original viewing page
415
- @section = old_section
416
- create_pathmap
417
- end
418
-
419
-
420
- def pdf_export(pdffile = Dir::tmpdir + "/ifmap.pdf", printer = nil)
421
-
422
- paper = 'LETTER'
423
- if printer
424
- case printer.mediasize
425
- when FXPrinter::MEDIA_LETTER
426
- paper = 'LETTER'
427
- when FXPrinter::MEDIA_LEGAL
428
- paper = 'LEGAL'
429
- when FXPrinter::MEDIA_A4
430
- paper = 'A4'
431
- when FXPrinter::MEDIA_ENVELOPE
432
- paper = 'ENVELOPE'
433
- when FXPrinter::MEDIA_CUSTOM
434
- raise "Sorry, custom paper not supported"
435
- end
436
- end
437
-
438
- # Open a new PDF writer with paper selected
439
- pdf = PDF::Writer.new :paper => paper
440
-
441
- pdf.margins_pt 0
442
-
443
- pdf_options = @options.dup
444
-
445
- ww = PDF_ROOM_WIDTH + PDF_ROOM_WS
446
- hh = PDF_ROOM_HEIGHT + PDF_ROOM_HS
447
-
448
- pdf_options.merge!(
449
- {
450
- 'ww' => ww,
451
- 'hh' => hh,
452
- 'w' => PDF_ROOM_WIDTH,
453
- 'h' => PDF_ROOM_HEIGHT,
454
- 'ws' => PDF_ROOM_WS,
455
- 'hs' => PDF_ROOM_HS,
456
- 'ws_2' => PDF_ROOM_WS / 2.0,
457
- 'hs_2' => PDF_ROOM_HS / 2.0,
458
- 'margin' => PDF_MARGIN,
459
- 'margin_2' => PDF_MARGIN / 2.0,
460
- 'width' => (pdf.page_width / ww).to_i - 1,
461
- 'height' => (pdf.page_height / hh).to_i - 1,
462
- }
463
- )
464
-
465
-
466
- begin
467
- # See if it is possible to pack several map sections (sections) into
468
- # a single print page.
469
- num = pack_sections( pdf_options['width'] + 2,
470
- pdf_options['height'] + 2 )
471
- pdf_draw_sections(pdf, pdf_options)
472
- if pdffile !~ /\.pdf$/
473
- pdffile << ".pdf"
474
- end
475
- status "Exporting PDF file '#{pdffile}'"
476
- pdf.save_as(pdffile)
477
- rescue => e
478
- p e
479
- p e.backtrace
480
- raise e
481
- end
482
- end
483
- end
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 it up and right
66
+ def pdf_draw_complex_as_lines( pdf, opts )
67
+ p = []
68
+ maxy = opts['height'] * opts['hh'] + opts['hs_2'] + opts['margin_2']
69
+ @pts.each { |pt|
70
+ if loop? == true
71
+ p << [ pt[0] * PDF_ZOOM + 10, maxy - pt[1] * PDF_ZOOM + 48 ]
72
+ else
73
+ p << [ pt[0] * PDF_ZOOM, maxy - pt[1] * PDF_ZOOM ]
74
+ end
75
+ }
76
+ return p
77
+ end
78
+
79
+ def pdf_draw_door( pdf, x1, y1, x2, y2 )
80
+ v = [ (x2-x1), (y2-y1) ]
81
+ t = 10 / Math.sqrt(v[0]*v[0]+v[1]*v[1])
82
+ v = [ v[0]*t, v[1]*t ]
83
+ m = [ (x2+x1)/2, (y2+y1)/2 ]
84
+ x1, y1 = [m[0] + v[1], m[1] - v[0]]
85
+ x2, y2 = [m[0] - v[1], m[1] + v[0]]
86
+ if @type == LOCKED_DOOR
87
+ pdf.move_to(x1, y1)
88
+ pdf.line_to(x2, y2).stroke
89
+ else
90
+ s = PDF::Writer::StrokeStyle.new(1,
91
+ :cap => :butt,
92
+ :join => :miter,
93
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
94
+ pdf.stroke_style(s)
95
+ v = [ v[0] / 3, v[1] / 3]
96
+ pdf.move_to(x1 - v[0], y1 - v[1])
97
+ pdf.line_to(x1 + v[0], y1 + v[1])
98
+ pdf.line_to(x2 + v[0], y2 + v[1])
99
+ pdf.line_to(x2 - v[0], y2 - v[1])
100
+ pdf.line_to(x1 - v[0], y1 - v[1])
101
+ pdf.stroke
102
+ s = PDF::Writer::StrokeStyle.new(2,
103
+ :cap => :butt,
104
+ :join => :miter,
105
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
106
+ pdf.stroke_style(s)
107
+ end
108
+ end
109
+
110
+ def pdf_draw_complex( pdf, opts )
111
+ if opts['Paths as Curves']
112
+ if @room[0] == @room[1]
113
+ dirA, dirB = dirs
114
+ if dirA == dirB
115
+ p = pdf_draw_complex_as_lines( pdf, opts )
116
+ else
117
+ p = pdf_draw_complex_as_bspline( pdf, opts )
118
+ end
119
+ else
120
+ p = pdf_draw_complex_as_bspline( pdf, opts )
121
+ end
122
+ else
123
+ p = pdf_draw_complex_as_lines( pdf, opts )
124
+ end
125
+ pdf.move_to( p[0][0], p[0][1] )
126
+ p.each { |pt| pdf.line_to( pt[0], pt[1] ) }
127
+ pdf.stroke
128
+
129
+ x1, y1 = [p[0][0], p[0][1]]
130
+ x2, y2 = [p[-1][0], p[-1][1]]
131
+ pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
132
+
133
+ if @type == LOCKED_DOOR or @type == CLOSED_DOOR
134
+ t = p.size / 2
135
+ x1, y1 = [ p[t][0], p[t][1] ]
136
+ x2, y2 = [ p[t-2][0], p[t-2][1] ]
137
+ pdf_draw_door(pdf, x1, y1, x2, y2)
138
+ end
139
+ end
140
+
141
+ def pdf_draw_simple(pdf, opts)
142
+ return if not @room[1] # PDF does not print unfinished complex connections
143
+
144
+ dir = @room[0].exits.index(self)
145
+ x1, y1 = @room[0].pdf_corner(opts, self, dir)
146
+ x2, y2 = @room[1].pdf_corner(opts, self)
147
+ pdf.move_to(x1, y1)
148
+ pdf.line_to(x2, y2).stroke
149
+ pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
150
+ if @type == LOCKED_DOOR or @type == CLOSED_DOOR
151
+ pdf_draw_door(pdf, x1, y1, x2, y2)
152
+ end
153
+ end
154
+
155
+ #
156
+ # Draw the connection text next to the arrow ('I', 'O', etc)
157
+ #
158
+ def pdf_draw_text(pdf, x, y, dir, text, arrow)
159
+ if dir == 7 or dir < 6 and dir != 1
160
+ if arrow and (dir == 0 or dir == 4)
161
+ x += 5
162
+ end
163
+ x += 2.5
164
+ elsif dir == 6 or dir == 1
165
+ x -= 7.5
166
+ end
167
+
168
+ if dir > 5 or dir < 4
169
+ if arrow and (dir == 6 or dir == 2)
170
+ y += 5
171
+ end
172
+ y += 2.5
173
+ elsif dir == 4 or dir == 5
174
+ y -= 7.5
175
+ end
176
+
177
+ font_size = 8
178
+ pdf.add_text(x, y, text, font_size)
179
+ end
180
+
181
+ def pdf_draw_exit_text(pdf, opts)
182
+
183
+ if @exitText[0] != 0
184
+ dir = @room[0].exits.index(self)
185
+ x, y = @room[0].pdf_corner(opts, self, dir)
186
+ pdf_draw_text( pdf, x, y, dir,
187
+ EXIT_TEXT[@exitText[0]], @dir == BtoA)
188
+ end
189
+
190
+ if @exitText[1] != 0
191
+ dir = @room[1].exits.rindex(self)
192
+ x, y = @room[1].pdf_corner(opts, self, dir)
193
+ pdf_draw_text( pdf, x, y, dir,
194
+ EXIT_TEXT[@exitText[1]], @dir == AtoB)
195
+ end
196
+ end
197
+
198
+ def pdf_draw(pdf, opts)
199
+ pdf_draw_exit_text(pdf, opts)
200
+ if @type == SPECIAL
201
+ s = PDF::Writer::StrokeStyle.new(2, :dash => {
202
+ :pattern => [2],
203
+ :phase => [1]
204
+ } )
205
+ else
206
+ s = PDF::Writer::StrokeStyle.new(2,
207
+ :cap => :butt,
208
+ :join => :miter,
209
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
210
+ end
211
+ pdf.stroke_style( s )
212
+ pdf.stroke_color Color::RGB::Black
213
+ # PRE: Let's set the fill colour to white so that we can see the text
214
+ pdf.fill_color Color::RGB::White
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