cyross-ruby-miyako 2.0.5.1.0 → 2.1.0

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 (91) hide show
  1. data/README +1092 -929
  2. data/Rakefile +7 -7
  3. data/defines.h +144 -144
  4. data/extern.h +29 -29
  5. data/install_miyako.rb +87 -87
  6. data/lib/Miyako/API/audio.rb +572 -198
  7. data/lib/Miyako/API/basic_data.rb +825 -573
  8. data/lib/Miyako/API/bitmap.rb +534 -507
  9. data/lib/Miyako/API/choices.rb +481 -475
  10. data/lib/Miyako/API/collision.rb +486 -460
  11. data/lib/Miyako/API/diagram.rb +586 -561
  12. data/lib/Miyako/API/drawing.rb +151 -151
  13. data/lib/Miyako/API/exceptions.rb +105 -0
  14. data/lib/Miyako/API/fixedmap.rb +462 -428
  15. data/lib/Miyako/API/font.rb +430 -403
  16. data/lib/Miyako/API/input.rb +456 -447
  17. data/lib/Miyako/API/layout.rb +636 -433
  18. data/lib/Miyako/API/map.rb +583 -529
  19. data/lib/Miyako/API/map_event.rb +222 -198
  20. data/lib/Miyako/API/modules.rb +357 -109
  21. data/lib/Miyako/API/movie.rb +166 -154
  22. data/lib/Miyako/API/parts.rb +276 -189
  23. data/lib/Miyako/API/plane.rb +205 -166
  24. data/lib/Miyako/API/screen.rb +341 -325
  25. data/lib/Miyako/API/shape.rb +443 -443
  26. data/lib/Miyako/API/sprite.rb +771 -752
  27. data/lib/Miyako/API/sprite_animation.rb +490 -481
  28. data/lib/Miyako/API/sprite_list.rb +1135 -0
  29. data/lib/Miyako/API/spriteunit.rb +168 -147
  30. data/lib/Miyako/API/story.rb +350 -300
  31. data/lib/Miyako/API/textbox.rb +770 -725
  32. data/lib/Miyako/API/utility.rb +419 -388
  33. data/lib/Miyako/API/viewport.rb +189 -139
  34. data/lib/Miyako/API/yuki.rb +1226 -996
  35. data/lib/Miyako/EXT/miyako_cairo.rb +62 -62
  36. data/lib/Miyako/EXT/raster_scroll.rb +138 -138
  37. data/lib/Miyako/EXT/slides.rb +157 -157
  38. data/lib/Miyako/miyako.rb +201 -171
  39. data/lib/Miyako/miyako_require_only.rb +35 -0
  40. data/miyako_basicdata.c +590 -590
  41. data/miyako_bitmap.c +1225 -1225
  42. data/miyako_collision.c +403 -403
  43. data/miyako_drawing.c +187 -187
  44. data/miyako_font.c +334 -334
  45. data/miyako_hsv.c +830 -830
  46. data/miyako_input_audio.c +254 -0
  47. data/miyako_layout.c +191 -191
  48. data/miyako_no_katana.c +1078 -1074
  49. data/miyako_sprite2.c +431 -0
  50. data/miyako_transform.c +438 -438
  51. data/miyako_utility.c +288 -288
  52. data/sample/Animation1/m1ku.rb +68 -68
  53. data/sample/Animation2/lex.rb +96 -96
  54. data/sample/Diagram_sample/diagram_sample_yuki2.rb +328 -386
  55. data/sample/Room3/blue.rb +297 -297
  56. data/sample/Room3/ending.rb +180 -180
  57. data/sample/Room3/green.rb +220 -220
  58. data/sample/Room3/main.rb +119 -119
  59. data/sample/Room3/main_component.rb +59 -59
  60. data/sample/Room3/red.rb +227 -227
  61. data/sample/Room3/room3.rb +25 -27
  62. data/sample/Room3/title.rb +184 -184
  63. data/sample/ball_action_sample.rb +204 -204
  64. data/sample/blit_rop.rb +70 -70
  65. data/sample/cairo_sample.rb +25 -25
  66. data/sample/circle_collision_test.rb +66 -66
  67. data/sample/collision_test.rb +33 -33
  68. data/sample/collision_test2.rb +108 -108
  69. data/sample/fixed_map_test/fixed_map_sample.rb +140 -140
  70. data/sample/fixed_map_test/readme.txt +72 -72
  71. data/sample/map_test/chara.rb +58 -58
  72. data/sample/map_test/main_parts.rb +69 -69
  73. data/sample/map_test/main_scene.rb +153 -153
  74. data/sample/map_test/map_manager.rb +75 -75
  75. data/sample/map_test/map_test.rb +23 -23
  76. data/sample/map_test/oasis.rb +71 -71
  77. data/sample/map_test/readme.txt +89 -89
  78. data/sample/map_test/route.rb +157 -157
  79. data/sample/map_test/town.rb +74 -74
  80. data/sample/polygon_test.rb +35 -35
  81. data/sample/rasterscroll.rb +24 -24
  82. data/sample/takahashi.rb +42 -42
  83. data/sample/textbox_sample.rb +189 -189
  84. data/sample/transform.rb +54 -54
  85. data/sample/utility_test.rb +73 -73
  86. data/sample/utility_test2.rb +61 -61
  87. data/sample/utility_test3.rb +64 -64
  88. data/sample/utility_test4.rb +73 -73
  89. data/uninstall_miyako.rb +19 -19
  90. data/win/miyako_no_katana.so +0 -0
  91. metadata +7 -2
