1
2
3
4
5
6
7 package main
8
9
10
11
12 import (
13 "bytes"
14 "flag"
15 "fmt"
16 "go/format"
17 "io"
18 "log"
19 "os"
20 )
21
22 var filename = flag.String("output", "palette.go", "output file name")
23
24 func main() {
25 flag.Parse()
26
27 var buf bytes.Buffer
28
29 fmt.Fprintln(&buf, `// Copyright 2013 The Go Authors. All rights reserved.
30 // Use of this source code is governed by a BSD-style
31 // license that can be found in the LICENSE file.`)
32 fmt.Fprintln(&buf)
33 fmt.Fprintln(&buf, "// Code generated by go run gen.go -output palette.go; DO NOT EDIT.")
34 fmt.Fprintln(&buf)
35 fmt.Fprintln(&buf, "package palette")
36 fmt.Fprintln(&buf)
37 fmt.Fprintln(&buf, `import "image/color"`)
38 fmt.Fprintln(&buf)
39 printPlan9(&buf)
40 printWebSafe(&buf)
41
42 data, err := format.Source(buf.Bytes())
43 if err != nil {
44 log.Fatal(err)
45 }
46 err = os.WriteFile(*filename, data, 0644)
47 if err != nil {
48 log.Fatal(err)
49 }
50 }
51
52 func printPlan9(w io.Writer) {
53 c, lines := [3]int{}, [256]string{}
54 for r, i := 0, 0; r != 4; r++ {
55 for v := 0; v != 4; v, i = v+1, i+16 {
56 for g, j := 0, v-r; g != 4; g++ {
57 for b := 0; b != 4; b, j = b+1, j+1 {
58 den := r
59 if g > den {
60 den = g
61 }
62 if b > den {
63 den = b
64 }
65 if den == 0 {
66 c[0] = 0x11 * v
67 c[1] = 0x11 * v
68 c[2] = 0x11 * v
69 } else {
70 num := 17 * (4*den + v)
71 c[0] = r * num / den
72 c[1] = g * num / den
73 c[2] = b * num / den
74 }
75 lines[i+(j&0x0f)] =
76 fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", c[0], c[1], c[2])
77 }
78 }
79 }
80 }
81 fmt.Fprintln(w, "// Plan9 is a 256-color palette that partitions the 24-bit RGB space")
82 fmt.Fprintln(w, "// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the")
83 fmt.Fprintln(w, "// [WebSafe], the idea is to reduce the color resolution by dicing the")
84 fmt.Fprintln(w, "// color cube into fewer cells, and to use the extra space to increase the")
85 fmt.Fprintln(w, "// intensity resolution. This results in 16 gray shades (4 gray subcubes with")
86 fmt.Fprintln(w, "// 4 samples in each), 13 shades of each primary and secondary color (3")
87 fmt.Fprintln(w, "// subcubes with 4 samples plus black) and a reasonable selection of colors")
88 fmt.Fprintln(w, "// covering the rest of the color cube. The advantage is better representation")
89 fmt.Fprintln(w, "// of continuous tones.")
90 fmt.Fprintln(w, "//")
91 fmt.Fprintln(w, "// This palette was used in the Plan 9 Operating System, described at")
92 fmt.Fprintln(w, "// https://9p.io/magic/man2html/6/color")
93 fmt.Fprintln(w, "var Plan9 = []color.Color{")
94 for _, line := range lines {
95 fmt.Fprintln(w, line)
96 }
97 fmt.Fprintln(w, "}")
98 fmt.Fprintln(w)
99 }
100
101 func printWebSafe(w io.Writer) {
102 lines := [6 * 6 * 6]string{}
103 for r := 0; r < 6; r++ {
104 for g := 0; g < 6; g++ {
105 for b := 0; b < 6; b++ {
106 lines[36*r+6*g+b] =
107 fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", 0x33*r, 0x33*g, 0x33*b)
108 }
109 }
110 }
111 fmt.Fprintln(w, "// WebSafe is a 216-color palette that was popularized by early versions")
112 fmt.Fprintln(w, "// of Netscape Navigator. It is also known as the Netscape Color Cube.")
113 fmt.Fprintln(w, "//")
114 fmt.Fprintln(w, "// See https://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.")
115 fmt.Fprintln(w, "var WebSafe = []color.Color{")
116 for _, line := range lines {
117 fmt.Fprintln(w, line)
118 }
119 fmt.Fprintln(w, "}")
120 fmt.Fprintln(w)
121 }
122
View as plain text