📄 xoutputdev.cc
字号:
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; } } }}XOutputServer16BitFont::~XOutputServer16BitFont() { xUMap->decRefCnt(); if (xFont) { XFreeFont(display, xFont); }}GBool XOutputServer16BitFont::isOk() { return xFont != NULL;}void XOutputServer16BitFont::updateGC(GC gc) { XSetFont(display, gc, xFont->fid);}void XOutputServer16BitFont::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) { char buf[16]; XChar2b c1; double dx1, dy1; int m, n, i, j, k; 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+1 < m; j += 2) { c1.byte1 = buf[j]; c1.byte2 = buf[j+1]; XDrawString16(display, pixmap, gc, xoutRound(x + k*dx1), xoutRound(y + k*dy1), &c1, 1); ++k; } } } else if (c != 0) { // some PDF files use CID 0, which is .notdef, so just ignore it error(-1, "Unknown character (CID=%d Unicode=%04x)", c, uLen > 0 ? u[0] : (Unicode)0); }}//------------------------------------------------------------------------// XOutputFontCache//------------------------------------------------------------------------#if HAVE_T1LIB_HXOutputT1FontFile::~XOutputT1FontFile() { delete fontFile; if (tmpFileName) { unlink(tmpFileName->getCString()); delete tmpFileName; }}#endif#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)XOutputFTFontFile::~XOutputFTFontFile() { delete fontFile; if (tmpFileName) { unlink(tmpFileName->getCString()); delete tmpFileName; }}#endif#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)XOutputTTFontFile::~XOutputTTFontFile() { delete fontFile; if (tmpFileName) { unlink(tmpFileName->getCString()); delete tmpFileName; }}#endifXOutputFontCache::XOutputFontCache(Display *displayA, Guint depthA, XOutputDev *xOutA, FontRastControl t1libControlA, FontRastControl freetypeControlA) { display = displayA; depth = depthA; xOut = xOutA;#if HAVE_T1LIB_H t1Engine = NULL; t1libControl = t1libControlA;#endif#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) ftEngine = NULL;#endif#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) ttEngine = NULL;#endif#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H freetypeControl = freetypeControlA;#endif clear();}XOutputFontCache::~XOutputFontCache() { delFonts();}void XOutputFontCache::startDoc(int screenNum, Visual *visual, Colormap colormap, GBool trueColor, int rMul, int gMul, int bMul, int rShift, int gShift, int bShift, Gulong *colors, int numColors) { delFonts(); clear();#if HAVE_T1LIB_H if (t1libControl != fontRastNone) { t1Engine = new T1FontEngine(display, visual, depth, colormap, t1libControl == fontRastAALow || t1libControl == fontRastAAHigh, t1libControl == fontRastAAHigh); if (t1Engine->isOk()) { if (trueColor) { t1Engine->useTrueColor(rMul, rShift, gMul, gShift, bMul, bShift); } else { t1Engine->useColorCube(colors, numColors); } } else { delete t1Engine; t1Engine = NULL; } }#endif // HAVE_T1LIB_H#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) if (freetypeControl != fontRastNone) { ftEngine = new FTFontEngine(display, visual, depth, colormap, freetypeControl == fontRastAALow || freetypeControl == fontRastAAHigh); if (ftEngine->isOk()) { if (trueColor) { ftEngine->useTrueColor(rMul, rShift, gMul, gShift, bMul, bShift); } else { ftEngine->useColorCube(colors, numColors); } } else { delete ftEngine; ftEngine = NULL; } }#endif // FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) if (freetypeControl != fontRastNone) { ttEngine = new TTFontEngine(display, visual, depth, colormap, freetypeControl == fontRastAALow || freetypeControl == fontRastAAHigh); if (ttEngine->isOk()) { if (trueColor) { ttEngine->useTrueColor(rMul, rShift, gMul, gShift, bMul, bShift); } else { ttEngine->useColorCube(colors, numColors); } } else { delete ttEngine; ttEngine = NULL; } }#endif // !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)}void XOutputFontCache::delFonts() { int i; for (i = 0; i < nFonts; ++i) { delete fonts[i]; }#if HAVE_T1LIB_H // delete Type 1 font files deleteGList(t1FontFiles, XOutputT1FontFile); if (t1Engine) { delete t1Engine; }#endif#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) // delete FreeType font files deleteGList(ftFontFiles, XOutputFTFontFile); if (ftEngine) { delete ftEngine; }#endif#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) // delete TrueType fonts deleteGList(ttFontFiles, XOutputTTFontFile); if (ttEngine) { delete ttEngine; }#endif}void XOutputFontCache::clear() { int i; for (i = 0; i < xOutFontCacheSize; ++i) { fonts[i] = NULL; } nFonts = 0;#if HAVE_T1LIB_H // clear Type 1 font files t1FontFiles = new GList();#endif#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) // clear FreeType font cache ftFontFiles = new GList();#endif#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) // clear TrueType font cache ttFontFiles = new GList();#endif}XOutputFont *XOutputFontCache::getFont(XRef *xref, GfxFont *gfxFont, double m11, double m12, double m21, double m22) { XOutputFont *font; DisplayFontParam *dfp; GString *substName; double m11New, m12New, m21New, m22New; double w1, w2, v; double *fm; char *name; int index; int code; int i, j; // is it the most recently used font? if (nFonts > 0 && fonts[0]->matches(gfxFont->getID(), m11, m12, m21, m22)) { return fonts[0]; } // is it in the cache? for (i = 1; i < nFonts; ++i) { if (fonts[i]->matches(gfxFont->getID(), m11, m12, m21, m22)) { font = fonts[i]; for (j = i; j > 0; --j) { fonts[j] = fonts[j-1]; } fonts[0] = font; return font; } } // try for a cached FontFile, an embedded font, or an external font // file font = NULL; switch (gfxFont->getType()) { case fontType1: case fontType1C:#if HAVE_T1LIB_H if (t1libControl != fontRastNone) { font = tryGetT1Font(xref, gfxFont, m11, m12, m21, m22); }#endif#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) if (!font) { if (freetypeControl != fontRastNone) { font = tryGetFTFont(xref, gfxFont, m11, m12, m21, m22); } }#endif break; case fontTrueType: case fontCIDType2:#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) if (freetypeControl != fontRastNone) { font = tryGetFTFont(xref, gfxFont, m11, m12, m21, m22); }#endif#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) if (freetypeControl != fontRastNone) { font = tryGetTTFont(xref, gfxFont, m11, m12, m21, m22); }#endif break; case fontCIDType0: case fontCIDType0C:#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) if (freetypeControl != fontRastNone) { font = tryGetFTFont(xref, gfxFont, m11, m12, m21, m22); }#endif break; default: break; } if (!font) { // search for a display font mapping dfp = NULL; if (gfxFont->isCIDFont()) { if (((GfxCIDFont *)gfxFont)->getCollection()) { dfp = globalParams-> getDisplayCIDFont(gfxFont->getName(), ((GfxCIDFont *)gfxFont)->getCollection()); } else { // this error (no CMap file) was already reported by GfxFont return NULL; } } else { if (gfxFont->getName()) { dfp = globalParams->getDisplayFont(gfxFont->getName()); } } if (dfp) { font = tryGetFont(xref, dfp, gfxFont, m11, m12, m21, m22, m11, m12, m21, m22, gFalse); } // substitute a font (8-bit fonts only) if (!font && !gfxFont->isCIDFont()) { // choose a substitute font if (gfxFont->isFixedWidth()) { index = 8; } else if (gfxFont->isSerif()) { index = 4; } else { index = 0; } if (gfxFont->isBold()) { index += 2; } if (gfxFont->isItalic()) { index += 1; } substName = new GString(xOutSubstFonts[index].name); // adjust the font matrix -- compare the width of 'm' in the // original font and the substituted font m11New = m11; m12New = m12; m21New = m21; m22New = m22; for (code = 0; code < 256; ++code) { if ((name = ((Gfx8BitFont *)gfxFont)->getCharName(code)) && name[0] == 'm' && name[1] == '\0') { break; } } if (code < 256) { w1 = ((Gfx8BitFont *)gfxFont)->getWidth(code); w2 = xOutSubstFonts[index].mWidth; if (gfxFont->getType() == fontType3) { // This is a hack which makes it possible to substitute for some // Type 3 fonts. The problem is that it's impossible to know what // the base coordinate system used in the font is without actually // rendering the font. This code tries to guess by looking at the // width of the character 'm' (which breaks if the font is a // subset that doesn't contain 'm'). if (w1 > 0 && (w1 > 1.1 * w2 || w1 < 0.9 * w2)) { w1 /= w2; m11New *= w1; m12New *= w1; m21New *= w1; m22New *= w1; } fm = gfxFont->getFontMatrix(); v = (fm[0] == 0) ? 1 : (fm[3] / fm[0]); m21New *= v; m22New *= v; } else if (!gfxFont->isSymbolic()) { // if real font is substantially narrower than substituted // font, reduce the font size accordingly if (w1 > 0.01 && w1 < 0.9 * w2) { w1 /= w2; m11New *= w1; m21New *= w1; } } } // get the font dfp = globalParams->getDisplayFont(substName); delete substName; if (!dfp) { // this should never happen since GlobalParams sets up default // mappings for the Base-14 fonts error(-1, "Couldn't find a font for '%s'", gfxFont->getName()->getCString()); return NULL; } font = tryGetFont(xref, dfp, gfxFont, m11, m12, m21, m22, m11New, m12New, m21New, m22New, gTrue); } } // check for error if (!font) { // This will happen if the user specifies a bogus font in the // config file (a non-existent font file or a font that requires a // rasterizer that is disabled or wasn't built in), or if a CID // font has no associated font in the config file. if (gfxFont->isCIDFont()) { error(-1, "Couldn't find a font for the '%s' character collection", ((GfxCIDFont *)gfxFont)->getCollection()->getCString()); } else { error(-1, "Couldn't find a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "[unnamed]"); } return NULL; } // insert font in cache if (nFonts == xOutFontCacheSize) { --nFonts; delete fonts[nFonts]; } for (j = nFonts; j > 0; --j) { fonts[j] = fonts[j-1]; } fonts[0] = font; ++nFonts; return font;}XOutputFont *XOutputFontCache::tryGetFont(XRef *xref, DisplayFontParam *dfp, GfxFont *gfxFont, double m11Orig, double m12Orig, double m21Orig, double m22Orig,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -