diff --git a/repos/gems/include/gems/dither_painter.h b/repos/gems/include/gems/dither_painter.h index 74619620b..896ccfb0e 100644 --- a/repos/gems/include/gems/dither_painter.h +++ b/repos/gems/include/gems/dither_painter.h @@ -14,64 +14,8 @@ #ifndef _INCLUDE__GEMS__DITHER_PAINTER_H_ #define _INCLUDE__GEMS__DITHER_PAINTER_H_ -/* Genode includes */ -#include -#include -#include +/* maintain compatibility */ +#include -struct Dither_painter -{ - /* - * Surface and texture must have the same size - */ - template - static inline void paint(Genode::Surface &surface, - Genode::Texture const &texture) - { - if (surface.size() != texture.size()) return; - - Genode::Surface_base::Rect const clipped = surface.clip(); - - if (!clipped.valid()) return; - - unsigned const offset = surface.size().w()*clipped.y1() + clipped.x1(); - - DST_PT *dst, *dst_line = surface.addr() + offset; - SRC_PT const *src_pixel, *src_pixel_line = texture.pixel() + offset; - unsigned char const *src_alpha, *src_alpha_line = texture.alpha() + offset; - - unsigned const line_len = surface.size().w(); - - for (int y = clipped.y1(), h = clipped.h() ; h--; y++) { - - src_pixel = src_pixel_line; - src_alpha = src_alpha_line; - dst = dst_line; - - for (int x = clipped.x1(), w = clipped.w(); w--; x++) { - - int const v = Genode::Dither_matrix::value(x, y) >> 4; - - SRC_PT const pixel = *src_pixel++; - unsigned char const alpha = *src_alpha++; - - int const r = pixel.r() - v; - int const g = pixel.g() - v; - int const b = pixel.b() - v; - int const a = alpha ? (int)alpha - v : 0; - - using Genode::min; - using Genode::max; - - *dst++ = DST_PT(max(0, r), max(0, g), max(0, b), max(0, a)); - } - - src_pixel_line += line_len; - src_alpha_line += line_len; - dst_line += line_len; - } - } -}; - #endif /* _INCLUDE__GEMS__DITHER_PAINTER_H_ */ diff --git a/repos/gems/include/gems/nitpicker_buffer.h b/repos/gems/include/gems/nitpicker_buffer.h index 36e058c96..065a01b8c 100644 --- a/repos/gems/include/gems/nitpicker_buffer.h +++ b/repos/gems/include/gems/nitpicker_buffer.h @@ -37,8 +37,9 @@ struct Nitpicker_buffer typedef Genode::Surface Pixel_surface; typedef Genode::Surface Alpha_surface; - typedef Genode::Surface_base::Area Area; - typedef Genode::Surface_base::Rect Rect; + typedef Genode::Surface_base::Area Area; + typedef Genode::Surface_base::Rect Rect; + typedef Genode::Surface_base::Point Point; typedef Genode::Attached_ram_dataspace Ram_ds; @@ -127,7 +128,7 @@ struct Nitpicker_buffer surface.clip(clip_rect); - Dither_painter::paint(surface, texture); + Dither_painter::paint(surface, texture, Point()); } void _update_input_mask() diff --git a/repos/os/include/os/dither_painter.h b/repos/os/include/os/dither_painter.h new file mode 100644 index 000000000..601d3e8b5 --- /dev/null +++ b/repos/os/include/os/dither_painter.h @@ -0,0 +1,100 @@ +/* + * \brief Functor for converting pixel formats by applying dithering + * \author Norman Feske + * \date 2014-09-10 + */ + +/* + * Copyright (C) 2014 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__DITHER_PAINTER_H_ +#define _INCLUDE__OS__DITHER_PAINTER_H_ + +/* Genode includes */ +#include +#include +#include + + +struct Dither_painter +{ + /* + * Surface and texture must have the same size + */ + template + static inline void paint(Genode::Surface &surface, + Genode::Texture const &texture, + Genode::Surface_base::Point const &pos) + { + Genode::Surface_base::Rect const clipped = surface.clip(); + + if (!clipped.valid()) return; + + using Genode::min; + using Genode::max; + + unsigned const dst_x = max(pos.x(), clipped.x1()); + unsigned const dst_y = max(pos.y(), clipped.y1()); + + unsigned const dst_line_len = surface.size().w(); + unsigned const dst_offset = dst_line_len*dst_y + dst_x; + + unsigned const src_line_len = texture.size().w(); + unsigned const src_offset = src_line_len*clipped.y1() + clipped.x1(); + + DST_PT *dst, *dst_line = surface.addr() + dst_offset; + SRC_PT const *src_pixel, *src_pixel_line = texture.pixel() + src_offset; + unsigned char const *src_alpha, *src_alpha_line = texture.alpha() + src_offset; + bool const src_has_alpha = texture.alpha() != nullptr; + + unsigned const x_max = min((unsigned)clipped.x2(), dst_x + texture.size().w() - 1); + unsigned const y_max = min((unsigned)clipped.y2(), dst_y + texture.size().h() - 1); + + for (unsigned y = dst_y; y <= y_max; y++) { + + src_pixel = src_pixel_line; + src_alpha = src_alpha_line; + dst = dst_line; + + if (src_has_alpha) { + for (unsigned x = dst_x; x <= x_max; x++) { + + int const v = Genode::Dither_matrix::value(x, y) >> 4; + + SRC_PT const pixel = *src_pixel++; + unsigned char const alpha = *src_alpha++; + + int const r = pixel.r() - v; + int const g = pixel.g() - v; + int const b = pixel.b() - v; + int const a = alpha ? (int)alpha - v : 0; + + *dst++ = DST_PT(max(0, r), max(0, g), max(0, b), max(0, a)); + } + } else { + for (unsigned x = dst_x; x <= x_max; x++) { + + int const v = Genode::Dither_matrix::value(x, y) >> 4; + + SRC_PT const pixel = *src_pixel++; + + int const r = pixel.r() - v; + int const g = pixel.g() - v; + int const b = pixel.b() - v; + + *dst++ = DST_PT(max(0, r), max(0, g), max(0, b)); + } + } + + src_pixel_line += src_line_len; + src_alpha_line += src_line_len; + dst_line += dst_line_len; + } + } +}; + +#endif /* _INCLUDE__OS__DITHER_PAINTER_H_ */ diff --git a/repos/demo/include/util/dither_matrix.h b/repos/os/include/util/dither_matrix.h similarity index 100% rename from repos/demo/include/util/dither_matrix.h rename to repos/os/include/util/dither_matrix.h