~ubuntu-branches/ubuntu/trusty/libxfont/trusty-updates

« back to all changes in this revision

Viewing changes to src/Type1/cidchar.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2007-02-16 14:32:57 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070216143257-r24zgvh3taklylv9
Tags: 1:1.2.7-1
* New upstream release.
* Add XS-Vcs-Git header to debian/control, and drop obsolete CVS information.
* Install the upstream ChangeLog.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved.
2
 
 *
3
 
 * The contents of this file are subject to the CID Font Code Public Licence
4
 
 * Version 1.0 (the "License"). You may not use this file except in compliance
5
 
 * with the Licence. You may obtain a copy of the License at Silicon Graphics,
6
 
 * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA
7
 
 * 94043 or at http://www.sgi.com/software/opensource/cid/license.html.
8
 
 *
9
 
 * Software distributed under the License is distributed on an "AS IS" basis.
10
 
 * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
11
 
 * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF
12
 
 * NON-INFRINGEMENT. See the License for the specific language governing
13
 
 * rights and limitations under the License.
14
 
 *
15
 
 * The Original Software is CID font code that was developed by Silicon
16
 
 * Graphics, Inc.
17
 
 */
18
 
/* $XFree86: xc/lib/font/Type1/cidchar.c,v 1.9tsi Exp $ */
19
 
 
20
 
#ifdef HAVE_CONFIG_H
21
 
#include <config.h>
22
 
#endif
23
 
#ifdef BUILDCID
24
 
#define XFONT_CID 1
25
 
#endif
26
 
 
27
 
#if XFONT_CID
28
 
#ifndef FONTMODULE
29
 
#include <stdio.h>
30
 
#include <string.h>
31
 
#include <sys/stat.h>
32
 
#ifdef USE_MMAP
33
 
#include <sys/mman.h>
34
 
#ifndef MAP_FAILED
35
 
#define MAP_FAILED ((caddr_t)(-1))
36
 
#endif
37
 
#endif
38
 
#else
39
 
#include "Xmd.h"        /* For INT32 declaration */
40
 
#include "Xdefs.h"      /* For Bool */
41
 
#include "xf86_ansic.h"
42
 
#endif
43
 
#ifndef FONTMODULE
44
 
#ifdef _XOPEN_SOURCE
45
 
#include <math.h>
46
 
#else
47
 
#define _XOPEN_SOURCE
48
 
#include <math.h>
49
 
#undef _XOPEN_SOURCE
50
 
#endif
51
 
#endif
52
 
#include <X11/fonts/fntfilst.h>
53
 
#include "objects.h"
54
 
#include "spaces.h"
55
 
#include "range.h"
56
 
#include "util.h"
57
 
#include "fontfcn.h"
58
 
#include "blues.h"
59
 
#include "AFM.h"
60
 
#include "t1intf.h"
61
 
 
62
 
#define BSIZE 4096
63
 
 
64
 
extern cidfont *CIDFontP;
65
 
extern psfont *FDArrayP;
66
 
extern psfont *FontP;
67
 
 
68
 
static unsigned char sd[] = "StartData";
69
 
 
70
 
CharInfoPtr
71
 
CIDGetGlyphInfo(FontPtr pFont, unsigned int cidcode, CharInfoPtr pci, int *rc)
72
 
