1 /************************************************************************
2 Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
6 Permission to use, copy, modify, and distribute this software and its
7 documentation for any purpose and without fee is hereby granted,
8 provided that the above copyright notice appear in all copies and that
9 both that copyright notice and this permission notice appear in
10 supporting documentation, and that the name of Digital not be
11 used in advertising or publicity pertaining to distribution of the
12 software without specific, written prior permission.
14 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22 ************************************************************************/
26 Copyright 1994, 1998 The Open Group
28 Permission to use, copy, modify, distribute, and sell this software and its
29 documentation for any purpose is hereby granted without fee, provided that
30 the above copyright notice appear in all copies and that both that
31 copyright notice and this permission notice appear in supporting
34 The above copyright notice and this permission notice shall be included
35 in all copies or substantial portions of the Software.
37 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
40 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
41 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43 OTHER DEALINGS IN THE SOFTWARE.
45 Except as contained in this notice, the name of The Open Group shall
46 not be used in advertising or otherwise to promote the sale, use or
47 other dealings in this Software without prior written authorization
57 #include <X11/fonts/fntfilst.h>
58 #include <X11/fonts/bitmap.h>
63 static void _X_ATTRIBUTE_PRINTF(1, 2)
64 snfError(const char* message, ...)
68 va_start(args, message);
70 fprintf(stderr, "SNF Error: ");
71 vfprintf(stderr, message, args);
75 static void snfUnloadFont(FontPtr pFont);
78 snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
80 snfCharInfoRec snfCharInfo;
82 #define Width(m) ((m).rightSideBearing - (m).leftSideBearing)
83 #define Height(m) ((m).ascent + (m).descent)
85 if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
86 sizeof(snfCharInfo)) {
89 charInfo->metrics = snfCharInfo.metrics;
90 if (snfCharInfo.exists)
91 charInfo->bits = base + snfCharInfo.byteOffset;
98 snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
100 snfCharInfoRec snfCharInfo;
102 if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
103 sizeof(snfCharInfo)) {
106 *charInfo = snfCharInfo.metrics;
111 snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
113 pFontInfo->firstCol = snfInfo->firstCol;
114 pFontInfo->lastCol = snfInfo->lastCol;
115 pFontInfo->firstRow = snfInfo->firstRow;
116 pFontInfo->lastRow = snfInfo->lastRow;
117 pFontInfo->defaultCh = snfInfo->chDefault;
118 pFontInfo->noOverlap = snfInfo->noOverlap;
119 pFontInfo->terminalFont = snfInfo->terminalFont;
120 pFontInfo->constantMetrics = snfInfo->constantMetrics;
121 pFontInfo->constantWidth = snfInfo->constantWidth;
122 pFontInfo->inkInside = snfInfo->inkInside;
123 pFontInfo->inkMetrics = snfInfo->inkMetrics;
124 pFontInfo->allExist = snfInfo->allExist;
125 pFontInfo->drawDirection = snfInfo->drawDirection;
126 pFontInfo->anamorphic = FALSE;
127 pFontInfo->cachable = TRUE;
128 pFontInfo->maxOverlap = 0;
129 pFontInfo->minbounds = snfInfo->minbounds.metrics;
130 pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
131 pFontInfo->fontAscent = snfInfo->fontAscent;
132 pFontInfo->fontDescent = snfInfo->fontDescent;
133 pFontInfo->nprops = snfInfo->nProps;
137 snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
141 snfFontPropPtr psnfp;
146 bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
147 BYTESOFSTRINGINFO(snfInfo);
148 propspace = malloc(bytestoalloc);
150 snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
154 if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
158 psnfp = (snfFontPropPtr) propspace;
160 strings = propspace + BYTESOFPROPINFO(snfInfo);
162 for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
163 pfp->name = MakeAtom(&strings[psnfp->name],
164 (unsigned) strlen(&strings[psnfp->name]), 1);
165 pFontInfo->isStringProp[i] = psnfp->indirect;
167 pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
168 (unsigned) strlen(&strings[psnfp->value]), 1);
170 pfp->value = psnfp->value;
178 snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
180 if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
183 if (snfInfo->version1 != FONT_FILE_VERSION ||
184 snfInfo->version2 != FONT_FILE_VERSION)
190 static int snf_bit, snf_byte, snf_glyph, snf_scan;
193 SnfSetFormat (int bit, int byte, int glyph, int scan)
203 SnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
206 FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
214 snfReadFont(FontPtr pFont, FontFilePtr file,
215 int bit, int byte, int glyph, int scan)
218 unsigned bytestoalloc;
221 BitmapFontPtr bitmapFont;
228 int isStringProp_off;
231 int def_bit, def_byte, def_glyph, def_scan;
233 ret = snfReadHeader(&fi, file);
234 if (ret != Successful)
237 SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
240 * we'll allocate one chunk of memory and split it among the various parts
243 * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
245 * If the glyphpad is not the same as the font file, then the glyphs
246 * are allocated separately, to be later realloc'ed when we know
247 * how big to make them.
250 bitmapsSize = BYTESOFGLYPHINFO(&fi);
251 num_chars = n2dChars(&fi);
252 bytestoalloc = sizeof(BitmapFontRec); /* bitmapFont */
253 metrics_off = bytestoalloc;
254 bytestoalloc += num_chars * sizeof(CharInfoRec); /* metrics */
255 encoding_off = bytestoalloc;
256 bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**);
258 props_off = bytestoalloc;
259 bytestoalloc += fi.nProps * sizeof(FontPropRec); /* props */
260 isStringProp_off = bytestoalloc;
261 bytestoalloc += fi.nProps * sizeof(char); /* isStringProp */
262 bytestoalloc = (bytestoalloc + 3) & ~3;
263 ink_off = bytestoalloc;
265 bytestoalloc += num_chars * sizeof(xCharInfo); /* ink_metrics */
267 fontspace = malloc(bytestoalloc);
269 snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
272 bitmaps = malloc (bitmapsSize);
275 snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
280 * now fix up pointers
283 bitmapFont = (BitmapFontPtr) fontspace;
284 bitmapFont->num_chars = num_chars;
285 bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
286 bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off);
287 bitmapFont->bitmaps = bitmaps;
288 bitmapFont->pDefault = NULL;
289 bitmapFont->bitmapExtra = NULL;
290 pFont->info.props = (FontPropPtr) (fontspace + props_off);
291 pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
293 bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
295 bitmapFont->ink_metrics = 0;
302 memset(bitmapFont->encoding, 0,
303 NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*));
304 for (i = 0; ret == Successful && i < num_chars; i++) {
305 ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
306 if (bitmapFont->metrics[i].bits) {
307 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
308 bitmapFont->encoding[SEGMENT_MAJOR(i)]=
309 calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
310 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
315 ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
319 if (ret != Successful) {
321 if(bitmapFont->encoding) {
322 for(j=0; j<SEGMENT_MAJOR(i); j++)
323 free(bitmapFont->encoding[i]);
332 if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
339 BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
340 if ((def_byte == def_bit) != (bit == byte)) {
341 switch (bit == byte ? def_scan : scan) {
345 TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
348 FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
352 if (def_glyph != glyph) {
359 metric = bitmapFont->metrics;
360 for (i = 0; i < num_chars; i++)
363 sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
366 padbitmaps = malloc(sizepadbitmaps);
368 snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
373 metric = bitmapFont->metrics;
374 bitmapFont->bitmaps = padbitmaps;
375 for (i = 0; i < num_chars; i++) {
376 sizechar = RepadBitmap(metric->bits, padbitmaps,
378 metric->metrics.rightSideBearing -
379 metric->metrics.leftSideBearing,
380 metric->metrics.ascent + metric->metrics.descent);
381 metric->bits = padbitmaps;
382 padbitmaps += sizechar;
388 /* now read and atom'ize properties */
390 ret = snfReadProps(&fi, &pFont->info, file);
391 if (ret != Successful) {
395 snfCopyInfo(&fi, &pFont->info);
397 /* finally, read the ink metrics if the exist */
401 ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
402 ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
403 for (i = 0; ret == Successful && i < num_chars; i++)
404 ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
405 if (ret != Successful) {
410 pFont->info.ink_minbounds = pFont->info.minbounds;
411 pFont->info.ink_maxbounds = pFont->info.maxbounds;
414 if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
419 r = pFont->info.defaultCh >> 8;
420 c = pFont->info.defaultCh & 0xFF;
421 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
422 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
423 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
424 r = r - pFont->info.firstRow;
425 c = c - pFont->info.firstCol;
426 bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
429 bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
430 pFont->fontPrivate = (pointer) bitmapFont;
431 pFont->get_glyphs = bitmapGetGlyphs;
432 pFont->get_metrics = bitmapGetMetrics;
433 pFont->unload_font = snfUnloadFont;
434 pFont->unload_glyphs = NULL;
437 pFont->glyph = glyph;
443 snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
450 ret = snfReadHeader(&fi, file);
451 if (ret != Successful)
453 snfCopyInfo(&fi, pFontInfo);
455 pFontInfo->props = malloc(fi.nProps * sizeof(FontPropRec));
456 if (!pFontInfo->props) {
457 snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n",
458 fi.nProps, (int) sizeof(FontPropRec));
461 pFontInfo->isStringProp = malloc(fi.nProps * sizeof(char));
462 if (!pFontInfo->isStringProp) {
463 snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n",
464 fi.nProps, (int) sizeof(char));
465 free(pFontInfo->props);
468 num_chars = n2dChars(&fi);
469 bytestoskip = num_chars * sizeof(snfCharInfoRec); /* charinfos */
470 bytestoskip += BYTESOFGLYPHINFO(&fi);
471 (void)FontFileSkip(file, bytestoskip);
473 ret = snfReadProps(&fi, pFontInfo, file);
474 if (ret != Successful) {
475 free(pFontInfo->props);
476 free(pFontInfo->isStringProp);
480 ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
481 if (ret != Successful) {
482 free(pFontInfo->props);
483 free(pFontInfo->isStringProp);
486 ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
487 if (ret != Successful) {
488 free(pFontInfo->props);
489 free(pFontInfo->isStringProp);
493 pFontInfo->ink_minbounds = pFontInfo->minbounds;
494 pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
501 snfUnloadFont(FontPtr pFont)
503 BitmapFontPtr bitmapFont;
505 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
506 free (bitmapFont->bitmaps);
508 DestroyFontRec (pFont);