3 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
12 #include <l4/sys/types.h>
13 #include <l4/re/video/colors>
23 /*** int-to-type template */
28 /*** Conversion for a single color component */
29 template< typename From, typename To >
30 static inline typename To::Value convert_comp(typename From::Value c, IT<true> const &)
32 enum { Sh = From::Shift - To::Shift + From::Size - To::Size };
33 return ((c & From::Mask) >> Sh) & To::Mask;
36 template< typename From, typename To >
37 static inline typename To::Value convert_comp(typename From::Value c, IT<false> const &)
39 enum { Sh = From::Shift - To::Shift + From::Size - To::Size };
40 return (((typename To::Value)(c & From::Mask)) << -Sh) & To::Mask;
43 template< typename From, typename To >
44 static inline typename To::Value convert_comp(typename From::Value c)
46 enum { Sh = From::Shift - To::Shift + From::Size - To::Size };
47 return convert_comp<From, To>(c, IT<(Sh > 0)>());
51 /*** Trivial pixel type with a size of a native data type and size-alignment. */
52 template< typename T >
56 T _v; /* refernece to video memory representation */
59 enum { Bpp = sizeof(T) };
62 explicit Trivial_pixel(T v) : _v(v) {}
64 T v() const { return _v; }
65 } __attribute__((packed));
68 /*** Encapsulation of properties of a pixel */
69 /* A pixel occupies the given number of bytes in video memory and
70 * has a representation in a some machine useable type (byte, short,
76 /*** Spezilization for 2byte */
81 typedef _Local::Trivial_pixel<l4_uint16_t> Pixel;
84 /*** Spezialization for 4byte */
89 typedef _Local::Trivial_pixel<l4_uint32_t> Pixel;
93 /*** Spezialization for 3byte */
98 /*** Encapsulation for 3byte memory references */
99 /* Looks like a pointer to a native data type */
104 typedef l4_uint32_t Value;
109 { return (Value)(*(l4_uint16_t const *)_b) | ((l4_uint32_t)_b[2] << 16); }
114 explicit Pixel(Value c)
116 *(l4_uint16_t*)_b = (l4_uint16_t)c;
120 Value v() const { return get(); }
121 } __attribute__((packed));
126 struct Pixel_info : public L4Re::Video::Pixel_info
130 Pixel_info(char bytes, char r, char rs, char g, char gs,
131 char b, char bs, char a, char as)
132 : L4Re::Video::Pixel_info(bytes, r, rs, g, gs, b, bs, a, as)
138 Color(int r, int g, int b, int a = 0xffff) : r(r), g(g), b(b), a(a) {}
141 Color get(void const *d) const
144 switch (bytes_per_pixel())
147 v = *(unsigned short const *)d;
152 v = *(unsigned const *)d;
159 return Color(r().get(v), g().get(v), b().get(v), a().get(v));
162 void set(void *d, Color const &c) const
164 unsigned v = r().set(c.r) | g().set(c.g) | b().set(c.b) | a().set(c.a);
165 switch (bytes_per_pixel())
168 *(unsigned short *)d = v;
173 char *_d = (char *)d;
192 int _Rshift, int _Rsize,
193 int _Gshift, int _Gsize,
194 int _Bshift, int _Bsize,
195 int _Ashift = 0, int _Asize = 0
199 enum { Extra_alpha = 128 };
200 typedef typename PT::Pixel Pixel;
201 template< int _size, int _shift >
202 struct C { enum { Size = _size, Shift = _shift }; };
204 typedef C<_Rsize, _Rshift> R;
205 typedef C<_Gsize, _Gshift> G;
206 typedef C<_Bsize, _Bshift> B;
207 typedef C<_Asize, _Ashift> A;
212 template< template < class UT > class CT, typename CD, bool AC >
215 template< template < class UT > class CT, typename CD >
216 struct Alpha_traits< CT, CD, true >
218 typedef CT< Color_def< Pixel_traits< CD::Pixel::Bpp >,
219 CD::R::Shift, CD::R::Size,
220 CD::G::Shift, CD::G::Size,
221 CD::B::Shift, CD::B::Size> > No_alpha;
223 typedef CT<CD> Alpha;
226 template< template < class UT > class CT, typename CD >
227 struct Alpha_traits< CT, CD, false >
229 typedef CT<CD> No_alpha;
230 typedef CT< Color_def< Pixel_traits< CD::Pixel::Bpp >,
231 CD::R::Shift, CD::R::Size,
232 CD::G::Shift, CD::G::Size,
233 CD::B::Shift, CD::B::Size> > Alpha;
237 /*** Encapsulation of color bit fields of any kind */
238 /* _Pixel must be the Pixel for the mode.
239 * _<X>shift and _<X>size is the bit shift and number of bits used for
240 * each color (and alpha)
243 * Color the register representation of a color.
244 * Pixel the reference to a pixel in video memory.
245 * R,G,B,A the traits for the single components
246 * (define Shift, Size, and Mask for each color component)
247 * C_space the sorted representation of the color components,
248 * Used to find the uppermost, middle, and lowermost component
252 * blend does optimized alpha blending
254 template< typename CD >
258 class Pixel : public CD::Pixel
261 typedef Color_traits<CD> Traits;
265 explicit Pixel(typename CD::Pixel::Value v)
268 } __attribute__((packed));
270 typedef Color_traits<CD> This;
273 Bpp = CD::Pixel::Bpp,
274 Bpp_xalpha = Bpp + (CD::A::Size == 0),
275 Need_extra_alpha = (CD::A::Size == 0)
278 static int bytes_per_pixel(bool alpha) { return alpha ? Bpp_xalpha : Bpp; }
280 template< int _Shift, int _Size, typename _C = typename CD::Pixel::Value >
289 Mask = ((1UL << Size) - 1) << Shift
292 static unsigned get(Value c)
293 { return (c & Mask) >> Shift; }
296 typedef Component<CD::R::Shift, CD::R::Size> R;
297 typedef Component<CD::G::Shift, CD::G::Size> G;
298 typedef Component<CD::B::Shift, CD::B::Size> B;
299 typedef Component<CD::A::Shift, CD::A::Size> A;
301 /** Sorting template for color components. */
306 bool _RG = ((unsigned)_R::Shift > (unsigned)_G::Shift),
307 bool _RB = ((unsigned)_R::Shift > (unsigned)_B::Shift),
308 bool _BG = ((unsigned)_B::Shift > (unsigned)_G::Shift)
312 template< typename _R, typename _G, typename _B >
313 class C_list<_R, _G, _B, true, true, true>
321 template< typename _R, typename _G, typename _B >
322 class C_list<_R, _G, _B, true, true, false>
330 template< typename _R, typename _G, typename _B >
331 class C_list<_R, _G, _B, true, false, true>
339 template< typename _R, typename _G, typename _B >
340 class C_list<_R, _G, _B, false, true, false>
348 template< typename _R, typename _G, typename _B >
349 class C_list<_R, _G, _B, false, false, false>
357 template< typename _R, typename _G, typename _B >
358 class C_list<_R, _G, _B, false, false, true>
366 class C_space : public C_list<R,G,B>
371 Mix_mask = (R::Mask | G::Mask | B::Mask)
372 & ~((1UL << R::Shift) | (1UL << G::Shift)
378 typedef typename _Local::Alpha_traits<Mag_gfx::Color_traits, CD, (A::Size > 0)>::No_alpha No_alpha;
379 typedef typename _Local::Alpha_traits<Mag_gfx::Color_traits, CD, (A::Size > 0)>::Alpha Alpha;
381 /** Encasulation for a color value of this color mode.
382 * The Color type is an efficient native representation of the color
383 * of a pixel for this color mode. It is designed to be kept in a
389 /** The value type (native data type to carry the color value. */
390 typedef typename CD::Pixel::Value Value;
392 /** The info for the red component of the color. */
393 typedef typename This::R R;
395 /** The info for the green component of the color. */
396 typedef typename This::G G;
398 /** The info for the blue component of the color. */
399 typedef typename This::B B;
401 /** The info for the alpha channel of the color. */
402 typedef typename This::A A;
404 /** Reference to the surrounding color traits. */
407 enum { Mix_mask = C_space::Mix_mask };
408 enum { Amax = (1UL << A::Size) - 1 };
413 static Value _m(unsigned v, int s, unsigned m)
416 return (v >> (-s)) & m;
423 explicit Color(Value v) : _c(v) {}
425 Color(Pixel p) : _c(p.v()) {}
426 Color(Pixel_info::Color const &c)
427 : _c(_m(c.r, R::Shift - 16 + R::Size, R::Mask)
428 |_m(c.g, G::Shift - 16 + G::Size, G::Mask)
429 |_m(c.b, B::Shift - 16 + B::Size, B::Mask)
430 |_m(c.a, A::Shift - 16 + A::Size, A::Mask))
433 Color(typename No_alpha::Color const &o)
434 : _c(o.v() | ((Value)Amax << A::Shift))
437 Color(typename No_alpha::Color const &o, int a)
438 : _c(o.v() | ((Value)a << A::Shift))
441 Color(int r, int g, int b, int a = Amax)
442 : _c((r << R::Shift) | (g << G::Shift) | (b << B::Shift)
443 | ((Value)a << A::Shift))
446 int r() const { return (_c & R::Mask) >> R::Shift; }
447 int g() const { return (_c & G::Mask) >> G::Shift; }
448 int b() const { return (_c & B::Mask) >> B::Shift; }
449 int a() const { return A::Size ? (_c & A::Mask) >> A::Shift : (Value)Amax; }
451 Value v() const { return _c; }
452 //operator Value () const { return _c; }
453 operator Pixel () const { return Pixel(_c); }
455 Color operator + (Color const &o) const { return Color(_c + o._c); }
458 /** Blend color with alpha value (0-255).
459 * \param color The original color.
460 * \param alpha The alpha value (0 = Transparent, 255 = Opaque)
462 static Color blend(Color color, int alpha)
466 AMask = C_space::Msb::Mask | C_space::Lsb::Mask,
467 BMask = C_space::Mid::Mask,
468 Gap = C_space::Mid::Size,
474 return Color(((((alpha >> AAs) * (color.v() & AMask)) >> As) & AMask)
475 | (((alpha * (color.v() & BMask)) >> Bs) & BMask));
478 /** Mix background and foreground color with alpha blending.
479 * \param bg The background color.
480 * \param fg the foreground color.
481 * \param alpha The alpha value of the foreground (0 = Transparent, 255 = Opaque)
483 static Color mix(Color bg, Color fg, int alpha)
488 return blend(bg, 256 - alpha) + blend(fg, alpha);
491 /** Calculate the avarage of two colors.
492 * \param c1 The first color.
493 * \param c2 The second color.
494 * \return The average value.
496 static Color avr(Color c1, Color c2)
498 return Color(((c1.v() & Color::Mix_mask) >> 1) + ((c2.v() & Color::Mix_mask) >> 1));
501 /** Calculate the avarage of four colors.
502 * \param c1 The first color.
503 * \param c2 The second color.
504 * \param c3 The third color.
505 * \param c4 The fourth color.
506 * \return The average value.
508 static Color avr(Color c1, Color c2, Color c3, Color c4)
509 { return avr(avr(c1, c2), avr(c3, c4)); }
511 typedef Pixel_info const *Type;
512 /** Returns a pointer to the dynamic pixel info for the color mode. */
515 static Pixel_info pixel_info
518 CD::R::Size, CD::R::Shift,
519 CD::G::Size, CD::G::Shift,
520 CD::B::Size, CD::B::Shift,
521 CD::A::Size, CD::A::Shift
527 /** Often used color black. */
528 static Color const Black;
530 /** Otfen used color White. */
531 static Color const White;
535 template< typename CD >
536 typename Color_traits<CD>::Color const Color_traits<CD>::Black(0);
538 template< typename CD >
539 typename Color_traits<CD>::Color const Color_traits<CD>::White(~0, ~0, ~0);
546 * convert to convert a single color from one color space to another
547 * blit paints the given color to the given pixel, does color
548 * conversion if necessary, and considers alpha values if
551 template< typename From, typename To >
555 typedef typename To::Color T_color;
556 typedef typename To::Pixel T_pixel;
557 typedef typename From::Color F_color;
559 static T_color convert(F_color c)
561 typedef typename To::R TR;
562 typedef typename To::G TG;
563 typedef typename To::B TB;
564 typedef typename From::R FR;
565 typedef typename From::G FG;
566 typedef typename From::B FB;
567 return T_color(convert_comp<FR, TR>(c.v())
568 | convert_comp<FG, TG>(c.v())
569 | convert_comp<FB, TB>(c.v()));
572 static void blit(F_color c, T_pixel *d)
574 if (From::A::Size > 0)
575 *d = To::blend(convert(c), From::A::get(c))
576 + To::blend(*d, 255 - From::A::get(c));
583 /*** Specialized conversion if source and target color space are equal */
584 template< typename T >
588 typedef typename T::Color T_color;
589 typedef typename T::Pixel T_pixel;
590 typedef typename T::Color F_color;
592 static T_color convert(F_color c) { return c; }
593 static void blit(F_color c, T_pixel *d)
596 *d = T::blend(c, T::A::get(c)) + T::blend(*d, 255 - T::A::get(c));
604 template< typename C1, typename C2 >
606 { return _Local::Conv<typename C2::Traits, typename C1::Traits>::convert(c); }
608 template< typename C >
609 C color_50(C const &c)
610 { return C((c.v() & (typename C::Value)C::Mix_mask) >> 1); }
613 /*** Typical instances for color spaces */
614 typedef Color_traits<Color_def<Pixel_traits<2>, 10,5,5,5,0,5> > Rgb15;
615 typedef Color_traits<Color_def<Pixel_traits<2>, 0,5,5,5,10,5> > Bgr15;
616 typedef Color_traits<Color_def<Pixel_traits<2>, 11,5,5,6,0,5> > Rgb16;
617 typedef Color_traits<Color_def<Pixel_traits<2>, 0,5,5,6,11,5> > Bgr16;
618 typedef Color_traits<Color_def<Pixel_traits<3>, 16,8,8,8,0,8> > Rgb24;
619 typedef Color_traits<Color_def<Pixel_traits<4>, 16,8,8,8,0,8> > Rgb32;
620 typedef Color_traits<Color_def<Pixel_traits<4>, 0,8,8,8,16,8> > Bgr32;
621 typedef Color_traits<Color_def<Pixel_traits<4>, 16,8,8,8,0,8,24,8> > Rgba32;