{
73
 
    CharInfoPtr cp = NULL;
74
 
#ifdef USE_MMAP
75
 
    int   fd;
76
 
    unsigned char *buf;
77
 
    long total_len = 0;
78
 
#else
79
 
    FILE *fp;
80
 
    unsigned char buf[BSIZE];
81
 
    unsigned int count = 0;
82
 
#endif
83
 
    cidglyphs *cid;
84
 
    unsigned char *p1 = NULL;
85
 
#ifndef USE_MMAP
86
 
    unsigned char *p2;
87
 
#endif
88
 
    register int i = 0, j;
89
 
    long byteoffset;
90
 
    int FDindex, FDBytes, GDBytes, SDBytes, SubrCount, CIDMapOffset, len;
91
 
    psobj *arrayP;
92
 
    psobj charstring;
93
 
    long *subroffsets = NULL, cstringoffset, nextcstringoffset;
94
 
    struct blues_struct *blues;
95
 
 
96
 
    cid = (cidglyphs *)pFont->fontPrivate;
97
 
 
98
 
#ifdef USE_MMAP
99
 
    if (!cid->CIDdata) {
100
 
       if (!(fd = open(cid->CIDFontName, O_RDONLY, 0))) {
101
 
           *rc = BadFontName;
102
 
           return(cp);
103
 
       }
104
 
       cid->CIDsize = lseek(fd, 0, SEEK_END);
105
 
       cid->CIDdata = (unsigned char *)
106
 
           mmap(0, (size_t)cid->CIDsize, PROT_READ, MAP_SHARED, fd, 0);
107
 
       close(fd);
108
 
       if (cid->CIDdata == (unsigned char *)MAP_FAILED) {
109
 
           *rc = AllocError;
110
 
           cid->CIDdata = NULL;
111
 
           return (cp);
112
 
       }
113
 
    }
114
 
#else
115
 
    if (!(fp = fopen(cid->CIDFontName,"rb"))) {
116
 
        *rc = BadFontName;
117
 
        return(cp);
118
 
    }
119
 
#endif
120
 
 
121
 
#ifdef USE_MMAP
122
 
    if (cid->dataoffset == 0) {
123
 
       if ((p1 = (unsigned char *)strstr((char *)cid->CIDdata, (char *)sd)) 
124
 
           != NULL) {
125
 
           cid->dataoffset = (p1 - cid->CIDdata) + strlen((char *)sd);
126
 
       }
127
 
       else {
128
 
           *rc = BadFontFormat;
129
 
           return(cp);
130
 
       }
131
 
    }
132
 
#else /* USE_MMAP */
133
 
    if (cid->dataoffset == 0) {
134
 
        p2 = sd;
135
 
 
136
 
        /* find "StartData" */
137
 
        while (*p2) {
138
 
            cid->dataoffset += count;
139
 
            if ((count = fread(buf, 1, BSIZE, fp)) == 0)
140
 
                break;
141
 
            p1 = buf;
142
 
            for (i=0; i < count && *p2; i++) {
143
 
                if (*p1 == *p2)
144
 
                    p2++;
145
 
                else {
146
 
                    p2 = sd;
147
 
                    if (*p1 == *p2)
148
 
                        p2++;
149
 
                }
150
 
                p1++;
151
 
            }
152
 
        }
153
 
 
154
 
        /* if "StartData" not found, or end of file */
155
 
        if (*p2 || count == 0) {
156
 
            *rc = BadFontFormat;
157
 
            fclose(fp);
158
 
            return(cp);
159
 
        }
160
 
 
161
 
        if (i >= count) {
162
 
            cid->dataoffset += count;
163
 
            count = fread(buf, 1, BSIZE, fp);
164
 
            p1 = buf;
165
 
        } else {
166
 
            cid->dataoffset += p1 - buf;
167
 
            count = count - (p1 - buf);
168
 
        }
169
 
    } else {
170
 
        if (fseek(fp, cid->dataoffset, SEEK_SET)) {
171
 
            *rc = BadFontFormat;
172
 
            fclose(fp);
173
 
            return(cp);
174
 
        }
175
 
        if ((count = fread(buf, 1, BSIZE, fp)) == 0) {
176
 
            *rc = BadFontFormat;
177
 
            fclose(fp);
178
 
            return(cp);
179
 
        }
180
 
        p1 = buf;
181
 
    }
182
 
 
183
 
    /* if "StartData" not found, or "Binary" data and the next character */
184
 
    /* is not the space character (0x20)                                 */
185
 
 
186
 
    if (count == 0 || (CIDFontP->binarydata && (*p1 != ' '))) {
187
 
        *rc = BadFontFormat;
188
 
        fclose(fp);
189
 
        return(cp);
190
 
    }
191
 
#endif /* USE_MMAP */
192
 
 
193
 
    FDBytes = CIDFontP->CIDfontInfoP[CIDFDBYTES].value.data.integer;
194
 
    GDBytes = CIDFontP->CIDfontInfoP[CIDGDBYTES].value.data.integer;
195
 
    CIDMapOffset = CIDFontP->CIDfontInfoP[CIDMAPOFFSET].value.data.integer;
196
 
    byteoffset = cid->dataoffset + 1 + CIDMapOffset +
197
 
        cidcode * (FDBytes + GDBytes);
198
 
#ifdef USE_MMAP
199
 
    buf = &cid->CIDdata[byteoffset];
200
 
#else
201
 
    if (fseek(fp, byteoffset, SEEK_SET)) {
202
 
        *rc = BadFontFormat;
203
 
        fclose(fp);
204
 
        return(cp);
205
 
    }
206
 
    if ((count = fread(buf, 1, BSIZE, fp)) < 2*(FDBytes + GDBytes)) {
207
 
        *rc = BadFontFormat;
208
 
        fclose(fp);
209
 
        return(cp);
210
 
    }
211
 
#endif
212
 
 
213
 
    /* if FDBytes is equal to 0, the CIDMap contains no FD indices, and the */
214
 
    /* FD index of 0 is assumed.                                            */
215
 
    if (FDBytes == 0)
216
 
        FDindex = 0;
217
 
    else {
218
 
        FDindex = 0;
219
 
        for (i = 0; i < FDBytes; i++)
220
 
            FDindex += (unsigned char)buf[i] << (8 * (FDBytes - 1 - i));
221
 
    }
222
 
 
223
 
    if (FDindex >= CIDFontP->CIDfontInfoP[CIDFDARRAY].value.len) {
224
 
        *rc = BadFontFormat;
225
 
#ifndef USE_MMAP
226
 
        fclose(fp);
227
 
#endif
228
 
        return(cp);
229
 
    }
230
 
 
231
 
    cstringoffset = 0;
232
 
    for (i = 0; i < GDBytes; i++)
233
 
        cstringoffset += (unsigned char)buf[FDBytes + i] <<
234
 
            (8 * (GDBytes - 1 - i));
235
 
 
236
 
    nextcstringoffset = 0;
237
 
    for (i = 0; i < GDBytes; i++)
238
 
        nextcstringoffset += (unsigned char)buf[2*FDBytes + GDBytes + i] <<
239
 
            (8 * (GDBytes - 1 - i));
240
 
 
241
 
    len = nextcstringoffset - cstringoffset;
242
 
 
243
 
    if (len <= 0) { /* empty interval, missing glyph */
244
 
        *rc = BadFontFormat;
245
 
#ifndef USE_MMAP
246
 
        fclose(fp);
247
 
#endif
248
 
        return(cp);
249
 
    }
250
 
 
251
 
    FontP = &FDArrayP[FDindex];
252
 
 
253
 
    charstring.type = OBJ_INTEGER;
254
 
    charstring.len = len;
255
 
 
256
 
#ifndef USE_MMAP
257
 
    if (!(charstring.data.stringP = (unsigned char *)xalloc(len))) {
258
 
        *rc = AllocError;
259
 
        fclose(fp);
260
 
        return(cp);
261
 
    }
262
 
#endif
263
 
 
264
 
    byteoffset = cid->dataoffset + 1 + cstringoffset;
265
 
 
266
 
#ifdef USE_MMAP
267
 
    charstring.data.stringP =  &cid->CIDdata[byteoffset];
268
 
#else
269
 
    if (fseek(fp, byteoffset, SEEK_SET)) {
270
 
        *rc = BadFontFormat;
271
 
        xfree(charstring.data.stringP);
272
 
        fclose(fp);
273
 
        return(cp);
274
 
    }
275
 
 
276
 
    if ((count = fread(charstring.data.stringP, 1, len, fp)) != len) {
277
 
        *rc = BadFontFormat;
278
 
        xfree(charstring.data.stringP);
279
 
        fclose(fp);
280
 
        return(cp);
281
 
    }
282
 
#endif
283
 
 
284
 
    if (FontP->Subrs.data.arrayP == NULL) {
285
 
        /* get subroutine data */
286
 
        byteoffset = cid->dataoffset + 1 +
287
 
            FDArrayP[FDindex].Private[CIDT1SUBMAPOFF].value.data.integer;
288
 
 
289
 
        SDBytes = FDArrayP[FDindex].Private[CIDT1SDBYTES].value.data.integer;
290
 
 
291
 
        SubrCount = FDArrayP[FDindex].Private[CIDT1SUBRCNT].value.data.integer;
292
 
#ifdef USE_MMAP
293
 
        buf = &cid->CIDdata[byteoffset];
294
 
#else
295
 
        if (fseek(fp, byteoffset, SEEK_SET)) {
296
 
            *rc = BadFontFormat;
297
 
            fclose(fp);
298
 
            return(cp);
299
 
        }
300
 
 
301
 
        if ((count = fread(buf, 1, BSIZE, fp)) < SDBytes * (SubrCount + 1)) {
302
 
            *rc = BadFontFormat;
303
 
            fclose(fp);
304
 
            return(cp);
305
 
        }
306
 
#endif
307
 
 
308
 
        arrayP = (psobj *)vm_alloc(SubrCount*sizeof(psobj));
309
 
        if (!arrayP) {
310
 
            *rc = AllocError;
311
 
#ifndef USE_MMAP
312
 
            fclose(fp);
313
 
#endif
314
 
            return(cp);
315
 
        }  
316
 
 
317
 
        if (!(subroffsets = (long *)xalloc((SubrCount + 1)*sizeof(long)))) {
318
 
            *rc = AllocError;
319
 
#ifndef USE_MMAP
320
 
            fclose(fp);
321
 
#endif
322
 
            return(cp);
323
 
        }
324
 
 
325
 
        for (i = 0; i <= SubrCount; i++) {
326
 
            subroffsets[i] = 0;
327
 
            for (j = 0; j < SDBytes; j++)
328
 
                subroffsets[i] += (unsigned char)buf[i * SDBytes + j] <<
329
 
                    (8 * (SDBytes - 1 - j));
330
 
        }
331
 
 
332
 
        byteoffset = cid->dataoffset + 1 + subroffsets[0];
333
 
 
334
 
        /* get subroutine info */
335
 
#ifndef USE_MMAP
336
 
        if (fseek(fp, byteoffset, SEEK_SET)) {
337
 
            *rc = BadFontFormat;
338
 
            xfree(subroffsets);
339
 
            fclose(fp);
340
 
            return(cp);
341
 
        }
342
 
#else
343
 
        total_len = byteoffset;
344
 
#endif
345
 
        for (i = 0; i < SubrCount; i++) {
346
 
            len = subroffsets[i + 1] - subroffsets[i];
347
 
#ifndef USE_MMAP
348
 
            arrayP[i].data.valueP = vm_alloc(len);
349
 
            if (!arrayP[i].data.valueP) {
350
 
                *rc = AllocError;
351
 
                xfree(subroffsets);
352
 
                fclose(fp);
353
 
                return(cp);
354
 
            }
355
 
#endif
356
 
            arrayP[i].len = len;
357
 
#ifdef USE_MMAP
358
 
            arrayP[i].data.valueP = (char *)&cid->CIDdata[total_len];
359
 
            total_len += len;
360
 
#else
361
 
            if ((count = fread(arrayP[i].data.valueP, 1, len, fp)) != len) {
362
 
                *rc = BadFontFormat;
363
 
                xfree(subroffsets);
364
 
                fclose(fp);
365
 
                return(cp);
366
 
            }
367
 
#endif
368
 
        }
369
 
 
370
 
        FontP->Subrs.len = SubrCount;
371
 
        FontP->Subrs.data.arrayP =  arrayP;
372
 
        xfree(subroffsets);
373
 
    }
374
 
 
375
 
    if (FontP->BluesP == NULL) {
376
 
        blues = (struct blues_struct *) vm_alloc(sizeof(struct blues_struct));
377
 
        if (!blues) {
378
 
            *rc = AllocError;
379
 
#ifndef USE_MMAP
380
 
            xfree(subroffsets);
381
 
            fclose(fp);
382
 
#endif
383
 
            return(cp);
384
 
        }
385
 
        bzero(blues, sizeof(struct blues_struct));
386
 
        blues->numBlueValues =
387
 
            FDArrayP[FDindex].Private[CIDT1BLUEVALUES].value.len;
388
 
        for (i = 0; i < blues->numBlueValues; i++)
389
 
            blues->BlueValues[i] =
390
 
                FDArrayP[FDindex].Private[CIDT1BLUEVALUES].value.data.arrayP[i].data.integer;
391
 
        blues->numOtherBlues =
392
 
            FDArrayP[FDindex].Private[CIDT1OTHERBLUES].value.len;
393
 
        for (i = 0; i < blues->numOtherBlues; i++)
394
 
            blues->OtherBlues[i] =
395
 
                FDArrayP[FDindex].Private[CIDT1OTHERBLUES].value.data.arrayP[i].data.integer;
396
 
        blues->numFamilyBlues =
397
 
            FDArrayP[FDindex].Private[CIDT1FAMBLUES].value.len;
398
 
        for (i = 0; i < blues->numFamilyBlues; i++)
399
 
            blues->FamilyBlues[i] =
400
 
                FDArrayP[FDindex].Private[CIDT1FAMBLUES].value.data.arrayP[i].data.integer;
401
 
        blues->numFamilyOtherBlues =
402
 
            FDArrayP[FDindex].Private[CIDT1FAMOTHERBLUES].value.len;
403
 
        for (i = 0; i < blues->numFamilyOtherBlues; i++)
404
 
            blues->FamilyOtherBlues[i] =
405
 
                FDArrayP[FDindex].Private[CIDT1FAMOTHERBLUES].value.data.arrayP[i].data.integer;
406
 
        blues->BlueScale = FDArrayP[FDindex].Private[CIDT1BLUESCALE].value.data.real;
407
 
        blues->BlueShift = FDArrayP[FDindex].Private[CIDT1BLUESHIFT].value.data.integer;
408
 
        blues->BlueFuzz = FDArrayP[FDindex].Private[CIDT1BLUEFUZZ].value.data.integer;
409
 
        blues->StdHW = (double)FDArrayP[FDindex].Private[CIDT1STDHW].value.data.arrayP[0].data.integer;
410
 
        blues->StdVW = (double)FDArrayP[FDindex].Private[CIDT1STDVW].value.data.arrayP[0].data.integer;
411
 
 
412
 
        blues->numStemSnapH =
413
 
            FDArrayP[FDindex].Private[CIDT1STEMSNAPH].value.len;
414
 
        for (i = 0; i < blues->numStemSnapH; i++)
415
 
            blues->StemSnapH[i] =
416
 
                FDArrayP[FDindex].Private[CIDT1STEMSNAPH].value.data.arrayP[i].data.integer;
417
 
        blues->numStemSnapV =
418
 
            FDArrayP[FDindex].Private[CIDT1STEMSNAPV].value.len;
419
 
        for (i = 0; i < blues->numStemSnapV; i++)
420
 
            blues->StemSnapV[i] =
421
 
                FDArrayP[FDindex].Private[CIDT1STEMSNAPV].value.data.arrayP[i].data.integer;
422
 
        blues->ForceBold =
423
 
            FDArrayP[FDindex].Private[CIDT1FORCEBOLD].value.data.boolean;
424
 
 
425
 
        blues->LanguageGroup =
426
 
            FDArrayP[FDindex].Private[CIDT1LANGGROUP].value.data.integer;
427
 
 
428
 
        blues->RndStemUp =
429
 
            FDArrayP[FDindex].Private[CIDT1RNDSTEMUP].value.data.boolean;
430
 
 
431
 
        blues->lenIV =
432
 
            FDArrayP[FDindex].Private[CIDT1LENIV].value.data.integer;
433
 
 
434
 
        blues->ExpansionFactor =
435
 
            FDArrayP[FDindex].Private[CIDT1EXPFACTOR].value.data.real;
436
 
 
437
 
        FontP->BluesP = blues;
438
 
    }
439
 
 
440
 
    cp = CIDRenderGlyph(pFont, &charstring, &FontP->Subrs, FontP->BluesP, pci, rc);
441
 
 
442
 
#ifndef USE_MMAP
443
 
    xfree(charstring.data.stringP);
444
 
 
445
 
    fclose(fp);
446
 
#endif
447
 
    return(cp);
448
 
}
449
 
 
450
 
