~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/PEX5/ospex/osPexFont.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: osPexFont.c,v 1.4 2001/02/09 02:04:19 xorgcvs Exp $ */
 
2
 
 
3
/*
 
4
 
 
5
Copyright 1989, 1990, 1991, 1998  The Open Group
 
6
 
 
7
Permission to use, copy, modify, distribute, and sell this software and its
 
8
documentation for any purpose is hereby granted without fee, provided that
 
9
the above copyright notice appear in all copies and that both that
 
10
copyright notice and this permission notice appear in supporting
 
11
documentation.
 
12
 
 
13
The above copyright notice and this permission notice shall be included in
 
14
all copies or substantial portions of the Software.
 
15
 
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
19
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
20
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
Except as contained in this notice, the name of The Open Group shall not be
 
24
used in advertising or otherwise to promote the sale, use or other dealings
 
25
in this Software without prior written authorization from The Open Group.
 
26
 
 
27
 
 
28
Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. 
 
29
 
 
30
                        All Rights Reserved
 
31
 
 
32
Permission to use, copy, modify, and distribute this software and its 
 
33
documentation for any purpose and without fee is hereby granted, 
 
34
provided that the above copyright notice appear in all copies and that
 
35
both that copyright notice and this permission notice appear in 
 
36
supporting documentation, and that the name of Sun Microsystems,
 
37
not be used in advertising or publicity pertaining to distribution of 
 
38
the software without specific, written prior permission.  
 
39
 
 
40
SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
 
41
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT 
 
42
SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
 
43
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
44
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
45
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
46
SOFTWARE.
 
47
 
 
48
*/
 
49
/* $XFree86: xc/programs/Xserver/PEX5/ospex/osPexFont.c,v 3.19 2002/05/31 18:45:53 dawes Exp $ */
 
50
 
 
51
#ifdef WIN32
 
52
#define _WILLWINSOCK_
 
53
#endif
 
54
 
 
55
#include "mipex.h"
 
56
#include "miFont.h"
 
57
#include "PEXErr.h"
 
58
#define XK_LATIN1
 
59
#include "keysymdef.h"
 
60
#define NEED_GETENV
 
61
#define NEED_OS_LIMITS
 
62
#include "pexos.h"
 
63
 
 
64
#ifndef PEX_DEFAULT_FONTPATH
 
65
#define PEX_DEFAULT_FONTPATH "/usr/lib/X11/fonts/PEX"
 
66
#endif
 
67
 
 
68
#ifndef WIN32
 
69
 
 
70
#ifndef XFree86LOADER
 
71
 
 
72
#if !defined(X_NOT_POSIX) || defined(SYSV) || defined(__CYGWIN__) || defined(USG)
 
73
#include <dirent.h>
 
74
#else
 
75
#include <sys/dir.h>
 
76
#ifndef dirent
 
77
#define dirent direct
 
78
#endif
 
79
#endif
 
80
typedef struct dirent    ENTRY;
 
81
 
 
82
#ifndef FILENAME_MAX
 
83
#ifdef MAXNAMLEN
 
84
#define FILENAME_MAX MAXNAMLEN
 
85
#else
 
86
#define FILENAME_MAX 255
 
87
#endif
 
88
#endif
 
89
 
 
90
#else /* XFree86LOADER */
 
91
 
 
92
/* XXX This should be taken care of elsewhere */
 
93
typedef struct _xf86dirent ENTRY;
 
94
 
 
95
#endif /* XFree86LOADER */
 
96
 
 
97
#define FileName(file) file->d_name
 
98
 
 
99
#else  /* WIN32 */
 
100
 
 
101
#define BOOL wBOOL
 
102
#define ATOM wATOM
 
103
#include <windows.h>
 
104
#undef BOOL
 
105
#undef ATOM
 
106
#define FileName(file) file.cFileName
 
107
 
 
108
#endif /* WIN32 */
 
109
 
 
110
extern void CopyISOLatin1Lowered();
 
