Class: PREP::Core::Loop

Inherits:
Drawable show all
Defined in:
lib/core/loop.rb

Overview

ループ読み込みクラスの定義

Constant Summary collapse

DIRECTIONS =
{
  :horizontal => 'horizontal',
  :vertical => 'vertical'
}
@@default_values =
{
  :direction => DIRECTIONS[:vertical],
  :gap => 0,
  :page_break => false,
  :layer => 4,
  :allow_header_split => true,
  :fixed_times => nil,
  :at_least_one => false,
  :header_repeat => true,
  :x => 0,
  :y => 0,
}

Instance Attribute Summary collapse

Attributes inherited from Drawable

#identifier, #layer

Instance Method Summary collapse

Methods inherited from Drawable

#<=>, #calculate_pos, #key_string_to_symbol, #rewind_current_page, #visible?

Constructor Details

#initialize(identifier, values = { }) ⇒ Loop

Returns a new instance of Loop.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/core/loop.rb', line 36

def initialize(identifier, values = { })
  values = @@default_values.merge(key_string_to_symbol(values))

  super(identifier, values[:layer])

  self.direction = values[:direction]
  @header_group = values[:header]
  @iterator_group = values[:iterator]
  @gap = values[:gap].mm2pixcel
  @footer_group = values[:footer]
  @point = Point.new(values[:x].mm2pixcel, values[:y].mm2pixcel)
  @page_break = values[:page_break]
  @allow_header_split = values[:allow_header_split]
  @fixed_times = values[:fixed_times]
  @at_least_one = !!values[:at_least_one]
  @header_repeat = !!values[:header_repeat]
  @header_rendering_count = 0
end

Instance Attribute Details

#allow_header_splitObject (readonly)

Returns the value of attribute allow_header_split.



33
34
35
# File 'lib/core/loop.rb', line 33

def allow_header_split
  @allow_header_split
end

#at_least_oneObject (readonly)

Returns the value of attribute at_least_one.



33
34
35
# File 'lib/core/loop.rb', line 33

def at_least_one
  @at_least_one
end

#directionObject

Returns the value of attribute direction.



32
33
34
# File 'lib/core/loop.rb', line 32

def direction
  @direction
end

#fixed_timesObject (readonly)

Returns the value of attribute fixed_times.



33
34
35
# File 'lib/core/loop.rb', line 33

def fixed_times
  @fixed_times
end

Returns the value of attribute footer_group.



32
33
34
# File 'lib/core/loop.rb', line 32

def footer_group
  @footer_group
end

#gapObject (readonly)

Returns the value of attribute gap.



32
33
34
# File 'lib/core/loop.rb', line 32

def gap
  @gap
end

#header_groupObject (readonly)

Returns the value of attribute header_group.



32
33
34
# File 'lib/core/loop.rb', line 32

def header_group
  @header_group
end

#header_repeatObject (readonly)

Returns the value of attribute header_repeat.



34
35
36
# File 'lib/core/loop.rb', line 34

def header_repeat
  @header_repeat
end

#heightObject (readonly)

Returns the value of attribute height.



33
34
35
# File 'lib/core/loop.rb', line 33

def height
  @height
end

#iterator_groupObject (readonly)

Returns the value of attribute iterator_group.



32
33
34
# File 'lib/core/loop.rb', line 32

def iterator_group
  @iterator_group
end

#page_breakObject (readonly)

Returns the value of attribute page_break.



33
34
35
# File 'lib/core/loop.rb', line 33

def page_break
  @page_break
end

#pointObject (readonly)

Returns the value of attribute point.



32
33
34
# File 'lib/core/loop.rb', line 32

def point
  @point
end

#widthObject (readonly)

Returns the value of attribute width.



33
34
35
# File 'lib/core/loop.rb', line 33

def width
  @width
end

Instance Method Details

#calculate_region(prep, region, values, stop_on_drawable = nil) ⇒ Object

データに依存してサイズが変化する可能性がある



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/core/loop.rb', line 87

