Put doc strings in comments.
[bpt/emacs.git] / src / w32bdf.c
1 /* Implementation of BDF font handling on the Microsoft W32 API.
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 /* Based heavily on code by H. Miyashita for Meadow (a descendant of
22 MULE for W32). */
23
24 #include <windows.h>
25 #include "config.h"
26 #include "lisp.h"
27 #include "charset.h"
28 #include "keyboard.h"
29 #include "frame.h"
30 #include "dispextern.h"
31 #include "fontset.h"
32 #include "blockinput.h"
33 #include "w32gui.h"
34 #include "w32term.h"
35 #include "w32bdf.h"
36
37 /* 10 planes */
38 #define BDF_CODEPOINT_HEAP_INITIAL_SIZE (96 * 10)
39 /* about 96 characters */
40 #define BDF_BITMAP_HEAP_INITIAL_SIZE (64 * 96)
41
42 HANDLE hbdf_cp_heap = INVALID_HANDLE_VALUE;
43 HANDLE hbdf_bmp_heap = INVALID_HANDLE_VALUE;
44
45 void w32_free_bdf_font(bdffont *fontp);
46 bdffont *w32_init_bdf_font(char *filename);
47
48 cache_bitmap cached_bitmap_slots[BDF_FONT_CACHE_SIZE];
49 cache_bitmap *pcached_bitmap_latest = cached_bitmap_slots;
50
51 #define FONT_CACHE_SLOT_OVER_P(p) ((p) >= cached_bitmap_slots + BDF_FONT_CACHE_SIZE)
52
53 static int
54 search_file_line(char *key, char *start, int len, char **val, char **next)
55 {
56 unsigned int linelen;
57 unsigned char *p;
58
59 p = memchr(start, '\n', len);
60 if (!p) return -1;
61 for (;(unsigned char *)start < p;start++)
62 {
63 if ((*start != ' ') && (*start != '\t')) break;
64 }
65 linelen = (char *) p - start + 1;
66 *next = p + 1;
67 if (strncmp(start, key, min(strlen(key), linelen)) == 0)
68 {
69 *val = start + strlen(key);
70 return 1;
71 }
72
73 return 0;
74 }
75
76 static int
77 proceed_file_line(char *key, char *start, int *len, char **val, char **next)
78 {
79 int flag = 0;
80
81 do {
82 flag = search_file_line(key, start, *len, val, next);
83 *len -= (int)(*next - start);
84 start = *next;
85 }while(flag == 0);
86
87 if (flag == -1) return 0;
88 return 1;
89 }
90
91 char*
92 get_quoted_string(char *start, char *end)
93 {
94 char *p, *q, *result;
95
96 p = memchr(start, '\"', end - start);
97 if (!p) return NULL;
98 p++;
99 q = memchr(p, '\"', end - p);
100 if (!q) return NULL;
101
102 result = (char*) xmalloc(q - p + 1);
103
104 memcpy(result, p, q - p);
105 result[q - p] = '\0';
106
107 return result;
108 }
109
110 static int
111 set_bdf_font_info(bdffont *fontp)
112 {
113 unsigned char *start, *p, *q;
114 int len, flag;
115 int bbw, bbh, bbx, bby;
116 int val1;
117
118 len = fontp->size;
119 start = fontp->font;
120
121 fontp->yoffset = 0;
122 fontp->relative_compose = 0;
123 fontp->default_ascent = 0;
124
125 fontp->registry = NULL;
126 fontp->encoding = NULL;
127 fontp->slant = NULL;
128 /* fontp->width = NULL; */
129
130 flag = proceed_file_line("FONTBOUNDINGBOX", start, &len,
131 (char **)&p, (char **)&q);
132 if (!flag) return 0;
133 bbw = strtol(p, (char **)&start, 10);
134 p = start;
135 bbh = strtol(p, (char **)&start, 10);
136 p = start;
137 bbx = strtol(p, (char **)&start, 10);
138 p = start;
139 bby = strtol(p, (char **)&start, 10);
140
141 fontp->llx = bbx;
142 fontp->lly = bby;
143 fontp->urx = bbw + bbx;
144 fontp->ury = bbh + bby;
145 fontp->width = bbw;
146 fontp->height = bbh;
147 start = q;
148 flag = proceed_file_line("STARTPROPERTIES", start, &len,
149 (char **)&p, (char **)&q);
150 if (!flag) return 1;
151
152 flag = 0;
153
154 do {
155 start = q;
156 if (search_file_line("PIXEL_SIZE", start, len,
157 (char **)&p, (char **)&q) == 1)
158 {
159 val1 = atoi(p);
160 fontp->pixsz = val1;
161 }
162 else if (search_file_line("FONT_ASCENT", start, len,
163 (char **)&p, (char **)&q) == 1)
164 {
165 val1 = atoi(p);
166 fontp->ury = val1;
167 }
168 else if (search_file_line("FONT_DESCENT", start, len,
169 (char **)&p, (char **)&q) == 1)
170 {
171 val1 = atoi(p);
172 fontp->lly = -val1;
173 }
174 else if (search_file_line("_MULE_BASELINE_OFFSET", start, len,
175 (char **)&p, (char **)&q) == 1)
176 {
177 val1 = atoi(p);
178 fontp->yoffset = -val1;
179 }
180 else if (search_file_line("_MULE_RELATIVE_COMPOSE", start, len,
181 (char **)&p, (char **)&q) == 1)
182 {
183 val1 = atoi(p);
184 fontp->relative_compose = val1;
185 }
186 else if (search_file_line("_MULE_DEFAULT_ASCENT", start, len,
187 (char **)&p, (char **)&q) == 1)
188 {
189 val1 = atoi(p);
190 fontp->default_ascent = val1;
191 }
192 else if (search_file_line("CHARSET_REGISTRY", start, len,
193 (char **)&p, (char **)&q) == 1)
194 {
195 fontp->registry = get_quoted_string(p, q);
196 }
197 else if (search_file_line("CHARSET_ENCODING", start, len,
198 (char **)&p, (char **)&q) == 1)
199 {
200 fontp->encoding = get_quoted_string(p, q);
201 }
202 else if (search_file_line("SLANT", start, len,
203 (char **)&p, (char **)&q) == 1)
204 {
205 fontp->slant = get_quoted_string(p, q);
206 }
207 /*
208 else if (search_file_line("SETWIDTH_NAME", start, len,
209 (char **)&p, (char **)&q) == 1)
210 {
211 fontp->width = get_quoted_string(p, q);
212 }
213 */
214 else
215 {
216 flag = search_file_line("ENDPROPERTIES", start, len,
217 (char **)&p, (char **)&q);
218 }
219 if (flag == -1) return 0;
220 len -= (q - start);
221 }while(flag == 0);
222 start = q;
223 flag = proceed_file_line("CHARS", start, &len, (char **)&p, (char **)&q);
224 if (!flag) return 0;
225 fontp->nchars = atoi(p);
226 fontp->seeked = q;
227
228 return 1;
229 }
230
231 bdffont*
232 w32_init_bdf_font(char *filename)
233 {
234 HANDLE hfile, hfilemap;
235 bdffont *bdffontp;
236 unsigned char *font;
237 BY_HANDLE_FILE_INFORMATION fileinfo;
238 int i;
239
240 if (hbdf_cp_heap == INVALID_HANDLE_VALUE)
241 hbdf_cp_heap = HeapCreate(0, BDF_CODEPOINT_HEAP_INITIAL_SIZE, 0);
242 if (hbdf_bmp_heap == INVALID_HANDLE_VALUE)
243 hbdf_bmp_heap = HeapCreate(0, BDF_BITMAP_HEAP_INITIAL_SIZE, 0);
244
245 if (!hbdf_cp_heap || !hbdf_bmp_heap)
246 error("Fail to create heap for BDF.");
247
248 hfile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
249 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
250 if (hfile == INVALID_HANDLE_VALUE) return NULL;
251 if (!GetFileInformationByHandle(hfile, &fileinfo) ||
252 (fileinfo.nFileSizeHigh != 0) ||
253 (fileinfo.nFileSizeLow > BDF_FILE_SIZE_MAX))
254 {
255 CloseHandle(hfile);
256 error("Fail to open BDF file.");
257 }
258 hfilemap = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
259 if (hfilemap == INVALID_HANDLE_VALUE)
260 {
261 CloseHandle(hfile);
262 error("Can't map font.");
263 }
264
265 font = MapViewOfFile(hfilemap, FILE_MAP_READ, 0, 0, 0);
266
267 if (!font)
268 {
269 CloseHandle(hfile);
270 CloseHandle(hfilemap);
271 error("Can't view font.");
272 }
273
274 bdffontp = (bdffont *) xmalloc(sizeof(bdffont));
275
276 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
277 bdffontp->chtbl[i] = NULL;
278 bdffontp->size = fileinfo.nFileSizeLow;
279 bdffontp->font = font;
280 bdffontp->hfile = hfile;
281 bdffontp->hfilemap = hfilemap;
282 bdffontp->filename = (char*) xmalloc(strlen(filename) + 1);
283 strcpy(bdffontp->filename, filename);
284
285 if (!set_bdf_font_info(bdffontp))
286 {
287 w32_free_bdf_font(bdffontp);
288 error("Invalid BDF font!");
289 }
290 return bdffontp;
291 }
292
293 void
294 w32_free_bdf_font(bdffont *fontp)
295 {
296 int i, j;
297 font_char *pch;
298 cache_bitmap *pcb;
299
300 UnmapViewOfFile(fontp->hfilemap);
301 CloseHandle(fontp->hfilemap);
302 CloseHandle(fontp->hfile);
303
304 if (fontp->registry) xfree(fontp->registry);
305 if (fontp->encoding) xfree(fontp->encoding);
306 if (fontp->slant) xfree(fontp->slant);
307 /* if (fontp->width) xfree(fontp->width); */
308
309 xfree(fontp->filename);
310 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
311 {
312 pch = fontp->chtbl[i];
313 if (pch)
314 {
315 for (j = 0;j < BDF_SECOND_OFFSET_TABLE;j++)
316 {
317 pcb = pch[j].pcbmp;
318 if (pcb)
319 {
320 if (pcb->pbmp)
321 HeapFree(hbdf_bmp_heap, 0, pcb->pbmp);
322 pcb->psrc = NULL;
323 }
324 }
325 HeapFree(hbdf_cp_heap, 0, pch);
326 }
327 }
328 xfree(fontp);
329 }
330
331 static font_char*
332 get_cached_font_char(bdffont *fontp, int index)
333 {
334 font_char *pch, *result;
335
336 if (!BDF_CODEPOINT_RANGE_COVER_P(index))
337 return NULL;
338
339 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
340 if (!pch)
341 return NULL;
342
343 result = &pch[BDF_SECOND_OFFSET(index)];
344
345 if (!result->offset) return NULL;
346
347 return result;
348 }
349
350 static font_char*
351 cache_char_offset(bdffont *fontp, int index, unsigned char *offset)
352 {
353 font_char *pch, *result;
354
355 if (!BDF_CODEPOINT_RANGE_COVER_P(index))
356 return NULL;
357
358 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
359 if (!pch)
360 {
361 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)] =
362 (font_char*) HeapAlloc(hbdf_cp_heap,
363 HEAP_ZERO_MEMORY,
364 sizeof(font_char) *
365 BDF_SECOND_OFFSET_TABLE);
366 if (!pch) return NULL;
367 /* memset(pch, 0, sizeof(font_char) * BDF_SECOND_OFFSET_TABLE); */
368 }
369
370 result = &pch[BDF_SECOND_OFFSET(index)];
371 result->offset = offset;
372
373 return result;
374 }
375
376 static font_char*
377 seek_char(bdffont *fontp, int index)
378 {
379 font_char *result;
380 int len, flag, font_index;
381 unsigned char *start, *p, *q;
382
383 if (!fontp->seeked) return NULL;
384
385 start = fontp->seeked;
386 len = fontp->size - (start - fontp->font);
387
388 do {
389 flag = proceed_file_line("ENCODING", start, &len,
390 (char **)&p, (char **)&q);
391 if (!flag)
392 {
393 fontp->seeked = NULL;
394 return NULL;
395 }
396 font_index = atoi(p);
397 result = cache_char_offset(fontp, font_index, q);
398 if (!result) return NULL;
399
400 start = result->offset;
401 } while (font_index != index);
402 fontp->seeked = start;
403
404 return result;
405 }
406
407 static void
408 clear_cached_bitmap_slots()
409 {
410 int i;
411 cache_bitmap *p;
412
413 p = pcached_bitmap_latest;
414 for (i = 0;i < BDF_FONT_CLEAR_SIZE;i++)
415 {
416 if (p->psrc)
417 {
418 if (p->pbmp)
419 HeapFree(hbdf_bmp_heap, 0, p->pbmp);
420 p->psrc->pcbmp = NULL;
421 p->psrc = NULL;
422 }
423 p++;
424 if (FONT_CACHE_SLOT_OVER_P(p))
425 p = cached_bitmap_slots;
426 }
427 }
428
429 #define GET_HEX_VAL(x) ((isdigit(x)) ? ((x) - '0') : \
430 (((x) >= 'A') && ((x) <= 'F')) ? ((x) - 'A' + 10) : \
431 (((x) >= 'a') && ((x) <= 'f')) ? ((x) - 'a' + 10) : \
432 (-1))
433
434 int
435 w32_get_bdf_glyph(bdffont *fontp, int index, int size, glyph_struct *glyph)
436 {
437 font_char *pch;
438 unsigned char *start, *p, *q, *bitmapp;
439 unsigned char val, val1, val2;
440 int i, j, len, flag, consumed;
441 int align, rowbytes;
442
443 pch = get_cached_font_char(fontp, index);
444 if (!pch)
445 {
446 pch = seek_char(fontp, index);
447 if (!pch)
448 return 0;
449 }
450
451 start = pch->offset;
452
453 if ((size == 0) && pch->pcbmp)
454 {
455 glyph->metric = pch->pcbmp->metric;
456 return 1;
457 }
458
459 len = fontp->size - (start - fontp->font);
460
461 flag = proceed_file_line("DWIDTH", start, &len, (char **)&p, (char **)&q);
462 if (!flag)
463 return 0;
464 glyph->metric.dwidth = atoi(p);
465
466 start = q;
467 flag = proceed_file_line("BBX", start, &len, (char **)&p, (char **)&q);
468 if (!flag)
469 return 0;
470 glyph->metric.bbw = strtol(p, (char **)&start, 10);
471 p = start;
472 glyph->metric.bbh = strtol(p, (char **)&start, 10);
473 p = start;
474 glyph->metric.bbox = strtol(p, (char **)&start, 10);
475 p = start;
476 glyph->metric.bboy = strtol(p, (char **)&start, 10);
477
478 if (size == 0) return 1;
479
480 start = q;
481 flag = proceed_file_line("BITMAP", start, &len, (char **)&p, (char **)&q);
482 if (!flag)
483 return 0;
484
485 consumed = 0;
486 flag = 0;
487 p = q;
488 bitmapp = glyph->bitmap;
489 rowbytes = (glyph->metric.bbw + 7) / 8;
490 /* DIB requires DWORD alignment. */
491 align = sizeof(DWORD) - rowbytes % sizeof(DWORD);
492 consumed = glyph->metric.bbh * (rowbytes + align);
493 glyph->bitmap_size = consumed;
494 glyph->row_byte_size = rowbytes;
495 if (size < consumed) return 0;
496
497 for(i = 0;i < glyph->metric.bbh;i++)
498 {
499 q = memchr(p, '\n', len);
500 if (!q) return 0;
501 for(j = 0;((q > p) && (j < rowbytes));j++)
502 {
503 int ival = GET_HEX_VAL(*p);
504
505 if (ival == -1) return 0;
506 val1 = ival;
507 p++;
508 ival = GET_HEX_VAL(*p);
509 if (ival == -1) return 0;
510 val2 = ival;
511 p++;
512 val = (unsigned char)((val1 << 4) | val2);
513 if (val) flag = 1;
514 *bitmapp++ = val;
515 }
516 for(j = 0;j < align;j++)
517 *bitmapp++ = 0x00;
518 p = q + 1;
519 }
520
521 /* If this glyph is white space, return -1. */
522 if (flag == 0) return -1;
523
524 return consumed;
525 }
526
527 static
528 cache_bitmap*
529 get_bitmap_with_cache(bdffont *fontp, int index)
530 {
531 int bitmap_size, bitmap_real_size;
532 font_char *pch;
533 cache_bitmap* pcb;
534 unsigned char *pbmp;
535 glyph_struct glyph;
536
537 pch = get_cached_font_char(fontp, index);
538 if (pch)
539 {
540 pcb = pch->pcbmp;
541 if (pcb) return pcb;
542 }
543
544 bitmap_size = ((fontp->urx - fontp->llx) / 8 + 3) * (fontp->ury - fontp->lly)
545 + 256;
546 glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
547
548 bitmap_real_size = w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph);
549
550 if (bitmap_real_size == 0)
551 return NULL;
552
553 pch = get_cached_font_char(fontp, index);
554 if (!pch) return NULL;
555
556 if (bitmap_real_size > 0)
557 {
558 pbmp = (unsigned char*) HeapAlloc(hbdf_bmp_heap, 0,
559 bitmap_real_size);
560 if (!pbmp) return NULL;
561 memcpy(pbmp, glyph.bitmap, bitmap_real_size);
562 }
563 else
564 pbmp = NULL; /* white space character */
565
566 pcb = pcached_bitmap_latest;
567 if (pcb->psrc)
568 clear_cached_bitmap_slots();
569
570 pcb->psrc = pch;
571 pcb->metric = glyph.metric;
572 pcb->pbmp = pbmp;
573 pcb->bitmap_size = glyph.bitmap_size;
574 pcb->row_byte_size = glyph.row_byte_size;
575
576 pch->pcbmp = pcb;
577
578 pcached_bitmap_latest++;
579 if (FONT_CACHE_SLOT_OVER_P(pcached_bitmap_latest))
580 pcached_bitmap_latest = cached_bitmap_slots;
581
582 return pcb;
583 }
584
585 static HBITMAP
586 create_offscreen_bitmap(HDC hdc, int width, int height, unsigned char **bitsp)
587 {
588 struct {
589 BITMAPINFOHEADER h;
590 RGBQUAD c[2];
591 } info;
592
593 memset(&info, 0, sizeof(info));
594 info.h.biSize = sizeof(BITMAPINFOHEADER);
595 info.h.biWidth = width;
596 info.h.biHeight = -height;
597 info.h.biPlanes = 1;
598 info.h.biBitCount = 1;
599 info.h.biCompression = BI_RGB;
600 info.c[1].rgbRed = info.c[1].rgbGreen = info.c[1].rgbBlue = 255;
601
602 return CreateDIBSection(hdc, (LPBITMAPINFO)&info,
603 DIB_RGB_COLORS, bitsp, NULL, 0);
604 }
605
606 glyph_metric *
607 w32_BDF_TextMetric(bdffont *fontp, unsigned char *text, int dim)
608 {
609 int index;
610 cache_bitmap *pcb;
611
612 if (dim == 1)
613 index = *text;
614 else
615 index = MAKELENDSHORT(text[1], text[0]);
616
617 pcb = get_bitmap_with_cache(fontp, index);
618 if (!pcb)
619 return NULL;
620
621 return &(pcb->metric);
622 }
623
624 int
625 w32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
626 int top, unsigned char *text, int dim, int bytelen,
627 int fixed_pitch_size)
628 {
629 int index, btop;
630 unsigned char *textp;
631 cache_bitmap *pcb;
632 HBRUSH hFgBrush, hOrgBrush;
633 HANDLE horgobj;
634 UINT textalign;
635 int width, height;
636 HDC hCompatDC;
637 int ret = 1;
638 static HBITMAP hBMP = 0;
639 static HDC DIBsection_hdc = 0;
640 static int DIBsection_width, DIBsection_height;
641 static unsigned char *bits;
642
643 hCompatDC = CreateCompatibleDC(hdc);
644 if (!hCompatDC)
645 return 0;
646
647 textalign = GetTextAlign(hdc);
648
649 hFgBrush = CreateSolidBrush(GetTextColor(hdc));
650 hOrgBrush = SelectObject(hdc, hFgBrush);
651
652 textp = text;
653
654 while(bytelen > 0)
655 {
656 if (dim == 1)
657 {
658 index = *textp++;
659 bytelen--;
660 }
661 else
662 {
663 bytelen -= 2;
664 if (bytelen < 0) break;
665 index = MAKELENDSHORT(textp[0], textp[1]);
666 textp += 2;
667 }
668 pcb = get_bitmap_with_cache(fontp, index);
669 if (!pcb)
670 {
671 ret = 0;
672 break;
673 }
674 if (pcb->pbmp)
675 {
676 width = pcb->metric.bbw;
677 height = pcb->metric.bbh;
678
679 if (!(hBMP
680 && (DIBsection_hdc == hdc)
681 && (DIBsection_width == width)
682 && (DIBsection_height == height)))
683 {
684 if (hBMP) DeleteObject(hBMP);
685 hBMP = create_offscreen_bitmap(hdc, width, height, &bits);
686 DIBsection_hdc = hdc;
687 DIBsection_width = width;
688 DIBsection_height = height;
689 if (!hBMP) return 0;
690 }
691
692 memcpy(bits, pcb->pbmp, pcb->bitmap_size);
693
694 if (textalign & TA_BASELINE)
695 btop = top - (pcb->metric.bbh + pcb->metric.bboy);
696 else if (textalign & TA_BOTTOM)
697 btop = top - pcb->metric.bbh;
698 else
699 btop = top;
700
701 horgobj = SelectObject(hCompatDC, hBMP);
702 BitBlt(hdc, left, btop, width, height, hCompatDC, 0, 0, 0xE20746);
703 SelectObject(hCompatDC, horgobj);
704 }
705
706 if (fixed_pitch_size)
707 left += fixed_pitch_size;
708 else
709 left += pcb->metric.dwidth;
710 }
711
712 DeleteDC(hCompatDC);
713
714 SelectObject(hdc, hOrgBrush);
715 DeleteObject(hFgBrush);
716
717 return ret;
718 }
719
720 struct font_info *w32_load_bdf_font (struct frame *f, char *fontname,
721 int size, char* filename)
722 {
723 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
724 struct font_info *fontp;
725 XFontStruct *font;
726 bdffont* bdf_font;
727
728 bdf_font = w32_init_bdf_font (filename);
729
730 if (!bdf_font) return NULL;
731
732 font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
733 bzero (font, sizeof (*font));
734
735 font->bdf = bdf_font;
736 font->hfont = 0;
737
738 /* NTEMACS_TODO: Better way of determining if a font is double byte
739 or not. */
740 font->double_byte_p = bdf_font->nchars > 255 ? 1 : 0;
741
742 w32_cache_char_metrics (font);
743
744 /* Do we need to create the table? */
745 if (dpyinfo->font_table_size == 0)
746 {
747 dpyinfo->font_table_size = 16;
748 dpyinfo->font_table
749 = (struct font_info *) xmalloc (dpyinfo->font_table_size
750 * sizeof (struct font_info));
751 }
752 /* Do we need to grow the table? */
753 else if (dpyinfo->n_fonts
754 >= dpyinfo->font_table_size)
755 {
756 dpyinfo->font_table_size *= 2;
757 dpyinfo->font_table
758 = (struct font_info *) xrealloc (dpyinfo->font_table,
759 (dpyinfo->font_table_size
760 * sizeof (struct font_info)));
761 }
762
763 fontp = dpyinfo->font_table + dpyinfo->n_fonts;
764
765 /* Now fill in the slots of *FONTP. */
766 BLOCK_INPUT;
767 fontp->font = font;
768 fontp->font_idx = dpyinfo->n_fonts;
769 fontp->name = (char *) xmalloc (strlen (fontname) + 1);
770 bcopy (fontname, fontp->name, strlen (fontname) + 1);
771 fontp->full_name = fontp->name;
772 fontp->size = FONT_WIDTH (font);
773 fontp->height = FONT_HEIGHT (font);
774
775 /* The slot `encoding' specifies how to map a character
776 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
777 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
778 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
779 0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
780 2:0xA020..0xFF7F). For the moment, we don't know which charset
781 uses this font. So, we set informatoin in fontp->encoding[1]
782 which is never used by any charset. If mapping can't be
783 decided, set FONT_ENCODING_NOT_DECIDED. */
784 fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
785 fontp->baseline_offset = bdf_font->yoffset;
786 fontp->relative_compose = bdf_font->relative_compose;
787 fontp->default_ascent = bdf_font->default_ascent;
788
789 UNBLOCK_INPUT;
790 dpyinfo->n_fonts++;
791 return fontp;
792 }
793
794 /* Check a file for an XFLD string describing it. */
795 int w32_BDF_to_x_font (char *file, char* xstr, int len)
796 {
797 HANDLE hfile, hfilemap;
798 BY_HANDLE_FILE_INFORMATION fileinfo;
799 char *font, *start, *p, *q;
800 int flag, size, retval = 0;
801
802 hfile = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL,
803 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
804 if (hfile == INVALID_HANDLE_VALUE) return 0;
805 if (!GetFileInformationByHandle(hfile, &fileinfo) ||
806 (fileinfo.nFileSizeHigh != 0) ||
807 (fileinfo.nFileSizeLow > BDF_FILE_SIZE_MAX))
808 {
809 CloseHandle (hfile);
810 return 0;
811 }
812 size = fileinfo.nFileSizeLow;
813
814 hfilemap = CreateFileMapping (hfile, NULL, PAGE_READONLY, 0, 0, NULL);
815 if (hfilemap == INVALID_HANDLE_VALUE)
816 {
817 CloseHandle (hfile);
818 return 0;
819 }
820
821 font = MapViewOfFile (hfilemap, FILE_MAP_READ, 0, 0, 0);
822 if (!font)
823 {
824 CloseHandle (hfile);
825 CloseHandle (hfilemap);
826 return 0;
827 }
828 start = font;
829
830 flag = proceed_file_line ("FONT ", start, &size, &p, &q);
831 if (flag)
832 {
833 /* If font provides a description of itself, check it is a
834 full XLFD before accepting it. */
835 int count = 0;
836 char *s;
837
838 for (s = p; s < q; s++)
839 if (*s == '\n')
840 break;
841 else if (*s == '-')
842 count++;
843 if (count == 14 && q - p - 1 <= len)
844 {
845 strncpy (xstr, p, q-p-1);
846 xstr[q-p-1] = '\0';
847 /* Files may have DOS line ends (ie still ^M on end). */
848 if (iscntrl(xstr[q-p-2]))
849 xstr[q-p-2] = '\0';
850
851 retval = 1;
852 }
853 }
854 CloseHandle (hfile);
855 CloseHandle (hfilemap);
856 return retval;
857 }