diff --git a/demo/src/server/nitlog/main.cc b/demo/src/server/nitlog/main.cc index 8cea22ee5b..6e8dfe77b2 100644 --- a/demo/src/server/nitlog/main.cc +++ b/demo/src/server/nitlog/main.cc @@ -24,18 +24,24 @@ #include <nitpicker_view/client.h> #include <timer_session/connection.h> #include <input/event.h> +#include <os/pixel_rgb565.h> /* * Nitpicker's graphics backend */ -#include <nitpicker_gfx/chunky_canvas.h> -#include <nitpicker_gfx/pixel_rgb565.h> -#include <nitpicker_gfx/font.h> +#include <nitpicker_gfx/text_painter.h> +#include <nitpicker_gfx/box_painter.h> enum { LOG_W = 80 }; /* number of visible characters per line */ enum { LOG_H = 25 }; /* number of lines of log window */ +typedef Text_painter::Font Font; +typedef Genode::Surface_base::Point Point; +typedef Genode::Surface_base::Area Area; +typedef Genode::Surface_base::Rect Rect; +typedef Genode::Color Color; + /* * Font initialization @@ -44,6 +50,47 @@ extern char _binary_mono_tff_start; Font default_font(&_binary_mono_tff_start); +/** + * Pixel-type-independent interface to graphics backend + */ +struct Canvas_base +{ + virtual void draw_string(Point p, Font const &font, Color color, + char const *sstr) = 0; + + virtual void draw_box(Rect rect, Color color) = 0; +}; + + +/** + * Pixel-type-specific graphics backend + */ +template <typename PT> +class Canvas : public Canvas_base +{ + private: + + Genode::Surface<PT> _surface; + + public: + + Canvas(PT *base, Area size) : _surface(base, size) { } + + void clip(Rect rect) { _surface.clip(rect); } + + void draw_string(Point p, Font const &font, Color color, + char const *sstr) + { + Text_painter::paint(_surface, p, font, color, sstr); + } + + void draw_box(Rect rect, Color color) + { + Box_painter::paint(_surface, rect, color); + } +}; + + class Log_entry { private: @@ -90,7 +137,7 @@ class Log_entry * marks a transition of output from one session to another. This * information is used to separate sessions visually. */ - void draw(Canvas *canvas, int y, int new_section = false) + void draw(Canvas_base &canvas, int y, int new_section = false) { Color label_fgcol = Color(Genode::min(255, _color.r + 200), Genode::min(255, _color.g + 200), @@ -103,23 +150,19 @@ class Log_entry int label_w = default_font.str_w(_label); int label_h = default_font.str_h(_label); - typedef Canvas::Rect Rect; - typedef Canvas::Area Area; - typedef Canvas::Point Point; - if (new_section) { - canvas->draw_box(Rect(Point(1, y), Area(label_w + 2, label_h - 1)), label_bgcol); - canvas->draw_string(Point(1, y - 1), default_font, label_fgcol, _label); - canvas->draw_box(Rect(Point(1, y + label_h - 1), Area(label_w + 2, 1)), Color(0, 0, 0)); - canvas->draw_box(Rect(Point(label_w + 2, y), Area(1, label_h - 1)), _color); - canvas->draw_box(Rect(Point(label_w + 3, y), Area(1, label_h - 1)), Color(0, 0, 0)); - canvas->draw_box(Rect(Point(label_w + 4, y), Area(1000, label_h)), text_bgcol); - canvas->draw_box(Rect(Point(label_w + 4, y), Area(1000, 1)), Color(0, 0, 0)); + canvas.draw_box(Rect(Point(1, y), Area(label_w + 2, label_h - 1)), label_bgcol); + canvas.draw_string(Point(1, y - 1), default_font, label_fgcol, _label); + canvas.draw_box(Rect(Point(1, y + label_h - 1), Area(label_w + 2, 1)), Color(0, 0, 0)); + canvas.draw_box(Rect(Point(label_w + 2, y), Area(1, label_h - 1)), _color); + canvas.draw_box(Rect(Point(label_w + 3, y), Area(1, label_h - 1)), Color(0, 0, 0)); + canvas.draw_box(Rect(Point(label_w + 4, y), Area(1000, label_h)), text_bgcol); + canvas.draw_box(Rect(Point(label_w + 4, y), Area(1000, 1)), Color(0, 0, 0)); } else - canvas->draw_box(Rect(Point(1, y), Area(1000, label_h)), text_bgcol); + canvas.draw_box(Rect(Point(1, y), Area(1000, label_h)), text_bgcol); /* draw log text */ - canvas->draw_string(Point(label_w + 6, y), default_font, text_fgcol, _text); + canvas.draw_string(Point(label_w + 6, y), default_font, text_fgcol, _text); } /** @@ -134,7 +177,7 @@ class Log_window { private: - Canvas *_canvas; /* graphics backend */ + Canvas_base &_canvas; Log_entry _entries[LOG_H]; /* log entries */ int _dst_entry; /* destination entry for next write */ int _view_pos; /* current view port on the entry array */ @@ -148,8 +191,9 @@ class Log_window /** * Constructor */ - Log_window(Canvas *canvas): - _canvas(canvas), _dst_entry(0), _view_pos(0), _dirty(true) { } + Log_window(Canvas_base &canvas) + : _canvas(canvas), _dst_entry(0), _view_pos(0), _dirty(true) + { } /** * Write log entry @@ -366,22 +410,19 @@ int main(int argc, char **argv) */ static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); - typedef Canvas::Point Point; - typedef Canvas::Area Area; - typedef Canvas::Rect Rect; - /* create log window */ void *addr = env()->rm_session()->attach(nitpicker.framebuffer()->dataspace()); - static Chunky_canvas<Pixel_rgb565> canvas((Pixel_rgb565 *)addr, - Area(log_win_w, log_win_h)); - static Log_window log_window(&canvas); + + static Canvas<Pixel_rgb565> canvas((Pixel_rgb565 *)addr, + ::Area(log_win_w, log_win_h)); + static Log_window log_window(canvas); /* * We clip a border of one pixel off the canvas. This way, the * border remains unaffected by the drawing operations and * acts as an outline for the log window. */ - canvas.clip(Rect(Point(1, 1), Area(log_win_w - 2, log_win_h - 2))); + canvas.clip(::Rect(::Point(1, 1), ::Area(log_win_w - 2, log_win_h - 2))); /* create view for log window */ Log_view log_view(&nitpicker, 20, 20, log_win_w, log_win_h); diff --git a/gems/src/server/terminal/main.cc b/gems/src/server/terminal/main.cc index f2b86dd6a7..d6158616cf 100644 --- a/gems/src/server/terminal/main.cc +++ b/gems/src/server/terminal/main.cc @@ -24,6 +24,7 @@ #include <input/event.h> #include <os/config.h> #include <util/color.h> +#include <os/pixel_rgb565.h> /* terminal includes */ #include <terminal/decoder.h> @@ -34,8 +35,11 @@ #include <terminal_session/terminal_session.h> /* nitpicker graphic back end */ -#include <nitpicker_gfx/font.h> -#include <nitpicker_gfx/pixel_rgb565.h> +#include <nitpicker_gfx/text_painter.h> + + +using Genode::Pixel_rgb565; +typedef Text_painter::Font Font; static bool const verbose = false; diff --git a/os/include/nitpicker_gfx/README b/os/include/nitpicker_gfx/README deleted file mode 100644 index dc615651ad..0000000000 --- a/os/include/nitpicker_gfx/README +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains the very simplistic graphics back end -used by Nitpicker. It is placed at this public location to make -it directly usable by other applications than Nitpicker. diff --git a/os/include/nitpicker_gfx/box_painter.h b/os/include/nitpicker_gfx/box_painter.h new file mode 100644 index 0000000000..2c83f95d1f --- /dev/null +++ b/os/include/nitpicker_gfx/box_painter.h @@ -0,0 +1,58 @@ +/* + * \brief Functor for drawing filled boxes into a surface + * \author Norman Feske + * \date 2006-08-04 + */ + +/* + * Copyright (C) 2006-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__NITPICKER_GFX__BOX_PAINTER_H_ +#define _INCLUDE__NITPICKER_GFX__BOX_PAINTER_H_ + +#include <os/surface.h> + + +struct Box_painter +{ + typedef Genode::Surface_base::Rect Rect; + + /** + * Draw filled box + * + * \param rect position and size of box + * \param color drawing color + */ + template <typename PT> + static inline void paint(Genode::Surface<PT> &surface, + Rect rect, + Genode::Color color) + { + Rect clipped = Rect::intersect(surface.clip(), rect); + + if (!clipped.valid()) return; + + PT pix(color.r, color.g, color.b); + PT *dst, *dst_line = surface.addr() + surface.size().w()*clipped.y1() + clipped.x1(); + + int const alpha = color.a; + + if (color.is_opaque()) + for (int w, h = clipped.h() ; h--; dst_line += surface.size().w()) + for (dst = dst_line, w = clipped.w(); w--; dst++) + *dst = pix; + + else if (!color.is_transparent()) + for (int w, h = clipped.h() ; h--; dst_line += surface.size().w()) + for (dst = dst_line, w = clipped.w(); w--; dst++) + *dst = PT::mix(*dst, pix, alpha); + + surface.flush_pixels(clipped); + } +}; + +#endif /* _INCLUDE__NITPICKER_GFX__BOX_PAINTER_H_ */ diff --git a/os/include/nitpicker_gfx/canvas.h b/os/include/nitpicker_gfx/canvas.h deleted file mode 100644 index 5de8275571..0000000000 --- a/os/include/nitpicker_gfx/canvas.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * \brief Generic interface of graphics backend - * \date 2006-08-04 - * \author Norman Feske - */ - -/* - * Copyright (C) 2006-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__NITPICKER_GFX__CANVAS_H_ -#define _INCLUDE__NITPICKER_GFX__CANVAS_H_ - -#include <util/geometry.h> -#include <util/color.h> - -#include <nitpicker_gfx/font.h> - - -class Texture : public Genode::Area<> -{ - public: - - Texture(Area<> size): Area<>(size) { } - - virtual ~Texture() { } - - /** - * Return pointer to alpha values, or 0 if no alpha channel exists - */ - virtual unsigned char const *alpha() const { return 0; } -}; - - -/* - * A canvas is a rectangular surface to which drawing operations can be - * applied. All coordinates are specified in pixels. The coordinate origin - * is the top-left corner of the canvas. - */ -class Canvas -{ - public: - - typedef Genode::Point<> Point; - typedef Genode::Area<> Area; - typedef Genode::Rect<> Rect; - typedef Genode::Color Color; - - protected: - - Rect _clip; /* clipping area */ - Area _size; /* boundaries of canvas */ - - /** - * Constructor - */ - Canvas(Area size) : _clip(Point(0, 0), size), _size(size) { } - - /** - * Register canvas area as to be flushed - * - * This function is called by the graphics primitives when - * canvas regions are changed. - */ - virtual void _flush_pixels(Rect) { } - - public: - - /* - * Modes for drawing textures - * - * The solid mode is used for normal operation in Nitpicker's - * flat mode and corresponds to plain pixel blitting. The - * masked mode allows us to tint texture with a specified - * mixing color. This feature is used by the X-Ray and Kill - * mode. The masked mode leaves all pixels untouched for - * which the corresponding texture pixel equals the mask key - * color (we use black). We use this mode for painting - * the mouse cursor. - */ - enum Mode { - SOLID = 0, /* draw texture pixel */ - MIXED = 1, /* mix texture pixel and color 1:1 */ - MASKED = 2, /* skip pixels with mask color */ - }; - - virtual ~Canvas() { } - - /** - * Define/request clipping rectangle - */ - void clip(Rect clip) { - _clip = Rect::intersect(Rect(Point(0, 0), _size), clip); } - - Rect clip() const { return _clip; } - bool clip_valid() const { return _clip.valid(); } - - /** - * Return dimension of canvas in pixels - */ - Area size() const { return _size; } - - /** - * Draw filled box - * - * \param rect position and size of box. - * \param color drawing color. - */ - virtual void draw_box(Rect rect, Color color) = 0; - - /** - * Draw string - */ - virtual void draw_string(Point position, Font const &font, Color color, - const char *str) = 0; - - /** - * Draw texture - */ - virtual void draw_texture(Texture const &src, Color mix_color, Point position, - Mode mode, bool allow_alpha = true) = 0; -}; - -#endif /* _INCLUDE__NITPICKER_GFX__CANVAS_H_ */ diff --git a/os/include/nitpicker_gfx/chunky_canvas.h b/os/include/nitpicker_gfx/chunky_canvas.h deleted file mode 100644 index c85271bab9..0000000000 --- a/os/include/nitpicker_gfx/chunky_canvas.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * \brief Canvas storing each pixel in one storage unit in a linear buffer - * \author Norman Feske - * \date 2006-08-04 - */ - -/* - * Copyright (C) 2006-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__NITPICKER_GFX__CHUNKY_CANVAS_H_ -#define _INCLUDE__NITPICKER_GFX__CHUNKY_CANVAS_H_ - -#include <blit/blit.h> -#include "canvas.h" - - -template <typename PT> -class Chunky_texture : public Texture -{ - private: - - PT const *_pixels; - unsigned char const *_alpha; - - public: - - Chunky_texture(PT const *pixels, unsigned char const *alpha, Area size) - : Texture(size), _pixels(pixels), _alpha(alpha) { } - - PT const *pixels() const { return _pixels; } - - unsigned char const *alpha() const { return _alpha; } -}; - - -/* - * \param PT pixel type - */ -template <typename PT> -class Chunky_canvas : public Canvas -{ - protected: - - PT *_addr; /* base address of pixel buffer */ - - public: - - /** - * Constructor - */ - Chunky_canvas(PT *addr, Area size): Canvas(size), _addr(addr) { } - - - /**************************************** - ** Implementation of Canvas interface ** - ****************************************/ - - void draw_box(Rect rect, Color color) - { - Rect clipped = Rect::intersect(_clip, rect); - - if (!clipped.valid()) return; - - PT pix(color.r, color.g, color.b); - PT *dst, *dst_line = _addr + _size.w()*clipped.y1() + clipped.x1(); - - for (int w, h = clipped.h() ; h--; dst_line += _size.w()) - for (dst = dst_line, w = clipped.w(); w--; dst++) - *dst = pix; - - _flush_pixels(clipped); - } - - void draw_string(Point p, Font const &font, Color color, char const *sstr) - { - unsigned char const *str = (unsigned char const *)sstr; - int x = p.x(), y = p.y(); - - unsigned char const *src = font.img; - int d, h = font.img_h; - - /* check top clipping */ - if ((d = _clip.y1() - y) > 0) { - src += d*font.img_w; - y += d; - h -= d; - } - - /* check bottom clipping */ - if ((d = y + h -1 - _clip.y2()) > 0) - h -= d; - - if (h < 1) return; - - /* skip hidden glyphs */ - for ( ; *str && (x + font.wtab[*str] < _clip.x1()); ) - x += font.wtab[*str++]; - - int x_start = x; - - PT *dst = _addr + y*_size.w(); - PT pix(color.r, color.g, color.b); - - /* draw glyphs */ - for ( ; *str && (x <= _clip.x2()); str++) { - - int w = font.wtab[*str]; - int start = Genode::max(0, _clip.x1() - x); - int end = Genode::min(w - 1, _clip.x2() - x); - PT *d = dst + x; - unsigned char const *s = src + font.otab[*str]; - - for (int j = 0; j < h; j++, s += font.img_w, d += _size.w()) - for (int i = start; i <= end; i++) - if (s[i]) d[i] = pix; - - x += w; - } - - _flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h))); - } - - void draw_texture(Texture const &texture, Color mix_color, Point position, - Mode mode, bool allow_alpha) - { - Rect clipped = Rect::intersect(Rect(position, texture), _clip); - - if (!clipped.valid()) return; - - int const src_w = texture.w(); - int const dst_w = _size.w(); - - Chunky_texture<PT> const &tex = static_cast<Chunky_texture<PT> const &>(texture); - - /* calculate offset of first texture pixel to copy */ - unsigned long tex_start_offset = (clipped.y1() - position.y())*src_w - + clipped.x1() - position.x(); - - /* start address of source pixels */ - PT const *src = tex.pixels() + tex_start_offset; - - /* start address of source alpha values */ - unsigned char const *alpha = tex.alpha() + tex_start_offset; - - /* start address of destination pixels */ - PT *dst = _addr + clipped.y1()*dst_w + clipped.x1(); - - PT mix_pixel(mix_color.r, mix_color.g, mix_color.b); - - int i, j; - PT const *s; - PT *d; - unsigned char const *a; - - switch (mode) { - - case SOLID: - - /* - * If the texture has no alpha channel, we can use - * a plain pixel blit. - */ - if (tex.alpha() == 0 || !allow_alpha) { - blit(src, src_w*sizeof(PT), - dst, dst_w*sizeof(PT), - clipped.w()*sizeof(PT), clipped.h()); - break; - } - - /* - * Copy texture with alpha blending - */ - for (j = clipped.h(); j--; src += src_w, alpha += src_w, dst += dst_w) - for (i = clipped.w(), s = src, a = alpha, d = dst; i--; s++, d++, a++) - if (*a) - *d = PT::mix(*d, *s, *a); - break; - - case MIXED: - - for (j = clipped.h(); j--; src += src_w, dst += dst_w) - for (i = clipped.w(), s = src, d = dst; i--; s++, d++) - *d = PT::avr(mix_pixel, *s); - break; - - case MASKED: - - for (j = clipped.h(); j--; src += src_w, dst += dst_w) - for (i = clipped.w(), s = src, d = dst; i--; s++, d++) - if (s->pixel) *d = *s; - break; - } - - _flush_pixels(clipped); - } -}; - -#endif /* _INCLUDE__NITPICKER_GFX__CHUNKY_CANVAS_H_ */ diff --git a/os/include/nitpicker_gfx/font.h b/os/include/nitpicker_gfx/font.h deleted file mode 100644 index 0f711fe958..0000000000 --- a/os/include/nitpicker_gfx/font.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * \brief Font representation - * \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__NITPICKER_GFX__FONT_H_ -#define _INCLUDE__NITPICKER_GFX__FONT_H_ - -#include <base/stdint.h> - -class Font -{ - private: - - typedef Genode::int32_t int32_t; - - public: - - unsigned char const *img; /* font image */ - int const img_w, img_h; /* size of font image */ - int32_t const *otab; /* offset table */ - int32_t const *wtab; /* width table */ - - /** - * Construct font from a TFF data block - */ - Font(const char *tff) - : - img((unsigned char *)(tff + 2056)), - - img_w(*((int32_t *)(tff + 2048))), - img_h(*((int32_t *)(tff + 2052))), - - otab((int32_t *)(tff)), - wtab((int32_t *)(tff + 1024)) - { } - - /** - * Calculate width of string when printed with the font - */ - int str_w(const char *sstr) const - { - const unsigned char *str = (const unsigned char *)sstr; - int res = 0; - for (; str && *str; str++) res += wtab[*str]; - return res; - } - - /** - * Calculate height of string when printed with the font - */ - int str_h(const char *str) const { return img_h; } -}; - -#endif /* _INCLUDE__NITPICKER_GFX__FONT_H_ */ diff --git a/os/include/nitpicker_gfx/pixel_rgb.h b/os/include/nitpicker_gfx/pixel_rgb.h deleted file mode 100644 index e00547e22b..0000000000 --- a/os/include/nitpicker_gfx/pixel_rgb.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * \brief Generic pixel representation - * \author Norman Feske - * \date 2006-08-04 - */ - -/* - * Copyright (C) 2006-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__NITPICKER_GFX__PIXEL_RGB_H_ -#define _INCLUDE__NITPICKER_GFX__PIXEL_RGB_H_ - -/* - * \param ST storage type of one pixel - */ -template <typename ST, int R_MASK, int R_SHIFT, - int G_MASK, int G_SHIFT, - int B_MASK, int B_SHIFT> -class Pixel_rgb -{ - private: - - /** - * Shift left with positive or negative shift value - */ - inline int _shift(int value, int shift) { - return shift > 0 ? value << shift : value >> -shift; } - - public: - - static const int r_mask = R_MASK, r_shift = R_SHIFT; - static const int g_mask = G_MASK, g_shift = G_SHIFT; - static const int b_mask = B_MASK, b_shift = B_SHIFT; - - ST pixel; - - /** - * Constructors - */ - Pixel_rgb() {} - - Pixel_rgb(int red, int green, int blue): - pixel((_shift(red, r_shift) & r_mask) - | (_shift(green, g_shift) & g_mask) - | (_shift(blue, b_shift) & b_mask)) { } - - /** - * Compute average color value of two pixels - */ - static inline Pixel_rgb avr(Pixel_rgb p1, Pixel_rgb p2); - - /** - * Multiply pixel with alpha value - */ - static inline Pixel_rgb blend(Pixel_rgb pixel, int alpha); - - /** - * Mix two pixels at the ratio specified as alpha - */ - static inline Pixel_rgb mix(Pixel_rgb p1, Pixel_rgb p2, int alpha); - - /** - * Return alpha value of pixel - */ - int alpha(); - -} __attribute__((packed)); - -#endif /* _INCLUDE__NITPICKER_GFX__PIXEL_RGB_H_ */ diff --git a/os/include/nitpicker_gfx/pixel_rgb565.h b/os/include/nitpicker_gfx/pixel_rgb565.h deleted file mode 100644 index 72bcfcb4a7..0000000000 --- a/os/include/nitpicker_gfx/pixel_rgb565.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief Template specializations for the RGB565 pixel format - * \date 2006-08-04 - * \author Norman Feske - */ - -/* - * Copyright (C) 2006-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__NITPICKER_GFX__PIXEL_RGB565_H_ -#define _INCLUDE__NITPICKER_GFX__PIXEL_RGB565_H_ - -#include "pixel_rgb.h" - -typedef Pixel_rgb<unsigned short, 0xf800, 8, 0x07e0, 3, 0x001f, -3> Pixel_rgb565; - - -template <> -inline Pixel_rgb565 Pixel_rgb565::avr(Pixel_rgb565 p1, Pixel_rgb565 p2) -{ - Pixel_rgb565 res; - res.pixel = ((p1.pixel&0xf7df)>>1) + ((p2.pixel&0xf7df)>>1); - return res; -} - - -template <> -inline Pixel_rgb565 Pixel_rgb565::blend(Pixel_rgb565 src, int alpha) -{ - Pixel_rgb565 res; - res.pixel = ((((alpha >> 3) * (src.pixel & 0xf81f)) >> 5) & 0xf81f) - | ((( alpha * (src.pixel & 0x07c0)) >> 8) & 0x07c0); - return res; -} - - -template <> -inline Pixel_rgb565 Pixel_rgb565::mix(Pixel_rgb565 p1, Pixel_rgb565 p2, int alpha) -{ - Pixel_rgb res; - - /* - * We substract the alpha from 264 instead of 255 to - * compensate the brightness loss caused by the rounding - * error of the blend function when having only 5 bits - * per channel. - */ - res.pixel = blend(p1, 264 - alpha).pixel + blend(p2, alpha).pixel; - return res; -} - -#endif /* _INCLUDE__NITPICKER_GFX__PIXEL_RGB565_H_ */ diff --git a/os/include/nitpicker_gfx/text_painter.h b/os/include/nitpicker_gfx/text_painter.h new file mode 100644 index 0000000000..ea75ef176d --- /dev/null +++ b/os/include/nitpicker_gfx/text_painter.h @@ -0,0 +1,133 @@ +/* + * \brief Functor for drawing text into a surface + * \author Norman Feske + * \date 2006-08-04 + */ + +/* + * Copyright (C) 2006-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__NITPICKER_GFX__TEXT_PAINTER_H_ +#define _INCLUDE__NITPICKER_GFX__TEXT_PAINTER_H_ + +#include <base/stdint.h> +#include <os/surface.h> + + +struct Text_painter +{ + class Font + { + private: + + typedef Genode::int32_t int32_t; + typedef Genode::size_t size_t; + + public: + + unsigned char const *img; /* font image */ + int const img_w, img_h; /* size of font image */ + int32_t const *otab; /* offset table */ + int32_t const *wtab; /* width table */ + + /** + * Construct font from a TFF data block + */ + Font(const char *tff) + : + img((unsigned char *)(tff + 2056)), + + img_w(*((int32_t *)(tff + 2048))), + img_h(*((int32_t *)(tff + 2052))), + + otab((int32_t *)(tff)), + wtab((int32_t *)(tff + 1024)) + { } + + /** + * Calculate width of string when printed with the font + */ + int str_w(const char *sstr, size_t len = ~0UL) const + { + const unsigned char *str = (const unsigned char *)sstr; + int res = 0; + for (; str && *str && len; len--, str++) res += wtab[*str]; + return res; + } + + /** + * Calculate height of string when printed with the font + */ + int str_h(const char *str, size_t len = ~0UL) const { return img_h; } + }; + + + typedef Genode::Surface_base::Point Point; + typedef Genode::Surface_base::Area Area; + typedef Genode::Surface_base::Rect Rect; + + + template <typename PT> + static inline void paint(Genode::Surface<PT> &surface, + Point p, + Font const &font, + Genode::Color color, + char const *sstr) + { + unsigned char const *str = (unsigned char const *)sstr; + int x = p.x(), y = p.y(); + + unsigned char const *src = font.img; + int d, h = font.img_h; + + /* check top clipping */ + if ((d = surface.clip().y1() - y) > 0) { + src += d*font.img_w; + y += d; + h -= d; + } + + /* check bottom clipping */ + if ((d = y + h -1 - surface.clip().y2()) > 0) + h -= d; + + if (h < 1) return; + + /* skip hidden glyphs */ + for ( ; *str && (x + font.wtab[*str] < surface.clip().x1()); ) + x += font.wtab[*str++]; + + int const x_start = x; + + PT *dst = surface.addr() + y*surface.size().w(); + + PT const pix(color.r, color.g, color.b); + int const alpha = color.a; + + /* draw glyphs */ + for ( ; *str && (x <= surface.clip().x2()); str++) { + + int const w = font.wtab[*str]; + int const start = Genode::max(0, surface.clip().x1() - x); + int const end = Genode::min(w - 1, surface.clip().x2() - x); + + PT *d = dst + x; + unsigned char const *s = src + font.otab[*str]; + + for (int j = 0; j < h; j++, s += font.img_w, d += surface.size().w()) + for (int i = start; i <= end; i++) + if (s[i]) + d[i] = (s[i] == 255 && alpha == 255) + ? pix : PT::mix(d[i], pix, (alpha*s[i]) >> 8); + x += w; + } + + surface.flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h))); + } +}; + +#endif /* _INCLUDE__NITPICKER_GFX__TEXT_PAINTER_H_ */ diff --git a/os/include/nitpicker_gfx/texture_painter.h b/os/include/nitpicker_gfx/texture_painter.h new file mode 100644 index 0000000000..5e3ce79e01 --- /dev/null +++ b/os/include/nitpicker_gfx/texture_painter.h @@ -0,0 +1,125 @@ +/* + * \brief Functor for painting textures on a surface + * \author Norman Feske + * \date 2006-08-04 + */ + +/* + * Copyright (C) 2006-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__NITPICKER_GFX__TEXTURE_PAINTER_H_ +#define _INCLUDE__NITPICKER_GFX__TEXTURE_PAINTER_H_ + +#include <blit/blit.h> +#include <os/texture.h> + + +struct Texture_painter +{ + /* + * Modes for drawing textures + * + * The solid mode is used for normal operation in Nitpicker's + * flat mode and corresponds to plain pixel blitting. The + * masked mode allows us to tint texture with a specified + * mixing color. This feature is used by the X-Ray and Kill + * mode. The masked mode leaves all pixels untouched for + * which the corresponding texture pixel equals the mask key + * color (we use black). We use this mode for painting + * the mouse cursor. + */ + enum Mode { + SOLID = 0, /* draw texture pixel */ + MIXED = 1, /* mix texture pixel and color 1:1 */ + MASKED = 2, /* skip pixels with mask color */ + }; + + + typedef Genode::Surface_base::Point Point; + typedef Genode::Surface_base::Rect Rect; + + + template <typename PT> + static inline void paint(Genode::Surface<PT> &surface, + Genode::Texture<PT> const &texture, + Genode::Color mix_color, + Point position, + Mode mode, + bool allow_alpha) + { + Rect clipped = Rect::intersect(Rect(position, texture.size()), + surface.clip()); + + if (!clipped.valid()) return; + + int const src_w = texture.size().w(); + int const dst_w = surface.size().w(); + + /* calculate offset of first texture pixel to copy */ + unsigned long tex_start_offset = (clipped.y1() - position.y())*src_w + + clipped.x1() - position.x(); + + /* start address of source pixels */ + PT const *src = texture.pixel() + tex_start_offset; + + /* start address of source alpha values */ + unsigned char const *alpha = texture.alpha() + tex_start_offset; + + /* start address of destination pixels */ + PT *dst = surface.addr() + clipped.y1()*dst_w + clipped.x1(); + + PT const mix_pixel(mix_color.r, mix_color.g, mix_color.b); + + int i, j; + PT const *s; + PT *d; + unsigned char const *a; + + switch (mode) { + + case SOLID: + + /* + * If the texture has no alpha channel, we can use + * a plain pixel blit. + */ + if (texture.alpha() == 0 || !allow_alpha) { + blit(src, src_w*sizeof(PT), + dst, dst_w*sizeof(PT), + clipped.w()*sizeof(PT), clipped.h()); + break; + } + + /* + * Copy texture with alpha blending + */ + for (j = clipped.h(); j--; src += src_w, alpha += src_w, dst += dst_w) + for (i = clipped.w(), s = src, a = alpha, d = dst; i--; s++, d++, a++) + if (*a) + *d = PT::mix(*d, *s, *a); + break; + + case MIXED: + + for (j = clipped.h(); j--; src += src_w, dst += dst_w) + for (i = clipped.w(), s = src, d = dst; i--; s++, d++) + *d = PT::avr(mix_pixel, *s); + break; + + case MASKED: + + for (j = clipped.h(); j--; src += src_w, dst += dst_w) + for (i = clipped.w(), s = src, d = dst; i--; s++, d++) + if (s->pixel) *d = *s; + break; + } + + surface.flush_pixels(clipped); + } +}; + +#endif /* _INCLUDE__NITPICKER_GFX__TEXTURE_PAINTER_H_ */ diff --git a/os/include/nitpicker_session/client.h b/os/include/nitpicker_session/client.h index ef10e53cda..897adfeb5a 100644 --- a/os/include/nitpicker_session/client.h +++ b/os/include/nitpicker_session/client.h @@ -20,7 +20,7 @@ namespace Nitpicker { struct Session_client; } -struct Nitpicker::Session_client : public Rpc_client<Session> +struct Nitpicker::Session_client : public Genode::Rpc_client<Session> { explicit Session_client(Session_capability session) : Rpc_client<Session>(session) { } diff --git a/os/include/nitpicker_session/connection.h b/os/include/nitpicker_session/connection.h index e45571edb9..0d7dbe4cca 100644 --- a/os/include/nitpicker_session/connection.h +++ b/os/include/nitpicker_session/connection.h @@ -43,6 +43,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>, /* * Declare ram-quota donation */ + using Genode::Arg_string; enum { SESSION_METADATA = 20*1024 }; Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA); @@ -74,10 +75,10 @@ class Nitpicker::Connection : public Genode::Connection<Session>, char argbuf[ARGBUF_SIZE]; argbuf[0] = 0; - Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", - ram_quota(mode, use_alpha)); + Genode::Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", + ram_quota(mode, use_alpha)); - env()->parent()->upgrade(cap(), argbuf); + Genode::env()->parent()->upgrade(cap(), argbuf); Session_client::buffer(mode, use_alpha); } diff --git a/os/include/nitpicker_session/nitpicker_session.h b/os/include/nitpicker_session/nitpicker_session.h index 8cc62c83a0..40e3e16c9b 100644 --- a/os/include/nitpicker_session/nitpicker_session.h +++ b/os/include/nitpicker_session/nitpicker_session.h @@ -22,7 +22,7 @@ #include <nitpicker_view/capability.h> namespace Nitpicker { - using namespace Genode; + using Genode::size_t; struct Session; } diff --git a/os/include/os/pixel_rgb565.h b/os/include/os/pixel_rgb565.h new file mode 100644 index 0000000000..97d2bfcea2 --- /dev/null +++ b/os/include/os/pixel_rgb565.h @@ -0,0 +1,61 @@ +/* + * \brief Template specializations for the RGB565 pixel format + * \date 2006-08-04 + * \author Norman Feske + */ + +/* + * Copyright (C) 2006-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__OS__PIXEL_RGB565_H_ +#define _INCLUDE__OS__PIXEL_RGB565_H_ + +#include <os/pixel_rgba.h> + +namespace Genode { + + typedef Pixel_rgba<unsigned short, Surface_base::RGB565, + 0xf800, 8, 0x07e0, 3, 0x001f, -3, 0, 0> + Pixel_rgb565; + + + template <> + inline Pixel_rgb565 Pixel_rgb565::avr(Pixel_rgb565 p1, Pixel_rgb565 p2) + { + Pixel_rgb565 res; + res.pixel = ((p1.pixel&0xf7df)>>1) + ((p2.pixel&0xf7df)>>1); + return res; + } + + + template <> + inline Pixel_rgb565 Pixel_rgb565::blend(Pixel_rgb565 src, int alpha) + { + Pixel_rgb565 res; + res.pixel = ((((alpha >> 3) * (src.pixel & 0xf81f)) >> 5) & 0xf81f) + | ((( alpha * (src.pixel & 0x07c0)) >> 8) & 0x07c0); + return res; + } + + + template <> + inline Pixel_rgb565 Pixel_rgb565::mix(Pixel_rgb565 p1, Pixel_rgb565 p2, int alpha) + { + Pixel_rgb565 res; + + /* + * We substract the alpha from 264 instead of 255 to + * compensate the brightness loss caused by the rounding + * error of the blend function when having only 5 bits + * per channel. + */ + res.pixel = blend(p1, 264 - alpha).pixel + blend(p2, alpha).pixel; + return res; + } +} + +#endif /* _INCLUDE__OS__PIXEL_RGB565_H_ */ diff --git a/os/include/os/pixel_rgba.h b/os/include/os/pixel_rgba.h new file mode 100644 index 0000000000..82a045daac --- /dev/null +++ b/os/include/os/pixel_rgba.h @@ -0,0 +1,113 @@ +/* + * \brief Generic pixel representation + * \author Norman Feske + * \date 2006-08-04 + */ + +/* + * Copyright (C) 2006-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__OS__PIXEL_RGBA_H_ +#define _INCLUDE__OS__PIXEL_RGBA_H_ + +#include <os/surface.h> + +namespace Genode { + template <typename ST, Genode::Surface_base::Pixel_format FORMAT, + int R_MASK, int R_SHIFT, + int G_MASK, int G_SHIFT, + int B_MASK, int B_SHIFT, + int A_MASK, int A_SHIFT> + class Pixel_rgba; +} + + +/* + * \param ST storage type of one pixel + * \param FORMAT pixel format + */ +template <typename ST, Genode::Surface_base::Pixel_format FORMAT, + int R_MASK, int R_SHIFT, + int G_MASK, int G_SHIFT, + int B_MASK, int B_SHIFT, + int A_MASK, int A_SHIFT> +class Genode::Pixel_rgba +{ + private: + + /** + * Shift left with positive or negative shift value + */ + static inline int _shift(int value, int shift) { + return shift > 0 ? value << shift : value >> -shift; } + + public: + + static const int r_mask = R_MASK, r_shift = R_SHIFT; + static const int g_mask = G_MASK, g_shift = G_SHIFT; + static const int b_mask = B_MASK, b_shift = B_SHIFT; + static const int a_mask = A_MASK, a_shift = A_SHIFT; + + ST pixel; + + /** + * Constructors + */ + Pixel_rgba() {} + + Pixel_rgba(int red, int green, int blue) : + pixel((_shift(red, r_shift) & r_mask) + | (_shift(green, g_shift) & g_mask) + | (_shift(blue, b_shift) & b_mask)) { } + + static Surface_base::Pixel_format format() { return FORMAT; } + + /** + * Assign new rgba values + */ + void rgba(int red, int green, int blue, int alpha = 255) + { + pixel = (_shift(red, r_shift) & r_mask) + | (_shift(green, g_shift) & g_mask) + | (_shift(blue, b_shift) & b_mask) + | (_shift(alpha, a_shift) & a_mask); + } + + inline int r() const { return _shift(pixel & r_mask, -r_shift); } + inline int g() const { return _shift(pixel & g_mask, -g_shift); } + inline int b() const { return _shift(pixel & b_mask, -b_shift); } + + /** + * Compute average color value of two pixels + */ + static inline Pixel_rgba avr(Pixel_rgba p1, Pixel_rgba p2); + + /** + * Multiply pixel with alpha value + */ + static inline Pixel_rgba blend(Pixel_rgba pixel, int alpha); + + /** + * Mix two pixels at the ratio specified as alpha + */ + static inline Pixel_rgba mix(Pixel_rgba p1, Pixel_rgba p2, int alpha); + + /** + * Compute average color value of four pixels + */ + static inline Pixel_rgba avr(Pixel_rgba p1, Pixel_rgba p2, + Pixel_rgba p3, Pixel_rgba p4) { + return avr(avr(p1, p2), avr(p3, p4)); } + + /** + * Return alpha value of pixel + */ + int alpha(); + +} __attribute__((packed)); + +#endif /* _INCLUDE__OS__PIXEL_RGBA_H_ */ diff --git a/os/include/os/surface.h b/os/include/os/surface.h new file mode 100644 index 0000000000..78e618e1f8 --- /dev/null +++ b/os/include/os/surface.h @@ -0,0 +1,122 @@ +/* + * \brief Generic interface to a graphics backend + * \date 2006-08-04 + * \author Norman Feske + */ + +/* + * Copyright (C) 2006-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__OS__SURFACE_H_ +#define _INCLUDE__OS__SURFACE_H_ + +#include <util/geometry.h> +#include <util/color.h> + +namespace Genode { + class Surface_base; + template <typename> class Surface; +} + + +/* + * A surface is a rectangular space to which drawing operations can be + * applied. All coordinates are specified in pixels. The coordinate origin + * is the top-left corner of the surface. + */ +class Genode::Surface_base +{ + public: + + typedef Genode::Point<> Point; + typedef Genode::Area<> Area; + typedef Genode::Rect<> Rect; + typedef Genode::Color Color; + + enum Pixel_format { UNKNOWN, RGB565 }; + + struct Flusher + { + virtual void flush_pixels(Rect rect) = 0; + }; + + protected: + + Rect _clip; /* clipping area */ + Area _size; /* boundaries of surface */ + Pixel_format _format; + Flusher *_flusher; + + /** + * Constructor + */ + Surface_base(Area size, Pixel_format format) + : _clip(Point(0, 0), size), _size(size), _format(format), _flusher(0) { } + + public: + + virtual ~Surface_base() { } + + /** + * Register part of surface to be flushed + * + * This function is called by graphics primitives when surface regions + * are changed. + */ + void flush_pixels(Rect rect) + { + if (_flusher) + _flusher->flush_pixels(rect); + } + + /** + * Register pixel flusher + */ + void flusher(Flusher *flusher) { _flusher = flusher; } + + /** + * Define/request clipping rectangle + */ + void clip(Rect clip) { + _clip = Rect::intersect(Rect(Point(0, 0), _size), clip); } + + Rect clip() const { return _clip; } + bool clip_valid() const { return _clip.valid(); } + + Pixel_format pixel_format() const { return _format; } + + /** + * Return dimension of surface in pixels + */ + Area size() const { return _size; } +}; + + +/** + * Surface that stores each pixel in one storage unit in a linear buffer + * + * \param PT pixel type + */ +template <typename PT> +class Genode::Surface : public Surface_base +{ + protected: + + PT *_addr; /* base address of pixel buffer */ + + public: + + PT *addr() { return _addr; } + + /** + * Constructor + */ + Surface(PT *addr, Area size) + : Surface_base(size, PT::format()), _addr(addr) { } +}; + +#endif /* _INCLUDE__OS__SURFACE_H_ */ diff --git a/os/include/os/texture.h b/os/include/os/texture.h new file mode 100644 index 0000000000..e0dce24f4c --- /dev/null +++ b/os/include/os/texture.h @@ -0,0 +1,63 @@ +/* + * \brief Texture representation + * \author Norman Feske + * \date 2013-12-30 + */ + +/* + * Copyright (C) 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__OS__TEXTURE_H_ +#define _INCLUDE__OS__TEXTURE_H_ + +#include <os/surface.h> + +namespace Genode { + class Texture_base; + template <typename PT> class Texture; +} + + +class Genode::Texture_base +{ + private: + + Surface_base::Area _size; + + public: + + Texture_base(Surface_base::Area size) : _size(size) { } + + Surface_base::Area size() const { return _size; } +}; + + +template <typename PT> +class Genode::Texture : public Texture_base +{ + private: + + PT *_pixel; + unsigned char *_alpha; + + public: + + Texture(PT *pixel, unsigned char *alpha, Surface_base::Area size) + : Texture_base(size), _pixel(pixel), _alpha(alpha) { } + + PT *pixel() { return _pixel; } + PT const *pixel() const { return _pixel; } + unsigned char *alpha() { return _alpha; } + unsigned char const *alpha() const { return _alpha; } + + /** + * Import rgba data line into texture + */ + void rgba(unsigned char const *rgba, unsigned len, int y); +}; + +#endif /* _INCLUDE__OS__TEXTURE_H_ */ diff --git a/os/include/util/color.h b/os/include/util/color.h index 691f295942..153e69b79c 100644 --- a/os/include/util/color.h +++ b/os/include/util/color.h @@ -26,10 +26,15 @@ namespace Genode { struct Genode::Color { - int r, g, b; + int r, g, b, a; - Color(int red, int green, int blue): r(red), g(green), b(blue) { } - Color(): r(0), g(0), b(0) { } + bool is_opaque() const { return a == 255; } + bool is_transparent() const { return a == 0; } + + Color(int red, int green, int blue, int alpha = 255) + : r(red), g(green), b(blue), a(alpha) { } + + Color(): r(0), g(0), b(0), a(0) { } }; diff --git a/os/src/server/nitpicker/background.h b/os/src/server/nitpicker/background.h index 4884db4925..069c1a5da9 100644 --- a/os/src/server/nitpicker/background.h +++ b/os/src/server/nitpicker/background.h @@ -14,23 +14,25 @@ #ifndef _BACKGROUND_H_ #define _BACKGROUND_H_ +#include <nitpicker_gfx/box_painter.h> + #include "view.h" #include "clip_guard.h" -struct Background : private Texture, Session, View +struct Background : private Texture_base, Session, View { - Genode::Color color; + Color color; /* * The background uses no texture. Therefore * we can pass a null pointer as texture argument * to the Session constructor. */ - Background(Canvas::Area size) + Background(Area size) : - Texture(Area(0, 0)), Session(Genode::Session_label(""), 0, false), + Texture_base(Area(0, 0)), Session(Genode::Session_label(""), 0, false), View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT, - View::BACKGROUND, Canvas::Rect(Canvas::Point(0, 0), size)), + View::BACKGROUND, Rect(Point(0, 0), size)), color(25, 37, 50) { } @@ -47,9 +49,9 @@ struct Background : private Texture, Session, View ********************/ int frame_size(Mode const &mode) const { return 0; } - void frame(Canvas &canvas, Mode const &mode) { } + void frame(Canvas_base &canvas, Mode const &mode) { } - void draw(Canvas &canvas, Mode const &mode) const + void draw(Canvas_base &canvas, Mode const &mode) const { Clip_guard clip_guard(canvas, *this); canvas.draw_box(*this, color); diff --git a/os/src/server/nitpicker/canvas.h b/os/src/server/nitpicker/canvas.h new file mode 100644 index 0000000000..0292b1a1fd --- /dev/null +++ b/os/src/server/nitpicker/canvas.h @@ -0,0 +1,102 @@ +/* + * \brief Graphics backend used by nitpicker + * \author Norman Feske + * \date 2013-12-29 + */ + +/* + * Copyright (C) 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 _CANVAS_H_ +#define _CANVAS_H_ + +#include <nitpicker_gfx/box_painter.h> +#include <nitpicker_gfx/text_painter.h> +#include <nitpicker_gfx/texture_painter.h> + +typedef Genode::Surface_base::Area Area; +typedef Genode::Surface_base::Point Point; +typedef Genode::Surface_base::Rect Rect; +typedef Genode::Color Color; + +using Genode::Texture_base; +using Genode::Texture; + + +/** + * Pixel-type-independent interface of nitpicker's graphics backend + */ +struct Canvas_base +{ + virtual Area size() const = 0; + + virtual Rect clip() const = 0; + + virtual void clip(Rect) = 0; + + virtual void flush_pixels(Rect) = 0; + + virtual void draw_box(Rect, Color) = 0; + + virtual void draw_texture(Point, Texture_base const &, Texture_painter::Mode, + Color mix_color, bool allow_alpha) = 0; + + virtual void draw_text(Point, Text_painter::Font const &, Color, + char const *string) = 0; +}; + + +/** + * Pixel-type-specific implementation of nitpicker's graphics backend + */ +template <typename PT> +class Canvas : public Canvas_base, public Genode::Surface_base::Flusher +{ + private: + + Genode::Surface<PT> _surface; + + public: + + Canvas(PT *base, Area size) : _surface(base, size) + { + _surface.flusher(this); + } + + /** + * Default implementation of Surface_base::Flusher interface + */ + void flush_pixels(Rect) { } + + Area size() const { return _surface.size(); } + + Rect clip() const { return _surface.clip(); } + + void clip(Rect rect) { _surface.clip(rect); } + + void draw_box(Rect rect, Color color) + { + Box_painter::paint(_surface, rect, color); + } + + void draw_texture(Point pos, Texture_base const &texture_base, + Texture_painter::Mode mode, Color mix_color, + bool allow_alpha) + { + Texture<PT> const &texture = static_cast<Texture<PT> const &>(texture_base); + Texture_painter::paint(_surface, texture, mix_color, pos, mode, + allow_alpha); + } + + void draw_text(Point pos, Text_painter::Font const &font, + Color color, char const *string) + { + Text_painter::paint(_surface, pos, font, color, string); + } +}; + +#endif /* _CANVAS_H_ */ diff --git a/os/src/server/nitpicker/chunky_menubar.h b/os/src/server/nitpicker/chunky_menubar.h index 6492adf0fa..07dc9b1516 100644 --- a/os/src/server/nitpicker/chunky_menubar.h +++ b/os/src/server/nitpicker/chunky_menubar.h @@ -14,26 +14,32 @@ #ifndef _CHUNKY_MENUBAR_ #define _CHUNKY_MENUBAR_ -#include <nitpicker_gfx/chunky_canvas.h> +#include <nitpicker_gfx/box_painter.h> +#include <nitpicker_gfx/texture_painter.h> + #include "menubar.h" template <typename PT> -class Chunky_menubar : public Chunky_texture<PT>, - public Session, public Menubar +class Chunky_menubar : public Texture<PT>, + public Session, + public Menubar, + public View { private: - Chunky_canvas<PT> _chunky_canvas; + Canvas<PT> _canvas; public: - Chunky_menubar(PT *pixels, Canvas::Area size) + Chunky_menubar(PT *pixels, Area size) : - Chunky_texture<PT>(pixels, 0, size), + Texture<PT>(pixels, 0, size), Session(Genode::Session_label(""), 0, false), - Menubar(_chunky_canvas, size, *this), _chunky_canvas(pixels, size) + View(*this, View::STAY_TOP, View::NOT_TRANSPARENT, + View::NOT_BACKGROUND, Rect(Point(0, 0), size)), + _canvas(pixels, size) { - Session::texture(this); + Session::texture(this, false); } @@ -49,13 +55,47 @@ class Chunky_menubar : public Chunky_texture<PT>, ********************/ int frame_size(Mode const &mode) const { return 0; } - void frame(Canvas &canvas, Mode const &mode) { } - void draw(Canvas const &canvas, Mode const &mode) + void frame(Canvas_base &canvas, Mode const &mode) { } + void draw(Canvas_base &canvas, Mode const &mode) { Clip_guard clip_guard(canvas, *this); /* draw menubar content */ - canvas.draw_texture(*this, BLACK, p1(), Canvas::SOLID); + canvas.draw_texture(p1(), *this, Texture_painter::SOLID, BLACK, false); + } + + + /*********************** + ** Menubar interface ** + ***********************/ + + void state(Mode const &mode, char const *session_label, + char const *view_title, Color session_color) + { + /* choose base color dependent on the Nitpicker state */ + int r = (mode.kill()) ? 200 : (mode.xray()) ? session_color.r : (session_color.r + 100) >> 1; + int g = (mode.kill()) ? 70 : (mode.xray()) ? session_color.g : (session_color.g + 100) >> 1; + int b = (mode.kill()) ? 70 : (mode.xray()) ? session_color.b : (session_color.b + 100) >> 1; + + /* highlight first line with slightly brighter color */ + _canvas.draw_box(Rect(Point(0, 0), Area(View::w(), 1)), + Color(r + (r / 2), g + (g / 2), b + (b / 2))); + + /* draw slightly shaded background */ + for (unsigned i = 1; i < View::h() - 1; i++) { + r -= r > 3 ? 4 : 0; + g -= g > 3 ? 4 : 0; + b -= b > 4 ? 4 : 0; + _canvas.draw_box(Rect(Point(0, i), Area(View::w(), 1)), Color(r, g, b)); + } + + /* draw last line darker */ + _canvas.draw_box(Rect(Point(0, View::h() - 1), Area(View::w(), 1)), + Color(r / 4, g / 4, b / 4)); + + /* draw label */ + draw_label(_canvas, center(label_size(session_label, view_title)), + session_label, WHITE, view_title, session_color); } }; diff --git a/os/src/server/nitpicker/clip_guard.h b/os/src/server/nitpicker/clip_guard.h index d1aa30f670..edb168f0e8 100644 --- a/os/src/server/nitpicker/clip_guard.h +++ b/os/src/server/nitpicker/clip_guard.h @@ -28,24 +28,24 @@ #ifndef _CLIP_GUARD_H_ #define _CLIP_GUARD_H_ -#include <nitpicker_gfx/canvas.h> +#include "canvas.h" class Clip_guard { private: - Canvas &_canvas; + Canvas_base &_canvas; - Canvas::Rect const _orig_clip_rect; + Rect const _orig_clip_rect; public: - Clip_guard(Canvas &canvas, Canvas::Rect new_clip_rect) + Clip_guard(Canvas_base &canvas, Rect new_clip_rect) : _canvas(canvas), _orig_clip_rect(_canvas.clip()) { - _canvas.clip(Canvas::Rect::intersect(_orig_clip_rect, new_clip_rect)); + _canvas.clip(Rect::intersect(_orig_clip_rect, new_clip_rect)); } ~Clip_guard() { _canvas.clip(_orig_clip_rect); } diff --git a/os/src/server/nitpicker/draw_label.h b/os/src/server/nitpicker/draw_label.h index b18e06bb9d..707430fe0e 100644 --- a/os/src/server/nitpicker/draw_label.h +++ b/os/src/server/nitpicker/draw_label.h @@ -14,7 +14,9 @@ #ifndef _DRAW_LABEL_H_ #define _DRAW_LABEL_H_ -extern Font default_font; +#include "canvas.h" + +extern Text_painter::Font default_font; /* * Gap between session label and view title in pixels @@ -24,12 +26,12 @@ enum { LABEL_GAP = 5 }; /** * Draw black outline of string */ -inline void draw_string_outline(Canvas &canvas, Canvas::Point pos, const char *s) +inline void draw_string_outline(Canvas_base &canvas, Point pos, char const *s) { for (int j = -1; j <= 1; j++) for (int i = -1; i <= 1; i++) if (i || j) - canvas.draw_string(pos + Canvas::Point(i, j), default_font, BLACK, s); + canvas.draw_text(pos + Point(i, j), default_font, BLACK, s); } @@ -39,8 +41,8 @@ inline void draw_string_outline(Canvas &canvas, Canvas::Point pos, const char *s * \param sl session label string * \param vt view title string */ -inline Canvas::Area label_size(const char *sl, const char *vt) { - return Canvas::Area(default_font.str_w(sl) + LABEL_GAP + default_font.str_w(vt) + 2, +inline Area label_size(const char *sl, const char *vt) { + return Area(default_font.str_w(sl) + LABEL_GAP + default_font.str_w(vt) + 2, default_font.str_h(sl) + 2); } @@ -52,19 +54,19 @@ inline Canvas::Area label_size(const char *sl, const char *vt) { * policy. In contrast, the view title can individually be defined by the * application. */ -static void draw_label(Canvas &canvas, Canvas::Point pos, - const char *session_label, Genode::Color session_label_color, - const char *view_title, Genode::Color view_title_color) +static inline void draw_label(Canvas_base &canvas, Point pos, + char const *session_label, Color session_label_color, + char const *view_title, Color view_title_color) { - pos = pos + Canvas::Point(1, 1); + pos = pos + Point(1, 1); draw_string_outline(canvas, pos, session_label); - canvas.draw_string(pos, default_font, session_label_color, session_label); + canvas.draw_text(pos, default_font, session_label_color, session_label); - pos = pos + Canvas::Point(default_font.str_w(session_label) + LABEL_GAP, 0); + pos = pos + Point(default_font.str_w(session_label) + LABEL_GAP, 0); draw_string_outline(canvas, pos, view_title); - canvas.draw_string(pos, default_font, view_title_color, view_title); + canvas.draw_text(pos, default_font, view_title_color, view_title); } #endif /* _DRAW_LABEL_H_ */ diff --git a/os/src/server/nitpicker/main.cc b/os/src/server/nitpicker/main.cc index 06c90134ff..bfae83db97 100644 --- a/os/src/server/nitpicker/main.cc +++ b/os/src/server/nitpicker/main.cc @@ -27,8 +27,8 @@ #include <nitpicker_view/nitpicker_view.h> #include <nitpicker_session/nitpicker_session.h> #include <framebuffer_session/connection.h> -#include <nitpicker_gfx/pixel_rgb565.h> #include <util/color.h> +#include <os/pixel_rgb565.h> #include <os/session_policy.h> #include <os/server.h> @@ -40,18 +40,31 @@ #include "mouse_cursor.h" #include "chunky_menubar.h" -namespace Input { using namespace Genode; } namespace Input { class Session_component; } -namespace Framebuffer { using namespace Genode; } namespace Framebuffer { class Session_component; } - namespace Nitpicker { - using namespace Genode; class Session_component; template <typename> class Root; struct Main; } +using Genode::size_t; +using Genode::Allocator; +using Genode::Rpc_entrypoint; +using Genode::List; +using Genode::Pixel_rgb565; +using Genode::strcmp; +using Genode::config; +using Genode::env; +using Genode::Arg_string; +using Genode::Object_pool; +using Genode::Dataspace_capability; +using Genode::Session_label; +using Genode::Signal_transmitter; +using Genode::Signal_context_capability; +using Genode::Signal_rpc_member; +using Genode::Attached_ram_dataspace; + /*************** ** Utilities ** @@ -62,46 +75,49 @@ namespace Nitpicker { */ extern char _binary_default_tff_start; -Font default_font(&_binary_default_tff_start); +Text_painter::Font default_font(&_binary_default_tff_start); class Flush_merger { private: - Canvas::Rect _to_be_flushed = { Canvas::Point(), Canvas::Area() }; + Rect _to_be_flushed = { Point(), Area() }; public: bool defer = false; - Canvas::Rect to_be_flushed() const { return _to_be_flushed; } + Rect to_be_flushed() const { return _to_be_flushed; } - void merge(Canvas::Rect rect) + void merge(Rect rect) { if (_to_be_flushed.valid()) - _to_be_flushed = Canvas::Rect::compound(_to_be_flushed, rect); + _to_be_flushed = Rect::compound(_to_be_flushed, rect); else _to_be_flushed = rect; } - void reset() { _to_be_flushed = Canvas::Rect(Canvas::Point(), Canvas::Area()); } + void reset() { _to_be_flushed = Rect(Point(), Area()); } }; template <typename PT> -class Screen : public Chunky_canvas<PT>, public Flush_merger +class Screen : public Canvas<PT>, public Flush_merger { protected: - virtual void _flush_pixels(Canvas::Rect rect) { merge(rect); } + /** + * Surface_base::Flusher interface + */ + void flush_pixels(Rect rect) { merge(rect); } public: /** * Constructor */ - Screen(PT *base, Canvas::Area size) : Chunky_canvas<PT>(base, size) { } + Screen(PT *base, Area size) : Canvas<PT>(base, size) { } }; @@ -109,7 +125,7 @@ class Buffer { private: - Canvas::Area _size; + Area _size; Framebuffer::Mode::Format _format; Genode::Attached_ram_dataspace _ram_ds; @@ -121,17 +137,17 @@ class Buffer * \throw Ram_session::Alloc_failed * \throw Rm_session::Attach_failed */ - Buffer(Canvas::Area size, Framebuffer::Mode::Format format, Genode::size_t bytes) + Buffer(Area size, Framebuffer::Mode::Format format, Genode::size_t bytes) : _size(size), _format(format), - _ram_ds(Genode::env()->ram_session(), bytes) + _ram_ds(env()->ram_session(), bytes) { } /** * Accessors */ Genode::Ram_dataspace_capability ds_cap() const { return _ram_ds.cap(); } - Canvas::Area size() const { return _size; } + Area size() const { return _size; } Framebuffer::Mode::Format format() const { return _format; } void *local_addr() const { return _ram_ds.local_addr<void>(); } }; @@ -150,7 +166,8 @@ struct Buffer_provider template <typename PT> -class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT> +class Chunky_dataspace_texture : public Buffer, + public Texture<PT> { private: @@ -160,7 +177,7 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT> /** * Return base address of alpha channel or 0 if no alpha channel exists */ - unsigned char *_alpha_base(Canvas::Area size, bool use_alpha) + unsigned char *_alpha_base(Area size, bool use_alpha) { if (!use_alpha) return 0; @@ -173,13 +190,13 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT> /** * Constructor */ - Chunky_dataspace_texture(Canvas::Area size, bool use_alpha) + Chunky_dataspace_texture(Area size, bool use_alpha) : Buffer(size, _format(), calc_num_bytes(size, use_alpha)), - Chunky_texture<PT>((PT *)local_addr(), - _alpha_base(size, use_alpha), size) { } + Texture<PT>((PT *)local_addr(), + _alpha_base(size, use_alpha), size) { } - static Genode::size_t calc_num_bytes(Canvas::Area size, bool use_alpha) + static Genode::size_t calc_num_bytes(Area size, bool use_alpha) { /* * If using an alpha channel, the alpha buffer follows the @@ -193,11 +210,13 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT> unsigned char *input_mask_buffer() { - if (!Chunky_texture<PT>::alpha()) return 0; + if (!Texture<PT>::alpha()) return 0; + + Area const size = Texture<PT>::size(); /* input-mask values come right after the alpha values */ - return (unsigned char *)local_addr() + calc_num_bytes(*this, false) - + Texture::w()*Texture::h(); + return (unsigned char *)local_addr() + calc_num_bytes(size, false) + + size.count(); } }; @@ -213,7 +232,7 @@ class Input::Session_component : public Genode::Rpc_object<Session> enum { MAX_EVENTS = 200 }; static size_t ev_ds_size() { - return align_addr(MAX_EVENTS*sizeof(Event), 12); } + return Genode::align_addr(MAX_EVENTS*sizeof(Event), 12); } private: @@ -335,7 +354,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session> { _buffer = _buffer_provider.realloc_buffer(_mode, _alpha); - return _buffer ? _buffer->ds_cap() : Ram_dataspace_capability(); + return _buffer ? _buffer->ds_cap() : Genode::Ram_dataspace_capability(); } void release() { } @@ -353,12 +372,11 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session> void refresh(int x, int y, int w, int h) { _view_stack.update_session_views(_session, - Canvas::Rect(Canvas::Point(x, y), - Canvas::Area(w, h))); + Rect(Point(x, y), Area(w, h))); /* flush dirty pixels to physical frame buffer */ if (_flush_merger.defer == false) { - Canvas::Rect r = _flush_merger.to_be_flushed(); + Rect r = _flush_merger.to_be_flushed(); _framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h()); _flush_merger.reset(); } @@ -388,7 +406,7 @@ class View_component : public Genode::List<View_component>::Element, _view_stack(view_stack), _view(session, session.stay_top() ? ::View::STAY_TOP : ::View::NOT_STAY_TOP, - ::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, Canvas::Rect()), + ::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, Rect()), _ep(ep) { } ::View &view() { return _view; } @@ -404,16 +422,13 @@ class View_component : public Genode::List<View_component>::Element, /* transpose y position by vertical session offset */ y += _view.session().v_offset(); - _view_stack.viewport(_view, Canvas::Rect(Canvas::Point(x, y), - Canvas::Area(w, h)), - Canvas::Point(buf_x, buf_y), redraw); + _view_stack.viewport(_view, Rect(Point(x, y), Area(w, h)), + Point(buf_x, buf_y), redraw); return 0; } int stack(Nitpicker::View_capability neighbor_cap, bool behind, bool redraw) { - using namespace Genode; - Object_pool<View_component>::Guard nvc(_ep.lookup_and_lock(neighbor_cap)); ::View *neighbor_view = nvc ? &nvc->view() : 0; @@ -440,7 +455,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>, { private: - Allocator_guard _buffer_alloc; + Genode::Allocator_guard _buffer_alloc; Framebuffer::Session &_framebuffer; @@ -480,7 +495,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>, Chunky_dataspace_texture<PT> const *cdt = static_cast<Chunky_dataspace_texture<PT> const *>(::Session::texture()); - ::Session::texture(0); + ::Session::texture(0, false); ::Session::input_mask(0); destroy(&_buffer_alloc, const_cast<Chunky_dataspace_texture<PT> *>(cdt)); @@ -549,7 +564,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>, */ if (e.ax() || e.ay()) e = Event(e.type(), e.code(), e.ax(), - max(0, e.ay() - v_offset()), e.rx(), e.ry()); + Genode::max(0, e.ay() - v_offset()), e.rx(), e.ry()); _input_session_component.submit(&e); } @@ -639,7 +654,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>, { _release_buffer(); - Canvas::Area const size(mode.width(), mode.height()); + Area const size(mode.width(), mode.height()); typedef Pixel_rgb565 PT; @@ -655,7 +670,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>, return 0; } - ::Session::texture(texture); + ::Session::texture(texture, use_alpha); ::Session::input_mask(texture->input_mask_buffer()); return texture; @@ -769,7 +784,7 @@ struct Nitpicker::Main void *fb_base = env()->rm_session()->attach(fb_ds_cap); - Screen<PT> screen = { (PT *)fb_base, Canvas::Area(mode.width(), mode.height()) }; + Screen<PT> screen = { (PT *)fb_base, Area(mode.width(), mode.height()) }; /* * Menu bar @@ -778,7 +793,7 @@ struct Nitpicker::Main PT *menubar_pixels = (PT *)env()->heap()->alloc(sizeof(PT)*mode.width()*16); - Chunky_menubar<PT> menubar = { menubar_pixels, Canvas::Area(mode.width(), MENUBAR_HEIGHT) }; + Chunky_menubar<PT> menubar = { menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT) }; /* * User-input policy @@ -792,16 +807,16 @@ struct Nitpicker::Main /* * Create view stack with default elements */ - Canvas::Area mouse_size { big_mouse.w, big_mouse.h }; - Mouse_cursor<PT> mouse_cursor { (PT *)&big_mouse.pixels[0][0], - mouse_size, user_state }; + Area mouse_size { big_mouse.w, big_mouse.h }; + Mouse_cursor<PT const> mouse_cursor { (PT const *)&big_mouse.pixels[0][0], + mouse_size, user_state }; Background background = { screen.size() }; /* * Initialize Nitpicker root interface */ - Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() }; + Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() }; Root<PT> np_root = { session_list, global_keys, ep.rpc_ep(), user_state, sliced_heap, screen, @@ -861,23 +876,23 @@ void Nitpicker::Main::handle_input(unsigned) return; do { - Canvas::Point const old_mouse_pos = user_state.mouse_pos(); + Point const old_mouse_pos = user_state.mouse_pos(); /* handle batch of pending events */ if (input.is_pending()) import_input_events(ev_buf, input.flush(), user_state); - Canvas::Point const new_mouse_pos = user_state.mouse_pos(); + Point const new_mouse_pos = user_state.mouse_pos(); /* update mouse cursor */ if (old_mouse_pos != new_mouse_pos) user_state.viewport(mouse_cursor, - Canvas::Rect(new_mouse_pos, mouse_size), - Canvas::Point(), true); + Rect(new_mouse_pos, mouse_size), + Point(), true); /* flush dirty pixels to physical frame buffer */ if (screen.defer == false) { - Canvas::Rect const r = screen.to_be_flushed(); + Rect const r = screen.to_be_flushed(); if (r.valid()) framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h()); screen.reset(); diff --git a/os/src/server/nitpicker/menubar.h b/os/src/server/nitpicker/menubar.h index a295f60f89..0417cd1477 100644 --- a/os/src/server/nitpicker/menubar.h +++ b/os/src/server/nitpicker/menubar.h @@ -18,56 +18,16 @@ #include "draw_label.h" #include "mode.h" -class Menubar : public View + +struct Menubar { - private: + virtual ~Menubar() { } - Canvas &_canvas; - - protected: - - Menubar(Canvas &canvas, Canvas::Area size, Session &session) - : - View(session, View::STAY_TOP, View::NOT_TRANSPARENT, - View::NOT_BACKGROUND, Canvas::Rect(Canvas::Point(0, 0), size)), - _canvas(canvas) - { } - - public: - - /** - * Set state that is displayed in the trusted menubar - */ - void state(Mode const &mode, const char *session_label, - const char *view_title, Genode::Color session_color) - { - /* choose base color dependent on the Nitpicker state */ - int r = (mode.kill()) ? 200 : (mode.xray()) ? session_color.r : (session_color.r + 100) >> 1; - int g = (mode.kill()) ? 70 : (mode.xray()) ? session_color.g : (session_color.g + 100) >> 1; - int b = (mode.kill()) ? 70 : (mode.xray()) ? session_color.b : (session_color.b + 100) >> 1; - - /* highlight first line with slightly brighter color */ - _canvas.draw_box(Canvas::Rect(Canvas::Point(0, 0), Canvas::Area(w(), 1)), - Genode::Color(r + (r / 2), g + (g / 2), b + (b / 2))); - - /* draw slightly shaded background */ - for (unsigned i = 1; i < h() - 1; i++) { - r -= r > 3 ? 4 : 0; - g -= g > 3 ? 4 : 0; - b -= b > 4 ? 4 : 0; - _canvas.draw_box(Canvas::Rect(Canvas::Point(0, i), - Canvas::Area(w(), 1)), - Genode::Color(r, g, b)); - } - - /* draw last line darker */ - _canvas.draw_box(Canvas::Rect(Canvas::Point(0, h() - 1), Canvas::Area(w(), 1)), - Genode::Color(r / 4, g / 4, b / 4)); - - /* draw label */ - draw_label(_canvas, center(label_size(session_label, view_title)), - session_label, WHITE, view_title, session_color); - } + /** + * Set state that is displayed in the trusted menubar + */ + virtual void state(Mode const &mode, char const *session_label, + char const *view_title, Genode::Color session_color) = 0; }; #endif diff --git a/os/src/server/nitpicker/mouse_cursor.h b/os/src/server/nitpicker/mouse_cursor.h index 327b8cb588..5a2cba4152 100644 --- a/os/src/server/nitpicker/mouse_cursor.h +++ b/os/src/server/nitpicker/mouse_cursor.h @@ -17,13 +17,14 @@ #ifndef _MOUSE_CURSOR_H_ #define _MOUSE_CURSOR_H_ -#include <nitpicker_gfx/chunky_canvas.h> +#include <nitpicker_gfx/texture_painter.h> #include "view.h" #include "session.h" template <typename PT> -class Mouse_cursor : public Chunky_texture<PT>, public Session, public View +class Mouse_cursor : public Texture<PT>, + public Session, public View { private: @@ -34,12 +35,12 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View /** * Constructor */ - Mouse_cursor(PT const *pixels, Canvas::Area size, View_stack const &view_stack) + Mouse_cursor(PT const *pixels, Area size, View_stack const &view_stack) : - Chunky_texture<PT>(pixels, 0, size), + Texture<PT>(pixels, 0, size), Session(Genode::Session_label(""), 0, false), View(*this, View::STAY_TOP, View::TRANSPARENT, View::NOT_BACKGROUND, - Canvas::Rect()), + Rect()), _view_stack(view_stack) { } @@ -61,9 +62,9 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View int frame_size(Mode const &mode) const { return 0; } - void frame(Canvas &canvas, Mode const &mode) const { } + void frame(Canvas_base &canvas, Mode const &mode) const { } - void draw(Canvas &canvas, Mode const &mode) const + void draw(Canvas_base &canvas, Mode const &mode) const { Clip_guard clip_guard(canvas, *this); @@ -71,7 +72,7 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View _view_stack.draw_rec(view_stack_next(), 0, 0, *this); /* draw mouse cursor */ - canvas.draw_texture(*this, BLACK, p1(), Canvas::MASKED); + canvas.draw_texture(p1(), *this, Texture_painter::MASKED, BLACK, true); } }; diff --git a/os/src/server/nitpicker/session.h b/os/src/server/nitpicker/session.h index 41c997386c..f9d0267d73 100644 --- a/os/src/server/nitpicker/session.h +++ b/os/src/server/nitpicker/session.h @@ -17,13 +17,12 @@ /* Genode includes */ #include <util/list.h> #include <util/string.h> -#include <nitpicker_gfx/canvas.h> #include <os/session_policy.h> /* local includes */ #include "color.h" +#include "canvas.h" -class Texture; class View; class Session; @@ -36,11 +35,12 @@ class Session : public Session_list::Element private: Genode::Session_label const _label; - Genode::Color _color; - Texture const *_texture; + Color _color; + Texture_base const *_texture = { 0 }; + bool _uses_alpha = { false }; View *_background = 0; int _v_offset; - unsigned char const *_input_mask; + unsigned char const *_input_mask = { 0 }; bool const _stay_top; public: @@ -54,8 +54,7 @@ class Session : public Session_list::Element */ Session(Genode::Session_label const &label, int v_offset, bool stay_top) : - _label(label), _texture(0), _v_offset(v_offset), - _input_mask(0), _stay_top(stay_top) + _label(label), _v_offset(v_offset), _stay_top(stay_top) { } virtual ~Session() { } @@ -64,9 +63,13 @@ class Session : public Session_list::Element Genode::Session_label const &label() const { return _label; } - Texture const *texture() const { return _texture; } + Texture_base const *texture() const { return _texture; } - void texture(Texture const *texture) { _texture = texture; } + void texture(Texture_base const *texture, bool uses_alpha) + { + _texture = texture; + _uses_alpha = uses_alpha; + } /** * Set input mask buffer @@ -82,7 +85,7 @@ class Session : public Session_list::Element */ void input_mask(unsigned char const *mask) { _input_mask = mask; } - Genode::Color color() const { return _color; } + Color color() const { return _color; } View *background() const { return _background; } @@ -93,7 +96,7 @@ class Session : public Session_list::Element /** * Return true if session uses an alpha channel */ - bool uses_alpha() const { return _texture ? _texture->alpha() : 0; } + bool uses_alpha() const { return _texture && _uses_alpha; } /** * Return vertical offset of session @@ -103,16 +106,16 @@ class Session : public Session_list::Element /** * Return input mask value at specified buffer position */ - unsigned char input_mask_at(Canvas::Point p) const + unsigned char input_mask_at(Point p) const { if (!_input_mask || !_texture) return 0; /* check boundaries */ - if ((unsigned)p.x() >= _texture->w() - || (unsigned)p.y() >= _texture->h()) + if ((unsigned)p.x() >= _texture->size().w() + || (unsigned)p.y() >= _texture->size().h()) return 0; - return _input_mask[p.y()*_texture->w() + p.x()]; + return _input_mask[p.y()*_texture->size().w() + p.x()]; } /** diff --git a/os/src/server/nitpicker/user_state.cc b/os/src/server/nitpicker/user_state.cc index 80e5904689..70a65f0a56 100644 --- a/os/src/server/nitpicker/user_state.cc +++ b/os/src/server/nitpicker/user_state.cc @@ -35,7 +35,7 @@ static inline bool _mouse_button(Keycode keycode) { ** User state interface ** **************************/ -User_state::User_state(Global_keys &global_keys, Canvas &canvas, Menubar &menubar) +User_state::User_state(Global_keys &global_keys, Canvas_base &canvas, Menubar &menubar) : View_stack(canvas, *this), _global_keys(global_keys), _key_cnt(0), _menubar(menubar), _pointed_view(0), _input_receiver(0), @@ -74,7 +74,7 @@ void User_state::handle_event(Input::Event ev) /* create the mangled event */ ev = Input::Event(type, keycode, ax, ay, rx, ry); - _mouse_pos = Canvas::Point(ax, ay); + _mouse_pos = Point(ax, ay); /* count keys */ if (type == Event::PRESS) _key_cnt++; diff --git a/os/src/server/nitpicker/user_state.h b/os/src/server/nitpicker/user_state.h index 827e036e2c..ff75aa74b6 100644 --- a/os/src/server/nitpicker/user_state.h +++ b/os/src/server/nitpicker/user_state.h @@ -18,8 +18,6 @@ #ifndef _USER_STATE_H_ #define _USER_STATE_H_ -#include <nitpicker_gfx/canvas.h> - #include "mode.h" #include "menubar.h" #include "view_stack.h" @@ -51,7 +49,7 @@ class User_state : public Mode, public View_stack /* * Current mouse cursor position */ - Canvas::Point _mouse_pos; + Point _mouse_pos; /* * Currently pointed-at view @@ -73,7 +71,7 @@ class User_state : public Mode, public View_stack /** * Constructor */ - User_state(Global_keys &global_keys, Canvas &canvas, Menubar &menubar); + User_state(Global_keys &, Canvas_base &, Menubar &); /** * Handle input event @@ -86,7 +84,7 @@ class User_state : public Mode, public View_stack /** * Accessors */ - Canvas::Point mouse_pos() { return _mouse_pos; } + Point mouse_pos() { return _mouse_pos; } /** * Mode interface diff --git a/os/src/server/nitpicker/view.cc b/os/src/server/nitpicker/view.cc index 4f97d45a76..a1d8c80c37 100644 --- a/os/src/server/nitpicker/view.cc +++ b/os/src/server/nitpicker/view.cc @@ -12,6 +12,10 @@ */ #include <base/printf.h> +#include <os/pixel_rgb565.h> + +#include <nitpicker_gfx/texture_painter.h> +#include <nitpicker_gfx/box_painter.h> #include "view.h" #include "clip_guard.h" @@ -26,19 +30,21 @@ /** * Draw rectangle */ -static void draw_rect(Canvas &canvas, int x, int y, int w, int h, Genode::Color color) +static void draw_rect(Canvas_base &canvas, int x, int y, int w, int h, + Color color) { - canvas.draw_box(Canvas::Rect(Canvas::Point(x, y), Canvas::Area(w, 1)), color); - canvas.draw_box(Canvas::Rect(Canvas::Point(x, y), Canvas::Area(1, h)), color); - canvas.draw_box(Canvas::Rect(Canvas::Point(x + w - 1, y), Canvas::Area(1, h)), color); - canvas.draw_box(Canvas::Rect(Canvas::Point(x, y + h - 1), Canvas::Area(w, 1)), color); + canvas.draw_box(Rect(Point(x, y), Area(w, 1)), color); + canvas.draw_box(Rect(Point(x, y), Area(1, h)), color); + canvas.draw_box(Rect(Point(x + w - 1, y), Area(1, h)), color); + canvas.draw_box(Rect(Point(x, y + h - 1), Area(w, 1)), color); } /** * Draw outlined frame with black outline color */ -static void draw_frame(Canvas &canvas, Canvas::Rect r, Genode::Color color, int frame_size) +static void draw_frame(Canvas_base &canvas, Rect r, Color color, + int frame_size) { /* draw frame around the view */ int d = frame_size; @@ -58,11 +64,11 @@ void View::title(const char *title) Genode::strncpy(_title, title, TITLE_LEN); /* calculate label size, the position is defined by the view stack */ - _label_rect = Canvas::Rect(Canvas::Point(0, 0), label_size(_session.label().string(), _title)); + _label_rect = Rect(Point(0, 0), label_size(_session.label().string(), _title)); } -void View::frame(Canvas &canvas, Mode const &mode) const +void View::frame(Canvas_base &canvas, Mode const &mode) const { /* do not draw frame in flat mode */ if (mode.flat()) return; @@ -71,20 +77,20 @@ void View::frame(Canvas &canvas, Mode const &mode) const } -void View::draw(Canvas &canvas, Mode const &mode) const +void View::draw(Canvas_base &canvas, Mode const &mode) const { /* is this the currently focused view? */ bool const view_is_focused = mode.focused_view() && mode.focused_view()->belongs_to(_session); - Genode::Color const frame_color = _session.color(); + Color const frame_color = _session.color(); /* * Use dimming in x-ray and kill mode, but do not dim the focused view in * x-ray mode. */ - Canvas::Mode const op = mode.flat() || (mode.xray() && view_is_focused) - ? Canvas::SOLID : Canvas::MIXED; + Texture_painter::Mode const op = mode.flat() || (mode.xray() && view_is_focused) + ? Texture_painter::SOLID : Texture_painter::MIXED; /* * The view content and label should never overdraw the @@ -98,23 +104,24 @@ void View::draw(Canvas &canvas, Mode const &mode) const * If the clipping area shrinked to zero, we do not process drawing * operations. */ - if (!canvas.clip_valid() || !&_session) return; + if (!canvas.clip().valid() || !&_session) return; /* allow alpha blending only in flat mode */ bool allow_alpha = mode.flat(); /* draw view content */ - Genode::Color const mix_color = mode.kill() ? KILL_COLOR - : Genode::Color(_session.color().r >> 1, - _session.color().g >> 1, - _session.color().b >> 1); + Color const mix_color = mode.kill() ? KILL_COLOR + : Color(_session.color().r >> 1, + _session.color().g >> 1, + _session.color().b >> 1); if (_session.texture()) - canvas.draw_texture(*_session.texture(), mix_color, _buffer_off + p1(), - op, allow_alpha); + canvas.draw_texture(_buffer_off + p1(), *_session.texture(), op, + mix_color, allow_alpha); if (mode.flat()) return; /* draw label */ - draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE, _title, frame_color); + draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE, + _title, frame_color); } diff --git a/os/src/server/nitpicker/view.h b/os/src/server/nitpicker/view.h index dd10707ecc..276caf0f60 100644 --- a/os/src/server/nitpicker/view.h +++ b/os/src/server/nitpicker/view.h @@ -17,8 +17,6 @@ #include <util/string.h> #include <util/list.h> -#include <nitpicker_gfx/canvas.h> - #include "mode.h" #include "session.h" @@ -37,7 +35,7 @@ struct View_stack_elem : Genode::List<View_stack_elem>::Element { }; class View : public Same_buffer_list_elem, public View_stack_elem, - public Canvas::Rect + public Rect { public: @@ -53,10 +51,10 @@ class View : public Same_buffer_list_elem, Transparent const _transparent; /* background is partly visible */ Background _background; /* view is a background view */ - Canvas::Rect _label_rect; /* position and size of label */ - Canvas::Point _buffer_off; /* offset to the visible buffer area */ - Session &_session; /* session that created the view */ - char _title[TITLE_LEN]; + Rect _label_rect; /* position and size of label */ + Point _buffer_off; /* offset to the visible buffer area */ + Session &_session; /* session that created the view */ + char _title[TITLE_LEN]; public: @@ -84,12 +82,12 @@ class View : public Same_buffer_list_elem, /** * Draw view-surrounding frame on canvas */ - virtual void frame(Canvas &canvas, Mode const &mode) const; + virtual void frame(Canvas_base &canvas, Mode const &mode) const; /** * Draw view on canvas */ - virtual void draw(Canvas &canvas, Mode const &mode) const; + virtual void draw(Canvas_base &canvas, Mode const &mode) const; /** * Set view title @@ -126,19 +124,18 @@ class View : public Same_buffer_list_elem, bool background() const { return _background; } Rect label_rect() const { return _label_rect; } bool uses_alpha() const { return _session.uses_alpha(); } - - Canvas::Point buffer_off() const { return _buffer_off; } + Point buffer_off() const { return _buffer_off; } char const *title() const { return _title; } - void buffer_off(Canvas::Point buffer_off) { _buffer_off = buffer_off; } + void buffer_off(Point buffer_off) { _buffer_off = buffer_off; } - void label_pos(Canvas::Point pos) { _label_rect = Rect(pos, _label_rect.area()); } + void label_pos(Point pos) { _label_rect = Rect(pos, _label_rect.area()); } /** * Return true if input at screen position 'p' refers to the view */ - bool input_response_at(Canvas::Point p, Mode const &mode) const + bool input_response_at(Point p, Mode const &mode) const { /* check if point lies outside view geometry */ if ((p.x() < x1()) || (p.x() > x2()) diff --git a/os/src/server/nitpicker/view_stack.cc b/os/src/server/nitpicker/view_stack.cc index 27853c58cf..f1da6c409d 100644 --- a/os/src/server/nitpicker/view_stack.cc +++ b/os/src/server/nitpicker/view_stack.cc @@ -63,15 +63,15 @@ VIEW *View_stack::_next_view(VIEW *view) const } -Canvas::Rect View_stack::_outline(View const &view) const +Rect View_stack::_outline(View const &view) const { if (_mode.flat()) return view; /* request thickness of view frame */ int const frame_size = view.frame_size(_mode); - return Canvas::Rect(Canvas::Point(view.x1() - frame_size, view.y1() - frame_size), - Canvas::Point(view.x2() + frame_size, view.y2() + frame_size)); + return Rect(Point(view.x1() - frame_size, view.y1() - frame_size), + Point(view.x2() + frame_size, view.y2() + frame_size)); } diff --git a/os/src/server/nitpicker/view_stack.h b/os/src/server/nitpicker/view_stack.h index 80c2f92572..56bf3c14f1 100644 --- a/os/src/server/nitpicker/view_stack.h +++ b/os/src/server/nitpicker/view_stack.h @@ -15,6 +15,7 @@ #define _VIEW_STACK_H_ #include "view.h" +#include "canvas.h" class Session; @@ -22,11 +23,7 @@ class View_stack { private: - typedef Canvas::Point Point; - typedef Canvas::Area Area; - typedef Canvas::Rect Rect; - - Canvas &_canvas; + Canvas_base &_canvas; Mode &_mode; Genode::List<View_stack_elem> _views; View *_default_background; @@ -38,7 +35,7 @@ class View_stack * active Nitpicker mode. In non-flat modes, we incorporate the * surrounding frame. */ - Canvas::Rect _outline(View const &view) const; + Rect _outline(View const &view) const; /** * Return top-most view of the view stack @@ -74,7 +71,7 @@ class View_stack /** * Constructor */ - View_stack(Canvas &canvas, Mode &mode) : + View_stack(Canvas_base &canvas, Mode &mode) : _canvas(canvas), _mode(mode), _default_background(0) { } /** diff --git a/ports/src/vancouver/console.cc b/ports/src/vancouver/console.cc index 3c9c28d7af..f625ce7079 100644 --- a/ports/src/vancouver/console.cc +++ b/ports/src/vancouver/console.cc @@ -28,16 +28,17 @@ #include <util/register.h> /* nitpicker graphics backend */ -#include <nitpicker_gfx/chunky_canvas.h> -#include <nitpicker_gfx/pixel_rgb565.h> -#include <nitpicker_gfx/font.h> - -extern char _binary_mono_tff_start; -Font default_font(&_binary_mono_tff_start); - +#include <os/pixel_rgb565.h> +#include <nitpicker_gfx/text_painter.h> using Genode::env; using Genode::Dataspace_client; +using Genode::Surface; +using Genode::Pixel_rgb565; +typedef Text_painter::Font Font; + +extern char _binary_mono_tff_start; +Font default_font(&_binary_mono_tff_start); bool fb_active = true; @@ -214,9 +215,9 @@ void Vancouver_console::entry() _pixels = env()->rm_session()->attach(framebuffer->dataspace()); - Chunky_canvas<Pixel_rgb565> canvas((Pixel_rgb565 *) _pixels, - Canvas::Area(_fb_mode.width(), - _fb_mode.height())); + Surface<Pixel_rgb565> surface((Pixel_rgb565 *) _pixels, + Genode::Surface_base::Area(_fb_mode.width(), + _fb_mode.height())); /* * Handle input events @@ -244,7 +245,7 @@ void Vancouver_console::entry() else checksum2 = 0; for (int j=0; j<25; j++) { for (int i=0; i<80; i++) { - Canvas::Point where(i*8, j*15); + Genode::Surface_base::Point where(i*8, j*15); char character = *((char *) (_guest_fb +(_regs->offset << 1) +j*80*2+i*2)); char colorvalue = *((char *) (_guest_fb+(_regs->offset << 1)+j*80*2+i*2+1)); char buffer[2]; buffer[0] = character; buffer[1] = 0; @@ -255,7 +256,7 @@ void Vancouver_console::entry() ((fg & 0x2) >> 1)*127+lum, /* G+luminosity */ (fg & 0x1)*127+lum /* B+luminosity */); - canvas.draw_string(where, default_font, color, buffer); + Text_painter::paint(surface, where, default_font, color, buffer); /* Checksum for comparing */ if (cmp_even) checksum1 += character;