comparison dmtext_bm.c @ 91:e1e308167991

Various improvements in the bitmapped font loading and saving functions.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 02 Oct 2012 17:50:28 +0300
parents b10884934aca
children f16d102dbbac
comparison
equal deleted inserted replaced
90:1ab3fd8b9afc 91:e1e308167991
198 198
199 if (version > DMFONT_VERSION) 199 if (version > DMFONT_VERSION)
200 return DMERR_VERSION; 200 return DMERR_VERSION;
201 } 201 }
202 202
203 // Check other data 203 // Read other header data
204 if (tsfont) 204 if (tsfont)
205 { 205 {
206 // TSFONT only has number of glyphs stored in the file
206 nglyphs = dmfgetc(res); 207 nglyphs = dmfgetc(res);
207 maxglyph = 256; 208
209 // Maximum glyph number
210 maxglyph = 255;
208 } 211 }
209 else 212 else
210 { 213 {
211 dmf_read_le16(res, &nglyphs); 214 dmf_read_le16(res, &nglyphs);
212 dmf_read_le16(res, &maxglyph); 215 dmf_read_le16(res, &maxglyph);
215 width = dmfgetc(res); 218 width = dmfgetc(res);
216 height = dmfgetc(res); 219 height = dmfgetc(res);
217 220
218 if (tsfont) 221 if (tsfont)
219 { 222 {
220 // TSFONT color assigns (boolean) .. we discard this. 223 // TSFONT color assignments (boolean) .. we discard this.
221 dmfgetc(res); 224 dmfgetc(res);
222 } 225 }
223 226
224 if (width < DMFONT_MIN_WIDTH || 227 if (width < DMFONT_MIN_WIDTH ||
225 height < DMFONT_MIN_HEIGHT || 228 height < DMFONT_MIN_HEIGHT ||
235 return DMERR_MALLOC; 238 return DMERR_MALLOC;
236 239
237 // Read glyph data, if any 240 // Read glyph data, if any
238 if (nglyphs > 0) 241 if (nglyphs > 0)
239 { 242 {
240 Uint32 i, BitsPerPixel, Rmask, Gmask, Bmask, Amask; 243 int n, i;
244 Uint32 BitsPerPixel, Rmask, Gmask, Bmask, Amask;
245 SDL_Color pal[DMFONT_NPALETTE];
246
247 // Setup palette for 8bpp fonts
248 for (n = 0; n < DMFONT_NPALETTE; n++)
249 {
250 pal[n].r = n * 16;
251 pal[n].g = n * 16;
252 pal[n].b = n * 16;
253 pal[n].unused = n > 0 ? n * 16 : 0;
254 }
241 255
242 if (tsfont) 256 if (tsfont)
243 { 257 {
244 BitsPerPixel = 8; 258 BitsPerPixel = 8;
245 Rmask = Gmask = Bmask = Amask = 0; 259 Rmask = Gmask = Bmask = Amask = 0;
258 int y; 272 int y;
259 Uint16 index; 273 Uint16 index;
260 Uint8 *pixels; 274 Uint8 *pixels;
261 SDL_Surface *glyph; 275 SDL_Surface *glyph;
262 276
277 // TSFONT format has only byte sized index
263 if (tsfont) 278 if (tsfont)
264 index = dmfgetc(res); 279 index = dmfgetc(res);
265 else 280 else
266 dmf_read_le16(res, &index); 281 dmf_read_le16(res, &index);
267 282
283 // Read dimensions
268 width = dmfgetc(res); 284 width = dmfgetc(res);
269 height = dmfgetc(res); 285 height = dmfgetc(res);
270 286
271 if (width < DMFONT_MIN_WIDTH || 287 if (width < DMFONT_MIN_WIDTH ||
272 height < DMFONT_MIN_HEIGHT || 288 height < DMFONT_MIN_HEIGHT ||
273 width > DMFONT_MAX_WIDTH || 289 width > DMFONT_MAX_WIDTH ||
274 height > DMFONT_MAX_HEIGHT || 290 height > DMFONT_MAX_HEIGHT ||
275 index > DMFONT_MAX_GLYPHS) 291 index > maxglyph)
276 return DMERR_INVALID_DATA; 292 return DMERR_INVALID_DATA;
277 293
294 // Allocate bitmap
278 font->glyphs[index] = glyph = SDL_CreateRGBSurface( 295 font->glyphs[index] = glyph = SDL_CreateRGBSurface(
279 SDL_SWSURFACE, width, height, 296 SDL_SWSURFACE, width, height,
280 BitsPerPixel, Rmask, Gmask, 297 BitsPerPixel, Rmask, Gmask,
281 Bmask, 298 Bmask,
282 Amask); 299 Amask);
283 300
284 if (glyph == NULL) 301 if (glyph == NULL)
285 return DMERR_MALLOC; 302 return DMERR_MALLOC;
286 303
304 if (BitsPerPixel == 8)
305 SDL_SetColors(glyph, pal, 0, DMFONT_NPALETTE);
306
307 // Read pixel data
287 pixels = glyph->pixels; 308 pixels = glyph->pixels;
288 for (y = 0; y < glyph->h; y++) 309 for (y = 0; y < glyph->h; y++)
289 { 310 {
290 if (dmfread(pixels, glyph->format->BytesPerPixel, glyph->w, res) != (size_t) glyph->w) 311 if (dmfread(pixels, glyph->format->BytesPerPixel, glyph->w, res) != (size_t) glyph->w)
291 return DMERR_FREAD; 312 return DMERR_FREAD;
298 } 319 }
299 320
300 321
301 int dmSaveBitmapFont(DMResource *res, DMBitmapFont *font) 322 int dmSaveBitmapFont(DMResource *res, DMBitmapFont *font)
302 { 323 {
303 int count, n; 324 int maxglyph, nglyphs, n;
304 if (font == NULL) 325 if (font == NULL)
305 return DMERR_NULLPTR; 326 return DMERR_NULLPTR;
306 327
307 if (font->nglyphs > DMFONT_MAX_GLYPHS || 328 if (font->nglyphs > DMFONT_MAX_GLYPHS ||
308 font->width > DMFONT_MAX_WIDTH || 329 font->width > DMFONT_MAX_WIDTH ||
310 font->width < DMFONT_MIN_WIDTH || 331 font->width < DMFONT_MIN_WIDTH ||
311 font->height < DMFONT_MIN_HEIGHT) 332 font->height < DMFONT_MIN_HEIGHT)
312 return DMERR_INVALID_DATA; 333 return DMERR_INVALID_DATA;
313 334
314 // Count number of actually existing glyphs 335 // Count number of actually existing glyphs
315 for (count = n = 0; n < font->nglyphs; n++) 336 for (maxglyph = nglyphs = n = 0; n < font->nglyphs; n++)
316 if (font->glyphs[n] != NULL) count++; 337 {
338 if (font->glyphs[n] != NULL)
339 {
340 nglyphs++;
341 maxglyph = n;
342 }
343 }
317 344
318 // Write the DMFONT header 345 // Write the DMFONT header
319 if (!dmf_write_str(res, (Uint8 *) DMFONT_MAGIC, 6)) 346 if (!dmf_write_str(res, (Uint8 *) DMFONT_MAGIC, 6))
320 return DMERR_FWRITE; 347 return DMERR_FWRITE;
321 348
322 dmf_write_le16(res, DMFONT_VERSION); 349 dmf_write_le16(res, DMFONT_VERSION);
323 dmf_write_le16(res, count); // # of glyphs actually 350 dmf_write_le16(res, nglyphs);
324 dmf_write_le16(res, font->nglyphs); // Max glyph # 351 dmf_write_le16(res, maxglyph);
325 dmfputc(font->width, res); 352 dmfputc(font->width, res);
326 dmfputc(font->height, res); 353 dmfputc(font->height, res);
327 354
328 if (font->nglyphs > 0) 355 if (nglyphs > 0)
329 { 356 {
330 int i; 357 int i;
331 SDL_Surface *glyph = font->glyphs[0]; 358 SDL_Surface *glyph = font->glyphs[maxglyph];
332 359
333 // If there are actual glyphs stored, save thi 360 // If there are actual glyphs stored, save thi
334 dmfputc(glyph->format->BitsPerPixel, res); 361 dmfputc(glyph->format->BitsPerPixel, res);
335 dmf_write_le32(res, glyph->format->Rmask); 362 dmf_write_le32(res, glyph->format->Rmask);
336 dmf_write_le32(res, glyph->format->Gmask); 363 dmf_write_le32(res, glyph->format->Gmask);