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