Module: Imgry::Geometry

Extended by:
Geometry
Included in:
Geometry
Defined in:
lib/imgry/geometry.rb

Constant Summary collapse

W =

borrowed from RMagick

/(\d+\.\d+%?)|(\d*%?)/
H =
W
X =
/(?:([-+]\d+))?/
Y =
X
REGEXP =
/\A#{W}x?#{H}#{X}#{Y}([!<>@\^]?)\Z/

Instance Method Summary collapse

Instance Method Details

#from_s(str) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/imgry/geometry.rb', line 57

def from_s(str)
  m = REGEXP.match(str)
  if m
      width  = (m[1] || m[2]).to_f
      height = (m[3] || m[4]).to_f
      x      = m[5].to_i
      y      = m[6].to_i
      flag   = m[7]
  else
      raise ArgumentError, "invalid geometry format"
  end
  [width, height, x, y, flag]
end

#scale(orig_width, orig_height, geometry) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/imgry/geometry.rb', line 5

def scale(orig_width, orig_height, geometry)
  # TODO: basic verification of geometry syntax
  new_width, new_height = nil, nil
  ask_width, ask_height, _, _, op = from_s(geometry)

  ask_height ||= 0
  aspect_ratio = orig_width.to_f / orig_height.to_f

  scale = Proc.new do |ask_is_maximum = true|
    ask_aspect_ratio = ask_width.to_f / ask_height.to_f
    # Fill requested height if result should cover narrower aspect or should be contained within wider aspect
    fill_height = (ask_is_maximum && ask_aspect_ratio > aspect_ratio) || (!ask_is_maximum && ask_aspect_ratio < aspect_ratio)
    if ask_width == 0 || (ask_height != 0 && fill_height)
      # Fill height, calculate width
      new_width, new_height = scale_by_height(ask_height, aspect_ratio)
    else
      # Fill width, calculate height
      new_width, new_height = scale_by_width(ask_width, aspect_ratio)
    end
  end

  case op
  when '!'
    new_width, new_height = ask_width.to_i, ask_height.to_i
  when '^'
    scale.call(false)
  when '>'
    scale.call if orig_width > ask_width || orig_height > ask_height
  when '<'
    scale.call if orig_width < ask_width || orig_height < ask_height
  else
    scale.call
  end

  [new_width || orig_width, new_height || orig_height]
end

#scale_by_height(new_height, aspect_ratio) ⇒ Object



46
47
48
# File 'lib/imgry/geometry.rb', line 46

def scale_by_height(new_height, aspect_ratio)
  [(new_height * aspect_ratio).to_i, new_height.to_i]
end

#scale_by_width(new_width, aspect_ratio) ⇒ Object



42
43
44
# File 'lib/imgry/geometry.rb', line 42

def scale_by_width(new_width, aspect_ratio)
  [new_width.to_i, (new_width / aspect_ratio).to_i]
end