diff --git a/ps.go b/ps.go index 8ad1195..97dd44f 100644 --- a/ps.go +++ b/ps.go @@ -181,7 +181,9 @@ func ApplyDataset(name string) ([]byte, error) { // JSLayer retrurns javascript code to get the layer with a given path. func JSLayer(path string) string { + path = strings.TrimLeft(path, "/") pth := strings.Split(path, "/") + // fmt.Println(path) js := "app.activeDocument" last := len(pth) - 1 if last > 0 { diff --git a/ps_test.go b/ps_test.go index 4c6ce68..55808f3 100644 --- a/ps_test.go +++ b/ps_test.go @@ -2,11 +2,12 @@ package ps import ( "fmt" - "os" - "path/filepath" + // "os" + // "path/filepath" "testing" ) +/* func TestPkgPath(t *testing.T) { out := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "sbrow", "ps") if filepath.Join(pkgpath) != out { @@ -21,7 +22,6 @@ func TestStart(t *testing.T) { } } -/* func TestOpen(t *testing.T) { if testing.Short() { t.Skip("Skipping \"TestOpen\"") @@ -31,8 +31,7 @@ func TestOpen(t *testing.T) { t.Fatal(err) } } -*/ -/* + func TestClose(t *testing.T) { if testing.Short() { t.Skip("Skipping \"TestClose\"") @@ -107,81 +106,55 @@ func TestSaveAs(t *testing.T) { } } -func TestLayers(t *testing.T) { - l, err := Layers("Areas/TitleBackground/") - fmt.Println(l) +func TestLayerSet(t *testing.T) { + _, err := NewLayerSet("Areas/TitleBackground/") if err != nil { t.Fatal(err) } } -*/ -/* + func TestLayer(t *testing.T) { _, err := Layer("Border/Inner Border") if err != nil { t.Fatal(err) } -}*/ +} -/*func TestMove(t *testing.T) { + +func TestMove(t *testing.T) { lyr, err := Layer("Group 1/Layer 1") if err != nil { t.Fatal(err) } lyr.Position(100, 50, "top") -}*/ - -/* -func TestLayerSet(t *testing.T) { - set, err := GetLayerSet("Indicators/") - fmt.Println(set) - fmt.Println(set.ArtLayers[0].Parent) - if err != nil { - t.Fatal(err) - } } */ - -func TestDocument(t *testing.T) { - d, err := GetDocument() - fmt.Println(d) - fmt.Println(d.ArtLayers[0]) - fmt.Println(d.ArtLayers[0].Parent) - fmt.Println(d.LayerSets[0]) - fmt.Println(d.LayerSets[0].Parent) - fmt.Println(d.LayerSets[0].ArtLayers[0]) - fmt.Println(d.LayerSets[0].ArtLayers[0].Parent) - fmt.Println(d.LayerSets[0].ArtLayers[0].Parent.Parent()) +func TestActiveDocument(t *testing.T) { + if testing.Short() { + t.Skip("Skipping \"TestDocument\"") + } + d, err := ActiveDocument() if err != nil { t.Fatal(err) } - if d != d.ArtLayers[0].Parent { - t.Fatal("Fucked") + if d != d.ArtLayers[0].Parent() { + fmt.Println(d) + fmt.Println(d.ArtLayers[0].Parent()) + t.Fatal("ArtLayers do not have doc as parent.") } if d != d.LayerSets[0].Parent() { - t.Fatal("Fucked") + fmt.Println(d) + fmt.Println(d.LayerSets[0].Parent()) + t.Fatal("LayerSets do not have doc as parent.") } - if d.LayerSets[0] != d.LayerSets[0].ArtLayers[0].Parent { - t.Fatal("Fucked") - } - -} - -/*func TestActiveDocument(t *testing.T) { - e, err := DoJs("compilejs.jsx", "alert('testing!')") - fmt.Println(string(e)) - if err != nil { - t.Fatal(err) - } - doc, err := ActiveDocument() - fmt.Println(doc) - if err != nil { - t.Fatal(err) + if d.LayerSets[0] != d.LayerSets[0].ArtLayers[0].Parent() { + fmt.Println(d.LayerSets[0]) + fmt.Println(d.LayerSets[0].ArtLayers[0]) + fmt.Println(d.LayerSets[0].ArtLayers[0].Parent()) + t.Fatal("Layerset's ArtLayers do not have correct parents") } } -*/ -/* func TestApplyDataset(t *testing.T) { out := []byte("done!\r\n") ret, err := ApplyDataset("Anger") @@ -197,14 +170,26 @@ func TestApplyDataset(t *testing.T) { t.Fatal(err) } } -*/ - -/*func TestDoJs_HideLayer(t *testing.T) { - _, err := DoJs("setLayerVisibility.jsx", "Areas/TitleBackground", "false") +func TestDoJs_HideLayer(t *testing.T) { + err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd") if err != nil { t.Fatal(err) } -}*/ + lyr, err := NewLayerSet("Areas/TitleBackground") + lyr.SetVisible(false) + if err != nil { + t.Fatal(err) + } +} + +func BenchmarkDoc_Go(b *testing.B) { + for i := 0; i < b.N; i++ { + _, err := ActiveDocument() + if err != nil { + b.Fatal(err) + } + } +} //.8s //.15 diff --git a/scripts/getActiveDoc.jsx b/scripts/getActiveDoc.jsx index 465d260..b473248 100644 --- a/scripts/getActiveDoc.jsx +++ b/scripts/getActiveDoc.jsx @@ -24,11 +24,7 @@ function lyrSets(sets, nm) { for (var i = 0; i < sets.length; i++) { var set = sets[i]; var name = nm + set.name + "/"; - stdout.write('{"Name": "' + set.name + '", "LayerSets": ['); - // lyrSets(set.layerSets, name); - stdout.write('], "ArtLayers": ['); - layers(set.artLayers); - stdout.write(']}'); + stdout.write('{"Name": "' + set.name + '"}'); if (i+1 != sets.length) stdout.write(','); } diff --git a/scripts/getActiveDocument.jsx b/scripts/getActiveDocument.jsx deleted file mode 100644 index 9e2cb41..0000000 --- a/scripts/getActiveDocument.jsx +++ /dev/null @@ -1,50 +0,0 @@ -#include lib.js - -var stdout = newFile(arguments[0]); -var doc = app.activeDocument; - -stdout.write(('{"Name": "' + doc.name +'", "Height":' +doc.height + - ', "Width":' + doc.width + ", ").replace(/ px/g, "")); - -function layersNsets(obj) { - stdout.write('"ArtLayers": ['); - lyrss(obj.artLayers, "") - stdout.write('], "LayerSets": ['); - lyrSets(obj.layerSets, ""); - // stdout.write('], "LayerSets": ['); -} - -function lyrss(lyrs, set) { - if (typeof lyrs === 'undefined') - return; - for (var i = 0; i < lyrs.length; i++) { - var lyr = lyrs[i]; - stdout.write(('{"Name":"' + lyr.name + '", "Bounds": [[' + lyr.bounds[0] + ',' + - lyr.bounds[1] + '],[' + lyr.bounds[2] + ',' + - lyr.bounds[3] + ']], "Path": "' + set + - '", "Visible": ' + lyr.visible + '}').replace(/ px/g, "")); - if (i+1 != lyrs.length) - stdout.write(','); - } -} -function lyrSets(sets, nm) { - if (typeof sets === 'undefined') - return; - for (var i = 0; i < sets.length; i++) { - var set = sets[i]; - var name = nm + set.name + "/"; - stdout.write('{"Name": "' + set.name + '", "LayerSets": ['); - lyrSets(set.layerSets, name); - stdout.write('], "Layers": ['); - lyrss(set.artLayers, name); - stdout.write(']}'); - if (i+1 != sets.length) - stdout.write(','); - } -} - -layersNsets(doc) -stdout.writeln(']}'); - -alert(doc.layerSets.getByName("Group 2").layerSets.getByName("Group 1").layers.getByName("Layer 1").name) -stdout.close(); \ No newline at end of file diff --git a/scripts/getLayerSet.jsx b/scripts/getLayerSet.jsx index 8e7b361..eaed0b5 100644 --- a/scripts/getLayerSet.jsx +++ b/scripts/getLayerSet.jsx @@ -11,5 +11,12 @@ for (var i = 0; i < set.artLayers.length; i++) { if (i != set.artLayers.length - 1) stdout.writeln(","); } +stdout.write('], "LayerSets": [') +for (var i = 0; i < set.layerSets.length; i++) { + var set = set.layerSets[i]; + stdout.write('{"Name": "'+ set.name +'"}'); + if (i < set.layerSets.length - 1) + stdout.writeln(","); +} stdout.write("]}") stdout.close(); \ No newline at end of file diff --git a/structs.go b/structs.go index f3d3c9d..c6c0e54 100644 --- a/structs.go +++ b/structs.go @@ -3,15 +3,43 @@ package ps import ( "encoding/json" "fmt" + "log" + "strings" ) +// Group represents a Document or LayerSet. type Group interface { + Name() string Parent() Group + SetParent(Group) + Path() string GetArtLayers() []*ArtLayer GetLayerSets() []*LayerSet } +// Document represents a Photoshop document (PSD file). type Document struct { + name string + Height int + Width int + ArtLayers []*ArtLayer + LayerSets []*LayerSet +} + +func (d *Document) UnmarshalJSON(b []byte) error { + tmp := &DocumentJSON{} + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + d.name = tmp.Name + d.Height = tmp.Height + d.Width = tmp.Width + d.ArtLayers = tmp.ArtLayers + d.LayerSets = tmp.LayerSets + return nil +} + +type DocumentJSON struct { Name string Height int Width int @@ -19,6 +47,9 @@ type Document struct { LayerSets []*LayerSet } +func (d *Document) Name() string { + return d.name +} func (d *Document) GetArtLayers() []*ArtLayer { return d.ArtLayers } @@ -30,45 +61,68 @@ func (d *Document) GetLayerSets() []*LayerSet { func (d *Document) Parent() Group { return nil } +func (d *Document) SetParent(g Group) {} -// ActiveDocument returns a Document object from Photoshop's active document. -func ActiveDocument() (Document, error) { - byt, err := DoJs("getActiveDocument.jsx") - var d Document - err = json.Unmarshal(byt, &d) - fmt.Println(string(byt)) - return d, err +func (d *Document) Path() string { + return "" } -func GetDocument() (*Document, error) { +func ActiveDocument() (*Document, error) { byt, err := DoJs("getActiveDoc.jsx") var d *Document err = json.Unmarshal(byt, &d) for _, lyr := range d.ArtLayers { - lyr.Parent = d + lyr.SetParent(d) } - for _, set := range d.LayerSets { - set.parent = d - for _, lyr := range set.ArtLayers { - lyr.Parent = set + for i, set := range d.LayerSets { + s, err := NewLayerSet(set.Path() + "/") + if err != nil { + log.Fatal(err) } + d.LayerSets[i] = s + s.SetParent(d) } - fmt.Println(string(byt)) return d, err } type ArtLayer struct { - Name string + name string // TextItem string Bounds [2][2]int - Parent Group - Path string + parent Group Visiblity bool } -// func (a *ArtLayer) setParent(c Group) { -// ArtLayer.Parent = c -// } +type ArtLayerJSON struct { + Name string + Bounds [2][2]int + Parent Group + Visible bool +} + +func (a *ArtLayer) UnmarshalJSON(b []byte) error { + tmp := &ArtLayerJSON{} + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + a.name = tmp.Name + a.Bounds = tmp.Bounds + a.parent = tmp.Parent + a.Visiblity = tmp.Visible + return nil +} + +func (a *ArtLayer) SetParent(c Group) { + a.parent = c +} + +func (a *ArtLayer) Parent() Group { + return a.parent +} + +func (a *ArtLayer) Path() string { + return fmt.Sprintf("%s%s", a.parent.Path(), a.name) +} // Layer returns an ArtLayer from the active document given a specified // path string. @@ -79,13 +133,12 @@ func Layer(path string) (ArtLayer, error) { if err != nil { return ArtLayer{}, err } - out.Path = path return out, err } // SetVisible makes the layer visible. func (a *ArtLayer) SetVisible() { - js := JSLayer(a.Path) + fmt.Sprintf(".visible=%s;", true) + js := JSLayer(a.Path()) + fmt.Sprintf(".visible=%s;", true) DoJs("compilejs.jsx", js) } @@ -100,7 +153,7 @@ func (a *ArtLayer) Position(x, y int, align string) { } else { lyrY = a.Bounds[1][1] } - 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 { panic(err) } @@ -111,12 +164,35 @@ func (a *ArtLayer) Position(x, y int, align string) { } type LayerSet struct { - Name string + name string parent Group ArtLayers []*ArtLayer LayerSets []*LayerSet } +type LayerSetJSON struct { + Name string + Parent Group + ArtLayers []*ArtLayer + LayerSets []*LayerSet +} + +func (l *LayerSet) UnmarshalJSON(b []byte) error { + tmp := &LayerSetJSON{} + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + l.name = tmp.Name + l.parent = tmp.Parent + l.ArtLayers = tmp.ArtLayers + l.LayerSets = tmp.LayerSets + return nil +} + +func (l *LayerSet) Name() string { + return l.name +} + func (l *LayerSet) GetArtLayers() []*ArtLayer { return l.ArtLayers } @@ -125,20 +201,47 @@ func (l *LayerSet) GetLayerSets() []*LayerSet { return l.LayerSets } +func (l *LayerSet) SetParent(c Group) { + l.parent = c +} + func (l *LayerSet) Parent() Group { return l.parent } -func GetLayerSet(path string) (LayerSet, error) { +func (l *LayerSet) Path() string { + if l.parent == nil { + return l.name + } + return fmt.Sprintf("%s%s/", l.parent.Path(), l.name) +} + +func NewLayerSet(path string) (*LayerSet, error) { byt, err := DoJs("getLayerSet.jsx", JSLayer(path)) - var out LayerSet - fmt.Println(string(byt)) // TODO: Debug + // fmt.Println(string(byt)) + var out *LayerSet err = json.Unmarshal(byt, &out) if err != nil { - return LayerSet{}, err + return &LayerSet{}, err } for _, lyr := range out.ArtLayers { - lyr.Parent = &out + lyr.SetParent(out) + } + for i, set := range out.LayerSets { + s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name())) + if err != nil { + log.Fatal(err) + } + out.LayerSets[i] = s + s.SetParent(out) } return out, err } + +// SetVisible makes the LayerSet visible. +func (s *LayerSet) SetVisible(b bool) { + fmt.Println(s.Path()) + fmt.Println(JSLayer(s.Path())) + js := JSLayer(strings.TrimRight(s.Path(), ";") + fmt.Sprintf(".visible=%v;", b)) + DoJs("compilejs.jsx", js) +}