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