From c203b3a83d1cb2c8936d8b2e310b47ef207a84ac Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 1 Jan 2012 18:27:09 +0100 Subject: [PATCH] font: move font handling into new subsystem We use a new font factory which is used to create a new font. It will later also be used to cache fonts and select proper system fonts. Signed-off-by: David Herrmann --- Makefile.am | 2 +- src/console.c | 14 +++-- src/console.h | 16 +----- src/font.h | 59 ++++++++++++++++++++ src/{console_char.c => font_pango.c} | 82 ++++++++++++++++++++-------- src/terminal.c | 5 +- src/terminal.h | 3 +- tests/test_console.c | 9 ++- tests/test_terminal.c | 8 ++- 9 files changed, 150 insertions(+), 48 deletions(-) create mode 100644 src/font.h rename src/{console_char.c => font_pango.c} (89%) diff --git a/Makefile.am b/Makefile.am index b061a9c..37d6f65 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,9 +22,9 @@ endif libkmscon_core_la_SOURCES = \ src/console.c src/console.h \ src/output.c src/output.h \ - src/console_char.c \ src/console_cell.c \ src/unicode.c src/unicode.h \ + src/font_pango.c src/font.h \ src/log.c src/log.h \ src/eloop.c src/eloop.h \ src/vt.c src/vt.h \ diff --git a/src/console.c b/src/console.c index f3eb4f2..d0ab596 100644 --- a/src/console.c +++ b/src/console.c @@ -47,12 +47,13 @@ #include #include "console.h" +#include "font.h" #include "log.h" #include "unicode.h" struct kmscon_console { size_t ref; - struct kmscon_symbol_table *st; + struct kmscon_font_factory *ff; /* GL texture and font */ GLuint tex; @@ -149,7 +150,7 @@ err_free: } int kmscon_console_new(struct kmscon_console **out, - struct kmscon_symbol_table *st) + struct kmscon_font_factory *ff) { struct kmscon_console *con; int ret; @@ -163,7 +164,7 @@ int kmscon_console_new(struct kmscon_console **out, memset(con, 0, sizeof(*con)); con->ref = 1; - con->st = st; + con->ff = ff; log_debug("console: new console\n"); ret = kmscon_buffer_new(&con->cells, 0, 0); @@ -173,7 +174,7 @@ int kmscon_console_new(struct kmscon_console **out, con->cells_x = kmscon_buffer_get_width(con->cells); con->cells_y = kmscon_buffer_get_height(con->cells); - kmscon_symbol_table_ref(con->st); + kmscon_font_factory_ref(con->ff); *out = con; return 0; @@ -206,7 +207,7 @@ void kmscon_console_unref(struct kmscon_console *con) kmscon_console_free_res(con); kmscon_font_unref(con->font); kmscon_buffer_unref(con->cells); - kmscon_symbol_table_unref(con->st); + kmscon_font_factory_unref(con->ff); free(con); log_debug("console: destroing console\n"); } @@ -279,7 +280,8 @@ int kmscon_console_resize(struct kmscon_console *con, unsigned int x, if (con->cursor_y > con->cells_y) con->cursor_y = con->cells_y; - ret = kmscon_font_new(&font, height / con->cells_y, con->st); + ret = kmscon_font_factory_load(con->ff, &font, 0, + height / con->cells_y); if (ret) { log_err("console: cannot create new font: %d\n", ret); return ret; diff --git a/src/console.h b/src/console.h index 213b0db..b91c625 100644 --- a/src/console.h +++ b/src/console.h @@ -37,24 +37,12 @@ #include #include +#include "font.h" #include "unicode.h" -struct kmscon_font; struct kmscon_buffer; struct kmscon_console; -/* font objects with cached glyphs */ - -int kmscon_font_new(struct kmscon_font **out, unsigned int height, - struct kmscon_symbol_table *st); -void kmscon_font_ref(struct kmscon_font *font); -void kmscon_font_unref(struct kmscon_font *font); - -unsigned int kmscon_font_get_height(struct kmscon_font *font); -unsigned int kmscon_font_get_width(struct kmscon_font *font); -int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch, - void *dcr, uint32_t x, uint32_t y); - /* console buffer with cell objects */ int kmscon_buffer_new(struct kmscon_buffer **out, unsigned int x, @@ -78,7 +66,7 @@ void kmscon_buffer_rotate(struct kmscon_buffer *buf); /* console objects */ int kmscon_console_new(struct kmscon_console **out, - struct kmscon_symbol_table *st); + struct kmscon_font_factory *ff); void kmscon_console_ref(struct kmscon_console *con); void kmscon_console_unref(struct kmscon_console *con); diff --git a/src/font.h b/src/font.h new file mode 100644 index 0000000..1486922 --- /dev/null +++ b/src/font.h @@ -0,0 +1,59 @@ +/* + * kmscon - Font Management + * + * Copyright (c) 2011 David Herrmann + * Copyright (c) 2011 University of Tuebingen + * + * 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. + */ + +/* + * Font Management + * A font factory helps loading and initializing fonts. The font object is used + * to draw glyphs onto the screen. + * Efficient caching is used to allow fast drawing operations. + */ + +#ifndef KMSCON_FONT_H +#define KMSCON_FONT_H + +#include +#include "unicode.h" + +struct kmscon_font_factory; +struct kmscon_font; + +int kmscon_font_factory_new(struct kmscon_font_factory **out, + struct kmscon_symbol_table *st); +void kmscon_font_factory_ref(struct kmscon_font_factory *ff); +void kmscon_font_factory_unref(struct kmscon_font_factory *ff); + +int kmscon_font_factory_load(struct kmscon_font_factory *ff, + struct kmscon_font **out, unsigned int width, unsigned int height); + +void kmscon_font_ref(struct kmscon_font *font); +void kmscon_font_unref(struct kmscon_font *font); + +unsigned int kmscon_font_get_height(struct kmscon_font *font); +unsigned int kmscon_font_get_width(struct kmscon_font *font); +int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch, + void *dcr, uint32_t x, uint32_t y); + +#endif /* KMSCON_FONT_H */ diff --git a/src/console_char.c b/src/font_pango.c similarity index 89% rename from src/console_char.c rename to src/font_pango.c index 0b3ecd3..aec3dfe 100644 --- a/src/console_char.c +++ b/src/font_pango.c @@ -1,5 +1,5 @@ /* - * kmscon - Console Characters + * kmscon - Font Management - Pango backend * * Copyright (c) 2011 David Herrmann * Copyright (c) 2011 University of Tuebingen @@ -25,20 +25,10 @@ */ /* - * Console Characters - * A console always has a fixed width and height measured in number of - * characters. This interfaces describes a single character. - * - * To be Unicode compatible, the most straightforward way would be using a UCS - * number for each character and printing them. However, Unicode allows - * combining marks, that is, a single printable character is constructed of - * multiple characters. We support this by allowing to append characters to an - * existing character. This should only be used with combining chars, though. - * Otherwise you end up with multiple printable characters in a cell and the - * output may get corrupted. - * - * We store each character (sequence) as UTF8 string because the pango library - * accepts only UTF8. Hence, we avoid conversion to UCS or wide-characters. + * Pango Font Management + * This is the font backend using the pango library in conjunction with cairo as + * output. See glyph type for detailed information on the caching algorithms + * used. */ #include @@ -49,7 +39,7 @@ #include #include #include -#include "console.h" +#include "font.h" #include "log.h" #include "unicode.h" @@ -78,6 +68,11 @@ struct kmscon_glyph { } src; }; +struct kmscon_font_factory { + unsigned long ref; + struct kmscon_symbol_table *st; +}; + struct kmscon_font { size_t ref; struct kmscon_symbol_table *st; @@ -88,8 +83,8 @@ struct kmscon_font { PangoContext *ctx; }; -static int kmscon_font_lookup(struct kmscon_font *font, kmscon_symbol_t key, - struct kmscon_glyph **out); +static int kmscon_font_lookup(struct kmscon_font *font, + kmscon_symbol_t key, struct kmscon_glyph **out); /* * Glyphs @@ -232,6 +227,48 @@ static int kmscon_glyph_set(struct kmscon_glyph *glyph, return 0; } +int kmscon_font_factory_new(struct kmscon_font_factory **out, + struct kmscon_symbol_table *st) +{ + struct kmscon_font_factory *ff; + + if (!out) + return -EINVAL; + + ff = malloc(sizeof(*ff)); + if (!ff) + return -ENOMEM; + + memset(ff, 0, sizeof(*ff)); + ff->ref = 1; + ff->st = st; + + kmscon_symbol_table_ref(ff->st); + *out = ff; + + return 0; +} + +void kmscon_font_factory_ref(struct kmscon_font_factory *ff) +{ + if (!ff) + return; + + ++ff->ref; +} + +void kmscon_font_factory_unref(struct kmscon_font_factory *ff) +{ + if (!ff || !ff->ref) + return; + + if (--ff->ref) + return; + + kmscon_symbol_table_unref(ff->st); + free(ff); +} + /* * Measure font width * We simply draw all ASCII characters and use the average width as default @@ -279,8 +316,9 @@ static int measure_width(struct kmscon_font *font) * \height is the height in pixel that we have for each character. * Returns 0 on success and stores the new font in \out. */ -int kmscon_font_new(struct kmscon_font **out, unsigned int height, - struct kmscon_symbol_table *st) + +int kmscon_font_factory_load(struct kmscon_font_factory *ff, + struct kmscon_font **out, unsigned int width, unsigned int height) { struct kmscon_font *font; int ret; @@ -289,7 +327,7 @@ int kmscon_font_new(struct kmscon_font **out, unsigned int height, PangoLanguage *lang; cairo_font_options_t *opt; - if (!out || !height) + if (!ff || !out || !height) return -EINVAL; log_debug("font: new font (height %u)\n", height); @@ -299,7 +337,7 @@ int kmscon_font_new(struct kmscon_font **out, unsigned int height, return -ENOMEM; font->ref = 1; font->height = height; - font->st = st; + font->st = ff->st; map = pango_cairo_font_map_get_default(); if (!map) { diff --git a/src/terminal.c b/src/terminal.c index ae20d9f..ec61bfd 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -38,6 +38,7 @@ #include "console.h" #include "eloop.h" +#include "font.h" #include "log.h" #include "terminal.h" #include "unicode.h" @@ -117,7 +118,7 @@ static void print_help(struct kmscon_terminal *term) } int kmscon_terminal_new(struct kmscon_terminal **out, - struct kmscon_symbol_table *st) + struct kmscon_font_factory *ff) { struct kmscon_terminal *term; int ret; @@ -138,7 +139,7 @@ int kmscon_terminal_new(struct kmscon_terminal **out, if (ret) goto err_free; - ret = kmscon_console_new(&term->console, st); + ret = kmscon_console_new(&term->console, ff); if (ret) goto err_idle; diff --git a/src/terminal.h b/src/terminal.h index a53da3f..0168b5f 100644 --- a/src/terminal.h +++ b/src/terminal.h @@ -35,13 +35,14 @@ #include #include "console.h" +#include "font.h" #include "output.h" #include "unicode.h" struct kmscon_terminal; int kmscon_terminal_new(struct kmscon_terminal **out, - struct kmscon_symbol_table *st); + struct kmscon_font_factory *ff); void kmscon_terminal_ref(struct kmscon_terminal *term); void kmscon_terminal_unref(struct kmscon_terminal *term); diff --git a/tests/test_console.c b/tests/test_console.c index b8a1c31..810e5c7 100644 --- a/tests/test_console.c +++ b/tests/test_console.c @@ -55,6 +55,7 @@ #include #include "console.h" #include "eloop.h" +#include "font.h" #include "log.h" #include "output.h" #include "unicode.h" @@ -68,6 +69,7 @@ struct console { struct kmscon_signal *sig_int; struct kmscon_fd *stdin_fd; struct kmscon_symbol_table *st; + struct kmscon_font_factory *ff; struct kmscon_compositor *comp; struct kmscon_vt *vt; struct kmscon_console *con; @@ -239,6 +241,7 @@ static void destroy_eloop(struct console *con) kmscon_console_unref(con->con); kmscon_compositor_unref(con->comp); kmscon_vt_unref(con->vt); + kmscon_font_factory_unref(con->ff); kmscon_symbol_table_unref(con->st); kmscon_eloop_rm_fd(con->stdin_fd); kmscon_eloop_rm_signal(con->sig_int); @@ -273,6 +276,10 @@ static int setup_eloop(struct console *con) if (ret) goto err_loop; + ret = kmscon_font_factory_new(&con->ff, con->st); + if (ret) + goto err_loop; + ret = kmscon_compositor_new(&con->comp); if (ret) goto err_loop; @@ -289,7 +296,7 @@ static int setup_eloop(struct console *con) if (ret) goto err_loop; - ret = kmscon_console_new(&con->con, con->st); + ret = kmscon_console_new(&con->con, con->ff); if (ret) goto err_loop; diff --git a/tests/test_terminal.c b/tests/test_terminal.c index c4e8859..48d30ba 100644 --- a/tests/test_terminal.c +++ b/tests/test_terminal.c @@ -49,6 +49,7 @@ struct app { struct kmscon_signal *sig_term; struct kmscon_signal *sig_int; struct kmscon_symbol_table *st; + struct kmscon_font_factory *ff; struct kmscon_compositor *comp; struct kmscon_input *input; struct kmscon_vt *vt; @@ -128,6 +129,7 @@ static void destroy_app(struct app *app) kmscon_vt_unref(app->vt); kmscon_input_unref(app->input); kmscon_compositor_unref(app->comp); + kmscon_font_factory_unref(app->ff); kmscon_symbol_table_unref(app->st); kmscon_eloop_rm_signal(app->sig_int); kmscon_eloop_rm_signal(app->sig_term); @@ -156,6 +158,10 @@ static int setup_app(struct app *app) if (ret) goto err_loop; + ret = kmscon_font_factory_new(&app->ff, app->st); + if (ret) + goto err_loop; + ret = kmscon_compositor_new(&app->comp); if (ret) goto err_loop; @@ -176,7 +182,7 @@ static int setup_app(struct app *app) if (ret) goto err_loop; - ret = kmscon_terminal_new(&app->term, app->st); + ret = kmscon_terminal_new(&app->term, app->ff); if (ret) goto err_loop;