1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // All Colors can convert themselves, with a possible loss of precision,
8 // to 64-bit alpha-premultiplied RGBA. Each channel value ranges within
10 type Color
interface {
11 RGBA() (r
, g
, b
, a
uint32)
14 // An RGBAColor represents a traditional 32-bit alpha-premultiplied color,
15 // having 8 bits for each of red, green, blue and alpha.
16 type RGBAColor
struct {
20 func (c RGBAColor
) RGBA() (r
, g
, b
, a
uint32) {
32 // An RGBA64Color represents a 64-bit alpha-premultiplied color,
33 // having 16 bits for each of red, green, blue and alpha.
34 type RGBA64Color
struct {
38 func (c RGBA64Color
) RGBA() (r
, g
, b
, a
uint32) {
39 return uint32(c
.R
), uint32(c
.G
), uint32(c
.B
), uint32(c
.A
)
42 // An NRGBAColor represents a non-alpha-premultiplied 32-bit color.
43 type NRGBAColor
struct {
47 func (c NRGBAColor
) RGBA() (r
, g
, b
, a
uint32) {
65 // An NRGBA64Color represents a non-alpha-premultiplied 64-bit color,
66 // having 16 bits for each of red, green, blue and alpha.
67 type NRGBA64Color
struct {
71 func (c NRGBA64Color
) RGBA() (r
, g
, b
, a
uint32) {
85 // An AlphaColor represents an 8-bit alpha.
86 type AlphaColor
struct {
90 func (c AlphaColor
) RGBA() (r
, g
, b
, a
uint32) {
96 // An Alpha16Color represents a 16-bit alpha.
97 type Alpha16Color
struct {
101 func (c Alpha16Color
) RGBA() (r
, g
, b
, a
uint32) {
106 // A GrayColor represents an 8-bit grayscale color.
107 type GrayColor
struct {
111 func (c GrayColor
) RGBA() (r
, g
, b
, a
uint32) {
114 return y
, y
, y
, 0xffff
117 // A Gray16Color represents a 16-bit grayscale color.
118 type Gray16Color
struct {
122 func (c Gray16Color
) RGBA() (r
, g
, b
, a
uint32) {
124 return y
, y
, y
, 0xffff
127 // A ColorModel can convert foreign Colors, with a possible loss of precision,
128 // to a Color from its own color model.
129 type ColorModel
interface {
130 Convert(c Color
) Color
133 // The ColorModelFunc type is an adapter to allow the use of an ordinary
134 // color conversion function as a ColorModel. If f is such a function,
135 // ColorModelFunc(f) is a ColorModel object that invokes f to implement
137 type ColorModelFunc
func(Color
) Color
139 func (f ColorModelFunc
) Convert(c Color
) Color
{
143 func toRGBAColor(c Color
) Color
{
144 if _
, ok
:= c
.(RGBAColor
); ok
{
147 r
, g
, b
, a
:= c
.RGBA()
148 return RGBAColor
{uint8(r
>> 8), uint8(g
>> 8), uint8(b
>> 8), uint8(a
>> 8)}
151 func toRGBA64Color(c Color
) Color
{
152 if _
, ok
:= c
.(RGBA64Color
); ok
{
155 r
, g
, b
, a
:= c
.RGBA()
156 return RGBA64Color
{uint16(r
), uint16(g
), uint16(b
), uint16(a
)}
159 func toNRGBAColor(c Color
) Color
{
160 if _
, ok
:= c
.(NRGBAColor
); ok
{
163 r
, g
, b
, a
:= c
.RGBA()
165 return NRGBAColor
{uint8(r
>> 8), uint8(g
>> 8), uint8(b
>> 8), 0xff}
168 return NRGBAColor
{0, 0, 0, 0}
170 // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
174 return NRGBAColor
{uint8(r
>> 8), uint8(g
>> 8), uint8(b
>> 8), uint8(a
>> 8)}
177 func toNRGBA64Color(c Color
) Color
{
178 if _
, ok
:= c
.(NRGBA64Color
); ok
{
181 r
, g
, b
, a
:= c
.RGBA()
183 return NRGBA64Color
{uint16(r
), uint16(g
), uint16(b
), 0xffff}
186 return NRGBA64Color
{0, 0, 0, 0}
188 // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
192 return NRGBA64Color
{uint16(r
), uint16(g
), uint16(b
), uint16(a
)}
195 func toAlphaColor(c Color
) Color
{
196 if _
, ok
:= c
.(AlphaColor
); ok
{
199 _
, _
, _
, a
:= c
.RGBA()
200 return AlphaColor
{uint8(a
>> 8)}
203 func toAlpha16Color(c Color
) Color
{
204 if _
, ok
:= c
.(Alpha16Color
); ok
{
207 _
, _
, _
, a
:= c
.RGBA()
208 return Alpha16Color
{uint16(a
)}
211 func toGrayColor(c Color
) Color
{
212 if _
, ok
:= c
.(GrayColor
); ok
{
215 r
, g
, b
, _
:= c
.RGBA()
216 y
:= (299*r
+ 587*g
+ 114*b
+ 500) / 1000
217 return GrayColor
{uint8(y
>> 8)}
220 func toGray16Color(c Color
) Color
{
221 if _
, ok
:= c
.(Gray16Color
); ok
{
224 r
, g
, b
, _
:= c
.RGBA()
225 y
:= (299*r
+ 587*g
+ 114*b
+ 500) / 1000
226 return Gray16Color
{uint16(y
)}
229 // The ColorModel associated with RGBAColor.
230 var RGBAColorModel ColorModel
= ColorModelFunc(toRGBAColor
)
232 // The ColorModel associated with RGBA64Color.
233 var RGBA64ColorModel ColorModel
= ColorModelFunc(toRGBA64Color
)
235 // The ColorModel associated with NRGBAColor.
236 var NRGBAColorModel ColorModel
= ColorModelFunc(toNRGBAColor
)
238 // The ColorModel associated with NRGBA64Color.
239 var NRGBA64ColorModel ColorModel
= ColorModelFunc(toNRGBA64Color
)
241 // The ColorModel associated with AlphaColor.
242 var AlphaColorModel ColorModel
= ColorModelFunc(toAlphaColor
)
244 // The ColorModel associated with Alpha16Color.
245 var Alpha16ColorModel ColorModel
= ColorModelFunc(toAlpha16Color
)
247 // The ColorModel associated with GrayColor.
248 var GrayColorModel ColorModel
= ColorModelFunc(toGrayColor
)
250 // The ColorModel associated with Gray16Color.
251 var Gray16ColorModel ColorModel
= ColorModelFunc(toGray16Color
)