From ff38043a109839ca4db19221ce7fb9385276e8d9 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 23 Mar 2018 15:26:33 -0400 Subject: [PATCH] Improved documentation all colors must now implement hex notation as well as rgb --- colors.go | 22 ++++++++++++++++++---- ps.go | 40 +++++++++++++++++++++++----------------- structs.go | 45 +++++++++++++++++++++++++++++---------------- 3 files changed, 70 insertions(+), 37 deletions(-) diff --git a/colors.go b/colors.go index c371a05..6a4e311 100644 --- a/colors.go +++ b/colors.go @@ -9,11 +9,16 @@ var Colors map[string]Color = map[string]Color{ "White": &RGB{255, 255, 255}, } -// Color represents a color. +// Color is an interface for color objects, allowing colors to be +// used in various formats. +// +// RGB is the default format for everything. type Color interface { - RGB() [3]int + RGB() [3]int // The color in RGB format. + Hex() []uint8 // The color in hexadecimal format. } +// Compare determines which of two colors is "brighter". func Compare(a, b Color) Color { A := a.RGB() B := b.RGB() @@ -25,7 +30,7 @@ func Compare(a, b Color) Color { return b } -// Color is a color in RGB format. +// RGB is a color in RGB format. It fulfills the Color interface. type RGB struct { Red int Green int @@ -37,7 +42,12 @@ func (r RGB) RGB() [3]int { return [3]int{r.Red, r.Green, r.Blue} } -// Hex is a color in hexidecimal format. +// TODO: Implement RGB.Hex() +func (r RGB) Hex() []uint8 { + return make([]uint8, 6) +} + +// Hex is a color in hexadecimal format. It fulfills the Color interface. type Hex []uint8 func (h Hex) RGB() [3]int { @@ -50,6 +60,10 @@ func (h Hex) RGB() [3]int { return [3]int{int(dst[0]), int(dst[1]), int(dst[2])} } +func (h Hex) Hex() []uint8 { + return h +} + // Stroke represents a layer stroke effect. type Stroke struct { Size float32 diff --git a/ps.go b/ps.go index 406b65b..fd49357 100644 --- a/ps.go +++ b/ps.go @@ -1,7 +1,7 @@ -// Package ps is a rudimentary API between Adobe Photoshop and go. +// Package ps is a rudimentary API between Adobe Photoshop CS5 and Golang. // // Most of the interaction between the two is implemented via -// javascript and/or VBS/Applescript. +// Javascript and/or VBS/Applescript. // // Currently only works with CS5 on Windows. package ps @@ -54,30 +54,41 @@ func Start() error { return err } -// Close closes the active document. +// Close closes the active document in Photoshop. func Close(save PSSaveOptions) error { _, err := run("close", save.String()) return err } -// Open opens a file with the specified path. +// Open opens a Photoshop document with the specified path. +// If Photoshop is not currently running, it is started before +// opening the document func Open(path string) error { _, err := run("open", path) return err } -// Quit exits Photoshop. +// Quit exits Photoshop with the given saving option. func Quit(save PSSaveOptions) error { _, err := run("quit", save.String()) return err } -// DoJs runs a Photoshop javascript script file (.jsx) from the specified location. +// SaveAs saves the Photoshop document to the given location. +func SaveAs(path string) error { + _, err := run("save", path) + return err +} + +// DoJs runs a Photoshop Javascript script file (.jsx) from the specified location. // It can't directly return output, so instead the scripts write their output to -// a temporary file. +// a temporary file, whose contents is then read and returned. 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") + if !strings.HasSuffix(path, ".jsx") { + path += ".jsx" + } defer os.Remove(outpath) args = append([]string{outpath}, args...) @@ -150,18 +161,12 @@ func run(name string, args ...string) ([]byte, error) { return out.Bytes(), nil } -// DoAction runs a Photoshop action with name from set. +// DoAction runs the Photoshop action with name from set. func DoAction(set, name string) error { _, err := run("action", set, name) return err } -// SaveAs saves the Photoshop document file to the given location. -func SaveAs(path string) error { - _, err := run("save", path) - return err -} - // Layers returns an array of ArtLayers from the active document // based on the given path string. /*func Layers(path string) ([]ArtLayer, error) { @@ -172,15 +177,16 @@ func SaveAs(path string) error { return []ArtLayer{}, err } return out, err -} -*/ +}*/ // ApplyDataset fills out a template file with information from a given dataset (csv) file. func ApplyDataset(name string) ([]byte, error) { return DoJs("applyDataset.jsx", name) } -// JSLayer retrurns javascript code to get the layer with a 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 +// property of the layer, you'll have to trim the output before concatenating func JSLayer(path string) string { path = strings.TrimLeft(path, "/") pth := strings.Split(path, "/") diff --git a/structs.go b/structs.go index 3d4eead..c7e3465 100644 --- a/structs.go +++ b/structs.go @@ -180,7 +180,7 @@ func (d *Document) Dump() { f.Write(byt) } -// ArtLayer represents an Art Layer in a photoshop document. +// ArtLayer reflects certain values from an Art Layer in a Photoshop document. type ArtLayer struct { name string // The layer's name. // TextItem string @@ -192,6 +192,14 @@ type ArtLayer struct { *Stroke // The layer's stroke. } +// Bounds returns the furthest corners of the ArtLayer. +func (a *ArtLayer) Bounds() [2][2]int { + return a.bounds +} + +// ArtLayerJSON is a bridge between the ArtLayer struct and +// the encoding/json package, allowing ArtLayer's unexported fields +// to ber written to and read from by the json package. type ArtLayerJSON struct { Name string Bounds [2][2]int @@ -201,6 +209,8 @@ type ArtLayerJSON struct { StrokeAmt float32 } +// MarshalJSON fufills the json.Marshaler interface, allowing the ArtLayer to be +// saved to disk in JSON format. func (a *ArtLayer) MarshalJSON() ([]byte, error) { return json.Marshal(&ArtLayerJSON{ Name: a.name, @@ -230,10 +240,6 @@ 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] @@ -244,7 +250,7 @@ func (a *ArtLayer) X2() int { return a.bounds[1][0] } -// Y1 returns the layer's topmost Y value. +// Y1 returns the layer's topmost y value. func (a *ArtLayer) Y1() int { return a.bounds[0][1] } @@ -369,23 +375,30 @@ func (a *ArtLayer) Visible() bool { } // SetPos snaps the given layer boundry to the given point. -// Valid options for bound are: TL, TR, BL, BR -// TODO: Improve +// Valid options for bound are: "TL", "TR", "BL", "BR" +// +// TODO: Test TR and BR func (a *ArtLayer) SetPos(x, y int, bound string) { - if x == 0 && y == 0 { + if !a.visible || (x == 0 && y == 0) { return } - if !a.visible { - return - } - var lyrX, lyrY int - lyrX = a.X1() - if bound != "TL" { + switch bound[:1] { + case "B": lyrY = a.Y2() - } else { // "BL" + case "T": + fallthrough + default: lyrY = a.Y1() } + switch bound[1:] { + case "R": + lyrX = a.X2() + case "L": + fallthrough + default: + lyrX = a.X1() + } byt, err := DoJs("moveLayer.jsx", JSLayer(a.Path()), fmt.Sprint(x-lyrX), fmt.Sprint(y-lyrY)) var bounds [2][2]int if err != nil {