138 lines
5.9 KiB
C
138 lines
5.9 KiB
C
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
|
|
/***
|
|
This file is part of systemd.
|
|
|
|
Copyright (C) 2014 David Herrmann <dh.herrmann@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/>.
|
|
***/
|
|
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include "sparse-endian.h"
|
|
#include "util.h"
|
|
|
|
typedef struct unifont_header unifont_header;
|
|
typedef struct unifont_glyph_header unifont_glyph_header;
|
|
|
|
/*
|
|
* Unifont: On-disk data
|
|
* Conventional font-formats have the problem that you have to pre-render each
|
|
* glyph before you can use it. If you just need one glyph, you have to parse
|
|
* the font-file until you found that glyph.
|
|
* GNU-Unifont is a bitmap font with very good Unicode coverage. All glyphs are
|
|
* (n*8)x16 bitmaps. Our on-disk data stores all those glyphs pre-compiled with
|
|
* fixed offsets. Therefore, the font-file can be mmap()ed and all glyphs can
|
|
* be accessed in O(1) (because all glyphs have the same size and thus their
|
|
* offsets can be easily computed). This guarantees, that the kernel only loads
|
|
* the pages that are really accessed. Thus, we have a far lower overhead than
|
|
* traditional font-formats like BDF. Furthermore, the backing file is read-only
|
|
* and can be shared in memory between multiple users.
|
|
*
|
|
* The binary-format starts with a fixed header:
|
|
*
|
|
* | 2bytes | 2bytes | 2bytes | 2bytes |
|
|
*
|
|
* +-----------------------------------+
|
|
* | SIGNATURE | 8 bytes
|
|
* +-----------------+-----------------+
|
|
* | COMPAT FLAGS | INCOMPAT FLAGS | 8 bytes
|
|
* +-----------------+--------+--------+
|
|
* | HEADER SIZE |GH-SIZE |G-STRIDE| 8 bytes
|
|
* +-----------------+--------+--------+
|
|
* | GLYPH BODY SIZE | 8 bytes
|
|
* +-----------------------------------+
|
|
*
|
|
* * The 8 bytes signature must be set to the ASCII string "DVDHRMUF".
|
|
* * The 4 bytes compatible-flags field contains flags for new features that
|
|
* might be added in the future and which are compatible to older parsers.
|
|
* * The 4 bytes incompatible-flags field contains flags for new features that
|
|
* might be added in the future and which are incompatible to old parses.
|
|
* Thus, if you encounter an unknown bit set, you must abort!
|
|
* * The 4 bytes header-size field contains the size of the header in bytes. It
|
|
* must be at least 32 (the size of this fixed header). If new features are
|
|
* added, it might be increased. It can also be used to add padding to the
|
|
* end of the header.
|
|
* * The 2 bytes glyph-header-size field specifies the size of each glyph
|
|
* header in bytes (see below).
|
|
* * The 2 bytes glyph-stride field specifies the stride of each line of glyph
|
|
* data in "bytes per line".
|
|
* * The 8 byte glyph-body-size field defines the size of each glyph body in
|
|
* bytes.
|
|
*
|
|
* After the header, the file can contain padding bytes, depending on the
|
|
* header-size field. Everything beyond the header+padding is treated as a big
|
|
* array of glyphs. Each glyph looks like this:
|
|
*
|
|
* | 1 byte |
|
|
*
|
|
* +-----------------------------------+
|
|
* | WIDTH | 1 byte
|
|
* +-----------------------------------+
|
|
* ~ PADDING ~
|
|
* +-----------------------------------+
|
|
* ~ ~
|
|
* ~ ~
|
|
* ~ DATA ~
|
|
* ~ ~
|
|
* ~ ~
|
|
* +-----------------------------------+
|
|
*
|
|
* * The first byte specifies the width of the glyph. If it is 0, the glyph
|
|
* must be treated as non-existent.
|
|
* All glyphs are "8*n" pixels wide and "16" pixels high. The width-field
|
|
* specifies the width multiplier "n".
|
|
* * After the width field padding might be added. This depends on the global
|
|
* glyph-header-size field. It defines the total size of each glyph-header.
|
|
* After the glyph-header+padding, the data-field starts.
|
|
* * The data-field contains a byte-array of bitmap data. The array is always
|
|
* as big as specified in the global glyph-body-size header field. This might
|
|
* include padding.
|
|
* The array contains all 16 lines of bitmap information for that glyph. The
|
|
* stride is given in the global glyph-stride header field. This can be used
|
|
* to add padding after each line.
|
|
* Each line is encoded as 1 bit per pixel bitmap. That is, each byte encodes
|
|
* data for 8 pixels (left most pixel is encoded in the LSB, right most pixel
|
|
* in the MSB). The width field defines the number of bytes valid per line.
|
|
* For width==1, you need 1 byte to encode the 8 pixels. The stride defines
|
|
* where the encoding of the next line starts.
|
|
* Any data beyond the 16th line is padding and must be ignored.
|
|
*/
|
|
|
|
/* path to binary file */
|
|
#define UNIFONT_PATH "/usr/share/systemd/unifont-glyph-array.bin"
|
|
|
|
/* header-size of version 1 */
|
|
#define UNIFONT_HEADER_SIZE_MIN 32
|
|
|
|
struct unifont_header {
|
|
/* fields available in version 1 */
|
|
uint8_t signature[8];
|
|
le32_t compatible_flags;
|
|
le32_t incompatible_flags;
|
|
le32_t header_size;
|
|
le16_t glyph_header_size;
|
|
le16_t glyph_stride;
|
|
le64_t glyph_body_size;
|
|
} _packed_;
|
|
|
|
struct unifont_glyph_header {
|
|
/* fields available in version 1 */
|
|
uint8_t width;
|
|
} _packed_;
|