Class: PSD::TypeTool

Inherits:
LayerInfo show all
Defined in:
lib/psd/layer_info/typetool.rb

Overview

Parses and provides information about text areas within layers in the document.

Direct Known Subclasses

LegacyTypeTool

Instance Attribute Summary

Attributes inherited from LayerInfo

#data

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from LayerInfo

#initialize, #skip

Constructor Details

This class inherits a constructor from PSD::LayerInfo

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



157
158
159
160
# File 'lib/psd/layer_info/typetool.rb', line 157

def method_missing(method, *args, &block)
  return @data[method] if @data.has_key?(method)
  return super
end

Class Method Details

.should_parse?(key) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
# File 'lib/psd/layer_info/typetool.rb', line 8

def self.should_parse?(key)
  key == 'TySh'
end

Instance Method Details

#alignmentObject



73
74
75
76
77
78
79
80
# File 'lib/psd/layer_info/typetool.rb', line 73

def alignment
  return {} if engine_data.nil?
  engine_data.EngineDict.ParagraphRun.RunArray.map do |s| 
    ["left", "right", "center", "justify"][[s.ParagraphSheet.Properties.Justification.to_i,3].min]
  end
rescue
  []
end

#colorsObject

Return all colors used for text in this layer. The colors are returned in RGBA format as an array of arrays.

> [[255, 0, 0, 255], [0, 0, 255, 255]]



86
87
88
89
90
91
92
93
# File 'lib/psd/layer_info/typetool.rb', line 86

def colors
  # If the color is opaque black, this field is sometimes omitted.
  return [[0, 0, 0, 255]] if engine_data.nil? || !styles.has_key?('FillColor')
  styles['FillColor'].map { |s|
    values = s['Values'].map { |v| (v * 255).round }
    values << values.shift # Change ARGB -> RGBA for consistency
  }.uniq
end

#engine_dataObject



95
96
97
# File 'lib/psd/layer_info/typetool.rb', line 95

def engine_data
  @data[:engine_data]
end

#fontObject

Gets all of the basic font information for this text area. This assumes that the first font is the only one you want.



50
51
52
53
54
55
56
57
58
# File 'lib/psd/layer_info/typetool.rb', line 50

def font
  {
    name: fonts.first,
    sizes: sizes,
    colors: colors,
    alignment: alignment,
    css: to_css
  }
end

#fontsObject

Returns all fonts listed for this layer, since fonts are defined on a per-character basis.



62
63
64
65
# File 'lib/psd/layer_info/typetool.rb', line 62

def fonts
  return [] if engine_data.nil?
  engine_data.ResourceDict.FontSet.map(&:Name)
end

#parseObject

Parse all of the text data in the layer.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/psd/layer_info/typetool.rb', line 13

def parse
  version = @file.read_short
  parse_transform_info

  text_version = @file.read_short
  descriptor_version = @file.read_int

  @data[:text] = Descriptor.new(@file).parse

  @data[:engine_data] = nil
  begin
    parser.parse!
    @data[:engine_data] = parser.result
  rescue Exception => e
    PSD.logger.error e.message
  end

  warpVersion = @file.read_short
  descriptor_version = @file.read_int

  @data[:warp] = Descriptor.new(@file).parse
  [:left, :top, :right, :bottom].each do |pos|
    @data[pos] = @file.read_int
  end

  return self
end

#parserObject



119
120
121
# File 'lib/psd/layer_info/typetool.rb', line 119

def parser
  @parser ||= PSD::EngineData.new(@data[:text]['EngineData'])
end

#sizesObject

Return all font sizes for this layer.



68
69
70
71
# File 'lib/psd/layer_info/typetool.rb', line 68

def sizes
  return [] if engine_data.nil? || !styles.has_key?('FontSize')
  styles['FontSize'].uniq
end

#stylesObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/psd/layer_info/typetool.rb', line 99

def styles
  return {} if engine_data.nil?

  @styles ||= (
    data = engine_data.EngineDict.StyleRun.RunArray.map do |r|
      r.StyleSheet.StyleSheetData
    end

    Hash[data.reduce({}) { |m, o|
      o.each do |k, v|
        (m[k] ||= []) << v
      end

      m
    }.map { |k, v|
      [k, v.uniq]
    }]
  )
end

#text_valueObject Also known as: to_s

Extracts the text within the text area. In the event that psd-enginedata fails for some reason, we attempt to extract the text using some rough regex.



43
44
45
# File 'lib/psd/layer_info/typetool.rb', line 43

def text_value
  @data[:text]['Txt ']
end

#to_cssObject

Creates the CSS string and returns it. Each property is newline separated and not all properties may be present depending on the document.

Colors are returned in rgba() format and fonts may include some internal Photoshop fonts.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/psd/layer_info/typetool.rb', line 128

def to_css      
  definition = {
    'font-family' => fonts.join(', '),
    'font-size' => "#{sizes.first}pt",
    'color' => "rgba(#{colors.first.join(', ')})",
    'text-align' => alignment.first
  }

  css = []
  definition.each do |k, v|
    next if v.nil?
    css << "#{k}: #{v};"
  end

  css.join("\n")
end

#to_hashObject



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/psd/layer_info/typetool.rb', line 145

def to_hash
  {
    value:      text_value,
    font:       font,
    left:       left,
    top:        top,
    right:      right,
    bottom:     bottom,
    transform:  transform
  }
end