comparison src/w32bdf.c @ 24496:541ff963ba80

Merged patches from Meadow.
author Geoff Voelker <voelker@cs.washington.edu>
date Wed, 17 Mar 1999 22:03:43 +0000
parents db9dfcd11c84
children d2d412758428
comparison
equal deleted inserted replaced
24495:14e1df6e60a8 24496:541ff963ba80
35 #define max(a, b) ((a) > (b) ? (a) : (b)) 35 #define max(a, b) ((a) > (b) ? (a) : (b))
36 36
37 void w32_free_bdf_font(bdffont *fontp); 37 void w32_free_bdf_font(bdffont *fontp);
38 bdffont *w32_init_bdf_font(char *filename); 38 bdffont *w32_init_bdf_font(char *filename);
39 39
40 cache_bitmap cached_bitmap_slots[BDF_FONT_CACHE_SIZE];
41 cache_bitmap *pcached_bitmap_latest = cached_bitmap_slots;
42
43 #define FONT_CACHE_SLOT_OVER_P(p) \
44 ((p) >= cached_bitmap_slots + BDF_FONT_CACHE_SIZE)
45
40 static int 46 static int
41 search_file_line(char *key, char *start, int len, char **val, char **next) 47 search_file_line(char *key, char *start, int len, char **val, char **next)
42 { 48 {
43 int linelen; 49 int linelen;
44 unsigned char *p, *q; 50 unsigned char *p, *q;
73 79
74 if (flag == -1) return 0; 80 if (flag == -1) return 0;
75 return 1; 81 return 1;
76 } 82 }
77 83
84 char*
85 get_quoted_string(char *start, char *end)
86 {
87 char *p, *q, *result;
88
89 p = memchr(start, '\"', end - start);
90 q = 0;
91
92 if (!p) return NULL;
93 p++;
94 q = memchr(p, '\"', end - q);
95 if (!q) return NULL;
96
97 result = (char*) xmalloc(q - p + 1);
98
99 memcpy(result, p, q - p);
100 result[q - p] = '\0';
101
102 return result;
103 }
104
78 static int 105 static int
79 set_bdf_font_info(bdffont *fontp) 106 set_bdf_font_info(bdffont *fontp)
80 { 107 {
81 unsigned char *start, *p, *q; 108 unsigned char *start, *p, *q;
82 int len, flag; 109 int len, flag;
87 start = fontp->font; 114 start = fontp->font;
88 115
89 fontp->yoffset = 0; 116 fontp->yoffset = 0;
90 fontp->relative_compose = 0; 117 fontp->relative_compose = 0;
91 fontp->default_ascent = 0; 118 fontp->default_ascent = 0;
119 fontp->registry = NULL;
120 fontp->encoding = NULL;
121 fontp->slant = NULL;
122 /* fontp->width = NULL; */
92 123
93 flag = proceed_file_line("FONTBOUNDINGBOX", start, &len, &p, &q); 124 flag = proceed_file_line("FONTBOUNDINGBOX", start, &len, &p, &q);
94 if (!flag) return 0; 125 if (!flag) return 0;
95 bbw = strtol(p, &start, 10); 126 bbw = strtol(p, &start, 10);
96 p = start; 127 p = start;
108 fontp->height = bbh; 139 fontp->height = bbh;
109 start = q; 140 start = q;
110 flag = proceed_file_line("STARTPROPERTIES", start, &len, &p, &q); 141 flag = proceed_file_line("STARTPROPERTIES", start, &len, &p, &q);
111 if (!flag) return 1; 142 if (!flag) return 1;
112 143
144 flag = 0;
145
113 do { 146 do {
114 start = q; 147 start = q;
115 if (search_file_line("PIXEL_SIZE", start, len, &p, &q) == 1) 148 if (search_file_line("PIXEL_SIZE", start, len, &p, &q) == 1)
116 { 149 {
117 val1 = atoi(p); 150 val1 = atoi(p);
140 else if (search_file_line("_MULE_DEFAULT_ASCENT", start, len, &p, &q) == 1) 173 else if (search_file_line("_MULE_DEFAULT_ASCENT", start, len, &p, &q) == 1)
141 { 174 {
142 val1 = atoi(p); 175 val1 = atoi(p);
143 fontp->default_ascent = val1; 176 fontp->default_ascent = val1;
144 } 177 }
178 else if (search_file_line("CHARSET_REGISTRY", start, len, &p, &q) == 1)
179 {
180 fontp->registry = get_quoted_string(p, q);
181 }
182 else if (search_file_line("CHARSET_ENCODING", start, len, &p, &q) == 1)
183 {
184 fontp->encoding = get_quoted_string(p, q);
185 }
186 else if (search_file_line("SLANT", start, len, &p, &q) == 1)
187 {
188 fontp->slant = get_quoted_string(p, q);
189 }
190 /*
191 else if (search_file_line("SETWIDTH_NAME", start, len, &p, &q) == 1)
192 {
193 fontp->width = get_quoted_string(p, q);
194 }
195 */
145 else 196 else
146 { 197 {
147 flag = search_file_line("ENDPROPERTIES", start, len, &p, &q); 198 flag = search_file_line("ENDPROPERTIES", start, len, &p, &q);
148 } 199 }
149 if (flag == -1) return 0; 200 if (flag == -1) return 0;
193 } 244 }
194 245
195 bdffontp = (bdffont *) xmalloc(sizeof(bdffont)); 246 bdffontp = (bdffont *) xmalloc(sizeof(bdffont));
196 247
197 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++) 248 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
198 bdffontp->offset[i] = NULL; 249 bdffontp->chtbl[i] = NULL;
199 bdffontp->size = fileinfo.nFileSizeLow; 250 bdffontp->size = fileinfo.nFileSizeLow;
200 bdffontp->font = font; 251 bdffontp->font = font;
201 bdffontp->hfile = hfile; 252 bdffontp->hfile = hfile;
202 bdffontp->hfilemap = hfilemap; 253 bdffontp->hfilemap = hfilemap;
203 bdffontp->filename = (char*) xmalloc(strlen(filename) + 1); 254 bdffontp->filename = (char*) xmalloc(strlen(filename) + 1);
212 } 263 }
213 264
214 void 265 void
215 w32_free_bdf_font(bdffont *fontp) 266 w32_free_bdf_font(bdffont *fontp)
216 { 267 {
217 int i; 268 int i, j;
269 font_char *pch;
270 cache_bitmap *pcb;
218 271
219 UnmapViewOfFile(fontp->hfilemap); 272 UnmapViewOfFile(fontp->hfilemap);
220 CloseHandle(fontp->hfilemap); 273 CloseHandle(fontp->hfilemap);
221 CloseHandle(fontp->hfile); 274 CloseHandle(fontp->hfile);
275
276 if (fontp->registry) xfree(fontp->registry);
277 if (fontp->encoding) xfree(fontp->encoding);
278 if (fontp->slant) xfree(fontp->slant);
279 /* if (fontp->width) xfree(fontp->width); */
280
222 xfree(fontp->filename); 281 xfree(fontp->filename);
223 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++) 282 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
224 { 283 {
225 if (fontp->offset[i]) xfree(fontp->offset[i]); 284 pch = fontp->chtbl[i];
285 if (pch)
286 {
287 for (j = 0;j < BDF_SECOND_OFFSET_TABLE;j++)
288 {
289 pcb = pch[j].pcbmp;
290 if (pcb) pcb->psrc = NULL;
291 }
292 xfree(pch);
293 }
226 } 294 }
227 xfree(fontp); 295 xfree(fontp);
228 } 296 }
229 297
230 static unsigned char* 298 static font_char*
231 get_cached_char_offset(bdffont *fontp, int index) 299 get_cached_font_char(bdffont *fontp, int index)
232 { 300 {
233 unsigned char **offset1; 301 font_char *pch, *result;
234 unsigned char *offset2;
235 int i; 302 int i;
236 303
237 if (index > 0xffff) 304 if (index > 0xffff)
238 return NULL; 305 return NULL;
239 306
240 offset1 = fontp->offset[BDF_FIRST_OFFSET(index)]; 307 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
241 if (!offset1) 308 if (!pch)
242 return NULL; 309 return NULL;
243 offset2 = offset1[BDF_SECOND_OFFSET(index)]; 310 result = &pch[BDF_SECOND_OFFSET(index)];
244 311
245 if (offset2) return offset2; 312 if (!result->offset) return NULL;
246 313
247 return NULL; 314 return result;
248 } 315 }
249 316
250 static void 317 static font_char*
251 cache_char_offset(bdffont *fontp, int index, unsigned char *offset) 318 cache_char_offset(bdffont *fontp, int index, unsigned char *offset)
252 { 319 {
253 unsigned char **offset1; 320 font_char *pch, *result;
254 int i; 321 int i;
255 322
256 if (index > 0xffff) 323 if (index > 0xffff)
257 return; 324 return NULL;
258 325
259 offset1 = fontp->offset[BDF_FIRST_OFFSET(index)]; 326 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
260 if (!offset1) 327 if (!pch)
261 { 328 {
262 offset1 = fontp->offset[BDF_FIRST_OFFSET(index)] = 329 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)] =
263 (unsigned char **) xmalloc(sizeof(unsigned char*) * 330 (font_char*) xmalloc(sizeof(font_char) *
264 BDF_SECOND_OFFSET_TABLE); 331 BDF_SECOND_OFFSET_TABLE);
265 memset(offset1, 0, sizeof(unsigned char*) * BDF_SECOND_OFFSET_TABLE); 332 memset(pch, 0, sizeof(font_char) * BDF_SECOND_OFFSET_TABLE);
266 } 333 }
267 offset1[BDF_SECOND_OFFSET(index)] = offset; 334
268 335 result = &pch[BDF_SECOND_OFFSET(index)];
269 return; 336 result->offset = offset;
270 } 337
271 338 return result;
272 static unsigned char* 339 }
273 seek_char_offset(bdffont *fontp, int index) 340
274 { 341 static font_char*
342 seek_char(bdffont *fontp, int index)
343 {
344 font_char *result;
275 int len, flag, font_index; 345 int len, flag, font_index;
276 unsigned char *start, *p, *q; 346 unsigned char *start, *p, *q;
277 347
278 if (!fontp->seeked) return NULL; 348 if (!fontp->seeked) return NULL;
279 349
286 { 356 {
287 fontp->seeked = NULL; 357 fontp->seeked = NULL;
288 return NULL; 358 return NULL;
289 } 359 }
290 font_index = atoi(p); 360 font_index = atoi(p);
291 cache_char_offset(fontp, font_index, q); 361 result = cache_char_offset(fontp, font_index, q);
292 start = q; 362 if (!result) return NULL;
363
364 start = result->offset;
293 } while (font_index != index); 365 } while (font_index != index);
294 fontp->seeked = q; 366 fontp->seeked = start;
295 367
296 return q; 368 return result;
369 }
370
371 void
372 clear_cached_bitmap_slots()
373 {
374 int i;
375 cache_bitmap *p;
376
377 p = pcached_bitmap_latest;
378 for (i = 0;i < BDF_FONT_CLEAR_SIZE;i++)
379 {
380 if (p->psrc)
381 {
382 DeleteObject(p->hbmp);
383 p->psrc->pcbmp = NULL;
384 p->psrc = NULL;
385 }
386 p++;
387 if (FONT_CACHE_SLOT_OVER_P(p))
388 p = cached_bitmap_slots;
389 }
297 } 390 }
298 391
299 #define GET_HEX_VAL(x) ((isdigit(x)) ? ((x) - '0') : \ 392 #define GET_HEX_VAL(x) ((isdigit(x)) ? ((x) - '0') : \
300 (((x) >= 'A') && ((x) <= 'Z')) ? ((x) - 'A' + 10) : \ 393 (((x) >= 'A') && ((x) <= 'Z')) ? ((x) - 'A' + 10) : \
301 (((x) >= 'a') && ((x) <= 'z')) ? ((x) - 'a' + 10) : \ 394 (((x) >= 'a') && ((x) <= 'z')) ? ((x) - 'a' + 10) : \
302 (-1)) 395 (-1))
303 396
304 int 397 int
305 w32_get_bdf_glyph(bdffont *fontp, int index, int size, glyph_struct *glyph) 398 w32_get_bdf_glyph(bdffont *fontp, int index, int size, glyph_struct *glyph)
306 { 399 {
400 font_char *pch;
307 unsigned char *start, *p, *q, *bitmapp; 401 unsigned char *start, *p, *q, *bitmapp;
308 unsigned char val1, val2; 402 unsigned char val1, val2;
309 int i, j, len, flag; 403 int i, j, len, flag;
310 404
311 start = get_cached_char_offset(fontp, index); 405 pch = get_cached_font_char(fontp, index);
312 if (!start) 406 if (!pch)
313 start = seek_char_offset(fontp, index); 407 {
314 if (!start) 408 pch = seek_char(fontp, index);
315 return 0; 409 if (!pch)
410 return 0;
411 }
412
413 start = pch->offset;
414
415 if ((size == 0) && pch->pcbmp)
416 {
417 glyph->metric = pch->pcbmp->metric;
418 return 1;
419 }
316 420
317 len = fontp->size - (start - fontp->font); 421 len = fontp->size - (start - fontp->font);
318 422
319 flag = proceed_file_line("DWIDTH", start, &len, &p, &q); 423 flag = proceed_file_line("DWIDTH", start, &len, &p, &q);
320 if (!flag) 424 if (!flag)
321 return 0; 425 return 0;
322 glyph->dwidth = atoi(p); 426 glyph->metric.dwidth = atoi(p);
323 427
324 start = q; 428 start = q;
325 flag = proceed_file_line("BBX", start, &len, &p, &q); 429 flag = proceed_file_line("BBX", start, &len, &p, &q);
326 if (!flag) 430 if (!flag)
327 return 0; 431 return 0;
328 glyph->bbw = strtol(p, &start, 10); 432 glyph->metric.bbw = strtol(p, &start, 10);
329 p = start; 433 p = start;
330 glyph->bbh = strtol(p, &start, 10); 434 glyph->metric.bbh = strtol(p, &start, 10);
331 p = start; 435 p = start;
332 glyph->bbox = strtol(p, &start, 10); 436 glyph->metric.bbox = strtol(p, &start, 10);
333 p = start; 437 p = start;
334 glyph->bboy = strtol(p, &start, 10); 438 glyph->metric.bboy = strtol(p, &start, 10);
335 439
336 if (size == 0) return 1; 440 if (size == 0) return 1;
337 441
338 start = q; 442 start = q;
339 flag = proceed_file_line("BITMAP", start, &len, &p, &q); 443 flag = proceed_file_line("BITMAP", start, &len, &p, &q);
340 if (!flag) 444 if (!flag)
341 return 0; 445 return 0;
342 446
343 p = q; 447 p = q;
344 bitmapp = glyph->bitmap; 448 bitmapp = glyph->bitmap;
345 for(i = 0;i < glyph->bbh;i++) 449 for(i = 0;i < glyph->metric.bbh;i++)
346 { 450 {
347 q = memchr(p, '\n', len); 451 q = memchr(p, '\n', len);
348 if (!q) return 0; 452 if (!q) return 0;
349 for(j = 0;((q > p) && (j < ((glyph->bbw + 7) / 8 )));j++) 453 for(j = 0;((q > p) && (j < ((glyph->metric.bbw + 7) / 8 )));j++)
350 { 454 {
351 val1 = GET_HEX_VAL(*p); 455 val1 = GET_HEX_VAL(*p);
352 if (val1 == -1) return 0; 456 if (val1 == -1) return 0;
353 p++; 457 p++;
354 val2 = GET_HEX_VAL(*p); 458 val2 = GET_HEX_VAL(*p);
368 } 472 }
369 473
370 return 1; 474 return 1;
371 } 475 }
372 476
477 static
478 cache_bitmap*
479 get_bitmap_with_cache(bdffont *fontp, int index)
480 {
481 int bitmap_size;
482 font_char *pch;
483 cache_bitmap* pcb;
484 HBITMAP hbmp;
485 glyph_struct glyph;
486
487 pch = get_cached_font_char(fontp, index);
488 if (pch)
489 {
490 pcb = pch->pcbmp;
491 if (pcb) return pcb;
492 }
493
494 bitmap_size = ((fontp->urx - fontp->llx) / 8 + 2) * (fontp->ury - fontp->lly)
495 + 256;
496 glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
497
498 if (!w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph))
499 return NULL;
500
501 pch = get_cached_font_char(fontp, index);
502 if (!pch) return NULL;
503
504 hbmp = CreateBitmap(glyph.metric.bbw, glyph.metric.bbh, 1, 1, glyph.bitmap);
505
506 pcb = pcached_bitmap_latest;
507 if (pcb->psrc)
508 clear_cached_bitmap_slots();
509
510 pcb->psrc = pch;
511 pcb->metric = glyph.metric;
512 pcb->hbmp = hbmp;
513
514 pch->pcbmp = pcb;
515
516 pcached_bitmap_latest++;
517 if (FONT_CACHE_SLOT_OVER_P(pcached_bitmap_latest))
518 pcached_bitmap_latest = cached_bitmap_slots;
519
520 return pcb;
521 }
522
373 int 523 int
374 w32_BDF_TextOut(bdffont *fontp, HDC hdc, int left, 524 w32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
375 int top, unsigned char *text, int dim, int bytelen, 525 int top, unsigned char *text, int dim, int bytelen,
376 int fixed_pitch_size) 526 int fixed_pitch_size)
377 { 527 {
378 int bitmap_size, index, btop; 528 int index, btop;
379 unsigned char *textp; 529 unsigned char *textp;
380 glyph_struct glyph;
381 HDC hCompatDC = 0; 530 HDC hCompatDC = 0;
531 cache_bitmap *pcb;
382 HBITMAP hBMP; 532 HBITMAP hBMP;
383 HBRUSH hFgBrush, hOrgBrush; 533 HBRUSH hFgBrush, hOrgBrush;
384 HANDLE holdobj, horgobj = 0; 534 HANDLE horgobj = 0;
385 UINT textalign; 535 UINT textalign;
386 int flag = 0; 536 int flag = 0;
387
388 bitmap_size = ((fontp->urx - fontp->llx) / 8 + 2) * (fontp->ury - fontp->lly)
389 + 256;
390
391 glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
392 537
393 hCompatDC = CreateCompatibleDC(hdc); 538 hCompatDC = CreateCompatibleDC(hdc);
394 539
395 textalign = GetTextAlign(hdc); 540 textalign = GetTextAlign(hdc);
396 541
414 bytelen -= 2; 559 bytelen -= 2;
415 if (bytelen < 0) break; 560 if (bytelen < 0) break;
416 index = MAKELENDSHORT(textp[1], textp[0]); 561 index = MAKELENDSHORT(textp[1], textp[0]);
417 textp += 2; 562 textp += 2;
418 } 563 }
419 if (!w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph)) 564 pcb = get_bitmap_with_cache(fontp, index);
565 if (!pcb)
420 { 566 {
421 if (horgobj) 567 if (horgobj)
422 { 568 {
423 SelectObject(hCompatDC, horgobj); 569 SelectObject(hCompatDC, horgobj);
424 DeleteObject(hBMP); 570 DeleteObject(hBMP);
425 } 571 }
426 DeleteDC(hCompatDC); 572 DeleteDC(hCompatDC);
427 return 0; 573 return 0;
428 } 574 }
429 hBMP = CreateBitmap(glyph.bbw, glyph.bbh, 1, 1, glyph.bitmap); 575 hBMP = pcb->hbmp;
576
430 if (textalign & TA_BASELINE) 577 if (textalign & TA_BASELINE)
431 { 578 btop = top - (pcb->metric.bbh + pcb->metric.bboy);
432 btop = top - (glyph.bbh + glyph.bboy);
433 }
434 else if (textalign & TA_BOTTOM) 579 else if (textalign & TA_BOTTOM)
435 { 580 btop = top - pcb->metric.bbh;
436 btop = top - glyph.bbh;
437 }
438 else 581 else
439 {
440 btop = top; 582 btop = top;
441 }
442 583
443 if (horgobj) 584 if (horgobj)
444 {
445 SelectObject(hCompatDC, hBMP); 585 SelectObject(hCompatDC, hBMP);
446 DeleteObject(holdobj);
447 holdobj = hBMP;
448 }
449 else 586 else
450 {
451 horgobj = SelectObject(hCompatDC, hBMP); 587 horgobj = SelectObject(hCompatDC, hBMP);
452 holdobj = hBMP;
453 }
454 #if 0 588 #if 0
455 BitBlt(hdc, left, btop, glyph.bbw, glyph.bbh, hCompatDC, 0, 0, SRCCOPY); 589 BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, SRCCOPY);
456 #else 590 #else
457 BitBlt(hdc, left, btop, glyph.bbw, glyph.bbh, hCompatDC, 0, 0, 0xB8074A); 591 BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, 0xB8074A);
458 #endif 592 #endif
459 if (fixed_pitch_size) 593 if (fixed_pitch_size)
460 left += fixed_pitch_size; 594 left += fixed_pitch_size;
461 else 595 else
462 left += glyph.dwidth; 596 left += pcb->metric.dwidth;
463 } 597 }
464 SelectObject(hCompatDC, horgobj); 598 SelectObject(hCompatDC, horgobj);
465 SelectObject(hdc, hOrgBrush); 599 SelectObject(hdc, hOrgBrush);
466 DeleteObject(hFgBrush); 600 DeleteObject(hFgBrush);
467 DeleteObject(hBMP);
468 DeleteDC(hCompatDC); 601 DeleteDC(hCompatDC);
469 RestoreDC(hdc, -1); 602 RestoreDC(hdc, -1);
470 603
471 return 1; 604 return 1;
472 } 605 }