| 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