mirror of
https://github.com/sbrow/ps.git
synced 2025-12-29 18:47:38 -05:00
Can now save and load from json
Much improved speed over loading everything manually.
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
data/
|
||||||
57
colors.go
Normal file
57
colors.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package ps
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Colors map[string]Color = map[string]Color{
|
||||||
|
"Gray": &RGB{128, 128, 128},
|
||||||
|
"White": &RGB{255, 255, 255},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color represents a color.
|
||||||
|
type Color interface {
|
||||||
|
RGB() [3]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func Compare(a, b Color) Color {
|
||||||
|
A := a.RGB()
|
||||||
|
B := b.RGB()
|
||||||
|
Aavg := (A[0] + A[1] + A[2]) / 3
|
||||||
|
Bavg := (B[0] + B[1] + B[2]) / 3
|
||||||
|
if Aavg > Bavg {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color is a color in RGB format.
|
||||||
|
type RGB struct {
|
||||||
|
Red int
|
||||||
|
Green int
|
||||||
|
Blue int
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGB returns the color in RGB format.
|
||||||
|
func (r RGB) RGB() [3]int {
|
||||||
|
return [3]int{r.Red, r.Green, r.Blue}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex is a color in hexidecimal format.
|
||||||
|
type Hex []uint8
|
||||||
|
|
||||||
|
func (h Hex) RGB() [3]int {
|
||||||
|
src := []byte(h)
|
||||||
|
dst := make([]byte, hex.DecodedLen(len(src)))
|
||||||
|
_, err := hex.Decode(dst, src)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return [3]int{int(dst[0]), int(dst[1]), int(dst[2])}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stroke represents a layer stroke effect.
|
||||||
|
type Stroke struct {
|
||||||
|
Size float32
|
||||||
|
Color
|
||||||
|
}
|
||||||
1
ps.go
1
ps.go
@@ -184,7 +184,6 @@ func ApplyDataset(name string) ([]byte, error) {
|
|||||||
func JSLayer(path string) string {
|
func JSLayer(path string) string {
|
||||||
path = strings.TrimLeft(path, "/")
|
path = strings.TrimLeft(path, "/")
|
||||||
pth := strings.Split(path, "/")
|
pth := strings.Split(path, "/")
|
||||||
// fmt.Println(path)
|
|
||||||
js := "app.activeDocument"
|
js := "app.activeDocument"
|
||||||
last := len(pth) - 1
|
last := len(pth) - 1
|
||||||
if last > 0 {
|
if last > 0 {
|
||||||
|
|||||||
41
ps_test.go
41
ps_test.go
@@ -1,7 +1,9 @@
|
|||||||
package ps
|
package ps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -112,9 +114,8 @@ func TestSaveAs(t *testing.T) {
|
|||||||
os.Remove("F:\\TEMP\\test.png")
|
os.Remove("F:\\TEMP\\test.png")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func TestLayerSet(t *testing.T) {
|
func TestLayerSet(t *testing.T) {
|
||||||
_, err := NewLayerSet("Areas/TitleBackground/")
|
_, err := NewLayerSet("Areas/TitleBackground/", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -132,9 +133,9 @@ func TestMove(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
lyr.Position(100, 50, "top")
|
lyr.SetPos(100, 50, "TL")
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
func TestActiveDocument(t *testing.T) {
|
func TestActiveDocument(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("Skipping \"TestDocument\"")
|
t.Skip("Skipping \"TestDocument\"")
|
||||||
@@ -166,10 +167,8 @@ func TestActiveDocument(t *testing.T) {
|
|||||||
}
|
}
|
||||||
s := Stroke{Size: 4, Color: &RGB{0, 0, 0}}
|
s := Stroke{Size: 4, Color: &RGB{0, 0, 0}}
|
||||||
lyr.SetStroke(s, &RGB{128, 128, 128})
|
lyr.SetStroke(s, &RGB{128, 128, 128})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func TestColor(t *testing.T) {
|
func TestColor(t *testing.T) {
|
||||||
byt, err := run("colorLayer.vbs", "255", "255", "255")
|
byt, err := run("colorLayer.vbs", "255", "255", "255")
|
||||||
fmt.Println(string(byt))
|
fmt.Println(string(byt))
|
||||||
@@ -179,9 +178,7 @@ func TestColor(t *testing.T) {
|
|||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
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")
|
||||||
@@ -215,20 +212,40 @@ func TestDocumentLayerSet(t *testing.T) {
|
|||||||
fmt.Println(lyr.name)
|
fmt.Println(lyr.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/*
|
func TestLoadedDoc(t *testing.T) {
|
||||||
|
var d *Document
|
||||||
|
byt, err := ioutil.ReadFile("Document.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(byt, &d)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if d != d.ArtLayers()[0].Parent() {
|
||||||
|
t.Fatal("Loaded document's ArtLayers do not point to doc")
|
||||||
|
}
|
||||||
|
if d != d.LayerSets()[0].Parent() {
|
||||||
|
t.Fatal("Loaded document's LayerSets do not point to doc")
|
||||||
|
}
|
||||||
|
if d.LayerSets()[0] != d.layerSets[0].artLayers[0].Parent() {
|
||||||
|
t.Fatal("Loaded document's LayerSet's ArtLayers do not point to layerSets")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
lyr, err := NewLayerSet("Areas/TitleBackground")
|
lyr, err := NewLayerSet("Areas/TitleBackground", nil)
|
||||||
lyr.SetVisible(false)
|
lyr.SetVisible(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
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()
|
||||||
|
|||||||
2
scripts/activeDocName.jsx
Normal file
2
scripts/activeDocName.jsx
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#include lib.js
|
||||||
|
var stdout = newFile(arguments[0]);stdout.writeln(app.activeDocument.name);stdout.close();
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
var stdout = newFile(arguments[0]);
|
var stdout = newFile(arguments[0]);
|
||||||
var lyr = eval(arguments[1]);
|
var lyr = eval(arguments[1]);
|
||||||
stdout.writeln(('{"Name":"' + lyr.name + '", "Bounds": [[' + lyr.bounds[0] + ',' +
|
stdout.writeln(('{"Name":"' + lyr.name + '","Bounds":[[' + lyr.bounds[0] + ',' +
|
||||||
lyr.bounds[1] + '],[' + lyr.bounds[2] + ',' +
|
lyr.bounds[1] + '],[' + lyr.bounds[2] + ',' +
|
||||||
lyr.bounds[3] + ']], "Visible": ' + lyr.visible + '}').replace(/ px/g, ""));
|
lyr.bounds[3] + ']],"Visible":' + lyr.visible + '}').replace(/ px/g, ""));
|
||||||
stdout.close();
|
stdout.close();
|
||||||
2
scripts/isVisible.jsx
Normal file
2
scripts/isVisible.jsx
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#include lib.js
|
||||||
|
var stdout = newFile(arguments[0]);stdout.writeln(eval(arguments[1]).visible);stdout.close();
|
||||||
239
structs.go
239
structs.go
@@ -1,65 +1,31 @@
|
|||||||
package ps
|
package ps
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Colors map[string]Color = map[string]Color{
|
type ModeEnum int
|
||||||
"Gray": &RGB{128, 128, 128},
|
|
||||||
"White": &RGB{255, 255, 255},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color represents a color.
|
// Mode determines how aggressively ps will attempt to sync with Photoshop.
|
||||||
type Color interface {
|
var Mode ModeEnum
|
||||||
RGB() [3]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func Compare(a, b Color) Color {
|
// Normal Mode Always checks to see if layers are updated
|
||||||
A := a.RGB()
|
// before returning them.
|
||||||
B := b.RGB()
|
const Normal ModeEnum = 0
|
||||||
Aavg := (A[0] + A[1] + A[2]) / 3
|
|
||||||
Bavg := (B[0] + B[1] + B[2]) / 3
|
|
||||||
if Aavg > Bavg {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color is a color in RGB format.
|
// Safe Mode Always loads the document from scratch. (Slow)
|
||||||
type RGB struct {
|
const Safe ModeEnum = 1
|
||||||
Red int
|
|
||||||
Green int
|
|
||||||
Blue int
|
|
||||||
}
|
|
||||||
|
|
||||||
// RGB returns the color in RGB format.
|
// Fast mode never checks layers before returning.
|
||||||
func (r *RGB) RGB() [3]int {
|
const Fast ModeEnum = 2
|
||||||
return [3]int{r.Red, r.Green, r.Blue}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hex is a color in hexidecimal format.
|
|
||||||
type Hex []uint8
|
|
||||||
|
|
||||||
func (h Hex) RGB() [3]int {
|
|
||||||
src := []byte(h)
|
|
||||||
dst := make([]byte, hex.DecodedLen(len(src)))
|
|
||||||
_, err := hex.Decode(dst, src)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return [3]int{int(dst[0]), int(dst[1]), int(dst[2])}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stroke represents a layer stroke effect.
|
|
||||||
type Stroke struct {
|
|
||||||
Size float32
|
|
||||||
Color
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group represents a Document or LayerSet.
|
// Group represents a Document or LayerSet.
|
||||||
type Group interface {
|
type Group interface {
|
||||||
@@ -69,6 +35,8 @@ type Group interface {
|
|||||||
Path() string
|
Path() string
|
||||||
ArtLayers() []*ArtLayer
|
ArtLayers() []*ArtLayer
|
||||||
LayerSets() []*LayerSet
|
LayerSets() []*LayerSet
|
||||||
|
MarshalJSON() ([]byte, error)
|
||||||
|
UnmarshalJSON(b []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Document represents a Photoshop document (PSD file).
|
// Document represents a Photoshop document (PSD file).
|
||||||
@@ -88,6 +56,11 @@ type DocumentJSON struct {
|
|||||||
LayerSets []*LayerSet
|
LayerSets []*LayerSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Document) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(&DocumentJSON{Name: d.name, Height: d.height,
|
||||||
|
Width: d.width, ArtLayers: d.artLayers, LayerSets: d.layerSets})
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Document) UnmarshalJSON(b []byte) error {
|
func (d *Document) UnmarshalJSON(b []byte) error {
|
||||||
tmp := &DocumentJSON{}
|
tmp := &DocumentJSON{}
|
||||||
if err := json.Unmarshal(b, &tmp); err != nil {
|
if err := json.Unmarshal(b, &tmp); err != nil {
|
||||||
@@ -97,7 +70,13 @@ func (d *Document) UnmarshalJSON(b []byte) error {
|
|||||||
d.height = tmp.Height
|
d.height = tmp.Height
|
||||||
d.width = tmp.Width
|
d.width = tmp.Width
|
||||||
d.artLayers = tmp.ArtLayers
|
d.artLayers = tmp.ArtLayers
|
||||||
|
for _, lyr := range d.artLayers {
|
||||||
|
lyr.SetParent(d)
|
||||||
|
}
|
||||||
d.layerSets = tmp.LayerSets
|
d.layerSets = tmp.LayerSets
|
||||||
|
for _, set := range d.layerSets {
|
||||||
|
set.SetParent(d)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,10 +120,37 @@ func (d *Document) Path() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filename returns the path to the json file for this document.
|
||||||
|
func (d *Document) Filename() string {
|
||||||
|
_, dir, _, ok := runtime.Caller(0)
|
||||||
|
if !ok {
|
||||||
|
log.Panic("No caller information")
|
||||||
|
}
|
||||||
|
return filepath.Join(filepath.Dir(dir), "data",
|
||||||
|
strings.TrimRight(string(d.name), "\r\n")+".txt")
|
||||||
|
}
|
||||||
|
|
||||||
func ActiveDocument() (*Document, error) {
|
func ActiveDocument() (*Document, error) {
|
||||||
log.Println("Loading ActiveDoucment/")
|
log.Println("Loading ActiveDoucment")
|
||||||
byt, err := DoJs("getActiveDoc.jsx")
|
d := &Document{}
|
||||||
var d *Document
|
|
||||||
|
byt, err := DoJs("activeDocName.jsx")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
d.name = string(byt)
|
||||||
|
if Mode != 1 {
|
||||||
|
byt, err = ioutil.ReadFile(d.Filename())
|
||||||
|
if err == nil {
|
||||||
|
log.Println("Previous version found, loading")
|
||||||
|
err = json.Unmarshal(byt, &d)
|
||||||
|
if err == nil {
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Loading manually (This could take awhile)")
|
||||||
|
byt, err = DoJs("getActiveDoc.jsx")
|
||||||
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)
|
||||||
@@ -155,27 +161,55 @@ func ActiveDocument() (*Document, error) {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
d.layerSets[i] = s
|
d.layerSets[i] = s
|
||||||
// s.SetParent(d)
|
s.SetParent(d)
|
||||||
}
|
}
|
||||||
|
d.Dump()
|
||||||
return d, err
|
return d, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Document) Dump() {
|
||||||
|
f, err := os.Create(d.Filename())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
byt, err := json.MarshalIndent(d, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
f.Write(byt)
|
||||||
|
}
|
||||||
|
|
||||||
// ArtLayer represents an Art Layer in a photoshop document.
|
// ArtLayer represents an Art Layer in a photoshop document.
|
||||||
type ArtLayer struct {
|
type ArtLayer struct {
|
||||||
name string
|
name string // The layer's name.
|
||||||
// TextItem string
|
// TextItem string
|
||||||
bounds [2][2]int
|
bounds [2][2]int // The layers' corners.
|
||||||
parent Group
|
parent Group // The LayerSet/Document this layer is in.
|
||||||
visible bool
|
visible bool // Whether or not the layer is visible.
|
||||||
Color
|
current bool // Whether we've checked this layer since we loaded from disk.
|
||||||
*Stroke
|
Color // The layer's color overlay.
|
||||||
|
*Stroke // The layer's stroke.
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArtLayerJSON struct {
|
type ArtLayerJSON struct {
|
||||||
Name string
|
Name string
|
||||||
Bounds [2][2]int
|
Bounds [2][2]int
|
||||||
Parent Group
|
|
||||||
Visible bool
|
Visible bool
|
||||||
|
Color [3]int
|
||||||
|
Stroke [3]int
|
||||||
|
StrokeAmt float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ArtLayer) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(&ArtLayerJSON{
|
||||||
|
Name: a.name,
|
||||||
|
Bounds: a.bounds,
|
||||||
|
Visible: a.visible,
|
||||||
|
Color: a.Color.RGB(),
|
||||||
|
Stroke: a.Stroke.RGB(),
|
||||||
|
StrokeAmt: a.Stroke.Size,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtLayer) UnmarshalJSON(b []byte) error {
|
func (a *ArtLayer) UnmarshalJSON(b []byte) error {
|
||||||
@@ -185,8 +219,10 @@ func (a *ArtLayer) UnmarshalJSON(b []byte) error {
|
|||||||
}
|
}
|
||||||
a.name = tmp.Name
|
a.name = tmp.Name
|
||||||
a.bounds = tmp.Bounds
|
a.bounds = tmp.Bounds
|
||||||
a.parent = tmp.Parent
|
a.Color = RGB{tmp.Color[0], tmp.Color[1], tmp.Color[2]}
|
||||||
|
a.Stroke = &Stroke{tmp.StrokeAmt, RGB{tmp.Stroke[0], tmp.Stroke[1], tmp.Stroke[2]}}
|
||||||
a.visible = tmp.Visible
|
a.visible = tmp.Visible
|
||||||
|
a.current = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,20 +267,25 @@ func (a *ArtLayer) SetActive() ([]byte, error) {
|
|||||||
|
|
||||||
// SetColor creates a color overlay for the layer
|
// SetColor creates a color overlay for the layer
|
||||||
func (a *ArtLayer) SetColor(c Color) {
|
func (a *ArtLayer) SetColor(c Color) {
|
||||||
|
if Mode == 2 && a.Color.RGB() == c.RGB() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if a.Stroke.Size != 0 {
|
||||||
|
a.SetStroke(*a.Stroke, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
a.Color = c
|
a.Color = c
|
||||||
cols := c.RGB()
|
cols := a.Color.RGB()
|
||||||
|
log.Printf(`Setting layer "%s" to color %v`, a.name, cols)
|
||||||
r := cols[0]
|
r := cols[0]
|
||||||
g := cols[1]
|
g := cols[1]
|
||||||
b := cols[2]
|
b := cols[2]
|
||||||
if a.Stroke != nil {
|
|
||||||
a.SetStroke(Stroke{a.Stroke.Size, a.Stroke.Color}, a.Color)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
byt, err := a.SetActive()
|
byt, err := a.SetActive()
|
||||||
if len(byt) != 0 {
|
if len(byt) != 0 {
|
||||||
log.Println(string(byt), "err")
|
log.Println(string(byt), "err")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(a.Path())
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
byt, err = run("colorLayer", fmt.Sprint(r), fmt.Sprint(g), fmt.Sprint(b))
|
byt, err = run("colorLayer", fmt.Sprint(r), fmt.Sprint(g), fmt.Sprint(b))
|
||||||
@@ -257,6 +298,13 @@ func (a *ArtLayer) SetColor(c Color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtLayer) SetStroke(stk Stroke, fill Color) {
|
func (a *ArtLayer) SetStroke(stk Stroke, fill Color) {
|
||||||
|
if Mode == 2 {
|
||||||
|
if stk.Size == a.Stroke.Size && stk.Color.RGB() == a.Color.RGB() {
|
||||||
|
if a.Color.RGB() == fill.RGB() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
byt, err := a.SetActive()
|
byt, err := a.SetActive()
|
||||||
if len(byt) != 0 {
|
if len(byt) != 0 {
|
||||||
log.Println(string(byt))
|
log.Println(string(byt))
|
||||||
@@ -264,8 +312,12 @@ func (a *ArtLayer) SetStroke(stk Stroke, fill Color) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
a.Stroke = &stk
|
||||||
|
a.Color = fill
|
||||||
stkCol := stk.Color.RGB()
|
stkCol := stk.Color.RGB()
|
||||||
col := fill.RGB()
|
col := fill.RGB()
|
||||||
|
log.Printf("Setting layer %s stroke to %.2fpt %v and color to %v\n", a.name, a.Stroke.Size,
|
||||||
|
a.Stroke.Color.RGB(), a.Color.RGB())
|
||||||
byt, err = run("colorStroke", fmt.Sprint(col[0]), fmt.Sprint(col[1]), fmt.Sprint(col[2]),
|
byt, err = run("colorStroke", fmt.Sprint(col[0]), fmt.Sprint(col[1]), fmt.Sprint(col[2]),
|
||||||
fmt.Sprintf("%.2f", stk.Size), fmt.Sprint(stkCol[0]), fmt.Sprint(stkCol[1]), fmt.Sprint(stkCol[2]))
|
fmt.Sprintf("%.2f", stk.Size), fmt.Sprint(stkCol[0]), fmt.Sprint(stkCol[1]), fmt.Sprint(stkCol[2]))
|
||||||
if len(byt) != 0 {
|
if len(byt) != 0 {
|
||||||
@@ -274,7 +326,6 @@ func (a *ArtLayer) SetStroke(stk Stroke, fill Color) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ArtLayer) Parent() Group {
|
func (a *ArtLayer) Parent() Group {
|
||||||
@@ -299,9 +350,16 @@ func Layer(path string) (ArtLayer, error) {
|
|||||||
|
|
||||||
// SetVisible makes the layer visible.
|
// SetVisible makes the layer visible.
|
||||||
func (a *ArtLayer) SetVisible(b bool) {
|
func (a *ArtLayer) SetVisible(b bool) {
|
||||||
|
if a.Visible() == b {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if b {
|
||||||
|
log.Printf("Showing %s", a.name)
|
||||||
|
} else {
|
||||||
|
log.Printf("Hiding %s", a.name)
|
||||||
|
}
|
||||||
js := fmt.Sprintf("%s.visible=%v;",
|
js := fmt.Sprintf("%s.visible=%v;",
|
||||||
strings.TrimRight(JSLayer(a.Path()), ";"), b)
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,6 +372,9 @@ func (a *ArtLayer) Visible() bool {
|
|||||||
// Valid options for bound are: TL, TR, BL, BR
|
// Valid options for bound are: TL, TR, BL, BR
|
||||||
// TODO: Improve
|
// TODO: Improve
|
||||||
func (a *ArtLayer) SetPos(x, y int, bound string) {
|
func (a *ArtLayer) SetPos(x, y int, bound string) {
|
||||||
|
if x == 0 && y == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
if !a.visible {
|
if !a.visible {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -326,35 +387,51 @@ func (a *ArtLayer) SetPos(x, y int, bound string) {
|
|||||||
lyrY = a.Y1()
|
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))
|
||||||
|
var bounds [2][2]int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
json.Unmarshal(byt, &a)
|
json.Unmarshal(byt, bounds)
|
||||||
|
a.bounds = bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
type LayerSet struct {
|
type LayerSet struct {
|
||||||
name string
|
name string
|
||||||
parent Group
|
parent Group
|
||||||
|
current bool // Whether we've checked this layer since we loaded from disk.
|
||||||
artLayers []*ArtLayer
|
artLayers []*ArtLayer
|
||||||
layerSets []*LayerSet
|
layerSets []*LayerSet
|
||||||
}
|
}
|
||||||
|
|
||||||
type LayerSetJSON struct {
|
type LayerSetJSON struct {
|
||||||
Name string
|
Name string
|
||||||
Parent Group
|
|
||||||
ArtLayers []*ArtLayer
|
ArtLayers []*ArtLayer
|
||||||
LayerSets []*LayerSet
|
LayerSets []*LayerSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *LayerSet) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(&LayerSetJSON{
|
||||||
|
Name: l.name,
|
||||||
|
ArtLayers: l.artLayers,
|
||||||
|
LayerSets: l.layerSets,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (l *LayerSet) UnmarshalJSON(b []byte) error {
|
func (l *LayerSet) UnmarshalJSON(b []byte) error {
|
||||||
tmp := &LayerSetJSON{}
|
tmp := &LayerSetJSON{}
|
||||||
if err := json.Unmarshal(b, &tmp); err != nil {
|
if err := json.Unmarshal(b, &tmp); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.name = tmp.Name
|
l.name = tmp.Name
|
||||||
l.parent = tmp.Parent
|
|
||||||
l.artLayers = tmp.ArtLayers
|
l.artLayers = tmp.ArtLayers
|
||||||
|
for _, lyr := range l.artLayers {
|
||||||
|
lyr.SetParent(l)
|
||||||
|
}
|
||||||
l.layerSets = tmp.LayerSets
|
l.layerSets = tmp.LayerSets
|
||||||
|
for _, set := range l.layerSets {
|
||||||
|
set.SetParent(l)
|
||||||
|
}
|
||||||
|
l.current = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,6 +440,11 @@ func (l *LayerSet) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *LayerSet) ArtLayers() []*ArtLayer {
|
func (l *LayerSet) ArtLayers() []*ArtLayer {
|
||||||
|
for i := 0; i < len(l.artLayers); i++ {
|
||||||
|
if l.artLayers[i] != nil && !l.artLayers[i].current {
|
||||||
|
l.artLayers[i] = l.ArtLayer(l.artLayers[i].name)
|
||||||
|
}
|
||||||
|
}
|
||||||
return l.artLayers
|
return l.artLayers
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,6 +453,18 @@ func (l *LayerSet) ArtLayers() []*ArtLayer {
|
|||||||
func (l *LayerSet) ArtLayer(name string) *ArtLayer {
|
func (l *LayerSet) ArtLayer(name string) *ArtLayer {
|
||||||
for _, lyr := range l.artLayers {
|
for _, lyr := range l.artLayers {
|
||||||
if lyr.name == name {
|
if lyr.name == name {
|
||||||
|
if Mode == 0 && !lyr.current {
|
||||||
|
byt, err := DoJs("getLayer.jsx", JSLayer(lyr.Path()))
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
var lyr2 *ArtLayer
|
||||||
|
err = json.Unmarshal(byt, &lyr2)
|
||||||
|
lyr.name = lyr2.name
|
||||||
|
lyr.bounds = lyr2.bounds
|
||||||
|
lyr.visible = lyr2.visible
|
||||||
|
lyr.current = true
|
||||||
|
}
|
||||||
return lyr
|
return lyr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -408,11 +502,13 @@ func (l *LayerSet) Path() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewLayerSet(path string, g Group) (*LayerSet, error) {
|
func NewLayerSet(path string, g Group) (*LayerSet, error) {
|
||||||
|
path = strings.Replace(path, "//", "/", -1)
|
||||||
byt, err := DoJs("getLayerSet.jsx", JSLayer(path))
|
byt, err := DoJs("getLayerSet.jsx", JSLayer(path))
|
||||||
var out *LayerSet
|
var out *LayerSet
|
||||||
err = json.Unmarshal(byt, &out)
|
err = json.Unmarshal(byt, &out)
|
||||||
if flag.Lookup("test.v") != nil {
|
if flag.Lookup("test.v") != nil {
|
||||||
// log.Println(string(byt))
|
// log.Println(path)
|
||||||
|
// log.Println(out)
|
||||||
}
|
}
|
||||||
out.SetParent(g)
|
out.SetParent(g)
|
||||||
log.Printf("Loading ActiveDocument/%s\n", out.Path())
|
log.Printf("Loading ActiveDocument/%s\n", out.Path())
|
||||||
@@ -423,7 +519,6 @@ func NewLayerSet(path string, g Group) (*LayerSet, error) {
|
|||||||
lyr.SetParent(out)
|
lyr.SetParent(out)
|
||||||
}
|
}
|
||||||
for i, set := range out.layerSets {
|
for i, set := range out.layerSets {
|
||||||
// log.Println("\t", set.name)
|
|
||||||
s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name()), out)
|
s, err := NewLayerSet(fmt.Sprintf("%s%s/", path, set.Name()), out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user