// Copyright 2015 by Sascha L. Teichmann // Use of this source code is governed by the MIT license // that can be found in the LICENSE file. package main import ( "bufio" "encoding/json" "image/color" "os" "regexp" "strconv" ) type Component struct { Value uint8 Used bool } type Expr struct{ *regexp.Regexp } type Col struct { E Expr `json:"expr"` R Component `json:"r"` G Component `json:"g"` B Component `json:"b"` A Component `json:"a"` } type PredefCols []Col func (e *Expr) UnmarshalJSON(data []byte) error { unquoted := string(data[1 : len(data)-1]) expr, err := regexp.Compile(unquoted) if err != nil { return err } *e = Expr{expr} return nil } func (c *Component) UnmarshalJSON(data []byte) error { v, err := strconv.ParseUint(string(data), 10, 8) if err != nil { return err } c.Value = uint8(v) c.Used = true return nil } func LoadPredefCols(filename string) (PredefCols, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() decoder := json.NewDecoder(bufio.NewReader(file)) var predef PredefCols if err = decoder.Decode(&predef); err != nil { return nil, err } return predef, nil } func (pd *PredefCols) findCol(name string) *Col { for i, n := 0, len(*pd); i < n; i++ { if (*pd)[i].E.MatchString(name) { return &(*pd)[i] } } return nil } func (c *Col) Complete() bool { return c.R.Used && c.G.Used && c.B.Used && c.A.Used } func (c *Col) RGBA() (r, g, b, a uint32) { r = uint32(c.R.Value) r |= r << 8 g = uint32(c.G.Value) g |= g << 8 b = uint32(c.B.Value) b |= b << 8 a = uint32(c.A.Value) a |= a << 8 return } func (c *Col) Apply(other color.Color) color.Color { r, g, b, a := other.RGBA() x := color.RGBA{ R: uint8(r >> 8), G: uint8(g >> 8), B: uint8(b >> 8), A: uint8(a >> 8)} if c.R.Used { x.R = c.R.Value } if c.G.Used { x.G = c.G.Value } if c.B.Used { x.B = c.B.Value } if c.A.Used { x.A = c.A.Value } return &x }