</td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>The blend mode describes important data regarding a layer, such as
</td><tdclass="code"><divclass="highlight"><pre><spanclass="p">{</span><spanclass="nx">Module</span><spanclass="p">}</span><spanclass="o">=</span><spanclass="nx">require</span><spanclass="s">'coffeescript-module'</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>The blend mode describes important data regarding a layer, such as
the blending mode, the opacity, and whether it's a part of a clipping mask.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><ahref="#section-3"class="pilcrow">¶</a></div><p>All of the blend modes are stored in the PSD file with a specific key.
<spanclass="nx">@aliasProperty</span><spanclass="s">'blendingMode'</span><spanclass="p">,</span><spanclass="s">'mode'</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><ahref="#section-3"class="pilcrow">¶</a></div><p>All of the blend modes are stored in the PSD file with a specific key.
This is the mapping of that key to its readable name.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><ahref="#section-4"class="pilcrow">¶</a></div><p>The 4 character key for the blending mode.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="pilwrap"><ahref="#section-5"class="pilcrow">¶</a></div><p>The opacity of the layer, from [0, 255].</p>
<spanclass="nv">constructor: </span><spanclass="nf">(@file) -></span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><ahref="#section-4"class="pilcrow">¶</a></div><p>The 4 character key for the blending mode.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="pilwrap"><ahref="#section-6"class="pilcrow">¶</a></div><p>Raw value for the clipping state of this layer.</p>
</td><tdclass="code"><divclass="highlight"><pre><spanclass="vi">@blendKey = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="pilwrap"><ahref="#section-5"class="pilcrow">¶</a></div><p>The opacity of the layer, from [0, 255].</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="pilwrap"><ahref="#section-7"class="pilcrow">¶</a></div><p>Is this layer a clipping mask?</p>
</td><tdclass="code"><divclass="highlight"><pre><spanclass="vi">@opacity = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="pilwrap"><ahref="#section-6"class="pilcrow">¶</a></div><p>Raw value for the clipping state of this layer.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="pilwrap"><ahref="#section-8"class="pilcrow">¶</a></div><p>The readable representation of the blend mode.</p>
</td><tdclass="code"><divclass="highlight"><pre><spanclass="vi">@clipping = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="pilwrap"><ahref="#section-7"class="pilcrow">¶</a></div><p>Is this layer a clipping mask?</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="pilwrap"><ahref="#section-9"class="pilcrow">¶</a></div><p>Is this layer visible?</p>
<spanclass="vi">@flags = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="pilwrap"><ahref="#section-8"class="pilcrow">¶</a></div><p>The readable representation of the blend mode.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="pilwrap"><ahref="#section-10"class="pilcrow">¶</a></div><p>Parses the blend mode data.</p>
</td><tdclass="code"><divclass="highlight"><pre><spanclass="vi">@mode = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="pilwrap"><ahref="#section-9"class="pilcrow">¶</a></div><p>Is this layer visible?</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="pilwrap"><ahref="#section-11"class="pilcrow">¶</a></div><p>Returns the layer opacity as a percentage.</p>
</td><tdclass="code"><divclass="highlight"><pre><spanclass="vi">@visible = </span><spanclass="kc">null</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="pilwrap"><ahref="#section-10"class="pilcrow">¶</a></div><p>Parses the blend mode data.</p>
</td><tdclass="code"><divclass="highlight"><pre>undefined</pre></div></td></tr></tbody></table><divid="generated">generated Mon May 11 2015 16:38:04 GMT-0400 (EDT) </div></div></body></html>
<spanclass="nx">@file</span><spanclass="p">.</span><spanclass="nx">seek</span><spanclass="mi">1</span><spanclass="p">,</span><spanclass="kc">true</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="pilwrap"><ahref="#section-11"class="pilcrow">¶</a></div><p>Returns the layer opacity as a percentage.</p>
<spanclass="vi">@infoKeys = </span><spanclass="p">[]</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><ahref="#section-4"class="pilcrow">¶</a></div><p>The layer's name can come from one of two places, depending on
what version of Photoshop was used to create the PSD.</p>
<spanclass="nx">@legacyName</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="pilwrap"><ahref="#section-5"class="pilcrow">¶</a></div><p>Every layer starts with the same set of data, and ends with a dynamic
<spanclass="nv">module.exports =</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>Every layer defines how it's blended with the rest of the document.
This is represented in the Photoshop UI above the layer list as
a drop down. It also defines the layer opacity and whether it's a
</td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">module.exports =</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>Blending ranges let you control which pixels from this layer and which
pixels from the underlying layers appear in the final image. This describes
the ranges in both greyscale and for each color channel.</p>
<spanclass="nv">Util = </span><spanclass="nx">require</span><spanclass="s">'../util.coffee'</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>This is an incredibly important object because the majority of the layer information
is contained in layer info blocks. The keys of this object define how the layer info
can be accessed. Each layer info block contains different data, so accessing the data
within each differs from type to type.</p>
<p>Here's an example of how to access some of this data:</p>
<spanclass="nv">parseLayerInfo: </span><spanclass="nf">-></span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><ahref="#section-3"class="pilcrow">¶</a></div><p>Layer info blocks are the last section in the layer, so we can continue until our
<spanclass="nx">@file</span><spanclass="p">.</span><spanclass="nx">seek</span><spanclass="mi">4</span><spanclass="p">,</span><spanclass="kc">true</span><spanclass="c1"># sig</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><ahref="#section-4"class="pilcrow">¶</a></div><p>Every layer info block is identified by a unique 4 character string.</p>
<spanclass="k">continue</span><spanclass="k">unless</span><spanclass="nx">klass</span><spanclass="p">.</span><spanclass="nx">shouldParse</span><spanclass="p">(</span><spanclass="nx">key</span><spanclass="p">)</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="pilwrap"><ahref="#section-5"class="pilcrow">¶</a></div><p>Once we find the right class to handle the layer info block, we create it and
register it with LazyExecute. This allows us to parse the PSD significantly
faster because we don't bother parsing the layer info block until it's accessed.</p>
<spanclass="p">.</span><spanclass="nx">get</span><spanclass="p">()</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="pilwrap"><ahref="#section-6"class="pilcrow">¶</a></div><p>We create a function that lets us easily access the data.</p>
<spanclass="nx">do</span><spanclass="nf">(name) =></span><spanclass="nx">@</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="nf">=></span><spanclass="nx">@adjustments</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="pilwrap"><ahref="#section-7"class="pilcrow">¶</a></div><p>For debugging purposes, we store every key that we can parse.</p>
<spanclass="k">break</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="pilwrap"><ahref="#section-8"class="pilcrow">¶</a></div><p>If we don't know how to parse this particular layer info block, we can skip it since we
<spanclass="nv">module.exports =</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>Every layer has a mask section, whether or not the layer actually
has a mask defined. If there is no mask, then the mask size will be
<spanclass="nv">module.exports =</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>Every Photoshop document has what we can consider to be the "legacy" name.
This used to be the sole place that Photoshop stored the layer name, but once
people started using fancy UTF-8 characters, they moved the layer name out into
a layer info block. This stayed behind for compatibility reasons. The newer layer
name is always preferred since it covers all possible characters (even emojis),
while this has a much more limited character set.</p>
</td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">module.exports =</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>Every layer starts with the basics. Here we have the layer dimensions,
the number of color channels for the image data, and information about
<spanclass="vi">@cols = @width = </span><spanclass="nx">@right</span><spanclass="o">-</span><spanclass="nx">@left</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><ahref="#section-3"class="pilcrow">¶</a></div><p>Every color channel has both an ID and a length. The ID correlates to
the color channel, e.g. 0 = R, 1 = G, 2 = B, -1 = A, and the length is
<spanclass="nv">Layer = </span><spanclass="nx">require</span><spanclass="s">'./layer.coffee'</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>The layer mask is the overarching data structure that describes both
the layers/groups in the PSD document, and the global mask.
This part of the document is ordered as such:</p>
<ul>
<li>Layers</li>
<li>Layer images</li>
<li>Global Mask</li>
</ul>
<p>The file does not need to have a global mask. If there is none, then
<spanclass="nx">@parseGlobalMask</span><spanclass="p">()</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><ahref="#section-3"class="pilcrow">¶</a></div><p>The layers are stored in the reverse order that we would like them. In other
words, they're stored bottom to top and we want them top to bottom.</p>
<spanclass="nv">mask.opacity = </span><spanclass="nx">@file</span><spanclass="p">.</span><spanclass="nx">readShort</span><spanclass="p">()</span><spanclass="o">/</span><spanclass="mf">16.0</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>0 = color selected, 1 = color protected, 128 = use value per layer</p>
<spanclass="nv">mask.opacity = </span><spanclass="nx">@file</span><spanclass="p">.</span><spanclass="nx">readShort</span><spanclass="p">()</span><spanclass="o">/</span><spanclass="mf">16.0</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><ahref="#section-4"class="pilcrow">¶</a></div><p>0 = color selected, 1 = color protected, 128 = use value per layer</p>
<spanclass="vi">@passthru = </span><spanclass="p">[]</span></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><ahref="#section-2"class="pilcrow">¶</a></div><p>This describes the method that we want to run at object instantiation. Typically this
will skip over the data that we will parse on-demand later. We can pass any arguments
<spanclass="k">return</span><spanclass="nx">@</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><ahref="#section-3"class="pilcrow">¶</a></div><p>Here we describe the method we want to run when the first method/property on the object
is accessed. We can also define any arguments that need to be passed to the function.</p>
<spanclass="k">return</span><spanclass="nx">@</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><ahref="#section-4"class="pilcrow">¶</a></div><p>Sometimes we don't have to parse the data in order to get some important information.
For example, we can get the widht/height from the full preview image without parsing the
image itself, since that data comes from the header. Purely convenience, but helps to
optimize usage.</p>
<p>The arguments are a list of method/property names we don't want to trigger on-demand parsing.</p>
<spanclass="k">return</span><spanclass="nx">@</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="pilwrap"><ahref="#section-5"class="pilcrow">¶</a></div><p>This is called once all of the paramters of the proxy have been set up, i.e. now, later, and skip.
This defines all items on the proxied objects prototype on this object, and checks to make sure
the proxied object has been loaded before passing on the call.</p>
<spanclass="nx">@</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="pilwrap"><ahref="#section-6"class="pilcrow">¶</a></div><p>If we are accessing a property for the first time, then this will call the load method, which
was defined during setup with <code>later()</code>. The steps this performs are:</p>
<ol>
<li>Records the current file position.</li>
<li>Jumps to the recorded start position for the proxied data.</li>
<li>Calls the load method, which was defined with <code>later()</code>.</li>
<li>Jumps back to the original file position.</li>
<li>Sets the <code>@loaded</code> flag to true so we know this object has been parsed.</li>