1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
22 //----------------------------------------------------------------------------
24 // color types gray8, gray16
26 //----------------------------------------------------------------------------
28 #ifndef AGG_COLOR_GRAY_INCLUDED
29 #define AGG_COLOR_GRAY_INCLUDED
31 #include "agg_basics.h"
32 #include "agg_color_rgba.h"
37 //===================================================================gray8
40 typedef int8u value_type
;
41 typedef int32u calc_type
;
42 typedef int32 long_type
;
46 base_size
= 1 << base_shift
,
47 base_mask
= base_size
- 1
49 typedef gray8 self_type
;
54 //--------------------------------------------------------------------
57 //--------------------------------------------------------------------
58 gray8(unsigned v_
, unsigned a_
=base_mask
) :
59 v(int8u(v_
)), a(int8u(a_
)) {}
61 //--------------------------------------------------------------------
62 gray8(const self_type
& c
, unsigned a_
) :
63 v(c
.v
), a(value_type(a_
)) {}
65 //--------------------------------------------------------------------
66 gray8(const rgba
& c
) :
67 v(value_type((0.299*c
.r
+ 0.587*c
.g
+ 0.114*c
.b
) * double(base_mask
) + 0.5)),
68 a(value_type(c
.a
* double(base_mask
))) {}
70 //--------------------------------------------------------------------
71 gray8(const rgba
& c
, double a_
) :
72 v(value_type((0.299*c
.r
+ 0.587*c
.g
+ 0.114*c
.b
) * double(base_mask
) + 0.5)),
73 a(value_type(a_
* double(base_mask
))) {}
75 //--------------------------------------------------------------------
76 gray8(const rgba8
& c
) :
77 v((c
.r
*77 + c
.g
*150 + c
.b
*29) >> 8),
80 //--------------------------------------------------------------------
81 gray8(const rgba8
& c
, unsigned a_
) :
82 v((c
.r
*77 + c
.g
*150 + c
.b
*29) >> 8),
85 //--------------------------------------------------------------------
91 //--------------------------------------------------------------------
92 const self_type
& transparent()
98 //--------------------------------------------------------------------
99 void opacity(double a_
)
101 if(a_
< 0.0) a_
= 0.0;
102 if(a_
> 1.0) a_
= 1.0;
103 a
= value_type(a_
* double(base_mask
));
106 //--------------------------------------------------------------------
107 double opacity() const
109 return double(a
) / double(base_mask
);
113 //--------------------------------------------------------------------
114 const self_type
& premultiply()
116 if(a
== base_mask
) return *this;
122 v
= value_type((calc_type(v
) * a
) >> base_shift
);
126 //--------------------------------------------------------------------
127 const self_type
& premultiply(unsigned a_
)
129 if(a
== base_mask
&& a_
>= base_mask
) return *this;
130 if(a
== 0 || a_
== 0)
135 calc_type v_
= (calc_type(v
) * a_
) / a
;
136 v
= value_type((v_
> a_
) ? a_
: v_
);
141 //--------------------------------------------------------------------
142 const self_type
& demultiply()
144 if(a
== base_mask
) return *this;
150 calc_type v_
= (calc_type(v
) * base_mask
) / a
;
151 v
= value_type((v_
> base_mask
) ? base_mask
: v_
);
155 //--------------------------------------------------------------------
156 self_type
gradient(self_type c
, double k
) const
159 calc_type ik
= calc_type(k
* base_size
);
160 ret
.v
= value_type(calc_type(v
) + (((calc_type(c
.v
) - v
) * ik
) >> base_shift
));
161 ret
.a
= value_type(calc_type(a
) + (((calc_type(c
.a
) - a
) * ik
) >> base_shift
));
165 //--------------------------------------------------------------------
166 static self_type
no_color() { return self_type(0,0); }
170 //-------------------------------------------------------------gray8_pre
171 inline gray8
gray8_pre(unsigned v
, unsigned a
= gray8::base_mask
)
173 return gray8(v
,a
).premultiply();
175 inline gray8
gray8_pre(const gray8
& c
, unsigned a
)
177 return gray8(c
,a
).premultiply();
179 inline gray8
gray8_pre(const rgba
& c
)
181 return gray8(c
).premultiply();
183 inline gray8
gray8_pre(const rgba
& c
, double a
)
185 return gray8(c
,a
).premultiply();
187 inline gray8
gray8_pre(const rgba8
& c
)
189 return gray8(c
).premultiply();
191 inline gray8
gray8_pre(const rgba8
& c
, unsigned a
)
193 return gray8(c
,a
).premultiply();
199 //==================================================================gray16
202 typedef int16u value_type
;
203 typedef int32u calc_type
;
204 typedef int64 long_type
;
208 base_size
= 1 << base_shift
,
209 base_mask
= base_size
- 1
211 typedef gray16 self_type
;
216 //--------------------------------------------------------------------
219 //--------------------------------------------------------------------
220 gray16(unsigned v_
, unsigned a_
=base_mask
) :
221 v(int16u(v_
)), a(int16u(a_
)) {}
223 //--------------------------------------------------------------------
224 gray16(const self_type
& c
, unsigned a_
) :
225 v(c
.v
), a(value_type(a_
)) {}
227 //--------------------------------------------------------------------
228 gray16(const rgba
& c
) :
229 v(value_type((0.299*c
.r
+ 0.587*c
.g
+ 0.114*c
.b
) * double(base_mask
) + 0.5)),
230 a(value_type(c
.a
* double(base_mask
))) {}
232 //--------------------------------------------------------------------
233 gray16(const rgba
& c
, double a_
) :
234 v(value_type((0.299*c
.r
+ 0.587*c
.g
+ 0.114*c
.b
) * double(base_mask
) + 0.5)),
235 a(value_type(a_
* double(base_mask
))) {}
237 //--------------------------------------------------------------------
238 gray16(const rgba8
& c
) :
239 v(c
.r
*77 + c
.g
*150 + c
.b
*29),
240 a((value_type(c
.a
) << 8) | c
.a
) {}
242 //--------------------------------------------------------------------
243 gray16(const rgba8
& c
, unsigned a_
) :
244 v(c
.r
*77 + c
.g
*150 + c
.b
*29),
245 a((value_type(a_
) << 8) | c
.a
) {}
247 //--------------------------------------------------------------------
253 //--------------------------------------------------------------------
254 const self_type
& transparent()
260 //--------------------------------------------------------------------
261 void opacity(double a_
)
263 if(a_
< 0.0) a_
= 0.0;
264 if(a_
> 1.0) a_
= 1.0;
265 a
= value_type(a_
* double(base_mask
));
268 //--------------------------------------------------------------------
269 double opacity() const
271 return double(a
) / double(base_mask
);
275 //--------------------------------------------------------------------
276 const self_type
& premultiply()
278 if(a
== base_mask
) return *this;
284 v
= value_type((calc_type(v
) * a
) >> base_shift
);
288 //--------------------------------------------------------------------
289 const self_type
& premultiply(unsigned a_
)
291 if(a
== base_mask
&& a_
>= base_mask
) return *this;
292 if(a
== 0 || a_
== 0)
297 calc_type v_
= (calc_type(v
) * a_
) / a
;
298 v
= value_type((v_
> a_
) ? a_
: v_
);
303 //--------------------------------------------------------------------
304 const self_type
& demultiply()
306 if(a
== base_mask
) return *this;
312 calc_type v_
= (calc_type(v
) * base_mask
) / a
;
313 v
= value_type((v_
> base_mask
) ? base_mask
: v_
);
317 //--------------------------------------------------------------------
318 self_type
gradient(self_type c
, double k
) const
321 calc_type ik
= calc_type(k
* base_size
);
322 ret
.v
= value_type(calc_type(v
) + (((calc_type(c
.v
) - v
) * ik
) >> base_shift
));
323 ret
.a
= value_type(calc_type(a
) + (((calc_type(c
.a
) - a
) * ik
) >> base_shift
));
327 //--------------------------------------------------------------------
328 static self_type
no_color() { return self_type(0,0); }
332 //------------------------------------------------------------gray16_pre
333 inline gray16
gray16_pre(unsigned v
, unsigned a
= gray16::base_mask
)
335 return gray16(v
,a
).premultiply();
337 inline gray16
gray16_pre(const gray16
& c
, unsigned a
)
339 return gray16(c
,a
).premultiply();
341 inline gray16
gray16_pre(const rgba
& c
)
343 return gray16(c
).premultiply();
345 inline gray16
gray16_pre(const rgba
& c
, double a
)
347 return gray16(c
,a
).premultiply();
349 inline gray16
gray16_pre(const rgba8
& c
)
351 return gray16(c
).premultiply();
353 inline gray16
gray16_pre(const rgba8
& c
, unsigned a
)
355 return gray16(c
,a
).premultiply();