Class: Retouch::Geometry
- Inherits:
-
Object
- Object
- Retouch::Geometry
- Defined in:
- lib/retouch/geometry.rb,
sig/retouch.rbs
Instance Attribute Summary collapse
-
#height ⇒ Integer, ...
readonly
Returns the value of attribute height.
-
#mode ⇒ Symbol
readonly
Returns the value of attribute mode.
-
#offset_x ⇒ Integer
readonly
Returns the value of attribute offset_x.
-
#offset_y ⇒ Integer
readonly
Returns the value of attribute offset_y.
-
#width ⇒ Integer, ...
readonly
Returns the value of attribute width.
Class Method Summary collapse
Instance Method Summary collapse
- #crop_size(source_width, source_height) ⇒ [Integer, Integer]
-
#initialize(width, height, offset_x, offset_y, mode) ⇒ Geometry
constructor
A new instance of Geometry.
- #target_size(source_width, source_height) ⇒ [Integer, Integer]
Constructor Details
#initialize(width, height, offset_x, offset_y, mode) ⇒ Geometry
Returns a new instance of Geometry.
30 31 32 33 34 35 36 |
# File 'lib/retouch/geometry.rb', line 30 def initialize(width, height, offset_x, offset_y, mode) @width = width @height = height @offset_x = offset_x @offset_y = offset_y @mode = mode end |
Instance Attribute Details
#height ⇒ Integer, ... (readonly)
Returns the value of attribute height.
5 6 7 |
# File 'lib/retouch/geometry.rb', line 5 def height @height end |
#mode ⇒ Symbol (readonly)
Returns the value of attribute mode.
5 6 7 |
# File 'lib/retouch/geometry.rb', line 5 def mode @mode end |
#offset_x ⇒ Integer (readonly)
Returns the value of attribute offset_x.
5 6 7 |
# File 'lib/retouch/geometry.rb', line 5 def offset_x @offset_x end |
#offset_y ⇒ Integer (readonly)
Returns the value of attribute offset_y.
5 6 7 |
# File 'lib/retouch/geometry.rb', line 5 def offset_y @offset_y end |
#width ⇒ Integer, ... (readonly)
Returns the value of attribute width.
5 6 7 |
# File 'lib/retouch/geometry.rb', line 5 def width @width end |
Class Method Details
.parse(value) ⇒ Geometry
7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/retouch/geometry.rb', line 7 def self.parse(value) text = String(value) match = /\A(?:(?<width>\d+(?:\.\d+)?%?)?x(?<height>\d+(?:\.\d+)?%?)?|(?<single>\d+(?:\.\d+)?%))(?<mode>[!^>])?(?<x>[+-]\d+)?(?<y>[+-]\d+)?\z/.match(text) raise ArgumentError, "invalid geometry: #{text}" unless match width = match[:width] || match[:single] height = match[:height] || match[:single] raise ArgumentError, "geometry needs at least one dimension" unless width || height mode = { "!" => :stretch, "^" => :cover, ">" => :shrink }.fetch(match[:mode], :fit) raise ArgumentError, "geometry needs both offsets" if match[:x].nil? != match[:y].nil? new(width && dimension(width), height && dimension(height), (match[:x] || 0).to_i, (match[:y] || 0).to_i, mode) end |
Instance Method Details
#crop_size(source_width, source_height) ⇒ [Integer, Integer]
38 39 40 41 42 |
# File 'lib/retouch/geometry.rb', line 38 def crop_size(source_width, source_height) raise ArgumentError, "crop geometry needs both dimensions" unless width && height [scaled_dimension(source_width, width), scaled_dimension(source_height, height)] end |
#target_size(source_width, source_height) ⇒ [Integer, Integer]
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/retouch/geometry.rb', line 44 def target_size(source_width, source_height) width_ratio = width.is_a?(Float) ? width : nil height_ratio = height.is_a?(Float) ? height : nil target_width = width_ratio ? source_width * width_ratio : width target_height = height_ratio ? source_height * height_ratio : height return [scaled_dimension(source_width, width_ratio), scaled_dimension(source_height, height_ratio)] if width_ratio && height_ratio return [scaled_dimension(source_width, target_width), scaled_dimension(source_height, target_height)] if mode == :stretch && target_width && target_height scale = if target_width && target_height horizontal = target_width.to_f / source_width vertical = target_height.to_f / source_height mode == :cover ? [horizontal, vertical].max : [horizontal, vertical].min elsif target_width target_width.to_f / source_width elsif target_height target_height.to_f / source_height else 1.0 end scale = [scale, 1.0].min if mode == :shrink [(source_width * scale).round.clamp(1, 1_000_000), (source_height * scale).round.clamp(1, 1_000_000)] end |