css-spriter 0.9.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +7 -9
- data/Rakefile +7 -8
- data/VERSION +1 -1
- data/bin/css-spriter +1 -1
- data/css-spriter.gemspec +106 -0
- data/lib/css-spriter.rb +2 -11
- data/lib/css-spriter/directory_processor.rb +82 -78
- data/lib/css-spriter/image.rb +13 -0
- data/lib/css-spriter/mtime_tracker.rb +64 -61
- data/lib/css-spriter/sprite.rb +39 -31
- data/lib/css-spriter/stylesheet_builder.rb +19 -17
- data/spec/builders/image_builder.rb +3 -8
- data/spec/integration_spec.rb +27 -50
- data/spec/lib/css_spriter_image_spec.rb +8 -0
- data/spec/lib/sprite_spec.rb +4 -6
- data/spec/mtime_tracking_spec.rb +33 -19
- data/spec/spec_helper.rb +5 -5
- metadata +50 -40
- data/.gitignore +0 -12
- data/bin/png_info +0 -61
- data/examples/filter_util.rb +0 -17
- data/lib/css-spriter/image_data.rb +0 -128
- data/lib/css-spriter/png/chunk.rb +0 -12
- data/lib/css-spriter/png/file_header.rb +0 -7
- data/lib/css-spriter/png/filters.rb +0 -80
- data/lib/css-spriter/png/idat.rb +0 -26
- data/lib/css-spriter/png/iend.rb +0 -9
- data/lib/css-spriter/png/ihdr.rb +0 -34
- data/lib/css-spriter/png/image.rb +0 -153
- data/lib/css-spriter/png/parser.rb +0 -54
- data/spec/image_data_spec.rb +0 -63
- data/spec/lib/file_header_spec.rb +0 -10
- data/spec/lib/idat_spec.rb +0 -31
- data/spec/lib/ihdr_spec.rb +0 -43
- data/spec/lib/image_spec.rb +0 -42
- data/spec/lib/parser_spec.rb +0 -12
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: css-spriter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 21
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- aberant
|
@@ -10,39 +16,56 @@ autorequire:
|
|
10
16
|
bindir: bin
|
11
17
|
cert_chain: []
|
12
18
|
|
13
|
-
date:
|
14
|
-
default_executable:
|
19
|
+
date: 2011-03-23 00:00:00 -05:00
|
20
|
+
default_executable: css-spriter
|
15
21
|
dependencies:
|
16
22
|
- !ruby/object:Gem::Dependency
|
17
23
|
name: rspec
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
21
27
|
requirements:
|
22
28
|
- - ">="
|
23
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
24
33
|
version: "0"
|
25
|
-
|
26
|
-
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: chunky_png
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 19
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 1
|
48
|
+
- 0
|
49
|
+
version: 1.1.0
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
description: CSS-Spriter is a pure ruby PNG spriting library. It can be used standalone or as a Rails plugin, see the readme for details.
|
27
53
|
email:
|
28
54
|
- qzzzq1@gmail.com
|
29
55
|
- tyler.jennings@gmail.com
|
30
56
|
executables:
|
31
57
|
- css-spriter
|
32
|
-
- png_info
|
33
58
|
extensions: []
|
34
59
|
|
35
60
|
extra_rdoc_files:
|
36
61
|
- README.rdoc
|
37
62
|
files:
|
38
|
-
- .gitignore
|
39
63
|
- MIT-LICENSE
|
40
64
|
- README.rdoc
|
41
65
|
- Rakefile
|
42
66
|
- VERSION
|
43
67
|
- bin/css-spriter
|
44
|
-
-
|
45
|
-
- examples/filter_util.rb
|
68
|
+
- css-spriter.gemspec
|
46
69
|
- examples/sprites/.mtimes
|
47
70
|
- examples/sprites/README
|
48
71
|
- examples/sprites/fragment.css
|
@@ -67,16 +90,8 @@ files:
|
|
67
90
|
- init.rb
|
68
91
|
- lib/css-spriter.rb
|
69
92
|
- lib/css-spriter/directory_processor.rb
|
70
|
-
- lib/css-spriter/
|
93
|
+
- lib/css-spriter/image.rb
|
71
94
|
- lib/css-spriter/mtime_tracker.rb
|
72
|
-
- lib/css-spriter/png/chunk.rb
|
73
|
-
- lib/css-spriter/png/file_header.rb
|
74
|
-
- lib/css-spriter/png/filters.rb
|
75
|
-
- lib/css-spriter/png/idat.rb
|
76
|
-
- lib/css-spriter/png/iend.rb
|
77
|
-
- lib/css-spriter/png/ihdr.rb
|
78
|
-
- lib/css-spriter/png/image.rb
|
79
|
-
- lib/css-spriter/png/parser.rb
|
80
95
|
- lib/css-spriter/processor.rb
|
81
96
|
- lib/css-spriter/sprite.rb
|
82
97
|
- lib/css-spriter/stylesheet_builder.rb
|
@@ -85,14 +100,9 @@ files:
|
|
85
100
|
- spec/css_fragments/some/fragment.css
|
86
101
|
- spec/expected_output/merge_right_test.png
|
87
102
|
- spec/expected_output/write_test.png
|
88
|
-
- spec/image_data_spec.rb
|
89
103
|
- spec/images/lightening.png
|
90
104
|
- spec/integration_spec.rb
|
91
|
-
- spec/lib/
|
92
|
-
- spec/lib/idat_spec.rb
|
93
|
-
- spec/lib/ihdr_spec.rb
|
94
|
-
- spec/lib/image_spec.rb
|
95
|
-
- spec/lib/parser_spec.rb
|
105
|
+
- spec/lib/css_spriter_image_spec.rb
|
96
106
|
- spec/lib/sprite_spec.rb
|
97
107
|
- spec/mtime_tracking_spec.rb
|
98
108
|
- spec/spec.opts
|
@@ -109,40 +119,40 @@ homepage: http://github.com/aberant/css-spriter
|
|
109
119
|
licenses: []
|
110
120
|
|
111
121
|
post_install_message:
|
112
|
-
rdoc_options:
|
113
|
-
|
122
|
+
rdoc_options: []
|
123
|
+
|
114
124
|
require_paths:
|
115
125
|
- lib
|
116
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
117
128
|
requirements:
|
118
129
|
- - ">="
|
119
130
|
- !ruby/object:Gem::Version
|
131
|
+
hash: 3
|
132
|
+
segments:
|
133
|
+
- 0
|
120
134
|
version: "0"
|
121
|
-
version:
|
122
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
123
137
|
requirements:
|
124
138
|
- - ">="
|
125
139
|
- !ruby/object:Gem::Version
|
140
|
+
hash: 3
|
141
|
+
segments:
|
142
|
+
- 0
|
126
143
|
version: "0"
|
127
|
-
version:
|
128
144
|
requirements: []
|
129
145
|
|
130
146
|
rubyforge_project:
|
131
|
-
rubygems_version: 1.3.
|
147
|
+
rubygems_version: 1.3.7
|
132
148
|
signing_key:
|
133
149
|
specification_version: 3
|
134
150
|
summary: pure ruby PNG spriting library
|
135
151
|
test_files:
|
152
|
+
- examples/sprites/server.rb
|
136
153
|
- spec/builders/image_builder.rb
|
137
|
-
- spec/image_data_spec.rb
|
138
154
|
- spec/integration_spec.rb
|
139
|
-
- spec/lib/
|
140
|
-
- spec/lib/idat_spec.rb
|
141
|
-
- spec/lib/ihdr_spec.rb
|
142
|
-
- spec/lib/image_spec.rb
|
143
|
-
- spec/lib/parser_spec.rb
|
155
|
+
- spec/lib/css_spriter_image_spec.rb
|
144
156
|
- spec/lib/sprite_spec.rb
|
145
157
|
- spec/mtime_tracking_spec.rb
|
146
158
|
- spec/spec_helper.rb
|
147
|
-
- examples/filter_util.rb
|
148
|
-
- examples/sprites/server.rb
|
data/.gitignore
DELETED
data/bin/png_info
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require File.join( File.dirname( __FILE__ ), '..', 'lib', 'css-spriter' )
|
3
|
-
|
4
|
-
module PNG
|
5
|
-
class Parser
|
6
|
-
def go!( file )
|
7
|
-
check_header( file )
|
8
|
-
|
9
|
-
while(! file.eof?) do
|
10
|
-
parse_chunk(file)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
def check_header( file )
|
16
|
-
header = file.read(8)
|
17
|
-
raise "Invalid PNG file header" unless ( header == FileHeader.new.encode)
|
18
|
-
end
|
19
|
-
|
20
|
-
def parse_chunk(f)
|
21
|
-
len = f.read(4).unpack("N")
|
22
|
-
type = f.read(4)
|
23
|
-
data = f.read(len[0])
|
24
|
-
crc = f.read(4)
|
25
|
-
handle(type, len, data )
|
26
|
-
end
|
27
|
-
|
28
|
-
def handle( type, len, data )
|
29
|
-
case type
|
30
|
-
when "IHDR"
|
31
|
-
attrs = data.unpack("N2C5")
|
32
|
-
puts "PNG width: #{attrs[0]}"
|
33
|
-
puts "PNG height: #{attrs[1]}"
|
34
|
-
puts "PNG depth: #{attrs[2]}"
|
35
|
-
puts "PNG color type: #{attrs[3]}"
|
36
|
-
puts "PNG compression method: #{attrs[4]}"
|
37
|
-
puts "PNG filter method: #{attrs[5]}"
|
38
|
-
puts "PNG interlace method: #{attrs[6]}"
|
39
|
-
end
|
40
|
-
|
41
|
-
puts "PNG block #{type}"
|
42
|
-
puts "length: #{len}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
class Info
|
48
|
-
def self.open( file_name )
|
49
|
-
@parser = Parser.new
|
50
|
-
|
51
|
-
name = File.basename( file_name, ".png" )
|
52
|
-
|
53
|
-
File.open(file_name, "r") do |f|
|
54
|
-
@parser.go!( f )
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
PNG::Info.open( ARGV[0] )
|
data/examples/filter_util.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# horrible place for this. just a sanity check for filtering
|
2
|
-
|
3
|
-
require File.join( File.dirname( __FILE__ ), '..', 'lib', 'css-spriter' )
|
4
|
-
|
5
|
-
image = PNG::Image.open( "sprites/many_sized_cats/darth_cat.png")
|
6
|
-
|
7
|
-
5.times do |i|
|
8
|
-
puts i
|
9
|
-
image.write("bob-filter-#{i}.png", :filter_type => i)
|
10
|
-
end
|
11
|
-
|
12
|
-
5.times do |i|
|
13
|
-
filename = "bob-filter-#{i}.png"
|
14
|
-
puts "filter #{i}: #{File.size( filename )}"
|
15
|
-
File.delete( filename )
|
16
|
-
end
|
17
|
-
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'enumerator'
|
2
|
-
|
3
|
-
module CssSpriter
|
4
|
-
class ImageData
|
5
|
-
RGB_WIDTH = 3
|
6
|
-
RGBA_WIDTH = 4
|
7
|
-
|
8
|
-
def initialize(options = {})
|
9
|
-
@data = (options.delete :data) || []
|
10
|
-
@properties = options
|
11
|
-
end
|
12
|
-
|
13
|
-
def name; @properties[:name] || "default"; end
|
14
|
-
def scanline_width; @properties[:scanline_width]; end
|
15
|
-
def width; scanline_width / pixel_width; end
|
16
|
-
def pixel_width; @properties[:pixel_width]; end
|
17
|
-
|
18
|
-
# need better checks, because currently compatible is
|
19
|
-
# similar color type, or depth.. maybe it doesn't matter...
|
20
|
-
def compatible?(image)
|
21
|
-
self.pixel_width == image.pixel_width
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_s
|
25
|
-
"#{name} pixel width: #{pixel_width}"
|
26
|
-
end
|
27
|
-
|
28
|
-
def last_scanline(idx)
|
29
|
-
last_row_index = idx - 1
|
30
|
-
(last_row_index < 0 ? [] : @data[last_row_index])
|
31
|
-
end
|
32
|
-
|
33
|
-
def merge_left( other )
|
34
|
-
merged = ImageData.new(@properties.merge(:scanline_width => self.scanline_width + other.scanline_width,
|
35
|
-
:name => "#{self.name}_#{other.name}"))
|
36
|
-
other.each_with_index do |row, idx|
|
37
|
-
merged[idx] = row + self[idx]
|
38
|
-
end
|
39
|
-
merged
|
40
|
-
end
|
41
|
-
|
42
|
-
def fill_to_height( desired_height )
|
43
|
-
return self if desired_height == height
|
44
|
-
|
45
|
-
img = ImageData.new(@properties.merge(:data => @data.clone))
|
46
|
-
empty_row = [0] * ( scanline_width )
|
47
|
-
|
48
|
-
( desired_height - height ).times do
|
49
|
-
img << empty_row
|
50
|
-
end
|
51
|
-
img
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_rgba( alpha_value=255 )
|
55
|
-
# test that conversion updates pixel width, scanline width
|
56
|
-
|
57
|
-
return self if pixel_width == RGBA_WIDTH
|
58
|
-
|
59
|
-
# so ruby 1.9 has different ideas then 1.8 on how Enumerable should work
|
60
|
-
# 1.9 returns Enumerable object if no block given
|
61
|
-
# 1.8 complains if no block, unless using enum_x methods
|
62
|
-
slice_method = (RUBY_VERSION.include?( "1.9" )) ? :each_slice : :enum_slice
|
63
|
-
|
64
|
-
rgba_data = @data.map do |row|
|
65
|
-
pixels = row.send( slice_method, RGB_WIDTH )
|
66
|
-
pixels.inject([]){|result, pixel| result + pixel + [alpha_value] }
|
67
|
-
end
|
68
|
-
|
69
|
-
ImageData.new( :data => rgba_data,
|
70
|
-
:pixel_width => 4,
|
71
|
-
:scanline_width => (@properties[:scanline_width] / RGB_WIDTH) * RGBA_WIDTH,
|
72
|
-
:name => name)
|
73
|
-
end
|
74
|
-
|
75
|
-
def [](row)
|
76
|
-
@data[row]
|
77
|
-
end
|
78
|
-
|
79
|
-
def []=(idx, row_data)
|
80
|
-
@data[idx] = row_data
|
81
|
-
end
|
82
|
-
|
83
|
-
def scanline(row)
|
84
|
-
self[row]
|
85
|
-
end
|
86
|
-
|
87
|
-
def empty?
|
88
|
-
@data.empty?
|
89
|
-
end
|
90
|
-
|
91
|
-
def height
|
92
|
-
size
|
93
|
-
end
|
94
|
-
|
95
|
-
def size
|
96
|
-
@data.size
|
97
|
-
end
|
98
|
-
|
99
|
-
def last
|
100
|
-
@data.last
|
101
|
-
end
|
102
|
-
|
103
|
-
def <<(row)
|
104
|
-
@data << row
|
105
|
-
self
|
106
|
-
end
|
107
|
-
|
108
|
-
def each(&block)
|
109
|
-
@data.each &block
|
110
|
-
end
|
111
|
-
|
112
|
-
def each_with_index(&block)
|
113
|
-
@data.each_with_index(&block)
|
114
|
-
end
|
115
|
-
|
116
|
-
def flatten!
|
117
|
-
@data.flatten!
|
118
|
-
end
|
119
|
-
|
120
|
-
def pack(*args)
|
121
|
-
@data.pack(*args)
|
122
|
-
end
|
123
|
-
|
124
|
-
def == (other)
|
125
|
-
@data == other
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module PNG
|
2
|
-
class Chunk
|
3
|
-
def chunk_name
|
4
|
-
raise "looks like you havn't subclassed and defined a chunk_name"
|
5
|
-
end
|
6
|
-
|
7
|
-
def to_chunk
|
8
|
-
to_check = chunk_name + encode
|
9
|
-
[encode.length].pack("N") + to_check + [Zlib.crc32(to_check)].pack("N")
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
module PNG
|
2
|
-
class Filters
|
3
|
-
class << self
|
4
|
-
def fetch_pixel(idx, row)
|
5
|
-
idx < 0 ? 0 : row[idx] || 0
|
6
|
-
end
|
7
|
-
|
8
|
-
#filter methods are inlined here for performance
|
9
|
-
def decode( filter_type, value, index, row, last_row, record_width )
|
10
|
-
case filter_type
|
11
|
-
when 0
|
12
|
-
#no filter
|
13
|
-
value
|
14
|
-
when 1
|
15
|
-
#left
|
16
|
-
(value + fetch_pixel(index - record_width, row)) % 256
|
17
|
-
when 2
|
18
|
-
#left
|
19
|
-
(value + fetch_pixel(index, last_row)) % 256
|
20
|
-
when 3
|
21
|
-
#avg
|
22
|
-
(value + ( (fetch_pixel(index - record_width, row) + fetch_pixel(index, last_row)) / 2 ).floor) % 256
|
23
|
-
when 4
|
24
|
-
#paeth
|
25
|
-
left = fetch_pixel(index - record_width, row)
|
26
|
-
above = fetch_pixel(index, last_row)
|
27
|
-
upper_left = fetch_pixel(index - record_width, last_row)
|
28
|
-
|
29
|
-
pr = paeth_predictor( left, above, upper_left )
|
30
|
-
|
31
|
-
(value + pr) % 256
|
32
|
-
else
|
33
|
-
raise "Invalid filter type (#{filter_type})"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
def encode( filter_type, value, index, row, last_row, record_width )
|
37
|
-
case filter_type
|
38
|
-
when 0
|
39
|
-
value
|
40
|
-
when 1
|
41
|
-
#left
|
42
|
-
(value - fetch_pixel(index - record_width, row)) % 256
|
43
|
-
when 2
|
44
|
-
#up
|
45
|
-
(value - fetch_pixel(index, last_row)) % 256
|
46
|
-
when 3
|
47
|
-
#avg
|
48
|
-
(value - ( (fetch_pixel(index - record_width, row) + fetch_pixel(index, last_row)) / 2 ).floor) % 256
|
49
|
-
when 4
|
50
|
-
#paeth
|
51
|
-
left = fetch_pixel(index - record_width, row)
|
52
|
-
above = fetch_pixel(index, last_row)
|
53
|
-
upper_left = fetch_pixel(index - record_width, last_row)
|
54
|
-
|
55
|
-
pr = paeth_predictor( left, above, upper_left )
|
56
|
-
(value - pr) % 256
|
57
|
-
else
|
58
|
-
raise "Filter type (#{filter_type}) is not supported"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def paeth_predictor( left, above, upper_left )
|
65
|
-
p = left + above - upper_left
|
66
|
-
pa = (p - left).abs
|
67
|
-
pb = (p - above).abs
|
68
|
-
pc = (p - upper_left).abs
|
69
|
-
|
70
|
-
pr = upper_left
|
71
|
-
if ( pa <= pb and pa <= pc)
|
72
|
-
pr = left
|
73
|
-
elsif (pb <= pc)
|
74
|
-
pr = above
|
75
|
-
end
|
76
|
-
pr
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|