mirror of
https://github.com/sbrow/ps.git
synced 2025-12-29 18:47:38 -05:00
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:
59
ps_test.go
59
ps_test.go
@@ -2,12 +2,11 @@ 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 {
|
||||
@@ -23,9 +22,9 @@ func TestStart(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOpen(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping \"TestOpen\"")
|
||||
}
|
||||
// if testing.Short() {
|
||||
// t.Skip("Skipping \"TestOpen\"")
|
||||
// }
|
||||
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -82,6 +81,9 @@ func TestWait(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")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -93,6 +95,9 @@ func TestDoAction_Crop(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoAction_Undo(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping \"TestDoAction_Undo\"")
|
||||
}
|
||||
err := DoAction("DK", "Undo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -104,8 +109,10 @@ func TestSaveAs(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Remove("F:\\TEMP\\test.png")
|
||||
}
|
||||
|
||||
/*
|
||||
func TestLayerSet(t *testing.T) {
|
||||
_, err := NewLayerSet("Areas/TitleBackground/")
|
||||
if err != nil {
|
||||
@@ -120,7 +127,6 @@ func TestLayer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestMove(t *testing.T) {
|
||||
lyr, err := Layer("Group 1/Layer 1")
|
||||
if err != nil {
|
||||
@@ -137,27 +143,27 @@ func TestActiveDocument(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if d != d.ArtLayers[0].Parent() {
|
||||
if d != d.artLayers[0].Parent() {
|
||||
fmt.Println(d)
|
||||
fmt.Println(d.ArtLayers[0].Parent())
|
||||
fmt.Println(d.artLayers[0].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.LayerSets[0].Parent())
|
||||
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() {
|
||||
fmt.Println(d.LayerSets[0])
|
||||
fmt.Println(d.LayerSets[0].ArtLayers[0])
|
||||
fmt.Println(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].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")
|
||||
ret, err := ApplyDataset(" Anger")
|
||||
if err != nil {
|
||||
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)
|
||||
t.Fatal(fail)
|
||||
}
|
||||
err = Quit(2)
|
||||
}
|
||||
|
||||
func TestDocumentLayerSet(t *testing.T) {
|
||||
d, err := ActiveDocument()
|
||||
if err != nil {
|
||||
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) {
|
||||
err := Open("F:\\GitLab\\dreamkeepers-psd\\Template009.1.psd")
|
||||
if err != nil {
|
||||
@@ -181,7 +204,7 @@ func TestDoJs_HideLayer(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
func BenchmarkDoc_Go(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := ActiveDocument()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include lib.js
|
||||
var stdout = newFile(arguments[0]);
|
||||
var doc = app.activeDocument;
|
||||
stdout.writeln(('{"Name": "' + doc.name +'", "Height":' +doc.height +
|
||||
', "Width":' + doc.width + ', "ArtLayers": [').replace(/ px/g, ""));
|
||||
stdout.writeln(('{"Name": "'+doc.name+'", "Height":'+doc.height+
|
||||
', "Width":'+doc.width+', "ArtLayers": [').replace(/ px/g, ""));
|
||||
function layers(lyrs) {
|
||||
if (typeof lyrs === 'undefined')
|
||||
return;
|
||||
|
||||
@@ -13,8 +13,8 @@ for (var i = 0; i < set.artLayers.length; i++) {
|
||||
}
|
||||
stdout.write('], "LayerSets": [')
|
||||
for (var i = 0; i < set.layerSets.length; i++) {
|
||||
var set = set.layerSets[i];
|
||||
stdout.write('{"Name": "'+ set.name +'"}');
|
||||
var s = set.layerSets[i];
|
||||
stdout.write('{"Name": "'+ s.name +'"}');
|
||||
if (i < set.layerSets.length - 1)
|
||||
stdout.writeln(",");
|
||||
}
|
||||
|
||||
196
structs.go
196
structs.go
@@ -2,6 +2,7 @@ package ps
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
@@ -13,13 +14,21 @@ type Group interface {
|
||||
Parent() Group
|
||||
SetParent(Group)
|
||||
Path() string
|
||||
GetArtLayers() []*ArtLayer
|
||||
GetLayerSets() []*LayerSet
|
||||
ArtLayers() []*ArtLayer
|
||||
LayerSets() []*LayerSet
|
||||
}
|
||||
|
||||
// Document represents a Photoshop document (PSD file).
|
||||
type Document struct {
|
||||
name string
|
||||
height int
|
||||
width int
|
||||
artLayers []*ArtLayer
|
||||
layerSets []*LayerSet
|
||||
}
|
||||
|
||||
type DocumentJSON struct {
|
||||
Name string
|
||||
Height int
|
||||
Width int
|
||||
ArtLayers []*ArtLayer
|
||||
@@ -32,30 +41,42 @@ func (d *Document) UnmarshalJSON(b []byte) error {
|
||||
return err
|
||||
}
|
||||
d.name = tmp.Name
|
||||
d.Height = tmp.Height
|
||||
d.Width = tmp.Width
|
||||
d.ArtLayers = tmp.ArtLayers
|
||||
d.LayerSets = tmp.LayerSets
|
||||
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
|
||||
ArtLayers []*ArtLayer
|
||||
LayerSets []*LayerSet
|
||||
}
|
||||
|
||||
// Name returns the document's title.
|
||||
// This fufills the Group interface.
|
||||
func (d *Document) Name() string {
|
||||
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 {
|
||||
return d.LayerSets
|
||||
func (d *Document) ArtLayers() []*ArtLayer {
|
||||
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 {
|
||||
@@ -68,29 +89,31 @@ func (d *Document) Path() string {
|
||||
}
|
||||
|
||||
func ActiveDocument() (*Document, error) {
|
||||
log.Println("Loading ActiveDoucment/")
|
||||
byt, err := DoJs("getActiveDoc.jsx")
|
||||
var d *Document
|
||||
err = json.Unmarshal(byt, &d)
|
||||
for _, lyr := range d.ArtLayers {
|
||||
for _, lyr := range d.artLayers {
|
||||
lyr.SetParent(d)
|
||||
}
|
||||
for i, set := range d.LayerSets {
|
||||
s, err := NewLayerSet(set.Path() + "/")
|
||||
for i, set := range d.layerSets {
|
||||
s, err := NewLayerSet(set.Path()+"/", d)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
d.LayerSets[i] = s
|
||||
s.SetParent(d)
|
||||
d.layerSets[i] = s
|
||||
// s.SetParent(d)
|
||||
}
|
||||
return d, err
|
||||
}
|
||||
|
||||
// ArtLayer represents an Art Layer in a photoshop document.
|
||||
type ArtLayer struct {
|
||||
name string
|
||||
// TextItem string
|
||||
Bounds [2][2]int
|
||||
bounds [2][2]int
|
||||
parent Group
|
||||
Visiblity bool
|
||||
visible bool
|
||||
}
|
||||
|
||||
type ArtLayerJSON struct {
|
||||
@@ -106,12 +129,40 @@ func (a *ArtLayer) UnmarshalJSON(b []byte) error {
|
||||
return err
|
||||
}
|
||||
a.name = tmp.Name
|
||||
a.Bounds = tmp.Bounds
|
||||
a.bounds = tmp.Bounds
|
||||
a.parent = tmp.Parent
|
||||
a.Visiblity = tmp.Visible
|
||||
a.visible = tmp.Visible
|
||||
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) {
|
||||
a.parent = c
|
||||
}
|
||||
@@ -137,37 +188,41 @@ func Layer(path string) (ArtLayer, error) {
|
||||
}
|
||||
|
||||
// SetVisible makes the layer visible.
|
||||
func (a *ArtLayer) SetVisible() {
|
||||
js := JSLayer(a.Path()) + fmt.Sprintf(".visible=%s;", true)
|
||||
func (a *ArtLayer) SetVisible(b bool) {
|
||||
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)
|
||||
}
|
||||
|
||||
// Position moves the layer to pos(x, y), measuring from
|
||||
// the top or bottom left-hand corner.
|
||||
// Visible returns whether or not the layer is currently hidden.
|
||||
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
|
||||
func (a *ArtLayer) Position(x, y int, align string) {
|
||||
func (a *ArtLayer) SetPos(x, y int, bound string) {
|
||||
var lyrX, lyrY int
|
||||
lyrX = a.Bounds[0][0]
|
||||
if align != "bottom" {
|
||||
lyrY = a.Bounds[0][1]
|
||||
} else {
|
||||
lyrY = a.Bounds[1][1]
|
||||
lyrX = a.X1()
|
||||
if bound != "TL" {
|
||||
lyrY = a.Y2()
|
||||
} else { // "BL"
|
||||
lyrY = a.Y1()
|
||||
}
|
||||
byt, err := DoJs("moveLayer.jsx", JSLayer(a.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("byte", string(byt))
|
||||
fmt.Println("bounds", a.Bounds)
|
||||
json.Unmarshal(byt, &a)
|
||||
fmt.Println("after", a.Bounds)
|
||||
}
|
||||
|
||||
type LayerSet struct {
|
||||
name string
|
||||
parent Group
|
||||
ArtLayers []*ArtLayer
|
||||
LayerSets []*LayerSet
|
||||
artLayers []*ArtLayer
|
||||
layerSets []*LayerSet
|
||||
}
|
||||
|
||||
type LayerSetJSON struct {
|
||||
@@ -184,8 +239,8 @@ func (l *LayerSet) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
l.name = tmp.Name
|
||||
l.parent = tmp.Parent
|
||||
l.ArtLayers = tmp.ArtLayers
|
||||
l.LayerSets = tmp.LayerSets
|
||||
l.artLayers = tmp.ArtLayers
|
||||
l.layerSets = tmp.LayerSets
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -193,12 +248,34 @@ func (l *LayerSet) Name() string {
|
||||
return l.name
|
||||
}
|
||||
|
||||
func (l *LayerSet) GetArtLayers() []*ArtLayer {
|
||||
return l.ArtLayers
|
||||
func (l *LayerSet) ArtLayers() []*ArtLayer {
|
||||
return l.artLayers
|
||||
}
|
||||
|
||||
func (l *LayerSet) GetLayerSets() []*LayerSet {
|
||||
return l.LayerSets
|
||||
// ArtLayer returns the first top level ArtLayer matching
|
||||
// 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) {
|
||||
@@ -216,32 +293,35 @@ func (l *LayerSet) Path() string {
|
||||
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))
|
||||
// fmt.Println(string(byt))
|
||||
var out *LayerSet
|
||||
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 {
|
||||
return &LayerSet{}, err
|
||||
}
|
||||
for _, lyr := range out.ArtLayers {
|
||||
for _, lyr := range out.artLayers {
|
||||
lyr.SetParent(out)
|
||||
}
|
||||
for i, set := range out.LayerSets {
|
||||
s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name()))
|
||||
for i, set := range out.layerSets {
|
||||
// log.Println("\t", set.name)
|
||||
s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name()), out)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
out.LayerSets[i] = s
|
||||
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))
|
||||
func (l *LayerSet) SetVisible(b bool) {
|
||||
js := fmt.Sprintf("%s%v", JSLayer(strings.TrimRight(l.Path(), ";")), b)
|
||||
DoJs("compilejs.jsx", js)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user