Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pdf/xpdf/T1Font.cc
diff options
context:
space:
mode:
Diffstat (limited to 'pdf/xpdf/T1Font.cc')
-rw-r--r--pdf/xpdf/T1Font.cc566
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