diff vendor/github.com/alecthomas/chroma/v2/colour.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/github.com/alecthomas/chroma/v2/colour.go	Sun Jul 23 13:18:53 2023 +0000
@@ -0,0 +1,192 @@
+package chroma
+
+import (
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+)
+
+// ANSI2RGB maps ANSI colour names, as supported by Chroma, to hex RGB values.
+var ANSI2RGB = map[string]string{
+	"#ansiblack":     "000000",
+	"#ansidarkred":   "7f0000",
+	"#ansidarkgreen": "007f00",
+	"#ansibrown":     "7f7fe0",
+	"#ansidarkblue":  "00007f",
+	"#ansipurple":    "7f007f",
+	"#ansiteal":      "007f7f",
+	"#ansilightgray": "e5e5e5",
+	// Normal
+	"#ansidarkgray":  "555555",
+	"#ansired":       "ff0000",
+	"#ansigreen":     "00ff00",
+	"#ansiyellow":    "ffff00",
+	"#ansiblue":      "0000ff",
+	"#ansifuchsia":   "ff00ff",
+	"#ansiturquoise": "00ffff",
+	"#ansiwhite":     "ffffff",
+
+	// Aliases without the "ansi" prefix, because...why?
+	"#black":     "000000",
+	"#darkred":   "7f0000",
+	"#darkgreen": "007f00",
+	"#brown":     "7f7fe0",
+	"#darkblue":  "00007f",
+	"#purple":    "7f007f",
+	"#teal":      "007f7f",
+	"#lightgray": "e5e5e5",
+	// Normal
+	"#darkgray":  "555555",
+	"#red":       "ff0000",
+	"#green":     "00ff00",
+	"#yellow":    "ffff00",
+	"#blue":      "0000ff",
+	"#fuchsia":   "ff00ff",
+	"#turquoise": "00ffff",
+	"#white":     "ffffff",
+}
+
+// Colour represents an RGB colour.
+type Colour int32
+
+// NewColour creates a Colour directly from RGB values.
+func NewColour(r, g, b uint8) Colour {
+	return ParseColour(fmt.Sprintf("%02x%02x%02x", r, g, b))
+}
+
+// Distance between this colour and another.
+//
+// This uses the approach described here (https://www.compuphase.com/cmetric.htm).
+// This is not as accurate as LAB, et. al. but is *vastly* simpler and sufficient for our needs.
+func (c Colour) Distance(e2 Colour) float64 {
+	ar, ag, ab := int64(c.Red()), int64(c.Green()), int64(c.Blue())
+	br, bg, bb := int64(e2.Red()), int64(e2.Green()), int64(e2.Blue())
+	rmean := (ar + br) / 2
+	r := ar - br
+	g := ag - bg
+	b := ab - bb
+	return math.Sqrt(float64((((512 + rmean) * r * r) >> 8) + 4*g*g + (((767 - rmean) * b * b) >> 8)))
+}
+
+// Brighten returns a copy of this colour with its brightness adjusted.
+//
+// If factor is negative, the colour is darkened.
+//
+// Uses approach described here (http://www.pvladov.com/2012/09/make-color-lighter-or-darker.html).
+func (c Colour) Brighten(factor float64) Colour {
+	r := float64(c.Red())
+	g := float64(c.Green())
+	b := float64(c.Blue())
+
+	if factor < 0 {
+		factor++
+		r *= factor
+		g *= factor
+		b *= factor
+	} else {
+		r = (255-r)*factor + r
+		g = (255-g)*factor + g
+		b = (255-b)*factor + b
+	}
+	return NewColour(uint8(r), uint8(g), uint8(b))
+}
+
+// BrightenOrDarken brightens a colour if it is < 0.5 brightness or darkens if > 0.5 brightness.
+func (c Colour) BrightenOrDarken(factor float64) Colour {
+	if c.Brightness() < 0.5 {
+		return c.Brighten(factor)
+	}
+	return c.Brighten(-factor)
+}
+
+// ClampBrightness returns a copy of this colour with its brightness adjusted such that
+// it falls within the range [min, max] (or very close to it due to rounding errors).
+// The supplied values use the same [0.0, 1.0] range as Brightness.
+func (c Colour) ClampBrightness(min, max float64) Colour {
+	if !c.IsSet() {
+		return c
+	}
+
+	min = math.Max(min, 0)
+	max = math.Min(max, 1)
+	current := c.Brightness()
+	target := math.Min(math.Max(current, min), max)
+	if current == target {
+		return c
+	}
+
+	r := float64(c.Red())
+	g := float64(c.Green())
+	b := float64(c.Blue())
+	rgb := r + g + b
+	if target > current {
+		// Solve for x: target == ((255-r)*x + r + (255-g)*x + g + (255-b)*x + b) / 255 / 3
+		return c.Brighten((target*255*3 - rgb) / (255*3 - rgb))
+	}
+	// Solve for x: target == (r*(x+1) + g*(x+1) + b*(x+1)) / 255 / 3
+	return c.Brighten((target*255*3)/rgb - 1)
+}
+
+// Brightness of the colour (roughly) in the range 0.0 to 1.0.
+func (c Colour) Brightness() float64 {
+	return (float64(c.Red()) + float64(c.Green()) + float64(c.Blue())) / 255.0 / 3.0
+}
+
+// ParseColour in the forms #rgb, #rrggbb, #ansi<colour>, or #<colour>.
+// Will return an "unset" colour if invalid.
+func ParseColour(colour string) Colour {
+	colour = normaliseColour(colour)
+	n, err := strconv.ParseUint(colour, 16, 32)
+	if err != nil {
+		return 0
+	}
+	return Colour(n + 1)
+}
+
+// MustParseColour is like ParseColour except it panics if the colour is invalid.
+//
+// Will panic if colour is in an invalid format.
+func MustParseColour(colour string) Colour {
+	parsed := ParseColour(colour)
+	if !parsed.IsSet() {
+		panic(fmt.Errorf("invalid colour %q", colour))
+	}
+	return parsed
+}
+
+// IsSet returns true if the colour is set.
+func (c Colour) IsSet() bool { return c != 0 }
+
+func (c Colour) String() string   { return fmt.Sprintf("#%06x", int(c-1)) }
+func (c Colour) GoString() string { return fmt.Sprintf("Colour(0x%06x)", int(c-1)) }
+
+// Red component of colour.
+func (c Colour) Red() uint8 { return uint8(((c - 1) >> 16) & 0xff) }
+
+// Green component of colour.
+func (c Colour) Green() uint8 { return uint8(((c - 1) >> 8) & 0xff) }
+
+// Blue component of colour.
+func (c Colour) Blue() uint8 { return uint8((c - 1) & 0xff) }
+
+// Colours is an orderable set of colours.
+type Colours []Colour
+
+func (c Colours) Len() int           { return len(c) }
+func (c Colours) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
+func (c Colours) Less(i, j int) bool { return c[i] < c[j] }
+
+// Convert colours to #rrggbb.
+func normaliseColour(colour string) string {
+	if ansi, ok := ANSI2RGB[colour]; ok {
+		return ansi
+	}
+	if strings.HasPrefix(colour, "#") {
+		colour = colour[1:]
+		if len(colour) == 3 {
+			return colour[0:1] + colour[0:1] + colour[1:2] + colour[1:2] + colour[2:3] + colour[2:3]
+		}
+	}
+	return colour
+}