111
extern int get_lowered_truncated_entry();
 
112
 
 
113
void ClosePEXFontFile();
 
114
void SetPEXFontFilePtr();
 
115
 
 
116
extern  diFontHandle defaultPEXFont;
 
117
 
 
118
/*
 
119
 * Unless an environment variable named PEX_FONTPATH is set before the
 
120
 * server is started up, PEX will look in the path defined in the
 
121
 * PEX_DEFAULT_FONTPATH compiler constant defined in miFont.h for PEX fonts.
 
122
 * If environment variable PEX_FONTPATH is defined, then this will
 
123
 * be used as the path to the fonts .
 
124
 */
 
125
 
 
126
static char *
 
127
pex_get_font_directory_path()
 
128
{
 
129
    static int   already_determined = 0;
 
130
    static char *font_dir_path = NULL;
 
131
    
 
132
    if (!already_determined) {
 
133
        if (getenv("PEX_FONTPATH")) {
 
134
            font_dir_path = 
 
135
               (char *)xalloc((unsigned long)(1+strlen(getenv("PEX_FONTPATH"))));
 
136
            strcpy(font_dir_path, getenv("PEX_FONTPATH"));
 
137
        } else {
 
138
#ifndef __UNIXOS2__
 
139
            font_dir_path =
 
140
                (char *)xalloc((unsigned long)(1+strlen(PEX_DEFAULT_FONTPATH)));
 
141
            strcpy(font_dir_path, PEX_DEFAULT_FONTPATH);
 
142
#else
 
143
            char *p = (char*)__XOS2RedirRoot(PEX_DEFAULT_FONTPATH);
 
144
            font_dir_path =
 
145
                (char *)xalloc((unsigned long)(1+strlen(p)));
 
146
            strcpy(font_dir_path, p);
 
147
#endif
 
148
        }
 
149
        already_determined = 1;
 
150
    }
 
151
    
 
152
    return (font_dir_path);
 
153
}
 
154
 
 
155
 
 
156
/*
 
157
 * The next two functions (pex_setup_wild_match() and pex_is_matching()) are 
 
158
 * stolen (and slightly modified) from MIT X11R4 fonts/mkfontdir/fontdir.c.
 
159
 * pex_setup_wild_match() sets up some state about the pattern to match, which
 
160
 * pex_is_matching() then uses.
 
161
 */
 
162
 
 
163
 
 
164
/* results of this function are used by pex_is_matching() */
 
165
 
 
166
static void
 
167
pex_setup_wild_match(pat, phead, ptail, plen)
 
168
char    *pat;                   /* in */
 
169
int     *phead, *ptail, *plen;  /* out */
 
170
{
 
171
    register int head, tail;
 
172
    register char c, *firstWild;
 
173
 
 
174
    *plen = tail = strlen(pat);
 
175
    for (   firstWild = pat; 
 
176
            ((c = *firstWild) && !((c == XK_asterisk) || (c == XK_question)));
 
177
            firstWild++)
 
178
        ;
 
179
            
 
180
    head = firstWild - pat;
 
181
 
 
182
    while ((c = pat[head]) && (c != XK_asterisk))
 
183
        head++;
 
184
    if (head < tail)
 
185
    {
 
186
        while (pat[tail-1] != XK_asterisk)
 
187
            tail--;
 
188
    }
 
189
    *phead = head;
 
190
    *ptail = tail;
 
191
}
 
192
 
 
193
/* returns value greater than 0 if successful.  head, tail, and plen
 
194
 * come from a previous call to pex_setup_wild_match 
 
195
 */
 
196
static int 
 
197
pex_is_matching(string, pat, head, tail, plen)
 
198
register char       *string;            /* in */
 
199
register char       *pat;               /* in */
 
200
int                 head, tail, plen;   /* in */
 
