From b04410f1a98e39af171a6038ad5c65b09548d69b Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 31 Jul 2012 16:50:20 +0200 Subject: [PATCH] text: add bblit text-renderer The bblit text-renderer is the most basic renderer which simply blits or blends the glyphs into the framebuffer memory. It cannot be used with displays that do not provide framebuffer access but only 3D access. However, 3D rendering is currently broken, anyway, so we can ignore it. Signed-off-by: David Herrmann --- src/text.h | 3 + src/text_bblit.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 src/text_bblit.c diff --git a/src/text.h b/src/text.h index 944e727..6bdd5dd 100644 --- a/src/text.h +++ b/src/text.h @@ -169,4 +169,7 @@ void kmscon_font_8x16_unload(void); int kmscon_font_pango_load(void); void kmscon_font_pango_unload(void); +int kmscon_text_bblit_load(void); +void kmscon_text_bblit_unload(void); + #endif /* KMSCON_TEXT_H */ diff --git a/src/text_bblit.c b/src/text_bblit.c new file mode 100644 index 0000000..d982934 --- /dev/null +++ b/src/text_bblit.c @@ -0,0 +1,198 @@ +/* + * kmscon - Bit-Blitting Text Renderer Backend + * + * Copyright (c) 2012 David Herrmann + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * SECTION:text_bblit.c + * @short_description: Bit-Blitting Text Renderer Backend + * @include: text.h + * + * TODO + */ + +#include +#include +#include +#include +#include "font.h" +#include "log.h" +#include "static_misc.h" +#include "text.h" +#include "unicode.h" +#include "uterm.h" + +#define LOG_SUBSYSTEM "text_bblit" + +struct bblit { + unsigned int advance_x; + unsigned int advance_y; + unsigned int base; +}; + +static int bblit_init(struct kmscon_text *txt) +{ + struct bblit *bblit; + + bblit = malloc(sizeof(*bblit)); + if (!bblit) + return -ENOMEM; + memset(bblit, 0, sizeof(*bblit)); + + txt->data = bblit; + return 0; +} + +static void bblit_destroy(struct kmscon_text *txt) +{ + struct bblit *bblit = txt->data; + + free(bblit); +} + +static void bblit_recalculate_size(struct kmscon_text *txt) +{ + unsigned int sw, sh, fw, fh; + + if (!txt->font || !txt->screen) + return; + + fw = txt->font->attr.width; + fh = txt->font->attr.height; + sw = uterm_screen_width(txt->screen); + sh = uterm_screen_height(txt->screen); + + txt->cols = sw / fw; + txt->rows = sh / fh; +} + +static void bblit_new_font(struct kmscon_text *txt) +{ + bblit_recalculate_size(txt); +} + +static void bblit_new_bgcolor(struct kmscon_text *txt) +{ + /* nothing to do here */ +} + +static void bblit_new_screen(struct kmscon_text *txt) +{ + bblit_recalculate_size(txt); +} + +static void bblit_prepare(struct kmscon_text *txt) +{ + int ret; + unsigned int w, h; + struct bblit *bblit = txt->data; + + /* clear screen by drawing background */ + w = uterm_screen_width(txt->screen); + h = uterm_screen_height(txt->screen); + ret = uterm_screen_fill(txt->screen, txt->bg_r, txt->bg_g, txt->bg_b, + 0, 0, w, h); + if (ret) + log_warning("cannot draw screen background"); + + /* precalculate values for glyph positioning */ + bblit->advance_x = txt->font->attr.width; + bblit->advance_y = txt->font->attr.height; + bblit->base = bblit->advance_y - txt->font->baseline; +} + +static void bblit_draw(struct kmscon_text *txt, kmscon_symbol_t ch, + unsigned int posx, unsigned int posy, + const struct font_char_attr *attr) +{ + const struct kmscon_glyph *glyph; + int ret; + struct bblit *bblit = txt->data; + int off, pos; + + ret = kmscon_font_render(txt->font, ch, &glyph); + if (ret) { + /* TODO: document 0 as fallback glyph */ + ret = kmscon_font_render(txt->font, 0, &glyph); + if (ret) + return; + } + + /* position glyph correctly */ + off = bblit->base - glyph->ascent; + pos = posy * bblit->advance_y; + if (pos + off < 0) + pos = 0; + else + pos += off; + + /* draw glyph */ + if (attr->inverse) { + uterm_screen_blend(txt->screen, &glyph->buf, + posx * bblit->advance_x, + pos, + attr->br, attr->bg, attr->bb, + attr->fr, attr->fg, attr->fb); + } else { + uterm_screen_blend(txt->screen, &glyph->buf, + posx * bblit->advance_x, + pos, + attr->fr, attr->fg, attr->fb, + attr->br, attr->bg, attr->bb); + } +} + +static void bblit_render(struct kmscon_text *txt) +{ + /* nothing to do */ +} + +static const struct kmscon_text_ops kmscon_text_bblit_ops = { + .name = "bblit", + .init = bblit_init, + .destroy = bblit_destroy, + .new_font = bblit_new_font, + .new_bgcolor = bblit_new_bgcolor, + .new_screen = bblit_new_screen, + .prepare = bblit_prepare, + .draw = bblit_draw, + .render = bblit_render, +}; + +int kmscon_text_bblit_load(void) +{ + int ret; + + ret = kmscon_text_register(&kmscon_text_bblit_ops); + if (ret) { + log_error("cannot register bblit renderer"); + return ret; + } + + return 0; +} + +void kmscon_text_bblit_unload(void) +{ + kmscon_text_unregister(kmscon_text_bblit_ops.name); +}