summaryrefslogtreecommitdiff
path: root/internal/colors
diff options
context:
space:
mode:
Diffstat (limited to 'internal/colors')
-rw-r--r--internal/colors/cmyk.go46
-rw-r--r--internal/colors/hsl.go1
-rw-r--r--internal/colors/precise.go38
-rw-r--r--internal/colors/rgb.go25
4 files changed, 110 insertions, 0 deletions
diff --git a/internal/colors/cmyk.go b/internal/colors/cmyk.go
new file mode 100644
index 0000000..3460c4e
--- /dev/null
+++ b/internal/colors/cmyk.go
@@ -0,0 +1,46 @@
+package colors
+
+import "math"
+
+type CMYK struct {
+ C int // 0-100
+ M int // 0-100
+ Y int // 0-100
+ K int // 0-100
+}
+
+func (c CMYK) ToPrecise() PreciseColor {
+ return PreciseColor{
+ R: (1 - float64(c.C)/100) * (1 - float64(c.K)/100),
+ G: (1 - float64(c.M)/100) * (1 - float64(c.K)/100),
+ B: (1 - float64(c.Y)/100) * (1 - float64(c.K)/100),
+ }
+}
+
+func (c CMYK) FromPrecise(p PreciseColor) ColorSpace {
+ // Extract RGB components from the PreciseColor
+ r := p.R
+ g := p.G
+ b := p.B
+
+ // Calculate the K (key/black) component
+ k := 1 - math.Max(math.Max(r, g), b)
+
+ // Avoid division by zero when K is 1 (pure black)
+ if k == 1 {
+ return CMYK{C: 0, M: 0, Y: 0, K: 100}
+ }
+
+ // Calculate the CMY components based on the remaining color values
+ cyan := (1 - r - k) / (1 - k)
+ magenta := (1 - g - k) / (1 - k)
+ yellow := (1 - b - k) / (1 - k)
+
+ // Scale to 0-100 and return
+ return CMYK{
+ C: int(math.Round(cyan * 100)),
+ M: int(math.Round(magenta * 100)),
+ Y: int(math.Round(yellow * 100)),
+ K: int(math.Round(k * 100)),
+ }
+}
diff --git a/internal/colors/hsl.go b/internal/colors/hsl.go
new file mode 100644
index 0000000..7477042
--- /dev/null
+++ b/internal/colors/hsl.go
@@ -0,0 +1 @@
+package colors
diff --git a/internal/colors/precise.go b/internal/colors/precise.go
new file mode 100644
index 0000000..fafa104
--- /dev/null
+++ b/internal/colors/precise.go
@@ -0,0 +1,38 @@
+package colors
+
+import (
+ "fmt"
+ "math"
+ "strings"
+)
+
+type ColorSpace interface {
+ ToPrecise() PreciseColor
+ FromPrecise(PreciseColor) ColorSpace
+}
+
+// PreciseColor is a color with floating point values for red, green, and blue.
+// The extra precision minimizes rounding errors when converting between different
+// color spaces. It is used as an intermediate representation when converting between
+// different color spaces.
+type PreciseColor struct {
+ R, G, B float64
+}
+
+func (c PreciseColor) ToPrecise() PreciseColor {
+ return c
+}
+
+func (c PreciseColor) FromPrecise(p PreciseColor) ColorSpace {
+ return p
+}
+
+func ToHexString(cs ColorSpace) string {
+ p := cs.ToPrecise()
+
+ return strings.ToUpper(fmt.Sprintf("#%02x%02x%02x",
+ int(math.Round(p.R*255)),
+ int(math.Round(p.G*255)),
+ int(math.Round(p.B*255)),
+ ))
+}
diff --git a/internal/colors/rgb.go b/internal/colors/rgb.go
new file mode 100644
index 0000000..e81aefc
--- /dev/null
+++ b/internal/colors/rgb.go
@@ -0,0 +1,25 @@
+package colors
+
+import "math"
+
+type RGB struct {
+ R int // 0-255
+ G int // 0-255
+ B int // 0-255
+}
+
+func (c RGB) ToPrecise() PreciseColor {
+ return PreciseColor{
+ R: float64(c.R) / 255,
+ G: float64(c.G) / 255,
+ B: float64(c.B) / 255,
+ }
+}
+
+func (c RGB) FromPrecise(p PreciseColor) ColorSpace {
+ return RGB{
+ R: int(math.Round(p.R * 255)),
+ G: int(math.Round(p.G * 255)),
+ B: int(math.Round(p.B * 255)),
+ }
+}