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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/lash-sprites/packer/vertical_split.rb', line 8
def self.pack(images, options = {})
width = 0
height = 0
images = images.dup
images.sort! do |a, b|
a.width <=> b.width
end
i = images.pop
width = i.width
height = i.height
i.x = 0
i.y = 0
images.sort! do |a, b|
a.area <=> b.area
end
block_heap = Heap.new {|a,b| b.area <=> a.area}
while !images.empty?
if block_heap.empty?
img = images.pop
if width == 0 && height == 0
img.x = 0
img.y = 0
width = img.width
height = img.height
else
if img.width > width
block_heap.insert(Block.new(width, 0, img.width - width, height))
width = img.width
elsif img.width < width
block_heap.insert(Block.new(img.width, height, width - img.width, img.height))
end
img.x = 0
img.y = height
height += img.height
end
else
while !block_heap.empty? && !images.empty?
block = block_heap.remove
cur_img = nil
cur_exact = nil
images.each_index do |i|
cur_img = i if block.fits?(images[i])
cur_exact = i if block.fits?(images[i]) && (block.width == images[i].width || block.height == images[i].height)
end
if !cur_exact.nil?
img = images.delete_at(cur_exact)
img.x = block.x
img.y = block.y
split_block(block, img).each do |b|
block_heap.insert(b)
end
elsif !cur_img.nil?
img = images.delete_at(cur_img)
img.x = block.x
img.y = block.y
split_block(block, img).each do |b|
block_heap.insert(b)
end
else
end
end
end
end
return {:width => width, :height => height}
end
|