def calculate_region(prep, region, values, stop_on_drawable = nil)
  if self === stop_on_drawable
    puts "STOPPING on #{stop_on_drawable.identifier}" if ENV["DEBUG"]
    gets if ENV["DEBUG"]
    raise ReRenderJump.new(region)
  end
  puts "Calculate region for #{self.class}: #{self.identifier} region: #{region}" if ENV["DEBUG"]
  # リージョン補正
  current_region = fit_region(region)
  # 描画計算の初期位置を保持
  @initial_calculate_region = current_region.dup

  # ヘッダの領域サイズを計算
  current_region = calculate_header_region(prep, current_region, values, stop_on_drawable)
  puts "Header:\t#{current_region}" if ENV["DEBUG"]

  # 繰り返し部分の領域サイズを計算
  current_region = calculate_iterator_region(prep, current_region, values, stop_on_drawable)
  puts "Iterator:\t#{current_region}" if ENV["DEBUG"]

  # フッタの領域サイズを計算
  current_region = calculate_footer_region(prep, current_region, values, stop_on_drawable)
  puts "Footer:\t#{current_region}" if ENV["DEBUG"]

  begin
    # 最終的にリージョン補正位置から必要な領域を計算
    # 元のリージョン範囲から最終的に残っているリージョン範囲を減算すればよい
    ret_region = Region.new(0, 0,
                            region.width - current_region.width,
                            region.height - current_region.height)

    # 進行方向じゃない方向に対しての差分は別途取得
    if @direction == DIRECTIONS[:horizontal]
      ret_region.height = @height
    else # if @direction == DIRECTIONS[:vertical]
      ret_region.width = @width
    end

    return ret_region.width, ret_region.height
  rescue RegionWidthOverflowError, RegionHeightOverflowError => e
    # これは負の数を返却してやれば上位では単純な加算しか起きない
    w, h = region.width - current_region.width, region.height - current_region.height
    if @direction == DIRECTIONS[:horizontal]
      h = @height
    else # if @direction == DIRECTIONS[:vertical]
      w = @width
    end

    puts "Inner page break!! width: #{w}, height: #{h}" if ENV["DEBUG"]
    gets if ENV["DEBUG"]

    return w, h
  end
  # 計算を抜けるタイミングで @header_rendering_count をクリア
  @header_rendering_count = 0
end

#draw(prep, region, values, stop_on_drawable = nil) ⇒ Object

実際の描画を実施



158
159
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
207
208
209
210
211
212
213
214
215
216
# File 'lib/core/loop.rb', line 158

def draw(prep, region, values, stop_on_drawable = nil)
  if self === stop_on_drawable
    puts "STOPPING on #{stop_on_drawable.identifier}" if ENV["DEBUG"]
    gets if ENV["DEBUG"]
    raise ReRenderJump.new(region)
  end
  STDERR.puts("Draw on #{self.class} #{self.identifier}") if ENV['DEBUG']
  # リージョン補正
  current_region = fit_region(region)
  # 描画計算の初期位置を保持
  @initial_draw_region = current_region.dup

  # 領域に関する情報を取得
  expand_setting = { }
  if !@page_break
    # 描画に先立ち領域拡張設定を実施
    # ループ要素の描画領域を算出(事前計算)
    rewind_current_page(prep) do
      calculate_region(prep, region.dup, values)
    end
    if @direction == DIRECTIONS[:horizontal]
      expand_setting[:height] = @height
    else # if @direction == DIRECTIONS[:vertical]
      expand_setting[:width] = @width
    end
  end
  # ヘッダおよびフッタの子に関してワンタイム設定を実施
  unless @header_group.nil?
    header = prep.group(@header_group)
    header.drawable_items.each do |drawable|
      if Label === drawable || Rectangle === drawable
        if drawable.expand
          drawable.expand_region(expand_setting)
        end
      end
    end
  end
  unless @footer_group.nil?
    footer = prep.group(@footer_group)
    footer.drawable_items.each do |drawable|
      if Label === drawable || Rectangle === drawable
        if drawable.expand
          drawable.expand_region(expand_setting)
        end
      end
    end
  end
  # ヘッダブロック描画
  current_region = draw_header(prep, current_region, values, stop_on_drawable)

  # 繰り返しブロック描画
  current_region = draw_iterator(prep, current_region, values, stop_on_drawable)

  # フッタブロック描画
  current_region = draw_footer(prep, current_region, values, stop_on_drawable)

  # ヘッダの描画回数をクリア
  @header_rendering_count = 0
end

#fit_region(region) ⇒ Object

リージョン補正

相対位置情報を元にリージョンを補正して返却



147
148
149
150
151
152
153
154
155
# File 'lib/core/loop.rb', line 147

def fit_region(region)
  current_region = region.dup
  current_region.x += point.x
  current_region.y += point.y
  current_region.width -= point.x
  current_region.height -= point.y

  return current_region
end

#generate_sample_dataset(prep) ⇒ Object

データセット雛形を生成



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/core/loop.rb', line 64

def generate_sample_dataset(prep)
  dataset = { }

  unless @header_group.nil?
    header = prep.group(@header_group)
    dataset[:header] = header.generate_sample_dataset(prep)
  end
  iterator = prep.group(@iterator_group)
  dataset[:values] =
    [
     iterator.generate_sample_dataset(prep),
     iterator.generate_sample_dataset(prep),
     iterator.generate_sample_dataset(prep),
    ]
  unless @footer_group.nil?
    footer = prep.group(@footer_group)
    dataset[:footer] = footer.generate_sample_dataset(prep)
  end

  return dataset
end