diff options
Diffstat (limited to 'pdf/xpdf/T1Font.cc')
-rw-r--r-- | pdf/xpdf/T1Font.cc | 566 |
1 files changed, 0 insertions, 566 deletions
diff --git a/pdf/xpdf/T1Font.cc b/pdf/xpdf/T1Font.cc deleted file mode 100644 index a03351d..0000000 --- a/pdf/xpdf/T1Font.cc +++ /dev/null @@ -1,566 +0,0 @@ -//======================================================================== -// -// T1Font.cc -// -// Copyright 2001-2003 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#if HAVE_T1LIB_H - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <math.h> -#include <string.h> -#include <X11/Xlib.h> -#include "gmem.h" -#include "GfxState.h" -#include "T1Font.h" - -//------------------------------------------------------------------------ - -int T1FontEngine::t1libInitCount = 0; - -//------------------------------------------------------------------------ - -T1FontEngine::T1FontEngine(Display *displayA, Visual *visualA, int depthA, - Colormap colormapA, GBool aaA, GBool aaHighA): - SFontEngine(displayA, visualA, depthA, colormapA) -{ - static unsigned long grayVals[17] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - }; - - ok = gFalse; - aa = aaA; - aaHigh = aaHighA; - //~ for multithreading: need a mutex here - if (t1libInitCount == 0) { - T1_SetBitmapPad(8); - if (!T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE | - T1_NO_AFM)) { - return; - } - if (aa) { - T1_AASetBitsPerPixel(8); - if (aaHigh) { - T1_AASetLevel(T1_AA_HIGH); - T1_AAHSetGrayValues(grayVals); - } else { - T1_AASetLevel(T1_AA_LOW); - T1_AASetGrayValues(0, 1, 2, 3, 4); - } - } else { - T1_AANSetGrayValues(0, 1); - } - } - ++t1libInitCount; - ok = gTrue; -} - -T1FontEngine::~T1FontEngine() { - //~ for multithreading: need a mutex here - if (--t1libInitCount == 0) { - T1_CloseLib(); - } -} - -//------------------------------------------------------------------------ - -T1FontFile::T1FontFile(T1FontEngine *engineA, char *fontFileName, - char **fontEnc, double *bboxA) { - int encStrSize; - char *encPtr; - int i; - - ok = gFalse; - engine = engineA; - enc = NULL; - encStr = NULL; - for (i = 0; i < 4; ++i) { - bbox[i] = bboxA[i]; - } - - // load the font file - if ((id = T1_AddFont(fontFileName)) < 0) { - return; - } - T1_LoadFont(id); - - // reencode it - encStrSize = 0; - for (i = 0; i < 256; ++i) { - if (fontEnc[i]) { - encStrSize += strlen(fontEnc[i]) + 1; - } - } - enc = (char **)gmalloc(257 * sizeof(char *)); - encStr = (char *)gmalloc(encStrSize * sizeof(char)); - encPtr = encStr; - for (i = 0; i < 256; ++i) { - if (fontEnc[i]) { - strcpy(encPtr, fontEnc[i]); - enc[i] = encPtr; - encPtr += strlen(encPtr) + 1; - } else { - enc[i] = ".notdef"; - } - } - enc[256] = "custom"; - T1_ReencodeFont(id, enc); - - ok = gTrue; -} - -T1FontFile::~T1FontFile() { - gfree(enc); - gfree(encStr); - if (id >= 0) { - T1_DeleteFont(id); - } -} - -//------------------------------------------------------------------------ - -T1Font::T1Font(T1FontFile *fontFileA, double *m) { - T1FontEngine *engine; - T1_TMATRIX matrix; - BBox bbox; - double bbx0, bby0, bbx1, bby1; - int x, y, xMin, xMax, yMin, yMax; - int i; - - ok = gFalse; - fontFile = fontFileA; - engine = fontFile->engine; - - id = T1_CopyFont(fontFile->id); - - // compute font size - size = (float)sqrt(m[2]*m[2] + m[3]*m[3]); - - // transform the four corners of the font bounding box -- the min - // and max values form the bounding box of the transformed font - bbx0 = fontFile->bbox[0]; - bby0 = fontFile->bbox[1]; - bbx1 = fontFile->bbox[2]; - bby1 = fontFile->bbox[3]; - // some fonts in PDF files have bboxes which are just plain wrong, - // so we check the font file's bbox too - bbox = T1_GetFontBBox(id); - if (0.001 * bbox.llx < bbx0) { - bbx0 = 0.001 * bbox.llx; - } - if (0.001 * bbox.lly < bby0) { - bby0 = 0.001 * bbox.lly; - } - if (0.001 * bbox.urx > bbx1) { - bbx1 = 0.001 * bbox.urx; - } - if (0.001 * bbox.ury > bby1) { - bby1 = 0.001 * bbox.ury; - } - // some fonts are completely broken, so we fake it (with values - // large enough that most glyphs should fit) - if (bbx0 == 0 && bby0 == 0 && bbx1 == 0 && bby1 == 0) { - bbx0 = bby0 = -0.5; - bbx1 = bby1 = 1.5; - } - x = (int)(m[0] * bbx0 + m[2] * bby0); - xMin = xMax = x; - y = (int)(m[1] * bbx0 + m[3] * bby0); - yMin = yMax = y; - x = (int)(m[0] * bbx0 + m[2] * bby1); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)(m[1] * bbx0 + m[3] * bby1); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - x = (int)(m[0] * bbx1 + m[2] * bby0); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)(m[1] * bbx1 + m[3] * bby0); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - x = (int)(m[0] * bbx1 + m[2] * bby1); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)(m[1] * bbx1 + m[3] * bby1); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - // This is a kludge: some buggy PDF generators embed fonts with - // zero bounding boxes. - if (xMax == xMin) { - xMin = 0; - xMax = (int)size; - } - if (yMax == yMin) { - yMin = 0; - yMax = (int)(1.2 * size); - } - // Another kludge: an unusually large xMin or yMin coordinate is - // probably wrong. - if (xMin > 0) { - xMin = 0; - } - if (yMin > 0) { - yMin = 0; - } - // Another kludge: t1lib doesn't correctly handle fonts with - // real (non-integer) bounding box coordinates. - if (xMax - xMin > 5000) { - xMin = 0; - xMax = (int)size; - } - if (yMax - yMin > 5000) { - yMin = 0; - yMax = (int)(1.2 * size); - } - // this should be (max - min + 1), but we add some padding to - // deal with rounding errors - glyphW = xMax - xMin + 3; - glyphH = yMax - yMin + 3; - if (engine->aa) { - glyphSize = glyphW * glyphH; - } else { - glyphSize = ((glyphW + 7) >> 3) * glyphH; - } - - // set up the glyph pixmap cache - cacheAssoc = 8; - if (glyphSize <= 256) { - cacheSets = 8; - } else if (glyphSize <= 512) { - cacheSets = 4; - } else if (glyphSize <= 1024) { - cacheSets = 2; - } else { - cacheSets = 1; - } - cache = (Guchar *)gmalloc(cacheSets * cacheAssoc * glyphSize); - cacheTags = (T1FontCacheTag *)gmalloc(cacheSets * cacheAssoc * - sizeof(T1FontCacheTag)); - for (i = 0; i < cacheSets * cacheAssoc; ++i) { - cacheTags[i].mru = i & (cacheAssoc - 1); - } - - // create the XImage - if (!(image = XCreateImage(engine->display, engine->visual, engine->depth, - ZPixmap, 0, NULL, glyphW, glyphH, 8, 0))) { - return; - } - image->data = (char *)gmalloc(glyphH * image->bytes_per_line); - - // transform the font - matrix.cxx = m[0] / size; - matrix.cxy = m[1] / size; - matrix.cyx = m[2] / size; - matrix.cyy = m[3] / size; - T1_TransformFont(id, &matrix); - - ok = gTrue; -} - -T1Font::~T1Font() { - gfree(cacheTags); - gfree(cache); - if (image) { - gfree(image->data); - image->data = NULL; - XDestroyImage(image); - } - T1_DeleteFont(id); -} - -GBool T1Font::drawChar(Drawable d, int w, int h, GC gc, - int x, int y, int r, int g, int b, - CharCode c, Unicode u) { - T1FontEngine *engine; - XColor xcolor; - int bgR, bgG, bgB; - Gulong colors[17]; - Guchar *bitmap, *p; - GBool tempBitmap; - XImage *img; - int xOffset, yOffset, x0, y0, x1, y1, gw, gh, w0, h0; - int xx, yy, xx1; - Guchar pix, mPix; - int i; - - engine = fontFile->engine; - - // generate the glyph pixmap - if (!(bitmap = getGlyphPixmap(c, &xOffset, &yOffset, &gw, &gh, - &tempBitmap))) { - return gFalse; - } - - // compute: (x0,y0) = position in destination drawable - // (x1,y1) = position in glyph image - // (w0,h0) = size of image transfer - x0 = x - xOffset; - y0 = y - yOffset; - x1 = 0; - y1 = 0; - w0 = gw; - h0 = gh; - if (x0 < 0) { - x1 = -x0; - w0 += x0; - x0 = 0; - } - if (x0 + w0 > w) { - w0 = w - x0; - } - if (w0 < 0) { - goto done; - } - if (y0 < 0) { - y1 = -y0; - h0 += y0; - y0 = 0; - } - if (y0 + h0 > h) { - h0 = h - y0; - } - if (h0 < 0) { - goto done; - } - - // getGlyphPixmap may have returned a larger-than-cache-entry - // bitmap, in which case we need to allocate a temporary XImage here - if (tempBitmap) { - if (!(img = XCreateImage(engine->display, engine->visual, engine->depth, - ZPixmap, 0, NULL, gw, gh, 8, 0))) { - goto done; - } - img->data = (char *)gmalloc(gh * img->bytes_per_line); - } else { - img = image; - } - - // read the X image - XGetSubImage(engine->display, d, x0, y0, w0, h0, (1 << engine->depth) - 1, - ZPixmap, img, x1, y1); - - if (engine->aa) { - - // compute the colors - xcolor.pixel = XGetPixel(img, x1 + w0/2, y1 + h0/2); - XQueryColor(engine->display, engine->colormap, &xcolor); - bgR = xcolor.red; - bgG = xcolor.green; - bgB = xcolor.blue; - if (engine->aaHigh) { - mPix = 16; - for (i = 1; i <= 16; ++i) { - colors[i] = engine->findColor((i * r + (16 - i) * bgR) / 16, - (i * g + (16 - i) * bgG) / 16, - (i * b + (16 - i) * bgB) / 16); - } - } else { - mPix = 4; - colors[1] = engine->findColor((r + 3*bgR) / 4, - (g + 3*bgG) / 4, - (b + 3*bgB) / 4); - colors[2] = engine->findColor((r + bgR) / 2, - (g + bgG) / 2, - (b + bgB) / 2); - colors[3] = engine->findColor((3*r + bgR) / 4, - (3*g + bgG) / 4, - (3*b + bgB) / 4); - colors[4] = engine->findColor(r, g, b); - } - - // stuff the glyph pixmap into the X image - p = bitmap; - for (yy = 0; yy < gh; ++yy) { - for (xx = 0; xx < gw; ++xx) { - pix = *p++; - if (pix > 0) { - if (pix > mPix) { - pix = mPix; - } - XPutPixel(img, xx, yy, colors[pix]); - } - } - } - - } else { - - // one color - colors[1] = engine->findColor(r, g, b); - - // stuff the glyph bitmap into the X image - p = bitmap; - for (yy = 0; yy < gh; ++yy) { - for (xx = 0; xx < gw; xx += 8) { - pix = *p++; - for (xx1 = xx; xx1 < xx + 8 && xx1 < gw; ++xx1) { - if (pix & 0x01) { - XPutPixel(img, xx1, yy, colors[1]); - } - pix >>= 1; - } - } - } - - } - - // draw the X image - XPutImage(engine->display, d, gc, img, x1, y1, x0, y0, w0, h0); - - if (tempBitmap) { - gfree(img->data); - img->data = NULL; - XDestroyImage(img); - } - done: - if (tempBitmap) { - gfree(bitmap); - } - return gTrue; -} - -Guchar *T1Font::getGlyphPixmap(CharCode c, int *x, int *y, int *w, int *h, - GBool *tempBitmap) { - T1FontEngine *engine; - GLYPH *glyph; - int gSize; - int i, j, k; - Guchar *ret; - - engine = fontFile->engine; - - // check the cache - i = (c & (cacheSets - 1)) * cacheAssoc; - for (j = 0; j < cacheAssoc; ++j) { - if ((cacheTags[i+j].mru & 0x8000) && cacheTags[i+j].code == c) { - *x = cacheTags[i+j].x; - *y = cacheTags[i+j].y; - *w = cacheTags[i+j].w; - *h = cacheTags[i+j].h; - for (k = 0; k < cacheAssoc; ++k) { - if (k != j && - (cacheTags[i+k].mru & 0x7fff) < (cacheTags[i+j].mru & 0x7fff)) { - ++cacheTags[i+k].mru; - } - } - cacheTags[i+j].mru = 0x8000; - *tempBitmap = gFalse; - return cache + (i+j) * glyphSize; - } - } - - // generate the glyph pixmap - if (engine->aa) { - glyph = T1_AASetChar(id, c, size, NULL); - } else { - glyph = T1_SetChar(id, c, size, NULL); - } - if (!glyph) { - return NULL; - } - - // copy the glyph into the cache or a temporary bitmap - *x = -glyph->metrics.leftSideBearing; - *y = glyph->metrics.ascent; - *w = glyph->metrics.rightSideBearing - glyph->metrics.leftSideBearing; - *h = glyph->metrics.ascent - glyph->metrics.descent; - if (engine->aa) { - gSize = *w * *h; - } else { - gSize = ((*w + 7) >> 3) * *h; - } - if (*w > glyphW || *h > glyphH) { - // the glyph doesn't fit in the bounding box -- return a - // temporary, uncached bitmap (this shouldn't happen but some - // fonts have incorrect bboxes) - ret = (Guchar *)gmalloc(gSize); - *tempBitmap = gTrue; - } else { - // store glyph pixmap in cache - ret = NULL; // make gcc happy - for (j = 0; j < cacheAssoc; ++j) { - if ((cacheTags[i+j].mru & 0x7fff) == cacheAssoc - 1) { - cacheTags[i+j].mru = 0x8000; - cacheTags[i+j].code = c; - cacheTags[i+j].x = *x; - cacheTags[i+j].y = *y; - cacheTags[i+j].w = *w; - cacheTags[i+j].h = *h; - ret = cache + (i+j) * glyphSize; - } else { - ++cacheTags[i+j].mru; - } - } - *tempBitmap = gFalse; - } - if (glyph->bits) { - memcpy(ret, glyph->bits, gSize); - } else { - memset(ret, 0, gSize); - } - return ret; -} - -GBool T1Font::getCharPath(CharCode c, Unicode u, GfxState *state) { - T1_OUTLINE *outline; - T1_PATHSEGMENT *seg; - T1_BEZIERSEGMENT *bez; - double x, y, x1, y1; - - outline = T1_GetCharOutline(id, c, size, NULL); - x = 0; - y = 0; - for (seg = outline; seg; seg = seg->link) { - switch (seg->type) { - case T1_PATHTYPE_MOVE: - x += seg->dest.x / 65536.0; - y += seg->dest.y / 65536.0; - state->moveTo(x, y); - break; - case T1_PATHTYPE_LINE: - x += seg->dest.x / 65536.0; - y += seg->dest.y / 65536.0; - state->lineTo(x, y); - break; - case T1_PATHTYPE_BEZIER: - bez = (T1_BEZIERSEGMENT *)seg; - x1 = x + bez->dest.x / 65536.0; - y1 = y + bez->dest.y / 65536.0; - state->curveTo(x + bez->B.x / 65536.0, y + bez->B.y / 65536.0, - x + bez->C.x / 65536.0, y + bez->C.y / 65536.0, - x1, y1); - x = x1; - y = y1; - break; - } - } - T1_FreeOutline(outline); - return gTrue; -} - -#endif // HAVE_T1LIB_H |