Class: Miyako::Shape

Inherits:
Object show all
Defined in:
lib/Miyako/API/shape.rb

Overview

テキストや図形を描画するクラス

図形は、長方形・丸み付き長方形・円・楕円が描画可能 文字列は、通常の文字列と高橋メソッド形式文字列が描画可能

Constant Summary collapse

@@shape_executer =
Shape.new

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.box(param) ⇒ Object

長方形を描画する(エッジ付きも可。そのとき、エッジは指定したサイズより内側に描画する)

param

設定パラメータ。ハッシュ形式。

(:size => 描画するサイズ(ピクセル単位、Size構造体のインスタンス、デフォルトは), :color => 長方形の色デフォルトはColor, :edge] => エッジを設定する。値は:width=>幅のハッシュを割り付ける)

返却値

描画したスプライト


80
81
82
# File 'lib/Miyako/API/shape.rb', line 80

def Shape.box(param)
  @@shape_executer.box(param)
end

.circle(param) ⇒ Object

円を描画する(エッジ付きも可。そのとき、エッジは指定したサイズより内側に描画する)

param

設定パラメータ。ハッシュ形式。

(:ray => 円の半径の大きさ(ピクセル単位。デフォルトは0), :color => 円の色デフォルトはColor, :edge => エッジを設定する。値は:width=>幅のハッシュを割り付ける)

返却値

描画したスプライト


101
102
103
# File 'lib/Miyako/API/shape.rb', line 101

def Shape.circle(param)
  @@shape_executer.circle(param)
end

.ellipse(param) ⇒ Object

楕円を描画する(エッジ付きも可。そのとき、エッジは指定したサイズより内側に描画する)

param

設定パラメータ。ハッシュ形式。

(:size => 楕円の半径の横・縦の大きさ(ピクセル単位。デフォルトは0), :color => 円の色デフォルトはColor, :edge => エッジを設定する。値は:width=>幅のハッシュを割り付ける)

返却値

描画したスプライト


111
112
113
# File 'lib/Miyako/API/shape.rb', line 111

def Shape.ellipse(param)
  @@shape_executer.ellipse(param)
end

.polygon(param) ⇒ Object

多角形を描画する

param

設定パラメータ。ハッシュ形式。

:vertexes => 頂点リスト。形式の配列の配列, :color => 円の色デフォルトはColor,

返却値

描画したスプライト


120
121
122
# File 'lib/Miyako/API/shape.rb', line 120

def Shape.polygon(param)
  @@shape_executer.polygon(param)
end

.roundbox(param) ⇒ Object

丸み付き長方形を描画する(エッジ付きも可。そのとき、エッジは指定したサイズより内側に描画する)

param

設定パラメータ。ハッシュ形式。

(:size => 描画するサイズ(ピクセル単位、Size構造体のインスタンス、デフォルトは), :ray => 丸みの半径の大きさ(ピクセル単位。デフォルトは0), :color => 長方形の色デフォルトはColor, :edge => エッジを設定する。値は:width=>幅のハッシュを割り付ける)

返却値

描画したスプライト


91
92
93
# File 'lib/Miyako/API/shape.rb', line 91

def Shape.roundbox(param)
  @@shape_executer.roundbox(param)
end

.takahashi(param, &block) ⇒ Object

テキストを高橋メソッド形式で描画した画像を作成

指定した大きさの矩形・行数で文字を描画する。 指定した行数で描画を基準に文字サイズを算出する。 但し、文字列が長すぎる時は、その文字数を基準に文字サイズを算出する。 ブロックに渡した行数が指定数より多くなると文字列がはみ出るため、注意すること。

param

設定パラメータ。ハッシュ形式。

