diff options
Diffstat (limited to 'src/Type1/t1funcs.c')
-rw-r--r-- | src/Type1/t1funcs.c | 1219 |
1 files changed, 1093 insertions, 126 deletions
diff --git a/src/Type1/t1funcs.c b/src/Type1/t1funcs.c index ef113db..20b7b66 100644 --- a/src/Type1/t1funcs.c +++ b/src/Type1/t1funcs.c @@ -54,6 +54,24 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/t1funcs.c,v 3.30 2002/12/09 17:29:59 dawes Exp $ */ /* @@ -82,8 +100,14 @@ other dealings in this Software without prior written authorization from The Open Group. */ - + +#ifndef FONTMODULE #include <string.h> +#ifdef BUILDCID +#include <stdlib.h> +#include <sys/types.h> +#include <dirent.h> +#endif #ifdef _XOPEN_SOURCE #include <math.h> #else @@ -92,54 +116,386 @@ from The Open Group. #undef _XOPEN_SOURCE #endif #include "X11/Xfuncs.h" +#ifdef USE_MMAP +#include <sys/types.h> +#include <sys/mman.h> +#endif +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include "os.h" #include "fntfilst.h" +#include "fontutil.h" #include "FSproto.h" -#include "t1intf.h" +#include "fontenc.h" +#include "t1unicode.h" +#ifdef BUILDCID +#include "range.h" +#endif + #include "objects.h" #include "spaces.h" +#include "paths.h" #include "regions.h" #include "t1stdio.h" #include "util.h" #include "fontfcn.h" - -int Type1OpenScalable (); -static int Type1GetGlyphs(); -void Type1CloseFont(); -extern int Type1GetInfoScalable (); - -static int Type1GetMetrics (); +#include "t1intf.h" + + +static int Type1GetGlyphs ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, CharInfoPtr *glyphs ); + +#ifdef BUILDCID +#define CMapDir "/CMap/" +#define CFMDir "/CFM/" +#define CIDFontDir "/CIDFont/" +#endif + +static int Type1GetMetrics ( FontPtr pFont, unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, + xCharInfo **glyphs ); + #define minchar(p) ((p).min_char_low + ((p).min_char_high << 8)) #define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8)) -static void fillrun(); - +static void fillrun ( char *p, pel x0, pel x1, int bit ); extern psfont *FontP; extern psobj *ISOLatin1EncArrayP; -extern unsigned long *Xalloc(); -static void fill(); +#ifdef BUILDCID +extern char CurCIDFontName[]; +extern char CurCMapName[]; + +static CharInfoPtr CIDGetGlyph ( FontPtr pFont, unsigned int charcode, + CharInfoPtr pci ); + +extern cidfont *CIDFontP; +extern cmapres *CMapP; +#endif + +static void fill ( char *dest, int h, int w, struct region *area, int byte, + int bit, int wordsize ); + +#ifdef BUILDCID +int +CIDOpenScalable (FontPathElementPtr fpe, + FontPtr *ppFont, + int flags, + FontEntryPtr entry, + char *fileName, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ +{ + FontPtr pFont; + int bit, + byte, + glyph, + scan, + image; + int pad,wordsize; /* scan & image in bits */ + long *pool; /* memory pool for ximager objects */ + int size; /* for memory size calculations */ + struct XYspace *S; /* coordinate space for character */ + register int i; + int nchars, len, rc; + cidglyphs *cid; + char *p; + double t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001; + double sxmult; + char CIDFontName[CID_NAME_MAX]; + char CMapName[CID_NAME_MAX]; + char cidfontname[CID_PATH_MAX]; + char cmapname[CID_PATH_MAX]; + char *path; + char cidfontpath[CID_PATH_MAX]; + char cmappath[CID_PATH_MAX]; +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) + char cfmdir[CID_PATH_MAX]; + char cfmfilename[CID_NAME_MAX]; +#endif +#if defined(CID_ALL_CHARS) + char *cf; +#endif + long sAscent, sDescent; + + /* check the font name */ + len = strlen(fileName); + if (len <= 0 || len > CID_NAME_MAX - 1) + return BadFontName; + +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) + strcpy(cfmdir, fileName); + p = strrchr(cfmdir, '/'); + if (p) *p = '\0'; +#endif + + path = fileName; + if (!(fileName = strrchr(fileName, '/'))) + return BadFontName; + + len = fileName - path; + strncpy(cidfontpath, path, len); + cidfontpath[len] = '\0'; + strcpy(cmappath, cidfontpath); + strcat(cmappath, CMapDir); +#ifdef HAVE_CFM + strcpy(cfmdir, cidfontpath); + strcat(cfmdir, CFMDir); +#endif + strcat(cidfontpath, CIDFontDir); + + fileName++; + + /* extract the CIDFontName and CMapName from the font name */ + /* check for <CIDFontName>--<CMapName> */ + if ((p = strstr(fileName, "--"))) { + if (p == fileName) + return BadFontName; + else { + strcpy(CIDFontName, fileName); + CIDFontName[p - fileName] = '\0'; + p += 2; + i = 0; + while (*p && *p != '.') + CMapName[i++] = *p++; + CMapName[i] = '\0'; + if ((len = strlen(CMapName)) <= 0) + return BadFontName; + } + } else + return BadFontName; + + /* The CMap files whose names end with -V are not yet supported */ + len = strlen(CMapName); + if ((len >= 2 && CMapName[len - 2] == '-' && CMapName[len - 1] == 'V') || + (len == 1 && CMapName[len - 1] == 'V')) + return BadFontName; + + /* Reject ridiculously small font sizes that will blow up the math */ + if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 || + hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0) + return BadFontName; + +#ifdef CID_ALL_CHARS + if ((cf = getenv("CFMDIR")) == NULL) + strcat(cfmdir, CFMDir); + else { + strcpy(cfmdir, cf); + strcat(cfmdir, "/"); + } +#endif + +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) + strcpy(cfmfilename, cfmdir); + strcat(cfmfilename, CIDFontName); + strcat(cfmfilename, "--"); + strcat(cfmfilename, CMapName); + strcat(cfmfilename, ".cfm"); +#endif + + /* create a full-path name for a CIDFont file */ + if (strlen(cidfontpath) + strlen(CIDFontName) + 2 > + CID_PATH_MAX) + return BadFontName; + strcpy(cidfontname, cidfontpath); + strcat(cidfontname, CIDFontName); + + /* create a full-path name for a CMap file */ + if (strlen(cmappath) + strlen(CMapName) + 2 > CID_PATH_MAX) + return BadFontName; + strcpy(cmapname, cmappath); + strcat(cmapname, CMapName); + + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + if (rc != Successful) + return rc; + + pad = glyph * 8; + wordsize = scan * 8; + +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + if (!(pFont = CreateFontRec())) + return AllocError; + + cid = (cidglyphs *)xalloc(sizeof(cidglyphs)); + if (cid == NULL) { + DestroyFontRec(pFont); + return AllocError; + } + bzero(cid, sizeof(cidglyphs)); + + /* heuristic for "maximum" size of pool we'll need: */ + size = 200000 + 600 * + (int)hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) + * sizeof(short); + if (size < 0 || NULL == (pool = (long *) xalloc(size))) { + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + + addmemory(pool, size); + + /* load font if not already loaded */ + if (!CIDfontfcnA(cidfontname, cmapname, &rc)) { + FontP = NULL; + delmemory(); + xfree(pool); + xfree(cid); + DestroyFontRec(pFont); + return Type1ReturnCodeToXReturnCode(rc); + } + + FontP = NULL; + + S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY, + t1, t2, t3, t4); + + S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S, + vals->pixel_matrix[0], + -vals->pixel_matrix[1], + vals->pixel_matrix[2], + -vals->pixel_matrix[3])); + + /* multiplier for computation of raw values */ + sxmult = hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]); + if (sxmult > EPS) sxmult = 1000.0 / sxmult; + + pFont->info.firstRow = CMapP->firstRow; + pFont->info.firstCol = CMapP->firstCol; + pFont->info.lastRow = CMapP->lastRow; + pFont->info.lastCol = CMapP->lastCol; + + nchars = (pFont->info.lastRow - pFont->info.firstRow + 1) * + (pFont->info.lastCol - pFont->info.firstCol + 1); + + delmemory(); + xfree(pool); + + if (pFont->info.firstCol > pFont->info.lastCol) + { + xfree(cid); + DestroyFontRec(pFont); + return BadFontName; + } + + cid->glyphs = (CharInfoRec **)xalloc(nchars*sizeof(CharInfoRec *)); + if (cid->glyphs == NULL) { + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + bzero(cid->glyphs, nchars*sizeof(CharInfoRec *)); + + pFont->info.defaultCh = 0; + pFont->format = format; + + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + + pFont->get_metrics = CIDGetMetrics; + pFont->get_glyphs = CIDGetGlyphs; + pFont->unload_font = CIDCloseFont; + pFont->unload_glyphs = NULL; + pFont->refcnt = 0; + + len = strlen(cidfontname); + cid->CIDFontName = (char *)xalloc(len + 1); + if (cid->CIDFontName == NULL) { + xfree(cid->glyphs); + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + strcpy(cid->CIDFontName, cidfontname); + + len = strlen(cmapname); + cid->CMapName = (char *)xalloc(len + 1); + if (cid->CMapName == NULL) { + xfree(cid->CIDFontName); + xfree(cid->glyphs); + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + strcpy(cid->CMapName, cmapname); + + cid->pixel_matrix[0] = vals->pixel_matrix[0]; + cid->pixel_matrix[1] = vals->pixel_matrix[1]; + cid->pixel_matrix[2] = vals->pixel_matrix[2]; + cid->pixel_matrix[3] = vals->pixel_matrix[3]; + + pFont->fontPrivate = (unsigned char *)cid; + + pFont->info.fontAscent = + (CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[3].data.integer * + vals->pixel_matrix[3] + + (CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[3].data.integer > + 0 ? 500 : -500)) / 1000; + + pFont->info.fontDescent = + -(int)((double)CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[1].data.integer + * vals->pixel_matrix[3] + + (CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[1].data.integer > + 0 ? 500 : -500)) / 1000; + + /* Adobe does not put isFixedPitch entries in CID-keyed fonts. */ + /* CID-keyed are not constant-width fonts. */ + pFont->info.constantWidth = 0; + + sAscent = CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[3].data.integer; + sDescent = -CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[1].data.integer; + + if (strncmp(entry->name.name, "-bogus", 6)) { +#ifdef CID_ALL_CHARS + ComputeBoundsAllChars(pFont, cfmfilename, sxmult); +#else +#ifdef HAVE_CFM + CIDFillFontInfo(pFont, vals, cidfontname, entry->name.name, cmapname, + cfmfilename, sAscent, sDescent, sxmult); +#else + CIDFillFontInfo(pFont, vals, cidfontname, entry->name.name, cmapname, + sAscent, sDescent, sxmult); +#endif /* HAVE_CFM */ +#endif /* CID_ALL_CHARS */ + } + + *ppFont = pFont; + + return Successful; +} +#endif /*ARGSUSED*/ -int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, - fmask, non_cachable_font) - FontPathElementPtr fpe; - FontPtr *ppFont; - int flags; - FontEntryPtr entry; - char *fileName; - FontScalablePtr vals; - fsBitmapFormat format; - fsBitmapFormatMask fmask; - FontPtr non_cachable_font; /* We don't do licensing */ +int +Type1OpenScalable (FontPathElementPtr fpe, + FontPtr *ppFont, + int flags, + FontEntryPtr entry, + char *fileName, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ { - extern struct XYspace *IDENTITY; - extern Bool fontfcnA(); - extern struct region *fontfcnB(); - - FontPtr pFont; int bit, byte, @@ -147,7 +503,7 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, scan, image; int pad,wordsize; /* scan & image in bits */ - unsigned long *pool; /* memory pool for ximager objects */ + long *pool; /* memory pool for ximager objects */ int size; /* for memory size calculations */ struct XYspace *S; /* coordinate space for character */ struct region *area; @@ -156,7 +512,8 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, int len, rc, count = 0; struct type1font *type1; char *p; - psobj *fontencoding = NULL; + FontMapPtr mapping = NULL; + int no_mapping; psobj *fontmatrix; long x0, total_width = 0, total_raw_width = 0; double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001; @@ -179,24 +536,28 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, #define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) - pFont = (FontPtr) xalloc(sizeof(FontRec)); + pFont = CreateFontRec(); if (pFont == NULL) return AllocError; - + type1 = (struct type1font *)xalloc(sizeof(struct type1font)); if (type1 == NULL) { - xfree(pFont); + DestroyFontRec(pFont); return AllocError; } bzero(type1, sizeof(struct type1font)); /* heuristic for "maximum" size of pool we'll need: */ - size = 200000 + 120 * +#ifdef BUILDCID + size = 400000 + 600 * +#else + size = 200000 + 600 * +#endif (int)hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) * sizeof(short); - if (size < 0 || NULL == (pool = (unsigned long *) xalloc(size))) { + if (size < 0 || NULL == (pool = (long *) xalloc(size))) { xfree(type1); - xfree(pFont); + DestroyFontRec(pFont); return AllocError; } @@ -209,7 +570,7 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, if (!fontfcnA(fileName, &rc)) { delmemory(); xfree(type1); - xfree(pFont); + DestroyFontRec(pFont); xfree(pool); return Type1ReturnCodeToXReturnCode(rc); } @@ -229,61 +590,103 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, assign(3, t4, .001); } - S = (struct XYspace *) t1_Transform(IDENTITY, t1, t2, t3, t4); + S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY, + t1, t2, t3, t4); - S = (struct XYspace *) Permanent(t1_Transform(S, vals->pixel_matrix[0], - -vals->pixel_matrix[1], - vals->pixel_matrix[2], - -vals->pixel_matrix[3])); + S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S, + vals->pixel_matrix[0], + -vals->pixel_matrix[1], + vals->pixel_matrix[2], + -vals->pixel_matrix[3])); /* multiplier for computation of raw values */ sxmult = hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]); if (sxmult > EPS) sxmult = 1000.0 / sxmult; - p = entry->name.name + entry->name.length - 19; - if (entry->name.ndashes == 14 && - p >= entry->name.name && - !strcmp (p, "-adobe-fontspecific")) - { - fontencoding = FontP->fontInfoP[ENCODING].value.data.arrayP; + no_mapping=0; + p = FontEncFromXLFD(entry->name.name, entry->name.length); + + if(p==0) { /* XLFD does not specify an encoding */ + mapping=0; + no_mapping=2; /* ISO 8859-1 */ } - if (!fontencoding) - fontencoding = ISOLatin1EncArrayP; + if(!strcmp(p, "adobe-fontspecific")) { + mapping=0; + no_mapping=1; /* font's native encoding vector */ + } + + if(!no_mapping) { + mapping = FontEncMapFind(p, + FONT_ENCODING_POSTSCRIPT, -1, -1, + fileName); + if(!mapping) + mapping = FontEncMapFind(p, + FONT_ENCODING_UNICODE, -1, -1, + fileName); + if(!mapping) + no_mapping=2; + else + no_mapping=0; + } pFont->info.firstCol = 255; - pFont->info.lastCol = FIRSTCOL; + pFont->info.lastCol = 0; - for (i=0; i < 256-FIRSTCOL; i++) { + for (i=0; i < 256; i++) { long h,w; long paddedW; int j; char *codename; - codename = fontencoding[i + FIRSTCOL].data.valueP; - len = fontencoding[i + FIRSTCOL].len; - if (len == 7 && strcmp(codename,".notdef")==0) - continue; - + if(no_mapping == 1) { + codename = FontP->fontInfoP[ENCODING]. + value.data.arrayP[i].data.valueP; + len = FontP->fontInfoP[ENCODING]. + value.data.arrayP[i].len; + } else if(no_mapping) { + codename = unicodetoPSname(i); + len = codename ? strlen(codename) : 0; + } else { + if(mapping->type == FONT_ENCODING_UNICODE) { + codename = unicodetoPSname(FontEncRecode(i, mapping)); + } else + codename = FontEncName(i, mapping); + len=codename?strlen(codename):0; + } + + /* Avoid multiply rasterising the undefined glyph */ + if(len==7 && !strncmp(codename, ".notdef", 7)) { + len=0; + codename=0; + } + + /* But do rasterise it at least once */ + if(len==0) { + if(i==0) { + codename=".notdef"; + len=7; + } else + continue; + } + /* See if this character is in the list of ranges specified in the XLFD name */ - for (j = 0; j < vals->nranges; j++) - if (i + FIRSTCOL >= minchar(vals->ranges[j]) && - i + FIRSTCOL <= maxchar(vals->ranges[j])) - break; + if(i!=0) { + for (j = 0; j < vals->nranges; j++) + if (i >= minchar(vals->ranges[j]) && + i <= maxchar(vals->ranges[j])) + break; - /* If not, don't realize it. */ - if (vals->nranges && j == vals->nranges) - continue; - - if (pFont->info.firstCol > i + FIRSTCOL) - pFont->info.firstCol = i + FIRSTCOL; - if (pFont->info.lastCol < i + FIRSTCOL) - pFont->info.lastCol = i + FIRSTCOL; + /* If not, don't realize it. */ + if (vals->nranges && j == vals->nranges) + continue; + } rc = 0; - area = fontfcnB(S, codename, &len, &rc); + area = (struct region *)fontfcnB(S, (unsigned char *)codename, + &len, &rc); if (rc < 0) { rc = Type1ReturnCodeToXReturnCode(rc); break; @@ -294,6 +697,11 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, if (area == NULL) continue; + if (pFont->info.firstCol > i) + pFont->info.firstCol = i; + if (pFont->info.lastCol < i) + pFont->info.lastCol = i; + h = area->ymax - area->ymin; w = area->xmax - area->xmin; paddedW = PAD(w, pad); @@ -356,16 +764,16 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, if (pFont->info.firstCol > pFont->info.lastCol) { xfree(type1); - xfree(pFont); + DestroyFontRec(pFont); return BadFontName; } - if (i != 256 - FIRSTCOL) { + if (i != 256) { for (i--; i >= 0; i--) if (glyphs[i].bits != NULL) xfree(glyphs[i].bits); xfree(type1); - xfree(pFont); + DestroyFontRec(pFont); return rc; } type1->pDefault = NULL; @@ -385,8 +793,6 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, pFont->unload_font = Type1CloseFont; pFont->unload_glyphs = NULL; pFont->refcnt = 0; - pFont->maxPrivate = -1; - pFont->devPrivates = 0; pFont->fontPrivate = (unsigned char *) type1; @@ -408,15 +814,283 @@ int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format, *ppFont = pFont; return Successful; } + +#ifdef BUILDCID +unsigned int +getCID(FontPtr pFont, unsigned int charcode) +{ + unsigned int cidcode = 0; + Bool charvalid = FALSE; + cidglyphs *cid; + int i, j; + unsigned int char_row, char_col, rangelo_row, rangelo_col, k; + unsigned int rangehi_row, rangehi_col; + spacerange *spacerangeP; + cidrange *notdefrangeP, *cidrangeP; + + cid = (cidglyphs *)pFont->fontPrivate; + + if (cid == NULL) + return cidcode; + + char_row = (charcode >> 8) & 0xff; + char_col = charcode & 0xff; + + spacerangeP = CIDFontP->spacerangeP; + for (i = 0; i < CIDFontP->spacerangecnt; i++) { + for (j = 0; j < spacerangeP->rangecnt; j++) { + rangelo_row = + (spacerangeP->spacecode[j].srcCodeLo >> 8) & 0xff; + rangelo_col = spacerangeP->spacecode[j].srcCodeLo & 0xff; + rangehi_row = + (spacerangeP->spacecode[j].srcCodeHi >> 8) & 0xff; + rangehi_col = spacerangeP->spacecode[j].srcCodeHi & 0xff; + if (char_row >= rangelo_row && char_row <= rangehi_row && + char_col >= rangelo_col && char_col <= rangehi_col) { + charvalid = TRUE; + break; + } + } + if (charvalid) break; + spacerangeP = spacerangeP->next; + } + + if (charvalid) { + charvalid = FALSE; + cidrangeP = CIDFontP->cidrangeP; + for (i = 0; i < CIDFontP->cidrangecnt; i++) { + for (j = 0; j < cidrangeP->rangecnt; j++) { + rangelo_row = + (cidrangeP->range[j].srcCodeLo >> 8) & 0xff; + rangelo_col = cidrangeP->range[j].srcCodeLo & 0xff; + rangehi_row = + (cidrangeP->range[j].srcCodeHi >> 8) & 0xff; + rangehi_col = cidrangeP->range[j].srcCodeHi & 0xff; + if (char_row >= rangelo_row && char_row <= rangehi_row && + char_col >= rangelo_col && char_col <= rangehi_col) { + charvalid = TRUE; + for (k = cidrangeP->range[j].srcCodeLo; + k <= cidrangeP->range[j].srcCodeHi; k++) { + if (k == charcode) + cidcode = cidrangeP->range[j].dstCIDLo + k - + cidrangeP->range[j].srcCodeLo; + } + break; + } + } + if (charvalid) break; + cidrangeP = cidrangeP->next; + } + } + + if (charvalid) { + charvalid = FALSE; + notdefrangeP = CIDFontP->notdefrangeP; + for (i = 0; i < CIDFontP->notdefrangecnt; i++) { + for (j = 0; j < notdefrangeP->rangecnt; j++) { + rangelo_row = + (notdefrangeP->range[j].srcCodeLo >> 8) & 0xff; + rangelo_col = notdefrangeP->range[j].srcCodeLo & 0xff; + rangehi_row = + (notdefrangeP->range[j].srcCodeHi >> 8) & 0xff; + rangehi_col = notdefrangeP->range[j].srcCodeHi & 0xff; + if (char_row >= rangelo_row && char_row <= rangehi_row && + char_col >= rangelo_col && char_col <= rangehi_col) { + charvalid = TRUE; + for (k = notdefrangeP->range[j].srcCodeLo; + k <= notdefrangeP->range[j].srcCodeHi; k++) { + if (k == charcode) + /* the whole range is mapped to a single CID code */ + cidcode = notdefrangeP->range[j].dstCIDLo; + } + break; + } + } + if (charvalid) break; + notdefrangeP = notdefrangeP->next; + } + } + + /* If you specify a CMap that has more CIDs than a specified CIDFont, */ + /* the program could go beyond the number of entries in CIDMap. Make */ + /* sure that that does not happen. */ + if (cidcode < CIDFontP->CIDfontInfoP[CIDCOUNT].value.data.integer) + return cidcode; + else + return 0; +} + +static CharInfoPtr +CIDGetGlyph(FontPtr pFont, unsigned int charcode, CharInfoPtr pci) +{ + int rc; + CharInfoPtr cp = NULL; + unsigned int cidcode; + + /* character code -> CID */ + cidcode = getCID(pFont, charcode); + + cp = CIDGetGlyphInfo(pFont, cidcode, pci, &rc); + + if (rc != Successful && cidcode) { + cidcode = 0; + cp = CIDGetGlyphInfo(pFont, cidcode, pci, &rc); + } + + return cp; +} + +int +CIDGetGlyphs(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + unsigned int firstRow, numRows, code, char_row, char_col; + CharInfoPtr *glyphsBase; + register unsigned int c; + CharInfoPtr pci; + CharInfoPtr pDefault; + cidglyphs *cid; + register int firstCol; + int rc = 0; + int cid_valid = 0; + + cid = (cidglyphs *)pFont->fontPrivate; + + FontP = NULL; + + firstCol = pFont->info.firstCol; + pDefault = cid->pDefault; + glyphsBase = glyphs; + + switch (charEncoding) { + +#define EXIST(pci) \ + ((pci)->metrics.attributes || \ + (pci)->metrics.ascent != -(pci)->metrics.descent || \ + (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing) + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + while (count--) { + c = (*chars++); + if (c >= firstCol && c <= pFont->info.lastCol) { + code = c - firstCol; + if (!(pci = (CharInfoRec *)cid->glyphs[code]) || + ((long)pci->bits == CID_BITMAP_UNDEFINED)) { + /* load font if not already loaded */ + if(!cid_valid) { + if(!CIDfontfcnA(cid->CIDFontName, cid->CMapName, &rc)) { FontP = NULL; + return Type1ReturnCodeToXReturnCode(rc); + } + cid_valid = 1; + } + pci = CIDGetGlyph(pFont, c, pci); + } + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + case Linear16Bit: + while (count--) { + char_row = *chars++; + char_col = *chars++; + c = char_row << 8; + c = (c | char_col); + if (pFont->info.firstRow <= char_row && char_row <= + pFont->info.lastRow && pFont->info.firstCol <= char_col && + char_col <= pFont->info.lastCol) { + code = pFont->info.lastCol - pFont->info.firstCol + 1; + char_row = char_row - pFont->info.firstRow; + char_col = char_col - pFont->info.firstCol; + code = char_row * code + char_col; + if (!(pci = (CharInfoRec *)cid->glyphs[code]) || + ((long)pci->bits == CID_BITMAP_UNDEFINED)) { + /* load font if not already loaded */ + if(!cid_valid) { + if(!CIDfontfcnA(cid->CIDFontName, cid->CMapName, &rc)) { FontP = NULL; + return Type1ReturnCodeToXReturnCode(rc); + } + cid_valid = 1; + } + pci = CIDGetGlyph(pFont, c, pci); + } + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + + case TwoD16Bit: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + while (count--) { + char_row = (*chars++); + char_col = (*chars++); + c = char_row << 8; + c = (c | char_col); + if (pFont->info.firstRow <= char_row && char_row <= + pFont->info.lastRow && pFont->info.firstCol <= char_col && + char_col <= pFont->info.lastCol) { + code = pFont->info.lastCol - pFont->info.firstCol + 1; + char_row = char_row - pFont->info.firstRow; + char_col = char_col - pFont->info.firstCol; + code = char_row * code + char_col; + if (!(pci = (CharInfoRec *)cid->glyphs[code]) || + ((long)pci->bits == CID_BITMAP_UNDEFINED)) { + /* load font if not already loaded */ + if(!cid_valid) { + if(!CIDfontfcnA(cid->CIDFontName, cid->CMapName, &rc)) { FontP = NULL; + return Type1ReturnCodeToXReturnCode(rc); + } + cid_valid = 1; + } + pci = CIDGetGlyph(pFont, c, pci); + } + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return Successful; + +#undef EXIST +} +#endif static int -Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs) - FontPtr pFont; - unsigned long count; - register unsigned char *chars; - FontEncoding charEncoding; - unsigned long *glyphCount; /* RETURN */ - CharInfoPtr *glyphs; /* RETURN */ +Type1GetGlyphs(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ { unsigned int firstRow; unsigned int numRows; @@ -447,7 +1121,7 @@ Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs) while (count--) { c = (*chars++); if (c >= firstCol && - (pci = &type1Font->glyphs[c-FIRSTCOL]) && + (pci = &type1Font->glyphs[c]) && EXIST(pci)) *glyphs++ = pci; else if (pDefault) @@ -459,7 +1133,7 @@ Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs) c = *chars++ << 8; c = (c | *chars++); if (c < 256 && c >= firstCol && - (pci = &type1Font->glyphs[c-FIRSTCOL]) && + (pci = &type1Font->glyphs[c]) && EXIST(pci)) *glyphs++ = pci; else if (pDefault) @@ -474,7 +1148,7 @@ Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs) r = (*chars++) - firstRow; c = (*chars++); if (r < numRows && c < 256 && c >= firstCol && - (pci = &type1Font->glyphs[(r << 8) + c - FIRSTCOL]) && + (pci = &type1Font->glyphs[(r << 8) + c]) && EXIST(pci)) *glyphs++ = pci; else if (pDefault) @@ -487,15 +1161,67 @@ Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs) #undef EXIST } - + +#ifdef BUILDCID +static CharInfoRec nonExistantChar; + +int +CIDGetMetrics(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ +{ + int ret; + cidglyphs *cid; + CharInfoPtr oldDefault; + char cidafmname[CID_PATH_MAX]; + char CIDFontName[CID_NAME_MAX]; + char *ptr; + + cid = (cidglyphs *)pFont->fontPrivate; + + strcpy(cidafmname, cid->CIDFontName); + if (!(ptr = strrchr(cidafmname, '/'))) + return BadFontName; + + *ptr = '\0'; + + strcpy(CIDFontName, ptr + 1); + + if (!(ptr = strrchr(cidafmname, '/'))) + return BadFontName; + + *ptr = '\0'; + + strcat(cidafmname, "/AFM/"); + strcat(cidafmname, CIDFontName); + + strcat(cidafmname, ".afm"); + + oldDefault = cid->pDefault; + cid->pDefault = &nonExistantChar; + + ret = CIDGetAFM(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr +*)glyphs, cidafmname); + if (ret != Successful) + ret = CIDGetGlyphs(pFont, count, chars, charEncoding, glyphCount, + (CharInfoPtr *)glyphs); + + *ptr = 0; + cid->pDefault = oldDefault; + return ret; +} +#endif + static int -Type1GetMetrics(pFont, count, chars, charEncoding, glyphCount, glyphs) - FontPtr pFont; - unsigned long count; - register unsigned char *chars; - FontEncoding charEncoding; - unsigned long *glyphCount; /* RETURN */ - xCharInfo **glyphs; /* RETURN */ +Type1GetMetrics(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ { static CharInfoRec nonExistantChar; @@ -510,15 +1236,75 @@ Type1GetMetrics(pFont, count, chars, charEncoding, glyphCount, glyphs) type1Font->pDefault = oldDefault; return ret; } - -void Type1CloseFont(pFont) - FontPtr pFont; + +#ifdef BUILDCID +void +CIDCloseFont(FontPtr pFont) +{ + register int i; + cidglyphs *cid; + int nchars; + + if (pFont) { + + cid = (cidglyphs *)pFont->fontPrivate; + + if (cid) { + + if (cid->CIDFontName && !strcmp(cid->CIDFontName, CurCIDFontName) + && cid->CMapName && !strcmp(cid->CMapName, CurCMapName)){ + strcpy(CurCIDFontName, ""); /* initialize to none */ + strcpy(CurCMapName, ""); /* initialize to none */ + } + + if (cid->CIDFontName) + xfree(cid->CIDFontName); + + if (cid->CMapName) + xfree(cid->CMapName); + + nchars = (pFont->info.lastRow - pFont->info.firstRow + 1) * + (pFont->info.lastCol - pFont->info.firstCol + 1); + + for (i = 0; i < nchars; i++) { + if (cid->glyphs[i] && (cid->glyphs[i] != &nonExistantChar)) { + if (cid->glyphs[i]->bits) + xfree(cid->glyphs[i]->bits); + xfree(cid->glyphs[i]); + } + } + + if (cid->glyphs) + xfree(cid->glyphs); + + if (cid->AFMinfo) + xfree(cid->AFMinfo); +#ifdef USE_MMAP + if (cid->CIDdata) + munmap(cid->CIDdata, cid->CIDsize); +#endif + xfree(cid); + } + + if (pFont->info.props) + xfree(pFont->info.props); + + if (pFont->info.isStringProp) + xfree(pFont->info.isStringProp); + + DestroyFontRec(pFont); + } +} +#endif + +void +Type1CloseFont(FontPtr pFont) { register int i; struct type1font *type1; type1 = (struct type1font *) pFont->fontPrivate; - for (i=0; i < 256 - FIRSTCOL; i++) + for (i=0; i < 256; i++) if (type1->glyphs[i].bits != NULL) xfree(type1->glyphs[i].bits); xfree(type1); @@ -529,20 +1315,15 @@ void Type1CloseFont(pFont) if (pFont->info.isStringProp) xfree(pFont->info.isStringProp); - if (pFont->devPrivates) - xfree(pFont->devPrivates); - - xfree(pFont); + DestroyFontRec(pFont); } - - - -static void fill(dest, h, w, area, byte, bit, wordsize) - register char *dest; /* destination bitmap */ - int h,w; /* dimensions of 'dest', w padded */ - register struct region *area; /* region to write to 'dest' */ - int byte,bit; /* flags; LSBFirst or MSBFirst */ - int wordsize; /* number of bits per word for LSB/MSB purposes */ + +static void +fill(char *dest, /* destination bitmap */ + int h, int w, /* dimensions of 'dest', w padded */ + struct region *area, /* region to write to 'dest' */ + int byte, int bit, /* flags; LSBFirst or MSBFirst */ + int wordsize) /* number of bits per word for LSB/MSB purposes */ { register struct edgelist *edge; /* for looping through edges */ register char *p; /* current scan line in 'dest' */ @@ -609,7 +1390,7 @@ it: break; } default: - abort("xiFill: unknown format"); + Abort("xiFill: unknown format"); } } @@ -617,10 +1398,10 @@ it: #define ALLONES 0xFF -static void fillrun(p, x0, x1, bit) - register char *p; /* address of this scan line */ - pel x0,x1; /* left and right X */ - int bit; /* format: LSBFirst or MSBFirst */ +static void +fillrun(char *p, /* address of this scan line */ + pel x0, pel x1, /* left and right X */ + int bit) /* format: LSBFirst or MSBFirst */ { register int startmask,endmask; /* bits to set in first and last char*/ register int middle; /* number of chars between start and end + 1 */ @@ -643,33 +1424,61 @@ static void fillrun(p, x0, x1, bit) else { *p++ |= startmask; while (--middle > 0) - *p++ = ALLONES; + *p++ = (char)ALLONES; *p |= endmask; } } #define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING) + +#ifdef BUILDCID +FontRendererRec CIDRendererInfo[] = { + { ".cid", 4, NULL, CIDOpenScalable, + NULL, CIDGetInfoScalable, 0, CAPABILITIES } +}; +#endif +#ifdef BUILDCID +FontRendererRec Type1RendererInfo[] = { +#else static FontRendererRec renderers[] = { - { ".pfa", 4, (int (*)()) 0, Type1OpenScalable, - (int (*)()) 0, Type1GetInfoScalable, 0, CAPABILITIES }, - { ".pfb", 4, (int (*)()) 0, Type1OpenScalable, - (int (*)()) 0, Type1GetInfoScalable, 0, CAPABILITIES } +#endif + { ".pfa", 4, NULL, Type1OpenScalable, + NULL, Type1GetInfoScalable, 0, CAPABILITIES }, + { ".pfb", 4, NULL, Type1OpenScalable, + NULL, Type1GetInfoScalable, 0, CAPABILITIES } }; - +#ifdef BUILDCID +void +CIDRegisterFontFileFunctions(void) +{ + int i; + + Type1InitStdProps(); + for (i=0; i < sizeof(CIDRendererInfo) / sizeof(FontRendererRec); i++) + FontFileRegisterRenderer(&CIDRendererInfo[i]); +} +#endif + void -Type1RegisterFontFileFunctions() +Type1RegisterFontFileFunctions(void) { int i; +#ifdef BUILDCID + Type1InitStdProps(); + for (i=0; i < sizeof(Type1RendererInfo) / sizeof(FontRendererRec); i++) + FontFilePriorityRegisterRenderer(&Type1RendererInfo[i], -10); +#else T1InitStdProps(); for (i=0; i < sizeof(renderers) / sizeof(FontRendererRec); i++) - FontFileRegisterRenderer(&renderers[i]); + FontFilePriorityRegisterRenderer(&renderers[i], -10); +#endif } -int Type1ReturnCodeToXReturnCode(rc) - int rc; +int +Type1ReturnCodeToXReturnCode(int rc) { switch(rc) { case SCAN_OK: @@ -688,7 +1497,165 @@ int Type1ReturnCodeToXReturnCode(rc) /* fall through */ default: /* this should not happen */ +#ifdef BUILDCID + ErrorF("Font return code cannot be converted to X return code: %d\n", rc); +#else ErrorF("Type1 return code not convertable to X return code: %d\n", rc); +#endif return rc; } } + +#ifdef BUILDCID +CharInfoPtr +CIDRenderGlyph(FontPtr pFont, psobj *charstringP, psobj *subarrayP, + struct blues_struct *bluesP, CharInfoPtr pci, int *mode) +{ + int bit, + byte, + glyph, + scan, + image; + int pad,wordsize; /* scan & image in bits */ + long *pool; /* memory pool for ximager objects */ + int size; /* for memory size calculations */ + struct XYspace *S; /* coordinate space for character */ + struct region *area; + CharInfoRec *glyphs; + int len, rc; + long x0; + double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001; + double sxmult; + long h,w; + long paddedW; + cidglyphs *cid; + fsBitmapFormat format = 0; + fsBitmapFormatMask fmask = 0; + + cid = (cidglyphs *)pFont->fontPrivate; + + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + if (rc != Successful) { + *mode = rc; + return(NULL); + } + + pad = glyph * 8; + wordsize = scan * 8; + +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + /* heuristic for "maximum" size of pool we'll need: */ + size = 200000 + 600 * + (int)hypot(cid->pixel_matrix[2], cid->pixel_matrix[3]) + * sizeof(short); + if (size < 0 || NULL == (pool = (long *) xalloc(size))) { + *mode = AllocError; + return(NULL); + } + + addmemory(pool, size); + + if (pci && (long)pci->bits == CID_BITMAP_UNDEFINED) + glyphs = pci; + else { + if (!(glyphs = (CharInfoRec *)xalloc(sizeof(CharInfoRec)))) { + delmemory(); + xfree(pool); + *mode = AllocError; + return(NULL); + } + bzero(glyphs, sizeof(CharInfoRec)); + } + + S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY, + t1, t2, t3, t4); + + S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S, + cid->pixel_matrix[0], + -cid->pixel_matrix[1], + cid->pixel_matrix[2], + -cid->pixel_matrix[3])); + + /* multiplier for computation of raw values */ + sxmult = hypot(cid->pixel_matrix[0], cid->pixel_matrix[1]); + if (sxmult > EPS) sxmult = 1000.0 / sxmult; + + rc = 0; + area = (struct region *)CIDfontfcnC(S, charstringP, subarrayP, bluesP, + &len, &rc); + if (rc < 0 || area == NULL) { + delmemory(); + xfree(pool); + if (pci != glyphs) xfree(glyphs); + *mode = Type1ReturnCodeToXReturnCode(rc); + return(NULL); + } + + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + paddedW = PAD(w, pad); + + if (h > 0 && w > 0) { + size = h * paddedW / 8; + glyphs[0].bits = (char *)xalloc(size); + if (glyphs[0].bits == NULL) { + Destroy(area); + delmemory(); + xfree(pool); + if (pci != glyphs) xfree(glyphs); + *mode = AllocError; + return(NULL); + } + bzero(glyphs[0].bits, size); + } + else { + size = 0; + h = w = 0; + area->xmin = area->xmax = 0; + area->ymax = area->ymax = 0; + glyphs[0].bits = NULL; + } + + glyphs[0].metrics.leftSideBearing = area->xmin; + x1 = (double)(x0 = area->ending.x - area->origin.x); + y1 = (double)(area->ending.y - area->origin.y); + glyphs[0].metrics.characterWidth = + (x0 + (x0 > 0 ? FPHALF : -FPHALF)) / (1 << FRACTBITS); + if (!glyphs[0].metrics.characterWidth && size == 0) + { + /* Zero size and zero extents: presumably caused by + the choice of transformation. Let's create a + small bitmap so we're not mistaken for an undefined + character. */ + h = w = 1; + size = paddedW = PAD(w, pad); + glyphs[0].bits = (char *)xalloc(size); + if (glyphs[0].bits == NULL) { + Destroy(area); + delmemory(); + xfree(pool); + if (pci != glyphs) xfree(glyphs); + *mode = AllocError; + return(NULL); + } + bzero(glyphs[0].bits, size); + } + glyphs[0].metrics.attributes = + NEARESTPEL((long)(hypot(x1, y1) * sxmult)); + glyphs[0].metrics.rightSideBearing = w + area->xmin; + glyphs[0].metrics.descent = area->ymax - NEARESTPEL(area->origin.y); + glyphs[0].metrics.ascent = h - glyphs[0].metrics.descent; + + if (h > 0 && w > 0) + fill(glyphs[0].bits, h, paddedW, area, byte, bit, wordsize); + Destroy(area); + delmemory(); + xfree(pool); + *mode = Successful; + return(glyphs); +} +#endif |