sprite-factory 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,7 +16,11 @@ Gem::Specification.new do |s|
16
16
  s.add_development_dependency 'rmagick'
17
17
  s.add_development_dependency 'chunky_png'
18
18
 
19
- s.files = `git ls-files`.split("\n")
19
+ s.has_rdoc = false
20
+ s.extra_rdoc_files = ["README.md"]
21
+ s.rdoc_options = ["--charset=UTF-8"]
22
+
23
+ s.files = `git ls-files `.split("\n")
20
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
25
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
26
  s.require_paths = ["lib"]
@@ -6,12 +6,14 @@
6
6
  <link href='regular.css' rel='stylesheet' type='text/css' media='screen'></link>
7
7
  <link href='regular.horizontal.css' rel='stylesheet' type='text/css' media='screen'></link>
8
8
  <link href='regular.vertical.css' rel='stylesheet' type='text/css' media='screen'></link>
9
+ <link href='regular.packed.css' rel='stylesheet' type='text/css' media='screen'></link>
9
10
  <link href='regular.padded.css' rel='stylesheet' type='text/css' media='screen'></link>
10
11
  <link href='regular.fixed.css' rel='stylesheet' type='text/css' media='screen'></link>
11
12
  <link href='regular.sassy.css' rel='stylesheet' type='text/css' media='screen'></link>
12
13
  <link href='irregular.css' rel='stylesheet' type='text/css' media='screen'></link>
13
14
  <link href='irregular.horizontal.css' rel='stylesheet' type='text/css' media='screen'></link>
14
15
  <link href='irregular.vertical.css' rel='stylesheet' type='text/css' media='screen'></link>
16
+ <link href='irregular.packed.css' rel='stylesheet' type='text/css' media='screen'></link>
15
17
  <link href='irregular.padded.css' rel='stylesheet' type='text/css' media='screen'></link>
16
18
  <link href='irregular.fixed.css' rel='stylesheet' type='text/css' media='screen'></link>
17
19
  <link href='irregular.sassy.css' rel='stylesheet' type='text/css' media='screen'></link>
@@ -44,6 +46,13 @@
44
46
  <img src='s.gif' class='vertical_regular4'><br>
45
47
  <img src='s.gif' class='vertical_regular5'><br>
46
48
 
49
+ <h1>Regular (packed)</h1>
50
+ <img src='s.gif' class='packed_regular1'>
51
+ <img src='s.gif' class='packed_regular2'>
52
+ <img src='s.gif' class='packed_regular3'>
53
+ <img src='s.gif' class='packed_regular4'>
54
+ <img src='s.gif' class='packed_regular5'>
55
+
47
56
  <h1>Regular (padded)</h1>
48
57
  <img src='s.gif' class='padded_regular1'>
49
58
  <img src='s.gif' class='padded_regular2'>
@@ -86,6 +95,13 @@
86
95
  <img src='s.gif' class='vertical_irregular4'><br>
87
96
  <img src='s.gif' class='vertical_irregular5'><br>
88
97
 
98
+ <h1>Irregular (packed)</h1>
99
+ <img src='s.gif' class='packed_irregular1'>
100
+ <img src='s.gif' class='packed_irregular2'>
101
+ <img src='s.gif' class='packed_irregular3'>
102
+ <img src='s.gif' class='packed_irregular4'>
103
+ <img src='s.gif' class='packed_irregular5'>
104
+
89
105
  <h1>Irregular (padded)</h1>
90
106
  <img src='s.gif' class='padded_irregular1'>
91
107
  <img src='s.gif' class='padded_irregular2'>
