1 /* 2 psftools: Manipulate console fonts in the .PSF (v2) format 3 Copyright (C) 2002 John Elliott 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20 /* This file prototypes functions to load and save fonts in the PSF format 21 * (versions 1 and 2) */ 22 23 #ifndef PSFLIB_H_INCLUDED 24 25 #define PSFLIB_H_INCLUDED 26 27 #define PSF_MAGIC 0x864ab572L /* PSF file magic number */ 28 #define PSF_MAGIC0 0x72 29 #define PSF_MAGIC1 0xb5 30 #define PSF_MAGIC2 0x4a 31 #define PSF_MAGIC3 0x86 32 33 34 #ifndef PSF1_MAGIC 35 #define PSF1_MAGIC 0x0436 /* PSF file magic number */ 36 37 #define PSF_E_OK ( 0) /* OK */ 38 #define PSF_E_NOMEM (-1) /* Out of memory */ 39 #define PSF_E_NOTIMPL (-2) /* Unsupported PSF file format */ 40 #define PSF_E_NOTPSF (-3) /* Attempt to load a non-PSF file */ 41 #define PSF_E_ERRNO (-4) /* Error in fread() or fwrite() */ 42 #define PSF_E_EMPTY (-5) /* Attempt to save an empty file */ 43 #define PSF_E_ASCII (-6) /* Not a Unicode PSF */ 44 #define PSF_E_UNICODE (-7) /* Failed to load Unicode directory */ 45 #define PSF_E_V2 (-8) /* PSF is in version 2 */ 46 #define PSF_E_NOTFOUND (-9) /* Code point not found */ 47 #define PSF_E_BANNED (-10) /* Invalid Unicode code point */ 48 #define PSF_E_PARSE (-11) /* Invalid Unicode sequence string */ 49 #define PSF_E_RANGE (-12) /* Character index out of range */ 50 51 typedef unsigned char psf_byte; 52 typedef unsigned short psf_word; 53 typedef unsigned long psf_dword; 54 55 typedef int psf_errno_t; 56 57 58 /* In-memory representation of a .PSF unicode directory entry. Rather than 59 * malloc these one at a time, we malloc them in blocks and keep a linked 60 * list of the blocks allocated (psf_unicode_buffer). 61 * 62 * The entries themselves also take the form of a linked list; there will 63 * be 256 or 512 chains for characters, and one for free blocks. 64 */ 65 66 typedef struct psfu_entry 67 { 68 struct psfu_entry *psfu_next; 69 psf_dword psfu_token; 70 } psf_unicode_dirent; 71 72 #define PSF_ENTRIES_PER_BUFFER 32 /* Can be tuned */ 73 74 typedef struct psfu_buffer 75 { 76 struct psfu_buffer *psfb_next; 77 psf_unicode_dirent psfb_dirents[PSF_ENTRIES_PER_BUFFER]; 78 } psf_unicode_buffer; 79 80 #endif 81 82 /* In-memory representation of a .PSF file (v1 or v2) */ 83 typedef struct 84 { 85 psf_dword psf_magic; 86 psf_dword psf_version; 87 psf_dword psf_hdrlen; /* Size of header */ 88 psf_dword psf_flags; 89 psf_dword psf_length; /* Number of characters */ 90 psf_dword psf_charlen; /* Length of a character bitmap */ 91 psf_dword psf_height; /* Height of a glyph */ 92 psf_dword psf_width; /* Width of a glyph */ 93 psf_byte *psf_data; /* Font bitmaps */ 94 psf_unicode_dirent **psf_dirents_used; 95 psf_unicode_dirent *psf_dirents_free; 96 psf_unicode_buffer *psf_dirents_buffer; 97 size_t psf_dirents_nused; 98 size_t psf_dirents_nfree; /* total malloced is always used+free */ 99 } PSF_FILE; 100 101 102 typedef struct array 103 { 104 psf_byte *data; 105 unsigned long len; 106 } PSFIO_ARRAY; 107 108 109 /* Stream I/O support */ 110 typedef struct psfio 111 { 112 PSF_FILE *psf; 113 int (*readfunc )(struct psfio *io); 114 int (*writefunc)(struct psfio *io, psf_byte b); 115 union 116 { 117 FILE *fp; 118 PSFIO_ARRAY arr; 119 void *general; 120 } data; 121 } PSFIO; 122 123 typedef struct psf_mapping 124 { 125 char *psfm_name; 126 psf_dword *psfm_tokens[256]; 127 } PSF_MAPPING; 128 129 /* Initialise the structure as empty */ 130 void psf_file_new(PSF_FILE *f); 131 /* Initialise the structure for a new font*/ 132 psf_errno_t psf_file_create(PSF_FILE *f, psf_dword width, psf_dword height, 133 psf_dword nchars, psf_byte unicode); 134 /* Add Unicode directory to a font */ 135 psf_errno_t psf_file_create_unicode(PSF_FILE *f); 136 137 /* Add an entry to the Unicode directory */ 138 psf_errno_t psf_unicode_add(PSF_FILE *f, psf_word nchar, psf_dword token); 139 /* Add a chain to the Unicode directory from the map */ 140 psf_errno_t psf_unicode_addmap(PSF_FILE *f, psf_word destchar, 141 PSF_MAPPING *m, psf_word srcchar); 142 /* Remove an entry from the Unicode directory */ 143 psf_errno_t psf_unicode_delete(PSF_FILE *f, psf_word nchar, psf_dword token); 144 /* Find a token in the Unicode directory */ 145 psf_errno_t psf_unicode_lookup(PSF_FILE *f, psf_dword token, psf_dword *nchar); 146 /* Find a token in the Unicode directory, based on chain slot in mapping m */ 147 psf_errno_t psf_unicode_lookupmap(PSF_FILE *f, PSF_MAPPING *m, psf_word slot, psf_dword *nchar, psf_dword *found); 148 /* Is 'token' a character that can't go in the Unicode mapping table? */ 149 psf_errno_t psf_unicode_banned(psf_dword token); 150 /* Convert a Unicode chain to a string */ 151 psf_errno_t psf_unicode_to_string(psf_unicode_dirent *chain, char **str); 152 /* ... and back */ 153 psf_errno_t psf_unicode_from_string(PSF_FILE *f, psf_word nchar, const char *str); 154 155 156 /* Allocate and initialise a psf_unicode_buffer */ 157 psf_unicode_buffer *psf_malloc_unicode_buffer(void); 158 159 /* Load a PSF from memory */ 160 psf_errno_t psf_memory_read(PSF_FILE *f, psf_byte *data, unsigned len); 161 /* Save a PSF to memory */ 162 psf_errno_t psf_memory_write(PSF_FILE *f, psf_byte *data, unsigned len); 163 /* Load a PSF from a stream 164 * nb: If the file pointer is important to you, you have to save it. */ 165 psf_errno_t psf_file_read (PSF_FILE *f, FILE *fp); 166 /* Write PSF to stream */ 167 psf_errno_t psf_file_write (PSF_FILE *f, FILE *fp); 168 /* Free any memory associated with a PSF file */ 169 void psf_file_delete (PSF_FILE *f); 170 /* Remove any unicode directory from a PSF file */ 171 void psf_file_delete_unicode(PSF_FILE *f); 172 /* Expand error number returned by other routines, to string */ 173 char *psf_error_string(psf_errno_t err); 174 175 /* Find an ASCII->Unicode mapping */ 176 PSF_MAPPING *psf_find_mapping(char *name); 177 void psf_list_mappings(FILE *fp); 178 179 /* Get/set pixel in a character bitmap */ 180 psf_errno_t psf_get_pixel(PSF_FILE *f, psf_dword ch, psf_dword x, psf_dword y, psf_byte *pixel); 181 psf_errno_t psf_set_pixel(PSF_FILE *f, psf_dword ch, psf_dword x, psf_dword y, psf_byte pixel); 182 183 /* Input/output from/to generic streams */ 184 psf_errno_t psf_read (PSFIO *io); 185 psf_errno_t psf_write(PSFIO *io); 186 187 /* Force a PSF file to be v1 or v2 */ 188 psf_errno_t psf_force_v1(PSF_FILE *f); 189 psf_errno_t psf_force_v2(PSF_FILE *f); 190 191 #define psf_is_unicode(f) ( ((f)->psf_flags) & 1 ) 192 #define psf_count_chars(f) ( (f)->psf_length ) 193 #include "psfutils.h" 194 195 #endif /* PSFLIB_H_INCLUDED */ 196 197