201
{
 
202
    register int i, l;
 
203
    int j, m, res;
 
204
    register char cp, cs;
 
205
 
 
206
    res = -1;
 
207
    for (i = 0; i < head; i++)
 
208
    {
 
209
        cp = pat[i];
 
210
        if (cp == XK_question)
 
211
        {
 
212
            if (!string[i])
 
213
                return res;
 
214
            res = 0;
 
215
        }
 
216
        else if (cp != string[i])
 
217
            return res;
 
218
    }
 
219
    if (head == plen)
 
220
        return (string[head] ? res : 1);
 
221
    l = head;
 
222
    while (++i < tail)
 
223
    {
 
224
        /* we just skipped an asterisk */
 
225
        j = i;
 
226
        m = l;
 
227
        while ((cp = pat[i]) != XK_asterisk)
 
228
        {
 
229
            if (!(cs = string[l]))
 
230
                return 0;
 
231
            if ((cp != cs) && (cp != XK_question))
 
232
            {
 
233
                m++;
 
234
                cp = pat[j];
 
235
                if (cp == XK_asterisk)
 
236
                {
 
237
                    if (!string[m])
 
238
                        return 0;
 
239
                }
 
240
                else
 
241
                {
 
242
                    while ((cs = string[m]) != cp)
 
243
                    {
 
244
                        if (!cs)
 
245
                            return 0;
 
246
                        m++;
 
247
                    }
 
248
                }
 
249
                l = m;
 
250
                i = j;
 
251
            }
 
252
            l++;
 
253
            i++;
 
254
        }
 
255
    }
 
256
    m = strlen(&string[l]);
 
257
    j = plen - tail;
 
258
    if (m < j)
 
259
        return 0;
 
260
    l = (l + m) - j;
 
261
    while (cp = pat[i])
 
262
    {
 
263
        if ((cp != string[l]) && (cp != XK_question))
 
264
            return 0;
 
265
        l++;
 
266
        i++;
 
267
    }
 
268
    return 1;
 
269
}
 
270
 
 
271
/*
 
272
 * Caller is responsible for freeing contents of buffer and buffer when
 
273
 * done with it.
 
274
 */
 
275
#define ABSOLUTE_MAX_NAMES 200
 
276
 
 
277
int
 
278
pex_get_matching_names(patLen, pPattern, maxNames, numNames, names)
 
279
ddUSHORT   patLen;              /* in */
 
280
ddUCHAR   *pPattern;            /* in */
 
281
ddUSHORT   maxNames;            /* in */
 
282
ddULONG   *numNames;            /* out - number of names found */
 
283
char    ***names;               /* out - pointer to list of strings */
 