@@ -0,0 +1,24 @@
1
+ /*
2
+
3
+ Creating a sprite from following images:
4
+
5
+ test/images/irregular/irregular1.png (60x60)
6
+ test/images/irregular/irregular3.png (48x48)
7
+ test/images/irregular/irregular5.png (46x25)
8
+ test/images/irregular/irregular4.png (34x14)
9
+ test/images/irregular/irregular2.png (16x16)
10
+
11
+ Output files:
12
+ test/images/irregular.packed.png
13
+ test/images/irregular.packed.css
14
+
15
+ Output size:
16
+ 108x101
17
+
18
+
19
+ */
20
+ img.packed_irregular1 { width: 60px; height: 60px; background: url(irregular.packed.png) 0px 0px no-repeat; }
21
+ img.packed_irregular3 { width: 48px; height: 48px; background: url(irregular.packed.png) -60px 0px no-repeat; }
22
+ img.packed_irregular5 { width: 46px; height: 25px; background: url(irregular.packed.png) 0px -60px no-repeat; }
23
+ img.packed_irregular4 { width: 34px; height: 14px; background: url(irregular.packed.png) -46px -60px no-repeat; }
24
+ img.packed_irregular2 { width: 16px; height: 16px; background: url(irregular.packed.png) 0px -85px no-repeat; }
@@ -0,0 +1,24 @@
1
+ /*
2
+
3
+ Creating a sprite from following images:
4
+
5
+ test/images/regular/regular1.png (64x64)
6
+ test/images/regular/regular2.png (64x64)
7
+ test/images/regular/regular3.png (64x64)
8
+ test/images/regular/regular4.png (64x64)
9
+ test/images/regular/regular5.png (64x64)
10
+
11
+ Output files:
12
+ test/images/regular.packed.png
13
+ test/images/regular.packed.css
14
+
15
+ Output size:
16
+ 192x128
17
+
18
+
19
+ */
20
+ img.packed_regular1 { width: 64px; height: 64px; background: url(regular.packed.png) 0px 0px no-repeat; }
21
+ img.packed_regular2 { width: 64px; height: 64px; background: url(regular.packed.png) -64px 0px no-repeat; }
22
+ img.packed_regular3 { width: 64px; height: 64px; background: url(regular.packed.png) 0px -64px no-repeat; }
23
+ img.packed_regular4 { width: 64px; height: 64px; background: url(regular.packed.png) -64px -64px no-repeat; }
24
+ img.packed_regular5 { width: 64px; height: 64px; background: url(regular.packed.png) -128px 0px no-repeat; }
@@ -21,6 +21,12 @@ module SpriteFactory
21
21
  :layout => :vertical)
22
22
  end
23
23
 
24
+ def test_generate_packed_regular_sprite
25
+ integration_test(REGULAR_PATH, :output => output_path('regular.packed'),
26
+ :selector => 'img.packed_',
27
+ :layout => :packed)
28
+ end
29
+
24
30
  def test_generate_regular_sprite_with_padding
25
31
  integration_test(REGULAR_PATH, :output => output_path('regular.padded'),
26
32
  :selector => 'img.padded_',
@@ -58,6 +64,12 @@ module SpriteFactory
58
64
  :layout => :vertical)
59
65
  end
60
66
 
67
+ def test_generate_packed_irregular_sprite
68
+ integration_test(IRREGULAR_PATH, :output => output_path('irregular.packed'),
69
+ :selector => 'img.packed_',
70
+ :layout => :packed)
71
+ end
72
+
61
73
  def test_generate_irregular_sprite_with_padding