(:font => 描画するフォントのインスタンス(デフォルトはFont.sans_serif), (:align => 複数行描画するときの文字列のアライン(:left,:center,:rightの三種。デフォルトは:left), (:size => 描画するサイズ(ピクセル単位、Size構造体のインスタンス、デフォルトは)) (:valign => 行中の小さい文字を描画するときの縦の位置(:top,:middle,:bottomの三種。デフォルトは:middle)) (:lines => 描画する行数(デフォルトは2))

_&block_

描画するテキスト(Yuki形式)

返却値

テキストを描画したスプライト


70
71
72
# File 'lib/Miyako/API/shape.rb', line 70

def Shape.takahashi(param, &block)
  @@shape_executer.takahashi(param, block)
end

.text(param, &block) ⇒ Object

テキストを描画した画像を作成

param

設定パラメータ。ハッシュ形式。

(:font => 描画するフォントのインスタンス(デフォルトはFont.sans_serif), (:align => 複数行描画するときの文字列のアライン(:left,:center,:rightの三種。デフォルトは:left)) (:valign => 行中の小さい文字を描画するときの縦の位置(:top,:middle,:bottomの三種。デフォルトは:middle))

_&block_

描画するテキスト(Yuki形式)

返却値

テキストを描画したスプライト

Raises:


52
53
54
55
# File 'lib/Miyako/API/shape.rb', line 52

def Shape.text(param, &block)
  raise MiyakoValueError, "Cannot find any text(:text parameter)!" unless (param[:text] || block)
  @@shape_executer.create_text(param, block)
end

Instance Method Details

#bold(&block) ⇒ Object

Shape.textメソッドのブロック内で使用する、太文字指示メソッド

ブロック内で指定した範囲でのみ太文字になる (使用すると文字の端が切れてしまう場合あり!) (例)Shape.text(){ text “abc”; cr; bold“def” }

返却値

自分自身


293
294
295
296
# File 'lib/Miyako/API/shape.rb', line 293

def bold(&block)
  @font.bold{ text instance_eval(&block) }
  return self
end

#box(param) ⇒ Object

:nodoc:


335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/Miyako/API/shape.rb', line 335

def box(param) #:nodoc:

  init_parameter(param)
  w = @size[0]
  h = @size[1]
  s = Sprite.new(:size => [w, h], :type => :alpha_channel)
  Drawing.fill(s, [0, 0, 0])
  Bitmap.ck_to_ac!(s, [0, 0, 0])
  if @edge
    width = @edge[:width]
    Drawing.rect(s, [0, 0, w, h], Color.to_rgb(@edge[:color]), true)
    Drawing.rect(s, [width, width, w-width*2-1, h-width*2-1], Color.to_rgb(@color), true)
  else
    Drawing.rect(s, [0, 0, w, h], Color.to_rgb(@color), true)
  end
  return s
end

#calc(block) ⇒ Object

:nodoc:


216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/Miyako/API/shape.rb', line 216

def calc(block) #:nodoc:

  @locate = Point.new(0, 0)
  @img_size = Size.new(0, 0)
  @max_height = @font.line_height
  @lines = 1
  @calc_mode = true
  text instance_eval(&block)
  @calc_mode = false
  if @locate.x != 0
    @margins << @locate.x
    @img_size.w = [@locate.x, @img_size.w].max
    @img_size.h += @max_height
    @heights << @max_height
  end
  return @img_size
end

#circle(param) ⇒ Object

:nodoc:


378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/Miyako/API/shape.rb', line 378

def circle(param) #:nodoc:

  init_parameter(param)
  s = Sprite.new(:size => [@ray*2+1, @ray*2+1], :type => :alpha_channel)
  Drawing.fill(s, [0, 0, 0])
  Bitmap.ck_to_ac!(s, [0, 0, 0])
  if @edge
    Drawing.circle(s, [@ray, @ray], @ray, Color.to_rgb(@edge[:color]), true)
    Drawing.circle(s, [@ray, @ray], @ray-@edge[:width], Color.to_rgb(@color), true)
  else
    Drawing.circle(s, [@ray, @ray], @ray, Color.to_rgb(@color), true)
  end
  return s
end

#color(color, &block) ⇒ Object

Shape.text/takahashiメソッドのブロック内で使用する、文字色指示メソッド

ブロック内で指定した範囲でのみ色が変更される (例)Shape.text(){ text “abc”; cr; color(:red)“def” }

color

変更する色()もしくはColor[]メソッドの引数

返却値

自分自身


264
265
266
267
# File 'lib/Miyako/API/shape.rb', line 264

def color(color, &block)
  @font.color_during(Color.to_rgb(color)){ text instance_eval(&block) }
  return self
end

#crObject

Shape.text/takahashiメソッドのブロック内で使用する、改行指示メソッド

(例)Shape.text(){ text “abc”; cr; bold“def” }

返却値

自分自身


320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/Miyako/API/shape.rb', line 320

def cr
  if @calc_mode
    @margins << @locate.x
    @heights << @max_height
    @img_size.w = [@locate.x, @img_size.w].max
    @img_size.h += @max_height
    @locate.x = 0
    @lines += 1
  else
    @locate.x = @margins.shift || 0
  end
  @locate.y += @max_height
  return self
end

#create_text(param, text_block) ⇒ Object

:nodoc:


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/Miyako/API/shape.rb', line 124

def create_text(param, text_block) #:nodoc:

  init_parameter(param)
  text_block = Proc.new{ @text } if @text
  org_size = @font.size
  org_color = @font.color
  @margins = []
  @heights = []
  area_size = calc(text_block)
  @sprite = Sprite.new(:size => area_size, :type => :ac)
  Drawing.fill(@sprite, [0, 0, 0])
  Bitmap.ck_to_ac!(@sprite, [0, 0, 0])
  case @align
    when :left
      @margins = @margins.map{|v| 0 }
    when :center
      @margins = @margins.map{|v| (area_size.w - v) >> 1 }
    when :right
      @margins = @margins.map{|v| area_size.w - v }
  end
  @lines = @margins.length
  vmargin = 0
  case @valign
    when :top
      vmargin = 0
    when :middle
      vmargin = (area_size.h - @heights.inject(:+)) >> 1
    when :bottom
      vmargin = area_size.h - @heights.inject(:+)
  end
  @locate = Point.new(@margins.shift, vmargin)
  text instance_eval(&text_block)
  @font.size = org_size
  @font.color = org_color
  return @sprite
end

#ellipse(param) ⇒ Object

:nodoc:


392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/Miyako/API/shape.rb', line 392

def ellipse(param) #:nodoc:

  init_parameter(param)
  w = @size[0]
  w2 = w * 2 + 1
  h = @size[1]
  h2 = h * 2 + 1
  s = Sprite.new(:size => [w2, h2], :type => :alpha_channel)
  Drawing.fill(s, [0, 0, 0])
  Bitmap.ck_to_ac!(s, [0, 0, 0])
  if @edge
    Drawing.ellipse(s, [w, h], w, h, Color.to_rgb(@edge[:color]), true)
    Drawing.ellipse(s, [w, h], w-@edge[:width], h-@edge[:width], Color.to_rgb(@color), true)
  else
    Drawing.ellipse(s, [w, h], w, h, Color.to_rgb(@color), true)
  end
  return s
end

#init_parameter(parameter) ⇒ Object


30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/Miyako/API/shape.rb', line 30

def init_parameter(parameter)
  @text = parameter[:text]
  @size = parameter[:size] ||= Size.new(100,100)
  @color = parameter[:color] ||= Color[:white]
  @font = parameter[:font] ||= Font.sans_serif
  @ray = parameter[:ray] ||= 0
  @edge = parameter[:edge] ||= nil
  @align = parameter[:align] ||= :left
  @valign = parameter[:valign] ||= :middle
  @lines = parameter[:lines] ||= 2
  @vertexes = parameter[:vertexes] ||= []
end

#italic(&block) ⇒ Object

Shape.textメソッドのブロック内で使用する、斜体指示メソッド

ブロック内で指定した範囲でのみ斜体文字になる (使用すると文字の端が切れてしまう場合あり!) (例)Shape.text(){ text “abc”; cr; italic“def” }

返却値

自分自身


303
304
305
306
# File 'lib/Miyako/API/shape.rb', line 303

def italic(&block)
  @font.italic{ text instance_eval(&block) }
  return self
end

#polygon(param) ⇒ Object

:nodoc:

Raises:


410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/Miyako/API/shape.rb', line 410

def polygon(param) #:nodoc:

  init_parameter(param)

  min_x, max_x = @vertexes.map{|v| v[0]}.minmax
  min_y, max_y = @vertexes.map{|v| v[1]}.minmax

  raise MiyakoError, "cannot find vertexes!" if min_x.nil? or min_y.nil?
  
  w = max_x - min_x
  h = max_y - min_y

  @vertexes = @vertexes.map{|v| [v[0]-min_x, v[1]-min_y]}

  s = Sprite.new(:size => [w, h], :type => :alpha_channel)
  Drawing.fill(s, [0, 0, 0])
  Bitmap.ck_to_ac!(s, [0, 0, 0])
  Drawing.polygon(s, @vertexes, Color.to_rgb(@color), true)
  return s
end

#roundbox(param) ⇒ Object

:nodoc:


362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/Miyako/API/shape.rb', line 362

def roundbox(param) #:nodoc:

  init_parameter(param)
  w = @size[0]
  h = @size[1]
  s = Sprite.new(:size => @size, :type => :ac)
  Drawing.fill(s, [0, 0, 0])
  Bitmap.ck_to_ac!(s, [0, 0, 0])
  if @edge
    roundbox_basic(s, 0, 0, w, h, @ray, Color.to_rgb(@edge[:color]))
    roundbox_basic(s, @edge[:width], @edge[:width], w, h, @ray, Color.to_rgb(@color))
  else
    roundbox_basic(s, 0, 0, w, h, @ray, Color.to_rgb(@color))
  end
  return s
end

#set_font_size_inner(text_block) ⇒ Object

:nodoc:


208
209
210
211
212
213
214
# File 'lib/Miyako/API/shape.rb', line 208

def set_font_size_inner(text_block) #:nodoc:

  @max_height = @font.line_height
  @margins = []
  @heights = []
  @lines = 1
  tcalc(text_block)
end

#size(size, &block) ⇒ Object

Shape.textメソッドのブロック内で使用する、文字サイズ指示メソッド

ブロック内で指定した範囲でのみサイズが変更される (例)Shape.text(){ text “abc”; cr; size(16)“def” }

size

変更するサイズ(整数)

返却値

自分自身


274
275
276
277
278
279
280
# File 'lib/Miyako/API/shape.rb', line 274

def size(size, &block)
  @font.size_during(size){
    @max_height = [@max_height, @font.line_height].max
    size_inner(@font.margin_height(@valign, @max_height), &block)
  }
  return self
end

#size_inner(margin, &block) ⇒ Object

:nodoc:


282
283
284
285
286
# File 'lib/Miyako/API/shape.rb', line 282

def size_inner(margin, &block) #:nodoc:

  @locate.y += margin
  text instance_eval(&block)
  @locate.y -= margin
end

#takahashi(param, text_block) ⇒ Object

:nodoc:


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/Miyako/API/shape.rb', line 160

def takahashi(param, text_block) #:nodoc:

  init_parameter(param)
  org_size = @font.size
  org_color = @font.color
  olines = @lines
  # calc font size

  @font.size = @size[1] / @lines
  # calc font size incldue line_height

  @font.size = @font.size * @font.size / @font.line_height
  set_font_size_inner(text_block)
  # over lines?

  if @lines > olines
    @font.size = @size[1] / @lines
    @font.size = @font.size * @font.size / @font.line_height
    set_font_size_inner(text_block)
  end
  # over width?

  if @img_size.w > @size[0]
    @font.size = @font.size * @size[0] / @img_size.w
    set_font_size_inner(text_block)
  end
  case @align
    when :left
      @margins = @margins.map{|v| 0 }
    when :center
      @margins = @margins.map{|v| (@size[0] - v) / 2 }
    when :right
      @margins = @margins.map{|v| @size[0] - v }
  end
  vmargin = 0
  case @valign
    when :top
      vmargin = 0
    when :middle
      vmargin = (@size[1] - @heights.inject(:+)) >> 1
    when :bottom
      vmargin = @size[1] - @heights.inject(:+)
  end
  @sprite = Sprite.new(:size => @size, :type => :ac)
  Drawing.fill(@sprite, [0, 0, 0])
  Bitmap.ck_to_ac!(@sprite, [0, 0, 0])
  @locate = Point.new(@margins.shift, vmargin)
  text instance_eval(&text_block)
  @font.size = org_size
  @font.color = org_color
  return @sprite
end

#tcalc(block) ⇒ Object

:nodoc:


233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/Miyako/API/shape.rb', line 233

def tcalc(block) #:nodoc:

  @locate = Point.new(0, 0)
  @img_size = Size.new(0, 0)
  @calc_mode = true
  text instance_eval(&block)
  @calc_mode = false
  if @locate.x != 0
    @margins << @locate.x if @locate.x != 0
    @heights << @max_height
  end
  @img_size.w = [@locate.x, @img_size.w].max
end

#text(txt) ⇒ Object

Shape.textメソッドのブロック内で使用する、文字描画指示メソッド

(例)Shape.text(){ text “abc” } (例)Shape.takahashi(:size=>){ text “名前重要” }

text

描画するテキスト

返却値

自分自身


251
252
253
254
255
256
257
# File 'lib/Miyako/API/shape.rb', line 251

def text(txt)
  return self if txt.eql?(self)
  txt = txt.gsub(/[\n\r\t\f]/,"")
  @font.draw_text(@sprite, txt, @locate.x, @locate.y) unless @calc_mode
  @locate.x += @font.text_size(txt)[0]
  return self
end

#under_line(&block) ⇒ Object

Shape.textメソッドのブロック内で使用する、下線指示メソッド

ブロック内で指定した範囲でのみ文字に下線が付く (例)Shape.text(){ text “abc”; cr; bold“def” }

返却値

自分自身


312
313
314
315
# File 'lib/Miyako/API/shape.rb', line 312

def under_line(&block)
  @font.under_line{ text instance_eval(&block) }
  return self
end