Added libgfxbitmap

This commit is contained in:
Martin Kuettler
2023-10-23 15:44:22 +02:00
committed by vreusch
parent ccd7c4a959
commit a10ff4fc79
18 changed files with 1322 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
provides: libgfxbitmap libgfxbitmap-support
requires: l4sys l4re_c libc
maintainer: adam@os.inf.tu-dresden.de

View File

@@ -0,0 +1,4 @@
PKGDIR = .
L4DIR ?= $(PKGDIR)/../..
include $(L4DIR)/mk/subdir.mk

View File

@@ -0,0 +1 @@
INPUT += l4/libgfxbitmap

View File

@@ -0,0 +1,6 @@
PKGDIR = ..
L4DIR ?= $(PKGDIR)/../..
EXTRA_TARGET = support
include $(L4DIR)/mk/include.mk

View File

@@ -0,0 +1,162 @@
/**
* \file
* \brief Bitmap renderer header file.
*/
/*
* (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* 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 <l4/sys/types.h>
#include <l4/re/c/video/view.h>
/**
* \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

View File

@@ -0,0 +1,133 @@
/**
* \file
* \brief Bitmap font renderer header file.
*/
/*
* (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* 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 <l4/sys/compiler.h>
#include <l4/re/c/video/view.h>
#include <l4/libgfxbitmap/bitmap.h>
/**
* \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
/*@}*/

View File

@@ -0,0 +1,27 @@
/* vim:set ft=cpp: */
/**
* \file
* \brief Terminal support functionality
*
* \date 2009
* \author Adam Lackorzynski <adam@os.inf.tu-dresden.de>
*/
/*
* (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 <l4/re/video/view>
void
libterm_init_colors(L4Re::Video::View::Info *fbi);
int
libterm_get_color(int mode, int color);
#endif

View File

@@ -0,0 +1,8 @@
PKGDIR = ..
L4DIR ?= $(PKGDIR)/../..
TARGET := src support
include $(L4DIR)/mk/subdir.mk
support: src

View File

@@ -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

View File

@@ -0,0 +1,667 @@
/**
* \file
* \brief bitmap functions
*
* \date 2001
* \author Christian Helmuth <ch12@os.inf.tu-dresden.de>
* Frank Mehnert <fm3@os.inf.tu-dresden.de>
* Adam Lackorzynski <adam@os.inf.tu-dresden.de> */
/*
* (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 <stdlib.h>
#include <string.h> /* needed for memmove */
#include <l4/sys/cache.h>
#include <l4/libgfxbitmap/bitmap.h>
#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);
}
}

View File

@@ -0,0 +1,245 @@
/**
* \file
* \brief Font functions
*
* \author Christian Helmuth <ch12@os.inf.tu-dresden.de>
* Frank Mehnert <fm3@os.inf.tu-dresden.de>
* Adam Lackorzynski <adam@os.inf.tu-dresden.de> */
/*
* (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 <l4/libgfxbitmap/font.h>
#include <l4/libgfxbitmap/bitmap.h>
#include <l4/sys/l4int.h>
#include <string.h>
#include <stdio.h>
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<font_yres(f); j++)
{
unsigned char mask = 0x80;
int k;
for (k=0; k<FONT_XRES; k++)
{
unsigned color = (*bmap & mask) ? fg : bg;
gfxbitmap_fill(fb, vi, lrect_x, lrect_y, lrect_w, lrect_h, color);
lrect_x += scale_x;
bmap += (mask & 1);
mask = (mask >> 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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
Taken and generated from QEmu's vgafont.h

View File

@@ -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

View File

@@ -0,0 +1,45 @@
/*
* (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* 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 <l4/libgfxbitmap/bitmap.h>
#include <l4/re/video/view>
#include <l4/libgfxbitmap/support>
// 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];
}