62
74
  integration_test(IRREGULAR_PATH, :output => output_path('irregular.padded'),
63
75
  :selector => 'img.padded_',
@@ -0,0 +1,100 @@
1
+ require File.expand_path('test_case', File.dirname(__FILE__))
2
+
3
+ module SpriteFactory
4
+ module Layout
5
+ class HorizontalTest < SpriteFactory::Layout::TestCase
6
+
7
+ #==========================================================================
8
+ # test REGULAR images
9
+ #==========================================================================
10
+
11
+ def test_horizontal_layout_of_regular_images
12
+ images = get_regular_images
13
+ expected = [
14
+ { :x => 0, :y => 0 },
15
+ { :x => 20, :y => 0 },
16
+ { :x => 40, :y => 0 },
17
+ { :x => 60, :y => 0 },
18
+ { :x => 80, :y => 0 }
19
+ ]
20
+ verify_layout(100, 10, expected, images, :layout => :horizontal)
21
+ end
22
+
23
+ #--------------------------------------------------------------------------
24
+
25
+ def test_padded_horizontal_layout_of_regular_images
26
+ images = get_regular_images
27
+ expected = [
28
+ { :cssx => 0, :cssy => 0, :cssw => 40, :cssh => 50, :x => 10, :y => 20 },
29
+ { :cssx => 40, :cssy => 0, :cssw => 40, :cssh => 50, :x => 50, :y => 20 },
30
+ { :cssx => 80, :cssy => 0, :cssw => 40, :cssh => 50, :x => 90, :y => 20 },
31
+ { :cssx => 120, :cssy => 0, :cssw => 40, :cssh => 50, :x => 130, :y => 20 },
32
+ { :cssx => 160, :cssy => 0, :cssw => 40, :cssh => 50, :x => 170, :y => 20 }
33
+ ]
34
+ verify_layout(200, 50, expected, images, :layout => :horizontal, :hpadding => 10, :vpadding => 20)
35
+ end
36
+
37
+ #--------------------------------------------------------------------------
38
+
39
+ def test_fixed_horizontal_layout_of_regular_images
40
+ images = get_regular_images
41
+ expected = [
42
+ { :cssx => 0, :cssy => 0, :cssw => 50, :cssh => 50, :x => 15, :y => 20 },
43
+ { :cssx => 50, :cssy => 0, :cssw => 50, :cssh => 50, :x => 65, :y => 20 },
44
+ { :cssx => 100, :cssy => 0, :cssw => 50, :cssh => 50, :x => 115, :y => 20 },
45
+ { :cssx => 150, :cssy => 0, :cssw => 50, :cssh => 50, :x => 165, :y => 20 },
46
+ { :cssx => 200, :cssy => 0, :cssw => 50, :cssh => 50, :x => 215, :y => 20 }
47
+ ]
48
+ verify_layout(250, 50, expected, images, :layout => :horizontal, :width => 50, :height => 50)
49
+ end
50
+
51
+ #==========================================================================
52
+ # test IRREGULAR images
53
+ #==========================================================================
54
+
55
+ def test_horizontal_layout_of_irregular_images
56
+ images = get_irregular_images
57
+ expected = [
58
+ { :x => 0, :y => 0 },
59
+ { :x => 20, :y => 5 },
60
+ { :x => 60, :y => 10 },
61
+ { :x => 120, :y => 15 },
62
+ { :x => 200, :y => 20 }
63
+ ]
64
+ verify_layout(300, 50, expected, images, :layout => :horizontal)
65
+ end
66
+
67
+ #--------------------------------------------------------------------------
68
+
69
+ def test_padded_horizontal_layout_of_irregular_images
70
+ images = get_irregular_images
71
+ expected = [
72
+ { :cssx => 0, :cssy => 0, :cssw => 40, :cssh => 90, :x => 10, :y => 20 },
73
+ { :cssx => 40, :cssy => 5, :cssw => 60, :cssh => 80, :x => 50, :y => 25 },
74
+ { :cssx => 100, :cssy => 10, :cssw => 80, :cssh => 70, :x => 110, :y => 30 },
75
+ { :cssx => 180, :cssy => 15, :cssw => 100, :cssh => 60, :x => 190, :y => 35 },
76
+ { :cssx => 280, :cssy => 20, :cssw => 120, :cssh => 50, :x => 290, :y => 40 }
77
+ ]
78
+ verify_layout(400, 90, expected, images, :layout => :horizontal, :hpadding => 10, :vpadding => 20)
79
+ end
80
+
81
+ #--------------------------------------------------------------------------
82
+
83
+ def test_fixed_horizontal_layout_of_irregular_images
84
+ images = get_irregular_images
85
+ expected = [
86
+ { :cssx => 0, :cssy => 0, :cssw => 100, :cssh => 100, :x => 40, :y => 25 },
87
+ { :cssx => 100, :cssy => 0, :cssw => 100, :cssh => 100, :x => 130, :y => 30 },
88
+ { :cssx => 200, :cssy => 0, :cssw => 100, :cssh => 100, :x => 220, :y => 35 },
89
+ { :cssx => 300, :cssy => 0, :cssw => 100, :cssh => 100, :x => 310, :y => 40 },
90
+ { :cssx => 400, :cssy => 0, :cssw => 100, :cssh => 100, :x => 400, :y => 45 }
91
+ ]
92
+ verify_layout(500, 100, expected, images, :layout => :horizontal, :width => 100, :height => 100)
93
+ end
94
+
95
+ #--------------------------------------------------------------------------
96
+
97
+ end # class HorizontalTest
98
+ end # module Layout
99
+ end # module SpriteFactory
100
+
@@ -0,0 +1,221 @@
1
+ require File.expand_path('test_case', File.dirname(__FILE__))
2
+
3
+ module SpriteFactory
4
+ module Layout
5
+ class PackedTest < SpriteFactory::Layout::TestCase
6
+
7
+ #==========================================================================
8
+ # test REGULAR images
9
+ #==========================================================================
10
+
11
+ def test_packed_layout_of_regular_images
12
+ images = get_regular_images
13
+ expected = [ # expected: ---------
14
+ { :x => 0, :y => 0 }, # |111|333|
15
+ { :x => 0, :y => 10 }, # ---------
16
+ { :x => 20, :y => 0 }, # |222|444|
17
+ { :x => 20, :y => 10 }, # ---------
18
+ { :x => 0, :y => 20 } # |555| |
19
+ ] # ---------
20
+ verify_layout(40, 30, expected, images, :layout => :packed)
21
+ end
22
+
23
+ #--------------------------------------------------------------------------
24
+
25
+ def test_padded_packed_layout_of_regular_images
26
+ assert_not_implemented ":packed layout does not support the :padding option" do
27
+ Layout::Packed.layout(get_regular_images, :padding => 10)
28
+ end
29
+ end
30
+
31
+ #--------------------------------------------------------------------------
32
+
33
+ def test_fixed_packed_layout_of_regular_images
34
+ assert_not_implemented ":packed layout does not support fixed :width/:height option" do
35
+ Layout::Packed.layout(get_regular_images, :width => 50, :height => 50)
36
+ end
37
+ end
38
+
39
+ #==========================================================================
40
+ # test IRREGULAR images
41
+ #==========================================================================
42
+
43
+ def test_packed_layout_of_irregular_images
44
+ images = get_irregular_images
45
+ # expected: -----------------
46
+ expected = [ # |11111111111|444|
47
+ { :x => 0, :y => 0 }, # ------------|444|
48
+ { :x => 0, :y => 10 }, # |2222222| |444|
49
+ { :x => 0, :y => 30 }, # ------------|444|
50
+ { :x => 100, :y => 0 }, # |3333| -----
51
+ { :x => 0, :y => 60 } # -----------------
52
+ ] # |555| |
53
+ # -----------------
54
+ verify_layout(120, 100, expected, images, :layout => :packed)
55
+ end
56
+
57
+ #==========================================================================
58
+ # other packed algorithm test
59
+ #==========================================================================
60
+
61
+ def test_single_image_is_100_percent_packed
62
+ images = [
63
+ { :width => 100, :height => 100 },
64
+ { :width => 100, :height => 50 },
65
+ { :width => 50, :height => 100 }
66
+ ]
67
+ images.each do |image|
68
+ verify_layout(image[:width], image[:height], [{:x => 0, :y => 0}], [image], :layout => :packed)
69
+ end
70
+ end
71
+
72
+ #==========================================================================
73
+ # some test cases from original bin packing demonstration
74
+ # (see http://codeincomplete.com/posts/2011/5/7/bin_packing/example/)
75
+ #==========================================================================
76
+
77
+ def test_packed_simple
78
+ images = expanded_images([
79
+ { :width => 500, :height => 200 },
80
+ { :width => 250, :height => 200 },
81
+ { :width => 50, :height => 50, :num => 20 }
82
+ ])
83
+ expected = [
84
+ { :x => 0, :y => 0 },
85
+ { :x => 0, :y => 200 },
86
+ { :x => 250, :y => 200 },
87
+ { :x => 300, :y => 200 },
88
+ { :x => 350, :y => 200 },
89
+ { :x => 400, :y => 200 },
90
+ { :x => 450, :y => 200 },
91
+ { :x => 250, :y => 250 },
92
+ { :x => 300, :y => 250 },
93
+ { :x => 350, :y => 250 },
94
+ { :x => 400, :y => 250 },
95
+ { :x => 450, :y => 250 },
96
+ { :x => 250, :y => 300 },
97
+ { :x => 300, :y => 300 },
98
+ { :x => 350, :y => 300 },
99
+ { :x => 400, :y => 300 },
100
+ { :x => 450, :y => 300 },
101
+ { :x => 250, :y => 350 },
102
+ { :x => 300, :y => 350 },
103
+ { :x => 350, :y => 350 },
104
+ { :x => 400, :y => 350 },
105
+ { :x => 450, :y => 350 }
106
+ ]
107
+ verify_layout(500, 400, expected, images, :layout => :packed)
108
+ end
109
+
110
+ #--------------------------------------------------------------------------
111
+
112
+ def test_packed_square
113
+ images = expanded_images([{ :width => 50, :height => 50, :num => 16 }])
114
+ expected = [
115
+ { :x => 0, :y => 0 },
116
+ { :x => 50, :y => 0 },
117
+ { :x => 0, :y => 50 },
118
+ { :x => 50, :y => 50 },
119
+ { :x => 100, :y => 0 },
120
+ { :x => 100, :y => 50 },
121
+ { :x => 0, :y => 100 },
122
+ { :x => 50, :y => 100 },
123
+ { :x => 100, :y => 100 },
124
+ { :x => 150, :y => 0 },
125
+ { :x => 150, :y => 50 },
126
+ { :x => 150, :y => 100 },
127
+ { :x => 0, :y => 150 },
128
+ { :x => 50, :y => 150 },
129
+ { :x => 100, :y => 150 },
130
+ { :x => 150, :y => 150 }
131
+ ]
132
+ verify_layout(200, 200, expected, images, :layout => :packed)
133
+ end
134
+
135
+ #--------------------------------------------------------------------------
136
+
137
+ def test_packed_tall
138
+ images = expanded_images([{ :width => 50, :height => 500, :num => 5 }])
139
+ expected = [
140
+ { :x => 0, :y => 0 },
141
+ { :x => 50, :y => 0 },
142
+ { :x => 100, :y => 0 },
143
+ { :x => 150, :y => 0 },
144
+ { :x => 200, :y => 0 }
145
+ ]
146
+ verify_layout(250, 500, expected, images, :layout => :packed)
147
+ end
148
+
149
+ #--------------------------------------------------------------------------
150
+
151
+ def test_packed_wide
152
+ images = expanded_images([{ :width => 500, :height => 50, :num => 5 }])
153
+ expected = [
154
+ { :x => 0, :y => 0 },
155
+ { :x => 0, :y => 50 },
156
+ { :x => 0, :y => 100 },
157
+ { :x => 0, :y => 150 },
158
+ { :x => 0, :y => 200 }
159
+ ]
160
+ verify_layout(500, 250, expected, images, :layout => :packed)
161
+ end
162
+
163
+ #--------------------------------------------------------------------------
164
+
165
+ def test_packed_tall_and_wide
166
+ images = expanded_images([
167
+ { :width => 50, :height => 500, :num => 3 },
168
+ { :width => 500, :height => 50, :num => 3 }
169
+ ])
170
+ expected = [
171
+ { :x => 0, :y => 0 },
172
+ { :x => 50, :y => 0 },
173
+ { :x => 100, :y => 0 },
174
+ { :x => 150, :y => 0 },
175
+ { :x => 150, :y => 50 },
176
+ { :x => 150, :y => 100 }
177
+ ]
178
+ verify_layout(650, 500, expected, images, :layout => :packed)
179
+ end
180
+
181
+ #--------------------------------------------------------------------------
182
+
183
+ def test_packed_powers_of_2
184
+ images = expanded_images([
185
+ { :width => 64, :height => 64, :num => 2 },
186
+ { :width => 32, :height => 32, :num => 4 },
187
+ { :width => 16, :height => 16, :num => 8 }
188
+ ])
189
+ expected = [
190
+ { :x => 0, :y => 0 },
191
+ { :x => 64, :y => 0 },
192
+ { :x => 0, :y => 64 },
193
+ { :x => 32, :y => 64 },
194
+ { :x => 64, :y => 64 },
195
+ { :x => 96, :y => 64 },
196
+ { :x => 0, :y => 96 },
197
+ { :x => 16, :y => 96 },
198
+ { :x => 32, :y => 96 },
199
+ { :x => 48, :y => 96 },
200
+ { :x => 64, :y => 96 },
201
+ { :x => 80, :y => 96 },
202
+ { :x => 96, :y => 96 },
203
+ { :x => 112, :y => 96 }
204
+ ]
205
+ verify_layout(128, 112, expected, images, :layout => :packed)
206
+ end
207
+
208
+ #--------------------------------------------------------------------------
209
+
210
+ protected
211
+
212
+ def expanded_images(images)
213
+ result = images.map do |i|
214
+ (1..(i[:num] || 1)).map{{:width => i[:width], :height => i[:height]}}
215
+ end.flatten
216
+ end
217
+
218
+ end # class PackedTest
219
+ end # module Layout
220
+ end # module SpriteFactory
221
+