1
/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
15
* The Original Software is CID font code that was developed by Silicon
18
/* $XFree86: xc/lib/font/Type1/cidchar.c,v 1.9tsi Exp $ */
35
#define MAP_FAILED ((caddr_t)(-1))
39
#include "Xmd.h" /* For INT32 declaration */
40
#include "Xdefs.h" /* For Bool */
41
#include "xf86_ansic.h"
52
#include <X11/fonts/fntfilst.h>
64
extern cidfont *CIDFontP;
65
extern psfont *FDArrayP;
68
static unsigned char sd[] = "StartData";
71
CIDGetGlyphInfo(FontPtr pFont, unsigned int cidcode, CharInfoPtr pci, int *rc)
73
CharInfoPtr cp = NULL;
80
unsigned char buf[BSIZE];
81
unsigned int count = 0;
84
unsigned char *p1 = NULL;
88
register int i = 0, j;
90
int FDindex, FDBytes, GDBytes, SDBytes, SubrCount, CIDMapOffset, len;
93
long *subroffsets = NULL, cstringoffset, nextcstringoffset;
94
struct blues_struct *blues;
96
cid = (cidglyphs *)pFont->fontPrivate;
100
if (!(fd = open(cid->CIDFontName, O_RDONLY, 0))) {
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);
108
if (cid->CIDdata == (unsigned char *)MAP_FAILED) {
115
if (!(fp = fopen(cid->CIDFontName,"rb"))) {
122
if (cid->dataoffset == 0) {
123
if ((p1 = (unsigned char *)strstr((char *)cid->CIDdata, (char *)sd))
125
cid->dataoffset = (p1 - cid->CIDdata) + strlen((char *)sd);
133
if (cid->dataoffset == 0) {
136
/* find "StartData" */
138
cid->dataoffset += count;
139
if ((count = fread(buf, 1, BSIZE, fp)) == 0)
142
for (i=0; i < count && *p2; i++) {
154
/* if "StartData" not found, or end of file */
155
if (*p2 || count == 0) {
162
cid->dataoffset += count;
163
count = fread(buf, 1, BSIZE, fp);
166
cid->dataoffset += p1 - buf;
167
count = count - (p1 - buf);
170
if (fseek(fp, cid->dataoffset, SEEK_SET)) {
175
if ((count = fread(buf, 1, BSIZE, fp)) == 0) {
183
/* if "StartData" not found, or "Binary" data and the next character */
184
/* is not the space character (0x20) */
186
if (count == 0 || (CIDFontP->binarydata && (*p1 != ' '))) {
191
#endif /* USE_MMAP */
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);
199
buf = &cid->CIDdata[byteoffset];
201
if (fseek(fp, byteoffset, SEEK_SET)) {
206
if ((count = fread(buf, 1, BSIZE, fp)) < 2*(FDBytes + GDBytes)) {
213
/* if FDBytes is equal to 0, the CIDMap contains no FD indices, and the */
214
/* FD index of 0 is assumed. */
219
for (i = 0; i < FDBytes; i++)
220
FDindex += (unsigned char)buf[i] << (8 * (FDBytes - 1 - i));
223
if (FDindex >= CIDFontP->CIDfontInfoP[CIDFDARRAY].value.len) {
232
for (i = 0; i < GDBytes; i++)
233
cstringoffset += (unsigned char)buf[FDBytes + i] <<
234
(8 * (GDBytes - 1 - i));
236
nextcstringoffset = 0;
237
for (i = 0; i < GDBytes; i++)
238
nextcstringoffset += (unsigned char)buf[2*FDBytes + GDBytes + i] <<
239
(8 * (GDBytes - 1 - i));
241
len = nextcstringoffset - cstringoffset;
243
if (len <= 0) { /* empty interval, missing glyph */
251
FontP = &FDArrayP[FDindex];
253
charstring.type = OBJ_INTEGER;
254
charstring.len = len;
257
if (!(charstring.data.stringP = (unsigned char *)xalloc(len))) {
264
byteoffset = cid->dataoffset + 1 + cstringoffset;
267
charstring.data.stringP = &cid->CIDdata[byteoffset];
269
if (fseek(fp, byteoffset, SEEK_SET)) {
271
xfree(charstring.data.stringP);
276
if ((count = fread(charstring.data.stringP, 1, len, fp)) != len) {
278
xfree(charstring.data.stringP);
284
if (FontP->Subrs.data.arrayP == NULL) {
285
/* get subroutine data */
286
byteoffset = cid->dataoffset + 1 +
287
FDArrayP[FDindex].Private[CIDT1SUBMAPOFF].value.data.integer;
289
SDBytes = FDArrayP[FDindex].Private[CIDT1SDBYTES].value.data.integer;
291
SubrCount = FDArrayP[FDindex].Private[CIDT1SUBRCNT].value.data.integer;
293
buf = &cid->CIDdata[byteoffset];
295
if (fseek(fp, byteoffset, SEEK_SET)) {
301
if ((count = fread(buf, 1, BSIZE, fp)) < SDBytes * (SubrCount + 1)) {
308
arrayP = (psobj *)vm_alloc(SubrCount*sizeof(psobj));
317
if (!(subroffsets = (long *)xalloc((SubrCount + 1)*sizeof(long)))) {
325
for (i = 0; i <= SubrCount; i++) {
327
for (j = 0; j < SDBytes; j++)
328
subroffsets[i] += (unsigned char)buf[i * SDBytes + j] <<
329
(8 * (SDBytes - 1 - j));
332
byteoffset = cid->dataoffset + 1 + subroffsets[0];
334
/* get subroutine info */
336
if (fseek(fp, byteoffset, SEEK_SET)) {
343
total_len = byteoffset;
345
for (i = 0; i < SubrCount; i++) {
346
len = subroffsets[i + 1] - subroffsets[i];
348
arrayP[i].data.valueP = vm_alloc(len);
349
if (!arrayP[i].data.valueP) {
358
arrayP[i].data.valueP = (char *)&cid->CIDdata[total_len];
361
if ((count = fread(arrayP[i].data.valueP, 1, len, fp)) != len) {
370
FontP->Subrs.len = SubrCount;
371
FontP->Subrs.data.arrayP = arrayP;
375
if (FontP->BluesP == NULL) {
376
blues = (struct blues_struct *) vm_alloc(sizeof(struct blues_struct));
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;
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;
423
FDArrayP[FDindex].Private[CIDT1FORCEBOLD].value.data.boolean;
425
blues->LanguageGroup =
426
FDArrayP[FDindex].Private[CIDT1LANGGROUP].value.data.integer;
429
FDArrayP[FDindex].Private[CIDT1RNDSTEMUP].value.data.boolean;
432
FDArrayP[FDindex].Private[CIDT1LENIV].value.data.integer;
434
blues->ExpansionFactor =
435
FDArrayP[FDindex].Private[CIDT1EXPFACTOR].value.data.real;
437
FontP->BluesP = blues;
440
cp = CIDRenderGlyph(pFont, &charstring, &FontP->Subrs, FontP->BluesP, pci, rc);
443
xfree(charstring.data.stringP);
451
node_compare(const void *node1, const void *node2)
453
return (((Metrics *)node1)->code - ((Metrics *)node2)->code);
457
CIDGetCharMetrics(FontPtr pFont, FontInfo *fi, unsigned int charcode, double sxmult)
461
unsigned int cidcode;
463
cidcode = node.code = getCID(pFont, charcode);
464
if ((cidcode < fi->nChars) && (cidcode == fi->metrics[cidcode].code))
465
p = &fi->metrics[cidcode];
467
p = (Metrics *)bsearch(&node, fi->metrics, fi->nChars, sizeof(Metrics), node_compare);
472
if (!(cp = (CharInfoRec *)Xalloc(sizeof(CharInfoRec))))
474
bzero(cp, sizeof(CharInfoRec));
476
/* indicate that character bitmap is not defined */
477
cp->bits = (char *)CID_BITMAP_UNDEFINED;
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);
489
cp->metrics.attributes = p->wx;
495
CIDGetAFM(FontPtr pFont, unsigned long count, unsigned char *chars, FontEncoding charEncoding, unsigned long *glyphCount, CharInfoPtr *glyphs, char *cidafmfile)
500
CharInfoPtr *glyphsBase;
501
register unsigned int c;
503
register CharInfoPtr pci;
504
CharInfoPtr pDefault;
505
unsigned int firstCol, code, char_row, char_col;
508
cid = (cidglyphs *)pFont->fontPrivate;
510
if (cid->AFMinfo == NULL) {
511
if (!(fp = fopen(cidafmfile, "rb")))
514
if (CIDAFM(fp, &fi) != 0) {
516
"There is something wrong with Adobe Font Metric file %s.\n",
526
firstCol = pFont->info.firstCol;
527
pDefault = cid->pDefault;
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);
535
switch (charEncoding) {
538
((pci)->metrics.attributes || \
539
(pci)->metrics.ascent != -(pci)->metrics.descent || \
540
(pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing)
544
if (pFont->info.firstRow > 0)
548
if (c >= firstCol && c <= pFont->info.lastCol) {
550
if (!(pci = (CharInfoRec *)cid->glyphs[code]))
551
pci = CIDGetCharMetrics(pFont, fi, c, sxmult);
552
if (pci && EXIST(pci)) {
554
cid->glyphs[code] = pci;
557
*glyphs++ = pDefault;
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)) {
577
cid->glyphs[code] = pci;
578
} else if (pDefault) {
579
*glyphs++ = pDefault;
580
cid->glyphs[code] = pDefault;
583
*glyphs++ = pDefault;
589
char_row = (*chars++);
590
char_col = (*chars++);
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)) {
604
cid->glyphs[code] = pci;
605
} else if (pDefault) {
606
*glyphs++ = pDefault;
607
cid->glyphs[code] = pDefault;
610
*glyphs++ = pDefault;
614
*glyphCount = glyphs - glyphsBase;