| # Add to a Sprite object, or derivative | |
| # Assumes self.bitmap has been set to the desired target width and height | |
| def blt_9slice(args={}) | |
| args = { | |
| src_bitmap: nil, | |
| :frame_width => { # Can also be a number to be used for all corners | |
| :top_left => 5, | |
| :top_right => :top_left, | |
| :mid_left => :top_left, | |
| :mid_right => :top_left, | |
| :btm_left => :top_left, | |
| :btm_right => :top_left | |
| }, | |
| :frame_height => { # Can also be a number to be used for all corners | |
| :top_left => 5, | |
| :top_right => :top_left, | |
| :mid_top => :top_left, | |
| :mid_btm => :top_left, | |
| :btm_left => :top_left, | |
| :btm_right => :top_left | |
| } | |
| }.merge(args) | |
| # Set src_bitmap for convenience | |
| src_bitmap = args[:src_bitmap] | |
| # Set width and height params for each frame / corner | |
| tl_f_width = tl_f_height = tr_f_width = tr_f_height = ml_f_width = mr_f_width = mt_f_height = mb_f_height = bl_f_width = bl_f_height = br_f_width = br_f_height = 0 | |
| # Go through hash params and find values or set defaults | |
| [:top_left, :top_right, :mid_left, :mid_right, :mid_top, :mid_btm, :btm_left, :btm_right].each do |frame| | |
| if args[:frame_width].is_a? Numeric | |
| width = args[:frame_width] | |
| else | |
| width = args[:frame_width][frame] | |
| # Reference other arg value if symbols | |
| width = args[:frame_width][width] if width.is_a? Symbol | |
| # If no value, set default to top left | |
| width = args[:frame_width][:top_left] unless width | |
| end | |
| if args[:frame_height].is_a? Numeric | |
| height = args[:frame_height] | |
| else | |
| height = args[:frame_height][frame] | |
| # Reference other arg value if symbols | |
| height = args[:frame_height][height] if height.is_a? Symbol | |
| # If no value, set default to top left | |
| height = args[:frame_height][:top_left] unless height | |
| end | |
| case frame | |
| when :top_left | |
| tl_f_width = width | |
| tl_f_height = height | |
| when :top_right | |
| tr_f_width = width | |
| tr_f_height = height | |
| when :mid_left | |
| ml_f_width = width | |
| when :mid_right | |
| mr_f_width = width | |
| when :mid_top | |
| mt_f_height = height | |
| when :mid_btm | |
| mb_f_height = height | |
| when :btm_left | |
| bl_f_width = width | |
| bl_f_height = height | |
| when :btm_right | |
| br_f_width = width | |
| br_f_height = height | |
| end | |
| end | |
| # Rects for copying sections of src_bitmap | |
| # Top | |
| tl_frame = Rect.new(0, 0, tl_f_width, tl_f_height) | |
| t_frame = Rect.new(tl_f_width, 0, src_bitmap.width - (tl_f_width + tr_f_width), mt_f_height) | |
| tr_frame = Rect.new(src_bitmap.width - tr_f_width, 0, tr_f_width, tr_f_height) | |
| # Middle | |
| ml_frame = Rect.new(0, tl_f_height, ml_f_width, src_bitmap.height - (tl_f_height + bl_f_height)) | |
| m_bg = Rect.new(ml_frame.width, ml_frame.y, src_bitmap.width - (ml_f_width + mr_f_width), ml_frame.height) | |
| mr_frame = Rect.new(src_bitmap.width - mr_f_width, tr_f_height, mr_f_width, ml_frame.height) | |
| # Bottom | |
| bl_frame = Rect.new(0, src_bitmap.height - bl_f_height, bl_f_width, bl_f_height) | |
| b_frame = Rect.new(bl_f_width, src_bitmap.height - mb_f_height, src_bitmap.width - (bl_f_width + br_f_width), mb_f_height) | |
| br_frame = Rect.new(src_bitmap.width - br_f_width, src_bitmap.height - br_f_height, br_f_width, br_f_height) | |
| # Diffs | |
| width_diff = (self.width.to_f / m_bg.width).ceil | |
| height_diff = (self.height.to_f / m_bg.height).ceil | |
| # First blt fill | |
| fill_width = self.width - (ml_f_width + mr_f_width) | |
| fill_height = self.height - (mt_f_height + mb_f_height) | |
| m_bg_width = m_bg.width | |
| m_bg_height = m_bg.height | |
| width_diff.times do |hn| | |
| total_width = m_bg.width * (hn+1) | |
| m_bg.width -= total_width - fill_width if total_width > fill_width | |
| m_bg.height = m_bg_height # Reset on horizontal pass | |
| height_diff.times do |vn| | |
| total_height = m_bg.height * (vn+1) | |
| m_bg.height -= total_height - fill_height if total_height > fill_height | |
| self.bitmap.blt(tl_f_width + (m_bg_width * hn), tl_f_height + (m_bg_height * vn), src_bitmap, m_bg) | |
| end | |
| end | |
| # Top left frame | |
| self.bitmap.blt(0, 0, src_bitmap, tl_frame) | |
| # Top frame | |
| mid_width = self.width - (tl_f_width + tr_f_width) | |
| t_frame_width = t_frame.width | |
| width_diff.times do |n| | |
| total_width = t_frame.width * (n+1) | |
| t_frame.width -= total_width - mid_width if total_width > mid_width | |
| self.bitmap.blt(tl_f_width + (t_frame_width * n), 0, src_bitmap, t_frame) | |
| end | |
| # Top right frame | |
| self.bitmap.blt(self.width - tr_frame.width, tr_frame.y, src_bitmap, tr_frame) | |
| # Mid left frame | |
| mid_height = self.height - (tl_f_height + bl_f_height) | |
| ml_frame_height = ml_frame.height | |
| height_diff.times do |n| | |
| total_height = ml_frame.height * (n+1) | |
| ml_frame.height -= total_height - mid_height if total_height > mid_height | |
| self.bitmap.blt(0, tl_f_height + (ml_frame_height * n), src_bitmap, ml_frame) | |
| end | |
| # Mid right frame | |
| mid_height = self.height - (tr_f_height + br_f_height) | |
| mr_frame_height = mr_frame.height | |
| height_diff.times do |n| | |
| total_height = mr_frame.height * (n+1) | |
| mr_frame.height -= total_height - fill_height if total_height > fill_height | |
| self.bitmap.blt(self.width - mr_frame.width, tr_f_height + (mr_frame_height * n), src_bitmap, mr_frame) | |
| end | |
| # Bottom left frame | |
| self.bitmap.blt(0, self.height - bl_f_height, src_bitmap, bl_frame) | |
| # Bottom frame | |
| mid_width = self.width - (bl_f_width + br_f_width) | |
| b_frame_width = b_frame.width | |
| width_diff.times do |n| | |
| total_width = b_frame.width * (n+1) | |
| b_frame.width -= total_width - mid_width if total_width > mid_width | |
| self.bitmap.blt(bl_f_width + (b_frame_width * n), self.height - b_frame.height, src_bitmap, b_frame) | |
| end | |
| # Bottom right frame | |
| self.bitmap.blt(self.width - br_frame.width, self.height - br_frame.height, src_bitmap, br_frame) | |
| end |