Module | Magick::RVG::Stretchable |
In: |
lib/rvg/stretchable.rb
|
The methods in this module describe the user-coordinate space. Only RVG objects are stretchable.
# File lib/rvg/stretchable.rb, line 119 119: def initialize(*args, &block) 120: super() 121: @vbx_x, @vbx_y, @vbx_width, @vbx_height = nil 122: @meet_or_slice = 'meet' 123: @align = nil 124: end
Describe a user coordinate system to be imposed on the viewbox. The arguments must be numbers and the width and height arguments must be positive.
# File lib/rvg/stretchable.rb, line 132 132: def viewbox(x, y, width, height) 133: begin 134: @vbx_x = Float(x) 135: @vbx_y = Float(y) 136: @vbx_width = Float(width) 137: @vbx_height = Float(height) 138: rescue ArgumentError 139: raise ArgumentError, "arguments must be convertable to float (got #{x.class}, #{y.class}, #{width.class}, #{height.class})" 140: end 141: raise(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0 142: raise(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0 143: yield(self) if block_given? 144: self 145: end
Establish the viewbox as necessary
# File lib/rvg/stretchable.rb, line 94 94: def add_viewbox_primitives(width, height, gc) 95: @vbx_width ||= width 96: @vbx_height ||= height 97: @vbx_x ||= 0.0 98: @vbx_y ||= 0.0 99: 100: if @align == 'none' 101: tx, ty, sx, sy = set_viewbox_none(width, height) 102: elsif @meet_or_slice == 'meet' 103: tx, ty, sx, sy = set_viewbox_meet(width, height) 104: else 105: tx, ty, sx, sy = set_viewbox_slice(width, height) 106: end 107: 108: # Establish clipping path around the current viewport 109: name = __id__.to_s 110: gc.define_clip_path(name) do 111: gc.path("M0,0 l#{width},0 l0,#{height} l-#{width},0 l0,-#{height}z") 112: end 113: 114: gc.clip_path(name) 115: gc.translate(tx, ty) if (tx.abs > 1.0e-10 || ty.abs > 1.0e-10) 116: gc.scale(sx, sy) if (sx != 1.0 || sy != 1.0) 117: end
Use align attribute to compute x- and y-offset from viewport’s upper-left corner.
# File lib/rvg/stretchable.rb, line 57 57: def align_to_viewport(width, height, sx, sy) 58: tx, ty = @vbx_x, @vbx_y 59: tx += case @align 60: when /\AxMin/ 61: 0 62: when NilClass, /\AxMid/ 63: (width - @vbx_width*sx) / 2.0 64: when /\AxMax/ 65: width - @vbx_width*sx 66: end 67: 68: ty += case @align 69: when /YMin\z/ 70: 0 71: when NilClass, /YMid\z/ 72: (height - @vbx_height*sy) / 2.0 73: when /YMax\z/ 74: height - @vbx_height*sy 75: end 76: return [tx, ty] 77: end
Scale to smaller viewbox dimension
# File lib/rvg/stretchable.rb, line 80 80: def set_viewbox_meet(width, height) 81: sx = sy = [width / @vbx_width, height / @vbx_height].min 82: tx, ty = align_to_viewport(width, height, sx, sy) 83: return [tx, ty, sx, sy] 84: end
# File lib/rvg/stretchable.rb, line 42 42: def set_viewbox_none(width, height) 43: sx, sy = 1.0, 1.0 44: tx, ty = @vbx_x, @vbx_y 45: 46: if @vbx_width 47: sx = width / @vbx_width 48: end 49: if @vbx_height 50: sy = height / @vbx_height 51: end 52: 53: return [tx, ty, sx, sy] 54: end