mirror of
https://github.com/sbrow/ps.git
synced 2025-12-29 18:47:38 -05:00
Various updates
* Layersets now have bounds. * TextItem is now writeable * Added flush function to writing, for faster debugging.
This commit is contained in:
8
ps.go
8
ps.go
@@ -73,7 +73,7 @@ func SaveAs(path string) error {
|
|||||||
func DoJs(path string, args ...string) (out []byte, err error) {
|
func DoJs(path string, args ...string) (out []byte, err error) {
|
||||||
// Temp file for js to output to.
|
// Temp file for js to output to.
|
||||||
outpath := filepath.Join(os.Getenv("TEMP"), "js_out.txt")
|
outpath := filepath.Join(os.Getenv("TEMP"), "js_out.txt")
|
||||||
defer os.Remove(outpath)
|
// defer os.Remove(outpath)
|
||||||
if !strings.HasSuffix(path, ".jsx") {
|
if !strings.HasSuffix(path, ".jsx") {
|
||||||
path += ".jsx"
|
path += ".jsx"
|
||||||
}
|
}
|
||||||
@@ -160,11 +160,15 @@ func ApplyDataset(name string) ([]byte, error) {
|
|||||||
// JSLayer "compiles" Javascript code to get an ArtLayer with the given path.
|
// JSLayer "compiles" Javascript code to get an ArtLayer with the given path.
|
||||||
// The output always ends with a semicolon, so if you want to access a specific
|
// The output always ends with a semicolon, so if you want to access a specific
|
||||||
// property of the layer, you'll have to trim the output before concatenating
|
// property of the layer, you'll have to trim the output before concatenating
|
||||||
func JSLayer(path string) string {
|
func JSLayer(path string, art ...bool) string {
|
||||||
path = strings.TrimLeft(path, "/")
|
path = strings.TrimLeft(path, "/")
|
||||||
pth := strings.Split(path, "/")
|
pth := strings.Split(path, "/")
|
||||||
js := "app.activeDocument"
|
js := "app.activeDocument"
|
||||||
last := len(pth) - 1
|
last := len(pth) - 1
|
||||||
|
if len(art) > 0 {
|
||||||
|
pth = pth[:len(pth)-1]
|
||||||
|
last--
|
||||||
|
}
|
||||||
if last > 0 {
|
if last > 0 {
|
||||||
for i := 0; i < last; i++ {
|
for i := 0; i < last; i++ {
|
||||||
js += fmt.Sprintf(".layerSets.getByName('%s')", pth[i])
|
js += fmt.Sprintf(".layerSets.getByName('%s')", pth[i])
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include lib.js
|
#include lib.js
|
||||||
|
|
||||||
var stdout = newFile(arguments[0]);
|
var stdout = newFile(arguments[0]);
|
||||||
var set = eval(arguments[1]);
|
var set = eval(arguments[1]);
|
||||||
stdout.writeln('{"Name": "'+set.name+'", "ArtLayers":[');
|
stdout.writeln('{"Name": "'+set.name+'", "ArtLayers":[');
|
||||||
|
stdout.flush();
|
||||||
for (var i = 0; i < set.artLayers.length; i++) {
|
for (var i = 0; i < set.artLayers.length; i++) {
|
||||||
var lyr = set.artLayers[i];
|
var lyr = set.artLayers[i];
|
||||||
stdout.write(('{"Name":"' + lyr.name + '", "Bounds": [[' + lyr.bounds[0] + ',' +
|
stdout.write(('{"Name":"' + lyr.name + '", "Bounds": [[' + lyr.bounds[0] + ',' +
|
||||||
@@ -15,13 +15,25 @@ for (var i = 0; i < set.artLayers.length; i++) {
|
|||||||
stdout.write("}")
|
stdout.write("}")
|
||||||
if (i != set.artLayers.length - 1)
|
if (i != set.artLayers.length - 1)
|
||||||
stdout.writeln(",");
|
stdout.writeln(",");
|
||||||
|
stdout.flush();
|
||||||
}
|
}
|
||||||
stdout.write('], "LayerSets": [')
|
stdout.writeln("]");
|
||||||
|
stdout.write(', "LayerSets": [')
|
||||||
for (var i = 0; i < set.layerSets.length; i++) {
|
for (var i = 0; i < set.layerSets.length; i++) {
|
||||||
var s = set.layerSets[i];
|
var s = set.layerSets[i];
|
||||||
stdout.write('{"Name":"' + s.name + '", "Visible": ' + s.visible + '}');
|
stdout.write('{"Name":"' + s.name + '", "Visible": ' + s.visible + '}');
|
||||||
if (i < set.layerSets.length - 1)
|
if (i < set.layerSets.length - 1)
|
||||||
stdout.writeln(",");
|
stdout.writeln(",");
|
||||||
|
stdout.flush()
|
||||||
}
|
}
|
||||||
stdout.write("]}")
|
stdout.writeln(']')
|
||||||
|
// app.activeDocument.activeLayer=set;
|
||||||
|
// set.merge();
|
||||||
|
// set=eval(arguments[2]);
|
||||||
|
stdout.write(', "Bounds": [[],[]]');
|
||||||
|
// stdout.write((', "Bounds": [[' + set.bounds[0] + ',' +
|
||||||
|
// set.bounds[1] + '],[' + set.bounds[2] + ',' +
|
||||||
|
// set.bounds[3] + ']]').replace(/ px/g, ""));
|
||||||
|
stdout.write("}");
|
||||||
|
// Undo();
|
||||||
stdout.close();
|
stdout.close();
|
||||||
@@ -1,13 +1,21 @@
|
|||||||
// Opens and returns a file, overwriting new data.
|
// Opens and returns a file, overwriting new data.
|
||||||
function newFile(path) {
|
function newFile(path) {
|
||||||
var f = File(path)
|
var f = File(path)
|
||||||
if(f.exists)
|
|
||||||
f.remove()
|
|
||||||
f.encoding = "UTF8"
|
f.encoding = "UTF8"
|
||||||
f.open("e", "TEXT", "????")
|
f.open("w")
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File.prototype.flush = function() {
|
||||||
|
this.close()
|
||||||
|
this.open("a")
|
||||||
|
};
|
||||||
|
function flush(file) {
|
||||||
|
file.close()
|
||||||
|
file.open("a")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Prints an error message.
|
// Prints an error message.
|
||||||
function err(e) {
|
function err(e) {
|
||||||
return 'ERROR: ' + e.message + ' at ' + e.fileName + ':' + e.line;
|
return 'ERROR: ' + e.message + ' at ' + e.fileName + ':' + e.line;
|
||||||
@@ -19,6 +27,14 @@ function bounds(lyr) {
|
|||||||
lyr.bounds[3] + ']]').replace(/ px/g, "");
|
lyr.bounds[3] + ']]').replace(/ px/g, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Undo() {
|
||||||
|
var desc = new ActionDescriptor();
|
||||||
|
var ref = new ActionReference();
|
||||||
|
ref.putEnumerated( charIDToTypeID( "HstS" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Prvs" ));
|
||||||
|
desc.putReference(charIDToTypeID( "null" ), ref);
|
||||||
|
executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The setFormatting function sets the font, font style, point size, and RGB color of specified
|
* The setFormatting function sets the font, font style, point size, and RGB color of specified
|
||||||
* characters in a Photoshop text layer.
|
* characters in a Photoshop text layer.
|
||||||
|
|||||||
@@ -2,5 +2,12 @@
|
|||||||
var stdout = newFile(arguments[0]);
|
var stdout = newFile(arguments[0]);
|
||||||
var lyr = eval(arguments[1]);
|
var lyr = eval(arguments[1]);
|
||||||
lyr.translate((Number)(arguments[2]), (Number)(arguments[3]));
|
lyr.translate((Number)(arguments[2]), (Number)(arguments[3]));
|
||||||
|
if (lyr.typename == 'LayerSet') {
|
||||||
|
alert(lyr.name + "\n" + lyr.typename)
|
||||||
|
alert(lyr)
|
||||||
|
// lyr.merge()
|
||||||
|
// lyr=eval(arguments[4])
|
||||||
|
// Undo();
|
||||||
|
}
|
||||||
stdout.writeln('{' + bounds(lyr) + '}')
|
stdout.writeln('{' + bounds(lyr) + '}')
|
||||||
stdout.close();
|
stdout.close();
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
#include lib.js
|
#include lib.js
|
||||||
var saveFile = File(arguments[0]);
|
|
||||||
if(saveFile.exists)
|
|
||||||
saveFile.remove();
|
|
||||||
|
|
||||||
saveFile.encoding = "UTF8";
|
// var saveFile = File(arguments[0]);
|
||||||
saveFile.open("e", "TEXT", "????");
|
var arg = 'app.activeDocument.layerSets.getByName("Indicators").layerSets.getByName("Deck")';
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
alert(arg.replace(/[^(?:layerSets)]*(layerSets)/, "artLayers"))
|
||||||
saveFile.writeln(arguments[i])
|
// var doc=app.activeDocument
|
||||||
}
|
// doc.layerSets.getByName("ResolveGem").merge();
|
||||||
setFormatting(0,6, "Arial", "Bold");
|
// alert(doc.artLayers.getByName("ResolveGem").bounds);
|
||||||
saveFile.close();
|
// doc.activeHistoryState=doc.historyStates[doc.historyStates.length-2]
|
||||||
|
// setFormatting(0,6, "Arial", "Bold");
|
||||||
|
// saveFile.close();
|
||||||
70
structs.go
70
structs.go
@@ -168,6 +168,7 @@ func (d *Document) Dump() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ArtLayer reflects certain values from an Art Layer in a Photoshop document.
|
// ArtLayer reflects certain values from an Art Layer in a Photoshop document.
|
||||||
|
// TODO: Make TextLayer a subclass of ArtLayer
|
||||||
type ArtLayer struct {
|
type ArtLayer struct {
|
||||||
name string // The layer's name.
|
name string // The layer's name.
|
||||||
Text *string // The contents of a text layer.
|
Text *string // The contents of a text layer.
|
||||||
@@ -197,6 +198,16 @@ type ArtLayerJSON struct {
|
|||||||
Text *string
|
Text *string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *ArtLayer) SetText(txt string) {
|
||||||
|
lyr := strings.TrimRight(JSLayer(a.Path()), ";")
|
||||||
|
js := fmt.Sprintf("%s.textItem.contents='%s';", lyr, txt)
|
||||||
|
_, err := DoJs("compilejs.jsx", js)
|
||||||
|
if err != nil {
|
||||||
|
a.Text = &txt
|
||||||
|
}
|
||||||
|
a.Refresh()
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON fulfills the json.Marshaler interface, allowing the ArtLayer to be
|
// MarshalJSON fulfills the json.Marshaler interface, allowing the ArtLayer to be
|
||||||
// saved to disk in JSON format.
|
// saved to disk in JSON format.
|
||||||
func (a *ArtLayer) MarshalJSON() ([]byte, error) {
|
func (a *ArtLayer) MarshalJSON() ([]byte, error) {
|
||||||
@@ -444,6 +455,7 @@ func (a *ArtLayer) Refresh() error {
|
|||||||
|
|
||||||
type LayerSet struct {
|
type LayerSet struct {
|
||||||
name string
|
name string
|
||||||
|
bounds [2][2]int
|
||||||
parent Group
|
parent Group
|
||||||
current bool // Whether we've checked this layer since we loaded from disk.
|
current bool // Whether we've checked this layer since we loaded from disk.
|
||||||
visible bool
|
visible bool
|
||||||
@@ -453,6 +465,7 @@ type LayerSet struct {
|
|||||||
|
|
||||||
type LayerSetJSON struct {
|
type LayerSetJSON struct {
|
||||||
Name string
|
Name string
|
||||||
|
Bounds [2][2]int
|
||||||
ArtLayers []*ArtLayer
|
ArtLayers []*ArtLayer
|
||||||
LayerSets []*LayerSet
|
LayerSets []*LayerSet
|
||||||
}
|
}
|
||||||
@@ -460,6 +473,7 @@ type LayerSetJSON struct {
|
|||||||
func (l *LayerSet) MarshalJSON() ([]byte, error) {
|
func (l *LayerSet) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(&LayerSetJSON{
|
return json.Marshal(&LayerSetJSON{
|
||||||
Name: l.name,
|
Name: l.name,
|
||||||
|
Bounds: l.bounds,
|
||||||
ArtLayers: l.artLayers,
|
ArtLayers: l.artLayers,
|
||||||
LayerSets: l.layerSets,
|
LayerSets: l.layerSets,
|
||||||
})
|
})
|
||||||
@@ -471,6 +485,7 @@ func (l *LayerSet) UnmarshalJSON(b []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.name = tmp.Name
|
l.name = tmp.Name
|
||||||
|
l.bounds = tmp.Bounds
|
||||||
l.artLayers = tmp.ArtLayers
|
l.artLayers = tmp.ArtLayers
|
||||||
for _, lyr := range l.artLayers {
|
for _, lyr := range l.artLayers {
|
||||||
lyr.SetParent(l)
|
lyr.SetParent(l)
|
||||||
@@ -544,6 +559,11 @@ func (l *LayerSet) LayerSet(name string) *LayerSet {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bounds returns the furthest corners of the LayerSet.
|
||||||
|
func (l *LayerSet) Bounds() [2][2]int {
|
||||||
|
return l.bounds
|
||||||
|
}
|
||||||
|
|
||||||
func (l *LayerSet) SetParent(c Group) {
|
func (l *LayerSet) SetParent(c Group) {
|
||||||
l.parent = c
|
l.parent = c
|
||||||
}
|
}
|
||||||
@@ -562,9 +582,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)
|
path = strings.Replace(path, "//", "/", -1)
|
||||||
byt, err := DoJs("getLayerSet.jsx", JSLayer(path))
|
byt, err := DoJs("getLayerSet.jsx", JSLayer(path))
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
var out *LayerSet
|
var out *LayerSet
|
||||||
err = json.Unmarshal(byt, &out)
|
err = json.Unmarshal(byt, &out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(JSLayer(path))
|
||||||
log.Println(string(byt))
|
log.Println(string(byt))
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
@@ -597,12 +621,53 @@ func (l *LayerSet) SetVisible(b bool) {
|
|||||||
DoJs("compilejs.jsx", js)
|
DoJs("compilejs.jsx", js)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPos snaps the given layerset boundry to the given point.
|
||||||
|
// Valid options for bound are: "TL", "TR", "BL", "BR"
|
||||||
|
//
|
||||||
|
// TODO: Test TR and BR
|
||||||
|
func (l *LayerSet) SetPos(x, y int, bound string) {
|
||||||
|
// if !l.visible || (x == 0 && y == 0) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
var lyrX, lyrY int
|
||||||
|
switch bound[:1] {
|
||||||
|
case "B":
|
||||||
|
lyrY = l.bounds[1][1]
|
||||||
|
case "T":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
lyrY = l.bounds[0][1]
|
||||||
|
}
|
||||||
|
switch bound[1:] {
|
||||||
|
case "R":
|
||||||
|
lyrX = l.bounds[1][0]
|
||||||
|
case "L":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
lyrX = l.bounds[0][0]
|
||||||
|
}
|
||||||
|
fmt.Println(JSLayer(l.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY))
|
||||||
|
byt, err := DoJs("moveLayer.jsx", JSLayer(l.Path()), fmt.Sprint(x-lyrX),
|
||||||
|
fmt.Sprint(y-lyrY), JSLayer(l.Path(), true))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("byte:", string(byt))
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var lyr LayerSet
|
||||||
|
err = json.Unmarshal(byt, &lyr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("byte:", string(byt))
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
l.bounds = lyr.bounds
|
||||||
|
}
|
||||||
|
|
||||||
func (l *LayerSet) Refresh() {
|
func (l *LayerSet) Refresh() {
|
||||||
var tmp *LayerSet
|
var tmp *LayerSet
|
||||||
byt, err := DoJs("getLayerSet.jsx", JSLayer(l.Path()))
|
byt, err := DoJs("getLayerSet.jsx", JSLayer(l.Path()), JSLayer(l.Path(), true))
|
||||||
err = json.Unmarshal(byt, &tmp)
|
err = json.Unmarshal(byt, &tmp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error in LayerSet.Refresh()", string(byt))
|
log.Println("Error in LayerSet.Refresh() \"", string(byt), "\"", "for", l.Path())
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
tmp.SetParent(l.Parent())
|
tmp.SetParent(l.Parent())
|
||||||
@@ -617,6 +682,7 @@ func (l *LayerSet) Refresh() {
|
|||||||
set.Refresh()
|
set.Refresh()
|
||||||
}
|
}
|
||||||
l.name = tmp.name
|
l.name = tmp.name
|
||||||
|
l.bounds = tmp.bounds
|
||||||
l.visible = tmp.visible
|
l.visible = tmp.visible
|
||||||
l.current = true
|
l.current = true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user