(Fexpand_abbrev): Remove unused variables.
[bpt/emacs.git] / src / w32bdf.c
CommitLineData
7b416d42
GV
1/* Implementation of BDF font handling on the Microsoft W32 API.
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, 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 "fontset.h"
29#include "blockinput.h"
30#include "w32gui.h"
31#include "w32term.h"
32#include "w32bdf.h"
33
34#define min(a, b) ((a) < (b) ? (a) : (b))
35#define max(a, b) ((a) > (b) ? (a) : (b))
36
9c332a80
JR
37/* Portion of GDI Objects which the font cache is allowed to use. This
38 can be quite high, since the font cache is the only part of Emacs
39 that uses a large number of GDI objects, but there should still be
40 some GDI objects reserved for other uses. */
41#define CACHE_GDI_ALLOWANCE 9 / 10
42
7b416d42
GV
43void w32_free_bdf_font(bdffont *fontp);
44bdffont *w32_init_bdf_font(char *filename);
45
46static int
47search_file_line(char *key, char *start, int len, char **val, char **next)
48{
49 int linelen;
50 unsigned char *p, *q;
51
52 p = memchr(start, '\n', len);
53 if (!p) return -1;
54 for (;start < p;start++)
55 {
56 if ((*start != ' ') || (*start != '\t')) break;
57 }
58 linelen = p - start + 1;
59 *next = p + 1;
60 if (strncmp(start, key, min(strlen(key), linelen)) == 0)
61 {
62 *val = start + strlen(key);
63 return 1;
64 }
65
66 return 0;
67}
68
69static int
70proceed_file_line(char *key, char *start, int *len, char **val, char **next)
71{
72 int flag = 0;
73
74 do {
75 flag = search_file_line(key, start, *len, val, next);
76 *len -= (int)(*next - start);
77 start = *next;
78 }while(flag == 0);
79
80 if (flag == -1) return 0;
81 return 1;
82}
83
865203c3
GV
84char*
85get_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
7b416d42
GV
105static int
106set_bdf_font_info(bdffont *fontp)
107{
108 unsigned char *start, *p, *q;
109 int len, flag;
110 int bbw, bbh, bbx, bby;
111 int val1;
112
113 len = fontp->size;
114 start = fontp->font;
115
116 fontp->yoffset = 0;
117 fontp->relative_compose = 0;
118 fontp->default_ascent = 0;
865203c3
GV
119 fontp->registry = NULL;
120 fontp->encoding = NULL;
121 fontp->slant = NULL;
122/* fontp->width = NULL; */
7b416d42
GV
123
124 flag = proceed_file_line("FONTBOUNDINGBOX", start, &len, &p, &q);
125 if (!flag) return 0;
126 bbw = strtol(p, &start, 10);
127 p = start;
128 bbh = strtol(p, &start, 10);
129 p = start;
130 bbx = strtol(p, &start, 10);
131 p = start;
132 bby = strtol(p, &start, 10);
133
134 fontp->llx = bbx;
135 fontp->lly = bby;
136 fontp->urx = bbw + bbx;
137 fontp->ury = bbh + bby;
138 fontp->width = bbw;
139 fontp->height = bbh;
140 start = q;
141 flag = proceed_file_line("STARTPROPERTIES", start, &len, &p, &q);
142 if (!flag) return 1;
143
865203c3
GV
144 flag = 0;
145
7b416d42
GV
146 do {
147 start = q;
148 if (search_file_line("PIXEL_SIZE", start, len, &p, &q) == 1)
149 {
150 val1 = atoi(p);
151 fontp->pixsz = val1;
152 }
153 else if (search_file_line("FONT_ASCENT", start, len, &p, &q) == 1)
154 {
155 val1 = atoi(p);
156 fontp->ury = val1;
157 }
158 else if (search_file_line("FONT_DESCENT", start, len, &p, &q) == 1)
159 {
160 val1 = atoi(p);
161 fontp->lly = -val1;
162 }
163 else if (search_file_line("_MULE_BASELINE_OFFSET", start, len, &p, &q) == 1)
164 {
165 val1 = atoi(p);
166 fontp->yoffset = val1;
167 }
168 else if (search_file_line("_MULE_RELATIVE_COMPOSE", start, len, &p, &q) == 1)
169 {
170 val1 = atoi(p);
171 fontp->relative_compose = val1;
172 }
173 else if (search_file_line("_MULE_DEFAULT_ASCENT", start, len, &p, &q) == 1)
174 {
175 val1 = atoi(p);
176 fontp->default_ascent = val1;
177 }
865203c3
GV
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*/
7b416d42
GV
196 else
197 {
198 flag = search_file_line("ENDPROPERTIES", start, len, &p, &q);
199 }
200 if (flag == -1) return 0;
201 len -= (q - start);
202 }while(flag == 0);
203 start = q;
204 flag = proceed_file_line("CHARS", start, &len, &p, &q);
205 if (!flag) return 0;
206 fontp->seeked = q;
207
208 return 1;
209}
210
211bdffont*
212w32_init_bdf_font(char *filename)
213{
214 HANDLE hfile, hfilemap;
215 bdffont *bdffontp;
216 unsigned char *font;
217 BY_HANDLE_FILE_INFORMATION fileinfo;
218 int i;
219
220 hfile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
221 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
222 if (hfile == INVALID_HANDLE_VALUE) return NULL;
223 if (!GetFileInformationByHandle(hfile, &fileinfo) ||
224 (fileinfo.nFileSizeHigh != 0) ||
225 (fileinfo.nFileSizeLow > BDF_FILE_SIZE_MAX))
226 {
227 CloseHandle(hfile);
228 error("Fail to open BDF file.");
229 }
230 hfilemap = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
231 if (hfilemap == INVALID_HANDLE_VALUE)
232 {
233 CloseHandle(hfile);
234 error("Can't map font.");
235 }
236
237 font = MapViewOfFile(hfilemap, FILE_MAP_READ, 0, 0, 0);
238
239 if (!font)
240 {
241 CloseHandle(hfile);
242 CloseHandle(hfilemap);
243 error("Can't view font.");
244 }
245
246 bdffontp = (bdffont *) xmalloc(sizeof(bdffont));
247
248 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
865203c3 249 bdffontp->chtbl[i] = NULL;
7b416d42
GV
250 bdffontp->size = fileinfo.nFileSizeLow;
251 bdffontp->font = font;
252 bdffontp->hfile = hfile;
253 bdffontp->hfilemap = hfilemap;
254 bdffontp->filename = (char*) xmalloc(strlen(filename) + 1);
255 strcpy(bdffontp->filename, filename);
256
257 if (!set_bdf_font_info(bdffontp))
258 {
259 w32_free_bdf_font(bdffontp);
260 error("Invalid BDF font!");
261 }
262 return bdffontp;
263}
264
265void
266w32_free_bdf_font(bdffont *fontp)
267{
865203c3
GV
268 int i, j;
269 font_char *pch;
270 cache_bitmap *pcb;
7b416d42
GV
271
272 UnmapViewOfFile(fontp->hfilemap);
273 CloseHandle(fontp->hfilemap);
274 CloseHandle(fontp->hfile);
865203c3
GV
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
7b416d42
GV
281 xfree(fontp->filename);
282 for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
283 {
865203c3
GV
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 }
7b416d42
GV
294 }
295 xfree(fontp);
296}
297
865203c3
GV
298static font_char*
299get_cached_font_char(bdffont *fontp, int index)
7b416d42 300{
865203c3 301 font_char *pch, *result;
7b416d42
GV
302 int i;
303
304 if (index > 0xffff)
305 return NULL;
306
865203c3
GV
307 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
308 if (!pch)
7b416d42 309 return NULL;
865203c3 310 result = &pch[BDF_SECOND_OFFSET(index)];
7b416d42 311
865203c3 312 if (!result->offset) return NULL;
7b416d42 313
865203c3 314 return result;
7b416d42
GV
315}
316
865203c3 317static font_char*
7b416d42
GV
318cache_char_offset(bdffont *fontp, int index, unsigned char *offset)
319{
865203c3 320 font_char *pch, *result;
7b416d42
GV
321 int i;
322
323 if (index > 0xffff)
865203c3 324 return NULL;
7b416d42 325
865203c3
GV
326 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)];
327 if (!pch)
7b416d42 328 {
865203c3
GV
329 pch = fontp->chtbl[BDF_FIRST_OFFSET(index)] =
330 (font_char*) xmalloc(sizeof(font_char) *
7b416d42 331 BDF_SECOND_OFFSET_TABLE);
865203c3 332 memset(pch, 0, sizeof(font_char) * BDF_SECOND_OFFSET_TABLE);
7b416d42 333 }
7b416d42 334
865203c3
GV
335 result = &pch[BDF_SECOND_OFFSET(index)];
336 result->offset = offset;
337
338 return result;
7b416d42
GV
339}
340
865203c3
GV
341static font_char*
342seek_char(bdffont *fontp, int index)
7b416d42 343{
865203c3 344 font_char *result;
7b416d42
GV
345 int len, flag, font_index;
346 unsigned char *start, *p, *q;
347
348 if (!fontp->seeked) return NULL;
349
350 start = fontp->seeked;
351 len = fontp->size - (start - fontp->font);
352
353 do {
354 flag = proceed_file_line("ENCODING", start, &len, &p, &q);
355 if (!flag)
356 {
357 fontp->seeked = NULL;
358 return NULL;
359 }
360 font_index = atoi(p);
865203c3
GV
361 result = cache_char_offset(fontp, font_index, q);
362 if (!result) return NULL;
363
364 start = result->offset;
7b416d42 365 } while (font_index != index);
865203c3 366 fontp->seeked = start;
7b416d42 367
865203c3
GV
368 return result;
369}
370
7b416d42
GV
371#define GET_HEX_VAL(x) ((isdigit(x)) ? ((x) - '0') : \
372 (((x) >= 'A') && ((x) <= 'Z')) ? ((x) - 'A' + 10) : \
373 (((x) >= 'a') && ((x) <= 'z')) ? ((x) - 'a' + 10) : \
374 (-1))
375
376int
377w32_get_bdf_glyph(bdffont *fontp, int index, int size, glyph_struct *glyph)
378{
865203c3 379 font_char *pch;
7b416d42
GV
380 unsigned char *start, *p, *q, *bitmapp;
381 unsigned char val1, val2;
382 int i, j, len, flag;
383
865203c3
GV
384 pch = get_cached_font_char(fontp, index);
385 if (!pch)
386 {
387 pch = seek_char(fontp, index);
388 if (!pch)
389 return 0;
390 }
391
392 start = pch->offset;
393
394 if ((size == 0) && pch->pcbmp)
395 {
396 glyph->metric = pch->pcbmp->metric;
397 return 1;
398 }
7b416d42
GV
399
400 len = fontp->size - (start - fontp->font);
401
402 flag = proceed_file_line("DWIDTH", start, &len, &p, &q);
403 if (!flag)
404 return 0;
865203c3 405 glyph->metric.dwidth = atoi(p);
7b416d42
GV
406
407 start = q;
408 flag = proceed_file_line("BBX", start, &len, &p, &q);
409 if (!flag)
410 return 0;
865203c3 411 glyph->metric.bbw = strtol(p, &start, 10);
7b416d42 412 p = start;
865203c3 413 glyph->metric.bbh = strtol(p, &start, 10);
7b416d42 414 p = start;
865203c3 415 glyph->metric.bbox = strtol(p, &start, 10);
7b416d42 416 p = start;
865203c3 417 glyph->metric.bboy = strtol(p, &start, 10);
7b416d42
GV
418
419 if (size == 0) return 1;
420
421 start = q;
422 flag = proceed_file_line("BITMAP", start, &len, &p, &q);
423 if (!flag)
424 return 0;
425
426 p = q;
427 bitmapp = glyph->bitmap;
865203c3 428 for(i = 0;i < glyph->metric.bbh;i++)
7b416d42
GV
429 {
430 q = memchr(p, '\n', len);
431 if (!q) return 0;
865203c3 432 for(j = 0;((q > p) && (j < ((glyph->metric.bbw + 7) / 8 )));j++)
7b416d42
GV
433 {
434 val1 = GET_HEX_VAL(*p);
435 if (val1 == -1) return 0;
436 p++;
437 val2 = GET_HEX_VAL(*p);
438 if (val2 == -1) return 0;
439 p++;
440 size--;
441 if (size <= 0) return 0;
442 /* NAND Operation. */
443 *bitmapp++ = (unsigned char)~((val1 << 4) | val2);
444 }
445 /* CreateBitmap requires WORD alignment. */
446 if (j % 2)
447 {
448 *bitmapp++ = 0xff;
449 }
450 p = q + 1;
451 }
452
453 return 1;
454}
455
9c332a80
JR
456#define NEXT_CACHE_SLOT(n) (((n) + 1 >= BDF_FONT_CACHE_SIZE) ? 0 : ((n) + 1))
457
865203c3
GV
458static
459cache_bitmap*
460get_bitmap_with_cache(bdffont *fontp, int index)
461{
462 int bitmap_size;
463 font_char *pch;
464 cache_bitmap* pcb;
465 HBITMAP hbmp;
466 glyph_struct glyph;
9c332a80
JR
467 static cache_bitmap cached_bitmap_slots[BDF_FONT_CACHE_SIZE];
468 static int cache_in_slot = 0; /* the next slot to use */
469 static int cache_out_slot = 0; /* the last slot allocated */
470 static int cache_occupancy = 0; /* current cache occupancy */
471 static int cache_limit = BDF_FONT_CACHE_SIZE; /* allowed maximum occupancy */
865203c3
GV
472
473 pch = get_cached_font_char(fontp, index);
474 if (pch)
475 {
476 pcb = pch->pcbmp;
477 if (pcb) return pcb;
478 }
479
480 bitmap_size = ((fontp->urx - fontp->llx) / 8 + 2) * (fontp->ury - fontp->lly)
481 + 256;
482 glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
483
484 if (!w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph))
485 return NULL;
486
487 pch = get_cached_font_char(fontp, index);
488 if (!pch) return NULL;
489
490 hbmp = CreateBitmap(glyph.metric.bbw, glyph.metric.bbh, 1, 1, glyph.bitmap);
491
9c332a80
JR
492 /* if bitmap allocation fails reduce the limit of the occupancy so
493 that we can hope it will not happen again. */
494 if (hbmp == NULL)
495 cache_limit = cache_occupancy * CACHE_GDI_ALLOWANCE;
496
497 /* if cache occupancy reaches at the limit release some cache slots */
498 if (cache_occupancy >= cache_limit)
499 {
500 register int size_to_clear = cache_limit * BDF_FONT_CLEAR_SIZE
501 / BDF_FONT_CACHE_SIZE;
502 for (; size_to_clear; size_to_clear--,
503 cache_out_slot = NEXT_CACHE_SLOT(cache_out_slot))
504 {
505 register cache_bitmap *p = &cached_bitmap_slots[cache_out_slot];
506 if (p->psrc)
507 {
508 DeleteObject(p->hbmp);
509 p->psrc->pcbmp = NULL;
510 p->psrc = NULL;
511 cache_occupancy--;
512 }
513 }
514 }
515
516 if (hbmp == NULL)
517 hbmp = CreateBitmap (glyph.metric.bbw, glyph.metric.bbh,
518 1, 1, glyph.bitmap);
519
520 pcb = &cached_bitmap_slots[cache_in_slot];
865203c3
GV
521
522 pcb->psrc = pch;
523 pcb->metric = glyph.metric;
524 pcb->hbmp = hbmp;
525
526 pch->pcbmp = pcb;
527
9c332a80
JR
528 cache_in_slot = NEXT_CACHE_SLOT(cache_in_slot);
529 cache_occupancy++;
865203c3
GV
530
531 return pcb;
532}
533
7b416d42
GV
534int
535w32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
536 int top, unsigned char *text, int dim, int bytelen,
537 int fixed_pitch_size)
538{
865203c3 539 int index, btop;
7b416d42 540 unsigned char *textp;
7b416d42 541 HDC hCompatDC = 0;
865203c3 542 cache_bitmap *pcb;
7b416d42
GV
543 HBITMAP hBMP;
544 HBRUSH hFgBrush, hOrgBrush;
865203c3 545 HANDLE horgobj = 0;
7b416d42
GV
546 UINT textalign;
547 int flag = 0;
548
7b416d42
GV
549 hCompatDC = CreateCompatibleDC(hdc);
550
551 textalign = GetTextAlign(hdc);
552
553 SaveDC(hdc);
554
555 hFgBrush = CreateSolidBrush(GetTextColor(hdc));
556 hOrgBrush = SelectObject(hdc, hFgBrush);
557 SetTextColor(hdc, RGB(0, 0, 0));
558 SetBkColor(hdc, RGB(0xff, 0xff, 0xff));
559
560 textp = text;
561 while(bytelen > 0)
562 {
563 if (dim == 1)
564 {
565 index = *textp++;
566 bytelen--;
567 }
568 else
569 {
570 bytelen -= 2;
571 if (bytelen < 0) break;
572 index = MAKELENDSHORT(textp[1], textp[0]);
573 textp += 2;
574 }
865203c3
GV
575 pcb = get_bitmap_with_cache(fontp, index);
576 if (!pcb)
7b416d42
GV
577 {
578 if (horgobj)
579 {
580 SelectObject(hCompatDC, horgobj);
581 DeleteObject(hBMP);
582 }
583 DeleteDC(hCompatDC);
584 return 0;
585 }
865203c3
GV
586 hBMP = pcb->hbmp;
587
7b416d42 588 if (textalign & TA_BASELINE)
865203c3 589 btop = top - (pcb->metric.bbh + pcb->metric.bboy);
7b416d42 590 else if (textalign & TA_BOTTOM)
865203c3 591 btop = top - pcb->metric.bbh;
7b416d42 592 else
7b416d42 593 btop = top;
7b416d42
GV
594
595 if (horgobj)
7b416d42 596 SelectObject(hCompatDC, hBMP);
7b416d42 597 else
7b416d42 598 horgobj = SelectObject(hCompatDC, hBMP);
7b416d42 599#if 0
865203c3 600 BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, SRCCOPY);
7b416d42 601#else
865203c3 602 BitBlt(hdc, left, btop, pcb->metric.bbw, pcb->metric.bbh, hCompatDC, 0, 0, 0xB8074A);
7b416d42
GV
603#endif
604 if (fixed_pitch_size)
605 left += fixed_pitch_size;
606 else
865203c3 607 left += pcb->metric.dwidth;
7b416d42
GV
608 }
609 SelectObject(hCompatDC, horgobj);
610 SelectObject(hdc, hOrgBrush);
611 DeleteObject(hFgBrush);
7b416d42
GV
612 DeleteDC(hCompatDC);
613 RestoreDC(hdc, -1);
614
615 return 1;
616}
617
618struct font_info *w32_load_bdf_font (struct frame *f, char *fontname,
619 int size, char* filename)
620{
621 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
622 struct font_info *fontp;
623 XFontStruct *font;
624 bdffont* bdf_font;
625
626 bdf_font = w32_init_bdf_font (filename);
627
628 if (!bdf_font) return NULL;
629
630 font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
631
632 font->bdf = bdf_font;
633 font->hfont = 0;
634
635 /* Do we need to create the table? */
636 if (dpyinfo->font_table_size == 0)
637 {
638 dpyinfo->font_table_size = 16;
639 dpyinfo->font_table
640 = (struct font_info *) xmalloc (dpyinfo->font_table_size
641 * sizeof (struct font_info));
642 }
643 /* Do we need to grow the table? */
644 else if (dpyinfo->n_fonts
645 >= dpyinfo->font_table_size)
646 {
647 dpyinfo->font_table_size *= 2;
648 dpyinfo->font_table
649 = (struct font_info *) xrealloc (dpyinfo->font_table,
650 (dpyinfo->font_table_size
651 * sizeof (struct font_info)));
652 }
653
654 fontp = dpyinfo->font_table + dpyinfo->n_fonts;
655
656 /* Now fill in the slots of *FONTP. */
657 BLOCK_INPUT;
658 fontp->font = font;
659 fontp->font_idx = dpyinfo->n_fonts;
660 fontp->name = (char *) xmalloc (strlen (fontname) + 1);
661 bcopy (fontname, fontp->name, strlen (fontname) + 1);
662 fontp->full_name = fontp->name;
663 fontp->size = FONT_WIDTH (font);
664 fontp->height = FONT_HEIGHT (font);
665
666 /* The slot `encoding' specifies how to map a character
667 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
668 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
669 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
670 0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
671 2:0xA020..0xFF7F). For the moment, we don't know which charset
672 uses this font. So, we set informatoin in fontp->encoding[1]
673 which is never used by any charset. If mapping can't be
674 decided, set FONT_ENCODING_NOT_DECIDED. */
675 fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
676 fontp->baseline_offset = bdf_font->yoffset;
677 fontp->relative_compose = bdf_font->relative_compose;
678 fontp->default_ascent = bdf_font->default_ascent;
679
680 UNBLOCK_INPUT;
681 dpyinfo->n_fonts++;
682 return fontp;
683}
684
685/* Check a file for an XFLD string describing it. */
686int w32_BDF_to_x_font (char *file, char* xstr, int len)
687{
688 HANDLE hfile, hfilemap;
689 BY_HANDLE_FILE_INFORMATION fileinfo;
690 unsigned char *font, *start, *p, *q;
691 int flag, size, retval = 0;
692
693 hfile = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL,
694 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
695 if (hfile == INVALID_HANDLE_VALUE) return 0;
696 if (!GetFileInformationByHandle(hfile, &fileinfo) ||
697 (fileinfo.nFileSizeHigh != 0) ||
698 (fileinfo.nFileSizeLow > BDF_FILE_SIZE_MAX))
699 {
700 CloseHandle (hfile);
701 return 0;
702 }
703 size = fileinfo.nFileSizeLow;
704
705 hfilemap = CreateFileMapping (hfile, NULL, PAGE_READONLY, 0, 0, NULL);
706 if (hfilemap == INVALID_HANDLE_VALUE)
707 {
708 CloseHandle (hfile);
709 return 0;
710 }
711
712 font = MapViewOfFile (hfilemap, FILE_MAP_READ, 0, 0, 0);
713 if (!font)
714 {
715 CloseHandle (hfile);
716 CloseHandle (hfilemap);
717 return 0;
718 }
719 start = font;
720
721 flag = proceed_file_line ("FONT ", start, &size, &p, &q);
722 if (flag)
723 {
724 /* If font provides a description of itself, check it is a
725 full XLFD before accepting it. */
726 int count = 0;
727 char *s;
728
729 for (s = p; s < q; s++)
730 if (*s == '\n')
731 break;
732 else if (*s == '-')
733 count++;
734 if (count == 14 && q - p - 1 <= len)
735 {
736 strncpy (xstr, p, q-p-1);
737 xstr[q-p-1] = '\0';
738 /* Files may have DOS line ends (ie still ^M on end). */
739 if (iscntrl(xstr[q-p-2]))
740 xstr[q-p-2] = '\0';
741
742 retval = 1;
743 }
744 }
745 CloseHandle (hfile);
746 CloseHandle (hfilemap);
747 return retval;
748}