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,124 +1,124 @@
1
-
2
- #
3
- # Class used to display a connection dialog box
4
- #
5
- class FXConnectionDialogBox < FXDialogBox
6
-
7
-
8
- TYPE_NUM = [
9
- Connection::FREE, # free
10
- Connection::CLOSED_DOOR, # door
11
- Connection::LOCKED_DOOR, # locked
12
- Connection::SPECIAL, # special
13
- ]
14
-
15
-
16
- attr_writer :map
17
-
18
- def copy_to()
19
- @conn.dir = @dir.currentNo
20
- @conn.type = TYPE_NUM[ @type.currentNo ]
21
- @conn.exitAtext = @exitA.currentNo
22
- @conn.exitBtext = @exitB.currentNo
23
-
24
- @map.draw
25
- end
26
-
27
-
28
- def copy_from(conn)
29
- title = conn.to_s
30
- self.title = title
31
-
32
- @dir.currentNo = conn.dir
33
- @type.currentNo = TYPE_NUM.index(conn.type) || 0
34
- @exitA.currentNo = conn.exitAtext
35
- @exitB.currentNo = conn.exitBtext
36
- @conn = conn
37
-
38
- if @map.navigation
39
- @dir.disable
40
- @type.disable
41
- @exitA.disable
42
- @exitB.disable
43
- else
44
- @dir.enable
45
- @type.enable
46
- @exitA.enable
47
- @exitB.enable
48
- end
49
- if conn.loop? or conn.stub?
50
- @type.disable
51
- @dir.disable
52
- @exitB.disable
53
- end
54
- end
55
-
56
- def initialize(map, conn, event = nil)
57
- pos = [40, 40]
58
- if event
59
- pos = [ event.last_x, event.last_y ]
60
- end
61
- maxW = map.window.width - 390
62
- maxH = map.window.height - 300
63
- pos[0] = maxW if pos[0] > maxW
64
- pos[1] = maxH if pos[1] > maxH
65
-
66
- decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
67
- super( map.window, '', decor, pos[0], pos[1], 0, 0 )
68
- mainFrame = FXVerticalFrame.new(self,
69
- FRAME_SUNKEN|FRAME_THICK|
70
- LAYOUT_FILL_X|LAYOUT_FILL_Y)
71
-
72
- frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
73
-
74
- FXLabel.new(frame, BOX_CONNECTION_TYPE, nil, 0, LAYOUT_FILL_X)
75
- pane = FXPopup.new(self)
76
- BOX_CONNECTION_TYPE_TEXT.each { |t|
77
- FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
78
- }
79
- @type = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
80
- JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
81
- LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
82
-
83
-
84
- FXLabel.new(frame, BOX_DIRECTION, nil, 0, LAYOUT_FILL_X)
85
- pane = FXPopup.new(self)
86
- BOX_DIR_TEXT.each { |t|
87
- FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
88
- }
89
- @dir = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
90
- JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
91
- LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
92
-
93
- frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
94
- FXLabel.new(frame, BOX_EXIT_A_TEXT, nil, 0, LAYOUT_FILL_X)
95
- pane = FXPopup.new(self)
96
- BOX_EXIT_TEXT.each { |t|
97
- FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
98
- }
99
- @exitA = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
100
- JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
101
- LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
102
- FXLabel.new(frame, BOX_EXIT_B_TEXT, nil, 0, LAYOUT_FILL_X)
103
- pane = FXPopup.new(self)
104
- BOX_EXIT_TEXT.each { |t|
105
- FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
106
- }
107
- @exitB = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
108
- JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
109
- LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
110
-
111
- @dir.connect(SEL_COMMAND) {
112
- copy_to()
113
- title = @conn.to_s
114
- self.title = title
115
- }
116
- @type.connect(SEL_COMMAND) { copy_to() }
117
- @exitA.connect(SEL_COMMAND) { copy_to() }
118
- @exitB.connect(SEL_COMMAND) { copy_to() }
119
- @map = map
120
-
121
- # We need to create the dialog box first, so we can use select text.
122
- create
123
- end
124
- end
1
+
2
+ #
3
+ # Class used to display a connection dialog box
4
+ #
5
+ class FXConnectionDialogBox < FXDialogBox
6
+
7
+
8
+ TYPE_NUM = [
9
+ Connection::FREE, # free
10
+ Connection::CLOSED_DOOR, # door
11
+ Connection::LOCKED_DOOR, # locked
12
+ Connection::SPECIAL, # special
13
+ ]
14
+
15
+
16
+ attr_writer :map
17
+
18
+ def copy_to()
19
+ @conn.dir = @dir.currentNo
20
+ @conn.type = TYPE_NUM[ @type.currentNo ]
21
+ @conn.exitAtext = @exitA.currentNo
22
+ @conn.exitBtext = @exitB.currentNo
23
+
24
+ @map.draw
25
+ end
26
+
27
+
28
+ def copy_from(conn)
29
+ title = conn.to_s
30
+ self.title = title
31
+
32
+ @dir.currentNo = conn.dir
33
+ @type.currentNo = TYPE_NUM.index(conn.type) || 0
34
+ @exitA.currentNo = conn.exitAtext
35
+ @exitB.currentNo = conn.exitBtext
36
+ @conn = conn
37
+
38
+ if @map.navigation
39
+ @dir.disable
40
+ @type.disable
41
+ @exitA.disable
42
+ @exitB.disable
43
+ else
44
+ @dir.enable
45
+ @type.enable
46
+ @exitA.enable
47
+ @exitB.enable
48
+ end
49
+ if conn.loop? or conn.stub?
50
+ @type.disable
51
+ @dir.disable
52
+ @exitB.disable
53
+ end
54
+ end
55
+
56
+ def initialize(map, conn, event = nil)
57
+ pos = [40, 40]
58
+ if event
59
+ pos = [ event.last_x, event.last_y ]
60
+ end
61
+ maxW = map.window.width - 390
62
+ maxH = map.window.height - 300
63
+ pos[0] = maxW if pos[0] > maxW
64
+ pos[1] = maxH if pos[1] > maxH
65
+
66
+ decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
67
+ super( map.window, '', decor, pos[0], pos[1], 0, 0 )
68
+ mainFrame = FXVerticalFrame.new(self,
69
+ FRAME_SUNKEN|FRAME_THICK|
70
+ LAYOUT_FILL_X|LAYOUT_FILL_Y)
71
+
72
+ frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
73
+
74
+ FXLabel.new(frame, BOX_CONNECTION_TYPE, nil, 0, LAYOUT_FILL_X)
75
+ pane = FXPopup.new(self)
76
+ BOX_CONNECTION_TYPE_TEXT.each { |t|
77
+ FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
78
+ }
79
+ @type = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
80
+ JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
81
+ LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
82
+
83
+
84
+ FXLabel.new(frame, BOX_DIRECTION, nil, 0, LAYOUT_FILL_X)
85
+ pane = FXPopup.new(self)
86
+ BOX_DIR_TEXT.each { |t|
87
+ FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
88
+ }
89
+ @dir = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
90
+ JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
91
+ LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
92
+
93
+ frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
94
+ FXLabel.new(frame, BOX_EXIT_A_TEXT, nil, 0, LAYOUT_FILL_X)
95
+ pane = FXPopup.new(self)
96
+ BOX_EXIT_TEXT.each { |t|
97
+ FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
98
+ }
99
+ @exitA = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
100
+ JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
101
+ LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
102
+ FXLabel.new(frame, BOX_EXIT_B_TEXT, nil, 0, LAYOUT_FILL_X)
103
+ pane = FXPopup.new(self)
104
+ BOX_EXIT_TEXT.each { |t|
105
+ FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
106
+ }
107
+ @exitB = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
108
+ JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
109
+ LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
110
+
111
+ @dir.connect(SEL_COMMAND) {
112
+ copy_to()
113
+ title = @conn.to_s
114
+ self.title = title
115
+ }
116
+ @type.connect(SEL_COMMAND) { copy_to() }
117
+ @exitA.connect(SEL_COMMAND) { copy_to() }
118
+ @exitB.connect(SEL_COMMAND) { copy_to() }
119
+ @map = map
120
+
121
+ # We need to create the dialog box first, so we can use select text.
122
+ create
123
+ end
124
+ end
@@ -1,404 +1,404 @@
1
-
2
-
3
- #
4
- # Class used to do Postscript printing. This class has only the basic
5
- # functionality needed for doing so and replaces the still somewhat buggy
6
- # version of Fox's 1.2 FXDCPrint
7
- #
8
- class FXDCPostscript < FXDC
9
- @@printcmd = 'lpr -P%s -o l -' # -#%d'
10
-
11
- def setContentRange(xmin, ymin, xmax, ymax)
12
- @pxmin = xmin.to_f
13
- @pymin = ymin.to_f
14
- @pxmax = xmax.to_f
15
- @pymax = ymax.to_f
16
- end
17
-
18
- # Transform point
19
- def tfm(xi, yi)
20
- pxrange = @pxmax - @pxmin
21
- pyrange = @pymax - @pymin
22
-
23
- if @flags & PRINT_LANDSCAPE != 0
24
- mxmin = @ymin.to_f
25
- mxmax = @ymax.to_f
26
- mymin = @width - @xmax
27
- mymax = @width - @xmin
28
- mxrange = mxmax - mxmin
29
- myrange = mymax - mymin
30
- else
31
- mxmin = @xmin
32
- mxmax = @xmax
33
- mymin = @ymin
34
- mymax = @ymax
35
- mxrange = mxmax-mxmin
36
- myrange = mymax-mymin
37
- end
38
-
39
- if pyrange/pxrange <= myrange/mxrange
40
- # short/wide
41
- xo = mxmin + ((xi.to_f-@pxmin)/pxrange) * mxrange;
42
- yo = mymin + 0.5 * (myrange-pyrange * (mxrange/pxrange)) +
43
- (pyrange-yi.to_f) * (mxrange/pxrange)
44
- else
45
- # tall/thin
46
- xo = mxmin + 0.5 * (mxrange-pxrange * (myrange/pyrange)) +
47
- xi * (myrange/pyrange)
48
- yo = mymin + ((pyrange-yi.to_f)/pyrange) * myrange
49
- end
50
- return [xo, yo]
51
- end
52
-
53
-
54
-
55
-
56
-
57
- def _header
58
- @f.puts <<'HEADER'
59
- %%!PS-Adobe-3.0
60
- %%%%Title: Print Job
61
- %%%%Creator: IFMapper
62
- HEADER
63
-
64
- end
65
-
66
- def beginPrint(printer, &block)
67
- @flags = printer.flags
68
- if @flags & PRINT_DEST_FILE != 0
69
- @f = File.open( printer.name, 'w' )
70
- else
71
- buffer = @@printcmd % [ printer.name, printer.numcopies ]
72
- puts buffer
73
- @f = File.popen( buffer, 'w')
74
- end
75
-
76
-
77
- @width = printer.mediawidth.to_f
78
- @height = printer.mediaheight.to_f
79
-
80
- @xmin = printer.leftmargin.to_f
81
- @xmax = @width - printer.rightmargin
82
-
83
- @ymin = printer.bottommargin.to_f
84
- @ymax = @height - printer.topmargin
85
-
86
-
87
- _header
88
- if @flags & PRINT_NOBOUNDS != 0
89
- xmin = 10000000.0
90
- xmax = -xmin
91
- ymin = 10000000.0
92
- ymax = -ymin
93
- @f.puts "%%%%BoundingBox: (atend)"
94
- else
95
- @f.puts "%%%%BoundingBox: %d %d %d %d" %
96
- [ @xmin, @ymin, @xmax, @ymax ]
97
- end
98
-
99
- @numpages = 1 + printer.firstpage - printer.lastpage
100
- if @flags & PRINT_PAGES_ODD
101
- @numpages = 1 + (printer.topage - printer.frompage) / 2
102
- elsif @flags & PRINT_PAGES_EVEN
103
- @numpages = 1 + (printer.topage - printer.frompage) / 2
104
- elsif @pages & PRINT_PAGES_RANGE
105
- @numpages = 1 + printer.topage - printer.frompage
106
- end
107
-
108
- if @numpages == 0
109
- @f.puts "%%%%Pages: (atend)"
110
- else
111
- @f.puts "%%%%Pages: #{@numpages}"
112
- end
113
-
114
- @f.puts "%%%%DocumentFonts:"
115
- @f.puts "%%%%EndComments"
116
- @f.puts "%%%%BeginProlog\n\n"
117
-
118
- # Various definitions
119
- @f.puts "%% h w x y drawRect\n"
120
- @f.puts "/drawRect {\n\tnewpath moveto dup 0 rlineto exch dup 0 exch\n\trlineto exch neg 0 rlineto neg 0 exch rlineto\n\tclosepath stroke\n} def\n"
121
- @f.puts "%% h w x y fillRect\n"
122
- @f.puts "/fillRect {\n\tnewpath moveto dup 0 rlineto exch dup 0 exch\n\trlineto exch neg 0 rlineto neg 0 exch rlineto\n\tclosepath fill stroke\n} def\n"
123
- @f.puts "%% x y a b drawLine\n"
124
- @f.puts "/drawLine {\n\tnewpath moveto lineto stroke\n} def\n"
125
- @f.puts "%% x y ..... npoints drawLines\n"
126
- @f.puts "/drawLines {\n\t3 1 roll newpath moveto {lineto} repeat stroke\n} def\n"
127
- @f.puts "%% x y a b ..... nsegments drawSegmt\n"
128
- @f.puts "/drawSegmt {\n\tnewpath {\n\t\tmoveto lineto\n\t} repeat stroke\n} def\n"
129
- @f.puts "%% x y drawPoint\n"
130
- @f.puts "/drawPoint {\n\ttranslate 1 1 scale 8 8 1 [ 8 0 0 8 0 0 ] {<0000>} image\n} def\n"
131
- @f.puts "%% centerx centery startAngle endAngle radiusX radiusY drawArc\n"
132
- @f.puts "/drawArc {\n\tgsave dup 3 1 roll div dup 1 scale 6 -1 roll\n\texch div 5 1 roll 3 -2 roll arc stroke grestore\n} def\n"
133
- @f.puts "/fillChord {\n\tgsave dup 3 1 roll div dup 1 scale 6 -1 roll\n\texch div 5 1 roll 3 -2 roll arc fill grestore\n} def\n"
134
- @f.puts "%% (string) x y height drawText\n"
135
- @f.puts "/drawText {\n\tgsave findfont exch scalefont setfont moveto\n\tshow grestore\n} def\n"
136
-
137
-
138
- @f.puts "%%%%EndProlog"
139
-
140
- @f.puts "%%%%BeginSetup"
141
- @f.puts "/#copies #{printer.numcopies} def"
142
- @f.puts "%%%%EndSetup"
143
-
144
- @page = 0
145
-
146
- if block_given?
147
- yield self
148
- endPrint()
149
- end
150
- end
151
-
152
-
153
- def endPrint
154
- @f.puts "%%%%Trailer\n"
155
-
156
- # We now know the bounding box
157
- if @flags & PRINT_NOBOUNDS != 0
158
- if @xmin < @xmax and @ymin < @ymax
159
- @f.puts "%%%%BoundingBox: %d %d %d %d" %
160
- [ @xmin, @ymin, @xmax, @ymax ]
161
- else
162
- @f.puts "%%%%BoundingBox: 0 0 100 100"
163
- end
164
- end
165
-
166
- # We now know the page count
167
- if not (@flags & PRINT_PAGES_ODD|PRINT_PAGES_EVEN|PRINT_PAGES_RANGE)
168
- @f.puts "%%%%Pages: #{page}"
169
- end
170
-
171
- @f.puts "%%%%EOF"
172
- @f.close
173
- end
174
-
175
-
176
- def beginPage(num = 1, &block)
177
- # Output page number
178
- @f.puts "%%%%Page: #{@page} #{@page}" # Ghostscript requests this, I do not know if it is right
179
-
180
- # Reset page bounding box
181
- if @flags & PRINT_NOBOUNDS != 0
182
- @xmin= 1000000;
183
- @xmax=-1000000;
184
- @ymin= 1000000;
185
- @ymax=-1000000;
186
- @f.puts "%%%%PageBoundingBox: (atend)"
187
- else
188
- # Use the doc bounding box
189
- @f.puts "%%%%PageBoundingBox: %d %d %d %d" % [@xmin, @ymin, @xmax, @ymax]
190
- end
191
-
192
- # Page setup
193
- @f.puts "%%%%BeginPageSetup"
194
- @f.puts "%%%%EndPageSetup"
195
- @f.puts "gsave"
196
-
197
- # Maybe in landscape?
198
- if @flags & PRINT_LANDSCAPE != 0
199
- @f.puts "#{@width} 0.0 translate"
200
- @f.puts "90 rotate"
201
- end
202
-
203
- if block_given?
204
- yield self
205
- endPage()
206
- end
207
- end
208
-
209
- def endPage
210
- @f.puts "%%%%PageTrailer"
211
-
212
- # We now know the bounding box
213
- if @flags & PRINT_NOBOUNDS != 0
214
- if @xmin < @xmax and @ymin < @ymax
215
- @f.puts "%%%%BoundingBox: %d %d %d %d" [@xmin, @ymin, @xmax, @ymax]
216
- else
217
- @f.puts "%%%%BoundingBox: 0 0 100 100" # Gotta come up with something...
218
- end
219
- end
220
- @f.puts "showpage"
221
- @f.puts "grestore"
222
- @page += 1
223
- end
224
-
225
- # Extends bounding box with point x,y
226
- def bbox(x, y)
227
- @xmin = x if x < @xmin
228
- @ymin = y if y < @ymin
229
- @xmax = x if x > @xmax
230
- @ymax = y if y > @ymax
231
- end
232
-
233
- def _rect(x, y, w, h)
234
- xl, yt = tfm(x, y)
235
- xr, yb = tfm(x + w - 1, y + h - 1)
236
- bbox(xl,yt)
237
- bbox(xr,yb)
238
- @f.print "newpath %g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto " %
239
- [xl,yt,xr,yt,xr,yb,xl,yb,xl,yt]
240
- end
241
-
242
- def drawRectangle(x, y, w, h)
243
- _rect(x, y, w, h)
244
- @f.puts "stroke"
245
- end
246
-
247
-
248
- def drawLine(x1, y1, x2, y2)
249
- xx1, yy1 = tfm(x1, y1)
250
- xx2, yy2 = tfm(x2, y2)
251
- bbox(xx1,yy1)
252
- bbox(xx2,yy2)
253
- @f.puts "newpath %g %g moveto %g %g lineto stroke" % [xx1, yy1, xx2, yy2]
254
- end
255
-
256
- def drawLines(points)
257
- return if points.size < 2
258
- xx, yy = tfm(points[0].x, points[0].y)
259
- bbox(xx,yy)
260
- @f.print "newpath %g %g moveto" % [xx, yy]
261
- 1.upto(points.size-1) { |i|
262
- xx, yy = tfm(points[i].x, points[i].y)
263
- bbox(xx,yy)
264
- @f.print " %g %g lineto" % [xx, yy]
265
- }
266
- @f.puts " stroke"
267
- end
268
-
269
- def drawText(x, y, text)
270
- # Draw string (only foreground bits)
271
- # Contributed by S. Ancelot <sancelot@online.fr>
272
- xx, yy = tfm( x, y )
273
-
274
- pxrange = @pxmax - @pxmin
275
- pyrange = @pymax - @pymin
276
-
277
- if @flags & PRINT_LANDSCAPE != 0
278
- mxmin = @ymin
279
- mxmax = @ymax
280
- mymin = @width - @xmax
281
- mymax = @width - @xmin
282
- mxrange = mxmax - mxmin
283
- myrange = mymax - mymin
284
- else
285
- mxmin = @xmin
286
- mxmax = @xmax
287
- mymin = @ymin
288
- mymax = @ymax
289
- mxrange = mxmax - mxmin
290
- myrange = mymax - mymin
291
- end
292
-
293
- fsize = 0.1 * @font.getSize
294
-
295
- # Hack...
296
- # Account for dpi and scale up or down with graph...
297
- # Perhaps override screen resolution via registry
298
- # FXint screenres=getApp()->reg().readUnsignedEntry("SETTINGS","screenres",100);
299
- # Validate
300
- screenres = 100
301
- # if(screenres<50) screenres=50;
302
- # if(screenres>200) screenres=200;
303
-
304
- if pyrange / pxrange <= myrange / mxrange
305
- # short/wide
306
- fsize *= (mxrange/pxrange)*(screenres/72.0)
307
- else
308
- # tall/thin
309
- fsize *= (myrange/pyrange)*(screenres/72.0)
310
- end
311
-
312
- fname = @font.name
313
- if fname =~ /times/i
314
- fname = 'Times-Roman'
315
- elsif fname =~ /(helvetica|verdana|tahoma|arial)/i
316
- fname = 'Helvetica'
317
- else
318
- fname = 'Courier'
319
- end
320
-
321
- if @font.getWeight == FXFont::FONTWEIGHT_BOLD
322
- fname << '-Bold'
323
- if @font.getSlant == FXFont::FONTSLANT_ITALIC
324
- fname << 'Italic'
325
- elsif @font.getSlant == FXFont::FONTSLANT_OBLIQUE
326
- fname << 'Oblique'
327
- end
328
- else
329
- if @font.getSlant == FXFont::FONTSLANT_ITALIC
330
- fname << '-Italic'
331
- elsif @font.getSlant == FXFont::FONTSLANT_OBLIQUE
332
- fname << '-Oblique'
333
- end
334
- end
335
-
336
- @f.puts "(%s) %g %g %d /%s drawText" % [text, xx, yy, fsize, fname]
337
- end
338
-
339
- def fillRectangle(x, y, w, h)
340
- _rect(x, y, w, h)
341
- @f.puts "fill"
342
- end
343
-
344
- def fillPolygon(points)
345
- return if points.size < 3
346
- xx, yy = tfm(points[0].x, points[0].y)
347
- bbox(xx,yy)
348
- @f.print "newpath %g %g moveto" % [ xx, yy ]
349
- 1.upto(points.size-1) { |i|
350
- xx, yy = tfm(points[i].x, points[i].y)
351
- bbox(xx,yy)
352
- @f.print " %g %g lineto" % [ xx, yy ]
353
- }
354
- @f.puts " fill"
355
- end
356
-
357
- def lineStyle=(x)
358
- if x == LINE_SOLID
359
- @f.puts "[ ] 0 setdash"
360
- elsif x == LINE_ONOFF_DASH
361
- @f.puts "[2 2] 0 setdash"
362
- end
363
- end
364
-
365
- def foreground=(c)
366
- if c.kind_of?(String)
367
- clr = fxcolorfromname(c)
368
- else
369
- clr = c
370
- end
371
- @f.puts "%g %g %g setrgbcolor" % [FXREDVAL(clr)/255.0,FXGREENVAL(clr)/255.0,FXBLUEVAL(clr)/255.0]
372
- end
373
-
374
- def lineJoin=(x)
375
- end
376
-
377
- def lineCap=(x)
378
- ncap = 0
379
- ncap = 1 if CAP_ROUND == x
380
- ncap = 3 if CAP_PROJECTING == x
381
- @f.puts "#{ncap} setlinecap"
382
- end
383
-
384
- def lineWidth
385
- return @lineWidth
386
- end
387
-
388
- def lineWidth=(x)
389
- @lineWidth = x
390
- @f.puts "%f setlinewidth" % [x * 0.5]
391
- end
392
-
393
- def initialize(app)
394
- @font = app.getNormalFont()
395
- end
396
-
397
- def font=(x)
398
- @font = x
399
- end
400
-
401
- def font
402
- return @font
403
- end
404
- end
1
+
2
+
3
+ #
4
+ # Class used to do Postscript printing. This class has only the basic
5
+ # functionality needed for doing so and replaces the still somewhat buggy
6
+ # version of Fox's 1.2 FXDCPrint
7
+ #
8
+ class FXDCPostscript < FXDC
9
+ @@printcmd = 'lpr -P%s -o l -' # -#%d'
10
+
11
+ def setContentRange(xmin, ymin, xmax, ymax)
12
+ @pxmin = xmin.to_f
13
+ @pymin = ymin.to_f
14
+ @pxmax = xmax.to_f
15
+ @pymax = ymax.to_f
16
+ end
17
+
18
+ # Transform point
19
+ def tfm(xi, yi)
20
+ pxrange = @pxmax - @pxmin
21
+ pyrange = @pymax - @pymin
22
+
23
+ if @flags & PRINT_LANDSCAPE != 0
24
+ mxmin = @ymin.to_f
25
+ mxmax = @ymax.to_f
26
+ mymin = @width - @xmax
27
+ mymax = @width - @xmin
28
+ mxrange = mxmax - mxmin
29
+ myrange = mymax - mymin
30
+ else
31
+ mxmin = @xmin
32
+ mxmax = @xmax
33
+ mymin = @ymin
34
+ mymax = @ymax
35
+ mxrange = mxmax-mxmin
36
+ myrange = mymax-mymin
37
+ end
38
+
39
+ if pyrange/pxrange <= myrange/mxrange
40
+ # short/wide
41
+ xo = mxmin + ((xi.to_f-@pxmin)/pxrange) * mxrange;
42
+ yo = mymin + 0.5 * (myrange-pyrange * (mxrange/pxrange)) +
43
+ (pyrange-yi.to_f) * (mxrange/pxrange)
44
+ else
45
+ # tall/thin
46
+ xo = mxmin + 0.5 * (mxrange-pxrange * (myrange/pyrange)) +
47
+ xi * (myrange/pyrange)
48
+ yo = mymin + ((pyrange-yi.to_f)/pyrange) * myrange
49
+ end
50
+ return [xo, yo]
51
+ end
52
+
53
+
54
+
55
+
56
+
57
+ def _header
58
+ @f.puts <<'HEADER'
59
+ %%!PS-Adobe-3.0
60
+ %%%%Title: Print Job
61
+ %%%%Creator: IFMapper
62
+ HEADER
63
+
64
+ end
65
+
66
+ def beginPrint(printer, &block)
67
+ @flags = printer.flags
68
+ if @flags & PRINT_DEST_FILE != 0
69
+ @f = File.open( printer.name, 'w' )
70
+ else
71
+ buffer = @@printcmd % [ printer.name, printer.numcopies ]
72
+ puts buffer
73
+ @f = File.popen( buffer, 'w')
74
+ end
75
+
76
+
77
+ @width = printer.mediawidth.to_f
78
+ @height = printer.mediaheight.to_f
79
+
80
+ @xmin = printer.leftmargin.to_f
81
+ @xmax = @width - printer.rightmargin
82
+
83
+ @ymin = printer.bottommargin.to_f
84
+ @ymax = @height - printer.topmargin
85
+
86
+
87
+ _header
88
+ if @flags & PRINT_NOBOUNDS != 0
89
+ xmin = 10000000.0
90
+ xmax = -xmin
91
+ ymin = 10000000.0
92
+ ymax = -ymin
93
+ @f.puts "%%%%BoundingBox: (atend)"
94
+ else
95
+ @f.puts "%%%%BoundingBox: %d %d %d %d" %
96
+ [ @xmin, @ymin, @xmax, @ymax ]
97
+ end
98
+
99
+ @numpages = 1 + printer.firstpage - printer.lastpage
100
+ if @flags & PRINT_PAGES_ODD
101
+ @numpages = 1 + (printer.topage - printer.frompage) / 2
102
+ elsif @flags & PRINT_PAGES_EVEN
103
+ @numpages = 1 + (printer.topage - printer.frompage) / 2
104
+ elsif @pages & PRINT_PAGES_RANGE
105
+ @numpages = 1 + printer.topage - printer.frompage
106
+ end
107
+
108
+ if @numpages == 0
109
+ @f.puts "%%%%Pages: (atend)"
110
+ else
111
+ @f.puts "%%%%Pages: #{@numpages}"
112
+ end
113
+
114
+ @f.puts "%%%%DocumentFonts:"
115
+ @f.puts "%%%%EndComments"
116
+ @f.puts "%%%%BeginProlog\n\n"
117
+
118
+ # Various definitions
119
+ @f.puts "%% h w x y drawRect\n"
120
+ @f.puts "/drawRect {\n\tnewpath moveto dup 0 rlineto exch dup 0 exch\n\trlineto exch neg 0 rlineto neg 0 exch rlineto\n\tclosepath stroke\n} def\n"
121
+ @f.puts "%% h w x y fillRect\n"
122
+ @f.puts "/fillRect {\n\tnewpath moveto dup 0 rlineto exch dup 0 exch\n\trlineto exch neg 0 rlineto neg 0 exch rlineto\n\tclosepath fill stroke\n} def\n"
123
+ @f.puts "%% x y a b drawLine\n"
124
+ @f.puts "/drawLine {\n\tnewpath moveto lineto stroke\n} def\n"
125
+ @f.puts "%% x y ..... npoints drawLines\n"
126
+ @f.puts "/drawLines {\n\t3 1 roll newpath moveto {lineto} repeat stroke\n} def\n"
127
+ @f.puts "%% x y a b ..... nsegments drawSegmt\n"
128
+ @f.puts "/drawSegmt {\n\tnewpath {\n\t\tmoveto lineto\n\t} repeat stroke\n} def\n"
129
+ @f.puts "%% x y drawPoint\n"
130
+ @f.puts "/drawPoint {\n\ttranslate 1 1 scale 8 8 1 [ 8 0 0 8 0 0 ] {<0000>} image\n} def\n"
131
+ @f.puts "%% centerx centery startAngle endAngle radiusX radiusY drawArc\n"
132
+ @f.puts "/drawArc {\n\tgsave dup 3 1 roll div dup 1 scale 6 -1 roll\n\texch div 5 1 roll 3 -2 roll arc stroke grestore\n} def\n"
133
+ @f.puts "/fillChord {\n\tgsave dup 3 1 roll div dup 1 scale 6 -1 roll\n\texch div 5 1 roll 3 -2 roll arc fill grestore\n} def\n"
134
+ @f.puts "%% (string) x y height drawText\n"
135
+ @f.puts "/drawText {\n\tgsave findfont exch scalefont setfont moveto\n\tshow grestore\n} def\n"
136
+
137
+
138
+ @f.puts "%%%%EndProlog"
139
+
140
+ @f.puts "%%%%BeginSetup"
141
+ @f.puts "/#copies #{printer.numcopies} def"
142
+ @f.puts "%%%%EndSetup"
143
+
144
+ @page = 0
145
+
146
+ if block_given?
147
+ yield self
148
+ endPrint()
149
+ end
150
+ end
151
+
152
+
153
+ def endPrint
154
+ @f.puts "%%%%Trailer\n"
155
+
156
+ # We now know the bounding box
157
+ if @flags & PRINT_NOBOUNDS != 0
158
+ if @xmin < @xmax and @ymin < @ymax
159
+ @f.puts "%%%%BoundingBox: %d %d %d %d" %
160
+ [ @xmin, @ymin, @xmax, @ymax ]
161
+ else
162
+ @f.puts "%%%%BoundingBox: 0 0 100 100"
163
+ end
164
+ end
165
+
166
+ # We now know the page count
167
+ if not (@flags & PRINT_PAGES_ODD|PRINT_PAGES_EVEN|PRINT_PAGES_RANGE)
168
+ @f.puts "%%%%Pages: #{page}"
169
+ end
170
+
171
+ @f.puts "%%%%EOF"
172
+ @f.close
173
+ end
174
+
175
+
176
+ def beginPage(num = 1, &block)
177
+ # Output page number
178
+ @f.puts "%%%%Page: #{@page} #{@page}" # Ghostscript requests this, I do not know if it is right
179
+
180
+ # Reset page bounding box
181
+ if @flags & PRINT_NOBOUNDS != 0
182
+ @xmin= 1000000;
183
+ @xmax=-1000000;
184
+ @ymin= 1000000;
185
+ @ymax=-1000000;
186
+ @f.puts "%%%%PageBoundingBox: (atend)"
187
+ else
188
+ # Use the doc bounding box
189
+ @f.puts "%%%%PageBoundingBox: %d %d %d %d" % [@xmin, @ymin, @xmax, @ymax]
190
+ end
191
+
192
+ # Page setup
193
+ @f.puts "%%%%BeginPageSetup"
194
+ @f.puts "%%%%EndPageSetup"
195
+ @f.puts "gsave"
196
+
197
+ # Maybe in landscape?
198
+ if @flags & PRINT_LANDSCAPE != 0
199
+ @f.puts "#{@width} 0.0 translate"
200
+ @f.puts "90 rotate"
201
+ end
202
+
203
+ if block_given?
204
+ yield self
205
+ endPage()
206
+ end
207
+ end
208
+
209
+ def endPage
210
+ @f.puts "%%%%PageTrailer"
211
+
212
+ # We now know the bounding box
213
+ if @flags & PRINT_NOBOUNDS != 0
214
+ if @xmin < @xmax and @ymin < @ymax
215
+ @f.puts "%%%%BoundingBox: %d %d %d %d" [@xmin, @ymin, @xmax, @ymax]
216
+ else
217
+ @f.puts "%%%%BoundingBox: 0 0 100 100" # Gotta come up with something...
218
+ end
219
+ end
220
+ @f.puts "showpage"
221
+ @f.puts "grestore"
222
+ @page += 1
223
+ end
224
+
225
+ # Extends bounding box with point x,y
226
+ def bbox(x, y)
227
+ @xmin = x if x < @xmin
228
+ @ymin = y if y < @ymin
229
+ @xmax = x if x > @xmax
230
+ @ymax = y if y > @ymax
231
+ end
232
+
233
+ def _rect(x, y, w, h)
234
+ xl, yt = tfm(x, y)
235
+ xr, yb = tfm(x + w - 1, y + h - 1)
236
+ bbox(xl,yt)
237
+ bbox(xr,yb)
238
+ @f.print "newpath %g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto " %
239
+ [xl,yt,xr,yt,xr,yb,xl,yb,xl,yt]
240
+ end
241
+
242
+ def drawRectangle(x, y, w, h)
243
+ _rect(x, y, w, h)
244
+ @f.puts "stroke"
245
+ end
246
+
247
+
248
+ def drawLine(x1, y1, x2, y2)
249
+ xx1, yy1 = tfm(x1, y1)
250
+ xx2, yy2 = tfm(x2, y2)
251
+ bbox(xx1,yy1)
252
+ bbox(xx2,yy2)
253
+ @f.puts "newpath %g %g moveto %g %g lineto stroke" % [xx1, yy1, xx2, yy2]
254
+ end
255
+
256
+ def drawLines(points)
257
+ return if points.size < 2
258
+ xx, yy = tfm(points[0].x, points[0].y)
259
+ bbox(xx,yy)
260
+ @f.print "newpath %g %g moveto" % [xx, yy]
261
+ 1.upto(points.size-1) { |i|
262
+ xx, yy = tfm(points[i].x, points[i].y)
263
+ bbox(xx,yy)
264
+ @f.print " %g %g lineto" % [xx, yy]
265
+ }
266
+ @f.puts " stroke"
267
+ end
268
+
269
+ def drawText(x, y, text)
270
+ # Draw string (only foreground bits)
271
+ # Contributed by S. Ancelot <sancelot@online.fr>
272
+ xx, yy = tfm( x, y )
273
+
274
+ pxrange = @pxmax - @pxmin
275
+ pyrange = @pymax - @pymin
276
+
277
+ if @flags & PRINT_LANDSCAPE != 0
278
+ mxmin = @ymin
279
+ mxmax = @ymax
280
+ mymin = @width - @xmax
281
+ mymax = @width - @xmin
282
+ mxrange = mxmax - mxmin
283
+ myrange = mymax - mymin
284
+ else
285
+ mxmin = @xmin
286
+ mxmax = @xmax
287
+ mymin = @ymin
288
+ mymax = @ymax
289
+ mxrange = mxmax - mxmin
290
+ myrange = mymax - mymin
291
+ end
292
+
293
+ fsize = 0.1 * @font.getSize
294
+
295
+ # Hack...
296
+ # Account for dpi and scale up or down with graph...
297
+ # Perhaps override screen resolution via registry
298
+ # FXint screenres=getApp()->reg().readUnsignedEntry("SETTINGS","screenres",100);
299
+ # Validate
300
+ screenres = 100
301
+ # if(screenres<50) screenres=50;
302
+ # if(screenres>200) screenres=200;
303
+
304
+ if pyrange / pxrange <= myrange / mxrange
305
+ # short/wide
306
+ fsize *= (mxrange/pxrange)*(screenres/72.0)
307
+ else
308
+ # tall/thin
309
+ fsize *= (myrange/pyrange)*(screenres/72.0)
310
+ end
311
+
312
+ fname = @font.name
313
+ if fname =~ /times/i
314
+ fname = 'Times-Roman'
315
+ elsif fname =~ /(helvetica|verdana|tahoma|arial)/i
316
+ fname = 'Helvetica'
317
+ else
318
+ fname = 'Courier'
319
+ end
320
+
321
+ if @font.getWeight == FXFont::FONTWEIGHT_BOLD
322
+ fname << '-Bold'
323
+ if @font.getSlant == FXFont::FONTSLANT_ITALIC
324
+ fname << 'Italic'
325
+ elsif @font.getSlant == FXFont::FONTSLANT_OBLIQUE
326
+ fname << 'Oblique'
327
+ end
328
+ else
329
+ if @font.getSlant == FXFont::FONTSLANT_ITALIC
330
+ fname << '-Italic'
331
+ elsif @font.getSlant == FXFont::FONTSLANT_OBLIQUE
332
+ fname << '-Oblique'
333
+ end
334
+ end
335
+
336
+ @f.puts "(%s) %g %g %d /%s drawText" % [text, xx, yy, fsize, fname]
337
+ end
338
+
339
+ def fillRectangle(x, y, w, h)
340
+ _rect(x, y, w, h)
341
+ @f.puts "fill"
342
+ end
343
+
344
+ def fillPolygon(points)
345
+ return if points.size < 3
346
+ xx, yy = tfm(points[0].x, points[0].y)
347
+ bbox(xx,yy)
348
+ @f.print "newpath %g %g moveto" % [ xx, yy ]
349
+ 1.upto(points.size-1) { |i|
350
+ xx, yy = tfm(points[i].x, points[i].y)
351
+ bbox(xx,yy)
352
+ @f.print " %g %g lineto" % [ xx, yy ]
353
+ }
354
+ @f.puts " fill"
355
+ end
356
+
357
+ def lineStyle=(x)
358
+ if x == LINE_SOLID
359
+ @f.puts "[ ] 0 setdash"
360
+ elsif x == LINE_ONOFF_DASH
361
+ @f.puts "[2 2] 0 setdash"
362
+ end
363
+ end
364
+
365
+ def foreground=(c)
366
+ if c.kind_of?(String)
367
+ clr = fxcolorfromname(c)
368
+ else
369
+ clr = c
370
+ end
371
+ @f.puts "%g %g %g setrgbcolor" % [FXREDVAL(clr)/255.0,FXGREENVAL(clr)/255.0,FXBLUEVAL(clr)/255.0]
372
+ end
373
+
374
+ def lineJoin=(x)
375
+ end
376
+
377
+ def lineCap=(x)
378
+ ncap = 0
379
+ ncap = 1 if CAP_ROUND == x
380
+ ncap = 3 if CAP_PROJECTING == x
381
+ @f.puts "#{ncap} setlinecap"
382
+ end
383
+
384
+ def lineWidth
385
+ return @lineWidth
386
+ end
387
+
388
+ def lineWidth=(x)
389
+ @lineWidth = x
390
+ @f.puts "%f setlinewidth" % [x * 0.5]
391
+ end
392
+
393
+ def initialize(app)
394
+ @font = app.getNormalFont()
395
+ end
396
+
397
+ def font=(x)
398
+ @font = x
399
+ end
400
+
401
+ def font
402
+ return @font
403
+ end
404
+ end