upload tizen2.0 source
[framework/uifw/xorg/lib/libxfont.git] / src / bitmap / snfread.c
1 /************************************************************************
2 Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3
4                         All Rights Reserved
5
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.
13
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
20 SOFTWARE.
21
22 ************************************************************************/
23
24 /*
25
26 Copyright 1994, 1998  The Open Group
27
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
32 documentation.
33
34 The above copyright notice and this permission notice shall be included
35 in all copies or substantial portions of the Software.
36
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.
44
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
48 from The Open Group.
49
50 */
51
52 #ifdef HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55
56 #include <ctype.h>
57 #include <X11/fonts/fntfilst.h>
58 #include <X11/fonts/bitmap.h>
59 #include "snfstr.h"
60
61 #include <stdarg.h>
62
63 static void _X_ATTRIBUTE_PRINTF(1, 2)
64 snfError(const char* message, ...)
65 {
66     va_list args;
67
68     va_start(args, message);
69
70     fprintf(stderr, "SNF Error: ");
71     vfprintf(stderr, message, args);
72     va_end(args);
73 }
74
75 static void snfUnloadFont(FontPtr pFont);
76
77 static int
78 snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
79 {
80     snfCharInfoRec snfCharInfo;
81
82 #define Width(m)    ((m).rightSideBearing - (m).leftSideBearing)
83 #define Height(m)   ((m).ascent + (m).descent)
84
85     if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
86             sizeof(snfCharInfo)) {
87         return BadFontName;
88     }
89     charInfo->metrics = snfCharInfo.metrics;
90     if (snfCharInfo.exists)
91         charInfo->bits = base + snfCharInfo.byteOffset;
92     else
93         charInfo->bits = 0;
94     return Successful;
95 }
96
97 static int
98 snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
99 {
100     snfCharInfoRec snfCharInfo;
101
102     if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
103             sizeof(snfCharInfo)) {
104         return BadFontName;
105     }
106     *charInfo = snfCharInfo.metrics;
107     return Successful;
108 }
109
110 static void
111 snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
112 {
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;
134 }
135
136 static int
137 snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
138 {
139     char       *strings;
140     FontPropPtr pfp;
141     snfFontPropPtr psnfp;
142     char       *propspace;
143     int         bytestoalloc;
144     int         i;
145
146     bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
147         BYTESOFSTRINGINFO(snfInfo);
148     propspace = malloc(bytestoalloc);
149     if (!propspace) {
150       snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
151         return AllocError;
152     }
153
154     if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
155         free(propspace);
156         return BadFontName;
157     }
158     psnfp = (snfFontPropPtr) propspace;
159
160     strings = propspace + BYTESOFPROPINFO(snfInfo);
161
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;
166         if (psnfp->indirect)
167             pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
168                                (unsigned) strlen(&strings[psnfp->value]), 1);
169         else
170             pfp->value = psnfp->value;
171     }
172
173     free(propspace);
174     return Successful;
175 }
176
177 static int
178 snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
179 {
180     if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
181         return BadFontName;
182
183     if (snfInfo->version1 != FONT_FILE_VERSION ||
184             snfInfo->version2 != FONT_FILE_VERSION)
185         return BadFontName;
186     return Successful;
187 }
188
189 static int  snf_set;
190 static int  snf_bit, snf_byte, snf_glyph, snf_scan;
191
192 void
193 SnfSetFormat (int bit, int byte, int glyph, int scan)
194 {
195     snf_bit = bit;
196     snf_byte = byte;
197     snf_glyph = glyph;
198     snf_scan = scan;
199     snf_set = 1;
200 }
201
202 static void
203 SnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
204 {
205     if (!snf_set)
206         FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
207     *bit = snf_bit;
208     *byte = snf_byte;
209     *glyph = snf_glyph;
210     *scan = snf_scan;
211 }
212
213 int
214 snfReadFont(FontPtr pFont, FontFilePtr file,
215             int bit, int byte, int glyph, int scan)
216 {
217     snfFontInfoRec fi;
218     unsigned    bytestoalloc;
219     int         i, j;
220     char       *fontspace;
221     BitmapFontPtr  bitmapFont;
222     int         num_chars;
223     int         bitmapsSize;
224     int         ret;
225     int         metrics_off;
226     int         encoding_off;
227     int         props_off;
228     int         isStringProp_off;
229     int         ink_off;
230     char        *bitmaps;
231     int         def_bit, def_byte, def_glyph, def_scan;
232
233     ret = snfReadHeader(&fi, file);
234     if (ret != Successful)
235         return ret;
236
237     SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
238
239     /*
240      * we'll allocate one chunk of memory and split it among the various parts
241      * of the font:
242      *
243      * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
244      *
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.
248      */
249
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**);
257                                                 /* encoding */
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;
264     if (fi.inkMetrics)
265         bytestoalloc += num_chars * sizeof(xCharInfo);  /* ink_metrics */
266
267     fontspace = malloc(bytestoalloc);
268     if (!fontspace) {
269       snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
270         return AllocError;
271     }
272     bitmaps = malloc (bitmapsSize);
273     if (!bitmaps)
274     {
275       snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
276         free (fontspace);
277         return AllocError;
278     }
279     /*
280      * now fix up pointers
281      */
282
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);
292     if (fi.inkMetrics)
293         bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
294     else
295         bitmapFont->ink_metrics = 0;
296
297     /*
298      * read the CharInfo
299      */
300
301     ret = Successful;
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)]) {
311                     ret = AllocError;
312                     break;
313                 }
314             }
315             ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
316         }
317     }
318
319     if (ret != Successful) {
320         free(bitmaps);
321         if(bitmapFont->encoding) {
322             for(j=0; j<SEGMENT_MAJOR(i); j++)
323                 free(bitmapFont->encoding[i]);
324         }
325         free(fontspace);
326         return ret;
327     }
328     /*
329      * read the glyphs
330      */
331
332     if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
333         free(bitmaps);
334         free(fontspace);
335         return BadFontName;
336     }
337
338     if (def_bit != bit)
339         BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
340     if ((def_byte == def_bit) != (bit == byte)) {
341         switch (bit == byte ? def_scan : scan) {
342         case 1:
343             break;
344         case 2:
345             TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
346             break;
347         case 4:
348             FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
349             break;
350         }
351     }
352     if (def_glyph != glyph) {
353         char        *padbitmaps;
354         int         sizepadbitmaps;
355         int         sizechar;
356         CharInfoPtr metric;
357
358         sizepadbitmaps = 0;
359         metric = bitmapFont->metrics;
360         for (i = 0; i < num_chars; i++)
361         {
362             if (metric->bits)
363                 sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
364             metric++;
365         }
366         padbitmaps = malloc(sizepadbitmaps);
367         if (!padbitmaps) {
368             snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
369             free (bitmaps);
370             free (fontspace);
371             return AllocError;
372         }
373         metric = bitmapFont->metrics;
374         bitmapFont->bitmaps = padbitmaps;
375         for (i = 0; i < num_chars; i++) {
376             sizechar = RepadBitmap(metric->bits, padbitmaps,
377                                def_glyph, glyph,
378                                metric->metrics.rightSideBearing -
379                                metric->metrics.leftSideBearing,
380                                metric->metrics.ascent + metric->metrics.descent);
381             metric->bits = padbitmaps;
382             padbitmaps += sizechar;
383             metric++;
384         }
385         free(bitmaps);
386     }
387
388     /* now read and atom'ize properties */
389
390     ret = snfReadProps(&fi, &pFont->info, file);
391     if (ret != Successful) {
392         free(fontspace);
393         return ret;
394     }
395     snfCopyInfo(&fi, &pFont->info);
396
397     /* finally, read the ink metrics if the exist */
398
399     if (fi.inkMetrics) {
400         ret = Successful;
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) {
406             free(fontspace);
407             return ret;
408         }
409     } else {
410         pFont->info.ink_minbounds = pFont->info.minbounds;
411         pFont->info.ink_maxbounds = pFont->info.maxbounds;
412     }
413
414     if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
415         unsigned int r,
416                     c,
417                     cols;
418
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];
427         }
428     }
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;
435     pFont->bit = bit;
436     pFont->byte = byte;
437     pFont->glyph = glyph;
438     pFont->scan = scan;
439     return Successful;
440 }
441
442 int
443 snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
444 {
445     int         ret;
446     snfFontInfoRec fi;
447     int         bytestoskip;
448     int         num_chars;
449
450     ret = snfReadHeader(&fi, file);
451     if (ret != Successful)
452         return ret;
453     snfCopyInfo(&fi, pFontInfo);
454
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));
459         return AllocError;
460     }
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);
466         return AllocError;
467     }
468     num_chars = n2dChars(&fi);
469     bytestoskip = num_chars * sizeof(snfCharInfoRec);   /* charinfos */
470     bytestoskip += BYTESOFGLYPHINFO(&fi);
471     (void)FontFileSkip(file, bytestoskip);
472
473     ret = snfReadProps(&fi, pFontInfo, file);
474     if (ret != Successful) {
475         free(pFontInfo->props);
476         free(pFontInfo->isStringProp);
477         return ret;
478     }
479     if (fi.inkMetrics) {
480         ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
481         if (ret != Successful) {
482             free(pFontInfo->props);
483             free(pFontInfo->isStringProp);
484             return ret;
485         }
486         ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
487         if (ret != Successful) {
488             free(pFontInfo->props);
489             free(pFontInfo->isStringProp);
490             return ret;
491         }
492     } else {
493         pFontInfo->ink_minbounds = pFontInfo->minbounds;
494         pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
495     }
496     return Successful;
497
498 }
499
500 static void
501 snfUnloadFont(FontPtr pFont)
502 {
503     BitmapFontPtr   bitmapFont;
504
505     bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
506     free (bitmapFont->bitmaps);
507     free (bitmapFont);
508     DestroyFontRec (pFont);
509 }
510