Anti-Grain Geometry Tutorial
agg_color_gray.h
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
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.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 //
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
18 //
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
23 //
24 // color types gray8, gray16
25 //
26 //----------------------------------------------------------------------------
27 
28 #ifndef AGG_COLOR_GRAY_INCLUDED
29 #define AGG_COLOR_GRAY_INCLUDED
30 
31 #include "agg_basics.h"
32 #include "agg_color_rgba.h"
33 
34 namespace agg
35 {
36 
37  //===================================================================gray8
38  template<class Colorspace>
39  struct gray8T
40  {
41  typedef int8u value_type;
42  typedef int32u calc_type;
43  typedef int32 long_type;
44  enum base_scale_e
45  {
46  base_shift = 8,
47  base_scale = 1 << base_shift,
48  base_mask = base_scale - 1,
49  base_MSB = 1 << (base_shift - 1)
50  };
51  typedef gray8T self_type;
52 
53  value_type v;
54  value_type a;
55 
56  static value_type luminance(const rgba& c)
57  {
58  // Calculate grayscale value as per ITU-R BT.709.
59  return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
60  }
61 
62  static value_type luminance(const rgba8& c)
63  {
64  // Calculate grayscale value as per ITU-R BT.709.
65  return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8);
66  }
67 
68  static void convert(gray8T<linear>& dst, const gray8T<sRGB>& src)
69  {
71  dst.a = src.a;
72  }
73 
74  static void convert(gray8T<sRGB>& dst, const gray8T<linear>& src)
75  {
77  dst.a = src.a;
78  }
79 
80  static void convert(gray8T<linear>& dst, const rgba8& src)
81  {
82  dst.v = luminance(src);
83  dst.a = src.a;
84  }
85 
86  static void convert(gray8T<linear>& dst, const srgba8& src)
87  {
88  // The RGB weights are only valid for linear values.
89  convert(dst, rgba8(src));
90  }
91 
92  static void convert(gray8T<sRGB>& dst, const rgba8& src)
93  {
94  dst.v = sRGB_conv<value_type>::rgb_to_sRGB(luminance(src));
95  dst.a = src.a;
96  }
97 
98  static void convert(gray8T<sRGB>& dst, const srgba8& src)
99  {
100  // The RGB weights are only valid for linear values.
101  convert(dst, rgba8(src));
102  }
103 
104  //--------------------------------------------------------------------
105  gray8T() {}
106 
107  //--------------------------------------------------------------------
108  explicit gray8T(unsigned v_, unsigned a_ = base_mask) :
109  v(int8u(v_)), a(int8u(a_)) {}
110 
111  //--------------------------------------------------------------------
112  gray8T(const self_type& c, unsigned a_) :
113  v(c.v), a(value_type(a_)) {}
114 
115  //--------------------------------------------------------------------
116  gray8T(const rgba& c) :
117  v(luminance(c)),
118  a(value_type(uround(c.a * base_mask))) {}
119 
120  //--------------------------------------------------------------------
121  template<class T>
122  gray8T(const gray8T<T>& c)
123  {
124  convert(*this, c);
125  }
126 
127  //--------------------------------------------------------------------
128  template<class T>
129  gray8T(const rgba8T<T>& c)
130  {
131  convert(*this, c);
132  }
133 
134  //--------------------------------------------------------------------
135  template<class T>
136  T convert_from_sRGB() const
137  {
138  typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_from_sRGB(v);
140  }
141 
142  template<class T>
143  T convert_to_sRGB() const
144  {
145  typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_to_sRGB(v);
147  }
148 
149  //--------------------------------------------------------------------
150  rgba8 make_rgba8(const linear&) const
151  {
152  return rgba8(v, v, v, a);
153  }
154 
155  rgba8 make_rgba8(const sRGB&) const
156  {
157  return convert_from_sRGB<srgba8>();
158  }
159 
160  operator rgba8() const
161  {
162  return make_rgba8(Colorspace());
163  }
164 
165  //--------------------------------------------------------------------
166  srgba8 make_srgba8(const linear&) const
167  {
168  return convert_to_sRGB<rgba8>();
169  }
170 
171  srgba8 make_srgba8(const sRGB&) const
172  {
173  return srgba8(v, v, v, a);
174  }
175 
176  operator srgba8() const
177  {
178  return make_rgba8(Colorspace());
179  }
180 
181  //--------------------------------------------------------------------
182  rgba16 make_rgba16(const linear&) const
183  {
184  rgba16::value_type rgb = (v << 8) | v;
185  return rgba16(rgb, rgb, rgb, (a << 8) | a);
186  }
187 
188  rgba16 make_rgba16(const sRGB&) const
189  {
190  return convert_from_sRGB<rgba16>();
191  }
192 
193  operator rgba16() const
194  {
195  return make_rgba16(Colorspace());
196  }
197 
198  //--------------------------------------------------------------------
199  rgba32 make_rgba32(const linear&) const
200  {
201  rgba32::value_type v32 = v / 255.0f;
202  return rgba32(v32, v32, v32, a / 255.0f);
203  }
204 
205  rgba32 make_rgba32(const sRGB&) const
206  {
207  return convert_from_sRGB<rgba32>();
208  }
209 
210  operator rgba32() const
211  {
212  return make_rgba32(Colorspace());
213  }
214 
215  //--------------------------------------------------------------------
216  static AGG_INLINE double to_double(value_type a)
217  {
218  return double(a) / base_mask;
219  }
220 
221  //--------------------------------------------------------------------
222  static AGG_INLINE value_type from_double(double a)
223  {
224  return value_type(uround(a * base_mask));
225  }
226 
227  //--------------------------------------------------------------------
228  static AGG_INLINE value_type empty_value()
229  {
230  return 0;
231  }
232 
233  //--------------------------------------------------------------------
234  static AGG_INLINE value_type full_value()
235  {
236  return base_mask;
237  }
238 
239  //--------------------------------------------------------------------
240  AGG_INLINE bool is_transparent() const
241  {
242  return a == 0;
243  }
244 
245  //--------------------------------------------------------------------
246  AGG_INLINE bool is_opaque() const
247  {
248  return a == base_mask;
249  }
250 
251  //--------------------------------------------------------------------
252  // Fixed-point multiply, exact over int8u.
253  static AGG_INLINE value_type multiply(value_type a, value_type b)
254  {
255  calc_type t = a * b + base_MSB;
256  return value_type(((t >> base_shift) + t) >> base_shift);
257  }
258 
259  //--------------------------------------------------------------------
260  static AGG_INLINE value_type demultiply(value_type a, value_type b)
261  {
262  if (a * b == 0)
263  {
264  return 0;
265  }
266  else if (a >= b)
267  {
268  return base_mask;
269  }
270  else return value_type((a * base_mask + (b >> 1)) / b);
271  }
272 
273  //--------------------------------------------------------------------
274  template<typename T>
275  static AGG_INLINE T downscale(T a)
276  {
277  return a >> base_shift;
278  }
279 
280  //--------------------------------------------------------------------
281  template<typename T>
282  static AGG_INLINE T downshift(T a, unsigned n)
283  {
284  return a >> n;
285  }
286 
287  //--------------------------------------------------------------------
288  // Fixed-point multiply, exact over int8u.
289  // Specifically for multiplying a color component by a cover.
290  static AGG_INLINE value_type mult_cover(value_type a, value_type b)
291  {
292  return multiply(a, b);
293  }
294 
295  //--------------------------------------------------------------------
296  static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
297  {
298  return multiply(b, a);
299  }
300 
301  //--------------------------------------------------------------------
302  // Interpolate p to q by a, assuming q is premultiplied by a.
303  static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
304  {
305  return p + q - multiply(p, a);
306  }
307 
308  //--------------------------------------------------------------------
309  // Interpolate p to q by a.
310  static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
311  {
312  int t = (q - p) * a + base_MSB - (p > q);
313  return value_type(p + (((t >> base_shift) + t) >> base_shift));
314  }
315 
316  //--------------------------------------------------------------------
317  self_type& clear()
318  {
319  v = a = 0;
320  return *this;
321  }
322 
323  //--------------------------------------------------------------------
324  self_type& transparent()
325  {
326  a = 0;
327  return *this;
328  }
329 
330  //--------------------------------------------------------------------
331  self_type& opacity(double a_)
332  {
333  if (a_ < 0) a = 0;
334  else if (a_ > 1) a = 1;
335  else a = (value_type)uround(a_ * double(base_mask));
336  return *this;
337  }
338 
339  //--------------------------------------------------------------------
340  double opacity() const
341  {
342  return double(a) / double(base_mask);
343  }
344 
345  //--------------------------------------------------------------------
346  self_type& premultiply()
347  {
348  if (a < base_mask)
349  {
350  if (a == 0) v = 0;
351  else v = multiply(v, a);
352  }
353  return *this;
354  }
355 
356  //--------------------------------------------------------------------
357  self_type& demultiply()
358  {
359  if (a < base_mask)
360  {
361  if (a == 0)
362  {
363  v = 0;
364  }
365  else
366  {
367  calc_type v_ = (calc_type(v) * base_mask) / a;
368  v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
369  }
370  }
371  return *this;
372  }
373 
374  //--------------------------------------------------------------------
375  self_type gradient(self_type c, double k) const
376  {
377  self_type ret;
378  calc_type ik = uround(k * base_scale);
379  ret.v = lerp(v, c.v, ik);
380  ret.a = lerp(a, c.a, ik);
381  return ret;
382  }
383 
384  //--------------------------------------------------------------------
385  AGG_INLINE void add(const self_type& c, unsigned cover)
386  {
387  calc_type cv, ca;
388  if (cover == cover_mask)
389  {
390  if (c.a == base_mask)
391  {
392  *this = c;
393  return;
394  }
395  else
396  {
397  cv = v + c.v;
398  ca = a + c.a;
399  }
400  }
401  else
402  {
403  cv = v + mult_cover(c.v, cover);
404  ca = a + mult_cover(c.a, cover);
405  }
406  v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
407  a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
408  }
409 
410  //--------------------------------------------------------------------
411  static self_type no_color() { return self_type(0,0); }
412  };
413 
414  typedef gray8T<linear> gray8;
415  typedef gray8T<sRGB> sgray8;
416 
417 
418  //==================================================================gray16
419  struct gray16
420  {
421  typedef int16u value_type;
422  typedef int32u calc_type;
423  typedef int64 long_type;
424  enum base_scale_e
425  {
426  base_shift = 16,
427  base_scale = 1 << base_shift,
428  base_mask = base_scale - 1,
429  base_MSB = 1 << (base_shift - 1)
430  };
431  typedef gray16 self_type;
432 
433  value_type v;
434  value_type a;
435 
436  static value_type luminance(const rgba& c)
437  {
438  // Calculate grayscale value as per ITU-R BT.709.
439  return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
440  }
441 
442  static value_type luminance(const rgba16& c)
443  {
444  // Calculate grayscale value as per ITU-R BT.709.
445  return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
446  }
447 
448  static value_type luminance(const rgba8& c)
449  {
450  return luminance(rgba16(c));
451  }
452 
453  static value_type luminance(const srgba8& c)
454  {
455  return luminance(rgba16(c));
456  }
457 
458  static value_type luminance(const rgba32& c)
459  {
460  return luminance(rgba(c));
461  }
462 
463  //--------------------------------------------------------------------
464  gray16() {}
465 
466  //--------------------------------------------------------------------
467  explicit gray16(unsigned v_, unsigned a_ = base_mask) :
468  v(int16u(v_)), a(int16u(a_)) {}
469 
470  //--------------------------------------------------------------------
471  gray16(const self_type& c, unsigned a_) :
472  v(c.v), a(value_type(a_)) {}
473 
474  //--------------------------------------------------------------------
475  gray16(const rgba& c) :
476  v(luminance(c)),
477  a((value_type)uround(c.a * double(base_mask))) {}
478 
479  //--------------------------------------------------------------------
480  gray16(const rgba8& c) :
481  v(luminance(c)),
482  a((value_type(c.a) << 8) | c.a) {}
483 
484  //--------------------------------------------------------------------
485  gray16(const srgba8& c) :
486  v(luminance(c)),
487  a((value_type(c.a) << 8) | c.a) {}
488 
489  //--------------------------------------------------------------------
490  gray16(const rgba16& c) :
491  v(luminance(c)),
492  a(c.a) {}
493 
494  //--------------------------------------------------------------------
495  gray16(const gray8& c) :
496  v((value_type(c.v) << 8) | c.v),
497  a((value_type(c.a) << 8) | c.a) {}
498 
499  //--------------------------------------------------------------------
500  gray16(const sgray8& c) :
503 
504  //--------------------------------------------------------------------
505  operator rgba8() const
506  {
507  return rgba8(v >> 8, v >> 8, v >> 8, a >> 8);
508  }
509 
510  //--------------------------------------------------------------------
511  operator srgba8() const
512  {
513  value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v);
514  return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a));
515  }
516 
517  //--------------------------------------------------------------------
518  operator rgba16() const
519  {
520  return rgba16(v, v, v, a);
521  }
522 
523  //--------------------------------------------------------------------
524  operator rgba32() const
525  {
526  rgba32::value_type v32 = v / 65535.0f;
527  return rgba32(v32, v32, v32, a / 65535.0f);
528  }
529 
530  //--------------------------------------------------------------------
531  operator gray8() const
532  {
533  return gray8(v >> 8, a >> 8);
534  }
535 
536  //--------------------------------------------------------------------
537  operator sgray8() const
538  {
539  return sgray8(
542  }
543 
544  //--------------------------------------------------------------------
545  static AGG_INLINE double to_double(value_type a)
546  {
547  return double(a) / base_mask;
548  }
549 
550  //--------------------------------------------------------------------
551  static AGG_INLINE value_type from_double(double a)
552  {
553  return value_type(uround(a * base_mask));
554  }
555 
556  //--------------------------------------------------------------------
557  static AGG_INLINE value_type empty_value()
558  {
559  return 0;
560  }
561 
562  //--------------------------------------------------------------------
563  static AGG_INLINE value_type full_value()
564  {
565  return base_mask;
566  }
567 
568  //--------------------------------------------------------------------
569  AGG_INLINE bool is_transparent() const
570  {
571  return a == 0;
572  }
573 
574  //--------------------------------------------------------------------
575  AGG_INLINE bool is_opaque() const
576  {
577  return a == base_mask;
578  }
579 
580  //--------------------------------------------------------------------
581  // Fixed-point multiply, exact over int16u.
582  static AGG_INLINE value_type multiply(value_type a, value_type b)
583  {
584  calc_type t = a * b + base_MSB;
585  return value_type(((t >> base_shift) + t) >> base_shift);
586  }
587 
588  //--------------------------------------------------------------------
589  static AGG_INLINE value_type demultiply(value_type a, value_type b)
590  {
591  if (a * b == 0)
592  {
593  return 0;
594  }
595  else if (a >= b)
596  {
597  return base_mask;
598  }
599  else return value_type((a * base_mask + (b >> 1)) / b);
600  }
601 
602  //--------------------------------------------------------------------
603  template<typename T>
604  static AGG_INLINE T downscale(T a)
605  {
606  return a >> base_shift;
607  }
608 
609  //--------------------------------------------------------------------
610  template<typename T>
611  static AGG_INLINE T downshift(T a, unsigned n)
612  {
613  return a >> n;
614  }
615 
616  //--------------------------------------------------------------------
617  // Fixed-point multiply, almost exact over int16u.
618  // Specifically for multiplying a color component by a cover.
619  static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
620  {
621  return multiply(a, b << 8 | b);
622  }
623 
624  //--------------------------------------------------------------------
625  static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
626  {
627  return mult_cover(b, a) >> 8;
628  }
629 
630  //--------------------------------------------------------------------
631  // Interpolate p to q by a, assuming q is premultiplied by a.
632  static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
633  {
634  return p + q - multiply(p, a);
635  }
636 
637  //--------------------------------------------------------------------
638  // Interpolate p to q by a.
639  static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
640  {
641  int t = (q - p) * a + base_MSB - (p > q);
642  return value_type(p + (((t >> base_shift) + t) >> base_shift));
643  }
644 
645  //--------------------------------------------------------------------
646  self_type& clear()
647  {
648  v = a = 0;
649  return *this;
650  }
651 
652  //--------------------------------------------------------------------
653  self_type& transparent()
654  {
655  a = 0;
656  return *this;
657  }
658 
659  //--------------------------------------------------------------------
660  self_type& opacity(double a_)
661  {
662  if (a_ < 0) a = 0;
663  else if(a_ > 1) a = 1;
664  else a = (value_type)uround(a_ * double(base_mask));
665  return *this;
666  }
667 
668  //--------------------------------------------------------------------
669  double opacity() const
670  {
671  return double(a) / double(base_mask);
672  }
673 
674 
675  //--------------------------------------------------------------------
676  self_type& premultiply()
677  {
678  if (a < base_mask)
679  {
680  if(a == 0) v = 0;
681  else v = multiply(v, a);
682  }
683  return *this;
684  }
685 
686  //--------------------------------------------------------------------
687  self_type& demultiply()
688  {
689  if (a < base_mask)
690  {
691  if (a == 0)
692  {
693  v = 0;
694  }
695  else
696  {
697  calc_type v_ = (calc_type(v) * base_mask) / a;
698  v = (v_ > base_mask) ? value_type(base_mask) : value_type(v_);
699  }
700  }
701  return *this;
702  }
703 
704  //--------------------------------------------------------------------
705  self_type gradient(self_type c, double k) const
706  {
707  self_type ret;
708  calc_type ik = uround(k * base_scale);
709  ret.v = lerp(v, c.v, ik);
710  ret.a = lerp(a, c.a, ik);
711  return ret;
712  }
713 
714  //--------------------------------------------------------------------
715  AGG_INLINE void add(const self_type& c, unsigned cover)
716  {
717  calc_type cv, ca;
718  if (cover == cover_mask)
719  {
720  if (c.a == base_mask)
721  {
722  *this = c;
723  return;
724  }
725  else
726  {
727  cv = v + c.v;
728  ca = a + c.a;
729  }
730  }
731  else
732  {
733  cv = v + mult_cover(c.v, cover);
734  ca = a + mult_cover(c.a, cover);
735  }
736  v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
737  a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
738  }
739 
740  //--------------------------------------------------------------------
741  static self_type no_color() { return self_type(0,0); }
742  };
743 
744 
745  //===================================================================gray32
746  struct gray32
747  {
748  typedef float value_type;
749  typedef double calc_type;
750  typedef double long_type;
751  typedef gray32 self_type;
752 
753  value_type v;
754  value_type a;
755 
756  // Calculate grayscale value as per ITU-R BT.709.
757  static value_type luminance(double r, double g, double b)
758  {
759  return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
760  }
761 
762  static value_type luminance(const rgba& c)
763  {
764  return luminance(c.r, c.g, c.b);
765  }
766 
767  static value_type luminance(const rgba32& c)
768  {
769  return luminance(c.r, c.g, c.b);
770  }
771 
772  static value_type luminance(const rgba8& c)
773  {
774  return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0);
775  }
776 
777  static value_type luminance(const rgba16& c)
778  {
779  return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0);
780  }
781 
782  //--------------------------------------------------------------------
783  gray32() {}
784 
785  //--------------------------------------------------------------------
786  explicit gray32(value_type v_, value_type a_ = 1) :
787  v(v_), a(a_) {}
788 
789  //--------------------------------------------------------------------
790  gray32(const self_type& c, value_type a_) :
791  v(c.v), a(a_) {}
792 
793  //--------------------------------------------------------------------
794  gray32(const rgba& c) :
795  v(luminance(c)),
796  a(value_type(c.a)) {}
797 
798  //--------------------------------------------------------------------
799  gray32(const rgba8& c) :
800  v(luminance(c)),
801  a(value_type(c.a / 255.0)) {}
802 
803  //--------------------------------------------------------------------
804  gray32(const srgba8& c) :
805  v(luminance(rgba32(c))),
806  a(value_type(c.a / 255.0)) {}
807 
808  //--------------------------------------------------------------------
809  gray32(const rgba16& c) :
810  v(luminance(c)),
811  a(value_type(c.a / 65535.0)) {}
812 
813  //--------------------------------------------------------------------
814  gray32(const rgba32& c) :
815  v(luminance(c)),
816  a(value_type(c.a)) {}
817 
818  //--------------------------------------------------------------------
819  gray32(const gray8& c) :
820  v(value_type(c.v / 255.0)),
821  a(value_type(c.a / 255.0)) {}
822 
823  //--------------------------------------------------------------------
824  gray32(const sgray8& c) :
827 
828  //--------------------------------------------------------------------
829  gray32(const gray16& c) :
830  v(value_type(c.v / 65535.0)),
831  a(value_type(c.a / 65535.0)) {}
832 
833  //--------------------------------------------------------------------
834  operator rgba() const
835  {
836  return rgba(v, v, v, a);
837  }
838 
839  //--------------------------------------------------------------------
840  operator gray8() const
841  {
842  return gray8(uround(v * 255.0), uround(a * 255.0));
843  }
844 
845  //--------------------------------------------------------------------
846  operator sgray8() const
847  {
848  // Return (non-premultiplied) sRGB values.
849  return sgray8(
852  }
853 
854  //--------------------------------------------------------------------
855  operator gray16() const
856  {
857  return gray16(uround(v * 65535.0), uround(a * 65535.0));
858  }
859 
860  //--------------------------------------------------------------------
861  operator rgba8() const
862  {
863  rgba8::value_type y = uround(v * 255.0);
864  return rgba8(y, y, y, uround(a * 255.0));
865  }
866 
867  //--------------------------------------------------------------------
868  operator srgba8() const
869  {
870  srgba8::value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v);
871  return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a));
872  }
873 
874  //--------------------------------------------------------------------
875  operator rgba16() const
876  {
877  rgba16::value_type y = uround(v * 65535.0);
878  return rgba16(y, y, y, uround(a * 65535.0));
879  }
880 
881  //--------------------------------------------------------------------
882  operator rgba32() const
883  {
884  return rgba32(v, v, v, a);
885  }
886 
887  //--------------------------------------------------------------------
888  static AGG_INLINE double to_double(value_type a)
889  {
890  return a;
891  }
892 
893  //--------------------------------------------------------------------
894  static AGG_INLINE value_type from_double(double a)
895  {
896  return value_type(a);
897  }
898 
899  //--------------------------------------------------------------------
900  static AGG_INLINE value_type empty_value()
901  {
902  return 0;
903  }
904 
905  //--------------------------------------------------------------------
906  static AGG_INLINE value_type full_value()
907  {
908  return 1;
909  }
910 
911  //--------------------------------------------------------------------
912  AGG_INLINE bool is_transparent() const
913  {
914  return a <= 0;
915  }
916 
917  //--------------------------------------------------------------------
918  AGG_INLINE bool is_opaque() const
919  {
920  return a >= 1;
921  }
922 
923  //--------------------------------------------------------------------
924  static AGG_INLINE value_type invert(value_type x)
925  {
926  return 1 - x;
927  }
928 
929  //--------------------------------------------------------------------
930  static AGG_INLINE value_type multiply(value_type a, value_type b)
931  {
932  return value_type(a * b);
933  }
934 
935  //--------------------------------------------------------------------
936  static AGG_INLINE value_type demultiply(value_type a, value_type b)
937  {
938  return (b == 0) ? 0 : value_type(a / b);
939  }
940 
941  //--------------------------------------------------------------------
942  template<typename T>
943  static AGG_INLINE T downscale(T a)
944  {
945  return a;
946  }
947 
948  //--------------------------------------------------------------------
949  template<typename T>
950  static AGG_INLINE T downshift(T a, unsigned n)
951  {
952  return n > 0 ? a / (1 << n) : a;
953  }
954 
955  //--------------------------------------------------------------------
956  static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
957  {
958  return value_type(a * b / cover_mask);
959  }
960 
961  //--------------------------------------------------------------------
962  static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
963  {
964  return cover_type(uround(a * b));
965  }
966 
967  //--------------------------------------------------------------------
968  // Interpolate p to q by a, assuming q is premultiplied by a.
969  static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
970  {
971  return (1 - a) * p + q; // more accurate than "p + q - p * a"
972  }
973 
974  //--------------------------------------------------------------------
975  // Interpolate p to q by a.
976  static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
977  {
978  // The form "p + a * (q - p)" avoids a multiplication, but may produce an
979  // inaccurate result. For example, "p + (q - p)" may not be exactly equal
980  // to q. Therefore, stick to the basic expression, which at least produces
981  // the correct result at either extreme.
982  return (1 - a) * p + a * q;
983  }
984 
985  //--------------------------------------------------------------------
986  self_type& clear()
987  {
988  v = a = 0;
989  return *this;
990  }
991 
992  //--------------------------------------------------------------------
993  self_type& transparent()
994  {
995  a = 0;
996  return *this;
997  }
998 
999  //--------------------------------------------------------------------
1000  self_type& opacity(double a_)
1001  {
1002  if (a_ < 0) a = 0;
1003  else if (a_ > 1) a = 1;
1004  else a = value_type(a_);
1005  return *this;
1006  }
1007 
1008  //--------------------------------------------------------------------
1009  double opacity() const
1010  {
1011  return a;
1012  }
1013 
1014 
1015  //--------------------------------------------------------------------
1016  self_type& premultiply()
1017  {
1018  if (a < 0) v = 0;
1019  else if(a < 1) v *= a;
1020  return *this;
1021  }
1022 
1023  //--------------------------------------------------------------------
1024  self_type& demultiply()
1025  {
1026  if (a < 0) v = 0;
1027  else if (a < 1) v /= a;
1028  return *this;
1029  }
1030 
1031  //--------------------------------------------------------------------
1032  self_type gradient(self_type c, double k) const
1033  {
1034  return self_type(
1035  value_type(v + (c.v - v) * k),
1036  value_type(a + (c.a - a) * k));
1037  }
1038 
1039  //--------------------------------------------------------------------
1040  static self_type no_color() { return self_type(0,0); }
1041  };
1042 }
1043 
1044 
1045 
1046 
1047 #endif
Definition: agg_arc.cpp:24