Module: SpriteFactory::Layout::Packed

Defined in:
lib/sprite_factory/layout/packed.rb

Class Method Summary collapse

Class Method Details

.findNode(root, w, h) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/sprite_factory/layout/packed.rb', line 56

def self.findNode(root, w, h)
  if root[:used]
    findNode(root[:right], w, h) || findNode(root[:down], w, h)
  elsif (w <= root[:w]) && (h <= root[:h])
    root
  end
end

.grow(root, w, h) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/sprite_factory/layout/packed.rb', line 70

def self.grow(root, w, h)

  canGrowDown  = (w <= root[:w])
  canGrowRight = (h <= root[:h])

  shouldGrowRight = canGrowRight && (root[:h] >= (root[:w] + w))
  shouldGrowDown  = canGrowDown  && (root[:w] >= (root[:h] + h))

  if shouldGrowRight
    growRight(root, w, h)
  elsif shouldGrowDown
    growDown(root, w, h)
  elsif canGrowRight
    growRight(root, w, h)
  elsif canGrowDown
    growDown(root, w, h)
  else
    raise RuntimeError, "can't fit #{w}x#{h} block into root #{root[:w]}x#{root[:h]} - this should not happen if images are pre-sorted correctly"
  end

end

.growDown(root, w, h) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/sprite_factory/layout/packed.rb', line 104

def self.growDown(root, w, h)
  return {
    :used  => true,
    :x     => 0,
    :y     => 0,
    :w     => root[:w],
    :h     => root[:h] + h,
    :down  => { :x => 0, :y => root[:h], :w => root[:w], :h => h },
    :right => root
  }
end

.growRight(root, w, h) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/sprite_factory/layout/packed.rb', line 92

def self.growRight(root, w, h)
  return {
    :used  => true,
    :x     => 0,
    :y     => 0,
    :w     => root[:w] + w,
    :h     => root[:h],
    :down  => root,
    :right => { :x => root[:w], :y => 0, :w => w, :h => root[:h] }
  }
end

.layout(images, options = {}) ⇒ Object


Raises:

  • (NotImplementedError)


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
41
42
43
44
45
# File 'lib/sprite_factory/layout/packed.rb', line 7

def self.layout(images, options = {})

  raise NotImplementedError, ":packed layout does not support fixed :width/:height option" if options[:width] || options[:height]

  return { :width => 0, :height => 0 } if images.empty?

  hpadding = options[:hpadding] || 0
  vpadding = options[:vpadding] || 0
  hmargin  = options[:hmargin]  || 0
  vmargin  = options[:vmargin]  || 0

  images.each do |i|
    i[:w] = i[:width]  + (2*hpadding) + (2*hmargin)
    i[:h] = i[:height] + (2*vpadding) + (2*vmargin)
  end

  images.sort! do |a,b|
    diff = [b[:w], b[:h]].max <=> [a[:w], a[:h]].max
    diff = [b[:w], b[:h]].min <=> [a[:w], a[:h]].min if diff.zero?
    diff = b[:h] <=> a[:h] if diff.zero?
    diff = b[:w]  <=> a[:w]  if diff.zero?
    diff
  end

  root = { :x => 0, :y => 0, :w => images[0][:w], :h => images[0][:h] }

  images.each do |i|
    if (node = findNode(root, i[:w], i[:h]))
      placeImage(i, node, hpadding, vpadding, hmargin, vmargin)
      splitNode(node, i[:w], i[:h])
    else
      root = grow(root, i[:w], i[:h])
      redo
    end
  end

  { :width => root[:w], :height => root[:h] }

end

.placeImage(image, node, hpadding, vpadding, hmargin, vmargin) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/sprite_factory/layout/packed.rb', line 47

def self.placeImage(image, node, hpadding, vpadding, hmargin, vmargin)
  image[:cssx] = node[:x] + hmargin
  image[:cssy] = node[:y] + vmargin
  image[:cssw] = image[:width]  + (2*hpadding)
  image[:cssh] = image[:height] + (2*vpadding)
  image[:x]    = image[:cssx] + hpadding 
  image[:y]    = image[:cssy] + vpadding
end

.splitNode(node, w, h) ⇒ Object



64
65
66
67
68
# File 'lib/sprite_factory/layout/packed.rb', line 64

def self.splitNode(node, w, h)
  node[:used]  = true
  node[:down]  = { :x => node[:x],     :y => node[:y] + h, :w => node[:w],     :h => node[:h] - h }
  node[:right] = { :x => node[:x] + w, :y => node[:y],     :w => node[:w] - w, :h => h            }
end