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) {
|
||||
// Temp file for js to output to.
|
||||
outpath := filepath.Join(os.Getenv("TEMP"), "js_out.txt")
|
||||
defer os.Remove(outpath)
|
||||
// defer os.Remove(outpath)
|
||||
if !strings.HasSuffix(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.
|
||||
// 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
|
||||
func JSLayer(path string) string {
|
||||
func JSLayer(path string, art ...bool) string {
|
||||
path = strings.TrimLeft(path, "/")
|
||||
pth := strings.Split(path, "/")
|
||||
js := "app.activeDocument"
|
||||
last := len(pth) - 1
|
||||
if len(art) > 0 {
|
||||
pth = pth[:len(pth)-1]
|
||||
last--
|
||||
}
|
||||
if last > 0 {
|
||||
for i := 0; i < last; i++ {
|
||||
js += fmt.Sprintf(".layerSets.getByName('%s')", pth[i])
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include lib.js
|
||||
|
||||
var stdout = newFile(arguments[0]);
|
||||
var set = eval(arguments[1]);
|
||||
stdout.writeln('{"Name": "'+set.name+'", "ArtLayers":[');
|
||||
stdout.flush();
|
||||
for (var i = 0; i < set.artLayers.length; i++) {
|
||||
var lyr = set.artLayers[i];
|
||||
stdout.write(('{"Name":"' + lyr.name + '", "Bounds": [[' + lyr.bounds[0] + ',' +
|
||||
@@ -15,13 +15,25 @@ for (var i = 0; i < set.artLayers.length; i++) {
|
||||
stdout.write("}")
|
||||
if (i != set.artLayers.length - 1)
|
||||
stdout.writeln(",");
|
||||
stdout.flush();
|
||||
}
|
||||
stdout.write('], "LayerSets": [')
|
||||
stdout.writeln("]");
|
||||
stdout.write(', "LayerSets": [')
|
||||
for (var i = 0; i < set.layerSets.length; i++) {
|
||||
var s = set.layerSets[i];
|
||||
stdout.write('{"Name":"' + s.name + '", "Visible": ' + s.visible + '}');
|
||||
if (i < set.layerSets.length - 1)
|
||||
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();
|
||||
@@ -1,13 +1,21 @@
|
||||
// Opens and returns a file, overwriting new data.
|
||||
function newFile(path) {
|
||||
var f = File(path)
|
||||
if(f.exists)
|
||||
f.remove()
|
||||
f.encoding = "UTF8"
|
||||
f.open("e", "TEXT", "????")
|
||||
f.open("w")
|
||||
return f
|
||||
}
|
||||
|
||||
File.prototype.flush = function() {
|
||||
this.close()
|
||||
this.open("a")
|
||||
};
|
||||
function flush(file) {
|
||||
file.close()
|
||||
file.open("a")
|
||||
}
|
||||
|
||||
|
||||
// Prints an error message.
|
||||
function err(e) {
|
||||
return 'ERROR: ' + e.message + ' at ' + e.fileName + ':' + e.line;
|
||||
@@ -19,6 +27,14 @@ function bounds(lyr) {
|
||||
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
|
||||
* characters in a Photoshop text layer.
|
||||
|
||||
@@ -2,5 +2,12 @@
|
||||
var stdout = newFile(arguments[0]);
|
||||
var lyr = eval(arguments[1]);
|
||||
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.close();
|
||||
@@ -1,12 +1,11 @@
|
||||
#include lib.js
|
||||
var saveFile = File(arguments[0]);
|
||||
if(saveFile.exists)
|
||||
saveFile.remove();
|
||||
|
||||
saveFile.encoding = "UTF8";
|
||||
saveFile.open("e", "TEXT", "????");
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
saveFile.writeln(arguments[i])
|
||||
}
|
||||
setFormatting(0,6, "Arial", "Bold");
|
||||
saveFile.close();
|
||||
// var saveFile = File(arguments[0]);
|
||||
var arg = 'app.activeDocument.layerSets.getByName("Indicators").layerSets.getByName("Deck")';
|
||||
alert(arg.replace(/[^(?:layerSets)]*(layerSets)/, "artLayers"))
|
||||
// var doc=app.activeDocument
|
||||
// doc.layerSets.getByName("ResolveGem").merge();
|
||||
// alert(doc.artLayers.getByName("ResolveGem").bounds);
|
||||
// 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.
|
||||
// TODO: Make TextLayer a subclass of ArtLayer
|
||||
type ArtLayer struct {
|
||||
name string // The layer's name.
|
||||
Text *string // The contents of a text layer.
|
||||
@@ -197,6 +198,16 @@ type ArtLayerJSON struct {
|
||||
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
|
||||
// saved to disk in JSON format.
|
||||
func (a *ArtLayer) MarshalJSON() ([]byte, error) {
|
||||
@@ -444,6 +455,7 @@ func (a *ArtLayer) Refresh() error {
|
||||
|
||||
type LayerSet struct {
|
||||
name string
|
||||
bounds [2][2]int
|
||||
parent Group
|
||||
current bool // Whether we've checked this layer since we loaded from disk.
|
||||
visible bool
|
||||
@@ -453,6 +465,7 @@ type LayerSet struct {
|
||||
|
||||
type LayerSetJSON struct {
|
||||
Name string
|
||||
Bounds [2][2]int
|
||||
ArtLayers []*ArtLayer
|
||||
LayerSets []*LayerSet
|
||||
}
|
||||
@@ -460,6 +473,7 @@ type LayerSetJSON struct {
|
||||
func (l *LayerSet) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&LayerSetJSON{
|
||||
Name: l.name,
|
||||
Bounds: l.bounds,
|
||||
ArtLayers: l.artLayers,
|
||||
LayerSets: l.layerSets,
|
||||
})
|
||||
@@ -471,6 +485,7 @@ func (l *LayerSet) UnmarshalJSON(b []byte) error {
|
||||
return err
|
||||
}
|
||||
l.name = tmp.Name
|
||||
l.bounds = tmp.Bounds
|
||||
l.artLayers = tmp.ArtLayers
|
||||
for _, lyr := range l.artLayers {
|
||||
lyr.SetParent(l)
|
||||
@@ -544,6 +559,11 @@ func (l *LayerSet) LayerSet(name string) *LayerSet {
|
||||
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) {
|
||||
l.parent = c
|
||||
}
|
||||
@@ -562,9 +582,13 @@ func (l *LayerSet) Path() string {
|
||||
func NewLayerSet(path string, g Group) (*LayerSet, error) {
|
||||
path = strings.Replace(path, "//", "/", -1)
|
||||
byt, err := DoJs("getLayerSet.jsx", JSLayer(path))
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
var out *LayerSet
|
||||
err = json.Unmarshal(byt, &out)
|
||||
if err != nil {
|
||||
log.Println(JSLayer(path))
|
||||
log.Println(string(byt))
|
||||
log.Panic(err)
|
||||
}
|
||||
@@ -597,12 +621,53 @@ func (l *LayerSet) SetVisible(b bool) {
|
||||
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() {
|
||||
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)
|
||||
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)
|
||||
}
|
||||
tmp.SetParent(l.Parent())
|
||||
@@ -617,6 +682,7 @@ func (l *LayerSet) Refresh() {
|
||||
set.Refresh()
|
||||
}
|
||||
l.name = tmp.name
|
||||
l.bounds = tmp.bounds
|
||||
l.visible = tmp.visible
|
||||
l.current = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user