psd 3.2.2 → 3.2.3
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 +4 -4
- data/lib/psd.rb +1 -25
- data/lib/psd/image.rb +10 -9
- data/lib/psd/image_modes/cmyk.rb +18 -5
- data/lib/psd/image_modes/greyscale.rb +6 -1
- data/lib/psd/image_modes/rgb.rb +14 -2
- data/lib/psd/layer_info/typetool.rb +10 -1
- data/lib/psd/renderer/canvas.rb +2 -3
- data/lib/psd/renderer/compose.rb +2 -5
- data/lib/psd/util.rb +4 -2
- data/lib/psd/version.rb +1 -1
- data/psd.gemspec +1 -1
- data/spec/files/alignment_modes.psd +0 -0
- data/spec/text_spec.rb +13 -1
- metadata +29 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f4587221b7f3298907408b999f0f6974736fdd0
|
4
|
+
data.tar.gz: 0c0db3b667c5bd30f4796835e6b4fb65d188fb28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d10bd3f42e0c24d6bed5a731bce1c6fc48dbbb55bc24c5998b8c9e1aad8f4eee8c6597d20cb9a198aa88772f4f36b7242b80bc357639f5b8948a45f9d0fa2777
|
7
|
+
data.tar.gz: affa248b3befb994fd365a4f81447517987904ed2b8c6018ec9c25b8f40d0a3517c4f1a56173a6846b2c01339bacc054fe2872a6ae02268f3ae3e7c33b88bfbc
|
data/lib/psd.rb
CHANGED
@@ -130,30 +130,6 @@ class PSD
|
|
130
130
|
)
|
131
131
|
end
|
132
132
|
|
133
|
-
# Export the current file to a new PSD. This may or may not work.
|
134
|
-
def export(file)
|
135
|
-
parse! unless parsed?
|
136
|
-
|
137
|
-
# Create our file for writing
|
138
|
-
outfile = File.open(file, 'w')
|
139
|
-
|
140
|
-
# Reset the file pointer
|
141
|
-
@file.seek 0
|
142
|
-
@header.write outfile
|
143
|
-
@file.seek @header.num_bytes, IO::SEEK_CUR
|
144
|
-
|
145
|
-
# Nothing in the header or resources we want to bother with changing
|
146
|
-
# right now. Write it straight to file.
|
147
|
-
outfile.write @file.read(@resources.end_of_section - @file.tell)
|
148
|
-
|
149
|
-
# Now, the changeable part. Layers and masks.
|
150
|
-
layer_mask.export(outfile)
|
151
|
-
|
152
|
-
# And the rest of the file (merged image data)
|
153
|
-
outfile.write @file.read
|
154
|
-
outfile.flush
|
155
|
-
end
|
156
|
-
|
157
133
|
private
|
158
134
|
|
159
135
|
def ensure_header
|
@@ -173,4 +149,4 @@ class PSD
|
|
173
149
|
@layer_mask = LayerMask.new(@file, @header, @opts)
|
174
150
|
@layer_mask.skip
|
175
151
|
end
|
176
|
-
end
|
152
|
+
end
|
data/lib/psd/image.rb
CHANGED
@@ -29,6 +29,8 @@ class PSD
|
|
29
29
|
@num_pixels *= 2 if depth == 16
|
30
30
|
|
31
31
|
calculate_length
|
32
|
+
set_channels_info
|
33
|
+
|
32
34
|
@channel_data = []
|
33
35
|
@pixel_data = []
|
34
36
|
@opacity = 1.0
|
@@ -38,15 +40,6 @@ class PSD
|
|
38
40
|
@end_pos = @start_pos + @length
|
39
41
|
|
40
42
|
PSD.logger.debug "Image: #{width}x#{height}, length = #{@length}, mode = #{@header.mode_name}, position = #{@start_pos}"
|
41
|
-
|
42
|
-
# Each color channel is represented by a unique ID
|
43
|
-
@channels_info = [
|
44
|
-
{id: 0},
|
45
|
-
{id: 1},
|
46
|
-
{id: 2}
|
47
|
-
]
|
48
|
-
|
49
|
-
@channels_info << {id: -1} if channels == 4
|
50
43
|
end
|
51
44
|
|
52
45
|
# Begins parsing the image by first figuring out the compression format used, and then
|
@@ -76,6 +69,14 @@ class PSD
|
|
76
69
|
|
77
70
|
private
|
78
71
|
|
72
|
+
def set_channels_info
|
73
|
+
case mode
|
74
|
+
when 1 then set_greyscale_channels
|
75
|
+
when 3 then set_rgb_channels
|
76
|
+
when 4 then set_cmyk_channels
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
79
80
|
def calculate_length
|
80
81
|
@length = case depth
|
81
82
|
when 1 then (width + 7) / 8 * height
|
data/lib/psd/image_modes/cmyk.rb
CHANGED
@@ -3,17 +3,30 @@ class PSD
|
|
3
3
|
module CMYK
|
4
4
|
private
|
5
5
|
|
6
|
+
def set_cmyk_channels
|
7
|
+
@channels_info = [
|
8
|
+
{ id: 0 },
|
9
|
+
{ id: 1 },
|
10
|
+
{ id: 2 },
|
11
|
+
{ id: 3 }
|
12
|
+
]
|
13
|
+
|
14
|
+
@channels_info << {id: -1} if channels == 5
|
15
|
+
end
|
16
|
+
|
6
17
|
def combine_cmyk_channel
|
18
|
+
cmyk_channels = @channels_info.
|
19
|
+
map { |ch| ch[:id] }.
|
20
|
+
reject { |ch| ch < -1 }
|
21
|
+
|
7
22
|
(0...@num_pixels).step(pixel_step) do |i|
|
8
23
|
c = m = y = k = 0
|
9
24
|
a = 255
|
10
25
|
|
11
|
-
|
12
|
-
next if chan[:id] == -2
|
13
|
-
|
26
|
+
cmyk_channels.each_with_index do |chan, index|
|
14
27
|
val = @channel_data[i + (@channel_length * index)]
|
15
28
|
|
16
|
-
case chan
|
29
|
+
case chan
|
17
30
|
when -1 then a = val
|
18
31
|
when 0 then c = val
|
19
32
|
when 1 then m = val
|
@@ -28,4 +41,4 @@ class PSD
|
|
28
41
|
end
|
29
42
|
end
|
30
43
|
end
|
31
|
-
end
|
44
|
+
end
|
@@ -3,6 +3,11 @@ class PSD
|
|
3
3
|
module Greyscale
|
4
4
|
private
|
5
5
|
|
6
|
+
def set_greyscale_channels
|
7
|
+
@channels_info = [{ id: 0 }]
|
8
|
+
@channels_info << { id: -1 } if channels == 2
|
9
|
+
end
|
10
|
+
|
6
11
|
def combine_greyscale_channel
|
7
12
|
if channels == 2
|
8
13
|
(0...@num_pixels).step(pixel_step) do |i|
|
@@ -19,4 +24,4 @@ class PSD
|
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
22
|
-
end
|
27
|
+
end
|
data/lib/psd/image_modes/rgb.rb
CHANGED
@@ -4,10 +4,22 @@ class PSD
|
|
4
4
|
module RGB
|
5
5
|
private
|
6
6
|
|
7
|
+
def set_rgb_channels
|
8
|
+
@channels_info = [
|
9
|
+
{ id: 0 },
|
10
|
+
{ id: 1 },
|
11
|
+
{ id: 2 }
|
12
|
+
]
|
13
|
+
|
14
|
+
@channels_info << {id: -1} if channels == 4
|
15
|
+
end
|
16
|
+
|
7
17
|
def combine_rgb_channel
|
8
18
|
PSD.logger.debug "Beginning RGB processing"
|
9
19
|
|
10
|
-
rgb_channels = @channels_info.
|
20
|
+
rgb_channels = @channels_info.
|
21
|
+
map { |ch| ch[:id] }.
|
22
|
+
reject { |ch| ch < -1 }
|
11
23
|
|
12
24
|
(0...@num_pixels).step(pixel_step) do |i|
|
13
25
|
r = g = b = 0
|
@@ -29,4 +41,4 @@ class PSD
|
|
29
41
|
end
|
30
42
|
end
|
31
43
|
end
|
32
|
-
end
|
44
|
+
end
|
@@ -52,6 +52,7 @@ class PSD
|
|
52
52
|
name: fonts.first,
|
53
53
|
sizes: sizes,
|
54
54
|
colors: colors,
|
55
|
+
alignment: alignment,
|
55
56
|
css: to_css
|
56
57
|
}
|
57
58
|
end
|
@@ -68,6 +69,13 @@ class PSD
|
|
68
69
|
return [] if engine_data.nil? || !styles.has_key?('FontSize')
|
69
70
|
styles['FontSize'].uniq
|
70
71
|
end
|
72
|
+
|
73
|
+
def alignment
|
74
|
+
return {} if engine_data.nil?
|
75
|
+
engine_data.EngineDict.ParagraphRun.RunArray.map do |s|
|
76
|
+
["left", "right", "center", "justify"][[s.ParagraphSheet.Properties.Justification.to_i,3].min]
|
77
|
+
end
|
78
|
+
end
|
71
79
|
|
72
80
|
# Return all colors used for text in this layer. The colors are returned in RGBA
|
73
81
|
# format as an array of arrays.
|
@@ -119,7 +127,8 @@ class PSD
|
|
119
127
|
definition = {
|
120
128
|
'font-family' => fonts.join(', '),
|
121
129
|
'font-size' => "#{sizes.first}pt",
|
122
|
-
'color' => "rgba(#{colors.first.join(', ')})"
|
130
|
+
'color' => "rgba(#{colors.first.join(', ')})",
|
131
|
+
'text-align' => alignment.first
|
123
132
|
}
|
124
133
|
|
125
134
|
css = []
|
data/lib/psd/renderer/canvas.rb
CHANGED
@@ -2,9 +2,8 @@ class PSD
|
|
2
2
|
class Renderer
|
3
3
|
class Canvas
|
4
4
|
attr_reader :canvas, :node, :opts, :width, :height, :opacity, :fill_opacity
|
5
|
-
|
6
|
-
[:top, :right, :bottom, :left].each { |dir| delegate dir, to: :node }
|
7
5
|
|
6
|
+
delegate :top, :right, :bottom, :left, to: :node
|
8
7
|
delegate :[], :[]=, :get_pixel, :set_pixel, to: :canvas
|
9
8
|
|
10
9
|
def initialize(node, width = nil, height = nil, opts = {})
|
@@ -112,4 +111,4 @@ class PSD
|
|
112
111
|
end
|
113
112
|
end
|
114
113
|
end
|
115
|
-
end
|
114
|
+
end
|
data/lib/psd/renderer/compose.rb
CHANGED
@@ -5,6 +5,7 @@ class PSD
|
|
5
5
|
# Mostly based on similar code from libpsd.
|
6
6
|
module Compose
|
7
7
|
extend self
|
8
|
+
extend ChunkyPNG::Color
|
8
9
|
|
9
10
|
#
|
10
11
|
# Normal blend modes
|
@@ -318,10 +319,6 @@ class PSD
|
|
318
319
|
rgba(new_r, new_g, new_b, dst_alpha)
|
319
320
|
end
|
320
321
|
|
321
|
-
[:r, :g, :b, :a, :rgba, :fully_transparent?].each do |meth|
|
322
|
-
define_method(meth) { |*args| ChunkyPNG::Color.send(meth, *args) }
|
323
|
-
end
|
324
|
-
|
325
322
|
# If the blend mode is missing, we fall back to normal composition.
|
326
323
|
def method_missing(method, *args, &block)
|
327
324
|
normal(*args)
|
@@ -351,4 +348,4 @@ class PSD
|
|
351
348
|
bg + ((255 - bg) * fg >> 8)
|
352
349
|
end
|
353
350
|
end
|
354
|
-
end
|
351
|
+
end
|
data/lib/psd/util.rb
CHANGED
data/lib/psd/version.rb
CHANGED
data/psd.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_dependency 'rake'
|
22
22
|
gem.add_dependency 'psd-enginedata', '~> 1'
|
23
23
|
gem.add_dependency 'chunky_png'
|
24
|
-
gem.add_dependency 'activesupport'
|
24
|
+
gem.add_dependency 'activesupport'
|
25
25
|
gem.add_dependency 'xmp'
|
26
26
|
|
27
27
|
gem.test_files = Dir.glob("spec/**/*")
|
Binary file
|
data/spec/text_spec.rb
CHANGED
@@ -24,4 +24,16 @@ describe 'Text' do
|
|
24
24
|
expect(c[-1]).to eq(";")
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Justified Text" do
|
30
|
+
let (:psd) { PSD.new('spec/files/alignment_modes.psd').tap(&:parse!) }
|
31
|
+
|
32
|
+
["left", "right", "center", "justify"].each do |alignment|
|
33
|
+
it "that is #{alignment} justified can be exported to CSS" do
|
34
|
+
type = psd.tree.children_at_path(alignment).first.type
|
35
|
+
css = type.to_css
|
36
|
+
expect(css).to include "text-align: #{alignment}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: psd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan LeFevre
|
@@ -9,132 +9,132 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-09-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: psd-enginedata
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - ~>
|
32
|
+
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '1'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - ~>
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '1'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: chunky_png
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: activesupport
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: '0'
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: '0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: xmp
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rspec
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- -
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: guard
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: guard-rspec
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: rb-fsevent
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- - ~>
|
130
|
+
- - "~>"
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0.9'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- - ~>
|
137
|
+
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0.9'
|
140
140
|
description: Parse Photoshop PSD files with ease
|
@@ -145,9 +145,9 @@ executables: []
|
|
145
145
|
extensions: []
|
146
146
|
extra_rdoc_files: []
|
147
147
|
files:
|
148
|
-
- .gitignore
|
149
|
-
- .rspec
|
150
|
-
- .travis.yml
|
148
|
+
- ".gitignore"
|
149
|
+
- ".rspec"
|
150
|
+
- ".travis.yml"
|
151
151
|
- CONTRIBUTING.md
|
152
152
|
- Gemfile
|
153
153
|
- Guardfile
|
@@ -242,6 +242,7 @@ files:
|
|
242
242
|
- lib/psd/util.rb
|
243
243
|
- lib/psd/version.rb
|
244
244
|
- psd.gemspec
|
245
|
+
- spec/files/alignment_modes.psd
|
245
246
|
- spec/files/blendmodes.psd
|
246
247
|
- spec/files/empty-layer-subgroups.psd
|
247
248
|
- spec/files/empty-layer.psd
|
@@ -274,12 +275,12 @@ require_paths:
|
|
274
275
|
- lib
|
275
276
|
required_ruby_version: !ruby/object:Gem::Requirement
|
276
277
|
requirements:
|
277
|
-
- -
|
278
|
+
- - ">="
|
278
279
|
- !ruby/object:Gem::Version
|
279
280
|
version: '0'
|
280
281
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
281
282
|
requirements:
|
282
|
-
- -
|
283
|
+
- - ">="
|
283
284
|
- !ruby/object:Gem::Version
|
284
285
|
version: '0'
|
285
286
|
requirements: []
|
@@ -289,6 +290,7 @@ signing_key:
|
|
289
290
|
specification_version: 4
|
290
291
|
summary: General purpose library for parsing Photoshop files
|
291
292
|
test_files:
|
293
|
+
- spec/files/alignment_modes.psd
|
292
294
|
- spec/files/blendmodes.psd
|
293
295
|
- spec/files/empty-layer-subgroups.psd
|
294
296
|
- spec/files/empty-layer.psd
|