psd
Version:
A general purpose Photoshop file parser.
173 lines (142 loc) • 4.64 kB
text/coffeescript
_ = require 'lodash'
parseEngineData = require 'parse-engine-data'
LayerInfo = require '../layer_info.coffee'
Descriptor = require '../descriptor.coffee'
module.exports = class TextElements extends LayerInfo
: (key) -> key is 'TySh'
TRANSFORM_VALUE = ['xx', 'xy', 'yx', 'yy', 'tx', 'ty']
COORDS_VALUE = ['left', 'top', 'right', 'bottom']
constructor: (layer, length) ->
super(layer, length)
= null
= {}
= null
= null
= null
= null
= null
= null
= null
= null
= {}
parse: ->
= .readShort()
= .readShort()
= .readInt()
= new Descriptor().parse()
= ['Txt ']
= parseEngineData(.EngineData)
= .readShort()
= .readInt()
= new Descriptor().parse()
for name, index in COORDS_VALUE
[name] = .readInt()
parseTransformInfo: ->
for name, index in TRANSFORM_VALUE
[name] = .readDouble()
fonts: ->
return [] unless ?
.ResourceDict.FontSet.map (f) -> f.Name
lengthArray: ->
arr = .EngineDict.StyleRun.RunLengthArray
sum = _.reduce(arr, (m, o) -> m + o)
arr[arr.length - 1] = arr[arr.length - 1] - 1 if sum - .length == 1
return arr
fontStyles: ->
data = .EngineDict.StyleRun.RunArray.map (r) ->
r.StyleSheet.StyleSheetData
data.map (f) ->
if f.FauxItalic
style = 'italic'
else
style = 'normal'
return style
fontWeights: ->
data = .EngineDict.StyleRun.RunArray.map (r) ->
r.StyleSheet.StyleSheetData
data.map (f) ->
if f.FauxBold
weight = 'bold'
else
weight = 'normal'
return weight
textDecoration: ->
data = .EngineDict.StyleRun.RunArray.map (r) ->
r.StyleSheet.StyleSheetData
data.map (f) ->
if f.Underline
decoration = 'underline'
else
decoration = 'none'
return decoration
leading: ->
data = .EngineDict.StyleRun.RunArray.map (r) ->
r.StyleSheet.StyleSheetData
data.map (f) ->
if f.Leading
leading = f.Leading
else
leading = 'auto'
return leading
sizes: ->
return [] if not ? and not .FontSize?
.FontSize
alignment: ->
return [] unless ?
alignments = ['left', 'right', 'center', 'justify']
.EngineDict.ParagraphRun.RunArray.map (s) ->
alignments[Math.min(parseInt(s.ParagraphSheet.Properties.Justification, 10), 3)]
# Return all colors used for text in this layer. The colors are returned in RGBA
# format as an array of arrays.
colors: ->
# If the color is opaque black, this field is sometimes omitted.
return [[0, 0, 0, 255]] if not ? or not .FillColor?
.FillColor.map (s) ->
values = s.Values.map (v) -> Math.round(v * 255)
values.push values.shift() # Change ARGB -> RGBA for consistency
values
styles: ->
return {} unless ?
return if ?
data = .EngineDict.StyleRun.RunArray.map (r) ->
r.StyleSheet.StyleSheetData
= _.reduce(data, (m, o) ->
for own k, v of o
m[k] or= []
m[k].push v
m
, {})
# 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.
toCSS: ->
definition =
'font-family': .join(', ')
'font-size': "#{@sizes()[0]}pt"
'color': "rgba(#{@colors()[0].join(', ')})"
'text-align': [0]
css = []
for k, v of definition
continue unless v?
css.push "#{k}: #{v};"
css.join("\n")
export: ->
value:
font:
lengthArray:
styles:
weights:
names:
sizes:
colors:
alignment:
textDecoration:
leading:
left: .left
top: .top
right: .right
bottom: .bottom
transform: