/*-*- 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_;