[systemd-devel] [RFC 05/12] gfx: add sd-gfx library with unifont section
Shawn Landden
shawn at churchofgit.com
Mon Dec 2 07:26:20 PST 2013
On Wed, Nov 27, 2013 at 10:48 AM, David Herrmann <dh.herrmann at gmail.com> wrote:
> If we want to interact with a user in the initrd, during
> emergency-situations, in single-user mode, or in any other rather limited
> situation, we currently rely on the kernel to do input and graphics access
> for us. More precisely, we rely on the VT layer to do keyboard parsing and
> font rendering. Or in other words: The *kernel* provides our UI!
>
> This is bad for the same reasons we don't put any other UI into the
> kernel. However, there are a few reasons to keep a minimal UI in the
> kernel:
> 1) show panic-screen with kernel oops message
> 2) show log-screen during early boot
> 3) allow kernel-debugging via kdb
> While people using kdb are encouraged to keep VTs, for 1) and 2) there is
> a replacement via fblog/drmlog.
>
> So we run out of reasons to keep a UI in the kernel. However, to allow
> moving the UI handling to userspace, we need a bunch of helpers:
> - keyboard handling: convert keycodes into keysyms and modifiers/..
> - modesetting: program the gfx pipeline and provide a rendering
> infrastructure
> - fonts: to render text, we need some basic fonts
> - hotplugging: device detection and assignment during runtime
> (Note that all these are implemented (often quite rudimentary) in the
> kernel to allow a basic UI.)
>
> This patch introduces sd-gfx, a systemd-internal library dealing with all
> these things. Note that it is designed to be exported some day, but for
> now we keep it internal.
> While the library itself will be kept small and almost self-contained, it
> is designed to be extensible and can be used in rather complex graphics
> applications. For systemd, we plan to add a basic emergency-console, an
> initrd password-query, kernel-log-screen and a fallback login-screen.
> These allow booting without CONFIG_VT and provide a basic system for
> seats without VTs (either CONFIT_VT=n or seats != seat0).
>
> As a first step, we add the required header+build-chain and add the
> font-handling. To avoid heavy font-pipelines in systemd, we only provide
> a statically-sized fallback-font based on GNU-Unifont. It contains glyphs
> for the *whole* Base-Multilingual-Plane of Unicode and thus allows
> internationalized text.
>
> The "make-unifont.py" script is used by the "make update-unifont" custom
> target to regenerate the unifont files. As this can take quite some time,
> we check the result into git so only maintainers need to run this.
>
> The binary file contains all glyphs in a compressed 1-bit-per-pixel format
> for all 8x16 and 16x16 glyphs. It is linked directly into libsystemd-gfx
> via the *.bin makefile target. Binary size is 2.1MB, but thanks to paging,
> the kernel only loads required pages into memory. A ASCII-only screen thus
> only needs 40k VIRT mem.
Do we have quad-glyphs (16x32) for the ASCII part of this for hi-res screens?
(also, if we use NFD we could reuse these for some of unicode[1], but
that is less important)
[1]http://blog.golang.org/normalization
> ---
> Hi
>
> I removed the unifont-data from this patch so this will not apply cleanly.
> However, the ML would reject the huge patch otherwise. If anyone is interested
> in the raw patch, the series is available on:
> http://cgit.freedesktop.org/~dvdhrm/systemd/log/?h=console
>
> Thanks
> David
>
> Makefile.am | 31 +
> configure.ac | 10 +
> make-unifont.py | 138 +
> src/libsystemd-gfx/.gitignore | 1 +
> src/libsystemd-gfx/Makefile | 1 +
> src/libsystemd-gfx/gfx-unifont.c | 273 +
> src/libsystemd-gfx/unifont.bin | Bin 0 -> 2162688 bytes
> src/libsystemd-gfx/unifont.hex | 63488 +++++++++++++++++++++++++++++++++++++
> src/systemd/sd-gfx.h | 65 +
> 9 files changed, 64007 insertions(+)
> create mode 100755 make-unifont.py
> create mode 100644 src/libsystemd-gfx/.gitignore
> create mode 120000 src/libsystemd-gfx/Makefile
> create mode 100644 src/libsystemd-gfx/gfx-unifont.c
> create mode 100644 src/libsystemd-gfx/unifont.bin
> create mode 100644 src/libsystemd-gfx/unifont.hex
> create mode 100644 src/systemd/sd-gfx.h
>
> diff --git a/Makefile.am b/Makefile.am
> index ce27e82..2edb091 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -3853,6 +3853,37 @@ EXTRA_DIST += \
> endif
>
> # ------------------------------------------------------------------------------
> +if HAVE_GFX
> +noinst_LTLIBRARIES += \
> + libsystemd-gfx.la
> +
> +libsystemd_gfx_la_SOURCES = \
> + src/libsystemd-gfx/sd-gfx.h \
> + src/libsystemd-gfx/gfx-unifont.c
> +
> +libsystemd_gfx_la_CFLAGS = \
> + $(AM_CFLAGS)
> +
> +libsystemd_gfx_la_LIBADD = \
> + libsystemd-shared.la \
> + src/libsystemd-gfx/unifont.bin.lo
> +
> +src/libsystemd-gfx/unifont.bin: make-unifont.py src/libsystemd-gfx/unifont.hex
> + $(AM_V_GEN)cat $(top_srcdir)/src/libsystemd-gfx/unifont.hex | $(PYTHON) $< >$@
> +
> +src/libsystemd-gfx/unifont.cmp: make-unifont.py src/libsystemd-gfx/unifont.bin
> + $(AM_V_GEN)cat $(top_srcdir)/src/libsystemd-gfx/unifont.bin | $(PYTHON) $< verify >$@
> +
> +update-unifont: src/libsystemd-gfx/unifont.bin src/libsystemd-gfx/unifont.cmp
> + @RET=`diff -u src/libsystemd-gfx/unifont.hex src/libsystemd-gfx/unifont.cmp | wc -l` ; \
> + if test "x$$?" != "x0" -o "x$$RET" != "x0" ; then \
> + echo "Generated Unifont-file differs from original; generator probably broken" ; \
> + exit 1 ; \
> + fi
> + @echo "unifont.bin has been regenerated"
> +endif
> +
> +# ------------------------------------------------------------------------------
> if ENABLE_NETWORKD
> rootlibexec_PROGRAMS += \
> systemd-networkd
> diff --git a/configure.ac b/configure.ac
> index 3fd05da..354673a 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -291,6 +291,15 @@ fi
> AM_CONDITIONAL(HAVE_KMOD, [test "$have_kmod" = "yes"])
>
> # ------------------------------------------------------------------------------
> +have_gfx=no
> +AC_ARG_ENABLE(gfx, AS_HELP_STRING([--disable-gfx], [disable sd-gfx graphics and input support]))
> +if test "x$enable_gfx" != "xno"; then
> + AC_DEFINE(HAVE_GFX, 1, [Define if sd-gfx is built])
> + have_gfx=yes
> +fi
> +AM_CONDITIONAL(HAVE_GFX, [test "$have_gfx" = "yes"])
> +
> +# ------------------------------------------------------------------------------
> have_blkid=no
> AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid], [disable blkid support]))
> if test "x$enable_blkid" != "xno"; then
> @@ -1079,6 +1088,7 @@ AC_MSG_RESULT([
> polkit: ${have_polkit}
> efi: ${have_efi}
> kmod: ${have_kmod}
> + sd-gfx: ${have_gfx}
> blkid: ${have_blkid}
> nss-myhostname: ${have_myhostname}
> gudev: ${enable_gudev}
> diff --git a/make-unifont.py b/make-unifont.py
> new file mode 100755
> index 0000000..375c8a4
> --- /dev/null
> +++ b/make-unifont.py
> @@ -0,0 +1,138 @@
> +# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
> +#
> +# This file is part of systemd.
> +#
> +# Copyright 2013 David Herrmann <dh.herrmann at gmail.com>
> +#
> +# systemd is free software; you can redistribute it and/or modify it
> +# under the terms of the GNU Lesser General Public License as published by
> +# the Free Software Foundation; either version 2.1 of the License, or
> +# (at your option) any later version.
> +#
> +# systemd is distributed in the hope that it will be useful, but
> +# WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public License
> +# along with systemd; If not, see <http://www.gnu.org/licenses/>.
> +
> +#
> +# Parse a unifont.hex file and produce a compressed binary-format we use in
> +# our gfx applications. Can also do the reverse to verify correctness.
> +#
> +
> +from __future__ import print_function
> +import re
> +import sys
> +import fileinput
> +import struct
> +
> +#
> +# Write "bits" array as binary output.
> +#
> +
> +def write_bin_entry(entry):
> + l = len(entry)
> + if l != 32 and l != 64:
> + entry = "0" * 64
> + l = 0
> + elif l < 64:
> + entry += "0" * (64 - l)
> +
> + sys.stdout.buffer.write(struct.pack('B', int(l / 32)))
> +
> + for i in range(0, 64, 2):
> + c = int(entry[i:i+2], 16)
> + sys.stdout.buffer.write(struct.pack('B', c))
> +
> +def write_bin(bits):
> + for idx in range(len(bits)):
> + write_bin_entry(bits[idx])
> +
> +#
> +# Parse hex file into "bits" array
> +#
> +
> +def parse_hex_line(bits, line):
> + m = re.match(r"^([0-9A-Fa-f]+):([0-9A-Fa-f]+)$", line)
> + if m == None:
> + return
> +
> + idx = int(m.group(1), 16)
> + val = m.group(2)
> +
> + # insert skipped lines
> + for i in range(len(bits), idx):
> + bits.append("")
> +
> + bits.insert(idx, val)
> +
> +def parse_hex():
> + bits = []
> +
> + for line in sys.stdin:
> + if not line:
> + continue
> + if line.startswith("#"):
> + continue
> +
> + parse_hex_line(bits, line)
> +
> + return bits
> +
> +#
> +# Write "bits" array as text-file line-by-line to stdout.
> +#
> +
> +def write_hex_line(idx, entry):
> + if entry:
> + print("%04X:%s" % (idx, entry))
> +
> +def write_hex(bits):
> + for idx, entry in enumerate(bits):
> + if not entry:
> + continue
> +
> + write_hex_line(idx, entry)
> +
> +#
> +# Parse a binary file into "bits" so we can verify the correctness of a given
> +# binary file.
> +#
> +
> +def parse_bin_entry(bits, chunk):
> + entry = ""
> + l = struct.unpack('B', chunk[0:1])[0]
> + for c in chunk[1:l*16+1]:
> + entry += format(c, "02X")
> +
> + bits.append(entry)
> +
> +def parse_bin():
> + bits = []
> +
> + while True:
> + chunk = sys.stdin.buffer.read(33)
> + if chunk:
> + parse_bin_entry(bits, chunk)
> + else:
> + break
> +
> + return bits
> +
> +#
> +# In normal mode we simply read line by line from standard-input (or first
> +# argument) and write the binary-file to standard-output.
> +#
> +# In verify-mode, we read the binary-file from standard-input and write the
> +# text-file line-by-line to standard-output.
> +#
> +
> +if __name__ == "__main__":
> + if len(sys.argv) > 1 and sys.argv[1] == "verify":
> + bits = parse_bin()
> + write_hex(bits)
> + else:
> + bits = parse_hex()
> + write_bin(bits)
> diff --git a/src/libsystemd-gfx/.gitignore b/src/libsystemd-gfx/.gitignore
> new file mode 100644
> index 0000000..a792d8f
> --- /dev/null
> +++ b/src/libsystemd-gfx/.gitignore
> @@ -0,0 +1 @@
> +/unifont.cmp
> diff --git a/src/libsystemd-gfx/Makefile b/src/libsystemd-gfx/Makefile
> new file mode 120000
> index 0000000..d0b0e8e
> --- /dev/null
> +++ b/src/libsystemd-gfx/Makefile
> @@ -0,0 +1 @@
> +../Makefile
> \ No newline at end of file
> diff --git a/src/libsystemd-gfx/gfx-unifont.c b/src/libsystemd-gfx/gfx-unifont.c
> new file mode 100644
> index 0000000..c2fc879
> --- /dev/null
> +++ b/src/libsystemd-gfx/gfx-unifont.c
> @@ -0,0 +1,273 @@
> +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
> +
> +/***
> + This file is part of systemd.
> +
> + Copyright 2013 David Herrmann <dh.herrmann at gmail.com>
> +
> + systemd is free software; you can redistribute it and/or modify it
> + under the terms of the GNU Lesser General Public License as published by
> + the Free Software Foundation; either version 2.1 of the License, or
> + (at your option) any later version.
> +
> + systemd is distributed in the hope that it will be useful, but
> + WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public License
> + along with systemd; If not, see <http://www.gnu.org/licenses/>.
> +***/
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <inttypes.h>
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include "def.h"
> +#include "hashmap.h"
> +#include "log.h"
> +#include "macro.h"
> +#include "sd-gfx.h"
> +#include "util.h"
> +
> +/* Glyphs are linked as binary data. The data layout is a size-byte followed by
> + * 32 data bytes. The data bytes are padded with 0 if the size is smaller than
> + * 32. The size-byte specifies the size of a single line. Each glyph always
> + * consists of 16 lines.
> + * Currently, size==1 is used for single-width glyphs and size==2 for
> + * double-width glyphs. */
> +
> +struct unifont_data {
> + uint8_t cells;
> + uint8_t data[32];
> +} _packed_;
> +
> +extern const struct unifont_data _binary_src_libsystemd_gfx_unifont_bin_start[];
> +extern const struct unifont_data _binary_src_libsystemd_gfx_unifont_bin_end[];
> +static const unsigned int unifont_width = 8;
> +static const unsigned int unifont_stride = 1;
> +static const unsigned int unifont_max_cells = 2;
> +static const unsigned int unifont_height = 16;
> +
> +static const struct unifont_data unifont_fallback = {
> + .cells = 1,
> + .data = "\x00\x00\x00\x7E\x66\x5A\x5A\x7A\x76\x76\x7E\x76\x76\x7E\x00\x00",
> +};
> +
> +static const struct unifont_data *unifont_get(uint32_t ucs4) {
> + const struct unifont_data *begin, *end, *g;
> +
> + begin = _binary_src_libsystemd_gfx_unifont_bin_start;
> + end = _binary_src_libsystemd_gfx_unifont_bin_end;
> +
> + g = &begin[ucs4];
> + if (g >= end)
> + return &unifont_fallback;
> + if (g->cells == 0 || g->cells > unifont_max_cells)
> + return &unifont_fallback;
> +
> + return g;
> +}
> +
> +/*
> + * Fonts
> + * We provide a built-in static font. This can be used to render text in any
> + * situation without depending on huge text-pipelines like pango. The font is
> + * based on "GNU Unifont" which provides fixed-size glyphs for the whole
> + * Unicode Basic Multilingual Plane.
> + * This can be used in initrds, emergency-consoles and other situations where a
> + * full text-pipeline would be overkill.
> + *
> + * Note that we provide some enhanced features to properly support all systems.
> + * This currently includes:
> + * - scaling: You can specify a "ppi" value to scale the static fonts. This
> + * can only be done with integer-scaling and should only be used
> + * as reading-aid or for high-DPI screens.
> + * - combining: Glyph-combining (eg., for unicode combining characters) is
> + * implemented in the renderer to correctly draw combined
> + * characters for non-latin scripts. Character-combining is left
> + * to the caller, we only allow drawing a set of characters as a
> + * single glyph.
> + * - caching: To support fast lookups we cache modified glyphs.
> + */
> +
> +typedef struct gfx_glyph gfx_glyph;
> +
> +struct gfx_glyph {
> + sd_gfx_buffer buf;
> +};
> +
> +struct sd_gfx_font {
> + unsigned int ppi;
> + unsigned int width;
> + unsigned int height;
> + Hashmap *glyphs;
> +
> + gfx_glyph fallback;
> +};
> +
> +static void gfx_glyph_blend(gfx_glyph *g, unsigned int ppi, const struct unifont_data *u) {
> + unsigned int i, j;
> + const uint8_t *src;
> + uint8_t *dst;
> +
> + /*
> + * TODO: scale glyph according to @ppi
> + */
> +
> + src = u->data;
> + dst = g->buf.data;
> +
> + for (i = 0; i < unifont_height; ++i) {
> + for (j = 0; j < u->cells; ++j)
> + dst[j] |= src[j];
> +
> + src += u->cells * unifont_stride;
> + dst += g->buf.stride;
> + }
> +}
> +
> +static int gfx_glyph_render(gfx_glyph *g, unsigned int ppi, const struct unifont_data *u) {
> + g->buf.width = u->cells * unifont_width;
> + g->buf.height = unifont_height;
> + g->buf.stride = u->cells * unifont_stride;
> + g->buf.format = SD_GFX_BUFFER_FORMAT_A1;
> +
> + g->buf.data = calloc(unifont_height, unifont_max_cells * unifont_stride);
> + if (!g->buf.data)
> + return -ENOMEM;
> +
> + gfx_glyph_blend(g, ppi, u);
> + return 0;
> +}
> +
> +int sd_gfx_font_new(sd_gfx_font **out, unsigned int ppi) {
> + sd_gfx_font *font;
> + int r;
> +
> + ppi = CLAMP(ppi, 10U, 1000U);
> +
> + font = calloc(1, sizeof(*font));
> + if (!font)
> + return log_oom();
> +
> + font->ppi = ppi;
> + font->width = unifont_width;
> + font->height = unifont_height;
> +
> + font->glyphs = hashmap_new(trivial_hash_func, trivial_compare_func);
> + if (!font->glyphs) {
> + free(font);
> + return log_oom();
> + }
> +
> + r = gfx_glyph_render(&font->fallback, font->ppi, &unifont_fallback);
> + if (r < 0) {
> + hashmap_free(font->glyphs);
> + free(font);
> + return log_oom();
> + }
> +
> + *out = font;
> + return 0;
> +}
> +
> +static void gfx_glyph_free(gfx_glyph *g) {
> + free(g->buf.data);
> + free(g);
> +}
> +
> +void sd_gfx_font_free(sd_gfx_font *font) {
> + gfx_glyph *g;
> +
> + if (!font)
> + return;
> +
> + while ((g = hashmap_steal_first(font->glyphs)))
> + gfx_glyph_free(g);
> +
> + hashmap_free(font->glyphs);
> + free(font);
> +}
> +
> +unsigned int sd_gfx_font_get_ppi(sd_gfx_font *font) {
> + return font->ppi;
> +}
> +
> +unsigned int sd_gfx_font_get_width(sd_gfx_font *font) {
> + return font->width;
> +}
> +
> +unsigned int sd_gfx_font_get_height(sd_gfx_font *font) {
> + return font->height;
> +}
> +
> +/*
> + * Render a glyph
> + * This first tries to look up the glyph in the cache. If found, it is returned,
> + * otherwise the glyph is rendered and put into the cache.
> + *
> + * This function never fails. If the glyph cannot be rendered, a fallback glyph
> + * is returned. Note that this function can render multiple glyphs into a single
> + * buffer. You simply have to pass multiple codepoints via @ucs4 / @len.
> + * However, this should only be used for combining-characters.
> + *
> + * Whenever you render a glyph, this functions needs a unique ID to identify it.
> + * You have to pass it via @id. If you render only a single codepoint, simply
> + * pass the codepoint as @id (or pass 0 in which case the first codepoint is
> + * automatically taken as id). But if you render combined codepoints, you need
> + * to allocate a unique ID for them. See libtsm for an example how to do that.
> + *
> + * The lifetime of the returned buffer is bound to @font. You don't have to free
> + * it yourself.
> + */
> +void sd_gfx_font_render(sd_gfx_font *font, uint32_t id, const uint32_t *ucs4, size_t len, sd_gfx_buffer **out) {
> + const struct unifont_data *u;
> + gfx_glyph *g;
> +
> + if (!len)
> + goto error;
> +
> + if (!id)
> + id = *ucs4;
> +
> + g = hashmap_get(font->glyphs, INT_TO_PTR(id));
> + if (g)
> + goto out;
> +
> + g = calloc(1, sizeof(*g));
> + if (!g) {
> + log_oom();
> + goto error;
> + }
> +
> + u = unifont_get(*ucs4);
> + if (gfx_glyph_render(g, font->ppi, u) < 0) {
> + log_oom();
> + free(g);
> + goto error;
> + }
> +
> + while (--len) {
> + u = unifont_get(*++ucs4);
> + gfx_glyph_blend(g, font->ppi, u);
> + }
> +
> + if (hashmap_put(font->glyphs, INT_TO_PTR(id), g) < 0) {
> + log_oom();
> + free(g->buf.data);
> + free(g);
> + goto error;
> + }
> +
> + goto out;
> +
> +error:
> + g = &font->fallback;
> +out:
> + *out = &g->buf;
> +}
> diff --git a/src/libsystemd-gfx/unifont.bin b/src/libsystemd-gfx/unifont.bin
> new file mode 100644
> index 0000000000000000000000000000000000000000..0b32d80222dd465d0612188915ef67355dc73e4d
> GIT binary patch
> literal 2162688
> z9F*YJIJ$6q>;c^VB)T=i&<gm^zxN+SppMS|-OpAY!~fZzt8D^U-P?cj(n~*i<Be_n
>
> [... skipped for ML ...]
>
> h<$hpdYOEeTz{h7Yzz4==k?}x2v&LpIyNUqW`UBL12zCGf
>
> literal 0
> HcmV?d00001
>
> diff --git a/src/libsystemd-gfx/unifont.hex b/src/libsystemd-gfx/unifont.hex
> new file mode 100644
> index 0000000..90672a8
> --- /dev/null
> +++ b/src/libsystemd-gfx/unifont.hex
> @@ -0,0 +1,63488 @@
> +0000:AAAA00018000000180004A51EA505A51C99E0001800000018000000180005555
> +0001:AAAA00018000000180003993C252325F8A527193800000018000000180005555
>
> [... skipped for ML ...]
>
> +FFFE:FFFFFFFFE187EFBFE38FEFBFEFBFFFFFFFFFE187EFBFE38FEFBFEF87FFFFFFFF
> +FFFF:FFFFFFFFE187EFBFE38FEFBFEFBFFFFFFFFFE187EFBFE38FEFBFEFBFFFFFFFFF
> diff --git a/src/systemd/sd-gfx.h b/src/systemd/sd-gfx.h
> new file mode 100644
> index 0000000..c46fbd4
> --- /dev/null
> +++ b/src/systemd/sd-gfx.h
> @@ -0,0 +1,65 @@
> +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
> +
> +#ifndef foosdgfxhfoo
> +#define foosdgfxhfoo
> +
> +/***
> + This file is part of systemd.
> +
> + Copyright 2013 David Herrmann <dh.herrmann at gmail.com>
> +
> + systemd is free software; you can redistribute it and/or modify it
> + under the terms of the GNU Lesser General Public License as published by
> + the Free Software Foundation; either version 2.1 of the License, or
> + (at your option) any later version.
> +
> + systemd is distributed in the hope that it will be useful, but
> + WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public License
> + along with systemd; If not, see <http://www.gnu.org/licenses/>.
> +***/
> +
> +#include <errno.h>
> +#include <inttypes.h>
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include <systemd/_sd-common.h>
> +
> +_SD_BEGIN_DECLARATIONS;
> +
> +typedef struct sd_gfx_buffer sd_gfx_buffer;
> +typedef struct sd_gfx_font sd_gfx_font;
> +
> +/* memory buffer */
> +
> +enum {
> + SD_GFX_BUFFER_FORMAT_A1,
> + SD_GFX_BUFFER_FORMAT_A8,
> + SD_GFX_BUFFER_FORMAT_XRGB8888,
> +};
> +
> +struct sd_gfx_buffer {
> + unsigned int width;
> + unsigned int height;
> + int stride;
> + unsigned int format;
> + void *data;
> +};
> +
> +/* unifont */
> +
> +int sd_gfx_font_new(sd_gfx_font **out, unsigned int ppi);
> +void sd_gfx_font_free(sd_gfx_font *font);
> +
> +unsigned int sd_gfx_font_get_ppi(sd_gfx_font *font);
> +unsigned int sd_gfx_font_get_width(sd_gfx_font *font);
> +unsigned int sd_gfx_font_get_height(sd_gfx_font *font);
> +
> +void sd_gfx_font_render(sd_gfx_font *font, uint32_t id, const uint32_t *ucs4, size_t len, sd_gfx_buffer **out);
> +
> +_SD_END_DECLARATIONS;
> +
> +#endif
> --
> 1.8.4.2
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
More information about the systemd-devel
mailing list