css-spriter 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +81 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/bin/css-spriter +45 -0
- data/bin/png_info +61 -0
- data/examples/filter_util.rb +17 -0
- data/examples/sprites/.mtimes +12 -0
- data/examples/sprites/README +5 -0
- data/examples/sprites/fragment.css +0 -0
- data/examples/sprites/index.html +26 -0
- data/examples/sprites/many_sized_cats/.mtimes +3 -0
- data/examples/sprites/many_sized_cats/cat-on-keyboard.png +0 -0
- data/examples/sprites/many_sized_cats/darth_cat.png +0 -0
- data/examples/sprites/many_sized_cats/fragment.css +21 -0
- data/examples/sprites/many_sized_cats/music-keyboard-cat.png +0 -0
- data/examples/sprites/many_sized_cats/sprite.css +21 -0
- data/examples/sprites/many_sized_cats/sprite.png +0 -0
- data/examples/sprites/server.rb +10 -0
- data/examples/sprites/sprite.css +49 -0
- data/examples/sprites/words/.mtimes +4 -0
- data/examples/sprites/words/fragment.css +28 -0
- data/examples/sprites/words/latitude.png +0 -0
- data/examples/sprites/words/of.png +0 -0
- data/examples/sprites/words/set.png +0 -0
- data/examples/sprites/words/specified.png +0 -0
- data/examples/sprites/words/sprite.css +28 -0
- data/examples/sprites/words/sprite.png +0 -0
- data/init.rb +1 -0
- data/lib/css-spriter.rb +16 -0
- data/lib/css-spriter/directory_processor.rb +94 -0
- data/lib/css-spriter/image_data.rb +128 -0
- data/lib/css-spriter/mtime_tracker.rb +79 -0
- data/lib/css-spriter/png/chunk.rb +12 -0
- data/lib/css-spriter/png/file_header.rb +7 -0
- data/lib/css-spriter/png/filters.rb +80 -0
- data/lib/css-spriter/png/idat.rb +26 -0
- data/lib/css-spriter/png/iend.rb +9 -0
- data/lib/css-spriter/png/ihdr.rb +34 -0
- data/lib/css-spriter/png/image.rb +153 -0
- data/lib/css-spriter/png/parser.rb +54 -0
- data/lib/css-spriter/processor.rb +28 -0
- data/lib/css-spriter/sprite.rb +39 -0
- data/lib/css-spriter/stylesheet_builder.rb +22 -0
- data/spec/builders/image_builder.rb +23 -0
- data/spec/css_fragments/deep/style/fragment.css +1 -0
- data/spec/css_fragments/some/fragment.css +1 -0
- data/spec/expected_output/merge_right_test.png +0 -0
- data/spec/expected_output/write_test.png +0 -0
- data/spec/image_data_spec.rb +63 -0
- data/spec/images/lightening.png +0 -0
- data/spec/integration_spec.rb +151 -0
- data/spec/lib/file_header_spec.rb +10 -0
- data/spec/lib/idat_spec.rb +31 -0
- data/spec/lib/ihdr_spec.rb +43 -0
- data/spec/lib/image_spec.rb +42 -0
- data/spec/lib/parser_spec.rb +12 -0
- data/spec/lib/sprite_spec.rb +39 -0
- data/spec/mtime_tracking_spec.rb +69 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/sprite_dirs/words/latitude.png +0 -0
- data/spec/sprite_dirs/words/of.png +0 -0
- data/spec/sprite_dirs/words/set.png +0 -0
- data/spec/sprite_dirs/words/specified.png +0 -0
- data/spec/tmp/merge_right_test.png +0 -0
- data/spec/tmp/write_test.png +0 -0
- data/tasks/spriter_tasks.rake +25 -0
- metadata +148 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Colin Harris & Tyler Jennings
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= CSS Spriter, a sprite generator
|
2
|
+
|
3
|
+
[ PNG, PNG, PNG ] (°_°)
|
4
|
+
[ PNG, PNG, PNG ] (° )
|
5
|
+
[ PNG, PNG, PNG ] )°)
|
6
|
+
[ PNG, PNG, )°)
|
7
|
+
[ PNG, )°)
|
8
|
+
[ )°)
|
9
|
+
|
10
|
+
\(°_°)/ -> SPRITES!!!
|
11
|
+
|
12
|
+
== Description
|
13
|
+
|
14
|
+
It takes your PNG's, chews them up and spits out sprites!
|
15
|
+
|
16
|
+
point bin/css-spriter at a directory, and watch it sprite away!
|
17
|
+
|
18
|
+
== Installation - standalone
|
19
|
+
|
20
|
+
sudo gem install css-spriter
|
21
|
+
|
22
|
+
=== Usage - standalone
|
23
|
+
|
24
|
+
css-spriter <directory>
|
25
|
+
|
26
|
+
If you point the sprite command at a directory tree by default it will construct sprites for each of the sub directories and generate a single css to access all of the sprites which is placed in the root of the directory tree
|
27
|
+
|
28
|
+
For a full list of options:
|
29
|
+
|
30
|
+
css-spriter -h
|
31
|
+
|
32
|
+
== Installation - Rails plugin
|
33
|
+
|
34
|
+
script/plugin install git://github.com/aberant/css-spriter.git
|
35
|
+
|
36
|
+
=== Usage - Rails plugin
|
37
|
+
|
38
|
+
Spittle assumes all of your sprites are located in the directory public/images/sprites. This directory should contain sub-directories for each sprite you wish to create. The css class names for an image in a sprite will take the form <directory_name>_<image_name>. Here is an example:
|
39
|
+
|
40
|
+
sprites /
|
41
|
+
cars /
|
42
|
+
ford.png
|
43
|
+
chevy.png
|
44
|
+
planes /
|
45
|
+
boeing.png
|
46
|
+
cesna.png
|
47
|
+
|
48
|
+
Running sprite:generate does all the work. Each sprite directory (cars, planes) will now contain a sprite.png. Spittle will also generate a sprites.css stylesheet in public/stylesheets/ that you should include in your layout. If you wished to use the ford image from the cars sprite you would give the 'cars_ford' class to the desired element in the view. That's it!
|
49
|
+
|
50
|
+
Check out examples/sprites if you want to see what spriter can do without doing any work.
|
51
|
+
|
52
|
+
== Limitations
|
53
|
+
|
54
|
+
- does not support color profiles (can cause a slight change in color from the source image)
|
55
|
+
- does not support reading interlaced PNGs.
|
56
|
+
|
57
|
+
== Features
|
58
|
+
|
59
|
+
- automatically generates sprites from a set of PNG images
|
60
|
+
- automatically generates css classes to access images within the sprite
|
61
|
+
- customizable css templates
|
62
|
+
- Rails plugin & rake tasks (sprite:generate & sprite:cleanup)
|
63
|
+
- Supports varying dimensions in source images
|
64
|
+
- Does not regenerate sprites that have not changed
|
65
|
+
- Supports all PNG filter types to improve image compression
|
66
|
+
- supports mixing RGB and RGBA color types
|
67
|
+
|
68
|
+
== Roadmap - by priority
|
69
|
+
|
70
|
+
- Reading interlaced images
|
71
|
+
- allow a global css template override
|
72
|
+
- allow per-sprite and global configuration
|
73
|
+
|
74
|
+
== Authors
|
75
|
+
|
76
|
+
- aberant - Colin Harris
|
77
|
+
- tjennings - Tyler Jennings
|
78
|
+
|
79
|
+
== Credits
|
80
|
+
|
81
|
+
- thanks to mattpuchlerz[http://github.com/mattpuchlerz] for the socially acceptable project name
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "css-spriter"
|
8
|
+
gem.summary = %Q{pure ruby PNG spriting library}
|
9
|
+
gem.description = %Q{Css Spriter is a pure ruby PNG spriting library. It can be used standalone or as a Rails plugin, see the readme for details.}
|
10
|
+
gem.email = ["qzzzq1@gmail.com", "tyler.jennings@gmail.com"]
|
11
|
+
gem.homepage = "http://github.com/aberant/css-spriter"
|
12
|
+
gem.authors = ["aberant", "tjennings"]
|
13
|
+
gem.add_development_dependency "rspec" #, ">= 1.2.9"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'spec/rake/spectask'
|
22
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
25
|
+
end
|
26
|
+
|
27
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
28
|
+
spec.libs << 'lib' << 'spec'
|
29
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
30
|
+
spec.rcov = true
|
31
|
+
end
|
32
|
+
|
33
|
+
task :spec #=> :check_dependencies
|
34
|
+
|
35
|
+
task :default => :spec
|
36
|
+
|
37
|
+
require 'rake/rdoctask'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "spittle #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.9.2
|
data/bin/css-spriter
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require File.dirname(__FILE__) + "/../lib/css-spriter.rb"
|
5
|
+
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
opts = OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: css-spriter [options] directory"
|
10
|
+
|
11
|
+
opts.on("-c", "--cleanup", "Remove all generated files") do |file|
|
12
|
+
options[:cleanup] = true
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on("-o", "--out FILE", "Write css output to an alternate location") do |file|
|
16
|
+
options[:css_file] = file
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on("-p", "--path-prefix PREFIX", "prepend sprite paths with the given string") do |prefix|
|
20
|
+
options[:path_prefix] = prefix
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on_tail("-h", "--help", "Prints this message") do
|
24
|
+
puts opts
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.parse!(ARGV)
|
29
|
+
end
|
30
|
+
|
31
|
+
dir = ARGV[0]
|
32
|
+
|
33
|
+
unless dir
|
34
|
+
puts opts.help
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
|
38
|
+
options[:source] = dir
|
39
|
+
processor = CssSpriter::Processor.new(options)
|
40
|
+
|
41
|
+
if options[:cleanup]
|
42
|
+
processor.cleanup
|
43
|
+
else
|
44
|
+
processor.write
|
45
|
+
end
|
data/bin/png_info
ADDED
@@ -0,0 +1,61 @@
|
|
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] )
|
@@ -0,0 +1,17 @@
|
|
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
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
./many_sized_cats/music-keyboard-cat.png 1258479430
|
2
|
+
./words/set.png 1258120615
|
3
|
+
./many_sized_cats/cat-on-keyboard.png 1258479384
|
4
|
+
./many_sized_cats 1261105635
|
5
|
+
./words/latitude.png 1258120615
|
6
|
+
./words/specified.png 1258120615
|
7
|
+
./server.rb 1258120560
|
8
|
+
./many_sized_cats/darth_cat.png 1258678472
|
9
|
+
./words/of.png 1258120615
|
10
|
+
./README 1258164457
|
11
|
+
./words 1261105635
|
12
|
+
./index.html 1261104700
|
@@ -0,0 +1,5 @@
|
|
1
|
+
The sprites here are pre generated. If you want to see it work yourself delete the the two sprite.png files and all the *.css. Then simply run '../bin/spittle' and it should regenreate the sprites.
|
2
|
+
|
3
|
+
The server script will start a WEBrick server on port 3000 and serve from this directory. If everything worked out you should see the two sprite samples displayed in index.html.
|
4
|
+
|
5
|
+
.
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>A simple sprite test</title>
|
4
|
+
<link href="/sprite.css" type="text/css" rel="stylesheet" />
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<style>
|
8
|
+
.float_left {float:left}
|
9
|
+
.menu {height: 100px}
|
10
|
+
.clear {clear:both}
|
11
|
+
</style>
|
12
|
+
<div>
|
13
|
+
Hello. See css-spriter run:
|
14
|
+
<div class="words_of">of</div>
|
15
|
+
<div class="words_latitude">latitude</div>
|
16
|
+
<div class="words_set">set</div>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
OMG Cats!!!! (of varying sizes, in one sprite)
|
20
|
+
<div>
|
21
|
+
<div class="many_sized_cats_cat-on-keyboard"></div>
|
22
|
+
<div class="many_sized_cats_darth_cat"></div>
|
23
|
+
<div class="many_sized_cats_music-keyboard-cat"></div>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
Binary file
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
.many_sized_cats_cat-on-keyboard {
|
2
|
+
background: transparent url(/many_sized_cats/sprite.png) 0px 0px no-repeat;
|
3
|
+
width:64;
|
4
|
+
height:48;
|
5
|
+
text-indent:-5000px;
|
6
|
+
}
|
7
|
+
|
8
|
+
.many_sized_cats_music-keyboard-cat {
|
9
|
+
background: transparent url(/many_sized_cats/sprite.png) -304px 0px no-repeat;
|
10
|
+
width:225;
|
11
|
+
height:166;
|
12
|
+
text-indent:-5000px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.many_sized_cats_darth_cat {
|
16
|
+
background: transparent url(/many_sized_cats/sprite.png) -64px 0px no-repeat;
|
17
|
+
width:240;
|
18
|
+
height:320;
|
19
|
+
text-indent:-5000px;
|
20
|
+
}
|
21
|
+
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
.._cat-on-keyboard {
|
2
|
+
background: transparent url(/spritepng) 0px 0px no-repeat;
|
3
|
+
width:64;
|
4
|
+
height:48;
|
5
|
+
text-indent:-5000px;
|
6
|
+
}
|
7
|
+
|
8
|
+
.._music-keyboard-cat {
|
9
|
+
background: transparent url(/spritepng) -304px 0px no-repeat;
|
10
|
+
width:225;
|
11
|
+
height:166;
|
12
|
+
text-indent:-5000px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.._darth_cat {
|
16
|
+
background: transparent url(/spritepng) -64px 0px no-repeat;
|
17
|
+
width:240;
|
18
|
+
height:320;
|
19
|
+
text-indent:-5000px;
|
20
|
+
}
|
21
|
+
|
Binary file
|
@@ -0,0 +1,49 @@
|
|
1
|
+
.many_sized_cats_cat-on-keyboard {
|
2
|
+
background: transparent url(/many_sized_cats/sprite.png) 0px 0px no-repeat;
|
3
|
+
width:64;
|
4
|
+
height:48;
|
5
|
+
text-indent:-5000px;
|
6
|
+
}
|
7
|
+
|
8
|
+
.many_sized_cats_music-keyboard-cat {
|
9
|
+
background: transparent url(/many_sized_cats/sprite.png) -304px 0px no-repeat;
|
10
|
+
width:225;
|
11
|
+
height:166;
|
12
|
+
text-indent:-5000px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.many_sized_cats_darth_cat {
|
16
|
+
background: transparent url(/many_sized_cats/sprite.png) -64px 0px no-repeat;
|
17
|
+
width:240;
|
18
|
+
height:320;
|
19
|
+
text-indent:-5000px;
|
20
|
+
}
|
21
|
+
|
22
|
+
.words_latitude {
|
23
|
+
background: transparent url(/words/sprite.png) 0px 0px no-repeat;
|
24
|
+
width:66;
|
25
|
+
height:21;
|
26
|
+
text-indent:-5000px;
|
27
|
+
}
|
28
|
+
|
29
|
+
.words_of {
|
30
|
+
background: transparent url(/words/sprite.png) -66px 0px no-repeat;
|
31
|
+
width:19;
|
32
|
+
height:21;
|
33
|
+
text-indent:-5000px;
|
34
|
+
}
|
35
|
+
|
36
|
+
.words_set {
|
37
|
+
background: transparent url(/words/sprite.png) -85px 0px no-repeat;
|
38
|
+
width:26;
|
39
|
+
height:21;
|
40
|
+
text-indent:-5000px;
|
41
|
+
}
|
42
|
+
|
43
|
+
.words_specified {
|
44
|
+
background: transparent url(/words/sprite.png) -111px 0px no-repeat;
|
45
|
+
width:70;
|
46
|
+
height:21;
|
47
|
+
text-indent:-5000px;
|
48
|
+
}
|
49
|
+
|