static int 
451
 
node_compare(const void *node1, const void *node2)
452
 
{
453
 
   return (((Metrics *)node1)->code - ((Metrics *)node2)->code);
454
 
}
455
 
 
456
 
static CharInfoRec *
457
 
CIDGetCharMetrics(FontPtr pFont, FontInfo *fi, unsigned int charcode, double sxmult)
458
 
{
459
 
    CharInfoPtr cp;
460
 
    Metrics *p, node;
461
 
    unsigned int cidcode;
462
 
 
463
 
    cidcode = node.code = getCID(pFont, charcode);
464
 
    if ((cidcode < fi->nChars) && (cidcode == fi->metrics[cidcode].code))
465
 
        p = &fi->metrics[cidcode];
466
 
    else
467
 
        p = (Metrics *)bsearch(&node, fi->metrics, fi->nChars, sizeof(Metrics), node_compare);
468
 
 
469
 
    if (!p)
470
 
        p = &fi->metrics[0];
471
 
 
472
 
    if (!(cp = (CharInfoRec *)Xalloc(sizeof(CharInfoRec))))
473
 
        return NULL;
474
 
    bzero(cp, sizeof(CharInfoRec));
475
 
 
476
 
    /* indicate that character bitmap is not defined */
477
 
    cp->bits = (char *)CID_BITMAP_UNDEFINED;
478
 
 
479
 
 
480
 
    /* get metric data for this CID code from the CID AFM file */
481
 
    cp->metrics.leftSideBearing =
482
 
        floor(p->charBBox.llx / sxmult + 0.5);
483
 
    cp->metrics.rightSideBearing =
484
 
        floor(p->charBBox.urx / sxmult + 0.5);
485
 
    cp->metrics.characterWidth = floor(p->wx / sxmult + 0.5);
486
 
    cp->metrics.ascent = floor(p->charBBox.ury / sxmult + 0.5);
487
 
    cp->metrics.descent = -floor(p->charBBox.lly / sxmult + 0.5);
488
 
 
489
 
    cp->metrics.attributes = p->wx;
490
 
 
491
 
    return cp;
492
 
}
493
 
 
494
 