284
{
 
285
#ifdef WIN32
 
286
    HANDLE              fontdirh;
 
287
    WIN32_FIND_DATA     dir_entry;
 
288
    char                path[MAX_PATH];
 
289
#else
 
290
    DIR             *fontdir;
 
291
    ENTRY           *dir_entry;
 
292
#endif
 
293
    char             *pattern;
 
294
    char             entry[PATH_MAX+1];
 
295
    int              i, head, tail, len, total = 0;
 
296
    
 
297
    if (!(pattern = (char *)xalloc((unsigned long)(1 + patLen))))
 
298
        return 0;
 
299
 
 
300
    CopyISOLatin1Lowered((unsigned char*)pattern, pPattern, patLen);
 
301
    
 
302
    if (!(*names = (char **)xalloc((unsigned long)(ABSOLUTE_MAX_NAMES * sizeof(char *)))))
 
303
        return 0;
 
304
    
 
305
#ifdef WIN32
 
306
    sprintf(path, "%s/*.*", pex_get_font_directory_path());
 
307
    if ((fontdirh = FindFirstFile(path, &dir_entry)) == INVALID_HANDLE_VALUE) {
 
308
        xfree(*names);
 
309
        xfree(pattern);
 
310
        return 0;
 
311
    }
 
312
#else
 
313
    if (!(fontdir = opendir(pex_get_font_directory_path()))) {
 
314
        xfree(*names);
 
315
        xfree(pattern);
 
316
        return 0;
 
317
    }
 
318
#endif
 
319
 
 
320
    pex_setup_wild_match(pattern, &head, &tail, &len);
 
321
    
 
322
#ifdef WIN32
 
323
    do
 
324
#else
 
325
    while (total < maxNames && (dir_entry = readdir(fontdir)))
 
326
#endif
 
327
        {
 
328
        
 
329
            if (!get_lowered_truncated_entry(FileName(dir_entry), entry))
 
330
                continue;
 
331
 
 
332
            if (pex_is_matching(entry, pattern, head, tail, len) > 0) {
 
333
            
 
334
                if (!( (*names)[total] = (char *)xalloc((unsigned long)(1 + strlen(entry))))) {
 
335
                    for (i = 0; i < total; i++)
 
336
                        xfree((*names)[i]);
 
337
                    xfree(*names);
 
338
                    xfree(pattern);
 
339
                    return 0;
 
340
                }
 
341
                
 
342
                strcpy((*names)[total], entry);
 
343
                total++;
 
344
            }
 
345
        }
 
346
#ifdef WIN32
 
347
    while (total < maxNames && FindNextFile(fontdirh, &dir_entry));
 
348
#endif
 
349
 
 
350
#ifdef WIN32
 
351
    FindClose(fontdirh);
 
352
#else
 
353
    closedir(fontdir);
 
354
#endif
 
355
    
 
356
    *numNames = total;
 
357
    
 
358
    return 1;
 
359
}
 
360
 
 
361
/*
 
362
 * get_stroke(stroke, fp) extracts the definition of characters
 
363
 * from the font file.  It return -1 if anything goes wrong, 0 if
 
364
 * everything is OK.  
 
365
 */
 
366
 
 
367
static int
 
368
get_stroke(stroke, fp)
 
369
    Ch_stroke_data     *stroke;
 
370
    FILE               *fp;
 
371
{
 
372
    listofddPoint          *spath;
 
373
    register int            i;
 
374
    unsigned long           closed;     /* placeholder, really unused */
 
375
    register ddULONG        npath;
 
376
    register miListHeader  *hdr = &(stroke->strokes);
 
377
 
 
378
    stroke->n_vertices = 0;
 
379
    npath = hdr->maxLists = hdr->numLists;
 
380
    hdr->type = DD_2D_POINT;
 
381
    hdr->ddList = spath = (listofddPoint *)
 
382
        xalloc((unsigned long)(sizeof(listofddPoint) * npath));
 
383
        
 
384
    if (spath == NULL)
 
385
        return -1;
 
386
 
 
387
    for (i = 0; i < npath; i++, spath++)
 
388
        spath->pts.p2Dpt = NULL;
 
389
 
 
390
    for (i = 0, spath = hdr->ddList; i < npath; i++, spath++) {
 
391
    
 
392
        /* for each subpath of the character definition ... */
 
393
        
 
394
        if (fread((char *) &spath->numPoints,
 
395
                  sizeof(spath->numPoints), 1, fp) != 1 ||
 
396
            fread((char *) &closed, sizeof(closed), 1, fp) != 1)
 
397
            return -1;
 
398
 
 
399
        if (spath->numPoints <= 0)
 
400
            continue;
 
401
 
 
402
        spath->maxData = sizeof(ddCoord2D) * spath->numPoints;
 
403
        
 
404
        if (!(spath->pts.p2Dpt = (ddCoord2D *) xalloc((unsigned long)(spath->maxData))))
 
405
            return -1;
 
406
            
 
407
        if (fread((char *)spath->pts.p2Dpt, sizeof(ddCoord2D), 
 
408
                  spath->numPoints, fp) != spath->numPoints)
 
409
            return -1;
 
410
            
 
411
        stroke->n_vertices += spath->numPoints;
 
412
    }
 
413
    return 0;
 
414
}
 
415
 
 
416
 
 
417
 
 
418
/*
 
419
    read in the pex font
 
420
 */
 
