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 124 124: def initialize(*args, &block) 125: super() 126: @vbx_x, @vbx_y, @vbx_width, @vbx_height = nil 127: @meet_or_slice = 'meet' 128: @align = nil 129: 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 137 137: def viewbox(x, y, width, height) 138: begin 139: @vbx_x = Float(x) 140: @vbx_y = Float(y) 141: @vbx_width = Float(width) 142: @vbx_height = Float(height) 143: rescue ArgumentError 144: raise ArgumentError, "arguments must be convertable to float (got #{x.class}, #{y.class}, #{width.class}, #{height.class})" 145: end 146: raise(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0 147: raise(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0 148: yield(self) if block_given? 149: self 150: end
Establish the viewbox as necessary
# File lib/rvg/stretchable.rb, line 92 92: def add_viewbox_primitives(width, height, gc) 93: @vbx_width ||= width 94: @vbx_height ||= height 95: @vbx_x ||= 0.0 96: @vbx_y ||= 0.0 97: 98: if @align == 'none' 99: sx, sy = set_viewbox_none(width, height) 100: tx, ty = 0, 0 101: elsif @meet_or_slice == 'meet' 102: sx, sy = set_viewbox_meet(width, height) 103: tx, ty = align_to_viewport(width, height, sx, sy) 104: else 105: sx, sy = set_viewbox_slice(width, height) 106: tx, ty = align_to_viewport(width, height, sx, sy) 107: end 108: 109: # Establish clipping path around the current viewport 110: name = __id__.to_s 111: gc.define_clip_path(name) do 112: gc.path("M0,0 l#{width},0 l0,#{height} l-#{width},0 l0,-#{height}z") 113: end 114: 115: gc.clip_path(name) 116: # Add a non-scaled translation if meet or slice 117: gc.translate(tx, ty) if (tx.abs > 1.0e-10 || ty.abs > 1.0e-10) 118: # Scale viewbox as necessary 119: gc.scale(sx, sy) if (sx != 1.0 || sy != 1.0) 120: # Add a scaled translation if non-0 origin 121: gc.translate(-@vbx_x, -@vbx_y) if (@vbx_x.abs != 0.0 || @vbx_y.abs != 0) 122: end
Use align attribute to compute x- and y-offset from viewport‘s upper-left corner.
# File lib/rvg/stretchable.rb, line 58 58: def align_to_viewport(width, height, sx, sy) 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 fit
# File lib/rvg/stretchable.rb, line 44 44: def set_viewbox_none(width, height) 45: sx, sy = 1.0, 1.0 46: 47: if @vbx_width 48: sx = width / @vbx_width 49: end 50: if @vbx_height 51: sy = height / @vbx_height 52: end 53: 54: return [sx, sy] 55: end