rastrillo / fiesta Public

Clone
git clone https://amadan.net/rastrillo/fiesta

Plain git — no account needed to clone.

Download

Download this file

1package check
2
3import (
4 "fmt"
5 "math"
6 "regexp"
7 "strconv"
8)
9
10// canonColours and what it reaches, from rastrillo's ui/derived_test.go:
11// untagged, so the CSS gates that read text and the browser drives that
12// read computed styles both use it. The derived-colour evaluator it sat
13// beside (evalColour, rgba, accentSupportsBlock) is ported with the
14// gate that uses it.
15
16// oklchClip renders OKLCh as eight-bit sRGB the way Chromium paints an
17// out-of-gamut colour: each linear channel clipped to 0..1. Lightness
18// and chroma are both kept, so a clipped colour is brighter than the
19// one asked for; that is what the dark fill's lightness drop exists to
20// absorb (day.css, the @supports comment).
21func oklchClip(l, c, hue float64) [3]uint8 {
22 rad := hue * math.Pi / 180
23 lin := oklabToLinear(l, c*math.Cos(rad), c*math.Sin(rad))
24 var v [3]uint8
25 for i, ch := range lin {
26 n := math.Round(linearToSRGB(math.Min(1, math.Max(0, ch))) * 255)
27 v[i] = uint8(math.Min(255, math.Max(0, n)))
28 }
29 return v
30}
31
32var (
33 srgbSer = regexp.MustCompile(`color\(srgb ([0-9.e-]+) ([0-9.e-]+) ([0-9.e-]+)(?: / ([0-9.e-]+))?\)`)
34 oklchSer = regexp.MustCompile(`oklch\(([0-9.e-]+) ([0-9.e-]+) ([0-9.e-]+)(?: / ([0-9.e-]+))?\)`)
35)
36
37// canonColours rewrites the colour functions Chromium serialises a
38// derived colour as, color(srgb …) for a color-mix() and oklch(…) for a
39// relative colour, into the rgb()/rgba() the drives compare against.
40// A computed value that is a legacy colour is already in that form.
41// Without this every literal in the depth drives would have to be the
42// six-decimal serialisation of a float, which changes with the engine's
43// printing rather than with the colour.
44func canonColours(s string) string {
45 s = srgbSer.ReplaceAllStringFunc(s, func(m string) string {
46 p := srgbSer.FindStringSubmatch(m)
47 var ch [3]int
48 for i := range ch {
49 f, _ := strconv.ParseFloat(p[i+1], 64)
50 ch[i] = int(math.Round(f * 255))
51 }
52 if p[4] == "" {
53 return fmt.Sprintf("rgb(%d, %d, %d)", ch[0], ch[1], ch[2])
54 }
55 return fmt.Sprintf("rgba(%d, %d, %d, %s)", ch[0], ch[1], ch[2], p[4])
56 })
57 return oklchSer.ReplaceAllStringFunc(s, func(m string) string {
58 p := oklchSer.FindStringSubmatch(m)
59 l, _ := strconv.ParseFloat(p[1], 64)
60 c, _ := strconv.ParseFloat(p[2], 64)
61 h, _ := strconv.ParseFloat(p[3], 64)
62 rgb := oklchClip(l, c, h)
63 if p[4] == "" {
64 return fmt.Sprintf("rgb(%d, %d, %d)", rgb[0], rgb[1], rgb[2])
65 }
66 return fmt.Sprintf("rgba(%d, %d, %d, %s)", rgb[0], rgb[1], rgb[2], p[4])
67 })
68}
69