/
canvas.go
122 lines (105 loc) · 2.35 KB
/
canvas.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package canvas
import (
"image/color"
"github.com/Laughs-In-Flowers/log"
"github.com/Laughs-In-Flowers/xrr"
)
// Provided Config functions, returns a new Canvas and any configuration errors.
func New(cnf ...Config) (Canvas, error) {
c := &canvas{
identity: newIdentity(),
pxl: newPxl(),
}
cc := newConfiguration(c, cnf...)
err := cc.Configure()
if err != nil {
return nil, err
}
return c, nil
}
// The primary interface for all image manipulation needs.
type Canvas interface {
log.Logger
Identity
Pxl
Nooper
Saver
Cloner
Operator
}
type canvas struct {
log.Logger
Configuration
*identity
*pxl
}
// An interface for denoting a non operational Canvas.
type Nooper interface {
Noop() bool
}
// Operational or Nonoperational status of a Canvas. Returns a boolean where
// true is nonoperational and false is operational.
func (c *canvas) Noop() bool {
switch {
case c.pxl.m == COLORNOOP,
c.path == PATHNOOP,
c.fileType == FILETYPENOOP,
c.action == ACTIONNOOP:
return true
default:
return false
}
return true
}
// An interface for saving a canvas.
type Saver interface {
Save() error
SaveTo(string) error
}
var SaveNoopError = xrr.Xrror("cannot save a non operational canvas")
// Saves the canvas according to its current status.
func (c *canvas) Save() error {
if !c.Noop() {
c.Printf("canvas %s saving...", c.path)
return save(c.path, c.fileType, c.pxl)
}
return SaveNoopError
}
// Save the canvas to its current status as the provided string color model.
func (c *canvas) SaveTo(cm string) error {
nm := stringToColorModel(cm).toColorModel()
nc := cloneTo(c, nm)
c.Printf("canvas switched to color model %s", cm)
return nc.Save()
}
// An interface for cloning a Canvas.
type Cloner interface {
Clone() Canvas
CloneTo(color.Model) Canvas
}
// clone the canvas
func (c *canvas) Clone() Canvas {
return c.CloneTo(c.pxl.ColorModel())
}
// clone the canvas to the provided color.Model
func (c *canvas) CloneTo(m color.Model) Canvas {
return cloneTo(c, m)
}
func cloneTo(c *canvas, m color.Model) *canvas {
nc := &canvas{
Logger: c.Logger,
Configuration: c.Configuration,
identity: c.identity.clone(),
pxl: c.pxl.clone(m),
}
return nc
}
type canvasMutate func() (*pxl, error)
func (c *canvas) mutate(fn canvasMutate) error {
np, err := fn()
if err != nil {
return err
}
c.pxl = np
return nil
}