2 * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 /**************************************************************************
27 * Executable header and font structures.
29 **************************************************************************/
34 unsigned int reshandler;
38 unsigned short offset;
39 unsigned short length;
42 unsigned short handle;
47 unsigned short e_magic;
48 unsigned short e_cblp;
50 unsigned short e_crlc;
51 unsigned short e_cparhdr;
52 unsigned short e_minalloc;
53 unsigned short e_maxalloc;
56 unsigned short e_csum;
59 unsigned short e_lfarlc;
60 unsigned short e_ovno;
61 unsigned short e_res[4];
62 unsigned short e_oemid;
63 unsigned short e_oeminfo;
64 unsigned short e_res2[10];
65 unsigned short e_lfanew;
69 unsigned short ne_magic;
70 unsigned char linker_version;
71 unsigned char linker_revision;
72 unsigned short entry_tab_offset;
73 unsigned short entry_tab_length;
74 unsigned int reserved1;
75 unsigned short format_flags;
76 unsigned short auto_data_seg;
77 unsigned short local_heap_length;
78 unsigned short stack_length;
83 unsigned short n_segment_tab;
84 unsigned short n_mod_ref_tab;
85 unsigned short nrname_tab_length;
86 unsigned short segment_tab_offset;
87 unsigned short resource_tab_offset;
88 unsigned short rname_tab_offset;
89 unsigned short moduleref_tab_offset;
90 unsigned short iname_tab_offset;
91 unsigned int nrname_tab_offset;
92 unsigned short n_mov_entry_points;
93 unsigned short align_shift_count;
94 unsigned short n_resource_seg;
95 unsigned char operating_system;
96 unsigned char additional_flags;
97 unsigned short fastload_offset;
98 unsigned short fastload_length;
99 unsigned short reserved2;
100 unsigned short expect_version;
104 unsigned short dfVersion;
106 unsigned char dfCopyright[60];
107 unsigned short dfType;
108 unsigned short dfPoints;
109 unsigned short dfVertRes;
110 unsigned short dfHorizRes;
111 unsigned short dfAscent;
112 unsigned short dfInternalLeading;
113 unsigned short dfExternalLeading;
114 unsigned char dfItalic;
115 unsigned char dfUnderline;
116 unsigned char dfStrikeOut;
117 unsigned short dfWeight;
118 unsigned char dfCharSet;
119 unsigned short dfPixWidth;
120 unsigned short dfPixHeight;
121 unsigned char dfPitchAndFamily;
122 unsigned short dfAvgWidth;
123 unsigned short dfMaxWidth;
124 unsigned char dfFirstChar;
125 unsigned char dfLastChar;
126 unsigned char dfDefaultChar;
127 unsigned char dfBreakChar;
128 unsigned short dfWidthBytes;
129 unsigned int dfDevice;
131 unsigned int dfBitsPointer;
132 unsigned int dfBitsOffset;
133 unsigned char dfReserved;
134 unsigned int dfFlags;
135 unsigned short dfAspace;
136 unsigned short dfBspace;
137 unsigned short dfCspace;
138 unsigned short dfColorPointer;
139 unsigned char dfReserved1[4];
141 unsigned int dfColorPointer;
142 unsigned char dfReserved1[16];
147 * A structure used to load the font info data before transfering to the
148 * real font structure.
151 unsigned char dfVersion[2];
152 unsigned char dfSize[4];
153 unsigned char dfCopyright[60];
154 unsigned char dfType[2];
155 unsigned char dfPoints[2];
156 unsigned char dfVertRes[2];
157 unsigned char dfHorizRes[2];
158 unsigned char dfAscent[2];
159 unsigned char dfInternalLeading[2];
160 unsigned char dfExternalLeading[2];
161 unsigned char dfItalic[1];
162 unsigned char dfUnderline[1];
163 unsigned char dfStrikeOut[1];
164 unsigned char dfWeight[2];
165 unsigned char dfCharSet[1];
166 unsigned char dfPixWidth[2];
167 unsigned char dfPixHeight[2];
168 unsigned char dfPitchAndFamily[1];
169 unsigned char dfAvgWidth[2];
170 unsigned char dfMaxWidth[2];
171 unsigned char dfFirstChar[1];
172 unsigned char dfLastChar[1];
173 unsigned char dfDefaultChar[1];
174 unsigned char dfBreakChar[1];
175 unsigned char dfWidthBytes[2];
176 unsigned char dfDevice[4];
177 unsigned char dfFace[4];
178 unsigned char dfBitsPointer[4];
179 unsigned char dfBitsOffset[4];
180 unsigned char dfReserved[1];
181 unsigned char dfFlags[4];
182 unsigned char dfAspace[2];
183 unsigned char dfBspace[2];
184 unsigned char dfCspace[2];
186 unsigned char dfColorPointer[4];
187 unsigned char dfReserved1[16];
189 unsigned char dfColorPointer[2];
190 unsigned char dfReserved1[4];
199 * Structure used for opening FON/FNT fonts. Tracks the list of offsets to
200 * the font or fonts in the file.
202 typedef struct _bdffnt_font_t {
205 unsigned int allocated;
210 unsigned int cinfo_used;
211 unsigned int cinfo_size;
216 /**************************************************************************
218 * Local macros and variables.
220 **************************************************************************/
223 * Executable signatures.
225 #define DOS_SIG 0x5a4d
226 #define WIN_SIG 0x454e
231 #define BDFFNT_WEIGHT_DONTCARE 0
232 #define BDFFNT_WEIGHT_THIN 100
233 #define BDFFNT_WEIGHT_EXTRALIGHT 200
234 #define BDFFNT_WEIGHT_ULTRALIGHT 200
235 #define BDFFNT_WEIGHT_LIGHT 300
236 #define BDFFNT_WEIGHT_NORMAL 400
237 #define BDFFNT_WEIGHT_REGULAR 400
238 #define BDFFNT_WEIGHT_MEDIUM 500
239 #define BDFFNT_WEIGHT_SEMIBOLD 600
240 #define BDFFNT_WEIGHT_DEMIBOLD 600
241 #define BDFFNT_WEIGHT_BOLD 700
242 #define BDFFNT_WEIGHT_EXTRABOLD 800
243 #define BDFFNT_WEIGHT_ULTRABOLD 800
244 #define BDFFNT_WEIGHT_HEAVY 900
245 #define BDFFNT_WEIGHT_BLACK 900
248 * Local structures to hold header info.
250 static dos_exe_t dos;
251 static win_exe_t win;
253 /**************************************************************************
257 **************************************************************************/
260 _bdffnt_endian_shorts(unsigned short *sp, unsigned int n)
262 for (; n > 0; n--, sp++)
263 *sp = ((*sp >> 8) & 0xff) |
264 (((*sp & 0xff) << 8) & 0xff00);
268 _bdffnt_endian_ints(unsigned int *lp, unsigned int n)
270 for (; n > 0; n--, lp++)
271 *lp = (((*lp & 0xff) << 24) & 0xff000000) |
272 (((*lp >> 8) << 16) & 0xff0000) |
273 (((*lp >> 16) << 8) & 0xff00) |
274 ((*lp >> 24) & 0xff);
277 static unsigned short
278 _bdffnt_get_short(unsigned char *field)
282 return (field[a] & 0xff) | ((field[b] & 0xff) << 8);
286 _bdffnt_get_int(unsigned char *field)
288 int a = 0, b = 1, c = 2, d = 3;
290 return (field[a] & 0xff) | ((field[b] & 0xff) << 8) |
291 ((field[c] & 0xff) << 16) | ((field[d] & 0xff) << 24);
295 * This routine is called when the font header needs some fields adjusted for
296 * the endianess of the machine.
299 _bdffnt_transfer_fntinfo(fntinfo_t *fi, fishadow_t *fis)
301 fi->dfVersion = _bdffnt_get_short(fis->dfVersion);
302 (void) memcpy(fi->dfCopyright, fis->dfCopyright, 60);
303 fi->dfSize = _bdffnt_get_int(fis->dfSize);
304 fi->dfType = _bdffnt_get_short(fis->dfType);
305 fi->dfPoints = _bdffnt_get_short(fis->dfPoints);
306 fi->dfVertRes = _bdffnt_get_short(fis->dfVertRes);
307 fi->dfHorizRes = _bdffnt_get_short(fis->dfHorizRes);
308 fi->dfAscent = _bdffnt_get_short(fis->dfAscent);
309 fi->dfInternalLeading = _bdffnt_get_short(fis->dfInternalLeading);
310 fi->dfExternalLeading = _bdffnt_get_short(fis->dfExternalLeading);
311 fi->dfItalic = fis->dfItalic[0];
312 fi->dfUnderline = fis->dfUnderline[0];
313 fi->dfStrikeOut = fis->dfStrikeOut[0];
314 fi->dfWeight = _bdffnt_get_short(fis->dfWeight);
315 fi->dfCharSet = fis->dfCharSet[0];
316 fi->dfPixWidth = _bdffnt_get_short(fis->dfPixWidth);
317 fi->dfPixHeight = _bdffnt_get_short(fis->dfPixHeight);
318 fi->dfPitchAndFamily = fis->dfPitchAndFamily[0];
319 fi->dfAvgWidth = _bdffnt_get_short(fis->dfAvgWidth);
320 fi->dfMaxWidth = _bdffnt_get_short(fis->dfMaxWidth);
321 fi->dfFirstChar = fis->dfFirstChar[0];
322 fi->dfLastChar = fis->dfLastChar[0];
323 fi->dfDefaultChar = fis->dfDefaultChar[0];
324 fi->dfBreakChar = fis->dfBreakChar[0];
325 fi->dfWidthBytes = _bdffnt_get_short(fis->dfWidthBytes);
326 fi->dfDevice = _bdffnt_get_int(fis->dfDevice);
327 fi->dfFace = _bdffnt_get_int(fis->dfFace);
328 fi->dfBitsPointer = _bdffnt_get_int(fis->dfBitsPointer);
329 fi->dfBitsOffset = _bdffnt_get_int(fis->dfBitsOffset);
330 fi->dfReserved = fis->dfReserved[0];
331 fi->dfFlags = _bdffnt_get_int(fis->dfFlags);
332 fi->dfAspace = _bdffnt_get_short(fis->dfAspace);
333 fi->dfBspace = _bdffnt_get_short(fis->dfBspace);
334 fi->dfCspace = _bdffnt_get_short(fis->dfCspace);
336 fi->dfColorPointer = _bdffnt_get_int(fis->dfColorPointer);
337 (void) memcpy(fi->dfReserved1, fis->dfReserved1, 16);
339 fi->dfColorPointer = _bdffnt_get_short(fis->dfColorPointer);
340 (void) memcpy(fi->dfReserved1, fis->dfReserved1, 4);
344 _bdffnt_weight_name(unsigned short weight, int *len)
351 } else if (weight <= BDFFNT_WEIGHT_THIN) {
354 } else if (weight <= BDFFNT_WEIGHT_ULTRALIGHT) {
357 } else if (weight <= BDFFNT_WEIGHT_LIGHT) {
360 } else if (weight <= BDFFNT_WEIGHT_MEDIUM) {
363 } else if (weight <= BDFFNT_WEIGHT_DEMIBOLD) {
366 } else if (weight <= BDFFNT_WEIGHT_BOLD) {
369 } else if (weight <= BDFFNT_WEIGHT_ULTRABOLD) {
380 _bdffnt_cset_name(int cset, int *enc)
384 case 0: *enc = 1; return "ISO8859";
385 case 1: return "WinDefault";
386 case 2: return "Symbol";
387 case 128: return "JISX0208.1983";
388 case 129: return "MSHangul";
389 case 134: return "GB2312.1980";
390 case 136: return "Big5";
391 case 161: *enc = 1; return "CP1253";
392 case 162: *enc = 1; return "CP1254";
393 case 177: *enc = 1; return "CP1255";
394 case 178: *enc = 1; return "CP1256";
395 case 186: *enc = 1; return "CP1257";
396 case 204: *enc = 1; return "CP1251";
397 case 238: *enc = 1; return "CP1250";
398 case 255: return "OEM";
403 /**************************************************************************
407 **************************************************************************/
410 bdffnt_open_font(char *path, bdffnt_font_t *fnt)
412 unsigned short sshift, version;
417 res_typeinfo_t rtype;
418 res_nameinfo_t ninfo;
420 if (path == 0 || *path == 0 || fnt == 0)
423 if ((in = fopen(path, "r")) == 0)
427 f = (_bdffnt_font_t *) malloc(sizeof(_bdffnt_font_t));
428 (void) memset((char *) f, 0, sizeof(_bdffnt_font_t));
432 if (fread((char *) &dos, 1, sizeof(dos_exe_t), in) != sizeof(dos_exe_t)) {
439 * Endian everything if on a big-endian machine.
441 if (!bdf_little_endian())
442 _bdffnt_endian_shorts((unsigned short *) &dos,
443 sizeof(dos_exe_t) / sizeof(unsigned short));
446 * Check for exe signatures.
448 if (dos.e_magic == DOS_SIG) {
449 fseek(in, dos.e_lfanew, 0L);
450 if (fread((char *) &win, 1, sizeof(win_exe_t), in) !=
458 * Only endian the fields used.
460 if (!bdf_little_endian()) {
461 _bdffnt_endian_shorts(&win.ne_magic, 1);
462 _bdffnt_endian_shorts(&win.resource_tab_offset, 1);
463 _bdffnt_endian_shorts(&win.rname_tab_offset, 1);
467 * This means the file is either NT 32-bit or something else.
469 if (win.ne_magic != WIN_SIG) {
476 * Seek to the beginning of the resources.
478 off = dos.e_lfanew + win.resource_tab_offset;
480 fread((char *) &sshift, 1, sizeof(unsigned short), in);
481 if (!bdf_little_endian())
482 _bdffnt_endian_shorts(&sshift, 1);
485 * Search the resources for all the font resources.
487 if (fread((char *) &rtype, 1, sizeof(res_typeinfo_t), in) !=
488 sizeof(res_typeinfo_t)) {
493 while (rtype.id != 0) {
495 * Change the endian order of the first two fields if necessary.
497 if (!bdf_little_endian())
498 _bdffnt_endian_shorts((unsigned short *) &rtype, 2);
500 if (rtype.id == 0x8008)
504 * Seek to the next resource entry and read it.
506 off = rtype.count * sizeof(res_nameinfo_t);
509 if (fread((char *) &rtype, 1, sizeof(res_typeinfo_t), in) !=
510 sizeof(res_typeinfo_t)) {
516 if (rtype.id == 0x8008) {
518 * Found a font resource, cycle through the entries.
520 for (i = 0; i < rtype.count; i++) {
521 if (fread((char *) &ninfo, 1, sizeof(res_nameinfo_t), in) !=
522 sizeof(res_nameinfo_t)) {
524 if (f->allocated > 0)
525 free((char *) f->fonts);
530 if (!bdf_little_endian())
531 _bdffnt_endian_shorts((unsigned short *) &ninfo,
532 sizeof(res_nameinfo_t) >> 1);
535 * Check to make sure that the indicated offset is really a
539 fseek(in, (ninfo.offset << sshift), 0L);
540 fread((char *) &version, sizeof(unsigned short), 1, in);
542 if (!bdf_little_endian())
543 _bdffnt_endian_shorts(&version, 1);
544 if (version != 0x200 && version != 0x300)
548 f->first = ninfo.offset << sshift;
550 if (f->nfonts >= f->allocated) {
551 if (f->allocated == 0)
552 f->fonts = (unsigned int *)
553 malloc(sizeof(unsigned int) << 3);
555 f->fonts = (unsigned int *)
556 realloc((char *) f->fonts,
557 sizeof(unsigned int) *
561 f->fonts[0] = f->first;
562 f->fonts[f->nfonts] = ninfo.offset << sshift;
567 } else if (dos.e_magic == 0x200 || dos.e_magic == 0x300) {
569 * Probably have a .FNT file.
571 f->first = ftell(in);
576 if (f->nfonts == 0) {
578 * If no fonts were loaded, free everything up.
588 bdffnt_close_font(bdffnt_font_t font)
594 if (font->cinfo_size > 0)
595 free((char *) font->cinfo);
596 if (font->allocated > 0)
597 free((char *) font->fonts);
602 bdffnt_font_count(bdffnt_font_t font)
604 return (font != 0) ? font->nfonts : 0;
608 bdffnt_get_copyright(bdffnt_font_t font, unsigned int fontID,
609 unsigned char *string)
615 off = (font->nfonts == 1) ? font->first : font->fonts[fontID];
616 fseek(font->in, off, 0L);
618 if (fread((char *) &fi, 1, sizeof(fishadow_t), font->in) !=
622 for (sp = fi.dfCopyright; (*string = *sp); sp++, string++) ;
623 return sp - fi.dfCopyright;
627 bdffnt_get_facename(bdffnt_font_t font, unsigned int fontID, int for_xlfd,
628 unsigned char *string)
632 unsigned char *sp, *wname;
635 if (font == 0 || fontID >= font->nfonts || string == 0)
638 off = (font->nfonts == 1) ? font->first : font->fonts[fontID];
639 fseek(font->in, off, 0L);
641 if (fread((char *) &fi, 1, sizeof(fishadow_t), font->in) !=
645 _bdffnt_transfer_fntinfo(&font->info, &fi);
648 * Seek to the location of the typeface name.
650 off = off + font->info.dfFace;
651 fseek(font->in, off, 0L);
654 * Copy the typeface name into the parameter.
656 * stops when: - == 0 -> end of string
657 * - < 0 -> end of file
660 while ((c = getc(font->in)) > 0) {
662 if (for_xlfd && *sp == '-')
669 * If the typeface name is not for an XLFD name, then append the style,
670 * weight and point size so the names will be informative.
674 if (font->info.dfItalic & 1) {
675 (void) strcpy((char *) sp, "Italic ");
678 wname = (unsigned char *) _bdffnt_weight_name(font->info.dfWeight,
680 (void) strcpy((char *) sp, (char *) wname);
683 sprintf((char *) sp, "%hdpt", font->info.dfPoints);
684 sp += strlen((char *) sp);
691 bdffnt_char_count(bdffnt_font_t font, unsigned int fontID)
696 if (font == 0 || fontID >= font->nfonts)
699 off = (font->nfonts == 1) ? font->first : font->fonts[fontID];
700 fseek(font->in, off, 0L);
702 if (fread((char *) &fi, 1, sizeof(fishadow_t), font->in) !=
706 _bdffnt_transfer_fntinfo(&font->info, &fi);
708 return (font->info.dfLastChar - font->info.dfFirstChar) + 1;
712 bdffnt_font_pointsize(bdffnt_font_t font, unsigned int fontID)
717 if (font == 0 || fontID >= font->nfonts)
720 off = (font->nfonts == 1) ? font->first : font->fonts[fontID];
721 fseek(font->in, off, 0L);
723 if (fread((char *) &fi, 1, sizeof(fishadow_t), font->in) !=
727 _bdffnt_transfer_fntinfo(&font->info, &fi);
729 return font->info.dfPoints;
733 bdffnt_load_font(bdffnt_font_t font, unsigned int fontID,
734 bdf_callback_t callback, void *data, bdf_font_t **out)
737 unsigned short tmp, bpr;
745 bdf_callback_struct_t cb;
748 if (font == 0 || fontID >= font->nfonts || out == 0)
751 off = (font->nfonts == 1) ? font->first : font->fonts[fontID];
752 fseek(font->in, off, 0L);
754 if (fread((char *) &fi, 1, sizeof(fishadow_t), font->in) !=
758 _bdffnt_transfer_fntinfo(&font->info, &fi);
761 * This cheap hack needed to get to the character info because the FNT
762 * docs don't mention that for Win 2.0 fonts, the header was a different
763 * size. This may be the case for a version 3.* as well, but I have no
764 * version 3.* fonts to test with.
766 fseek(font->in, off + 118, 0L);
769 * Determine how many character info records there are and make sure
770 * enough space is allocated in the font structure.
772 nchars = (font->info.dfLastChar - font->info.dfFirstChar) + 1;
774 if (font->cinfo_size < nchars) {
775 if (font->cinfo_size == 0)
776 font->cinfo = (chrinfo_t *) malloc(sizeof(chrinfo_t) * nchars);
778 font->cinfo = (chrinfo_t *) realloc((char *) font->cinfo,
779 sizeof(chrinfo_t) * nchars);
780 font->cinfo_size = nchars;
783 for (i = 0, font->cinfo_used = 0; i < nchars; i++, cp++) {
784 fread((char *) &tmp, sizeof(unsigned short), 1, font->in);
785 if (!bdf_little_endian())
786 _bdffnt_endian_shorts(&tmp, 1);
788 if (font->info.dfVersion == 0x300) {
789 fread((char *) &cp->offset, sizeof(unsigned int), 1, font->in);
790 if (!bdf_little_endian())
791 _bdffnt_endian_ints(&cp->offset, 1);
793 fread((char *) &tmp, sizeof(unsigned short), 1, font->in);
794 if (!bdf_little_endian())
795 _bdffnt_endian_shorts(&tmp, 1);
803 f = (bdf_font_t *) malloc(sizeof(bdf_font_t));
804 (void) memset((char *) f, 0, sizeof(bdf_font_t));
810 f->default_glyph = font->info.dfDefaultChar + font->info.dfFirstChar;
811 f->spacing = (font->info.dfFlags & 1) ? BDF_CHARCELL : BDF_PROPORTIONAL;
812 f->glyphs_size = nchars;
813 f->glyphs = (bdf_glyph_t *) malloc(sizeof(bdf_glyph_t) * nchars);
814 (void) memset((char *) f->glyphs, 0, sizeof(bdf_glyph_t) * nchars);
815 f->point_size = font->info.dfPoints;
816 f->resolution_x = font->info.dfHorizRes;
817 f->resolution_y = font->info.dfVertRes;
818 f->font_ascent = font->info.dfAscent;
819 f->font_descent = f->font_ascent - font->info.dfPixHeight;
822 * Set the font bounding box.
824 f->bbx.width = font->info.dfMaxWidth;
825 f->bbx.height = font->info.dfPixHeight;
826 f->bbx.ascent = font->info.dfAscent;
827 f->bbx.descent = f->bbx.height - f->bbx.ascent;
828 f->bbx.y_offset = -f->bbx.descent;
831 if (f->spacing == BDF_CHARCELL)
832 f->monowidth = f->bbx.width;
835 * Determine the SWIDTH scale factor.
837 swscale = ((double) f->resolution_y) * ((double) f->point_size);
840 * Call the initial callback if one was provided.
843 cb.reason = BDF_LOAD_START;
846 (*callback)(&cb, data);
850 * Start collecting glyphs.
852 for (i = 0, cp = font->cinfo, gp = f->glyphs; i < nchars;
855 * Set the glyph encoding.
857 gp->encoding = font->info.dfFirstChar + i;
860 * Set the glyph bounding box.
862 gp->bbx.width = gp->dwidth = cp->width;
863 gp->bbx.height = font->info.dfPixHeight;
864 gp->bbx.ascent = font->info.dfAscent;
865 gp->bbx.descent = gp->bbx.height - gp->bbx.ascent;
866 gp->bbx.y_offset = -gp->bbx.descent;
867 gp->bbx.x_offset = 0;
868 gp->swidth = (unsigned short)
869 (((double) gp->dwidth) * 72000.0) / swscale;
872 * Allocate the glyph bitmap.
874 bpr = (cp->width + 7) >> 3;
875 gp->bytes = bpr * font->info.dfPixHeight;
876 gp->bitmap = (unsigned char *) malloc(gp->bytes);
879 * Seek to the bitmap and read the bytes.
881 fseek(font->in, off + cp->offset, 0L);
883 fread((char *) gp->bitmap, gp->bytes, 1, font->in);
886 * Typical MS wierdness. This awkward section is just to get the
887 * bytes in the right place.
889 for (x = 0; x < bpr; x++) {
890 for (y = 0; y < gp->bbx.height; y++)
891 gp->bitmap[(y * bpr) + x] = getc(font->in);
896 cb.reason = BDF_LOADING;
899 (*callback)(&cb, data);
904 * Call the callback one more time to make sure the client knows the
908 cb.reason = BDF_LOADING;
911 (*callback)(&cb, data);
915 * Set the number of glyphs used.
917 f->glyphs_used = gp - f->glyphs;
920 * Add all the properties.
922 prop.name = "FOUNDRY";
923 prop.format = BDF_ATOM;
924 prop.value.atom = "Windows";
925 bdf_add_font_property(f, &prop);
927 i = bdffnt_get_facename(font, fontID, 1, (unsigned char *) name);
928 prop.name = "FAMILY_NAME";
929 prop.format = BDF_ATOM;
930 prop.value.atom = name;
931 bdf_add_font_property(f, &prop);
933 prop.name = "WEIGHT_NAME";
934 prop.format = BDF_ATOM;
935 prop.value.atom = _bdffnt_weight_name(font->info.dfWeight, &i);
936 bdf_add_font_property(f, &prop);
939 prop.format = BDF_ATOM;
940 if (font->info.dfItalic & 1)
941 prop.value.atom = "I";
943 prop.value.atom = "R";
944 bdf_add_font_property(f, &prop);
946 prop.name = "SETWIDTH_NAME";
947 prop.format = BDF_ATOM;
948 prop.value.atom = "Normal";
949 bdf_add_font_property(f, &prop);
951 if (font->info.dfPitchAndFamily & 0xf0) {
952 prop.name = "ADDSTYLE_NAME";
953 prop.format = BDF_ATOM;
954 switch (font->info.dfPitchAndFamily & 0xf0) {
955 case 0x20: prop.value.atom = "Swiss"; break;
956 case 0x30: prop.value.atom = "Modern"; break;
957 case 0x40: prop.value.atom = "Script"; break;
958 case 0x50: prop.value.atom = "Decorative"; break;
959 default: prop.value.atom = 0;
961 if (prop.value.atom != 0)
962 bdf_add_font_property(f, &prop);
965 prop.name = "PIXEL_SIZE";
966 prop.format = BDF_INTEGER;
967 prop.value.int32 = (int)
968 ((((double) (f->point_size * 10) *
969 (double) f->resolution_y) / 722.7) + 0.5);
970 bdf_add_font_property(f, &prop);
972 prop.name = "POINT_SIZE";
973 prop.format = BDF_INTEGER;
974 prop.value.int32 = f->point_size * 10;
975 bdf_add_font_property(f, &prop);
977 prop.name = "RESOLUTION_X";
978 prop.format = BDF_CARDINAL;
979 prop.value.card32 = (unsigned int) f->resolution_x;
980 bdf_add_font_property(f, &prop);
982 prop.name = "RESOLUTION_Y";
983 prop.format = BDF_CARDINAL;
984 prop.value.card32 = (unsigned int) f->resolution_y;
985 bdf_add_font_property(f, &prop);
987 prop.name = "FONT_ASCENT";
988 prop.format = BDF_INTEGER;
989 prop.value.int32 = f->font_ascent;
990 bdf_add_font_property(f, &prop);
992 prop.name = "FONT_DESCENT";
993 prop.format = BDF_INTEGER;
994 prop.value.int32 = f->font_descent;
995 bdf_add_font_property(f, &prop);
997 prop.name = "AVERAGE_WIDTH";
998 prop.format = BDF_INTEGER;
999 prop.value.int32 = font->info.dfAvgWidth * 10;
1000 bdf_add_font_property(f, &prop);
1002 prop.name = "SPACING";
1003 prop.format = BDF_ATOM;
1004 prop.value.atom = "P";
1005 switch (f->spacing) {
1006 case BDF_PROPORTIONAL: prop.value.atom = "P"; break;
1007 case BDF_MONOWIDTH: prop.value.atom = "M"; break;
1008 case BDF_CHARCELL: prop.value.atom = "C"; break;
1010 bdf_add_font_property(f, &prop);
1012 prop.name = "CHARSET_REGISTRY";
1013 prop.format = BDF_ATOM;
1014 prop.value.atom = _bdffnt_cset_name(font->info.dfCharSet, &i);
1015 bdf_add_font_property(f, &prop);
1017 sprintf(name, "%d", i);
1018 prop.name = "CHARSET_ENCODING";
1019 prop.format = BDF_ATOM;
1020 prop.value.atom = name;
1021 bdf_add_font_property(f, &prop);
1024 * Generate the XLFD name.
1026 f->name = bdf_make_xlfd_name(f, 0, 0);
1029 * Add messages indicating the font was converted.
1031 _bdf_add_comment(f, "Font converted from FNT/FON to BDF.", 35);
1032 _bdf_add_acmsg(f, "Font converted from FNT/FON to BDF.", 35);
1035 * Mark the font as being modified.