int 
495
 
CIDGetAFM(FontPtr pFont, unsigned long count, unsigned char *chars, FontEncoding charEncoding, unsigned long *glyphCount, CharInfoPtr *glyphs, char *cidafmfile)
496
 
{
497
 
    FILE *fp;
498
 
    FontInfo *fi = NULL;
499
 
    cidglyphs *cid;
500
 
    CharInfoPtr *glyphsBase;
501
 
    register unsigned int c;
502
 
 
503
 
    register CharInfoPtr pci;
504
 
    CharInfoPtr pDefault;
505
 
    unsigned int firstCol, code, char_row, char_col;
506
 
    double sxmult;
507
 
 
508
 
    cid = (cidglyphs *)pFont->fontPrivate;
509
 
 
510
 
    if (cid->AFMinfo == NULL) {
511
 
        if (!(fp = fopen(cidafmfile, "rb")))
512
 
            return(BadFontName);
513
 
 
514
 
        if (CIDAFM(fp, &fi) != 0) {
515
 
            fprintf(stderr,
516
 
                "There is something wrong with Adobe Font Metric file %s.\n",
517
 
                cidafmfile);
518
 
            fclose(fp);
519
 
            return(BadFontName);
520
 
        }
521
 
        fclose(fp);
522
 
        cid->AFMinfo = fi;
523
 
    }
524
 
    fi = cid->AFMinfo;
525
 
 
526
 
    firstCol   = pFont->info.firstCol;
527
 
    pDefault   = cid->pDefault;
528
 
    glyphsBase = glyphs;
529
 
 
530
 
    /* multiplier for computation of raw values */
531
 
    sxmult = hypot(cid->pixel_matrix[0], cid->pixel_matrix[1]);
532
 
    if (sxmult > EPS) sxmult = 1000.0 / sxmult;
533
 
    if (sxmult == 0.0) return(0);
534
 
 
535
 
    switch (charEncoding) {
536
 
 
537
 
#define EXIST(pci) \
538
 
    ((pci)->metrics.attributes || \
539
 
     (pci)->metrics.ascent != -(pci)->metrics.descent || \
540
 
     (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing)
541
 
 
542
 
    case Linear8Bit:
543
 
    case TwoD8Bit:
544
 
        if (pFont->info.firstRow > 0)
545
 
            break;
546
 
        while (count--) {
547
 
            c = (*chars++);
548
 
            if (c >= firstCol && c <= pFont->info.lastCol) {
549
 
                code = c - firstCol;
550
 
                if (!(pci = (CharInfoRec *)cid->glyphs[code]))
551
 
                    pci = CIDGetCharMetrics(pFont, fi, c, sxmult);
552
 
                if (pci && EXIST(pci)) {
553
 
                    *glyphs++ = pci;
554
 
                    cid->glyphs[code] = pci;
555
 
                }
556
 
            } else if (pDefault)
557
 
                *glyphs++ = pDefault;
558
 
        }
559
 
        break;
560
 
    case Linear16Bit:
561
 
        while (count--) {
562
 
            char_row = *chars++;
563
 
            char_col = *chars++;
564
 
            c = char_row << 8;
565
 
            c = (c | char_col);
566
 
            if (pFont->info.firstRow <= char_row && char_row <=
567
 
                pFont->info.lastRow && pFont->info.firstCol <= char_col &&
568
 
                char_col <= pFont->info.lastCol) {
569
 
                code = pFont->info.lastCol - pFont->info.firstCol + 1;
570
 
                char_row = char_row - pFont->info.firstRow;
571
 
                char_col = char_col - pFont->info.firstCol;
572
 
                code = char_row * code + char_col;
573
 
                if (!(pci = (CharInfoRec *)cid->glyphs[code]))
574
 
                    pci = CIDGetCharMetrics(pFont, fi, c, sxmult);
575
 
                if (pci && EXIST(pci)) {
576
 
                    *glyphs++ = pci;
577
 
                    cid->glyphs[code] = pci;
578
 
                } else if (pDefault) {
579
 
                    *glyphs++ = pDefault;
580
 
                    cid->glyphs[code] = pDefault;
581
 
                }
582
 
            } else if (pDefault)
583
 
                *glyphs++ = pDefault;
584
 
        }
585
 
        break;
586
 
 
587
 
    case TwoD16Bit:
588
 
        while (count--) {
589
 
            char_row = (*chars++);
590
 
            char_col = (*chars++);
591
 
            c = char_row << 8;
592
 
            c = (c | char_col);
593
 
            if (pFont->info.firstRow <= char_row && char_row <=
594
 
                pFont->info.lastRow && pFont->info.firstCol <= char_col &&
595
 
                char_col <= pFont->info.lastCol) {
596
 
                code = pFont->info.lastCol - pFont->info.firstCol + 1;
597
 
                char_row = char_row - pFont->info.firstRow;
598
 
                char_col = char_col - pFont->info.firstCol;
599
 
                code = char_row * code + char_col;
600
 
                if (!(pci = (CharInfoRec *)cid->glyphs[code]))
601
 
                    pci = CIDGetCharMetrics(pFont, fi, c, sxmult);
602
 
                if (pci && EXIST(pci)) {
603
 
                    *glyphs++ = pci;
604
 
                    cid->glyphs[code] = pci;
605
 
                } else if (pDefault) {
606
 
                    *glyphs++ = pDefault;
607
 
                    cid->glyphs[code] = pDefault;
608
 
                }
609
 
            } else if (pDefault)
610
 
                *glyphs++ = pDefault;
611
 
        }
612
 
        break;
613
 
    }
614
 
    *glyphCount = glyphs - glyphsBase;
615
 
 
616
 
#undef EXIST
617
 
 
618
 
    return Successful;
619
 
 
620
 
}
621
 
#endif