diff --git a/src/l4/pkg/libgfxbitmap/Control b/src/l4/pkg/libgfxbitmap/Control new file mode 100644 index 00000000..8e8584b3 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/Control @@ -0,0 +1,3 @@ +provides: libgfxbitmap libgfxbitmap-support +requires: l4sys l4re_c libc +maintainer: adam@os.inf.tu-dresden.de diff --git a/src/l4/pkg/libgfxbitmap/Makefile b/src/l4/pkg/libgfxbitmap/Makefile new file mode 100644 index 00000000..a6ff4ea7 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/Makefile @@ -0,0 +1,4 @@ +PKGDIR = . +L4DIR ?= $(PKGDIR)/../.. + +include $(L4DIR)/mk/subdir.mk diff --git a/src/l4/pkg/libgfxbitmap/doc/files.cfg b/src/l4/pkg/libgfxbitmap/doc/files.cfg new file mode 100644 index 00000000..225cc7f6 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/doc/files.cfg @@ -0,0 +1 @@ +INPUT += l4/libgfxbitmap diff --git a/src/l4/pkg/libgfxbitmap/include/Makefile b/src/l4/pkg/libgfxbitmap/include/Makefile new file mode 100644 index 00000000..1070aebf --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/include/Makefile @@ -0,0 +1,6 @@ +PKGDIR = .. +L4DIR ?= $(PKGDIR)/../.. + +EXTRA_TARGET = support + +include $(L4DIR)/mk/include.mk diff --git a/src/l4/pkg/libgfxbitmap/include/bitmap.h b/src/l4/pkg/libgfxbitmap/include/bitmap.h new file mode 100644 index 00000000..40fdd667 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/include/bitmap.h @@ -0,0 +1,162 @@ +/** + * \file + * \brief Bitmap renderer header file. + */ +/* + * (c) 2009 Adam Lackorzynski + * economic rights: Technische Universität Dresden (Germany) + * This file is part of TUD:OS and distributed under the terms of the + * GNU Lesser General Public License 2.1. + * Please see the COPYING-LGPL-2.1 file for details. + */ +#pragma once + +#include +#include + +/** + * \defgroup api_gfxbitmap Bitmap graphics and fonts + * \ingroup l4util_api + * + * This library provides some functions for bitmap handling in frame + * buffers. Includes simple functions like filling or copying an area of the + * frame buffer going up to rendering text into the frame buffer using + * bitmap fonts. + */ + +/** + * \defgroup api_gfxbitmap_bitmap Functions for rendering bitmap data in frame buffers + * \ingroup api_gfxbitmap + */ + +EXTERN_C_BEGIN +/** + * \name Param macros for bmap_* + * + * Bitmap type - start least or start most significant bit */ +/*@{*/ +#define pSLIM_BMAP_START_MSB 0x02 /*!<\brief `pbm'-style: "The bits are + * stored eight per byte, high bit first + * low bit last." */ +#define pSLIM_BMAP_START_LSB 0x01 /*!< the other way round*/ +/*@}*/ + +/** + * \addtogroup api_gfxbitmap_bitmap + */ +/*@{*/ + +/** + * \brief Standard color type + * + * It's a RGB type with 8bits for each channel, regardless of the + * framebuffer used. + */ +typedef unsigned int gfxbitmap_color_t; + +/** + * \brief Specific color type + * + * This color type is specific for a particular framebuffer, it can be use + * to write pixel on a framebuffer. Use gfxbitmap_convert_color to convert + * from gfxbitmap_color_t to gfxbitmap_color_pix_t. + */ +typedef unsigned int gfxbitmap_color_pix_t; + +/** offsets in pmap[] and bmap[] */ +struct gfxbitmap_offset +{ + l4_uint32_t preskip_x; /**< skip pixels at beginning of line */ + l4_uint32_t preskip_y; /**< skip lines */ + l4_uint32_t endskip_x; /**< skip pixels at end of line */ +}; + +/** + * \brief Convert a color. + * + * Converts a given color in standard format to the format used in the + * framebuffer. + */ +gfxbitmap_color_pix_t +gfxbitmap_convert_color(l4re_video_view_info_t *vi, gfxbitmap_color_t rgb); + +/** + * \brief Fill a rectangular area with a color. + * + * \param vfb Frame buffer. + * \param vi Frame buffer information structure. + * \param x X position of area. + * \param y Y position of area. + * \param w Width of area. + * \param h Height of area. + * \param color Color of area. + */ +void +gfxbitmap_fill(l4_uint8_t *vfb, l4re_video_view_info_t *vi, + int x, int y, int w, int h, gfxbitmap_color_pix_t color); + +/** + * \brief Fill a rectangular area with a bicolor bitmap pattern. + * + * \param vfb Frame buffer. + * \param vi Frame buffer information structure. + * \param x X position of area. + * \param y Y position of area. + * \param w Width of area. + * \param h Height of area. + * \param bmap Bitmap pattern. + * \param fgc Foreground color. + * \param bgc Background color. + * \param offset Offsets. + * \param mode Mode + * + * \see #pSLIM_BMAP_START_MSB and #pSLIM_BMAP_START_LSB. + */ +void +gfxbitmap_bmap(l4_uint8_t *vfb, l4re_video_view_info_t *vi, + l4_int16_t x, l4_int16_t y, l4_uint32_t w, + l4_uint32_t h, l4_uint8_t *bmap, + gfxbitmap_color_pix_t fgc, gfxbitmap_color_pix_t bgc, + struct gfxbitmap_offset *offset, l4_uint8_t mode); + +/** + * \brief Set area from source area. + * + * \param vfb Frame buffer. + * \param vi Frame buffer information structure. + * \param x X position of area. + * \param y Y position of area. + * \param w Width of area. + * \param h Height of area. + * \param pmap Source. + * \param xoffs X offset. + * \param yoffs Y offset. + * \param offset Offsets. + * \param pwidth Width of source in bytes. + */ +void +gfxbitmap_set(l4_uint8_t *vfb, l4re_video_view_info_t *vi, + l4_int16_t x, l4_int16_t y, l4_uint32_t w, + l4_uint32_t h, l4_uint32_t xoffs, l4_uint32_t yoffs, + l4_uint8_t *pmap, struct gfxbitmap_offset *offset, + l4_uint32_t pwidth); + +/** + * \brief Copy a rectangular area. + * + * \param dest Destination frame buffer. + * \param src Source frame buffer. + * \param vi Frame buffer information structure. + * \param x Source X position of area. + * \param y Source Y position of area. + * \param w Width of area. + * \param h Height of area. + * \param dx Source X position of area. + * \param dy Source Y position of area. + */ +void +gfxbitmap_copy(l4_uint8_t *dest, l4_uint8_t *src, l4re_video_view_info_t *vi, + int x, int y, int w, int h, int dx, int dy); +/*@}*/ + +EXTERN_C_END diff --git a/src/l4/pkg/libgfxbitmap/include/font.h b/src/l4/pkg/libgfxbitmap/include/font.h new file mode 100644 index 00000000..5428a946 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/include/font.h @@ -0,0 +1,133 @@ +/** + * \file + * \brief Bitmap font renderer header file. + */ +/* + * (c) 2009 Adam Lackorzynski + * economic rights: Technische Universität Dresden (Germany) + * This file is part of TUD:OS and distributed under the terms of the + * GNU Lesser General Public License 2.1. + * Please see the COPYING-LGPL-2.1 file for details. + */ +#pragma once + +#include +#include +#include + +/** + * \defgroup api_gfxbitmap_font Functions for rendering bitmap fonts to frame buffers + * \ingroup api_gfxbitmap + */ + +/** + * \addtogroup api_gfxbitmap_font + */ +/*@{*/ + +/** + * \brief Constant to use for the default font. + */ +#define GFXBITMAP_DEFAULT_FONT (void *)0 + +/** + * \brief Constant for length field. + * + * Use this if the function should call strlen on the text argument itself. + */ +enum { GFXBITMAP_USE_STRLEN = ~0U }; + +EXTERN_C_BEGIN + +/** \brief Font */ +typedef void *gfxbitmap_font_t; + +/** + * \brief Initialize the library. + * + * This function must be called before any other font function of this + * library. + * + * \return 0 on success, other on error + */ +L4_CV int gfxbitmap_font_init(void); + +/** + * \brief Get a font descriptor. + * + * \param name Name of the font. + * + * \return A (opaque) font descriptor, or NULL if font could not be found. + */ +L4_CV gfxbitmap_font_t gfxbitmap_font_get(const char *name); + +/** + * \brief Get the font width. + * + * \param font Font. + * \return Font width, 0 if font width could not be retrieved. + */ +L4_CV unsigned +gfxbitmap_font_width(gfxbitmap_font_t font); + +/** + * \brief Get the font height. + * + * \param font Font. + * \return Font height, 0 if font height could not be retrieved. + */ +L4_CV unsigned +gfxbitmap_font_height(gfxbitmap_font_t font); + +/** + * \brief Get bitmap font data for a specific character. + * + * \param font Font. + * \param c Character. + * \return Pointer to bmap data, NULL on error. + */ +L4_CV void * +gfxbitmap_font_data(gfxbitmap_font_t font, unsigned c); + +/** + * \brief Render a string to a framebuffer. + * + * \param fb Pointer to frame buffer. + * \param vi Frame buffer info structure. + * \param font Font. + * \param text Text string. + * \param len Length of the text string. + * \param x Horizontal position in the frame buffer. + * \param y Vertical position in the frame buffer. + * \param fg Foreground color. + * \param bg Background color. + */ +L4_CV void +gfxbitmap_font_text(void *fb, l4re_video_view_info_t *vi, + gfxbitmap_font_t font, const char *text, unsigned len, + unsigned x, unsigned y, + gfxbitmap_color_pix_t fg, gfxbitmap_color_pix_t bg); + +/** + * \brief Render a string to a framebuffer, including scaling. + * + * \param fb Pointer to frame buffer. + * \param vi Frame buffer info structure. + * \param font Font. + * \param text Text string. + * \param len Length of the text string. + * \param x Horizontal position in the frame buffer. + * \param y Vertical position in the frame buffer. + * \param fg Foreground color. + * \param bg Background color. + * \param scale_x Horizonal scale factor. + * \param scale_y Vertical scale factor. + */ +L4_CV void +gfxbitmap_font_text_scale(void *fb, l4re_video_view_info_t *vi, + gfxbitmap_font_t font, const char *text, unsigned len, + unsigned x, unsigned y, + gfxbitmap_color_pix_t fg, gfxbitmap_color_pix_t bg, + int scale_x, int scale_y); +EXTERN_C_END +/*@}*/ diff --git a/src/l4/pkg/libgfxbitmap/include/support b/src/l4/pkg/libgfxbitmap/include/support new file mode 100644 index 00000000..2857cbf6 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/include/support @@ -0,0 +1,27 @@ +/* vim:set ft=cpp: */ +/** + * \file + * \brief Terminal support functionality + * + * \date 2009 + * \author Adam Lackorzynski + */ +/* + * (c) 2009 Author(s) + * economic rights: Technische Universität Dresden (Germany) + * This file is part of TUD:OS and distributed under the terms of the + * GNU Lesser General Public License 2.1. + * Please see the COPYING-LGPL-2.1 file for details. + */ +#ifndef __LIBTERM__SUPPORT_H__ +#define __LIBTERM__SUPPORT_H__ + +#include + +void +libterm_init_colors(L4Re::Video::View::Info *fbi); + +int +libterm_get_color(int mode, int color); + +#endif diff --git a/src/l4/pkg/libgfxbitmap/lib/Makefile b/src/l4/pkg/libgfxbitmap/lib/Makefile new file mode 100644 index 00000000..78f0515f --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/Makefile @@ -0,0 +1,8 @@ +PKGDIR = .. +L4DIR ?= $(PKGDIR)/../.. + +TARGET := src support + +include $(L4DIR)/mk/subdir.mk + +support: src diff --git a/src/l4/pkg/libgfxbitmap/lib/src/Makefile b/src/l4/pkg/libgfxbitmap/lib/src/Makefile new file mode 100644 index 00000000..8008f9b9 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/src/Makefile @@ -0,0 +1,11 @@ +PKGDIR ?= ../.. +L4DIR ?= $(PKGDIR)/../.. + +TARGET = libgfxbitmap.a +SRC_C = font.c bitmap.c + +FONTS = lat0-12.psf lat0-14.psf lat0-16.psf vgafont.psf +SRC_DATA += $(FONTS) + +include $(L4DIR)/mk/lib.mk + diff --git a/src/l4/pkg/libgfxbitmap/lib/src/bitmap.c b/src/l4/pkg/libgfxbitmap/lib/src/bitmap.c new file mode 100644 index 00000000..0ed6c877 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/src/bitmap.c @@ -0,0 +1,667 @@ +/** + * \file + * \brief bitmap functions + * + * \date 2001 + * \author Christian Helmuth + * Frank Mehnert + * Adam Lackorzynski */ +/* + * (c) 2001-2009 Author(s) + * economic rights: Technische Universität Dresden (Germany) + * This file is part of TUD:OS and distributed under the terms of the + * GNU Lesser General Public License 2.1. + * Please see the COPYING-LGPL-2.1 file for details. + */ + +#include +#include /* needed for memmove */ + +#include + +#include + +#ifdef ARCH_x86 +static int use_fastmemcpy; +#endif + +#define OFFSET(x, y, ptr, bytepp) ptr += (y) * bwidth + (x) * (bytepp); + +static inline void +_bmap16lsb(l4_uint8_t *vfb, + l4_uint8_t *bmap, + l4_uint32_t fgc, + l4_uint32_t bgc, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth) +{ + l4_uint32_t nobits=0; + l4_uint32_t i, j, k, kmod; + + nobits += offset->preskip_y + * (w + offset->preskip_x + offset->endskip_x); + /* length of one line in bmap (bits!) */ + + for (i = 0; i < h; i++) { + nobits += offset->preskip_x; + for (j = 0; j < w; j++, nobits++) { + k = nobits>>3; + kmod = (nobits)%8; + if ( bmap[k] & (0x01 << kmod) ) + *(l4_uint16_t*) (&vfb[2*j]) = (l4_uint16_t) (fgc & 0xffff); + else + *(l4_uint16_t*) (&vfb[2*j]) = (l4_uint16_t) (bgc & 0xffff); + } +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)vfb, + (unsigned long)vfb + w*2); +#endif + vfb += bwidth; + } +} + +static inline void +_bmap16msb(l4_uint8_t *vfb, + l4_uint8_t *bmap, + l4_uint32_t fgc, + l4_uint32_t bgc, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth) +{ + l4_uint32_t i, j; + l4_uint32_t nobits = offset->preskip_y + * (w + offset->preskip_x + offset->endskip_x); + + for (i = 0; i < h; i++) + { + unsigned char mask, *b; + nobits += offset->preskip_x; + mask = 0x80 >> (nobits % 8); + b = bmap + nobits / 8; + for (j = 0; j < w; j++, nobits++) + { + /* gcc is able to code the entire loop without using any jump + * if compiled with -march=i686 (uses cmov instructions then) */ + *(l4_uint16_t*) (&vfb[2*j]) = (*b & mask) + ? (l4_uint16_t) (fgc & 0xffff) + : (l4_uint16_t) (bgc & 0xffff); + b += mask & 1; + mask = (mask >> 1) | (mask << 7); /* gcc optimizes this into ROR */ + } +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)vfb, + (unsigned long)vfb + w*2); +#endif + vfb += bwidth; + nobits += offset->endskip_x; + } +} + +static inline void +_bmap24lsb(l4_uint8_t *vfb, + l4_uint8_t *bmap, + l4_uint32_t fgc, + l4_uint32_t bgc, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth) +{ + l4_uint32_t nobits=0; + l4_uint32_t i,j, k,kmod; + + nobits += offset->preskip_y + * (w + offset->preskip_x + offset->endskip_x); + /* length of one line in bmap (bits!) */ + + for (i = 0; i < h; i++) { + nobits += offset->preskip_x; + for (j = 0; j < w; j++, nobits++) { + k = nobits>>3; + kmod = (nobits)%8; + if ( bmap[k] & (0x01 << kmod) ) { + *(l4_uint16_t*) (&vfb[3*j]) = (l4_uint16_t) (fgc & 0xffff); + vfb[3*j+2] = (l4_uint8_t) (fgc >> 16); + } + else { + *(l4_uint16_t*) (&vfb[3*j]) = (l4_uint16_t) (bgc & 0xffff); + vfb[3*j+2] = (l4_uint8_t) (bgc >> 16); + } + } +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)vfb, + (unsigned long)vfb + w*3); +#endif + vfb += bwidth; + } +} + +static inline void +_bmap24msb(l4_uint8_t *vfb, + l4_uint8_t *bmap, + l4_uint32_t fgc, + l4_uint32_t bgc, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth) +{ + l4_uint32_t nobits=0; + l4_uint32_t i,j, k,kmod; + + nobits += offset->preskip_y + * (w + offset->preskip_x + offset->endskip_x); + /* length of one line in bmap (bits!) */ + + for (i = 0; i < h; i++) { + nobits += offset->preskip_x; + for (j = 0; j < w; j++, nobits++) { + k = nobits>>3; + kmod = (nobits)%8; + if ( bmap[k] & (0x80 >> kmod) ) { + *(l4_uint16_t*) (&vfb[3*j]) = (l4_uint16_t) (fgc & 0xffff); + vfb[3*j+2] = (l4_uint8_t) (fgc >> 16); + } + else { + *(l4_uint16_t*) (&vfb[3*j]) = (l4_uint16_t) (bgc & 0xffff); + vfb[3*j+2] = (l4_uint8_t) (bgc >> 16); + } + } +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)vfb, + (unsigned long)vfb + w*3); +#endif + vfb += bwidth; + /* length of one line in bmap parsed */ + nobits += offset->endskip_x; + } +} + +static inline void +_bmap32lsb(l4_uint8_t *vfb, + l4_uint8_t *bmap, + l4_uint32_t fgc, + l4_uint32_t bgc, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth) +{ + l4_uint32_t nobits=0; + l4_uint32_t i,j, k,kmod; + + nobits += offset->preskip_y + * (w + offset->preskip_x + offset->endskip_x); + /* length of one line in bmap (bits!) */ + + for (i = 0; i < h; i++) { + nobits += offset->preskip_x; + for (j = 0; j < w; j++, nobits++) { + l4_uint32_t *dest = (l4_uint32_t*)&vfb[4*j]; + k = nobits>>3; + kmod = (nobits)%8; + *dest = (bmap[k] & (0x01 << kmod)) + ? fgc & 0xffffffff + : bgc & 0xffffffff; + } +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)vfb, + (unsigned long)vfb + w*4); +#endif + vfb += bwidth; + } +} + +static inline void +_bmap32msb(l4_uint8_t *vfb, + l4_uint8_t *bmap, + l4_uint32_t fgc, + l4_uint32_t bgc, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth) +{ + l4_uint32_t nobits=0; + l4_uint32_t i,j,k,kmod; + + nobits += offset->preskip_y + * (w + offset->preskip_x + offset->endskip_x); + /* length of one line in bmap (bits!) */ + + for (i = 0; i < h; i++) { + nobits += offset->preskip_x; + for (j = 0; j < w; j++, nobits++) { + k = nobits>>3; + kmod = (nobits)%8; + if ( bmap[k] & (0x80 >> kmod) ) + *(l4_uint32_t*) (&vfb[4*j]) = (l4_uint32_t) (fgc & 0x00ffffff); + else + *(l4_uint32_t*) (&vfb[4*j]) = (l4_uint32_t) (bgc & 0x00ffffff); + } +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)vfb, + (unsigned long)vfb + w*4); +#endif + vfb += bwidth; + /* length of one line in bmap parsed */ + nobits += offset->endskip_x; + } +} + +static inline void +_set16(l4_uint8_t *dest, + l4_uint8_t *pmap, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth, + l4_uint32_t pwidth) +{ + l4_uint32_t i; + +#ifdef ARCH_x86 + if (use_fastmemcpy && (w % 4 == 0)) + { + asm ("emms"); + for (i = 0; i < h; i++) + { + l4_umword_t dummy; + pmap += 2 * offset->preskip_x; + asm volatile("xorl %%edx,%%edx \n\t" + "1: \n\t" + "movq (%%esi,%%edx,8),%%mm0 \n\t" + "movntq %%mm0,(%%edi,%%edx,8) \n\t" + "add $1,%%edx \n\t" + "dec %%ecx \n\t" + "jnz 1b \n\t" + : "=c"(dummy), "=d"(dummy) + : "c"(w/4), "S"(pmap), "D"(dest)); + dest += bwidth; + pmap += pwidth; + } + asm ("sfence; emms"); + } + else +#endif + { + for (i = 0; i < h; i++) + { + pmap += 2 * offset->preskip_x; + memcpy(dest, pmap, w*2); +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)dest, + (unsigned long)dest + w*2); +#endif + dest += bwidth; + pmap += pwidth; + } + } +} + +static inline void +_set24(l4_uint8_t *dest, + l4_uint8_t *pmap, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth, + l4_uint32_t pwidth) +{ + l4_uint32_t i; + + for (i = 0; i < h; i++) + { + pmap += 3 * offset->preskip_x; + memcpy(dest, pmap, w*3); +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)dest, + (unsigned long)dest + w*3); +#endif + dest += bwidth; + pmap += pwidth; + } +} + +static inline void +_set32(l4_uint8_t *dest, + l4_uint8_t *pmap, + l4_uint32_t w, l4_uint32_t h, + struct gfxbitmap_offset* offset, + l4_uint32_t bwidth, + l4_uint32_t pwidth) +{ + l4_uint32_t i; + + for (i = 0; i < h; i++) + { + pmap += 4 * offset->preskip_x; + memcpy(dest, pmap, w*4); +#ifdef CLEAN_CACHE + l4_sys_cache_clean_range((unsigned long)dest, + (unsigned long)dest + w*4); +#endif + dest += bwidth; + pmap += pwidth; + } +} + +static inline void +_copy16(l4_uint8_t *dest, + l4_uint8_t *src, + l4_int16_t x, l4_int16_t y, + l4_int16_t dx, l4_int16_t dy, + l4_uint32_t w, l4_uint32_t h, + l4_uint32_t bwidth) +{ + l4_uint32_t i; + + if (dy == y && dx == x) + return; + + if (y >= dy) + { + OFFSET( x, y, src, 2); + OFFSET(dx, dy, dest, 2); + for (i = 0; i < h; i++) + { + /* memmove can deal with overlapping regions */ + memmove(dest, src, 2*w); + src += bwidth; + dest += bwidth; + } + } + else + { + OFFSET( x, y + h - 1, src, 2); + OFFSET(dx, dy + h - 1, dest, 2); + for (i = 0; i < h; i++) + { + /* memmove can deal with overlapping regions */ + memmove(dest, src, 2*w); + src -= bwidth; + dest -= bwidth; + } + } +} + +static inline void +_copy24(l4_uint8_t *dest, + l4_uint8_t *src, + l4_int16_t x, l4_int16_t y, + l4_int16_t dx, l4_int16_t dy, + l4_uint32_t w, l4_uint32_t h, + l4_uint32_t bwidth) +{ + l4_uint32_t i; + + if (y >= dy) { + if (y == dy && dx >= x) { /* tricky */ + int j; + if (x == dx) + return; + /* my way: start right go left */ + OFFSET( x, y, src, 3); + OFFSET(dx, dy, dest, 3); + for (i = 0; i < h; i++) { + for (j = w; j >= 0; --j) { + *(l4_uint16_t*) (&dest[3*j]) = *(l4_uint16_t*) (&src[3*j]); + dest[3*j+2] = src[3*j+2]; + } + src += bwidth; + dest += bwidth; + } + + } + else { /* copy from top to bottom */ + l4_uint32_t j; + OFFSET( x, y, src, 3); + OFFSET(dx, dy, dest, 3); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + *(l4_uint16_t*) (&dest[3*j]) = *(l4_uint16_t*) (&src[3*j]); + dest[3*j+2] = src[3*j+2]; + } + src += bwidth; + dest += bwidth; + } + } + } + else { /* copy from bottom to top */ + OFFSET( x, y + h, src, 3); + OFFSET(dx, dy + h, dest, 3); + for (i = 0; i < h; i++) { + l4_uint32_t j; + src -= bwidth; + dest -= bwidth; + for (j = 0; j < w; j++) { + *(l4_uint16_t*) (&dest[3*j]) = *(l4_uint16_t*) (&src[3*j]); + dest[3*j+2] = src[3*j+2]; + } + } + } +} + +static inline void +_copy32(l4_uint8_t *dest, + l4_uint8_t *src, + l4_int16_t x, l4_int16_t y, + l4_int16_t dx, l4_int16_t dy, + l4_uint32_t w, l4_uint32_t h, + l4_uint32_t bwidth) +{ + l4_uint32_t i; + + if (y >= dy) { + if (y == dy && dx >= x) { /* tricky */ + int j; + if (x == dx) + return; + /* my way: start right go left */ + OFFSET( x, y, src, 4); + OFFSET(dx, dy, dest, 4); + for (i = 0; i < h; i++) { + for (j = w; j >= 0; --j) + *(l4_uint32_t*) (&dest[4*j]) = *(l4_uint32_t*) (&src[4*j]); + src += bwidth; + dest += bwidth; + } + + } + else { /* copy from top to bottom */ + l4_uint32_t j; + OFFSET( x, y, src, 4); + OFFSET(dx, dy, dest, 4); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) + *(l4_uint32_t*) (&dest[4*j]) = *(l4_uint32_t*) (&src[4*j]); + src += bwidth; + dest += bwidth; + } + } + } + else { /* copy from bottom to top */ + l4_uint32_t j; + OFFSET( x, y + h, src, 4); + OFFSET(dx, dy + h, dest, 4); + for (i = 0; i < h; i++) { + src -= bwidth; + dest -= bwidth; + for (j = 0; j < w; j++) + *(l4_uint32_t*) (&dest[4*j]) = *(l4_uint32_t*) (&src[4*j]); + } + } +} + +static inline void +_fill16(l4_uint8_t *vfb, + l4_uint32_t w, l4_uint32_t h, + l4_uint32_t color, + l4_uint32_t bwidth) +{ + l4_uint32_t i,j; + + for (i = 0; i < h; i++) + { + for (j = 0; j < w; j++) + *(l4_uint16_t*) (&vfb[2*j]) = (l4_uint16_t)color; + vfb += bwidth; + } +} + +static inline void +_fill24(l4_uint8_t *vfb, + l4_uint32_t w, l4_uint32_t h, + l4_uint32_t color, + l4_uint32_t bwidth) +{ + l4_uint32_t i,j; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + *(l4_uint16_t*) (&vfb[3*j ]) = (l4_uint16_t)color; + vfb[3*j+2] = (l4_uint8_t) (color >> 16); + } + vfb += bwidth; + } +} + +static inline void +_fill32(l4_uint8_t *vfb, + l4_uint32_t w, l4_uint32_t h, + l4_uint32_t color, + l4_uint32_t bwidth) +{ + l4_uint32_t i,j; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) + *(l4_uint32_t*) (&vfb[4*j]) = (l4_uint32_t)color; + vfb += bwidth; + } +} + +void +gfxbitmap_fill(l4_uint8_t *vfb, l4re_video_view_info_t *vi, + int x, int y, int w, int h, unsigned color) +{ + unsigned bwidth = vi->bytes_per_line; + OFFSET(x, y, vfb, vi->pixel_info.bytes_per_pixel); + + switch (vi->pixel_info.bytes_per_pixel) + { + case 4: + _fill32(vfb, w, h, color, vi->bytes_per_line); + break; + case 3: + _fill24(vfb, w, h, color, vi->bytes_per_line); + break; + case 2: + default: + _fill16(vfb, w, h, color, vi->bytes_per_line); + } +} + +void +gfxbitmap_bmap(l4_uint8_t *vfb, l4re_video_view_info_t *vi, + l4_int16_t x, l4_int16_t y, l4_uint32_t w, + l4_uint32_t h, l4_uint8_t *bmap, l4_uint32_t fgc, l4_uint32_t bgc, + struct gfxbitmap_offset* offset, l4_uint8_t mode) +{ + l4_uint32_t bwidth = vi->bytes_per_line; + OFFSET(x, y, vfb, vi->pixel_info.bytes_per_pixel); + + switch (mode) + { + case pSLIM_BMAP_START_MSB: + switch (vi->pixel_info.bytes_per_pixel) + { + case 4: + _bmap32msb(vfb, bmap, fgc, bgc, w, h, offset, bwidth); + break; + case 3: + _bmap24msb(vfb, bmap, fgc, bgc, w, h, offset, bwidth); + break; + case 2: + default: + _bmap16msb(vfb, bmap, fgc, bgc, w, h, offset, bwidth); + } + break; + case pSLIM_BMAP_START_LSB: + default: /* `start at least significant' bit is default */ + switch (vi->pixel_info.bytes_per_pixel) + { + case 4: + _bmap32lsb(vfb, bmap, fgc, bgc, w, h, offset, bwidth); + break; + case 3: + _bmap24lsb(vfb, bmap, fgc, bgc, w, h, offset, bwidth); + break; + case 2: + default: + _bmap16lsb(vfb, bmap, fgc, bgc, w, h, offset, bwidth); + } + } +} + +void +gfxbitmap_set(l4_uint8_t *vfb, l4re_video_view_info_t *vi, + l4_int16_t x, l4_int16_t y, l4_uint32_t w, + l4_uint32_t h, l4_uint32_t xoffs, l4_uint32_t yoffs, + l4_uint8_t *pmap, struct gfxbitmap_offset* offset, + l4_uint32_t pwidth) +{ + l4_uint32_t bwidth = vi->bytes_per_line; + + OFFSET(x+xoffs, y+yoffs, vfb, vi->pixel_info.bytes_per_pixel); + + switch (vi->pixel_info.bytes_per_pixel) + { + case 4: + _set32(vfb, pmap, w, h, offset, bwidth, pwidth); + break; + case 3: + _set24(vfb, pmap, w, h, offset, bwidth, pwidth); + break; + case 2: + default: + _set16(vfb, pmap, w, h, offset, bwidth, pwidth); + } +} + +void +gfxbitmap_copy(l4_uint8_t *dest, l4_uint8_t *src, l4re_video_view_info_t *vi, + int x, int y, int w, int h, int dx, int dy) +{ + switch (vi->pixel_info.bytes_per_pixel) + { + case 4: + _copy32(dest, src, x, y, dx, dy, w, h, vi->bytes_per_line); + break; + case 3: + _copy24(dest, src, x, y, dx, dy, w, h, vi->bytes_per_line); + break; + case 2: + default: + _copy16(dest, src, x, y, dx, dy, w, h, vi->bytes_per_line); + } +} + +gfxbitmap_color_pix_t +gfxbitmap_convert_color(l4re_video_view_info_t *vi, gfxbitmap_color_t rgb) +{ + switch (l4re_video_bits_per_pixel(&vi->pixel_info)) + { + case 24: + case 32: + return rgb & 0x00FFFFFF; + + case 15: + return (((rgb >> (16 + 8 - vi->pixel_info.r.size)) & ((1 << vi->pixel_info.r.size)-1)) << vi->pixel_info.r.shift) + | (((rgb >> ( 8 + 8 - vi->pixel_info.g.size)) & ((1 << vi->pixel_info.g.size)-1)) << vi->pixel_info.g.shift) + | (((rgb >> ( 0 + 8 - vi->pixel_info.b.size)) & ((1 << vi->pixel_info.b.size)-1)) << vi->pixel_info.b.shift); + + case 16: + default: + return ((rgb & 0x00F80000) >> 8) + | ((rgb & 0x0000FC00) >> 5) + | ((rgb & 0x000000F8) >> 3); + } + +} diff --git a/src/l4/pkg/libgfxbitmap/lib/src/font.c b/src/l4/pkg/libgfxbitmap/lib/src/font.c new file mode 100644 index 00000000..89b67f2d --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/src/font.c @@ -0,0 +1,245 @@ +/** + * \file + * \brief Font functions + * + * \author Christian Helmuth + * Frank Mehnert + * Adam Lackorzynski */ + +/* + * (c) 2001-2009 Author(s) + * economic rights: Technische Universität Dresden (Germany) + * This file is part of TUD:OS and distributed under the terms of the + * GNU Lesser General Public License 2.1. + * Please see the COPYING-LGPL-2.1 file for details. + */ + +#include +#include +#include +#include +#include + +extern const char _binary_vgafont_psf_start[]; +extern const char _binary_lat0_12_psf_start[]; +extern const char _binary_lat0_14_psf_start[]; +extern const char _binary_lat0_16_psf_start[]; + +static struct { + const char *fontdata; + const char *name; +} font_list[] = { + { _binary_lat0_14_psf_start, "lat0-14" }, // first one is the default one + { _binary_lat0_12_psf_start, "lat0-12" }, + { _binary_lat0_16_psf_start, "lat0-16" }, + { _binary_vgafont_psf_start, "vgafont" }, +}; + +enum { + FONT_XRES = 8, +}; + +struct psf_header +{ + unsigned char magic[2]; + unsigned char mode; + unsigned char height; +} __attribute__((packed)); + +struct psf_font +{ + struct psf_header header; + char data[]; +}; + +static struct psf_font *std_font; + + +static int check_magic(struct psf_font *f) +{ return f->header.magic[0] == 0x36 && f->header.magic[1] == 0x4; } + +static inline struct psf_font *font_cast(gfxbitmap_font_t font) +{ + struct psf_font *f = (struct psf_font *)font; + if (!f || !check_magic(f)) + return std_font; + return f; +} + +static unsigned char font_yres(struct psf_font *f) +{ return f->header.height; } + +L4_CV unsigned +gfxbitmap_font_width(gfxbitmap_font_t font) +{ + (void)font; + return FONT_XRES; +} + +L4_CV unsigned +gfxbitmap_font_height(gfxbitmap_font_t font) +{ + struct psf_font *f = font_cast(font); + return f ? f->header.height : 0; +} + +static inline +void * +get_font_char(struct psf_font *f, unsigned c) +{ + return &f->data[(FONT_XRES / 8) * font_yres(f) * c]; +} + +L4_CV void * +gfxbitmap_font_data(gfxbitmap_font_t font, unsigned c) +{ + struct psf_font *f = font_cast(font); + if (!f) + return NULL; + + return get_font_char(f, c); +} + +L4_CV void +gfxbitmap_font_text(void *fb, l4re_video_view_info_t *vi, + gfxbitmap_font_t font, const char *text, unsigned len, + unsigned x, unsigned y, + gfxbitmap_color_pix_t fg, gfxbitmap_color_pix_t bg) +{ + unsigned i, j; + struct gfxbitmap_offset offset = {0,0,0}; + struct psf_font *f = font_cast(font); + + if (!f) + return; + + if (len == GFXBITMAP_USE_STRLEN) + len = strlen(text); + + for (i = 0; i < len; i++, text++) + { + /* optimization: collect spaces */ + for (j = 0; (i < len) && (*text == ' '); i++, j++, text++) + ; + + if (j > 0) + { + gfxbitmap_fill(fb, vi, x, y, j * FONT_XRES, font_yres(f), bg); + x += j * FONT_XRES; + i--; + text--; + continue; + } + + gfxbitmap_bmap(fb, vi, x, y, FONT_XRES, font_yres(f), + get_font_char(f, *(unsigned char *)text), fg, bg, + &offset, pSLIM_BMAP_START_MSB); + x += FONT_XRES; + } +} + + +L4_CV void +gfxbitmap_font_text_scale(void *fb, l4re_video_view_info_t *vi, + gfxbitmap_font_t font, const char *text, unsigned len, + unsigned x, unsigned y, + gfxbitmap_color_pix_t fg, gfxbitmap_color_pix_t bg, + int scale_x, int scale_y) +{ + int pix_x, pix_y; + unsigned rect_x = x; + unsigned rect_y = y; + unsigned rect_w = gfxbitmap_font_width(font) * scale_x; + unsigned i; + struct psf_font *f = font_cast(font); + + if (!f) + return; + + pix_x = scale_x; + if (scale_x >= 5) + pix_x = scale_x * 14/15; + pix_y = scale_y; + if (scale_y >= 5) + pix_y = scale_y * 14/15; + + if (len == GFXBITMAP_USE_STRLEN) + len = strlen(text); + + for (i=0; i < len; i++, text++) + { + unsigned lrect_x = rect_x; + unsigned lrect_y = rect_y; + unsigned lrect_w = pix_x; + unsigned lrect_h = pix_y; + const char *bmap = get_font_char(f, *text); + int j; + + for (j=0; j> 1) | (mask << 7); + } + lrect_x -= rect_w; + lrect_y += scale_y; + } + rect_x += rect_w; + } +} + + +L4_CV gfxbitmap_font_t +gfxbitmap_font_get(const char *name) +{ + unsigned i = 0; + for (; i < sizeof(font_list) / sizeof(font_list[0]); ++i) + if (!strcmp(font_list[i].name, name)) + return (gfxbitmap_font_t)font_list[i].fontdata; + return NULL; +} + +/** Init lib */ +L4_CV int +gfxbitmap_font_init(void) +{ + unsigned chars; + + struct psf_font *f; + f = font_cast((gfxbitmap_font_t)font_list[0].fontdata); + + /* check magic number of .psf */ + if (!check_magic(f)) + return 1; // psf magic number failed + + std_font = f; + + /* check file mode */ + switch (f->header.mode) + { + case 0: + case 2: + chars = 256; + break; + case 1: + case 3: + chars = 512; + break; + default: + return 2; // "bad psf font file magic %02x!", f->header.mode + } + + if (0) + printf("Font: Character size is %dx%d, font has %d characters\n", + FONT_XRES, font_yres(f), chars); + + return 0; +} + diff --git a/src/l4/pkg/libgfxbitmap/lib/src/lat0-12.psf b/src/l4/pkg/libgfxbitmap/lib/src/lat0-12.psf new file mode 100644 index 00000000..6a5dcc41 Binary files /dev/null and b/src/l4/pkg/libgfxbitmap/lib/src/lat0-12.psf differ diff --git a/src/l4/pkg/libgfxbitmap/lib/src/lat0-14.psf b/src/l4/pkg/libgfxbitmap/lib/src/lat0-14.psf new file mode 100644 index 00000000..39452f8d Binary files /dev/null and b/src/l4/pkg/libgfxbitmap/lib/src/lat0-14.psf differ diff --git a/src/l4/pkg/libgfxbitmap/lib/src/lat0-16.psf b/src/l4/pkg/libgfxbitmap/lib/src/lat0-16.psf new file mode 100644 index 00000000..323ef384 Binary files /dev/null and b/src/l4/pkg/libgfxbitmap/lib/src/lat0-16.psf differ diff --git a/src/l4/pkg/libgfxbitmap/lib/src/vgafont.psf b/src/l4/pkg/libgfxbitmap/lib/src/vgafont.psf new file mode 100644 index 00000000..3f913c74 Binary files /dev/null and b/src/l4/pkg/libgfxbitmap/lib/src/vgafont.psf differ diff --git a/src/l4/pkg/libgfxbitmap/lib/src/vgafont.txt b/src/l4/pkg/libgfxbitmap/lib/src/vgafont.txt new file mode 100644 index 00000000..f3e3ff4e --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/src/vgafont.txt @@ -0,0 +1 @@ +Taken and generated from QEmu's vgafont.h diff --git a/src/l4/pkg/libgfxbitmap/lib/support/Makefile b/src/l4/pkg/libgfxbitmap/lib/support/Makefile new file mode 100644 index 00000000..78845164 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/support/Makefile @@ -0,0 +1,9 @@ +PKGDIR ?= ../.. +L4DIR ?= $(PKGDIR)/../.. + +TARGET := libterm-support.a +SRC_CC := support.cc +PC_FILENAME := libgfxbitmap-support +REQUIRES_LIBS:= libgfxbitmap + +include $(L4DIR)/mk/lib.mk diff --git a/src/l4/pkg/libgfxbitmap/lib/support/support.cc b/src/l4/pkg/libgfxbitmap/lib/support/support.cc new file mode 100644 index 00000000..22eb65c3 --- /dev/null +++ b/src/l4/pkg/libgfxbitmap/lib/support/support.cc @@ -0,0 +1,45 @@ +/* + * (c) 2009 Adam Lackorzynski + * economic rights: Technische Universität Dresden (Germany) + * This file is part of TUD:OS and distributed under the terms of the + * GNU Lesser General Public License 2.1. + * Please see the COPYING-LGPL-2.1 file for details. + */ + + +#include +#include +#include + + +// array will be converted to gfxbitmap_color_pix_t in init +gfxbitmap_color_t libterm_std_colors[24] = +{ + // dark + 0x00000000, 0x007f0000, 0x00007f00, 0x007f7f00, + 0x0000007f, 0x007f007f, 0x00007f7f, 0x007f7f7f, + // normal + 0x00000000, 0x00cf0000, 0x0000cf00, 0x00cfcf00, + 0x000000cf, 0x00cf00cf, 0x0000cfcf, 0xcfcfcfcf, + // bright + 0x00000000, 0x00ff0000, 0x0000ff00, 0x00ffff00, + 0x000000ff, 0x00ff00ff, 0x0000ffff, 0x00ffffff +}; + + +void +libterm_init_colors(L4Re::Video::View::Info *vi) +{ + unsigned i = 0; + for (; i < (sizeof(libterm_std_colors) / sizeof(libterm_std_colors[0])); ++i) + libterm_std_colors[i] = gfxbitmap_convert_color((l4re_video_view_info_t *)vi, libterm_std_colors[i]); +} + +int +libterm_get_color(int mode, int color) +{ + if (mode >= 3 || color >= 8) + return 0; // black + + return libterm_std_colors[color + 8 * mode]; +}