/* * \brief Generic interface of graphics backend and chunky template * \date 2005-10-24 * \author Norman Feske */ /* * Copyright (C) 2005-2013 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ #ifndef _INCLUDE__SCOUT__CANVAS_H_ #define _INCLUDE__SCOUT__CANVAS_H_ #include #include #include #include #include #include #include #include #include #include #include namespace Scout { using Genode::Color; using Genode::Pixel_rgba; typedef Text_painter::Font Font; struct Canvas_base; template class Canvas; } struct Scout::Canvas_base : Texture_allocator { virtual ~Canvas_base() { } virtual Area size() const = 0; virtual Rect clip() const = 0; virtual void clip(Rect rect) = 0; virtual void draw_box(int x, int y, int w, int h, Color c) = 0; virtual void draw_string(int x, int y, Font *font, Color color, char const *str, int len) = 0; virtual void draw_horizontal_shadow(Rect rect, int intensity) = 0; virtual void draw_icon(Rect, Texture_base const &, unsigned alpha) = 0; virtual void draw_sky_texture(int py, Sky_texture_painter::Sky_texture_base const &, bool detail) = 0; virtual void draw_refracted_icon(Point pos, Scout::Refracted_icon_painter::Distmap const &distmap, Texture_base &tmp, Texture_base const &foreground, bool detail, bool filter_backbuf) = 0; virtual void draw_texture(Point pos, Texture_base const &texture) = 0; }; #include #include namespace Genode { template <> inline void Texture::rgba(unsigned char const *rgba, unsigned len, int y) { if (len > size().w()) len = size().w(); if (y < 0 || y >= (int)size().h()) return; Genode::Pixel_rgb565 *dst_pixel = pixel() + y*size().w(); unsigned char *dst_alpha = alpha() ? alpha() + y*size().w() : 0; Genode::Dither_matrix::Row dither_row = Dither_matrix::row(y); for (unsigned i = 0; i < len; i++) { int v = dither_row.value(i) >> 5; int r = *rgba++ + v; int g = *rgba++ + v; int b = *rgba++ + v; int a = *rgba++ + v; using Genode::min; dst_pixel[i].rgba(min(r, 255), min(g, 255), min(b, 255)); if (dst_alpha) dst_alpha[i] = min(a, 255); } } } template class Scout::Canvas : public Canvas_base { private: Genode::Surface _surface; public: Canvas(PT *base, Area size) : _surface(base, size) { } Area size() const { return _surface.size(); } Rect clip() const { return _surface.clip(); } void clip(Rect rect) { _surface.clip(rect); } void draw_string(int x, int y, Font *font, Color color, char const *str, int len) { char buf[len + 1]; Genode::strncpy(buf, str, len + 1); Text_painter::paint(_surface, Point(x, y), *font, color, buf); } void draw_box(int x, int y, int w, int h, Color c) { Box_painter::paint(_surface, Rect(Point(x, y), Area(w, h)), c); } void draw_horizontal_shadow(Rect rect, int intensity) { Horizontal_shadow_painter::paint(_surface, rect, intensity); } void draw_icon(Rect rect, Texture_base const &icon, unsigned alpha) { Icon_painter::paint(_surface, rect, static_cast const &>(icon), alpha); } void draw_sky_texture(int py, Sky_texture_painter::Sky_texture_base const &texture, bool detail) { Sky_texture_painter::paint(_surface, py, texture, detail); } void draw_refracted_icon(Point pos, Scout::Refracted_icon_painter::Distmap const &distmap, Texture_base &tmp, Texture_base const &foreground, bool detail, bool filter_backbuf) { using namespace Scout; Refracted_icon_painter::paint(_surface, pos, distmap, static_cast &>(tmp), static_cast const &>(foreground), detail, filter_backbuf); } void draw_texture(Point pos, Texture_base const &texture_base) { Texture const &texture = static_cast const &>(texture_base); Texture_painter::paint(_surface, texture, Color(0, 0, 0), pos, Texture_painter::SOLID, true); } Texture_base *alloc_texture(Area size, bool has_alpha) { using namespace Genode; PT *pixel = (PT *)env()->heap()->alloc(size.count()*sizeof(PT)); unsigned char *alpha = 0; if (has_alpha) alpha = (unsigned char *)env()->heap()->alloc(size.count()); return new (env()->heap()) Genode::Texture(pixel, alpha, size); } virtual void free_texture(Texture_base *texture_base) { using namespace Genode; Texture *texture = static_cast *>(texture_base); size_t const num_pixels = texture->size().count(); if (texture->alpha()) env()->heap()->free(texture->alpha(), num_pixels); env()->heap()->free(texture->pixel(), sizeof(PT)*num_pixels); destroy(env()->heap(), texture); } virtual void set_rgba_texture(Texture_base *texture_base, unsigned char const *rgba, unsigned len, int y) { Texture *texture = static_cast *>(texture_base); texture->rgba(rgba, len, y); } }; #endif /* _INCLUDE__SCOUT__CANVAS_H_ */