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

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



151
152
153
154
# File 'lib/psd/layer_info/typetool.rb', line 151

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

Instance Method Details

#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]]



82
83
84
85
86
87
88
89
# File 'lib/psd/layer_info/typetool.rb', line 82

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



91
92
93
# File 'lib/psd/layer_info/typetool.rb', line 91

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.



56
57
58
59
60
61
62
63
# File 'lib/psd/layer_info/typetool.rb', line 56

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

#fontsObject

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



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

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

#parseObject

Parse all of the text data in the layer.



11
12
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
40
# File 'lib/psd/layer_info/typetool.rb', line 11

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[:text]['EngineData']
    .encode!('UTF-8', 'MacRoman')
    .delete!("\000")

  @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



115
116
117
# File 'lib/psd/layer_info/typetool.rb', line 115

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

#sizesObject

Return all font sizes for this layer.



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

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

#stylesObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/psd/layer_info/typetool.rb', line 95

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.



44
45
46
47
48
49
50
51
# File 'lib/psd/layer_info/typetool.rb', line 44

def text_value
  if engine_data.nil?
    # Something went wrong, lets hack our way through.
    /\/Text \(˛ˇ(.*)\)$/.match(@data[:text]['EngineData'])[1].gsub /\r/, "\n"
  else
    engine_data.EngineDict.Editor.Text
  end
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.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/psd/layer_info/typetool.rb', line 124

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

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

  css.join("\n")
end

#to_hashObject



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/psd/layer_info/typetool.rb', line 139

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