|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/file.h>
3:
4: #include "X.h"
5: #include "Xmd.h"
6: #include "Xproto.h"
7: #include "misc.h"
8: #include "fontstruct.h"
9:
10: #include "port.h" /* used by converters only */
11: #include "fc.h" /* used by converters only */
12:
13: #ifndef u_char
14: #define u_char unsigned char
15: #endif
16:
17: extern int glyphPad;
18: extern int bitorder;
19:
20: char * malloc();
21: char * invertbitsandbytes();
22:
23: /*
24: * Computes accelerators, which by definition can be extracted from
25: * the font; therefore a pointer to the font is the only argument.
26: *
27: * Should also give a final sanity-check to the font, so it can be
28: * written to disk.
29: *
30: * Generates values for the following fields in the FontInfo structure:
31: * version
32: * minbounds
33: * maxbounds - except byteOffset
34: * Generates values for the following fields in the CharInfo array.
35: * u.flags
36: */
37: computeNaccelerators(font)
38: TempFont *font;
39: {
40: int chi, nchars;
41: register CharInfoPtr minbounds = &font->pFI->minbounds;
42: register CharInfoPtr maxbounds = &font->pFI->maxbounds;
43:
44: int maxoverlap = MINSHORT; /* used to set fiFlags */
45: int nnonexistchars = 0; /* used to set fiFlags */
46:
47: font->pFI->version1 = font->pFI->version2 = FONT_FILE_VERSION;
48:
49: minbounds->metrics.ascent = MAXSHORT;
50: minbounds->metrics.descent = MAXSHORT;
51: minbounds->metrics.leftSideBearing = MAXSHORT;
52: minbounds->metrics.rightSideBearing = MAXSHORT;
53: minbounds->metrics.characterWidth = font->pCI->metrics.characterWidth;
54: /* don't touch byteOffset! */
55: minbounds->exists = 0;
56: minbounds->metrics.attributes = 0xFFFF; /* all bits on */
57:
58: maxbounds->metrics.ascent = MINSHORT;
59: maxbounds->metrics.descent = MINSHORT;
60: maxbounds->metrics.leftSideBearing = MINSHORT;
61: maxbounds->metrics.rightSideBearing = MINSHORT;
62: maxbounds->metrics.characterWidth = font->pCI->metrics.characterWidth;
63: /* don't touch byteOffset! */
64: maxbounds->exists = 0;
65: maxbounds->metrics.attributes = 0;
66:
67: nchars = n2dChars(font->pFI);
68: for (chi = 0; chi < nchars; chi++)
69: {
70: register CharInfoPtr pci = &font->pCI[chi];
71:
72: if ( pci->metrics.ascent == 0
73: && pci->metrics.descent == 0
74: && pci->metrics.leftSideBearing == 0
75: && pci->metrics.rightSideBearing == 0
76: && pci->metrics.characterWidth == 0) {
77: nnonexistchars++;
78: pci->exists = FALSE;
79: }
80: else {
81:
82: #define MINMAX(field) \
83: if (minbounds->metrics.field > pci->metrics.field) \
84: minbounds->metrics.field = pci->metrics.field; \
85: if (maxbounds->metrics.field < pci->metrics.field) \
86: maxbounds->metrics.field = pci->metrics.field;
87:
88: pci->exists = TRUE;
89: MINMAX(ascent);
90: MINMAX(descent);
91: MINMAX(leftSideBearing);
92: MINMAX(rightSideBearing);
93: MINMAX(characterWidth);
94: minbounds->metrics.attributes &= pci->metrics.attributes;
95: maxbounds->metrics.attributes |= pci->metrics.attributes;
96: maxoverlap = MAX(
97: maxoverlap,
98: pci->metrics.rightSideBearing-pci->metrics.characterWidth);
99: #undef MINMAX
100: }
101: }
102:
103: if ( maxoverlap <= minbounds->metrics.leftSideBearing)
104: font->pFI->noOverlap = TRUE;
105: else
106: font->pFI->noOverlap = FALSE;
107:
108: if ( nnonexistchars == 0)
109: font->pFI->allExist = TRUE;
110: else
111: font->pFI->allExist = FALSE;
112:
113: if ( (minbounds->metrics.ascent == maxbounds->metrics.ascent) &&
114: (minbounds->metrics.descent == maxbounds->metrics.descent) &&
115: (minbounds->metrics.leftSideBearing ==
116: maxbounds->metrics.leftSideBearing) &&
117: (minbounds->metrics.rightSideBearing ==
118: maxbounds->metrics.rightSideBearing) &&
119: (minbounds->metrics.characterWidth ==
120: maxbounds->metrics.characterWidth) &&
121: (minbounds->metrics.attributes == maxbounds->metrics.attributes)) {
122: font->pFI->constantMetrics = TRUE;
123: if ( maxbounds->metrics.rightSideBearing + maxbounds->metrics.leftSideBearing ==
124: maxbounds->metrics.characterWidth)
125: font->pFI->terminalFont = TRUE;
126: }
127: else {
128: font->pFI->constantMetrics = FALSE;
129: font->pFI->terminalFont = FALSE;
130: }
131: }
132:
133:
134:
135: /*
136: * Note that ReadNFont lives in dix/fontserver.c. It would seem cleaner if
137: * ReadNFont and WriteNFont could live together.
138: */
139: WriteNFont( pfile, font)
140: FILE * pfile;
141: TempFont *font;
142: {
143: int np;
144: FontPropPtr fp;
145: int off; /* running index into string table */
146: int strbytes; /* size of string table */
147: char *strings; /* string table */
148: long zero = 0;
149:
150: /* run through the properties and add up the string lengths */
151: strbytes = 0;
152: for (fp=font->pFP,np=font->pFI->nProps; np; np--,fp++)
153: {
154: strbytes += strlen((char *)fp->name)+1;
155: if (fp->indirect)
156: strbytes += strlen((char *)fp->value)+1;
157: }
158: font->pFI->lenStrings = strbytes;
159:
160: /* build string table and convert pointers to offsets */
161: strings = malloc(strbytes);
162: off = 0;
163: for (fp=font->pFP,np=font->pFI->nProps; np; np--,fp++)
164: {
165: int l;
166: l = strlen(fp->name)+1; /* include null */
167: bcopy((char *)fp->name, strings+off, l);
168: fp->name = off;
169: off += l;
170: if (fp->indirect) {
171: l = strlen(fp->value)+1; /* include null */
172: bcopy((char *)fp->value, strings+off, l);
173: fp->value = off;
174: off += l;
175: }
176: }
177:
178: fwrite( (char *)font->pFI, BYTESOFFONTINFO(font->pFI), 1, pfile);
179:
180: fwrite( (char *)(font->pCI),
181: BYTESOFCHARINFO(font->pFI), 1, pfile);
182:
183: fwrite( font->pGlyphs, 1, BYTESOFGLYPHINFO(font->pFI), pfile);
184:
185: fwrite( (char *)font->pFP, 1, BYTESOFPROPINFO(font->pFI), pfile);
186:
187: fwrite( strings, 1, BYTESOFSTRINGINFO(font->pFI), pfile);
188: }
189:
190:
191:
192: DumpFont( pfont, bVerbose)
193: TempFont * pfont;
194: int bVerbose;
195: {
196: FontInfoPtr pfi = pfont->pFI;
197: int bFailure = 0;
198: int i;
199:
200: if ( pfont == NULL)
201: {
202: fprintf( stderr, "DumpFont: NULL FONT pointer passed\n");
203: exit( 1);
204: }
205: if ( pfi == NULL)
206: {
207: fprintf( stderr, "DumpFont: NULL FontInfo pointer passed\n");
208: exit( 1);
209: }
210:
211: printf("version1: 0x%x (version2: 0x%x)\n", pfi->version1, pfi->version2);
212: if ( pfi->version1 != FONT_FILE_VERSION)
213: printf( "*** NOT CURRENT VERSION ***\n");
214: if ( pfi->noOverlap)
215: printf( " no overlap");
216: if ( pfi->allExist)
217: printf( " all exist");
218: printf("\nprinting direction: ");
219: switch ( pfi->drawDirection)
220: {
221: case FontLeftToRight:
222: printf( "left-to-right\n");
223: break;
224: case FontRightToLeft:
225: printf( "right-to-left\n");
226: break;
227: }
228: printf("first character: 0x%x\n", pfi->chFirst);
229: printf("last characters: 0x%x\n", pfi->chLast);
230:
231: printf("number of font properties: 0x%x\n", pfi->nProps);
232: for (i=0; i<pfi->nProps; i++) {
233: printf(" %-15s ", pfont->pFP[i].name);
234: if (pfont->pFP[i].indirect)
235: printf("%s\n", pfont->pFP[i].value);
236: else
237: printf("%d\n", pfont->pFP[i].value);
238: }
239:
240: printf("default character: 0x%x\n", pfi->chDefault);
241:
242: printf("minbounds:\n");
243: DumpCharInfo( -1, &pfi->minbounds, 1);
244: printf("maxbounds:\n");
245: DumpCharInfo( -1, &pfi->maxbounds, 1);
246: printf("FontInfo struct: virtual memory address == %x\tsize == %x\n",
247: pfont->pFI, sizeof(FontInfoRec));
248:
249: printf("CharInfo array: virtual memory base address == %x\tsize == %x\n",
250: pfont->pCI, n1dChars(pfi)*sizeof(CharInfoRec));
251:
252: printf("glyph block: virtual memory address == %x\tsize == %x\n",
253: pfont->pGlyphs, pfi->maxbounds.byteOffset );
254:
255: if ( bVerbose>0)
256: DumpCharInfo( pfont->pFI->chFirst, pfont->pCI, n1dChars(pfont->pFI));
257:
258: if ( bVerbose>1)
259: {
260: if (bFailure)
261: fprintf( stderr, "verbosity not possible with failed read");
262: else
263: /*
264: if ( pixDepth > 1)
265: DumpAABitmaps( pfont);
266: else
267: */
268: DumpBitmaps( pfont);
269: }
270: printf("\n");
271: }
272:
273: DumpCharInfo( first, pxci, count)
274: int first;
275: CharInfoPtr pxci;
276: int count;
277: {
278: /*
279: printf( "\nrbearing\tlbearing\tdescent\tascent\nwidth\tbyteOffset\tbitOffset\tciFlags");
280: */
281: if (first >= 0) {
282: putchar ('\t');
283: }
284: printf( "rbearing\tdescent\t\twidth\t\texists\n");
285: if (first >= 0) printf("number\t");
286: printf( "\tlbearing\tascent\t\tbyteOffset\tciFlags\n");
287:
288: while( count--)
289: {
290: if (first >= 0) printf ("%d\t", first++);
291: printf( "%4d\t%4d\t%4d\t%4d\t%4d\t0x%x\t%4s\t0x%x\n",
292: pxci->metrics.rightSideBearing, pxci->metrics.leftSideBearing,
293: pxci->metrics.descent, pxci->metrics.ascent,
294: pxci->metrics.characterWidth, pxci->byteOffset,
295: pxci->exists?"yes":"no", pxci->metrics.attributes);
296: pxci++;
297: }
298: }
299:
300: DumpBitmaps( pFont)
301: TempFont *pFont;
302: {
303: int ch; /* current character */
304: int r; /* current row */
305: int b; /* current bit in the row */
306: FontInfoPtr pFI = pFont->pFI;
307: CharInfoPtr pCI = pFont->pCI;
308: u_char * bitmap = (u_char *)pFont->pGlyphs;
309: int n = n1dChars(pFont->pFI);
310:
311: for (ch = 0; ch < n; ch++)
312: {
313: int bpr = GLWIDTHBYTESPADDED(pCI[ch].metrics.rightSideBearing
314: - pCI[ch].metrics.leftSideBearing, glyphPad);
315: printf("character %d", ch + pFont->pFI->chFirst);
316: if ( !pCI[ch].exists || pCI[ch].metrics.characterWidth == 0) {
317: printf (" doesn't exist\n");
318: continue;
319: } else {
320: putchar('\n');
321: }
322: for (r=0; r < pCI[ch].metrics.descent + pCI[ch].metrics.ascent; r++)
323: {
324: unsigned char *row = bitmap + pCI[ch].byteOffset+(r*bpr);
325: for ( b=0;
326: b < pCI[ch].metrics.rightSideBearing - pCI[ch].metrics.leftSideBearing;
327: b++) {
328: if (bitorder == LSBFirst) {
329: putchar((row[b>>3] & (1<<(b&7)))? '#' : '_');
330: } else {
331: putchar((row[b>>3] & (1<<(7-(b&7))))? '#' : '_');
332: }
333: }
334: putchar('\n');
335: }
336: }
337: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.