Can now retrieve ArtLayers/LayerSets from Document/LayerSets by name.

- Added helper methods to ArtLayer to get each boundry.
- Fixed a bug in getActiveDoc.jsx
This commit is contained in:
Unknown
2018-03-20 13:32:43 -04:00
parent 0202d5c188
commit 8f0e80863c
4 changed files with 184 additions and 81 deletions

View File

@@ -2,12 +2,11 @@ package ps
import ( import (
"fmt" "fmt"
// "os" "os"
// "path/filepath" "path/filepath"
"testing" "testing"
) )
/*
func TestPkgPath(t *testing.T) { func TestPkgPath(t *testing.T) {
out := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "sbrow", "ps") out := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "sbrow", "ps")
if filepath.Join(pkgpath) != out { if filepath.Join(pkgpath) != out {
@@ -23,9 +22,9 @@ func TestStart(t *testing.T) {
} }
func TestOpen(t *testing.T) { func TestOpen(t *testing.T) {
if testing.Short() { // if testing.Short() {
t.Skip("Skipping \"TestOpen\"") // t.Skip("Skipping \"TestOpen\"")
} // }
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd") err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -82,6 +81,9 @@ func TestWait(t *testing.T) {
} }
func TestDoAction_Crop(t *testing.T) { func TestDoAction_Crop(t *testing.T) {
if testing.Short() {
t.Skip("Skipping \"TestDoAction_Crop\"")
}
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd") err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -93,6 +95,9 @@ func TestDoAction_Crop(t *testing.T) {
} }
func TestDoAction_Undo(t *testing.T) { func TestDoAction_Undo(t *testing.T) {
if testing.Short() {
t.Skip("Skipping \"TestDoAction_Undo\"")
}
err := DoAction("DK", "Undo") err := DoAction("DK", "Undo")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -104,8 +109,10 @@ func TestSaveAs(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
os.Remove("F:\\TEMP\\test.png")
} }
/*
func TestLayerSet(t *testing.T) { func TestLayerSet(t *testing.T) {
_, err := NewLayerSet("Areas/TitleBackground/") _, err := NewLayerSet("Areas/TitleBackground/")
if err != nil { if err != nil {
@@ -120,7 +127,6 @@ func TestLayer(t *testing.T) {
} }
} }
func TestMove(t *testing.T) { func TestMove(t *testing.T) {
lyr, err := Layer("Group 1/Layer 1") lyr, err := Layer("Group 1/Layer 1")
if err != nil { if err != nil {
@@ -137,27 +143,27 @@ func TestActiveDocument(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if d != d.ArtLayers[0].Parent() { if d != d.artLayers[0].Parent() {
fmt.Println(d) fmt.Println(d)
fmt.Println(d.ArtLayers[0].Parent()) fmt.Println(d.artLayers[0].Parent())
t.Fatal("ArtLayers do not have doc as parent.") t.Fatal("ArtLayers do not have doc as parent.")
} }
if d != d.LayerSets[0].Parent() { if d != d.layerSets[0].Parent() {
fmt.Println(d) fmt.Println(d)
fmt.Println(d.LayerSets[0].Parent()) fmt.Println(d.layerSets[0].Parent())
t.Fatal("LayerSets do not have doc as parent.") t.Fatal("LayerSets do not have doc as parent.")
} }
if d.LayerSets[0] != d.LayerSets[0].ArtLayers[0].Parent() { if d.layerSets[0] != d.layerSets[0].artLayers[0].Parent() {
fmt.Println(d.LayerSets[0]) fmt.Println(d.layerSets[0])
fmt.Println(d.LayerSets[0].ArtLayers[0]) fmt.Println(d.layerSets[0].artLayers[0])
fmt.Println(d.LayerSets[0].ArtLayers[0].Parent()) fmt.Println(d.layerSets[0].artLayers[0].Parent())
t.Fatal("Layerset's ArtLayers do not have correct parents") t.Fatal("Layerset's ArtLayers do not have correct parents")
} }
} }
func TestApplyDataset(t *testing.T) { func TestApplyDataset(t *testing.T) {
out := []byte("done!\r\n") out := []byte("done!\r\n")
ret, err := ApplyDataset("Anger") ret, err := ApplyDataset(" Anger")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -165,11 +171,28 @@ func TestApplyDataset(t *testing.T) {
fail := fmt.Sprintf("TestJS failed.\ngot:\t\"%s\"\nwant:\t\"%s\"", ret, out) fail := fmt.Sprintf("TestJS failed.\ngot:\t\"%s\"\nwant:\t\"%s\"", ret, out)
t.Fatal(fail) t.Fatal(fail)
} }
err = Quit(2) }
func TestDocumentLayerSet(t *testing.T) {
d, err := ActiveDocument()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
set := d.LayerSet("Text")
fmt.Println(set)
for _, lyr := range set.ArtLayers() {
fmt.Println(lyr.name)
}
lyr := set.ArtLayer("id")
fmt.Println(lyr)
set = d.LayerSet("Indicators").LayerSet("Life")
fmt.Println(set)
for _, lyr := range set.ArtLayers() {
fmt.Println(lyr.name)
}
} }
/*
func TestDoJs_HideLayer(t *testing.T) { func TestDoJs_HideLayer(t *testing.T) {
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd") err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")
if err != nil { if err != nil {
@@ -181,7 +204,7 @@ func TestDoJs_HideLayer(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
*/
func BenchmarkDoc_Go(b *testing.B) { func BenchmarkDoc_Go(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_, err := ActiveDocument() _, err := ActiveDocument()

View File

@@ -1,8 +1,8 @@
#include lib.js #include lib.js
var stdout = newFile(arguments[0]); var stdout = newFile(arguments[0]);
var doc = app.activeDocument; var doc = app.activeDocument;
stdout.writeln(('{"Name": "' + doc.name +'", "Height":' +doc.height + stdout.writeln(('{"Name": "'+doc.name+'", "Height":'+doc.height+
', "Width":' + doc.width + ', "ArtLayers": [').replace(/ px/g, "")); ', "Width":'+doc.width+', "ArtLayers": [').replace(/ px/g, ""));
function layers(lyrs) { function layers(lyrs) {
if (typeof lyrs === 'undefined') if (typeof lyrs === 'undefined')
return; return;

View File

@@ -13,8 +13,8 @@ for (var i = 0; i < set.artLayers.length; i++) {
} }
stdout.write('], "LayerSets": [') stdout.write('], "LayerSets": [')
for (var i = 0; i < set.layerSets.length; i++) { for (var i = 0; i < set.layerSets.length; i++) {
var set = set.layerSets[i]; var s = set.layerSets[i];
stdout.write('{"Name": "'+ set.name +'"}'); stdout.write('{"Name": "'+ s.name +'"}');
if (i < set.layerSets.length - 1) if (i < set.layerSets.length - 1)
stdout.writeln(","); stdout.writeln(",");
} }

View File

@@ -2,6 +2,7 @@ package ps
import ( import (
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@@ -13,13 +14,21 @@ type Group interface {
Parent() Group Parent() Group
SetParent(Group) SetParent(Group)
Path() string Path() string
GetArtLayers() []*ArtLayer ArtLayers() []*ArtLayer
GetLayerSets() []*LayerSet LayerSets() []*LayerSet
} }
// Document represents a Photoshop document (PSD file). // Document represents a Photoshop document (PSD file).
type Document struct { type Document struct {
name string name string
height int
width int
artLayers []*ArtLayer
layerSets []*LayerSet
}
type DocumentJSON struct {
Name string
Height int Height int
Width int Width int
ArtLayers []*ArtLayer ArtLayers []*ArtLayer
@@ -32,30 +41,42 @@ func (d *Document) UnmarshalJSON(b []byte) error {
return err return err
} }
d.name = tmp.Name d.name = tmp.Name
d.Height = tmp.Height d.height = tmp.Height
d.Width = tmp.Width d.width = tmp.Width
d.ArtLayers = tmp.ArtLayers d.artLayers = tmp.ArtLayers
d.LayerSets = tmp.LayerSets d.layerSets = tmp.LayerSets
return nil return nil
} }
type DocumentJSON struct { // Name returns the document's title.
Name string // This fufills the Group interface.
Height int
Width int
ArtLayers []*ArtLayer
LayerSets []*LayerSet
}
func (d *Document) Name() string { func (d *Document) Name() string {
return d.name return d.name
} }
func (d *Document) GetArtLayers() []*ArtLayer {
return d.ArtLayers // The height of the document, in pixels.
func (d *Document) Height() int {
return d.height
} }
func (d *Document) GetLayerSets() []*LayerSet { func (d *Document) ArtLayers() []*ArtLayer {
return d.LayerSets return d.artLayers
}
// LayerSets returns all the document's top level LayerSets.
func (d *Document) LayerSets() []*LayerSet {
return d.layerSets
}
// LayerSet returns the first top level LayerSet matching
// the given name.
func (d *Document) LayerSet(name string) *LayerSet {
for _, set := range d.layerSets {
if set.name == name {
return set
}
}
return nil
} }
func (d *Document) Parent() Group { func (d *Document) Parent() Group {
@@ -68,29 +89,31 @@ func (d *Document) Path() string {
} }
func ActiveDocument() (*Document, error) { func ActiveDocument() (*Document, error) {
log.Println("Loading ActiveDoucment/")
byt, err := DoJs("getActiveDoc.jsx") byt, err := DoJs("getActiveDoc.jsx")
var d *Document var d *Document
err = json.Unmarshal(byt, &d) err = json.Unmarshal(byt, &d)
for _, lyr := range d.ArtLayers { for _, lyr := range d.artLayers {
lyr.SetParent(d) lyr.SetParent(d)
} }
for i, set := range d.LayerSets { for i, set := range d.layerSets {
s, err := NewLayerSet(set.Path() + "/") s, err := NewLayerSet(set.Path()+"/", d)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
d.LayerSets[i] = s d.layerSets[i] = s
s.SetParent(d) // s.SetParent(d)
} }
return d, err return d, err
} }
// ArtLayer represents an Art Layer in a photoshop document.
type ArtLayer struct { type ArtLayer struct {
name string name string
// TextItem string // TextItem string
Bounds [2][2]int bounds [2][2]int
parent Group parent Group
Visiblity bool visible bool
} }
type ArtLayerJSON struct { type ArtLayerJSON struct {
@@ -106,12 +129,40 @@ func (a *ArtLayer) UnmarshalJSON(b []byte) error {
return err return err
} }
a.name = tmp.Name a.name = tmp.Name
a.Bounds = tmp.Bounds a.bounds = tmp.Bounds
a.parent = tmp.Parent a.parent = tmp.Parent
a.Visiblity = tmp.Visible a.visible = tmp.Visible
return nil return nil
} }
func (a *ArtLayer) Name() string {
return a.name
}
func (a *ArtLayer) Bounds() [2][2]int {
return a.bounds
}
// X1 returns the layer's leftmost x value.
func (a *ArtLayer) X1() int {
return a.bounds[0][0]
}
// X2 returns the layer's rightmost x value.
func (a *ArtLayer) X2() int {
return a.bounds[1][0]
}
// Y1 returns the layer's topmost Y value.
func (a *ArtLayer) Y1() int {
return a.bounds[0][1]
}
// Y2 returns the layer's bottommost y value.
func (a *ArtLayer) Y2() int {
return a.bounds[1][1]
}
func (a *ArtLayer) SetParent(c Group) { func (a *ArtLayer) SetParent(c Group) {
a.parent = c a.parent = c
} }
@@ -137,37 +188,41 @@ func Layer(path string) (ArtLayer, error) {
} }
// SetVisible makes the layer visible. // SetVisible makes the layer visible.
func (a *ArtLayer) SetVisible() { func (a *ArtLayer) SetVisible(b bool) {
js := JSLayer(a.Path()) + fmt.Sprintf(".visible=%s;", true) js := fmt.Sprintf("%s.visible=%v;",
strings.TrimRight(JSLayer(a.Path()), ";"), b)
log.Printf("Setting %s.Visible to %v\n", a.name, b)
DoJs("compilejs.jsx", js) DoJs("compilejs.jsx", js)
} }
// Position moves the layer to pos(x, y), measuring from // Visible returns whether or not the layer is currently hidden.
// the top or bottom left-hand corner. func (a *ArtLayer) Visible() bool {
return a.visible
}
// SetPos snaps the given layer boundry to the given point.
// Valid options for bound are: TL, TR, BL, BR
// TODO: Improve // TODO: Improve
func (a *ArtLayer) Position(x, y int, align string) { func (a *ArtLayer) SetPos(x, y int, bound string) {
var lyrX, lyrY int var lyrX, lyrY int
lyrX = a.Bounds[0][0] lyrX = a.X1()
if align != "bottom" { if bound != "TL" {
lyrY = a.Bounds[0][1] lyrY = a.Y2()
} else { } else { // "BL"
lyrY = a.Bounds[1][1] lyrY = a.Y1()
} }
byt, err := DoJs("moveLayer.jsx", JSLayer(a.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY)) byt, err := DoJs("moveLayer.jsx", JSLayer(a.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY))
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println("byte", string(byt))
fmt.Println("bounds", a.Bounds)
json.Unmarshal(byt, &a) json.Unmarshal(byt, &a)
fmt.Println("after", a.Bounds)
} }
type LayerSet struct { type LayerSet struct {
name string name string
parent Group parent Group
ArtLayers []*ArtLayer artLayers []*ArtLayer
LayerSets []*LayerSet layerSets []*LayerSet
} }
type LayerSetJSON struct { type LayerSetJSON struct {
@@ -184,8 +239,8 @@ func (l *LayerSet) UnmarshalJSON(b []byte) error {
} }
l.name = tmp.Name l.name = tmp.Name
l.parent = tmp.Parent l.parent = tmp.Parent
l.ArtLayers = tmp.ArtLayers l.artLayers = tmp.ArtLayers
l.LayerSets = tmp.LayerSets l.layerSets = tmp.LayerSets
return nil return nil
} }
@@ -193,12 +248,34 @@ func (l *LayerSet) Name() string {
return l.name return l.name
} }
func (l *LayerSet) GetArtLayers() []*ArtLayer { func (l *LayerSet) ArtLayers() []*ArtLayer {
return l.ArtLayers return l.artLayers
} }
func (l *LayerSet) GetLayerSets() []*LayerSet { // ArtLayer returns the first top level ArtLayer matching
return l.LayerSets // the given name.
func (l *LayerSet) ArtLayer(name string) *ArtLayer {
for _, lyr := range l.artLayers {
if lyr.name == name {
return lyr
}
}
return nil
}
func (l *LayerSet) LayerSets() []*LayerSet {
return l.layerSets
}
// LayerSet returns the first top level LayerSet matching
// the given name.
func (l *LayerSet) LayerSet(name string) *LayerSet {
for _, set := range l.layerSets {
if set.name == name {
return set
}
}
return nil
} }
func (l *LayerSet) SetParent(c Group) { func (l *LayerSet) SetParent(c Group) {
@@ -216,32 +293,35 @@ func (l *LayerSet) Path() string {
return fmt.Sprintf("%s%s/", l.parent.Path(), l.name) return fmt.Sprintf("%s%s/", l.parent.Path(), l.name)
} }
func NewLayerSet(path string) (*LayerSet, error) { func NewLayerSet(path string, g Group) (*LayerSet, error) {
byt, err := DoJs("getLayerSet.jsx", JSLayer(path)) byt, err := DoJs("getLayerSet.jsx", JSLayer(path))
// fmt.Println(string(byt))
var out *LayerSet var out *LayerSet
err = json.Unmarshal(byt, &out) err = json.Unmarshal(byt, &out)
if flag.Lookup("test.v") != nil {
// log.Println(string(byt))
}
out.SetParent(g)
log.Printf("Loading ActiveDocument/%s\n", out.Path())
if err != nil { if err != nil {
return &LayerSet{}, err return &LayerSet{}, err
} }
for _, lyr := range out.ArtLayers { for _, lyr := range out.artLayers {
lyr.SetParent(out) lyr.SetParent(out)
} }
for i, set := range out.LayerSets { for i, set := range out.layerSets {
s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name())) // log.Println("\t", set.name)
s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name()), out)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
out.LayerSets[i] = s out.layerSets[i] = s
s.SetParent(out) s.SetParent(out)
} }
return out, err return out, err
} }
// SetVisible makes the LayerSet visible. // SetVisible makes the LayerSet visible.
func (s *LayerSet) SetVisible(b bool) { func (l *LayerSet) SetVisible(b bool) {
fmt.Println(s.Path()) js := fmt.Sprintf("%s%v", JSLayer(strings.TrimRight(l.Path(), ";")), b)
fmt.Println(JSLayer(s.Path()))
js := JSLayer(strings.TrimRight(s.Path(), ";") + fmt.Sprintf(".visible=%v;", b))
DoJs("compilejs.jsx", js) DoJs("compilejs.jsx", js)
} }