@@ -1,403 +1,430 @@
1
- # -*- encoding: utf-8 -*-
2
- =begin
3
- --
4
- Miyako v2.0
5
- Copyright (C) 2007-2009 Cyross Makoto
6
-
7
- This library is free software; you can redistribute it and/or
8
- modify it under the terms of the GNU Lesser General Public
9
- License as published by the Free Software Foundation; either
10
- version 2.1 of the License, or (at your option) any later version.
11
-
12
- This library is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
- Lesser General Public License for more details.
16
-
17
- You should have received a copy of the GNU Lesser General Public
18
- License along with this library; if not, write to the Free Software
19
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
- ++
21
- =end
22
-
23
- # フォント関連クラス(群)
24
- module Miyako
25
-
26
- =begin rdoc
27
- ==フォント管理クラス
28
- フォントは、等幅フォント奨励(プロポーショナルフォントを選ぶと、文字が正しく描画されない可能性あり)
29
- =end
30
- class Font
31
- extend Forwardable
32
-
33
- # OS_MAC_OS_X = "mac_osx"
34
- # ORG_ENC = "UTF-8"
35
- # NEW_ENC = "UTF-8-MAC"
36
-
37
- attr_reader :size, :line_skip, :height, :ascent, :descent
38
- attr_accessor :color, :use_shadow, :shadow_color, :shadow_margin, :vspace, :hspace
39
-
40
- @@font_cache = {}
41
-
42
- @@name_2_font_path = Hash.new
43
-
44
- @@font_base_path = Hash.new
45
- @@font_base_path["win"] = ENV['SystemRoot'] ? ["./", ENV['SystemRoot'].tr("\\", "/") + "/fonts/"] : ["./"]
46
- @@font_base_path["linux"] = ["./", "/usr/share/fonts/", "/usr/X11R6/lib/X11/fonts/"]
47
- @@font_base_path["mac_osx"] = ["./", "~/Library/Fonts/", "/Library/Fonts/", "/System/Library/Fonts/",
48
- "/ライブラリ/Fonts/", "/システム/ライブラリ/Fonts/"]
49
-
50
- @@font_base_name = Hash.new
51
- @@font_base_name["win"] = [{:serif=>"msmincho.ttc", :sans_serif=>"msgothic.ttc"},
52
- {:serif=>"VL-Gothic-Regular.ttf", :sans_serif=>"VL-Gothic-Regular.ttf"},
53
- {:serif=>"umeplus-gothic.ttf", :sans_serif=>"umeplus-gothic.ttf"},
54
- {:serif=>"msmincho.ttc", :sans_serif=>"meiryo.ttc"}]
55
- @@font_base_name["linux"] = [{:serif=>"sazanami-mincho.ttf", :sans_serif=>"sazanami-gothic.ttf"},
56
- {:serif=>"VL-Gothic-Regular.ttf", :sans_serif=>"VL-Gothic-Regular.ttf"},
57
- {:serif=>"umeplus-gothic.ttf", :sans_serif=>"umeplus-gothic.ttf"}]
58
- @@font_base_name["mac_osx"] = [{:serif=>"Hiragino Mincho Pro W3.otf", :sans_serif=>"Hiragino Kaku Gothic Pro W3.otf"},
59
- {:serif=>"Hiragino Mincho Pro W6.otf", :sans_serif=>"Hiragino Kaku Gothic Pro W6.otf"},
60
- {:serif=>"ヒラギノ明朝 Pro W3.otf", :sans_serif=>"ヒラギノ角ゴ Pro W3.otf"},
61
- {:serif=>"ヒラキ゛ノ明朝 Pro W3.otf", :sans_serif=>"ヒラキ゛ノ角コ゛ Pro W3.otf"},
62
- {:serif=>"ヒラギノ明朝 Pro W6.otf", :sans_serif=>"ヒラギノ角ゴ Pro W6.otf"},
63
- {:serif=>"ヒラキ゛ノ明朝 Pro W6.otf", :sans_serif=>"ヒラキ゛ノ角コ゛ Pro W6.otf"},
64
- {:serif=>"VL-Gothic-Regular.ttf", :sans_serif=>"VL-Gothic-Regular.ttf"},
65
- {:serif=>"umeplus-gothic.ttf", :sans_serif=>"umeplus-gothic.ttf"}]
66
-
67
- def Font.search_font_path_file(hash, path) #:nodoc:
68
- Dir.glob(path+"*"){|d|
69
- hash = Font.search_font_path_file(hash, d+"/") if test(?d, d)
70
- d = d.encode(Encoding::UTF_8) if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
71
- d = d.tr("\\", "\/")
72
- hash[$1] = d if (d =~ /\/([^\/\.]+\.tt[fc])\z/ || d =~ /\/([^\/\.]+\.otf)\z/) # MacOSX対応
73
- }
74
- return hash
75
- end
76
-
77
- def Font.create_font_path #:nodoc:
78
- osn = Miyako::getOSName
79
- @@font_base_path[osn].each{|path|
80
- path = path.encode(Encoding::UTF_8) if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
81
- path = path.tr("\\", "\/")
82
- @@name_2_font_path = Font.search_font_path_file(@@name_2_font_path, path)
83
- }
84
- end
85
-
86
- def Font.findFontPath(fname) #:nodoc:
87
- fname = fname.encode(Encoding::UTF_8) if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
88
- return @@name_2_font_path.fetch(fname, nil)
89
- end
90
-
91
- def Font.get_font_inner(fname, fpath, size=16) #:nodoc:
92
- if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
93
- fname = fname.encode(Encoding::UTF_8)
94
- fpath = fpath.encode(Encoding::UTF_8)
95
- end
96
- @@font_cache[fname] ||= {}
97
- @@font_cache[fname][size] ||= SDL::TTF.open(fpath, size)
98
- return @@font_cache[fname][size]
99
- end
100
-
101
- def init_height #:nodoc:
102
- @line_skip = @font.line_skip
103
- @height = @font.height
104
- @ascent = @font.ascent
105
- @descent = @font.descent
106
- end
107
-
108
- private :init_height
109
-
110
- #===インスタンス生成
111
- #指定したフォントファイル名から、フォントインスタンスを生成する。
112
- #フォントファイルのパスは、Miyako2.0起動時にファイルパス(カレントディレクトリとシステムのフォントディレクトリ)
113
- #再帰的に検索し、先に見つけた方を採用する(同一ファイル名がカレントディレクトリとシステムのディレクトリに両方
114
- #存在するときは、カレントディレクトリを優先する)
115
- #そのため、フォントファイル名は、パスを指定する必要がない(逆に言うと、パスを指定すると例外が発生する)。
116
- #_fname_:: フォントファイル名(フォントファミリー名不可)。パス指定不可
117
- #_size_:: フォントの大きさ。単位はピクセル。デフォルトは 16
118
- #返却値:: 生成されたインスタンスを返す
119
- def initialize(fname, size=16)
120
- @size = size
121
- @color = [255, 255, 255]
122
- @fname = fname
123
- @vspace = 0
124
- @hspace = 0
125
- @bold = false
126
- @italic = false
127
- @under_line = false
128
- @fpath = Font.findFontPath(@fname) or raise MiyakoError, "Cannot Find Font! : #{@fname}"
129
- @font = Font.get_font_inner(@fname, @fpath, @size)
130
- @font.style = SDL::TTF::STYLE_NORMAL
131
- init_height
132
- @use_shadow = false
133
- @shadow_color = [128, 128, 128]
134
- @shadow_margin = [2, 2]
135
- @unit = SpriteUnitFactory.create
136
- end
137
-
138
- #===フォントの大きさを変更する
139
- #_sz_:: 変更するフォントの大きさ(単位:ピクセル)
140
- #返却値:: 変更されたフォントのインスタンス
141
- def size=(sz)
142
- @size = sz
143
- @font = Font.get_font_inner(@fname, @fpath, @size)
144
- @font.style = (@bold ? SDL::TTF::STYLE_BOLD : 0) | (@italic ? SDL::TTF::STYLE_ITALIC : 0) | (@under_line ? SDL::TTF::STYLE_UNDERLINE : 0)
145
- init_height
146
- return self
147
- end
148
-
149
- #===ブロック評価中のみ、フォントの大きさを変更する
150
- #_sz_:: 変更するフォントの大きさ(単位:ピクセル)
151
- #返却値:: 自分自身を返す
152
- def size_during(sz)
153
- raise MiyakoError, "not given block!" unless block_given?
154
- tsize = @size
155
- self.size = sz
156
- yield
157
- self.size = tsize
158
- return self
159
- end
160
-
161
- #===ブロック評価中のみ、フォントの文字の色を変更する
162
- #_color_:: 変更する色([r,g,b]の3要素の配列(値:0~255))
163
- #返却値:: 自分自身を返す
164
- def color_during(color)
165
- raise MiyakoError, "not given block!" unless block_given?
166
- tcolor, self.color = @color, color
167
- yield
168
- self.color = tcolor
169
- return self
170
- end
171
-
172
- #===ブロック評価中のみ、影文字文字の色・マージンを変更する
173
- #また、ブロック評価中は影文字が強制的に有効になる
174
- #_color_:: 変更する色([r,g,b]の3要素の配列(値:0~255))、デフォルトはFont#shadow_colorメソッドの値([128,128,128])
175
- #_margin_:: 変更する色(2要素の整数の配列、デフォルトはFont#shadow_marginメソッドの値([2,2])
176
- #返却値:: 自分自身を返す
177
- def shadow_during(color = @shadow_color, margin = @shadow_margin)
178
- raise MiyakoError, "not given block!" unless block_given?
179
- tflag, @use_shadow = @use_shadow, true
180
- tcolor, @shadow_color = @shadow_color, color
181
- tmargin, @shadow_margin = @shadow_margin, margin
182
- yield
183
- @use_shadow = tflag
184
- @shadow_color = tcolor
185
- @shadow_margin = tmargin
186
- return self
187
- end
188
-
189
- #===指定したピクセル数のフォントが十分(欠けることなく)収まるピクセル数を取得する
190
- #_size_:: フォントの大きさ(単位:ピクセル)
191
- #返却値:: 算出されたピクセル数
192
- def get_fit_size(size)
193
- path = Font.findFontPath(@fname)
194
- font = SDL::TTF.open(path, size)
195
- return (size.to_f * (size.to_f / font.line_skip.to_f)).to_i
196
- end
197
-
198
- #===フォントサイズ(yやjなどの下にはみ出る箇所も算出)を取得する
199
- #返却値:: 算出されたフォントサイズ
200
- def line_height
201
- return @line_skip + @vspace + (@use_shadow ? @shadow_margin[1] : 0)
202
- end
203
-
204
- #===フォントインスタンスを解放する
205
- def dispose
206
- @font = nil
207
- end
208
-
209
- #===フォントの属性をbold(太文字)に設定する
210
- #ブロックを渡したときは、ブロック評価中のみ太字になる
211
- #文字が領域外にはみ出る場合があるので注意!
212
- #返却値:: 自分自身
213
- def bold
214
- if block_given?
215
- tbold, self.bold = self.bold?, true
216
- yield
217
- self.bold = tbold
218
- else
219
- self.bold = true
220
- end
221
- return self
222
- end
223
-
224
- #===フォントのbold属性の有無を返す
225
- #返却値:: bold属性かどうか(true/false)
226
- def bold?
227
- return @bold
228
- end
229
-
230
- #===フォントのbold属性を設定する
231
- #_f_:: bold属性かどうか(true/false)
232
- def bold=(f)
233
- @bold = f
234
- @font.style |= SDL::TTF::STYLE_BOLD
235
- @font.style -= SDL::TTF::STYLE_BOLD unless @bold
236
- return self
237
- end
238
-
239
- #===フォントの属性をitalic(斜め)に設定する
240
- #ブロックを渡したときは、ブロック評価中のみ斜体文字になる
241
- #文字が領域外にはみ出る場合があるので注意!
242
- #返却値:: 自分自身
243
- def italic
244
- if block_given?
245
- titalic, self.italic = self.italic?, true
246
- yield
247
- self.italic = titalic
248
- else
249
- self.italic = true
250
- end
251
- return self
252
- end
253
-
254
- #===フォントのitalic属性の有無を返す
255
- #返却値:: italic属性かどうか(true/false)
256
- def italic?
257
- return @italic
258
- end
259
-
260
- #===フォントのitalic属性を設定する
261
- #_f_:: italic属性かどうか(true/false)
262
- def italic=(f)
263
- @italic = f
264
- @font.style |= SDL::TTF::STYLE_ITALIC
265
- @font.style -= SDL::TTF::STYLE_ITALIC unless @italic
266
- return self
267
- end
268
-
269
- #===フォントの属性をunder_line(下線)に設定する
270
- #ブロックを渡したときは、ブロック評価中のみ下線付き文字になる
271
- #返却値:: 自分自身
272
- def under_line
273
- if block_given?
274
- tunder_line, self.under_line = self.under_line?, true
275
- yield
276
- self.under_line = tunder_line
277
- else
278
- self.under_line = true
279
- end
280
- return self
281
- end
282
-
283
- #===フォントのunder_line属性の有無を返す
284
- #返却値:: under_line属性かどうか(true/false)
285
- def under_line?
286
- return @under_line
287
- end
288
-
289
- #===フォントのunder_line属性を設定する
290
- #_f_:: under_line属性かどうか(true/false)
291
- def under_line=(f)
292
- @under_line = f
293
- @font.style |= SDL::TTF::STYLE_UNDERLINE
294
- @font.style -= SDL::TTF::STYLE_UNDERLINE unless @under_line
295
- return self
296
- end
297
-
298
- #===フォントの属性をすべてクリアする
299
- #_f_:: 自分自身
300
- def normal
301
- @font.style = 0
302
- return self
303
- end
304
-
305
- #===文字列を描画する
306
- #対象のスプライトに文字列を描画する
307
- #_dst_:: 描画先スプライト
308
- #_str_:: 描画する文字列
309
- #_x_:: 描画位置x軸
310
- #_y_:: 描画位置Y軸
311
- def draw_text(dst, str, x, y)
312
- str = str.encode(Encoding::UTF_8)
313
- str.chars{|c|
314
- if @use_shadow
315
- src2 = @font.renderBlendedUTF8(c, @shadow_color[0], @shadow_color[1], @shadow_color[2])
316
- if src2
317
- SpriteUnitFactory.apply(@unit, {:bitmap=>src2, :ow=>src2.w, :oh=>src2.h})
318
- Miyako::Bitmap.blit_aa(@unit, dst.to_unit, x+@shadow_margin[0], y+@shadow_margin[1])
319
- else
320
- break x
321
- end
322
- end
323
- src = @font.renderBlendedUTF8(c, @color[0], @color[1], @color[2])
324
- if src
325
- SpriteUnitFactory.apply(@unit, {:bitmap=>src, :ow=>src.w, :oh=>src.h})
326
- Miyako::Bitmap.blit_aa(@unit, dst.to_unit, x, y)
327
- else
328
- break x
329
- end
330
- x += chr_size_inner(c)
331
- }
332
- return x
333
- end
334
-
335
- #===文字列描画したときの大きさを取得する
336
- #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
337
- #_txt_:: 算出したい文字列
338
- #返却値:: 文字列を描画したときの大きさ([w,h]の配列)
339
- def chr_size_inner(char)
340
- return (char.bytesize == 1 ? @size >> 1 : @size) + (@use_shadow ? @shadow_margin[0] : 0) + @hspace
341
- end
342
-
343
- private :chr_size_inner
344
-
345
- #===文字列描画したときの大きさを取得する
346
- #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
347
- #_txt_:: 算出したい文字列
348
- #返却値:: 文字列を描画したときの大きさ([w,h]の配列)
349
- def text_size(txt)
350
- width = txt.chars.inject(0){|r, c|
351
- r += (c.bytesize == 1 ? @size >> 1 : @size) } +
352
- ((@use_shadow ? @shadow_margin[0] : 0) + @hspace) * (txt.chars.to_a.length - 1)
353
- return [width, self.line_height]
354
- end
355
-
356
- #===指定した高さで描画する際のマージンを求める
357
- #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
358
- #第1引数に渡す"align"は、以下の3種類のシンボルのどれかを渡す
359
- #:top:: 上側に描画(マージンはゼロ)
360
- #:middle:: 中間に描画
361
- #:bottom:: 下部に描画
362
- #
363
- #_align_:: 描画位置
364
- #_height_:: 描画する高さ
365
- #返却値:: マージンの値
366
- def margin_height(align, height)
367
- case align
368
- when :top
369
- return 0
370
- when :middle
371
- return (height - self.line_height) >> 1
372
- when :bottom
373
- return height - self.line_height
374
- end
375
- #else
376
- raise MiyakoError, "Illegal margin_height align! : #{align}"
377
- end
378
-
379
- Font.create_font_path
380
-
381
- #===Serifフォント(明朝フォント)を取得する
382
- #マルチプラットフォームのソフトを作る際、OS間の差異を吸収するため、
383
- #共通の名称でフォントインスタンスを取得するときに使う(主に明朝フォント)
384
- #返却値:: OSごとに設定されたフォントイン寸タンス(フォントサイズは16)
385
- def Font::serif
386
- filename = @@font_base_name[Miyako::getOSName].detect{|base| Font.findFontPath(base[:serif]) }[:serif]
387
- return Font.new(filename)
388
- end
389
-
390
- #===Sans Serifフォント(ゴシックフォント)を取得する
391
- #マルチプラットフォームのソフトを作る際、OS間の差異を吸収するため、
392
- #共通の名称でフォントインスタンスを取得するときに使う(主にゴシックフォント)
393
- #返却値:: OSごとに設定されたフォントイン寸タンス(フォントサイズは16)
394
- def Font::sans_serif
395
- filename = @@font_base_name[Miyako::getOSName].detect{|base| Font.findFontPath(base[:sans_serif]) }[:sans_serif]
396
- return Font.new(filename)
397
- end
398
-
399
- def Font::system_font #:nodoc:
400
- return Font.serif
401
- end
402
- end
403
- end
1
+ # -*- encoding: utf-8 -*-
2
+ =begin
3
+ --
4
+ Miyako v2.1
5
+ Copyright (C) 2007-2009 Cyross Makoto
6
+
7
+ This library is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU Lesser General Public
9
+ License as published by the Free Software Foundation; either
10
+ version 2.1 of the License, or (at your option) any later version.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public
18
+ License along with this library; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ ++
21
+ =end
22
+
23
+ # フォント関連クラス(群)
24
+ module Miyako
25
+
26
+ =begin rdoc
27
+ ==フォント管理クラス
28
+ フォントは、等幅フォント奨励(プロポーショナルフォントを選ぶと、文字が正しく描画されない可能性あり)
29
+ =end
30
+ class Font
31
+ extend Forwardable
32
+
33
+ # OS_MAC_OS_X = "mac_osx"
34
+ # ORG_ENC = "UTF-8"
35
+ # NEW_ENC = "UTF-8-MAC"
36
+
37
+ attr_reader :size, :line_skip, :height, :ascent, :descent
38
+ attr_accessor :color, :use_shadow, :shadow_color, :shadow_margin, :vspace, :hspace
39
+
40
+ @@font_cache = {}
41
+
42
+ @@name_2_font_path = Hash.new
43
+
44
+ @@font_base_path = Hash.new
45
+ @@font_base_path["win"] = ENV['SystemRoot'] ? ["./", ENV['SystemRoot'].tr("\\", "/") + "/fonts/"] : ["./"]
46
+ @@font_base_path["linux"] = ["./", "/usr/share/fonts/", "/usr/X11R6/lib/X11/fonts/"]
47
+ @@font_base_path["mac_osx"] = ["./", "~/Library/Fonts/", "/Library/Fonts/", "/System/Library/Fonts/",
48
+ "/ライブラリ/Fonts/", "/システム/ライブラリ/Fonts/"]
49
+
50
+ @@font_base_name = Hash.new
51
+ @@font_base_name["win"] = [{:serif=>"msmincho.ttc", :sans_serif=>"msgothic.ttc"},
52
+ {:serif=>"VL-Gothic-Regular.ttf", :sans_serif=>"VL-Gothic-Regular.ttf"},
53
+ {:serif=>"umeplus-gothic.ttf", :sans_serif=>"umeplus-gothic.ttf"},
54
+ {:serif=>"msmincho.ttc", :sans_serif=>"meiryo.ttc"}]
55
+ @@font_base_name["linux"] = [{:serif=>"sazanami-mincho.ttf", :sans_serif=>"sazanami-gothic.ttf"},
56
+ {:serif=>"VL-Gothic-Regular.ttf", :sans_serif=>"VL-Gothic-Regular.ttf"},
57
+ {:serif=>"umeplus-gothic.ttf", :sans_serif=>"umeplus-gothic.ttf"}]
58
+ @@font_base_name["mac_osx"] = [{:serif=>"Hiragino Mincho Pro W3.otf", :sans_serif=>"Hiragino Kaku Gothic Pro W3.otf"},
59
+ {:serif=>"Hiragino Mincho Pro W6.otf", :sans_serif=>"Hiragino Kaku Gothic Pro W6.otf"},
60
+ {:serif=>"ヒラギノ明朝 Pro W3.otf", :sans_serif=>"ヒラギノ角ゴ Pro W3.otf"},
61
+ {:serif=>"ヒラキ゛ノ明朝 Pro W3.otf", :sans_serif=>"ヒラキ゛ノ角コ゛ Pro W3.otf"},
62
+ {:serif=>"ヒラギノ明朝 Pro W6.otf", :sans_serif=>"ヒラギノ角ゴ Pro W6.otf"},
63
+ {:serif=>"ヒラキ゛ノ明朝 Pro W6.otf", :sans_serif=>"ヒラキ゛ノ角コ゛ Pro W6.otf"},
64
+ {:serif=>"VL-Gothic-Regular.ttf", :sans_serif=>"VL-Gothic-Regular.ttf"},
65
+ {:serif=>"umeplus-gothic.ttf", :sans_serif=>"umeplus-gothic.ttf"}]
66
+ @@initialized = false
67
+
68
+ #===フォント関連の初期化処理
69
+ #既に初期化済みの時はMiyakoErrorが発生する
70
+ def Font.init
71
+ raise MiyakoError, "Already initialized!" if @@initialized
72
+ SDL::TTF.init
73
+ Font.create_font_path
74
+ @@initialized = true
75
+ end
76
+
77
+ #===フォント周辺の初期化がされた?
78
+ def Font.initialized?
79
+ @@initialized
80
+ end
81
+
82
+ def Font.search_font_path_file(hash, path) #:nodoc:
83
+ Dir.glob(path+"*"){|d|
84
+ hash = Font.search_font_path_file(hash, d+"/") if test(?d, d)
85
+ d = d.encode(Encoding::UTF_8) if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
86
+ d = d.tr("\\", "\/")
87
+ hash[$1] = d if (d =~ /\/([^\/\.]+\.tt[fc])\z/ || d =~ /\/([^\/\.]+\.otf)\z/) # MacOSX対応
88
+ }
89
+ return hash
90
+ end
91
+
92
+ def Font.create_font_path #:nodoc:
93
+ osn = Miyako::getOSName
94
+ @@font_base_path[osn].each{|path|
95
+ path = path.encode(Encoding::UTF_8) if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
96
+ path = path.tr("\\", "\/")
97
+ @@name_2_font_path = Font.search_font_path_file(@@name_2_font_path, path)
98
+ }
99
+ end
100
+
101
+ def Font.findFontPath(fname) #:nodoc:
102
+ fname = fname.encode(Encoding::UTF_8) if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
103
+ return @@name_2_font_path.fetch(fname, nil)
104
+ end
105
+
106
+ def Font.get_font_inner(fname, fpath, size=16) #:nodoc:
107
+ if Miyako.getOSName == "mac_osx" # MacOSXはパス名がUTF-8固定のため
108
+ fname = fname.encode(Encoding::UTF_8)
109
+ fpath = fpath.encode(Encoding::UTF_8)
110
+ end
111
+ @@font_cache[fname] ||= {}
112
+ @@font_cache[fname][size] ||= SDL::TTF.open(fpath, size)
113
+ return @@font_cache[fname][size]
114
+ end
115
+
116
+ def init_height #:nodoc:
117
+ @line_skip = @font.line_skip
118
+ @height = @font.height
119
+ @ascent = @font.ascent
120
+ @descent = @font.descent
121
+ end
122
+
123
+ private :init_height
124
+
125
+ #===インスタンス生成
126
+ #指定したフォントファイル名から、フォントインスタンスを生成する。
127
+ #フォントファイルのパスは、Miyako2.0起動時にファイルパス(カレントディレクトリとシステムのフォントディレクトリ)を
128
+ #再帰的に検索し、先に見つけた方を採用する(同一ファイル名がカレントディレクトリとシステムのディレクトリに両方
129
+ #存在するときは、カレントディレクトリを優先する)
130
+ #そのため、フォントファイル名は、パスを指定する必要がない(逆に言うと、パスを指定すると例外が発生する)。
131
+ #_fname_:: フォントファイル名(フォントファミリー名不可)。パス指定不可
132
+ #_size_:: フォントの大きさ。単位はピクセル。デフォルトは 16
133
+ #返却値:: 生成されたインスタンスを返す
134
+ def initialize(fname, size=16)
135
+ @size = size
136
+ @color = [255, 255, 255]
137
+ @fname = fname
138
+ @vspace = 0
139
+ @hspace = 0
140
+ @bold = false
141
+ @italic = false
142
+ @under_line = false
143
+ @fpath = Font.findFontPath(@fname) or raise MiyakoIOError.new(@fname)
144
+ @font = Font.get_font_inner(@fname, @fpath, @size)
145
+ @font.style = SDL::TTF::STYLE_NORMAL
146
+ init_height
147
+ @use_shadow = false
148
+ @shadow_color = [128, 128, 128]
149
+ @shadow_margin = [2, 2]
150
+ @unit = SpriteUnitFactory.create
151
+ end
152
+
153
+ def initialize_copy(obj) #:nodoc:
154
+ @size = @size.dup
155
+ @color = @color.dup
156
+ @fname = @fname.dup
157
+ @shadow_color = @shadow_color.dup
158
+ @shadow_margin = @shadow_margin.dup
159
+ @unit = @unit.dup
160
+ end
161
+
162
+ #===フォントの大きさを変更する
163
+ #_sz_:: 変更するフォントの大きさ(単位:ピクセル)
164
+ #返却値:: 変更されたフォントのインスタンス
165
+ def size=(sz)
166
+ @size = sz
167
+ @font = Font.get_font_inner(@fname, @fpath, @size)
168
+ @font.style = (@bold ? SDL::TTF::STYLE_BOLD : 0) |
169
+ (@italic ? SDL::TTF::STYLE_ITALIC : 0) |
170
+ (@under_line ? SDL::TTF::STYLE_UNDERLINE : 0)
171
+ init_height
172
+ return self
173
+ end
174
+
175
+ #===ブロック評価中のみ、フォントの大きさを変更する
176
+ #_sz_:: 変更するフォントの大きさ(単位:ピクセル)
177
+ #返却値:: 自分自身を返す
178
+ def size_during(sz)
179
+ raise MiyakoError, "not given block!" unless block_given?
180
+ tsize = @size
181
+ self.size = sz
182
+ yield
183
+ self.size = tsize
184
+ return self
185
+ end
186
+
187
+ #===ブロック評価中のみ、フォントの文字の色を変更する
188
+ #_color_:: 変更する色([r,g,b]の3要素の配列(値:0~255))
189
+ #返却値:: 自分自身を返す
190
+ def color_during(color)
191
+ raise MiyakoError, "not given block!" unless block_given?
192
+ tcolor, self.color = @color, color
193
+ yield
194
+ self.color = tcolor
195
+ return self
196
+ end
197
+
198
+ #===ブロック評価中のみ、影文字文字の色・マージンを変更する
199
+ #また、ブロック評価中は影文字が強制的に有効になる
200
+ #_color_:: 変更する色([r,g,b]の3要素の配列(値:0~255))、デフォルトはFont#shadow_colorメソッドの値([128,128,128])
201
+ #_margin_:: 変更する色(2要素の整数の配列、デフォルトはFont#shadow_marginメソッドの値([2,2])
202
+ #返却値:: 自分自身を返す
203
+ def shadow_during(color = @shadow_color, margin = @shadow_margin)
204
+ raise MiyakoError, "not given block!" unless block_given?
205
+ tflag, @use_shadow = @use_shadow, true
206
+ tcolor, @shadow_color = @shadow_color, color
207
+ tmargin, @shadow_margin = @shadow_margin, margin
208
+ yield
209
+ @use_shadow = tflag
210
+ @shadow_color = tcolor
211
+ @shadow_margin = tmargin
212
+ return self
213
+ end
214
+
215
+ #===指定したピクセル数のフォントが十分(欠けることなく)収まるピクセル数を取得する
216
+ #_size_:: フォントの大きさ(単位:ピクセル)
217
+ #返却値:: 算出されたピクセル数
218
+ def get_fit_size(size)
219
+ path = Font.findFontPath(@fname)
220
+ font = SDL::TTF.open(path, size)
221
+ return (size.to_f * (size.to_f / font.line_skip.to_f)).to_i
222
+ end
223
+
224
+ #===フォントサイズ(yやjなどの下にはみ出る箇所も算出)を取得する
225
+ #返却値:: 算出されたフォントサイズ
226
+ def line_height
227
+ return @line_skip + @vspace + (@use_shadow ? @shadow_margin[1] : 0)
228
+ end
229
+
230
+ #===フォントインスタンスを解放する
231
+ def dispose
232
+ @font = nil
233
+ end
234
+
235
+ #===フォントの属性をbold(太文字)に設定する
236
+ #ブロックを渡したときは、ブロック評価中のみ太字になる
237
+ #文字が領域外にはみ出る場合があるので注意!
238
+ #返却値:: 自分自身
239
+ def bold
240
+ if block_given?
241
+ tbold, self.bold = self.bold?, true
242
+ yield
243
+ self.bold = tbold
244
+ else
245
+ self.bold = true
246
+ end
247
+ return self
248
+ end
249
+
250
+ #===フォントのbold属性の有無を返す
251
+ #返却値:: bold属性かどうか(true/false)
252
+ def bold?
253
+ return @bold
254
+ end
255
+
256
+ #===フォントのbold属性を設定する
257
+ #_f_:: bold属性かどうか(true/false)
258
+ def bold=(f)
259
+ @bold = f
260
+ @font.style |= SDL::TTF::STYLE_BOLD
261
+ @font.style -= SDL::TTF::STYLE_BOLD unless @bold
262
+ return self
263
+ end
264
+
265
+ #===フォントの属性をitalic(斜め)に設定する
266
+ #ブロックを渡したときは、ブロック評価中のみ斜体文字になる
267
+ #文字が領域外にはみ出る場合があるので注意!
268
+ #返却値:: 自分自身
269
+ def italic
270
+ if block_given?
271
+ titalic, self.italic = self.italic?, true
272
+ yield
273
+ self.italic = titalic
274
+ else
275
+ self.italic = true
276
+ end
277
+ return self
278
+ end
279
+
280
+ #===フォントのitalic属性の有無を返す
281
+ #返却値:: italic属性かどうか(true/false)
282
+ def italic?
283
+ return @italic
284
+ end
285
+
286
+ #===フォントのitalic属性を設定する
287
+ #_f_:: italic属性かどうか(true/false)
288
+ def italic=(f)
289
+ @italic = f
290
+ @font.style |= SDL::TTF::STYLE_ITALIC
291
+ @font.style -= SDL::TTF::STYLE_ITALIC unless @italic
292
+ return self
293
+ end
294
+
295
+ #===フォントの属性をunder_line(下線)に設定する
296
+ #ブロックを渡したときは、ブロック評価中のみ下線付き文字になる
297
+ #返却値:: 自分自身
298
+ def under_line
299
+ if block_given?
300
+ tunder_line, self.under_line = self.under_line?, true
301
+ yield
302
+ self.under_line = tunder_line
303
+ else
304
+ self.under_line = true
305
+ end
306
+ return self
307
+ end
308
+
309
+ #===フォントのunder_line属性の有無を返す
310
+ #返却値:: under_line属性かどうか(true/false)
311
+ def under_line?
312
+ return @under_line
313
+ end
314
+
315
+ #===フォントのunder_line属性を設定する
316
+ #_f_:: under_line属性かどうか(true/false)
317
+ def under_line=(f)
318
+ @under_line = f
319
+ @font.style |= SDL::TTF::STYLE_UNDERLINE
320
+ @font.style -= SDL::TTF::STYLE_UNDERLINE unless @under_line
321
+ return self
322
+ end
323
+
324
+ #===フォントの属性をすべてクリアする
325
+ #_f_:: 自分自身
326
+ def normal
327
+ @font.style = 0
328
+ return self
329
+ end
330
+
331
+ #===文字列を描画する
332
+ #対象のスプライトに文字列を描画する
333
+ #_dst_:: 描画先スプライト
334
+ #_str_:: 描画する文字列
335
+ #_x_:: 描画位置x軸
336
+ #_y_:: 描画位置Y軸
337
+ def draw_text(dst, str, x, y)
338
+ str = str.encode(Encoding::UTF_8)
339
+ str.chars{|c|
340
+ if @use_shadow
341
+ src2 = @font.renderBlendedUTF8(c, @shadow_color[0], @shadow_color[1], @shadow_color[2])
342
+ if src2
343
+ SpriteUnitFactory.apply(@unit, {:bitmap=>src2, :ow=>src2.w, :oh=>src2.h})
344
+ Miyako::Bitmap.blit_aa(@unit, dst.to_unit, x+@shadow_margin[0], y+@shadow_margin[1])
345
+ else
346
+ break x
347
+ end
348
+ end
349
+ src = @font.renderBlendedUTF8(c, @color[0], @color[1], @color[2])
350
+ if src
351
+ SpriteUnitFactory.apply(@unit, {:bitmap=>src, :ow=>src.w, :oh=>src.h})
352
+ Miyako::Bitmap.blit_aa(@unit, dst.to_unit, x, y)
353
+ else
354
+ break x
355
+ end
356
+ x += chr_size_inner(c)
357
+ }
358
+ return x
359
+ end
360
+
361
+ #===文字列描画したときの大きさを取得する
362
+ #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
363
+ #_txt_:: 算出したい文字列
364
+ #返却値:: 文字列を描画したときの大きさ([w,h]の配列)
365
+ def chr_size_inner(char)
366
+ return (char.bytesize == 1 ? @size >> 1 : @size) + (@use_shadow ? @shadow_margin[0] : 0) + @hspace
367
+ end
368
+
369
+ private :chr_size_inner
370
+
371
+ #===文字列描画したときの大きさを取得する
372
+ #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
373
+ #_txt_:: 算出したい文字列
374
+ #返却値:: 文字列を描画したときの大きさ([w,h]の配列)
375
+ def text_size(txt)
376
+ width = txt.chars.inject(0){|r, c|
377
+ r += (c.bytesize == 1 ? @size >> 1 : @size) } +
378
+ ((@use_shadow ? @shadow_margin[0] : 0) + @hspace) * (txt.chars.to_a.length - 1)
379
+ return [width, self.line_height]
380
+ end
381
+
382
+ #===指定した高さで描画する際のマージンを求める
383
+ #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
384
+ #第1引数に渡す"align"は、以下の3種類のシンボルのどれかを渡す
385
+ #:top:: 上側に描画(マージンはゼロ)
386
+ #:middle:: 中間に描画
387
+ #:bottom:: 下部に描画
388
+ #
389
+ #_align_:: 描画位置
390
+ #_height_:: 描画する高さ
391
+ #返却値:: マージンの値
392
+ def margin_height(align, height)
393
+ case align
394
+ when :top
395
+ return 0
396
+ when :middle
397
+ return (height - self.line_height) >> 1
398
+ when :bottom
399
+ return height - self.line_height
400
+ end
401
+ #else
402
+ raise MiyakoError, "Illegal margin_height align! : #{align}"
403
+ end
404
+
405
+ #===Serifフォント(明朝フォント)を取得する
406
+ #マルチプラットフォームのソフトを作る際、OS間の差異を吸収するため、
407
+ #共通の名称でフォントインスタンスを取得するときに使う(主に明朝フォント)
408
+ #返却値:: OSごとに設定されたフォントイン寸タンス(フォントサイズは16)
409
+ def Font::serif
410
+ filename = @@font_base_name[Miyako::getOSName].detect{|base| Font.findFontPath(base[:serif]) }[:serif]
411
+ return Font.new(filename)
412
+ end
413
+
414
+ #===Sans Serifフォント(ゴシックフォント)を取得する
415
+ #マルチプラットフォームのソフトを作る際、OS間の差異を吸収するため、
416
+ #共通の名称でフォントインスタンスを取得するときに使う(主にゴシックフォント)
417
+ #返却値:: OSごとに設定されたフォントイン寸タンス(フォントサイズは16)
418
+ def Font::sans_serif
419
+ filename = @@font_base_name[Miyako::getOSName].
420
+ detect{|base|
421
+ Font.findFontPath(base[:sans_serif])
422
+ }[:sans_serif]
423
+ return Font.new(filename)
424
+ end
425
+
426
+ def Font::system_font #:nodoc:
427
+ return Font.serif
428
+ end
429
+ end
430
+ end