421
ErrorCode
 
422
LoadPEXFontFile(length, fontname, pFont)
 
423
    unsigned        length;
 
424
    char *          fontname;
 
425
    diFontHandle    pFont;
 
426
{
 
427
    char                fname[FILENAME_MAX+1];
 
428
    FILE               *fp;
 
429
    Font_file_header    header;
 
430
    Property           *properties = 0;
 
431
    Dispatch           *table = 0;
 
432
    miFontHeader       *font = (miFontHeader *)(pFont->deviceData);
 
433
    int                 found_first, found_it = 0, err = Success, numChars, np;
 
434
    char                *name_to_match;
 
435
    char                lowered_entry[PATH_MAX+1];
 
436
#ifdef WIN32
 
437
    HANDLE              fontdirh;
 
438
    WIN32_FIND_DATA     dir_entry;
 
439
    char                path[MAX_PATH];
 
440
#else
 
441
    DIR                *fontdir;
 
442
    ENTRY              *dir_entry;
 
443
#endif
 
444
    register int        i;
 
445
    register Ch_stroke_data **ch_font, *ch_stroke = 0;
 
446
    register Dispatch  *tblptr = 0;
 
447
    register Property  *propptr = 0;
 
448
    register pexFontProp *fpptr = 0;
 
449
 
 
450
    if (!(name_to_match = (char *)xalloc((unsigned int)(1 + length))))
 
451
        return (PEXERR(PEXFontError));
 
452
 
 
453
    CopyISOLatin1Lowered((unsigned char *)name_to_match,
 
454
                         (unsigned char *)fontname, length);
 
455
 
 
456
    /* open up the font directory and look for matching file names */
 
457
#ifdef WIN32
 
458
    sprintf(path, "%s/*.*", pex_get_font_directory_path());
 
459
    if ((fontdirh = FindFirstFile(path, &dir_entry)) == INVALID_HANDLE_VALUE)
 
460
        return (PEXERR(PEXFontError));
 
461
#else
 
462
    if (!(fontdir = opendir(pex_get_font_directory_path())))
 
463
        return (PEXERR(PEXFontError));
 
464
#endif
 
465
 
 
466
#ifdef WIN32
 
467
    do
 
468
#else
 
469
    while(!found_it && (dir_entry = readdir(fontdir)))
 
470
#endif
 
471
        {
 
472
            /* strip off .phont and make all lower case */
 
473
            if (!get_lowered_truncated_entry(FileName(dir_entry), lowered_entry))
 
474
                continue;
 
475
                
 
476
            /* does this match what got passed in? */
 
477
            if (strcmp(lowered_entry, name_to_match) == 0)
 
478
                found_it = 1;
 
479
        }
 
480
    xfree(name_to_match);
 
481
#ifdef WIN32
 
482
    while (!found_it && FindNextFile(fontdirh, &dir_entry) && !found_it);
 
483
#endif
 
484
    
 
485
    if (!found_it)
 
486
        return (PEXERR(PEXFontError));
 
487
    
 
488
    (void) strcpy(fname, pex_get_font_directory_path());
 
489
    (void) strcat(fname, "/");
 
490
    (void) strcat(fname, FileName(dir_entry));
 
491
    
 
492
#ifdef WIN32
 
493
    FindClose(fontdirh);
 
494
#else
 
495
    closedir(fontdir);
 
496
#endif
 
497
 
 
498
    if ((fp = fopen(fname, "r")) == NULL)
 
499
        return (PEXERR(PEXFontError));
 
500
 
 
501
    /*
 
502
     * read in the file header.  The file header has fields containing the
 
503
     * num of characters in the font, the extreme values, and number of font
 
504
     * properties defined, if any.
 
505
     */
 
506
 
 
507
    tblptr = 0;
 
508
    if (fread((char *) &header, sizeof(header), 1, fp) != 1) {
 
509
        (void) ClosePEXFontFile(fp);
 
510
        return (PEXERR(PEXFontError)); }
 
511
    
 
512
    /* Initialize font structure */
 
513
    (void) strcpy(font->name, header.name);
 
514
    font->font_type = FONT_POLYLINES;
 
515
    font->top = header.top;
 
516
    font->bottom = header.bottom;
 
517
    font->num_ch = header.num_ch;
 
518
    font->font_info.numProps = (CARD32)header.num_props;
 
519
    font->max_width = header.max_width;
 
520
 
 
521
    /* read in the font properties, if any, into font data area */
 
522
    if (header.num_props > 0) {
 
523
 
 
524
        (void) SetPEXFontFilePtr(fp, START_PROPS);   /* Get to props position */
 
525
        properties = (Property *) xalloc(header.num_props * sizeof(Property));
 
526
        if (properties == NULL) {
 
527
            (void) ClosePEXFontFile(fp);
 
528
            return (BadAlloc); }
 
529
 
 
530
        if (fread((char *) properties, sizeof(Property), 
 
531
                  header.num_props, fp) != header.num_props) {
 
532
            xfree((char *) properties);
 
533
            (void) ClosePEXFontFile(fp);
 
534
            return (PEXERR(PEXFontError)); }
 
535
    
 
536
        /* Create space for font properties in the font data area */
 
537
 
 
538
        font->properties =
 
539
            (pexFontProp *) xalloc( (unsigned long)(header.num_props
 
540
                                    * sizeof(pexFontProp)));
 
541
        if (font->properties == NULL) {
 
542
            xfree((char *) properties);
 
543
            (void) ClosePEXFontFile(fp);
 
544
            return (BadAlloc); }
 
545
 
 
546
        np = header.num_props;
 
547
        for (   i=0, propptr = properties, fpptr = font->properties;
 
548
                i < np;
 
549
                i++, propptr++, fpptr++) {
 
550
 
 
551
            if (propptr->propname == NULL) {
 
552
                (header.num_props)--;
 
553
                continue; }
 
554
 
 
555
            fpptr->name = MakeAtom( (char *)propptr->propname,
 
556
                                    strlen(propptr->propname), 1);
 
557
 
 
558
            if (propptr->propvalue != NULL)
 
559
                fpptr->value = MakeAtom((char *)propptr->propvalue,
 
560
                                        strlen(propptr->propvalue), 1);
 
561
            else fpptr->value = 0;
 
562
        }
 
563
 
 
564
        /* free up local storage allocated for properties */
 
565
         xfree((char *) properties);
 
566
    }
 
567
 
 
568
    /* position file pointer to dispatch data */
 
569
    (void) SetPEXFontFilePtr(fp, (long) START_DISPATCH(header.num_props));
 
570
 
 
571
    /*
 
572
     * read in the distable font, use the offset to see if the
 
573
     * character is defined or not.  The strokes are defined in Phigs style.
 
574
     * The "center" of the character is not the physical center. It is the
 
575
     * center defined by the font designer.  The actual center is half the
 
576
     * "right" value.
 
577
     */
 
578
 
 
579
    table = (Dispatch *)xalloc((unsigned long)(sizeof(Dispatch) *font->num_ch));
 
580
    
 
581
    if (table == NULL) {
 
582
        (void) ClosePEXFontFile(fp);
 
583
        return (BadAlloc); }
 
584
    
 
585
    if (fread((char *) table, sizeof(Dispatch), font->num_ch, fp)
 
586
            != font->num_ch) {
 
587
        xfree((char *) table);
 
588
        (void) ClosePEXFontFile(fp);
 
589
        return (PEXERR(PEXFontError)); }
 
590
    
 
591
    font->ch_data =
 
592
        (Ch_stroke_data **) xalloc((unsigned long)(sizeof(Ch_stroke_data *) * 
 
593
                                                    font->num_ch));
 
594
    if (font->ch_data == NULL) {
 
595
        xfree((char *) table);
 
596
        (void) ClosePEXFontFile(fp);
 
597
        return (BadAlloc); }
 
598
    
 
599
    /* The next loop initializes all ch_data pointers to null; essential
 
600
        for non-crashing during font clean-up in case of failed font file
 
601
        read.  Also count the number of non-blank chars.
 
602
     */
 
603
    for (   i = 0, ch_font = font->ch_data, tblptr = table, numChars = 0;
 
604
            i < font->num_ch;
 
605
            i++, ch_font++, tblptr++) {
 
606
        *ch_font = NULL;
 
607
        if (tblptr->offset != 0) numChars++; }
 
608
 
 
609
    ch_stroke = (Ch_stroke_data *)xalloc((unsigned long)(numChars *
 
610
                                                    sizeof(Ch_stroke_data)));
 
611
    if (!ch_stroke) {
 
612
        err = BadAlloc;
 
613
        goto disaster;
 
614
    }
 
615
 
 
616
    /* read in the char data  (the font file format should be changed
 
617
        so that the allocation can be done outside this loop--this
 
618
        method is inefficient)
 
619
     */
 
620
    for (   i = 0, ch_font = font->ch_data, tblptr = table, found_first = 0;
 
621
            i < font->num_ch;
 
622
            i++, ch_font++, tblptr++) {
 
623
        if (tblptr->offset != 0) {
 
624
            (*ch_font) = ch_stroke++;
 
625
            (*ch_font)->strokes.ddList = NULL;
 
626
            (*ch_font)->center = table[i].center;
 
627
            (*ch_font)->right = table[i].right;
 
628
            
 
629
            (void) SetPEXFontFilePtr(fp, tblptr->offset);
 
630
 
 
631
            /* read in the type, number of subpaths, and n_vertices fields */
 
632
            if (    (fread(&((*ch_font)->type),
 
633
                           sizeof(Font_path_type), 1, fp) != 1) 
 
634
                ||  (fread(&((*ch_font)->strokes.numLists),
 
635
                           sizeof(ddULONG),1,fp) != 1)
 
636
                ||  (fread(&((*ch_font)->n_vertices),
 
637
                           sizeof(ddULONG), 1, fp) != 1) )
 
638
                {                 
 
639
                    err = PEXERR(PEXFontError);
 
640
                    goto disaster;
 
641
                }
 
642
            
 
643
            (*ch_font)->strokes.maxLists = (*ch_font)->strokes.numLists;
 
644
            if ((*ch_font)->strokes.numLists > 0) {
 
645
            
 
646
                if (get_stroke(*ch_font, fp)) {
 
647
                    err = BadAlloc;
 
648
                    goto disaster; }
 
649
            
 
650
                if (!found_first) {
 
651
                    font->font_info.firstGlyph = i;
 
652
                    found_first = 1; }
 
653
 
 
654
                font->font_info.lastGlyph = i; }
 
655
            }
 
656
    }
 
657
 
 
658
    xfree((char *)table);
 
659
 
 
660
    (void) ClosePEXFontFile(fp);
 
661
    
 
662
    return (Success);
 
663
 
 
664
disaster:
 
665
    (void) ClosePEXFontFile(fp);
 
666
    if (table) xfree(table);
 
667
#if 0
 
668
    if (pFont == defaultPEXFont) defaultPEXFont = 0;    /* force free */
 
669
#endif
 
670
    FreePEXFont((diFontHandle) pFont, pFont->id);
 
671
    return (err);
 
672
    
 
673
}
 
674
void
 
675
ClosePEXFontFile(fp)
 
676
    FILE *fp;
 
677
{
 
678
    fclose (fp);
 
679
}
 
680
 
 
681
void
 
682
SetPEXFontFilePtr(fp,where)
 
683
    FILE *fp;
 
684
    long where;
 
685
{
 
686
    (void) fseek(fp, where, SEEK_SET);      /* set pointer at "where" bytes
 
687
                                                from the beginning of the file */
 
688
}