diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/font.h | 35 | ||||
-rw-r--r-- | firmware/font.c | 369 | ||||
-rw-r--r-- | firmware/powermgmt.c | 2 |
3 files changed, 257 insertions, 149 deletions
diff --git a/firmware/export/font.h b/firmware/export/font.h index 0fe6c30f2c..e9bf086423 100644 --- a/firmware/export/font.h +++ b/firmware/export/font.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) | 31 | #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) |
32 | #ifndef __PCTOOL__ | 32 | #ifndef __PCTOOL__ |
33 | #include "font_cache.h" | ||
33 | #include "sysfont.h" | 34 | #include "sysfont.h" |
34 | #endif | 35 | #endif |
35 | 36 | ||
@@ -47,9 +48,14 @@ | |||
47 | enum { | 48 | enum { |
48 | FONT_SYSFIXED, /* system fixed pitch font*/ | 49 | FONT_SYSFIXED, /* system fixed pitch font*/ |
49 | FONT_UI, /* system porportional font*/ | 50 | FONT_UI, /* system porportional font*/ |
50 | MAXFONTS | 51 | #ifdef HAVE_REMOTE_LCD |
52 | FONT_UI_REMOTE, /* UI font for remote LCD */ | ||
53 | #endif | ||
54 | SYSTEMFONTCOUNT /* Number of fonts reserved for the system and ui */ | ||
51 | }; | 55 | }; |
52 | 56 | ||
57 | #define MAXFONTS 10 | ||
58 | |||
53 | /* | 59 | /* |
54 | * .fnt loadable font file format definition | 60 | * .fnt loadable font file format definition |
55 | * | 61 | * |
@@ -89,17 +95,38 @@ struct font { | |||
89 | const unsigned char *width; /* character widths or NULL if fixed*/ | 95 | const unsigned char *width; /* character widths or NULL if fixed*/ |
90 | int defaultchar; /* default char (not glyph index)*/ | 96 | int defaultchar; /* default char (not glyph index)*/ |
91 | int32_t bits_size; /* # bytes of glyph bits*/ | 97 | int32_t bits_size; /* # bytes of glyph bits*/ |
98 | |||
99 | /* file, buffer and cache management */ | ||
100 | int fd; /* fd for the font file. >= 0 if cached */ | ||
101 | unsigned char *buffer_start; /* buffer to store the font in */ | ||
102 | unsigned char *buffer_position; /* position in the buffer */ | ||
103 | unsigned char *buffer_end; /* end of the buffer */ | ||
104 | int buffer_size; /* size of the buffer in bytes */ | ||
105 | #ifndef __PCTOOL__ | ||
106 | struct font_cache cache; | ||
107 | uint32_t file_width_offset; /* offset to file width data */ | ||
108 | uint32_t file_offset_offset; /* offset to file offset data */ | ||
109 | int long_offset; | ||
110 | #endif | ||
111 | |||
92 | }; | 112 | }; |
93 | 113 | ||
94 | /* font routines*/ | 114 | /* font routines*/ |
95 | void font_init(void); | 115 | void font_init(void); |
96 | struct font* font_load(const char *path); | 116 | #ifdef HAVE_REMOTE_LCD |
117 | /* Load a font into the special remote ui font slot */ | ||
118 | int font_load_remoteui(const char* path); | ||
119 | #endif | ||
120 | int font_load(struct font* pf, const char *path); | ||
121 | void font_unload(int font_id); | ||
122 | |||
97 | struct font* font_get(int font); | 123 | struct font* font_get(int font); |
98 | void font_reset(void); | 124 | |
125 | void font_reset(struct font *pf); | ||
99 | int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber); | 126 | int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber); |
100 | int font_get_width(struct font* ft, unsigned short ch); | 127 | int font_get_width(struct font* ft, unsigned short ch); |
101 | const unsigned char * font_get_bits(struct font* ft, unsigned short ch); | 128 | const unsigned char * font_get_bits(struct font* ft, unsigned short ch); |
102 | void glyph_cache_save(void); | 129 | void glyph_cache_save(struct font* pf); |
103 | 130 | ||
104 | #else /* HAVE_LCD_BITMAP */ | 131 | #else /* HAVE_LCD_BITMAP */ |
105 | 132 | ||
diff --git a/firmware/font.c b/firmware/font.c index a8734e93a1..52c6ffae6a 100644 --- a/firmware/font.c +++ b/firmware/font.c | |||
@@ -75,64 +75,77 @@ extern struct font sysfont; | |||
75 | 75 | ||
76 | /* structure filled in by font_load */ | 76 | /* structure filled in by font_load */ |
77 | static struct font font_ui; | 77 | static struct font font_ui; |
78 | /* static buffer allocation structures */ | ||
79 | static unsigned char main_buf[MAX_FONT_SIZE]; | ||
80 | #ifdef HAVE_REMOTE_LCD | ||
81 | #define REMOTE_FONT_SIZE 10000 | ||
82 | static struct font remote_font_ui; | ||
83 | static unsigned char remote_buf[REMOTE_FONT_SIZE]; | ||
84 | #endif | ||
78 | 85 | ||
79 | /* system font table, in order of FONT_xxx definition */ | 86 | /* system font table, in order of FONT_xxx definition */ |
80 | static struct font* const sysfonts[MAXFONTS] = { &sysfont, &font_ui }; | 87 | static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui, NULL}; |
81 | 88 | ||
82 | /* static buffer allocation structures */ | ||
83 | static unsigned char mbuf[MAX_FONT_SIZE]; | ||
84 | static unsigned char *freeptr = mbuf; | ||
85 | static unsigned char *fileptr; | ||
86 | static unsigned char *eofptr; | ||
87 | 89 | ||
88 | /* Font cache structures */ | 90 | /* Font cache structures */ |
89 | static struct font_cache font_cache_ui; | 91 | static void cache_create(struct font* pf, int maxwidth, int height); |
90 | static int fnt_file = -1; /* >=0 if font is cached */ | 92 | static void glyph_cache_load(struct font* pf); |
91 | static uint32_t file_width_offset; /* offset to file width data */ | ||
92 | static uint32_t file_offset_offset; /* offset to file offset data */ | ||
93 | static void cache_create(int maxwidth, int height); | ||
94 | static int long_offset = 0; | ||
95 | static int glyph_file; | ||
96 | /* End Font cache structures */ | 93 | /* End Font cache structures */ |
97 | 94 | ||
98 | static void glyph_cache_load(void); | ||
99 | |||
100 | void font_init(void) | 95 | void font_init(void) |
101 | { | 96 | { |
102 | memset(&font_ui, 0, sizeof(struct font)); | 97 | int i = SYSTEMFONTCOUNT; |
98 | while (i<MAXFONTS) | ||
99 | sysfonts[i++] = NULL; | ||
100 | font_reset(NULL); | ||
103 | } | 101 | } |
104 | 102 | ||
105 | /* Check if we have x bytes left in the file buffer */ | 103 | /* Check if we have x bytes left in the file buffer */ |
106 | #define HAVEBYTES(x) (fileptr + (x) <= eofptr) | 104 | #define HAVEBYTES(x) (pf->buffer_position + (x) <= pf->buffer_end) |
107 | 105 | ||
108 | /* Helper functions to read big-endian unaligned short or long from | 106 | /* Helper functions to read big-endian unaligned short or long from |
109 | the file buffer. Bounds-checking must be done in the calling | 107 | the file buffer. Bounds-checking must be done in the calling |
110 | function. | 108 | function. |
111 | */ | 109 | */ |
112 | 110 | ||
113 | static short readshort(void) | 111 | static short readshort(struct font *pf) |
114 | { | 112 | { |
115 | unsigned short s; | 113 | unsigned short s; |
116 | 114 | ||
117 | s = *fileptr++ & 0xff; | 115 | s = *pf->buffer_position++ & 0xff; |
118 | s |= (*fileptr++ << 8); | 116 | s |= (*pf->buffer_position++ << 8); |
119 | return s; | 117 | return s; |
120 | } | 118 | } |
121 | 119 | ||
122 | static int32_t readlong(void) | 120 | static int32_t readlong(struct font *pf) |
123 | { | 121 | { |
124 | uint32_t l; | 122 | uint32_t l; |
125 | 123 | ||
126 | l = *fileptr++ & 0xff; | 124 | l = *pf->buffer_position++ & 0xff; |
127 | l |= *fileptr++ << 8; | 125 | l |= *pf->buffer_position++ << 8; |
128 | l |= ((uint32_t)(*fileptr++)) << 16; | 126 | l |= ((uint32_t)(*pf->buffer_position++)) << 16; |
129 | l |= ((uint32_t)(*fileptr++)) << 24; | 127 | l |= ((uint32_t)(*pf->buffer_position++)) << 24; |
130 | return l; | 128 | return l; |
131 | } | 129 | } |
132 | 130 | ||
133 | void font_reset(void) | 131 | void font_reset(struct font *pf) |
134 | { | 132 | { |
135 | memset(&font_ui, 0, sizeof(struct font)); | 133 | unsigned char* buffer = NULL; |
134 | size_t buf_size = 0; | ||
135 | if (pf == NULL) | ||
136 | pf = &font_ui; | ||
137 | else | ||
138 | { | ||
139 | buffer = pf->buffer_start; | ||
140 | buf_size = pf->buffer_size; | ||
141 | } | ||
142 | memset(pf, 0, sizeof(struct font)); | ||
143 | pf->fd = -1; | ||
144 | if (buffer) | ||
145 | { | ||
146 | pf->buffer_start = buffer; | ||
147 | pf->buffer_size = buf_size; | ||
148 | } | ||
136 | } | 149 | } |
137 | 150 | ||
138 | static struct font* font_load_header(struct font *pf) | 151 | static struct font* font_load_header(struct font *pf) |
@@ -142,23 +155,23 @@ static struct font* font_load_header(struct font *pf) | |||
142 | return NULL; | 155 | return NULL; |
143 | 156 | ||
144 | /* read magic and version #*/ | 157 | /* read magic and version #*/ |
145 | if (memcmp(fileptr, VERSION, 4) != 0) | 158 | if (memcmp(pf->buffer_position, VERSION, 4) != 0) |
146 | return NULL; | 159 | return NULL; |
147 | 160 | ||
148 | fileptr += 4; | 161 | pf->buffer_position += 4; |
149 | 162 | ||
150 | /* font info*/ | 163 | /* font info*/ |
151 | pf->maxwidth = readshort(); | 164 | pf->maxwidth = readshort(pf); |
152 | pf->height = readshort(); | 165 | pf->height = readshort(pf); |
153 | pf->ascent = readshort(); | 166 | pf->ascent = readshort(pf); |
154 | fileptr += 2; /* Skip padding */ | 167 | pf->buffer_position += 2; /* Skip padding */ |
155 | pf->firstchar = readlong(); | 168 | pf->firstchar = readlong(pf); |
156 | pf->defaultchar = readlong(); | 169 | pf->defaultchar = readlong(pf); |
157 | pf->size = readlong(); | 170 | pf->size = readlong(pf); |
158 | 171 | ||
159 | /* get variable font data sizes*/ | 172 | /* get variable font data sizes*/ |
160 | /* # words of bitmap_t*/ | 173 | /* # words of bitmap_t*/ |
161 | pf->bits_size = readlong(); | 174 | pf->bits_size = readlong(pf); |
162 | 175 | ||
163 | return pf; | 176 | return pf; |
164 | } | 177 | } |
@@ -171,32 +184,32 @@ static struct font* font_load_in_memory(struct font* pf) | |||
171 | return NULL; | 184 | return NULL; |
172 | 185 | ||
173 | /* # longs of offset*/ | 186 | /* # longs of offset*/ |
174 | noffset = readlong(); | 187 | noffset = readlong(pf); |
175 | 188 | ||
176 | /* # bytes of width*/ | 189 | /* # bytes of width*/ |
177 | nwidth = readlong(); | 190 | nwidth = readlong(pf); |
178 | 191 | ||
179 | /* variable font data*/ | 192 | /* variable font data*/ |
180 | pf->bits = (unsigned char *)fileptr; | 193 | pf->bits = (unsigned char *)pf->buffer_position; |
181 | fileptr += pf->bits_size*sizeof(unsigned char); | 194 | pf->buffer_position += pf->bits_size*sizeof(unsigned char); |
182 | 195 | ||
183 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) | 196 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) |
184 | { | 197 | { |
185 | /* pad to 16-bit boundary */ | 198 | /* pad to 16-bit boundary */ |
186 | fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1); | 199 | pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 1) & ~1); |
187 | } | 200 | } |
188 | else | 201 | else |
189 | { | 202 | { |
190 | /* pad to 32-bit boundary*/ | 203 | /* pad to 32-bit boundary*/ |
191 | fileptr = (unsigned char *)(((intptr_t)fileptr + 3) & ~3); | 204 | pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 3) & ~3); |
192 | } | 205 | } |
193 | 206 | ||
194 | if (noffset) | 207 | if (noffset) |
195 | { | 208 | { |
196 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) | 209 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) |
197 | { | 210 | { |
198 | long_offset = 0; | 211 | pf->long_offset = 0; |
199 | pf->offset = (uint16_t*)fileptr; | 212 | pf->offset = (uint16_t*)pf->buffer_position; |
200 | 213 | ||
201 | /* Check we have sufficient buffer */ | 214 | /* Check we have sufficient buffer */ |
202 | if (!HAVEBYTES(noffset * sizeof(uint16_t))) | 215 | if (!HAVEBYTES(noffset * sizeof(uint16_t))) |
@@ -204,13 +217,13 @@ static struct font* font_load_in_memory(struct font* pf) | |||
204 | 217 | ||
205 | for (i=0; i<noffset; ++i) | 218 | for (i=0; i<noffset; ++i) |
206 | { | 219 | { |
207 | ((uint16_t*)(pf->offset))[i] = (uint16_t)readshort(); | 220 | ((uint16_t*)(pf->offset))[i] = (uint16_t)readshort(pf); |
208 | } | 221 | } |
209 | } | 222 | } |
210 | else | 223 | else |
211 | { | 224 | { |
212 | long_offset = 1; | 225 | pf->long_offset = 1; |
213 | pf->offset = (uint16_t*)fileptr; | 226 | pf->offset = (uint16_t*)pf->buffer_position; |
214 | 227 | ||
215 | /* Check we have sufficient buffer */ | 228 | /* Check we have sufficient buffer */ |
216 | if (!HAVEBYTES(noffset * sizeof(int32_t))) | 229 | if (!HAVEBYTES(noffset * sizeof(int32_t))) |
@@ -218,7 +231,7 @@ static struct font* font_load_in_memory(struct font* pf) | |||
218 | 231 | ||
219 | for (i=0; i<noffset; ++i) | 232 | for (i=0; i<noffset; ++i) |
220 | { | 233 | { |
221 | ((uint32_t*)(pf->offset))[i] = (uint32_t)readlong(); | 234 | ((uint32_t*)(pf->offset))[i] = (uint32_t)readlong(pf); |
222 | } | 235 | } |
223 | } | 236 | } |
224 | } | 237 | } |
@@ -226,13 +239,13 @@ static struct font* font_load_in_memory(struct font* pf) | |||
226 | pf->offset = NULL; | 239 | pf->offset = NULL; |
227 | 240 | ||
228 | if (nwidth) { | 241 | if (nwidth) { |
229 | pf->width = (unsigned char *)fileptr; | 242 | pf->width = (unsigned char *)pf->buffer_position; |
230 | fileptr += nwidth*sizeof(unsigned char); | 243 | pf->buffer_position += nwidth*sizeof(unsigned char); |
231 | } | 244 | } |
232 | else | 245 | else |
233 | pf->width = NULL; | 246 | pf->width = NULL; |
234 | 247 | ||
235 | if (fileptr > eofptr) | 248 | if (pf->buffer_position > pf->buffer_end) |
236 | return NULL; | 249 | return NULL; |
237 | 250 | ||
238 | return pf; /* success!*/ | 251 | return pf; /* success!*/ |
@@ -242,135 +255,203 @@ static struct font* font_load_in_memory(struct font* pf) | |||
242 | static struct font* font_load_cached(struct font* pf) | 255 | static struct font* font_load_cached(struct font* pf) |
243 | { | 256 | { |
244 | uint32_t noffset, nwidth; | 257 | uint32_t noffset, nwidth; |
245 | unsigned char* oldfileptr = fileptr; | 258 | unsigned char* oldfileptr = pf->buffer_position; |
246 | 259 | ||
247 | if (!HAVEBYTES(2 * sizeof(int32_t))) | 260 | if (!HAVEBYTES(2 * sizeof(int32_t))) |
248 | return NULL; | 261 | return NULL; |
249 | 262 | ||
250 | /* # longs of offset*/ | 263 | /* # longs of offset*/ |
251 | noffset = readlong(); | 264 | noffset = readlong(pf); |
252 | 265 | ||
253 | /* # bytes of width*/ | 266 | /* # bytes of width*/ |
254 | nwidth = readlong(); | 267 | nwidth = readlong(pf); |
255 | 268 | ||
256 | /* We are now at the bitmap data, this is fixed at 36.. */ | 269 | /* We are now at the bitmap data, this is fixed at 36.. */ |
257 | pf->bits = NULL; | 270 | pf->bits = NULL; |
258 | 271 | ||
259 | /* Calculate offset to offset data */ | 272 | /* Calculate offset to offset data */ |
260 | fileptr += pf->bits_size * sizeof(unsigned char); | 273 | pf->buffer_position += pf->bits_size * sizeof(unsigned char); |
261 | 274 | ||
262 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) | 275 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) |
263 | { | 276 | { |
264 | long_offset = 0; | 277 | pf->long_offset = 0; |
265 | /* pad to 16-bit boundary */ | 278 | /* pad to 16-bit boundary */ |
266 | fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1); | 279 | pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 1) & ~1); |
267 | } | 280 | } |
268 | else | 281 | else |
269 | { | 282 | { |
270 | long_offset = 1; | 283 | pf->long_offset = 1; |
271 | /* pad to 32-bit boundary*/ | 284 | /* pad to 32-bit boundary*/ |
272 | fileptr = (unsigned char *)(((intptr_t)fileptr + 3) & ~3); | 285 | pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 3) & ~3); |
273 | } | 286 | } |
274 | 287 | ||
275 | if (noffset) | 288 | if (noffset) |
276 | file_offset_offset = (uint32_t)(fileptr - freeptr); | 289 | pf->file_offset_offset = (uint32_t)(pf->buffer_position - pf->buffer_start); |
277 | else | 290 | else |
278 | file_offset_offset = 0; | 291 | pf->file_offset_offset = 0; |
279 | 292 | ||
280 | /* Calculate offset to widths data */ | 293 | /* Calculate offset to widths data */ |
281 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) | 294 | if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS) |
282 | fileptr += noffset * sizeof(uint16_t); | 295 | pf->buffer_position += noffset * sizeof(uint16_t); |
283 | else | 296 | else |
284 | fileptr += noffset * sizeof(uint32_t); | 297 | pf->buffer_position += noffset * sizeof(uint32_t); |
285 | 298 | ||
286 | if (nwidth) | 299 | if (nwidth) |
287 | file_width_offset = (uint32_t)(fileptr - freeptr); | 300 | pf->file_width_offset = (uint32_t)(pf->buffer_position - pf->buffer_start); |
288 | else | 301 | else |
289 | file_width_offset = 0; | 302 | pf->file_width_offset = 0; |
290 | 303 | ||
291 | fileptr = oldfileptr; | 304 | pf->buffer_position = oldfileptr; |
292 | 305 | ||
293 | /* Create the cache */ | 306 | /* Create the cache */ |
294 | cache_create(pf->maxwidth, pf->height); | 307 | cache_create(pf, pf->maxwidth, pf->height); |
295 | 308 | ||
296 | return pf; | 309 | return pf; |
297 | } | 310 | } |
298 | 311 | ||
299 | /* read and load font into incore font structure*/ | 312 | static bool internal_load_font(struct font* pf, const char *path, |
300 | struct font* font_load(const char *path) | 313 | char *buf, size_t buf_size) |
301 | { | 314 | { |
302 | int size; | 315 | int size; |
303 | struct font* pf = &font_ui; | 316 | |
304 | |||
305 | /* save loaded glyphs */ | 317 | /* save loaded glyphs */ |
306 | glyph_cache_save(); | 318 | glyph_cache_save(pf); |
307 | |||
308 | /* Close font file handle */ | 319 | /* Close font file handle */ |
309 | if (fnt_file >= 0) | 320 | if (pf->fd >= 0) |
310 | close(fnt_file); | 321 | close(pf->fd); |
322 | |||
323 | font_reset(pf); | ||
311 | 324 | ||
312 | /* open and read entire font file*/ | 325 | /* open and read entire font file*/ |
313 | fnt_file = open(path, O_RDONLY|O_BINARY); | 326 | pf->fd = open(path, O_RDONLY|O_BINARY); |
314 | 327 | ||
315 | if (fnt_file < 0) { | 328 | if (pf->fd < 0) { |
316 | DEBUGF("Can't open font: %s\n", path); | 329 | DEBUGF("Can't open font: %s\n", path); |
317 | return NULL; | 330 | return false; |
318 | } | 331 | } |
319 | 332 | ||
320 | /* Check file size */ | 333 | /* Check file size */ |
321 | size = filesize(fnt_file); | 334 | size = filesize(pf->fd); |
322 | 335 | pf->buffer_start = buf; | |
323 | font_reset(); | 336 | pf->buffer_size = buf_size; |
324 | 337 | ||
325 | /* currently, font loading replaces earlier font allocation*/ | 338 | pf->buffer_position = buf; |
326 | freeptr = (unsigned char *)(((intptr_t)mbuf + 3) & ~3); | 339 | |
327 | fileptr = freeptr; | 340 | if (size > pf->buffer_size) |
328 | |||
329 | |||
330 | if (size > MAX_FONT_SIZE) | ||
331 | { | 341 | { |
332 | read(fnt_file, fileptr, FONT_HEADER_SIZE); | 342 | read(pf->fd, pf->buffer_position, FONT_HEADER_SIZE); |
333 | eofptr = fileptr + FONT_HEADER_SIZE; | 343 | pf->buffer_end = pf->buffer_position + FONT_HEADER_SIZE; |
334 | 344 | ||
335 | if (!font_load_header(pf)) | 345 | if (!font_load_header(pf)) |
336 | { | 346 | { |
337 | DEBUGF("Failed font header load"); | 347 | DEBUGF("Failed font header load"); |
338 | return NULL; | 348 | return false; |
339 | } | 349 | } |
340 | 350 | ||
341 | if (!font_load_cached(pf)) | 351 | if (!font_load_cached(pf)) |
342 | { | 352 | { |
343 | DEBUGF("Failed font cache load"); | 353 | DEBUGF("Failed font cache load"); |
344 | return NULL; | 354 | return false; |
345 | } | 355 | } |
346 | 356 | ||
347 | glyph_cache_load(); | 357 | glyph_cache_load(pf); |
348 | } | 358 | } |
349 | else | 359 | else |
350 | { | 360 | { |
351 | read(fnt_file, fileptr, MAX_FONT_SIZE); | 361 | read(pf->fd, pf->buffer_position, pf->buffer_size); |
352 | eofptr = fileptr + size; | 362 | pf->buffer_end = pf->buffer_position + size; |
353 | close(fnt_file); | 363 | close(pf->fd); |
354 | fnt_file = -1; | 364 | pf->fd = -1; |
355 | 365 | ||
356 | if (!font_load_header(pf)) | 366 | if (!font_load_header(pf)) |
357 | { | 367 | { |
358 | DEBUGF("Failed font header load"); | 368 | DEBUGF("Failed font header load"); |
359 | return NULL; | 369 | return false; |
360 | } | 370 | } |
361 | 371 | ||
362 | if (!font_load_in_memory(pf)) | 372 | if (!font_load_in_memory(pf)) |
363 | { | 373 | { |
364 | DEBUGF("Failed mem load"); | 374 | DEBUGF("Failed mem load"); |
365 | return NULL; | 375 | return false; |
366 | } | 376 | } |
367 | } | 377 | } |
378 | return true; | ||
379 | } | ||
380 | |||
381 | #ifdef HAVE_REMOTE_LCD | ||
382 | /* Load a font into the special remote ui font slot */ | ||
383 | int font_load_remoteui(const char* path) | ||
384 | { | ||
385 | struct font* pf = &remote_font_ui; | ||
386 | if (!path) | ||
387 | { | ||
388 | if (sysfonts[FONT_UI_REMOTE] && sysfonts[FONT_UI_REMOTE] != sysfonts[FONT_UI]) | ||
389 | font_unload(FONT_UI_REMOTE); | ||
390 | sysfonts[FONT_UI_REMOTE] = NULL; | ||
391 | return FONT_UI; | ||
392 | } | ||
393 | if (!internal_load_font(pf, path, remote_buf, REMOTE_FONT_SIZE)) | ||
394 | { | ||
395 | sysfonts[FONT_UI_REMOTE] = NULL; | ||
396 | return -1; | ||
397 | } | ||
398 | |||
399 | sysfonts[FONT_UI_REMOTE] = pf; | ||
400 | return FONT_UI_REMOTE; | ||
401 | } | ||
402 | #endif | ||
368 | 403 | ||
369 | /* no need for multiple font loads currently*/ | 404 | /* read and load font into incore font structure, |
370 | /*freeptr += filesize;*/ | 405 | * returns the font number on success, -1 on failure */ |
371 | /*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/ | 406 | int font_load(struct font* pf, const char *path) |
407 | { | ||
408 | int font_id = -1; | ||
409 | char *buffer; | ||
410 | size_t buffer_size; | ||
411 | if (pf == NULL) | ||
412 | { | ||
413 | pf = &font_ui; | ||
414 | font_id = FONT_UI; | ||
415 | } | ||
416 | else | ||
417 | { | ||
418 | for (font_id = SYSTEMFONTCOUNT; font_id < MAXFONTS; font_id++) | ||
419 | { | ||
420 | if (sysfonts[font_id] == NULL) | ||
421 | break; | ||
422 | } | ||
423 | if (font_id == MAXFONTS) | ||
424 | return -1; /* too many fonts */ | ||
425 | } | ||
426 | |||
427 | if (font_id == FONT_UI) | ||
428 | { | ||
429 | /* currently, font loading replaces earlier font allocation*/ | ||
430 | buffer = (unsigned char *)(((intptr_t)main_buf + 3) & ~3); | ||
431 | buffer_size = MAX_FONT_SIZE; | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | buffer = pf->buffer_start; | ||
436 | buffer_size = pf->buffer_size; | ||
437 | } | ||
438 | |||
439 | if (!internal_load_font(pf, path, buffer, buffer_size)) | ||
440 | return -1; | ||
441 | |||
442 | sysfonts[font_id] = pf; | ||
443 | return font_id; /* success!*/ | ||
444 | } | ||
372 | 445 | ||
373 | return pf; /* success!*/ | 446 | void font_unload(int font_id) |
447 | { | ||
448 | struct font* pf = sysfonts[font_id]; | ||
449 | if (font_id >= SYSTEMFONTCOUNT && pf) | ||
450 | { | ||
451 | if (pf->fd >= 0) | ||
452 | close(pf->fd); | ||
453 | sysfonts[font_id] = NULL; | ||
454 | } | ||
374 | } | 455 | } |
375 | 456 | ||
376 | /* | 457 | /* |
@@ -382,9 +463,6 @@ struct font* font_get(int font) | |||
382 | { | 463 | { |
383 | struct font* pf; | 464 | struct font* pf; |
384 | 465 | ||
385 | if (font >= MAXFONTS) | ||
386 | font = 0; | ||
387 | |||
388 | while (1) { | 466 | while (1) { |
389 | pf = sysfonts[font]; | 467 | pf = sysfonts[font]; |
390 | if (pf && pf->height) | 468 | if (pf && pf->height) |
@@ -404,11 +482,11 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data) | |||
404 | unsigned short char_code = p->_char_code; | 482 | unsigned short char_code = p->_char_code; |
405 | unsigned char tmp[2]; | 483 | unsigned char tmp[2]; |
406 | 484 | ||
407 | if (file_width_offset) | 485 | if (pf->file_width_offset) |
408 | { | 486 | { |
409 | int width_offset = file_width_offset + char_code; | 487 | int width_offset = pf->file_width_offset + char_code; |
410 | lseek(fnt_file, width_offset, SEEK_SET); | 488 | lseek(pf->fd, width_offset, SEEK_SET); |
411 | read(fnt_file, &(p->width), 1); | 489 | read(pf->fd, &(p->width), 1); |
412 | } | 490 | } |
413 | else | 491 | else |
414 | { | 492 | { |
@@ -417,14 +495,14 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data) | |||
417 | 495 | ||
418 | int32_t bitmap_offset = 0; | 496 | int32_t bitmap_offset = 0; |
419 | 497 | ||
420 | if (file_offset_offset) | 498 | if (pf->file_offset_offset) |
421 | { | 499 | { |
422 | int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(int16_t)); | 500 | int32_t offset = pf->file_offset_offset + char_code * (pf->long_offset ? sizeof(int32_t) : sizeof(int16_t)); |
423 | lseek(fnt_file, offset, SEEK_SET); | 501 | lseek(pf->fd, offset, SEEK_SET); |
424 | read (fnt_file, tmp, 2); | 502 | read (pf->fd, tmp, 2); |
425 | bitmap_offset = tmp[0] | (tmp[1] << 8); | 503 | bitmap_offset = tmp[0] | (tmp[1] << 8); |
426 | if (long_offset) { | 504 | if (pf->long_offset) { |
427 | read (fnt_file, tmp, 2); | 505 | read (pf->fd, tmp, 2); |
428 | bitmap_offset |= (tmp[0] << 16) | (tmp[1] << 24); | 506 | bitmap_offset |= (tmp[0] << 16) | (tmp[1] << 24); |
429 | } | 507 | } |
430 | } | 508 | } |
@@ -434,22 +512,22 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data) | |||
434 | } | 512 | } |
435 | 513 | ||
436 | int32_t file_offset = FONT_HEADER_SIZE + bitmap_offset; | 514 | int32_t file_offset = FONT_HEADER_SIZE + bitmap_offset; |
437 | lseek(fnt_file, file_offset, SEEK_SET); | 515 | lseek(pf->fd, file_offset, SEEK_SET); |
438 | 516 | ||
439 | int src_bytes = p->width * ((pf->height + 7) / 8); | 517 | int src_bytes = p->width * ((pf->height + 7) / 8); |
440 | read(fnt_file, p->bitmap, src_bytes); | 518 | read(pf->fd, p->bitmap, src_bytes); |
441 | } | 519 | } |
442 | 520 | ||
443 | /* | 521 | /* |
444 | * Converts cbuf into a font cache | 522 | * Converts cbuf into a font cache |
445 | */ | 523 | */ |
446 | static void cache_create(int maxwidth, int height) | 524 | static void cache_create(struct font* pf, int maxwidth, int height) |
447 | { | 525 | { |
448 | /* maximum size of rotated bitmap */ | 526 | /* maximum size of rotated bitmap */ |
449 | int bitmap_size = maxwidth * ((height + 7) / 8); | 527 | int bitmap_size = maxwidth * ((height + 7) / 8); |
450 | 528 | ||
451 | /* Initialise cache */ | 529 | /* Initialise cache */ |
452 | font_cache_create(&font_cache_ui, mbuf, MAX_FONT_SIZE, bitmap_size); | 530 | font_cache_create(&pf->cache, pf->buffer_start, pf->buffer_size, bitmap_size); |
453 | } | 531 | } |
454 | 532 | ||
455 | /* | 533 | /* |
@@ -462,8 +540,8 @@ int font_get_width(struct font* pf, unsigned short char_code) | |||
462 | char_code = pf->defaultchar; | 540 | char_code = pf->defaultchar; |
463 | char_code -= pf->firstchar; | 541 | char_code -= pf->firstchar; |
464 | 542 | ||
465 | return (fnt_file >= 0 && pf != &sysfont)? | 543 | return (pf->fd >= 0 && pf != &sysfont)? |
466 | font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->width: | 544 | font_cache_get(&pf->cache,char_code,load_cache_entry,pf)->width: |
467 | pf->width? pf->width[char_code]: pf->maxwidth; | 545 | pf->width? pf->width[char_code]: pf->maxwidth; |
468 | } | 546 | } |
469 | 547 | ||
@@ -476,10 +554,10 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) | |||
476 | char_code = pf->defaultchar; | 554 | char_code = pf->defaultchar; |
477 | char_code -= pf->firstchar; | 555 | char_code -= pf->firstchar; |
478 | 556 | ||
479 | if (fnt_file >= 0 && pf != &sysfont) | 557 | if (pf->fd >= 0 && pf != &sysfont) |
480 | { | 558 | { |
481 | bits = | 559 | bits = |
482 | (unsigned char*)font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->bitmap; | 560 | (unsigned char*)font_cache_get(&pf->cache,char_code,load_cache_entry,pf)->bitmap; |
483 | } | 561 | } |
484 | else | 562 | else |
485 | { | 563 | { |
@@ -497,7 +575,7 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) | |||
497 | 575 | ||
498 | return bits; | 576 | return bits; |
499 | } | 577 | } |
500 | 578 | static int cache_fd; | |
501 | static void glyph_file_write(void* data) | 579 | static void glyph_file_write(void* data) |
502 | { | 580 | { |
503 | struct font_cache_entry* p = data; | 581 | struct font_cache_entry* p = data; |
@@ -507,45 +585,48 @@ static void glyph_file_write(void* data) | |||
507 | 585 | ||
508 | ch = p->_char_code + pf->firstchar; | 586 | ch = p->_char_code + pf->firstchar; |
509 | 587 | ||
510 | if (ch != 0xffff && glyph_file >= 0) { | 588 | if (ch != 0xffff && cache_fd >= 0) { |
511 | tmp[0] = ch >> 8; | 589 | tmp[0] = ch >> 8; |
512 | tmp[1] = ch & 0xff; | 590 | tmp[1] = ch & 0xff; |
513 | if (write(glyph_file, tmp, 2) != 2) { | 591 | if (write(cache_fd, tmp, 2) != 2) { |
514 | close(glyph_file); | 592 | close(cache_fd); |
515 | glyph_file = -1; | 593 | cache_fd = -1; |
516 | } | 594 | } |
517 | } | 595 | } |
518 | return; | 596 | return; |
519 | } | 597 | } |
520 | 598 | ||
521 | /* save the char codes of the loaded glyphs to a file */ | 599 | /* save the char codes of the loaded glyphs to a file */ |
522 | void glyph_cache_save(void) | 600 | void glyph_cache_save(struct font* pf) |
523 | { | 601 | { |
524 | 602 | if (!pf) | |
525 | if (fnt_file >= 0) { | 603 | pf = &font_ui; |
604 | if (pf->fd >= 0 && pf == &font_ui) | ||
605 | { | ||
526 | #ifdef WPSEDITOR | 606 | #ifdef WPSEDITOR |
527 | glyph_file = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC); | 607 | cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC); |
528 | #else | 608 | #else |
529 | glyph_file = creat(GLYPH_CACHE_FILE); | 609 | cache_fd = creat(GLYPH_CACHE_FILE); |
530 | #endif | 610 | #endif |
531 | if (glyph_file < 0) return; | 611 | if (cache_fd < 0) return; |
532 | 612 | ||
533 | lru_traverse(&font_cache_ui._lru, glyph_file_write); | 613 | lru_traverse(&pf->cache._lru, glyph_file_write); |
534 | 614 | ||
535 | if (glyph_file >= 0) | 615 | if (cache_fd < 0) |
536 | close(glyph_file); | 616 | { |
617 | close(cache_fd); | ||
618 | cache_fd = -1; | ||
619 | } | ||
537 | } | 620 | } |
538 | return; | 621 | return; |
539 | } | 622 | } |
540 | 623 | ||
541 | static void glyph_cache_load(void) | 624 | static void glyph_cache_load(struct font* pf) |
542 | { | 625 | { |
543 | if (fnt_file >= 0) { | 626 | if (pf->fd >= 0) { |
544 | |||
545 | int fd; | 627 | int fd; |
546 | unsigned char tmp[2]; | 628 | unsigned char tmp[2]; |
547 | unsigned short ch; | 629 | unsigned short ch; |
548 | struct font* pf = &font_ui; | ||
549 | 630 | ||
550 | fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY); | 631 | fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY); |
551 | 632 | ||
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 5f488810ac..3f2b3c0f85 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c | |||
@@ -744,7 +744,7 @@ void shutdown_hw(void) | |||
744 | 744 | ||
745 | if (battery_level_safe()) { /* do not save on critical battery */ | 745 | if (battery_level_safe()) { /* do not save on critical battery */ |
746 | #ifdef HAVE_LCD_BITMAP | 746 | #ifdef HAVE_LCD_BITMAP |
747 | glyph_cache_save(); | 747 | glyph_cache_save(NULL); |
748 | #endif | 748 | #endif |
749 | 749 | ||
750 | /* Commit pending writes if needed. Even though we don't do write caching, | 750 | /* Commit pending writes if needed. Even though we don't do write caching, |