summaryrefslogtreecommitdiff
path: root/src/Type1/t1funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Type1/t1funcs.c')
-rw-r--r--src/Type1/t1funcs.c1219
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