87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package helper
|
|
|
|
import (
|
|
_color "image/color"
|
|
"iter"
|
|
)
|
|
|
|
// Enum iterates over a sparse sample of the RGBA colour space.
|
|
//
|
|
// If color is true, the colours will have distinct RGB components.
|
|
// otherwise, the colours will have identical RGB components.
|
|
//
|
|
// If alpha is true, the colours will include transparency,
|
|
// otherwise the returned colours will be fully opaque.
|
|
//
|
|
// If slow is false, an even smaller number of samples will be returned
|
|
// making this suitable for use in a nested loop.
|
|
//
|
|
// color=true alpha=true slow=true: 87481 samples.
|
|
// color=true alpha=false slow=true: 140608 samples.
|
|
// color=true alpha=true slow=false: 649 samples.
|
|
// color=true alpha=false slow=false: 216 samples.
|
|
func Enum(color, alpha, slow bool) iter.Seq[_color.RGBA64] {
|
|
var aStart, aStep, cDiv uint32
|
|
|
|
switch {
|
|
case color && alpha && slow:
|
|
aStart, aStep, cDiv = 0, 0xffff/15, 17
|
|
case color && alpha: // color && alpha && !slow
|
|
aStart, aStep, cDiv = 0, 0xffff/3, 5
|
|
case color && slow: // color && !alpha && slow
|
|
aStart, aStep, cDiv = 0xffff, 1, 51
|
|
case color: // color && !alpha && !slow
|
|
aStart, aStep, cDiv = 0xffff, 1, 5
|
|
|
|
case alpha && slow: // !color && alpha && slow
|
|
aStart, aStep, cDiv = 0, 0xffff/15, 4369
|
|
case alpha: // !color && alpha && !slow
|
|
aStart, aStep, cDiv = 0, 0xffff/15, 17
|
|
case slow: // !color && !alpha && slow
|
|
aStart, aStep, cDiv = 0xffff, 1, 65535
|
|
default: // !color && !alpha && !slow
|
|
aStart, aStep, cDiv = 0xffff, 1, 257
|
|
}
|
|
|
|
if color {
|
|
return func(yield func(_color.RGBA64) bool) {
|
|
for a := aStart; a <= 0xffff; a += aStep {
|
|
cStep := max(1, a/cDiv)
|
|
|
|
for b := uint32(0); b <= a; b += cStep {
|
|
for g := uint32(0); g <= a; g += cStep {
|
|
for r := uint32(0); r <= a; r += cStep {
|
|
if !yield(_color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return func(yield func(_color.RGBA64) bool) {
|
|
for a := aStart; a <= 0xffff; a += aStep {
|
|
cStep := max(1, a/cDiv)
|
|
|
|
for c := uint32(0); c <= a; c += cStep {
|
|
if !yield(_color.RGBA64{uint16(c), uint16(c), uint16(c), uint16(a)}) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// EnumColor is identical to [Enum], but invokes a [color.Model] to return a concrete colour type.
|
|
func EnumColor[C _color.Color](color, alpha, slow bool, m _color.Model) iter.Seq[C] {
|
|
return func(yield func(C) bool) {
|
|
for rgba := range Enum(color, alpha, slow) {
|
|
if !yield(m.Convert(rgba).(C)) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|