📄 xoutputdev.cc
字号:
//========================================================================//// XOutputDev.cc//// Copyright 1996-2002 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <math.h>#include "gmem.h"#include "gfile.h"#include "GString.h"#include "GList.h"#include "Object.h"#include "Stream.h"#include "Link.h"#include "GfxState.h"#include "GfxFont.h"#include "UnicodeMap.h"#include "CharCodeToUnicode.h"#include "FontFile.h"#include "Error.h"#include "TextOutputDev.h"#include "XOutputDev.h"#if HAVE_T1LIB_H#include "T1Font.h"#endif#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)#include "FTFont.h"#endif#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)#include "TTFont.h"#endif#ifdef VMS#if (__VMS_VER < 70000000)extern "C" int unlink(char *filename);#endif#endif#ifdef XlibSpecificationRelease#if XlibSpecificationRelease < 5typedef char *XPointer;#endif#elsetypedef char *XPointer;#endif//------------------------------------------------------------------------// Constants and macros//------------------------------------------------------------------------#define xoutRound(x) ((int)(x + 0.5))#define maxCurveSplits 6 // max number of splits when recursively // drawing Bezier curves//------------------------------------------------------------------------// Font substitutions//------------------------------------------------------------------------struct XOutFontSubst { char *name; double mWidth;};// index: {symbolic:12, fixed:8, serif:4, sans-serif:0} + bold*2 + italicstatic XOutFontSubst xOutSubstFonts[16] = { {"Helvetica", 0.833}, {"Helvetica-Oblique", 0.833}, {"Helvetica-Bold", 0.889}, {"Helvetica-BoldOblique", 0.889}, {"Times-Roman", 0.788}, {"Times-Italic", 0.722}, {"Times-Bold", 0.833}, {"Times-BoldItalic", 0.778}, {"Courier", 0.600}, {"Courier-Oblique", 0.600}, {"Courier-Bold", 0.600}, {"Courier-BoldOblique", 0.600}, {"Symbol", 0.576}, {"Symbol", 0.576}, {"Symbol", 0.576}, {"Symbol", 0.576}};//------------------------------------------------------------------------static void outputToFile(void *stream, char *data, int len) { fwrite(data, 1, len, (FILE *)stream);}//------------------------------------------------------------------------// XOutputFont//------------------------------------------------------------------------XOutputFont::XOutputFont(Ref *idA, double m11OrigA, double m12OrigA, double m21OrigA, double m22OrigA, double m11A, double m12A, double m21A, double m22A, Display *displayA, XOutputDev *xOutA) { id = *idA; display = displayA; xOut = xOutA; m11Orig = m11OrigA; m12Orig = m12OrigA; m21Orig = m21OrigA; m22Orig = m22OrigA; m11 = m11A; m12 = m12A; m21 = m21A; m22 = m22A;}XOutputFont::~XOutputFont() {}void XOutputFont::getCharPath(GfxState *state, CharCode c, Unicode *u, int ulen) {}#if HAVE_T1LIB_H//------------------------------------------------------------------------// XOutputT1Font//------------------------------------------------------------------------XOutputT1Font::XOutputT1Font(Ref *idA, T1FontFile *fontFileA, double m11OrigA, double m12OrigA, double m21OrigA, double m22OrigA, double m11A, double m12A, double m21A, double m22A, Display *displayA, XOutputDev *xOutA): XOutputFont(idA, m11OrigA, m12OrigA, m21OrigA, m22OrigA, m11A, m12A, m21A, m22A, displayA, xOutA){ double matrix[4]; fontFile = fontFileA; // create the transformed instance matrix[0] = m11; matrix[1] = -m12; matrix[2] = m21; matrix[3] = -m22; font = new T1Font(fontFile, matrix);}XOutputT1Font::~XOutputT1Font() { if (font) { delete font; }}GBool XOutputT1Font::isOk() { return font != NULL;}void XOutputT1Font::updateGC(GC gc) {}void XOutputT1Font::drawChar(GfxState *state, Pixmap pixmap, int w, int h, GC gc, GfxRGB *rgb, double x, double y, double dx, double dy, CharCode c, Unicode *u, int uLen) { font->drawChar(pixmap, w, h, gc, xoutRound(x), xoutRound(y), (int)(rgb->r * 65535), (int)(rgb->g * 65535), (int)(rgb->b * 65535), c, u[0]);}void XOutputT1Font::getCharPath(GfxState *state, CharCode c, Unicode *u, int uLen) { font->getCharPath(c, u[0], state);}#endif // HAVE_T1LIB_H#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)//------------------------------------------------------------------------// XOutputFTFont//------------------------------------------------------------------------XOutputFTFont::XOutputFTFont(Ref *idA, FTFontFile *fontFileA, double m11OrigA, double m12OrigA, double m21OrigA, double m22OrigA, double m11A, double m12A, double m21A, double m22A, Display *displayA, XOutputDev *xOutA): XOutputFont(idA, m11OrigA, m12OrigA, m21OrigA, m22OrigA, m11A, m12A, m21A, m22A, displayA, xOutA){ double matrix[4]; fontFile = fontFileA; // create the transformed instance matrix[0] = m11; matrix[1] = -m12; matrix[2] = m21; matrix[3] = -m22; font = new FTFont(fontFile, matrix);}XOutputFTFont::~XOutputFTFont() { if (font) { delete font; }}GBool XOutputFTFont::isOk() { return font != NULL;}void XOutputFTFont::updateGC(GC gc) {}void XOutputFTFont::drawChar(GfxState *state, Pixmap pixmap, int w, int h, GC gc, GfxRGB *rgb, double x, double y, double dx, double dy, CharCode c, Unicode *u, int uLen) { font->drawChar(pixmap, w, h, gc, xoutRound(x), xoutRound(y), (int)(rgb->r * 65535), (int)(rgb->g * 65535), (int)(rgb->b * 65535), c, uLen > 0 ? u[0] : 0);}void XOutputFTFont::getCharPath(GfxState *state, CharCode c, Unicode *u, int uLen) { font->getCharPath(c, u[0], state);}#endif // FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)//------------------------------------------------------------------------// XOutputTTFont//------------------------------------------------------------------------XOutputTTFont::XOutputTTFont(Ref *idA, TTFontFile *fontFileA, double m11OrigA, double m12OrigA, double m21OrigA, double m22OrigA, double m11A, double m12A, double m21A, double m22A, Display *displayA, XOutputDev *xOutA): XOutputFont(idA, m11OrigA, m12OrigA, m21OrigA, m22OrigA, m11A, m12A, m21A, m22A, displayA, xOutA){ double matrix[4]; fontFile = fontFileA; // create the transformed instance matrix[0] = m11; matrix[1] = -m12; matrix[2] = m21; matrix[3] = -m22; font = new TTFont(fontFile, matrix);}XOutputTTFont::~XOutputTTFont() { if (font) { delete font; }}GBool XOutputTTFont::isOk() { return font != NULL;}void XOutputTTFont::updateGC(GC gc) {}void XOutputTTFont::drawChar(GfxState *state, Pixmap pixmap, int w, int h, GC gc, GfxRGB *rgb, double x, double y, double dx, double dy, CharCode c, Unicode *u, int uLen) { font->drawChar(pixmap, w, h, gc, xoutRound(x), xoutRound(y), (int)(rgb->r * 65535), (int)(rgb->g * 65535), (int)(rgb->b * 65535), c, u[0]);}#endif // !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)//------------------------------------------------------------------------// XOutputServer8BitFont//------------------------------------------------------------------------// Copy <fmt>, substituting <val> for one occurrence of "%s", into// <buf>.static void stringSubst(char *buf, int bufSize, char *fmt, char *val) { char *p, *q; int i; i = 0; p = fmt; while (*p) { if (p[0] == '%' && p[1] == 's') { q = val; while (*q && i < bufSize - 1) { buf[i++] = *q++; } p += 2; } else { if (i < bufSize - 1) { buf[i++] = *p; } ++p; } } buf[i] = '\0';}XOutputServer8BitFont::XOutputServer8BitFont(Ref *idA, GString *xlfdFmt, UnicodeMap *xUMapA, CharCodeToUnicode *fontUMap, double m11OrigA, double m12OrigA, double m21OrigA, double m22OrigA, double m11A, double m12A, double m21A, double m22A, Display *displayA, XOutputDev *xOutA): XOutputFont(idA, m11OrigA, m12OrigA, m21OrigA, m22OrigA, m11A, m12A, m21A, m22A, displayA, xOutA){ double size, ntm11, ntm12, ntm21, ntm22; GBool rotated; int startSize, sz; char fontName[500], fontSize[100]; Unicode u; char buf; int i; // compute size and normalized transform matrix size = sqrt(m21*m21 + m22*m22); ntm11 = m11 / size; ntm12 = -m12 / size; ntm21 = m21 / size; ntm22 = -m22 / size; // try to get a rotated font? rotated = !(ntm11 > 0 && ntm22 > 0 && fabs(ntm11 / ntm22 - 1) < 0.2 && fabs(ntm12) < 0.01 && fabs(ntm21) < 0.01); // open X font -- if font is not found (which means the server can't // scale fonts), try progressively smaller and then larger sizes startSize = (int)size; if (rotated) { sprintf(fontSize, "[%s%0.2f %s%0.2f %s%0.2f %s%0.2f]", ntm11<0 ? "~" : "", fabs(ntm11 * size), ntm12<0 ? "~" : "", fabs(ntm12 * size), ntm21<0 ? "~" : "", fabs(ntm21 * size), ntm22<0 ? "~" : "", fabs(ntm22 * size)); } else { sprintf(fontSize, "%d", startSize); } stringSubst(fontName, sizeof(fontName), xlfdFmt->getCString(), fontSize); xFont = XLoadQueryFont(display, fontName); if (!xFont) { for (sz = startSize; sz >= startSize/2 && sz >= 1; --sz) { sprintf(fontSize, "%d", sz); stringSubst(fontName, sizeof(fontName), xlfdFmt->getCString(), fontSize); if ((xFont = XLoadQueryFont(display, fontName))) break; } if (!xFont) { for (sz = startSize + 1; sz < startSize + 10; ++sz) { sprintf(fontSize, "%d", sz); stringSubst(fontName, sizeof(fontName), xlfdFmt->getCString(), fontSize); if ((xFont = XLoadQueryFont(display, fontName))) { break; } } if (!xFont) { sprintf(fontSize, "%d", startSize); stringSubst(fontName, sizeof(fontName), xlfdFmt->getCString(), fontSize); error(-1, "Failed to open font: '%s'", fontName); return; } } } // Construct char code map. xUMap = xUMapA; for (i = 0; i < 256; ++i) { if (fontUMap->mapToUnicode((CID)i, &u, 1) == 1 && xUMap->mapUnicode(u, &buf, 1) == 1) { map[i] = buf & 0xff; } else { map[i] = 0; } }}XOutputServer8BitFont::~XOutputServer8BitFont() { if (xFont) { XFreeFont(display, xFont); }}GBool XOutputServer8BitFont::isOk() { return xFont != NULL;}void XOutputServer8BitFont::updateGC(GC gc) { XSetFont(display, gc, xFont->fid);}void XOutputServer8BitFont::drawChar(GfxState *state, Pixmap pixmap, int w, int h, GC gc, GfxRGB *rgb, double x, double y, double dx, double dy, CharCode c, Unicode *u, int uLen) { Gushort c1; char buf[8]; double dx1, dy1; int m, n, i, j, k; c1 = map[c]; if (c1 > 0) { buf[0] = (char)c1; XDrawString(display, pixmap, gc, xoutRound(x), xoutRound(y), buf, 1); } else { // substituted character, using more than one character n = 0; for (i = 0; i < uLen; ++i) { n += xUMap->mapUnicode(u[i], buf, sizeof(buf)); } if (n > 0) { dx1 = dx / n; dy1 = dy / n; k = 0; for (i = 0; i < uLen; ++i) { m = xUMap->mapUnicode(u[i], buf, sizeof(buf)); for (j = 0; j < m; ++j) { XDrawString(display, pixmap, gc, xoutRound(x + k*dx1), xoutRound(y + k*dy1), buf + j, 1); ++k; } } } }}//------------------------------------------------------------------------// XOutputServer16BitFont//------------------------------------------------------------------------XOutputServer16BitFont::XOutputServer16BitFont(Ref *idA, GString *xlfdFmt, UnicodeMap *xUMapA, CharCodeToUnicode *fontUMap, double m11OrigA, double m12OrigA, double m21OrigA, double m22OrigA, double m11A, double m12A, double m21A, double m22A, Display *displayA, XOutputDev *xOutA): XOutputFont(idA, m11OrigA, m12OrigA, m21OrigA, m22OrigA, m11A, m12A, m21A, m22A, displayA, xOutA){ double size, ntm11, ntm12, ntm21, ntm22; GBool rotated; int startSize, sz; char fontName[500], fontSize[100]; xUMap = xUMapA; xUMap->incRefCnt(); // compute size and normalized transform matrix size = sqrt(m21*m21 + m22*m22); ntm11 = m11 / size; ntm12 = -m12 / size; ntm21 = m21 / size; ntm22 = -m22 / size; // try to get a rotated font? rotated = !(ntm11 > 0 && ntm22 > 0 && fabs(ntm11 / ntm22 - 1) < 0.2 &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -