summaryrefslogtreecommitdiffstats
path: root/filters/kword/pdf/xpdf/xpdf/FTFont.cc
diff options
context:
space:
mode:
Diffstat (limited to 'filters/kword/pdf/xpdf/xpdf/FTFont.cc')
-rw-r--r--filters/kword/pdf/xpdf/xpdf/FTFont.cc685
1 files changed, 0 insertions, 685 deletions
diff --git a/filters/kword/pdf/xpdf/xpdf/FTFont.cc b/filters/kword/pdf/xpdf/xpdf/FTFont.cc
deleted file mode 100644
index 8de09e0e6..000000000
--- a/filters/kword/pdf/xpdf/xpdf/FTFont.cc
+++ /dev/null
@@ -1,685 +0,0 @@
-//========================================================================
-//
-// FTFont.cc
-//
-// Copyright 2001-2002 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <math.h>
-#include <string.h>
-#include "gmem.h"
-#include "freetype/ftoutln.h"
-#include "freetype/internal/ftobjs.h"
-#if 1 //~ cff cid->gid map
-#include "freetype/internal/cfftypes.h"
-#include "freetype/internal/tttypes.h"
-#endif
-#include "GlobalParams.h"
-#include "GfxState.h"
-#include "FTFont.h"
-
-//------------------------------------------------------------------------
-
-FTFontEngine::FTFontEngine(Display *displayA, Visual *visualA, int depthA,
- Colormap colormapA, GBool aaA):
- SFontEngine(displayA, visualA, depthA, colormapA) {
-
- ok = gFalse;
- if (FT_Init_FreeType(&lib)) {
- return;
- }
- aa = aaA;
- ok = gTrue;
-}
-
-FTFontEngine::~FTFontEngine() {
- FT_Done_FreeType(lib);
-}
-
-//------------------------------------------------------------------------
-
-FTFontFile::FTFontFile(FTFontEngine *engineA, char *fontFileName,
- char **fontEnc, GBool pdfFontHasEncoding) {
- char *name;
- int unicodeCmap, macRomanCmap, msSymbolCmap;
- int i, j;
-
- ok = gFalse;
- engine = engineA;
- codeMap = NULL;
- if (FT_New_Face(engine->lib, fontFileName, 0, &face)) {
- return;
- }
-
- if (!strcmp(face->driver->root.clazz->module_name, "type1") ||
- !strcmp(face->driver->root.clazz->module_name, "cff")) {
-
- mode = ftFontModeCodeMapDirect;
- codeMap = (Guint *)gmalloc(256 * sizeof(Guint));
- for (i = 0; i < 256; ++i) {
- codeMap[i] = 0;
- if ((name = fontEnc[i])) {
- codeMap[i] = FT_Get_Name_Index(face, name);
- }
- }
-
- } else {
-
- // To match up with the Adobe-defined behaviour, we choose a cmap
- // like this:
- // 1. If the PDF font has an encoding:
- // 1a. If the TrueType font has a Microsoft Unicode cmap, use it,
- // and use the Unicode indexes, not the char codes.
- // 1b. If the TrueType font has a Macintosh Roman cmap, use it,
- // and reverse map the char names through MacRomanEncoding to
- // get char codes.
- // 2. If the PDF font does not have an encoding:
- // 2a. If the TrueType font has a Macintosh Roman cmap, use it,
- // and use char codes directly.
- // 2b. If the TrueType font has a Microsoft Symbol cmap, use it,
- // and use (0xf000 + char code).
- // 3. If none of these rules apply, use the first cmap and hope for
- // the best (this shouldn't happen).
- unicodeCmap = macRomanCmap = msSymbolCmap = 0xffff;
- for (i = 0; i < face->num_charmaps; ++i) {
- if (face->charmaps[i]->platform_id == 3 &&
- face->charmaps[i]->encoding_id == 1) {
- unicodeCmap = i;
- } else if (face->charmaps[i]->platform_id == 1 &&
- face->charmaps[i]->encoding_id == 0) {
- macRomanCmap = i;
- } else if (face->charmaps[i]->platform_id == 3 &&
- face->charmaps[i]->encoding_id == 0) {
- msSymbolCmap = i;
- }
- }
- i = 0;
- mode = ftFontModeCharCode;
- charMapOffset = 0;
- if (pdfFontHasEncoding) {
- if (unicodeCmap != 0xffff) {
- i = unicodeCmap;
- mode = ftFontModeUnicode;
- } else if (macRomanCmap != 0xffff) {
- i = macRomanCmap;
- mode = ftFontModeCodeMap;
- codeMap = (Guint *)gmalloc(256 * sizeof(Guint));
- for (j = 0; j < 256; ++j) {
- if (fontEnc[j]) {
- codeMap[j] = globalParams->getMacRomanCharCode(fontEnc[j]);
- } else {
- codeMap[j] = 0;
- }
- }
- }
- } else {
- if (macRomanCmap != 0xffff) {
- i = macRomanCmap;
- mode = ftFontModeCharCode;
- } else if (msSymbolCmap != 0xffff) {
- i = msSymbolCmap;
- mode = ftFontModeCharCodeOffset;
- charMapOffset = 0xf000;
- }
- }
- if (FT_Set_Charmap(face, face->charmaps[i])) {
- return;
- }
- }
-
- ok = gTrue;
-}
-
-FTFontFile::FTFontFile(FTFontEngine *engineA, char *fontFileName,
- Gushort *cidToGIDA, int cidToGIDLenA) {
- ok = gFalse;
- engine = engineA;
- codeMap = NULL;
- if (FT_New_Face(engine->lib, fontFileName, 0, &face)) {
- return;
- }
- cidToGID = cidToGIDA;
- cidToGIDLen = cidToGIDLenA;
- mode = ftFontModeCIDToGIDMap;
- ok = gTrue;
-}
-
-FTFontFile::FTFontFile(FTFontEngine *engineA, char *fontFileName) {
- ok = gFalse;
- engine = engineA;
- codeMap = NULL;
- if (FT_New_Face(engine->lib, fontFileName, 0, &face)) {
- return;
- }
- cidToGID = NULL;
- cidToGIDLen = 0;
- mode = ftFontModeCFFCharset;
- ok = gTrue;
-}
-
-FTFontFile::~FTFontFile() {
- if (face) {
- FT_Done_Face(face);
- }
- if (codeMap) {
- gfree(codeMap);
- }
-}
-
-//------------------------------------------------------------------------
-
-FTFont::FTFont(FTFontFile *fontFileA, double *m) {
- FTFontEngine *engine;
- FT_Face face;
- double size, div;
- int x, xMin, xMax;
- int y, yMin, yMax;
- int i;
-
- ok = gFalse;
- fontFile = fontFileA;
- engine = fontFile->engine;
- face = fontFile->face;
- if (FT_New_Size(face, &sizeObj)) {
- return;
- }
- face->size = sizeObj;
- size = sqrt(m[2]*m[2] + m[3]*m[3]);
- if (FT_Set_Pixel_Sizes(face, 0, (int)size)) {
- return;
- }
-
- div = face->bbox.xMax > 20000 ? 65536 : 1;
-
- // transform the four corners of the font bounding box -- the min
- // and max values form the bounding box of the transformed font
- x = (int)((m[0] * face->bbox.xMin + m[2] * face->bbox.yMin) /
- (div * face->units_per_EM));
- xMin = xMax = x;
- y = (int)((m[1] * face->bbox.xMin + m[3] * face->bbox.yMin) /
- (div * face->units_per_EM));
- yMin = yMax = y;
- x = (int)((m[0] * face->bbox.xMin + m[2] * face->bbox.yMax) /
- (div * face->units_per_EM));
- if (x < xMin) {
- xMin = x;
- } else if (x > xMax) {
- xMax = x;
- }
- y = (int)((m[1] * face->bbox.xMin + m[3] * face->bbox.yMax) /
- (div * face->units_per_EM));
- if (y < yMin) {
- yMin = y;
- } else if (y > yMax) {
- yMax = y;
- }
- x = (int)((m[0] * face->bbox.xMax + m[2] * face->bbox.yMin) /
- (div * face->units_per_EM));
- if (x < xMin) {
- xMin = x;
- } else if (x > xMax) {
- xMax = x;
- }
- y = (int)((m[1] * face->bbox.xMax + m[3] * face->bbox.yMin) /
- (div * face->units_per_EM));
- if (y < yMin) {
- yMin = y;
- } else if (y > yMax) {
- yMax = y;
- }
- x = (int)((m[0] * face->bbox.xMax + m[2] * face->bbox.yMax) /
- (div * face->units_per_EM));
- if (x < xMin) {
- xMin = x;
- } else if (x > xMax) {
- xMax = x;
- }
- y = (int)((m[1] * face->bbox.xMax + m[3] * face->bbox.yMax) /
- (div * face->units_per_EM));
- 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);
- }
- // this should be (max - min + 1), but we add some padding to
- // deal with rounding errors, bogus bboxes, etc.
- glyphW = xMax - xMin + 3;
- glyphW += glyphW >> 1;
- glyphH = yMax - yMin + 3;
- glyphH += glyphH >> 1;
- 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 = (FTFontCacheTag *)gmalloc(cacheSets * cacheAssoc *
- sizeof(FTFontCacheTag));
- 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);
-
- // compute the transform matrix
- matrix.xx = (FT_Fixed)((m[0] / size) * 65536);
- matrix.yx = (FT_Fixed)((m[1] / size) * 65536);
- matrix.xy = (FT_Fixed)((m[2] / size) * 65536);
- matrix.yy = (FT_Fixed)((m[3] / size) * 65536);
-
- ok = gTrue;
-}
-
-FTFont::~FTFont() {
- gfree(cacheTags);
- gfree(cache);
- gfree(image->data);
- image->data = NULL;
- XDestroyImage(image);
-}
-
-GBool FTFont::drawChar(Drawable d, int w, int h, GC gc,
- int x, int y, int r, int g, int b,
- CharCode c, Unicode u) {
- FTFontEngine *engine;
- XColor xcolor;
- int bgR, bgG, bgB;
- Gulong colors[5];
- Guchar *p;
- int pix;
- int xOffset, yOffset, x0, y0, x1, y1, gw, gh, w0, h0;
- int xx, yy, xx1;
-
- engine = fontFile->engine;
-
- // no Unicode index for this char - don't draw anything
- if (fontFile->mode == ftFontModeUnicode && u == 0) {
- return gFalse;
- }
-
- // generate the glyph pixmap
- if (!(p = getGlyphPixmap(c, u, &xOffset, &yOffset, &gw, &gh))) {
- 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) {
- return gTrue;
- }
- if (y0 < 0) {
- y1 = -y0;
- h0 += y0;
- y0 = 0;
- }
- if (y0 + h0 > h) {
- h0 = h - y0;
- }
- if (h0 < 0) {
- return gTrue;
- }
-
- // read the X image
- XGetSubImage(engine->display, d, x0, y0, w0, h0, (1 << engine->depth) - 1,
- ZPixmap, image, x1, y1);
-
- if (engine->aa) {
-
- // compute the colors
- xcolor.pixel = XGetPixel(image, x1 + w0/2, y1 + h0/2);
- XQueryColor(engine->display, engine->colormap, &xcolor);
- bgR = xcolor.red;
- bgG = xcolor.green;
- bgB = xcolor.blue;
- 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
- for (yy = 0; yy < gh; ++yy) {
- for (xx = 0; xx < gw; ++xx) {
- pix = *p++ & 0xff;
- // this is a heuristic which seems to produce decent
- // results -- the linear mapping would be:
- // pix = (pix * 5) / 256;
- pix = ((pix + 10) * 5) / 256;
- if (pix > 4) {
- pix = 4;
- }
- if (pix > 0) {
- XPutPixel(image, xx, yy, colors[pix]);
- }
- }
- }
-
- } else {
-
- // one color
- colors[1] = engine->findColor(r, g, b);
-
- // stuff the glyph bitmap into the X image
- 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 & 0x80) {
- XPutPixel(image, xx1, yy, colors[1]);
- }
- pix <<= 1;
- }
- }
- }
-
- }
-
- // draw the X image
- XPutImage(engine->display, d, gc, image, x1, y1, x0, y0, w0, h0);
-
- return gTrue;
-}
-
-Guchar *FTFont::getGlyphPixmap(CharCode c, Unicode u,
- int *x, int *y, int *w, int *h) {
- FT_GlyphSlot slot;
- FT_UInt idx;
- int rowSize;
- int i, j, k;
- Guchar *ret, *p, *q;
-
- // 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;
- return cache + (i+j) * glyphSize;
- }
- }
-
- // generate the glyph pixmap or bitmap
- fontFile->face->size = sizeObj;
- FT_Set_Transform(fontFile->face, &matrix, NULL);
- slot = fontFile->face->glyph;
- idx = getGlyphIndex(c, u);
- // if we have the FT2 bytecode interpreter, autohinting won't be used
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- if (FT_Load_Glyph(fontFile->face, idx, FT_LOAD_DEFAULT)) {
- return gFalse;
- }
-#else
- // FT2's autohinting doesn't always work very well (especially with
- // font subsets), so turn it off if anti-aliasing is enabled; if
- // anti-aliasing is disabled, this seems to be a tossup - some fonts
- // look better with hinting, some without, so leave hinting on
- if (FT_Load_Glyph(fontFile->face, idx,
- fontFile->engine->aa ? FT_LOAD_NO_HINTING
- : FT_LOAD_DEFAULT)) {
- return gFalse;
- }
-#endif
- if (FT_Render_Glyph(slot,
- fontFile->engine->aa ? ft_render_mode_normal :
- ft_render_mode_mono)) {
- return gFalse;
- }
- *x = -slot->bitmap_left;
- *y = slot->bitmap_top;
- *w = slot->bitmap.width;
- *h = slot->bitmap.rows;
- if (*w > glyphW || *h > glyphH) {
-#if 1 //~ debug
- fprintf(stderr, "Weird FreeType glyph size: %d > %d or %d > %d\n",
- *w, glyphW, *h, glyphH);
-#endif
- return NULL;
- }
-
- // store glyph pixmap in cache
- ret = NULL;
- 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;
- if (fontFile->engine->aa) {
- rowSize = *w;
- } else {
- rowSize = (*w + 7) >> 3;
- }
- ret = cache + (i+j) * glyphSize;
- for (k = 0, p = ret, q = slot->bitmap.buffer;
- k < slot->bitmap.rows;
- ++k, p += rowSize, q += slot->bitmap.pitch) {
- memcpy(p, q, rowSize);
- }
- } else {
- ++cacheTags[i+j].mru;
- }
- }
- return ret;
-}
-
-GBool FTFont::getCharPath(CharCode c, Unicode u, GfxState *state) {
- static FT_Outline_Funcs outlineFuncs = {
- &charPathMoveTo,
- &charPathLineTo,
- &charPathConicTo,
- &charPathCubicTo,
- 0, 0
- };
- FT_GlyphSlot slot;
- FT_UInt idx;
- FT_Glyph glyph;
-
- fontFile->face->size = sizeObj;
- FT_Set_Transform(fontFile->face, &matrix, NULL);
- slot = fontFile->face->glyph;
- idx = getGlyphIndex(c, u);
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- if (FT_Load_Glyph(fontFile->face, idx, FT_LOAD_DEFAULT)) {
- return gFalse;
- }
-#else
- // FT2's autohinting doesn't always work very well (especially with
- // font subsets), so turn it off if anti-aliasing is enabled; if
- // anti-aliasing is disabled, this seems to be a tossup - some fonts
- // look better with hinting, some without, so leave hinting on
- if (FT_Load_Glyph(fontFile->face, idx,
- fontFile->engine->aa ? FT_LOAD_NO_HINTING
- : FT_LOAD_DEFAULT)) {
- return gFalse;
- }
-#endif
- if (FT_Get_Glyph(slot, &glyph)) {
- return gFalse;
- }
- FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
- &outlineFuncs, state);
- return gTrue;
-}
-
-int FTFont::charPathMoveTo(FT_Vector *pt, void *state) {
- ((GfxState *)state)->moveTo(pt->x / 64.0, -pt->y / 64.0);
- return 0;
-}
-
-int FTFont::charPathLineTo(FT_Vector *pt, void *state) {
- ((GfxState *)state)->lineTo(pt->x / 64.0, -pt->y / 64.0);
- return 0;
-}
-
-int FTFont::charPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *state) {
- double x0, y0, x1, y1, x2, y2, x3, y3, xc, yc;
-
- x0 = ((GfxState *)state)->getCurX();
- y0 = ((GfxState *)state)->getCurY();
- xc = ctrl->x / 64.0;
- yc = -ctrl->y / 64.0;
- x3 = pt->x / 64.0;
- y3 = -pt->y / 64.0;
-
- // A second-order Bezier curve is defined by two endpoints, p0 and
- // p3, and one control point, pc:
- //
- // p(t) = (1-t)^2*p0 + t*(1-t)*pc + t^2*p3
- //
- // A third-order Bezier curve is defined by the same two endpoints,
- // p0 and p3, and two control points, p1 and p2:
- //
- // p(t) = (1-t)^3*p0 + 3t*(1-t)^2*p1 + 3t^2*(1-t)*p2 + t^3*p3
- //
- // Applying some algebra, we can convert a second-order curve to a
- // third-order curve:
- //
- // p1 = (1/3) * (p0 + 2pc)
- // p2 = (1/3) * (2pc + p3)
-
- x1 = (1.0 / 3.0) * (x0 + 2 * xc);
- y1 = (1.0 / 3.0) * (y0 + 2 * yc);
- x2 = (1.0 / 3.0) * (2 * xc + x3);
- y2 = (1.0 / 3.0) * (2 * yc + y3);
-
- ((GfxState *)state)->curveTo(x1, y1, x2, y2, x3, y3);
- return 0;
-}
-
-int FTFont::charPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2,
- FT_Vector *pt, void *state) {
- ((GfxState *)state)->curveTo(ctrl1->x / 64.0, -ctrl1->y / 64.0,
- ctrl2->x / 64.0, -ctrl2->y / 64.0,
- pt->x / 64.0, -pt->y / 64.0);
- return 0;
-}
-
-FT_UInt FTFont::getGlyphIndex(CharCode c, Unicode u) {
- FT_UInt idx;
- int j;
-
- idx = 0; // make gcc happy
- switch (fontFile->mode) {
- case ftFontModeUnicode:
- idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)u);
- break;
- case ftFontModeCharCode:
- idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)c);
- break;
- case ftFontModeCharCodeOffset:
- idx = FT_Get_Char_Index(fontFile->face,
- (FT_ULong)(c + fontFile->charMapOffset));
- break;
- case ftFontModeCodeMap:
- if (c <= 0xff) {
- idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)fontFile->codeMap[c]);
- } else {
- idx = 0;
- }
- break;
- case ftFontModeCodeMapDirect:
- if (c <= 0xff) {
- idx = (FT_UInt)fontFile->codeMap[c];
- } else {
- idx = 0;
- }
- break;
- case ftFontModeCIDToGIDMap:
- if (fontFile->cidToGIDLen) {
- if ((int)c < fontFile->cidToGIDLen) {
- idx = (FT_UInt)fontFile->cidToGID[c];
- } else {
- idx = (FT_UInt)0;
- }
- } else {
- idx = (FT_UInt)c;
- }
- break;
- case ftFontModeCFFCharset:
-#if 1 //~ cff cid->gid map
-#if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0
- CFF_Font *cff = (CFF_Font *)((TT_Face)fontFile->face)->extra.data;
-#else
- CFF_Font cff = (CFF_Font)((TT_Face)fontFile->face)->extra.data;
-#endif
- idx = 0;
- for (j = 0; j < (int)cff->num_glyphs; ++j) {
- if (cff->charset.sids[j] == c) {
- idx = j;
- break;
- }
- }
-#endif
- break;
- }
- return idx;
-}
-
-#endif // FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)