5 #include <l4/sys/types.h>
6 #include <l4/re/video/colors>
16 /*** int-to-type template */
21 /*** Conversion for a single color component */
22 template< typename From, typename To >
23 static inline typename To::Value convert_comp(typename From::Value c, IT<true> const &)
25 enum { Sh = From::Shift - To::Shift + From::Size - To::Size };
26 return ((c & From::Mask) >> Sh) & To::Mask;
29 template< typename From, typename To >
30 static inline typename To::Value convert_comp(typename From::Value c, IT<false> const &)
32 enum { Sh = From::Shift - To::Shift + From::Size - To::Size };
33 return (((typename To::Value)(c & From::Mask)) << -Sh) & To::Mask;
36 template< typename From, typename To >
37 static inline typename To::Value convert_comp(typename From::Value c)
39 enum { Sh = From::Shift - To::Shift + From::Size - To::Size };
40 return convert_comp<From, To>(c, IT<(Sh > 0)>());
44 /*** Trivial pixel type with a size of a native data type and size-alignment. */
45 template< typename T >
49 T _v; /* refernece to video memory representation */
52 enum { Bpp = sizeof(T) };
55 explicit Trivial_pixel(T v) : _v(v) {}
57 T v() const { return _v; }
58 } __attribute__((packed));
61 /*** Encapsulation of properties of a pixel */
62 /* A pixel occupies the given number of bytes in video memory and
63 * has a representation in a some machine useable type (byte, short,
69 /*** Spezilization for 2byte */
74 typedef _Local::Trivial_pixel<l4_uint16_t> Pixel;
77 /*** Spezialization for 4byte */
82 typedef _Local::Trivial_pixel<l4_uint32_t> Pixel;
86 /*** Spezialization for 3byte */
91 /*** Encapsulation for 3byte memory references */
92 /* Looks like a pointer to a native data type */
97 typedef l4_uint32_t Value;
102 { return (Value)(*(l4_uint16_t const *)_b) | ((l4_uint32_t)_b[2] << 16); }
107 explicit Pixel(Value c)
109 *(l4_uint16_t*)_b = (l4_uint16_t)c;
113 Value v() const { return get(); }
114 } __attribute__((packed));
119 struct Pixel_info : public L4Re::Video::Pixel_info
123 Pixel_info(char bytes, char r, char rs, char g, char gs,
124 char b, char bs, char a, char as)
125 : L4Re::Video::Pixel_info(bytes, r, rs, g, gs, b, bs, a, as)
131 Color(int r, int g, int b, int a = 0xffff) : r(r), g(g), b(b), a(a) {}
134 Color get(void const *d) const
137 switch (bytes_per_pixel())
140 v = *(unsigned short const *)d;
145 v = *(unsigned const *)d;
152 return Color(r().get(v), g().get(v), b().get(v), a().get(v));
155 void set(void *d, Color const &c) const
157 unsigned v = r().set(c.r) | g().set(c.g) | b().set(c.b) | a().set(c.a);
158 switch (bytes_per_pixel())
161 *(unsigned short *)d = v;
166 char *_d = (char *)d;
185 int _Rshift, int _Rsize,
186 int _Gshift, int _Gsize,
187 int _Bshift, int _Bsize,
188 int _Ashift = 0, int _Asize = 0
192 enum { Extra_alpha = 128 };
193 typedef typename PT::Pixel Pixel;
194 template< int _size, int _shift >
195 struct C { enum { Size = _size, Shift = _shift }; };
197 typedef C<_Rsize, _Rshift> R;
198 typedef C<_Gsize, _Gshift> G;
199 typedef C<_Bsize, _Bshift> B;
200 typedef C<_Asize, _Ashift> A;
205 template< template < class UT > class CT, typename CD, bool AC >
208 template< template < class UT > class CT, typename CD >
209 struct Alpha_traits< CT, CD, true >
211 typedef CT< Color_def< Pixel_traits< CD::Pixel::Bpp >,
212 CD::R::Shift, CD::R::Size,
213 CD::G::Shift, CD::G::Size,
214 CD::B::Shift, CD::B::Size> > No_alpha;
216 typedef CT<CD> Alpha;
219 template< template < class UT > class CT, typename CD >
220 struct Alpha_traits< CT, CD, false >
222 typedef CT<CD> No_alpha;
223 typedef CT< Color_def< Pixel_traits< CD::Pixel::Bpp >,
224 CD::R::Shift, CD::R::Size,
225 CD::G::Shift, CD::G::Size,
226 CD::B::Shift, CD::B::Size> > Alpha;
230 /*** Encapsulation of color bit fields of any kind */
231 /* _Pixel must be the Pixel for the mode.
232 * _<X>shift and _<X>size is the bit shift and number of bits used for
233 * each color (and alpha)
236 * Color the register representation of a color.
237 * Pixel the reference to a pixel in video memory.
238 * R,G,B,A the traits for the single components
239 * (define Shift, Size, and Mask for each color component)
240 * C_space the sorted representation of the color components,
241 * Used to find the uppermost, middle, and lowermost component
245 * blend does optimized alpha blending
247 template< typename CD >
251 class Pixel : public CD::Pixel
254 typedef Color_traits<CD> Traits;
258 explicit Pixel(typename CD::Pixel::Value v)
261 } __attribute__((packed));
263 typedef Color_traits<CD> This;
266 Bpp = CD::Pixel::Bpp,
267 Bpp_xalpha = Bpp + (CD::A::Size == 0),
268 Need_extra_alpha = (CD::A::Size == 0)
271 static int bytes_per_pixel(bool alpha) { return alpha ? Bpp_xalpha : Bpp; }
273 template< int _Shift, int _Size, typename _C = typename CD::Pixel::Value >
282 Mask = ((1UL << Size) - 1) << Shift
285 static unsigned get(Value c)
286 { return (c & Mask) >> Shift; }
289 typedef Component<CD::R::Shift, CD::R::Size> R;
290 typedef Component<CD::G::Shift, CD::G::Size> G;
291 typedef Component<CD::B::Shift, CD::B::Size> B;
292 typedef Component<CD::A::Shift, CD::A::Size> A;
294 /** Sorting template for color components. */
299 bool _RG = ((unsigned)_R::Shift > (unsigned)_G::Shift),
300 bool _RB = ((unsigned)_R::Shift > (unsigned)_B::Shift),
301 bool _BG = ((unsigned)_B::Shift > (unsigned)_G::Shift)
305 template< typename _R, typename _G, typename _B >
306 class C_list<_R, _G, _B, true, true, true>
314 template< typename _R, typename _G, typename _B >
315 class C_list<_R, _G, _B, true, true, false>
323 template< typename _R, typename _G, typename _B >
324 class C_list<_R, _G, _B, true, false, true>
332 template< typename _R, typename _G, typename _B >
333 class C_list<_R, _G, _B, false, true, false>
341 template< typename _R, typename _G, typename _B >
342 class C_list<_R, _G, _B, false, false, false>
350 template< typename _R, typename _G, typename _B >
351 class C_list<_R, _G, _B, false, false, true>
359 class C_space : public C_list<R,G,B>
364 Mix_mask = (R::Mask | G::Mask | B::Mask)
365 & ~((1UL << R::Shift) | (1UL << G::Shift)
371 typedef typename _Local::Alpha_traits<Mag_gfx::Color_traits, CD, (A::Size > 0)>::No_alpha No_alpha;
372 typedef typename _Local::Alpha_traits<Mag_gfx::Color_traits, CD, (A::Size > 0)>::Alpha Alpha;
374 /** Encasulation for a color value of this color mode.
375 * The Color type is an efficient native representation of the color
376 * of a pixel for this color mode. It is designed to be kept in a
382 /** The value type (native data type to carry the color value. */
383 typedef typename CD::Pixel::Value Value;
385 /** The info for the red component of the color. */
386 typedef typename This::R R;
388 /** The info for the green component of the color. */
389 typedef typename This::G G;
391 /** The info for the blue component of the color. */
392 typedef typename This::B B;
394 /** The info for the alpha channel of the color. */
395 typedef typename This::A A;
397 /** Reference to the surrounding color traits. */
400 enum { Mix_mask = C_space::Mix_mask };
401 enum { Amax = (1UL << A::Size) - 1 };
406 static Value _m(unsigned v, int s, unsigned m)
409 return (v >> (-s)) & m;
416 explicit Color(Value v) : _c(v) {}
418 Color(Pixel p) : _c(p.v()) {}
419 Color(Pixel_info::Color const &c)
420 : _c(_m(c.r, R::Shift - 16 + R::Size, R::Mask)
421 |_m(c.g, G::Shift - 16 + G::Size, G::Mask)
422 |_m(c.b, B::Shift - 16 + B::Size, B::Mask)
423 |_m(c.a, A::Shift - 16 + A::Size, A::Mask))
426 Color(typename No_alpha::Color const &o)
427 : _c(o.v() | ((Value)Amax << A::Shift))
430 Color(typename No_alpha::Color const &o, int a)
431 : _c(o.v() | ((Value)a << A::Shift))
434 Color(int r, int g, int b, int a = Amax)
435 : _c((r << R::Shift) | (g << G::Shift) | (b << B::Shift)
436 | ((Value)a << A::Shift))
439 int r() const { return (_c & R::Mask) >> R::Shift; }
440 int g() const { return (_c & G::Mask) >> G::Shift; }
441 int b() const { return (_c & B::Mask) >> B::Shift; }
442 int a() const { return A::Size ? (_c & A::Mask) >> A::Shift : (Value)Amax; }
444 Value v() const { return _c; }
445 //operator Value () const { return _c; }
446 operator Pixel () const { return Pixel(_c); }
448 Color operator + (Color const &o) const { return Color(_c + o._c); }
451 /** Blend color with alpha value (0-255).
452 * \param color The original color.
453 * \param alpha The alpha value (0 = Transparent, 255 = Opaque)
455 static Color blend(Color color, int alpha)
459 AMask = C_space::Msb::Mask | C_space::Lsb::Mask,
460 BMask = C_space::Mid::Mask,
461 Gap = C_space::Mid::Size,
467 return Color(((((alpha >> AAs) * (color.v() & AMask)) >> As) & AMask)
468 | (((alpha * (color.v() & BMask)) >> Bs) & BMask));
471 /** Mix background and foreground color with alpha blending.
472 * \param bg The background color.
473 * \param fg the foreground color.
474 * \param alpha The alpha value of the foreground (0 = Transparent, 255 = Opaque)
476 static Color mix(Color bg, Color fg, int alpha)
481 return blend(bg, 256 - alpha) + blend(fg, alpha);
484 /** Calculate the avarage of two colors.
485 * \param c1 The first color.
486 * \param c2 The second color.
487 * \return The average value.
489 static Color avr(Color c1, Color c2)
491 return Color(((c1.v() & Color::Mix_mask) >> 1) + ((c2.v() & Color::Mix_mask) >> 1));
494 /** Calculate the avarage of four colors.
495 * \param c1 The first color.
496 * \param c2 The second color.
497 * \param c3 The third color.
498 * \param c4 The fourth color.
499 * \return The average value.
501 static Color avr(Color c1, Color c2, Color c3, Color c4)
502 { return avr(avr(c1, c2), avr(c3, c4)); }
504 typedef Pixel_info const *Type;
505 /** Returns a pointer to the dynamic pixel info for the color mode. */
508 static Pixel_info pixel_info
511 CD::R::Size, CD::R::Shift,
512 CD::G::Size, CD::G::Shift,
513 CD::B::Size, CD::B::Shift,
514 CD::A::Size, CD::A::Shift
520 /** Often used color black. */
521 static Color const Black;
523 /** Otfen used color White. */
524 static Color const White;
528 template< typename CD >
529 typename Color_traits<CD>::Color const Color_traits<CD>::Black(0);
531 template< typename CD >
532 typename Color_traits<CD>::Color const Color_traits<CD>::White(~0, ~0, ~0);
539 * convert to convert a single color from one color space to another
540 * blit paints the given color to the given pixel, does color
541 * conversion if necessary, and considers alpha values if
544 template< typename From, typename To >
548 typedef typename To::Color T_color;
549 typedef typename To::Pixel T_pixel;
550 typedef typename From::Color F_color;
552 static T_color convert(F_color c)
554 typedef typename To::R TR;
555 typedef typename To::G TG;
556 typedef typename To::B TB;
557 typedef typename From::R FR;
558 typedef typename From::G FG;
559 typedef typename From::B FB;
560 return T_color(convert_comp<FR, TR>(c.v())
561 | convert_comp<FG, TG>(c.v())
562 | convert_comp<FB, TB>(c.v()));
565 static void blit(F_color c, T_pixel *d)
567 if (From::A::Size > 0)
568 *d = To::blend(convert(c), From::A::get(c))
569 + To::blend(*d, 255 - From::A::get(c));
576 /*** Specialized conversion if source and target color space are equal */
577 template< typename T >
581 typedef typename T::Color T_color;
582 typedef typename T::Pixel T_pixel;
583 typedef typename T::Color F_color;
585 static T_color convert(F_color c) { return c; }
586 static void blit(F_color c, T_pixel *d)
589 *d = T::blend(c, T::A::get(c)) + T::blend(*d, 255 - T::A::get(c));
597 template< typename C1, typename C2 >
599 { return _Local::Conv<typename C2::Traits, typename C1::Traits>::convert(c); }
601 template< typename C >
602 C color_50(C const &c)
603 { return C((c.v() & (typename C::Value)C::Mix_mask) >> 1); }
606 /*** Typical instances for color spaces */
607 typedef Color_traits<Color_def<Pixel_traits<2>, 10,5,5,5,0,5> > Rgb15;
608 typedef Color_traits<Color_def<Pixel_traits<2>, 0,5,5,5,10,5> > Bgr15;
609 typedef Color_traits<Color_def<Pixel_traits<2>, 11,5,5,6,0,5> > Rgb16;
610 typedef Color_traits<Color_def<Pixel_traits<2>, 0,5,5,6,11,5> > Bgr16;
611 typedef Color_traits<Color_def<Pixel_traits<3>, 16,8,8,8,0,8> > Rgb24;
612 typedef Color_traits<Color_def<Pixel_traits<4>, 16,8,8,8,0,8> > Rgb32;
613 typedef Color_traits<Color_def<Pixel_traits<4>, 16,8,8,8,0,8,24,8> > Rgba32;