ase 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +1 -0
- data/ase.gemspec +26 -0
- data/examples/control.php +114 -0
- data/examples/simple.rb +20 -0
- data/lib/ase.rb +39 -0
- data/lib/ase/color.rb +53 -0
- data/lib/ase/file.rb +71 -0
- data/lib/ase/palette.rb +37 -0
- data/lib/ase/reader.rb +75 -0
- data/lib/ase/version.rb +3 -0
- data/lib/ase/writer.rb +62 -0
- data/spec/ase_spec.rb +94 -0
- data/spec/file_spec.rb +91 -0
- data/spec/files/control.ase +0 -0
- data/spec/spec_helper.rb +16 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8f02ed546d29cb98fc1e48ec4327a551d544fad
|
4
|
+
data.tar.gz: 3e8545e46be2158f2040eb42dda2368402cf04dd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6aa291a962d1d474d722d184bf802327e97590307b3b0e01b97679137c5fe98f60725f2b4731ef54ed41531930b403abeccbd421a203e944f90a01d12cb2dea0
|
7
|
+
data.tar.gz: 0acd8002bd0f69550c86d7627de4bfb5921032b56419244bf01def81ca2a308a37e4c6d141bea26e922f93b6ba30afb8c574c247d4ca16a52ade887bd181803c
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ryan LeFevre
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# ASE.rb
|
2
|
+
|
3
|
+
A general purpose library for reading and writing Adobe Swatch Exchange files in Ruby. ASE files can be used across the entire Adobe Creative Suite (Photoshop, Illustrator, etc).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'ase'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install ase
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
**Writing**
|
22
|
+
|
23
|
+
``` ruby
|
24
|
+
doc = ASE.new
|
25
|
+
|
26
|
+
palette = ASE::Palette.new('My Colors')
|
27
|
+
palette.add 'Black', ASE::Color.new(0, 0, 0)
|
28
|
+
palette.add 'Red', ASE::Color.from_hex('#ff0000')
|
29
|
+
|
30
|
+
doc << palette
|
31
|
+
doc.to_file('path/to/file.ase')
|
32
|
+
```
|
33
|
+
|
34
|
+
**Reading**
|
35
|
+
|
36
|
+
``` ruby
|
37
|
+
doc = ASE.from_file('path/to/file.ase')
|
38
|
+
|
39
|
+
puts doc['My Colors']['Red'].to_rgb
|
40
|
+
#=> [255, 0, 0]
|
41
|
+
|
42
|
+
puts doc['My Colors'].size
|
43
|
+
#=> 2
|
44
|
+
```
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
1. Fork it
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
50
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
52
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/ase.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ase/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ase"
|
8
|
+
spec.version = ASE::VERSION
|
9
|
+
spec.authors = ["Ryan LeFevre"]
|
10
|
+
spec.email = ["meltingice8917@gmail.com"]
|
11
|
+
spec.description = %q{Reader/writer for Adobe Swatch Exchange files}
|
12
|
+
spec.summary = %q{Reader/writer for Adobe Swatch Exchange files. Can be used across the entire Adobe Creative Suite.}
|
13
|
+
spec.homepage = "http://cosmos.layervault.com/aserb.html"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "guard"
|
24
|
+
spec.add_development_dependency "guard-rspec"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Make an Adobe Swatch Exchange file
|
4
|
+
*
|
5
|
+
* @param array
|
6
|
+
* @return string
|
7
|
+
* @see http://www.colourlovers.com/web/blog/2007/11/08/color-palettes-in-adobe-swatch-exchange-ase
|
8
|
+
* @author Chris Williams - http://www.colourlovers.com
|
9
|
+
* @version 2.0
|
10
|
+
* This script uses the Multibyte String extension: http://www.php.net/manual/en/book.mbstring.php
|
11
|
+
* MIT License
|
12
|
+
* Copyright (c) 2011 Chris Williams - http://www.colourlovers.com
|
13
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
14
|
+
* of this software and associated documentation files (the "Software"), to deal
|
15
|
+
* in the Software without restriction, including without limitation the rights
|
16
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
17
|
+
* copies of the Software, and to permit persons to whom the Software is
|
18
|
+
* furnished to do so, subject to the following conditions:
|
19
|
+
* The above copyright notice and this permission notice shall be included in
|
20
|
+
* all copies or substantial portions of the Software.
|
21
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
22
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
23
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
24
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
25
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
26
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
27
|
+
* THE SOFTWARE.
|
28
|
+
*/
|
29
|
+
function mkASE($palettes) {
|
30
|
+
$internal_encoding = mb_internal_encoding();
|
31
|
+
mb_internal_encoding("UTF-8");
|
32
|
+
|
33
|
+
ob_start();
|
34
|
+
|
35
|
+
$totalColors = $numPalettes = 0;
|
36
|
+
|
37
|
+
foreach ($palettes as $palette) {
|
38
|
+
$totalColors += count($palette["colors"]);
|
39
|
+
++$numPalettes;
|
40
|
+
}
|
41
|
+
|
42
|
+
echo "ASEF"; # File signature
|
43
|
+
echo pack("n*",1,0); # Version
|
44
|
+
echo pack("N",$totalColors + ($numPalettes * 2)); # Total number of blocks
|
45
|
+
|
46
|
+
foreach ($palettes as $palette) {
|
47
|
+
echo pack("n",0xC001); # Group start
|
48
|
+
|
49
|
+
# Length of this block - see below
|
50
|
+
|
51
|
+
$title = (mb_convert_encoding($palette["title"],"UTF-16BE","UTF-8") . pack("n",0));
|
52
|
+
$buffer = pack("n",(strlen($title) / 2)); # Length of the group title
|
53
|
+
$buffer .= $title; # Group title
|
54
|
+
|
55
|
+
echo pack("N",strlen($buffer)); # Length of this block
|
56
|
+
echo $buffer;
|
57
|
+
|
58
|
+
foreach ($palette["colors"] as $color) {
|
59
|
+
echo pack("n",1); # Color entry
|
60
|
+
|
61
|
+
# Length of this block - see below
|
62
|
+
|
63
|
+
$title = (mb_convert_encoding($color[1],"UTF-16BE","UTF-8") . pack("n",0));
|
64
|
+
$buffer = pack("n",(strlen($title) / 2)); # Length of the title
|
65
|
+
$buffer .= $title; # Title
|
66
|
+
|
67
|
+
# Colors
|
68
|
+
list ($r,$g,$b) = array_map("intval",sscanf($color[0],"%2x%2x%2x"));
|
69
|
+
$r /= 255;
|
70
|
+
$g /= 255;
|
71
|
+
$b /= 255;
|
72
|
+
|
73
|
+
$buffer .= "RGB ";
|
74
|
+
$buffer .= strrev(pack("f",$r));
|
75
|
+
$buffer .= strrev(pack("f",$g));
|
76
|
+
$buffer .= strrev(pack("f",$b));
|
77
|
+
$buffer .= pack("n",0); # Color type - 0x00 "Global"
|
78
|
+
|
79
|
+
echo pack("N",strlen($buffer)); # Length of this block
|
80
|
+
echo $buffer;
|
81
|
+
}
|
82
|
+
echo pack("n",0xC002); # Group end
|
83
|
+
|
84
|
+
echo pack("N",0); # Length of "Group end" block, which is 0
|
85
|
+
}
|
86
|
+
|
87
|
+
$return = ob_get_contents();
|
88
|
+
ob_end_clean();
|
89
|
+
|
90
|
+
mb_internal_encoding($internal_encoding);
|
91
|
+
|
92
|
+
return $return;
|
93
|
+
}
|
94
|
+
|
95
|
+
/*
|
96
|
+
Colors from the Palettes:
|
97
|
+
Vintage Modern http://www.colourlovers.com/palette/110225/Vintage_Modern
|
98
|
+
Thought Provoking http://www.colourlovers.com/palette/694737/Thought_Provoking
|
99
|
+
|
100
|
+
Licensed under Creative Commons: http://creativecommons.org/licenses/by-nc-sa/3.0/
|
101
|
+
*/
|
102
|
+
|
103
|
+
$palettes = array (
|
104
|
+
array (
|
105
|
+
"title" => "Simple",
|
106
|
+
"colors" => array (
|
107
|
+
array ("FFFFFF","White"),
|
108
|
+
array ("000000","Black"),
|
109
|
+
),
|
110
|
+
),
|
111
|
+
);
|
112
|
+
|
113
|
+
$ase = mkASE($palettes);
|
114
|
+
file_put_contents('./control.ase', $ase);
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require './lib/ase'
|
3
|
+
|
4
|
+
doc = ASE.new
|
5
|
+
|
6
|
+
palette = ASE::Palette.new("Simple")
|
7
|
+
palette.add 'White', ASE::Color.from_hex('#ffffff')
|
8
|
+
palette.add 'Black', ASE::Color.from_hex('#000000')
|
9
|
+
|
10
|
+
doc << palette
|
11
|
+
|
12
|
+
puts "\nTO FILE"
|
13
|
+
pp doc
|
14
|
+
|
15
|
+
doc.to_file './output.ase'
|
16
|
+
|
17
|
+
puts "\nFROM FILE"
|
18
|
+
doc2 = ASE.from_file './output.ase'
|
19
|
+
|
20
|
+
pp doc2
|
data/lib/ase.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
dir_root = File.dirname(File.absolute_path(__FILE__))
|
2
|
+
|
3
|
+
require dir_root + "/ase/version"
|
4
|
+
require dir_root + "/ase/color"
|
5
|
+
require dir_root + "/ase/file"
|
6
|
+
require dir_root + "/ase/palette"
|
7
|
+
require dir_root + "/ase/reader"
|
8
|
+
require dir_root + "/ase/writer"
|
9
|
+
|
10
|
+
|
11
|
+
class ASE
|
12
|
+
include Reader
|
13
|
+
include Writer
|
14
|
+
|
15
|
+
attr_accessor :palettes
|
16
|
+
|
17
|
+
def initialize(file=nil)
|
18
|
+
@file = file
|
19
|
+
@palettes = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_palette(palette)
|
23
|
+
raise "Can only pass an ASE::Palette" unless palette.is_a?(ASE::Palette)
|
24
|
+
@palettes[palette.name] = palette
|
25
|
+
end
|
26
|
+
alias :<< :add_palette
|
27
|
+
|
28
|
+
def [](name)
|
29
|
+
@palettes[name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(method, *args, &block)
|
33
|
+
if @palettes.has_key?(method.to_s)
|
34
|
+
return @palettes[method.to_s]
|
35
|
+
end
|
36
|
+
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
data/lib/ase/color.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Nice little wrapper that lets us easily perform some functions on a
|
2
|
+
# given color.
|
3
|
+
class ASE
|
4
|
+
class Color
|
5
|
+
class << self
|
6
|
+
def from_rgba(*args)
|
7
|
+
args = args.first if args.length == 1
|
8
|
+
self.new *args
|
9
|
+
end
|
10
|
+
alias :from_rgb :from_rgba
|
11
|
+
|
12
|
+
def from_hex(hex)
|
13
|
+
self.new *hex.gsub('#', '').scan(/../).map { |c| c.to_i(16) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :r, :g, :b, :a
|
18
|
+
|
19
|
+
# We always internally store the color as RGBA.
|
20
|
+
def initialize(r, g, b, a = 255)
|
21
|
+
@r = r
|
22
|
+
@g = g
|
23
|
+
@b = b
|
24
|
+
@a = a
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_rgba
|
28
|
+
[@r, @g, @b, @a]
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_rgb
|
32
|
+
[@r, @g, @b]
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_css
|
36
|
+
"rgba(#{r}, #{g}, #{b}, #{a})"
|
37
|
+
end
|
38
|
+
|
39
|
+
def [](i)
|
40
|
+
[@r, @g, @b, @a][i]
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_hex(incl_hash=true, incl_alpha=false)
|
44
|
+
hex = incl_hash ? '#' : ''
|
45
|
+
colors = [@r, @g, @b]
|
46
|
+
colors << @a if incl_alpha
|
47
|
+
|
48
|
+
colors.each { |c| hex << c.to_s(16) }
|
49
|
+
return hex
|
50
|
+
end
|
51
|
+
alias :to_s :to_hex
|
52
|
+
end
|
53
|
+
end
|
data/lib/ase/file.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
class ASE
|
2
|
+
class File < ::File
|
3
|
+
FORMATS = {
|
4
|
+
ulonglong: {
|
5
|
+
length: 8,
|
6
|
+
code: 'Q>'
|
7
|
+
},
|
8
|
+
longlong: {
|
9
|
+
length: 8,
|
10
|
+
code: 'q>'
|
11
|
+
},
|
12
|
+
double: {
|
13
|
+
length: 8,
|
14
|
+
code: 'G'
|
15
|
+
},
|
16
|
+
float: {
|
17
|
+
length: 4,
|
18
|
+
code: 'F'
|
19
|
+
},
|
20
|
+
uint: {
|
21
|
+
length: 4,
|
22
|
+
code: 'L>'
|
23
|
+
},
|
24
|
+
int: {
|
25
|
+
length: 4,
|
26
|
+
code: 'l>'
|
27
|
+
},
|
28
|
+
ushort: {
|
29
|
+
length: 2,
|
30
|
+
code: 'S>'
|
31
|
+
},
|
32
|
+
short: {
|
33
|
+
length: 2,
|
34
|
+
code: 's>'
|
35
|
+
},
|
36
|
+
ulong: {
|
37
|
+
length: 4,
|
38
|
+
code: 'L>'
|
39
|
+
},
|
40
|
+
long: {
|
41
|
+
length: 4,
|
42
|
+
code: 'l>'
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
FORMATS.each do |format, info|
|
47
|
+
define_method "read_#{format}" do
|
48
|
+
read(info[:length]).unpack(info[:code])[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
define_method "write_#{format}" do |*args|
|
52
|
+
write args.pack(info[:code] + '*')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_string
|
57
|
+
length = read_ushort
|
58
|
+
read(length * 2).encode('UTF-8', 'UTF-16BE').delete("\00")
|
59
|
+
end
|
60
|
+
|
61
|
+
def write_string(string)
|
62
|
+
write_ushort(string.length + 1)
|
63
|
+
write string.encode('UTF-16BE')
|
64
|
+
write_null_byte
|
65
|
+
end
|
66
|
+
|
67
|
+
def write_null_byte
|
68
|
+
write [0].pack('S>')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/ase/palette.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class ASE
|
2
|
+
class Palette
|
3
|
+
attr_accessor :name, :colors
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
@colors = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(name, color)
|
11
|
+
@colors[name] = color
|
12
|
+
end
|
13
|
+
alias :[]= :add
|
14
|
+
alias :add_color :add
|
15
|
+
|
16
|
+
def remove(name)
|
17
|
+
@colors.delete(name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](i)
|
21
|
+
@colors[i]
|
22
|
+
end
|
23
|
+
|
24
|
+
def length
|
25
|
+
@colors.length
|
26
|
+
end
|
27
|
+
alias :size :length
|
28
|
+
|
29
|
+
def method_missing(method, *args, &block)
|
30
|
+
if @colors.has_key?(method.to_s)
|
31
|
+
return @colors[method.to_s]
|
32
|
+
end
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/ase/reader.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
class ASE
|
2
|
+
module Reader
|
3
|
+
def self.included(base)
|
4
|
+
base.send :include, InstanceMethods
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def from_file(file)
|
10
|
+
doc = ASE.new(file)
|
11
|
+
doc.read!
|
12
|
+
|
13
|
+
return doc
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
def from_file(file)
|
19
|
+
@file = file
|
20
|
+
read!
|
21
|
+
end
|
22
|
+
|
23
|
+
def read!
|
24
|
+
raise "Must specify an output file" if @file.nil?
|
25
|
+
@file = File.new(@file, 'rb')
|
26
|
+
|
27
|
+
# Signature and version, who cares?
|
28
|
+
# Okay maybe we should validate this in the future.
|
29
|
+
@file.seek 8, IO::SEEK_CUR
|
30
|
+
|
31
|
+
block_count = @file.read_ulong
|
32
|
+
|
33
|
+
read_palette until @file.eof?
|
34
|
+
|
35
|
+
@file.close
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def read_palette
|
41
|
+
block_start = @file.read_ushort
|
42
|
+
|
43
|
+
title_block_size = @file.read_ulong
|
44
|
+
title = @file.read_string
|
45
|
+
|
46
|
+
palette = Palette.new(title)
|
47
|
+
|
48
|
+
# Read the colors
|
49
|
+
while true
|
50
|
+
color_start = @file.read_ushort
|
51
|
+
break if color_start == 0xC002
|
52
|
+
|
53
|
+
color_size = @file.read_ulong
|
54
|
+
color_name = @file.read_string
|
55
|
+
color_mode = @file.read(4)
|
56
|
+
|
57
|
+
r, g, b = @file.read(12).scan(/.{1,4}/).map do |c|
|
58
|
+
(c.reverse.unpack('F')[0] * 255).to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
palette.add color_name, Color.new(r, g, b)
|
62
|
+
|
63
|
+
# Null byte
|
64
|
+
@file.seek 2, IO::SEEK_CUR
|
65
|
+
end
|
66
|
+
|
67
|
+
# Group end block
|
68
|
+
@file.seek 4, IO::SEEK_CUR
|
69
|
+
|
70
|
+
add_palette palette
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/ase/version.rb
ADDED
data/lib/ase/writer.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
class ASE
|
2
|
+
module Writer
|
3
|
+
def to_file(file)
|
4
|
+
@file = file
|
5
|
+
write!
|
6
|
+
end
|
7
|
+
|
8
|
+
def write!
|
9
|
+
raise "Must specify an output file" if @file.nil?
|
10
|
+
@file = File.new(@file, 'wb')
|
11
|
+
|
12
|
+
palette_count = @palettes.length
|
13
|
+
color_count = @palettes.inject(0) { |sum, p| p.size }
|
14
|
+
|
15
|
+
# Signature
|
16
|
+
@file.write "ASEF"
|
17
|
+
|
18
|
+
# Version
|
19
|
+
@file.write_ushort 1, 0
|
20
|
+
|
21
|
+
# Number of blocks
|
22
|
+
@file.write_ulong(color_count + (palette_count * 2))
|
23
|
+
|
24
|
+
@palettes.each do |palette_name, palette|
|
25
|
+
# Block start
|
26
|
+
@file.write_ushort 0xC001
|
27
|
+
|
28
|
+
# Block length (title is UTF-16 encoded)
|
29
|
+
@file.write_ulong 4 + (palette_name.length * 2)
|
30
|
+
|
31
|
+
# Palette name
|
32
|
+
@file.write_string palette_name
|
33
|
+
|
34
|
+
palette.colors.each do |name, color|
|
35
|
+
# Color start
|
36
|
+
@file.write_ushort 1
|
37
|
+
|
38
|
+
# Block length
|
39
|
+
@file.write_ulong 22 + (name.length * 2)
|
40
|
+
|
41
|
+
# Color name
|
42
|
+
@file.write_string name
|
43
|
+
|
44
|
+
# Color mode
|
45
|
+
@file.write 'RGB '
|
46
|
+
|
47
|
+
# Colors
|
48
|
+
rgb = color.to_rgb.map { |c| c / 255 }
|
49
|
+
rgb.each { |c| @file.write [c].pack('F').reverse }
|
50
|
+
|
51
|
+
# End of colors
|
52
|
+
@file.write_null_byte
|
53
|
+
end
|
54
|
+
|
55
|
+
@file.write_ushort 0xC002 # Group end
|
56
|
+
@file.write_ulong 0 # Group end block
|
57
|
+
end
|
58
|
+
|
59
|
+
@file.close
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/ase_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ASE do
|
4
|
+
before(:each) do
|
5
|
+
@doc = ASE.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "is initialized with defaults" do
|
9
|
+
expect(@doc.palettes).to eq({})
|
10
|
+
expect(@doc.palettes.length).to be 0
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can add palettes" do
|
14
|
+
@doc.add_palette ASE::Palette.new('Test')
|
15
|
+
@doc << ASE::Palette.new('Also Test')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ASE::Palette do
|
19
|
+
it "must have a name" do
|
20
|
+
expect {
|
21
|
+
ASE::Palette.new
|
22
|
+
}.to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is initialized with proper defaults" do
|
26
|
+
palette = ASE::Palette.new('Test')
|
27
|
+
|
28
|
+
expect(palette.name).to eq('Test')
|
29
|
+
expect(palette.colors).to eq({})
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can add and remove colors" do
|
33
|
+
palette = ASE::Palette.new('Test')
|
34
|
+
color = ASE::Color.new(255, 255, 255)
|
35
|
+
|
36
|
+
palette.add 'White', color
|
37
|
+
expect(palette.colors).to eq({
|
38
|
+
'White' => color
|
39
|
+
})
|
40
|
+
|
41
|
+
palette.remove 'White'
|
42
|
+
expect(palette.colors).to eq({})
|
43
|
+
end
|
44
|
+
|
45
|
+
it '#length returns the number of colors' do
|
46
|
+
palette = ASE::Palette.new('Test')
|
47
|
+
palette.add 'White', ASE::Color.new(255, 255, 255)
|
48
|
+
palette.add 'Black', ASE::Color.new(0, 0, 0)
|
49
|
+
|
50
|
+
expect(palette.length).to be 2
|
51
|
+
expect(palette.size).to be 2
|
52
|
+
end
|
53
|
+
|
54
|
+
it '#[] lets you access a specific color' do
|
55
|
+
palette = ASE::Palette.new('Test')
|
56
|
+
color = ASE::Color.new(255, 255, 255)
|
57
|
+
|
58
|
+
palette.add 'White', color
|
59
|
+
expect(palette['White']).to be color
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe ASE::Color do
|
64
|
+
it 'must be initialized with all RGB channels' do
|
65
|
+
expect {
|
66
|
+
ASE::Color.new
|
67
|
+
}.to raise_error
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'sets a proper default for the alpha channel' do
|
71
|
+
color = ASE::Color.new(0, 0, 0)
|
72
|
+
expect(color.a).to be 255
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'can be created with an RGB array' do
|
76
|
+
color1 = ASE::Color.from_rgba [0, 0, 0]
|
77
|
+
color2 = ASE::Color.from_rgb [0, 0, 0]
|
78
|
+
|
79
|
+
expect(color1.to_rgba).to eq([0, 0, 0, 255])
|
80
|
+
expect(color2.to_rgba).to eq([0, 0, 0, 255])
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'can be created from a hex value' do
|
84
|
+
color1 = ASE::Color.from_hex('#000000')
|
85
|
+
color2 = ASE::Color.from_hex('000000')
|
86
|
+
color3 = ASE::Color.from_hex('#00000000')
|
87
|
+
|
88
|
+
rgba = [0, 0, 0, 255]
|
89
|
+
expect(color1.to_rgba).to eq(rgba)
|
90
|
+
expect(color2.to_rgba).to eq(rgba)
|
91
|
+
expect(color3.to_rgba).to eq([0, 0, 0, 0])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe 'Files' do
|
5
|
+
describe 'Reading' do
|
6
|
+
it 'throws an error if file is not set' do
|
7
|
+
doc = ASE.new
|
8
|
+
|
9
|
+
expect {
|
10
|
+
doc.read!
|
11
|
+
}.to raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'can read via factory or instantiation' do
|
15
|
+
doc1 = ASE.from_file('spec/files/control.ase')
|
16
|
+
expect(doc1.palettes.length).to be 1
|
17
|
+
|
18
|
+
doc2 = ASE.new('spec/files/control.ase')
|
19
|
+
doc2.read!
|
20
|
+
expect(doc2.palettes.length).to be 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'properly reads the palette name' do
|
24
|
+
doc = ASE.from_file('spec/files/control.ase')
|
25
|
+
expect(doc.palettes).to have_key('Simple')
|
26
|
+
expect(doc['Simple']).to eq(doc.palettes['Simple'])
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'reads the correct number of colors' do
|
30
|
+
doc = ASE.from_file('spec/files/control.ase')
|
31
|
+
expect(doc['Simple'].size).to be 2
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'correctly reads the color names' do
|
35
|
+
doc = ASE.from_file('spec/files/control.ase')
|
36
|
+
expect(doc['Simple'].colors).to have_key('White')
|
37
|
+
expect(doc['Simple'].colors).to have_key('Black')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'correctly reads the color values' do
|
41
|
+
doc = ASE.from_file('spec/files/control.ase')
|
42
|
+
expect(doc['Simple']['White'].to_rgb).to eq([255, 255, 255])
|
43
|
+
expect(doc['Simple']['Black'].to_rgb).to eq([0, 0, 0])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'Writing' do
|
48
|
+
before(:each) do
|
49
|
+
doc = ASE.new
|
50
|
+
|
51
|
+
palette = ASE::Palette.new('Test')
|
52
|
+
palette.add 'Red', ASE::Color.new(255, 0, 0)
|
53
|
+
palette.add 'Blue', ASE::Color.new(0, 0, 255)
|
54
|
+
|
55
|
+
doc << palette
|
56
|
+
|
57
|
+
@output = Tempfile.new('output.ase')
|
58
|
+
doc.to_file @output.path
|
59
|
+
end
|
60
|
+
|
61
|
+
after(:each) do
|
62
|
+
@output.unlink
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'writes data to the output file' do
|
66
|
+
expect(@output.size).to be > 0
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'properly writes the palette name' do
|
70
|
+
d = ASE.from_file(@output.path)
|
71
|
+
expect(d.palettes).to have_key('Test')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'writes the correct number of colors' do
|
75
|
+
d = ASE.from_file(@output.path)
|
76
|
+
expect(d['Test'].size).to be 2
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'writes the correct color names' do
|
80
|
+
d = ASE.from_file(@output.path)
|
81
|
+
expect(d['Test'].colors).to have_key('Red')
|
82
|
+
expect(d['Test'].colors).to have_key('Blue')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'writes the correct color values' do
|
86
|
+
d = ASE.from_file(@output.path)
|
87
|
+
expect(d['Test']['Red'].to_rgb).to eq([255, 0, 0])
|
88
|
+
expect(d['Test']['Blue'].to_rgb).to eq([0, 0, 255])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require './lib/ase'
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
5
|
+
config.run_all_when_everything_filtered = true
|
6
|
+
|
7
|
+
unless ENV['CIRCLECI']
|
8
|
+
config.filter_run :focus
|
9
|
+
end
|
10
|
+
|
11
|
+
# Run specs in random order to surface order dependencies. If you find an
|
12
|
+
# order dependency and want to debug it, you can fix the order by providing
|
13
|
+
# the seed, which is printed after each run.
|
14
|
+
# --seed 1234
|
15
|
+
config.order = 'random'
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ase
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan LeFevre
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Reader/writer for Adobe Swatch Exchange files
|
84
|
+
email:
|
85
|
+
- meltingice8917@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- .rspec
|
92
|
+
- Gemfile
|
93
|
+
- Guardfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- ase.gemspec
|
98
|
+
- examples/control.php
|
99
|
+
- examples/simple.rb
|
100
|
+
- lib/ase.rb
|
101
|
+
- lib/ase/color.rb
|
102
|
+
- lib/ase/file.rb
|
103
|
+
- lib/ase/palette.rb
|
104
|
+
- lib/ase/reader.rb
|
105
|
+
- lib/ase/version.rb
|
106
|
+
- lib/ase/writer.rb
|
107
|
+
- spec/ase_spec.rb
|
108
|
+
- spec/file_spec.rb
|
109
|
+
- spec/files/control.ase
|
110
|
+
- spec/spec_helper.rb
|
111
|
+
homepage: http://cosmos.layervault.com/aserb.html
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.0.3
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Reader/writer for Adobe Swatch Exchange files. Can be used across the entire
|
135
|
+
Adobe Creative Suite.
|
136
|
+
test_files:
|
137
|
+
- spec/ase_spec.rb
|
138
|
+
- spec/file_spec.rb
|
139
|
+
- spec/files/control.ase
|
140
|
+
- spec/spec_helper.rb
|