📄 xoutputdev.cc
字号:
if (!font->isOk()) { delete font; return NULL; } return font;}#endif // !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)XOutputFont *XOutputFontCache::tryGetServerFont(GString *xlfd, GString *encodingName, GfxFont *gfxFont, double m11Orig, double m12Orig, double m21Orig, double m22Orig, double m11, double m12, double m21, double m22) { XOutputFont *font; UnicodeMap *uMap; CharCodeToUnicode *ctu; uMap = globalParams->getUnicodeMap(encodingName); if (gfxFont->isCIDFont()) { ctu = ((GfxCIDFont *)gfxFont)->getToUnicode(); font = new XOutputServer16BitFont(gfxFont->getID(), xlfd, uMap, ctu, m11Orig, m12Orig, m21Orig, m22Orig, m11, m12, m21, m22, display, xOut); ctu->decRefCnt(); } else { ctu = ((Gfx8BitFont *)gfxFont)->getToUnicode(); font = new XOutputServer8BitFont(gfxFont->getID(), xlfd, uMap, ctu, m11Orig, m12Orig, m21Orig, m22Orig, m11, m12, m21, m22, display, xOut); ctu->decRefCnt(); } uMap->decRefCnt(); if (!font->isOk()) { delete font; return NULL; } return font;}//------------------------------------------------------------------------// T3FontCache//------------------------------------------------------------------------struct T3FontCacheTag { Gushort code; Gushort mru; // valid bit (0x8000) and MRU index double wx, wy; // untransformed glyph metrics};class T3FontCache {public: T3FontCache(Ref *fontID, double m11A, double m12A, double m21A, double m22A, int glyphXA, int glyphYA, int glyphWA, int glyphHA, Display *displayA, Visual *visual, Guint depth, Pixmap origPixmap); ~T3FontCache(); GBool matches(Ref *idA, double m11A, double m12A, double m21A, double m22A) { return fontID.num == idA->num && fontID.gen == idA->gen && m11 == m11A && m12 == m12A && m21 == m21A && m22 == m22A; } Ref fontID; // PDF font ID double m11, m12, m21, m22; // transform matrix int glyphX, glyphY; // pixel offset of glyph pixmaps int glyphW, glyphH; // size of glyph pixmaps, in pixels int glyphSize; // size of glyph pixmaps, in bytes int cacheSets; // number of sets in cache int cacheAssoc; // cache associativity (glyphs per set) Guchar *cacheData; // glyph pixmap cache T3FontCacheTag *cacheTags; // cache tags, i.e., char codes Display *display; Pixmap pixmap; XImage *image;};T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A, double m21A, double m22A, int glyphXA, int glyphYA, int glyphWA, int glyphHA, Display *displayA, Visual *visual, Guint depth, Pixmap origPixmap) { int i; fontID = *fontIDA; m11 = m11A; m12 = m12A; m21 = m21A; m22 = m22A; glyphX = glyphXA; glyphY = glyphYA; glyphW = glyphWA; glyphH = glyphHA; glyphSize = glyphW * glyphH; cacheAssoc = 8; if (glyphSize <= 256) { cacheSets = 8; } else if (glyphSize <= 512) { cacheSets = 4; } else if (glyphSize <= 1024) { cacheSets = 2; } else { cacheSets = 1; } cacheData = (Guchar *)gmalloc(cacheSets * cacheAssoc * glyphSize); cacheTags = (T3FontCacheTag *)gmalloc(cacheSets * cacheAssoc * sizeof(T3FontCacheTag)); for (i = 0; i < cacheSets * cacheAssoc; ++i) { cacheTags[i].mru = i & (cacheAssoc - 1); } display = displayA; pixmap = XCreatePixmap(display, origPixmap, glyphW, glyphH, depth); image = XCreateImage(display, visual, depth, ZPixmap, 0, NULL, glyphW, glyphH, 8, 0); image->data = (char *)gmalloc(glyphH * image->bytes_per_line);}T3FontCache::~T3FontCache() { gfree(cacheData); gfree(cacheTags); XFreePixmap(display, pixmap); gfree(image->data); image->data = NULL; XDestroyImage(image);}struct T3GlyphStack { GBool cacheable; Gushort code; T3FontCache *cache; int cacheIdx; T3FontCacheTag *cacheTag; Guchar *cacheData; double x, y; Unicode *u; int uLen; GfxRGB color; int origPixmapW, origPixmapH; Pixmap origPixmap; GC origStrokeGC; GC origFillGC; Region origClipRegion; double origCTM4, origCTM5; double wx, wy; // untransformed glyph metrics T3GlyphStack *next;};//------------------------------------------------------------------------// XOutputDev//------------------------------------------------------------------------XOutputDev::XOutputDev(Display *displayA, int screenNumA, Visual *visualA, Colormap colormapA, GBool reverseVideoA, unsigned long paperColorA, GBool installCmap, int rgbCubeSize, int forceDepth) { XVisualInfo visualTempl; XVisualInfo *visualList; int nVisuals; Gulong mask; XColor xcolor; XColor *xcolors; int r, g, b, n, m; GBool ok; // no document yet xref = NULL; // display / screen / visual / colormap display = displayA; screenNum = screenNumA; visual = visualA; colormap = colormapA; // no pixmap yet pixmapW = pixmapH = 0; // check for TrueColor visual if (forceDepth != 0) { depth = forceDepth; trueColor = depth >= 16; } else { visualTempl.visualid = XVisualIDFromVisual(visual); visualList = XGetVisualInfo(display, VisualIDMask, &visualTempl, &nVisuals); if (nVisuals < 1) { // this shouldn't happen XFree((XPointer)visualList); visualList = XGetVisualInfo(display, VisualNoMask, &visualTempl, &nVisuals); } depth = visualList->depth; if (visualList->c_class == TrueColor) { trueColor = gTrue; for (mask = visualList->red_mask, rShift = 0; mask && !(mask & 1); mask >>= 1, ++rShift) ; rMul = (int)mask; for (mask = visualList->green_mask, gShift = 0; mask && !(mask & 1); mask >>= 1, ++gShift) ; gMul = (int)mask; for (mask = visualList->blue_mask, bShift = 0; mask && !(mask & 1); mask >>= 1, ++bShift) ; bMul = (int)mask; } else { trueColor = gFalse; } XFree((XPointer)visualList); } // allocate a color cube if (!trueColor) { redMap[BlackPixel(display, screenNum) & 0xff] = 0; redMap[WhitePixel(display, screenNum) & 0xff] = 1; // set colors in private colormap if (installCmap) { for (numColors = 6; numColors >= 2; --numColors) { m = numColors * numColors * numColors; if (XAllocColorCells(display, colormap, False, NULL, 0, colors, m)) { break; } } if (numColors >= 2) { m = numColors * numColors * numColors; xcolors = (XColor *)gmalloc(m * sizeof(XColor)); n = 0; for (r = 0; r < numColors; ++r) { for (g = 0; g < numColors; ++g) { for (b = 0; b < numColors; ++b) { xcolors[n].pixel = colors[n]; xcolors[n].red = (r * 65535) / (numColors - 1); xcolors[n].green = (g * 65535) / (numColors - 1); xcolors[n].blue = (b * 65535) / (numColors - 1); xcolors[n].flags = DoRed | DoGreen | DoBlue; redMap[xcolors[n].pixel & 0xff] = xcolors[n].red / 65535.0; ++n; } } } XStoreColors(display, colormap, xcolors, m); gfree(xcolors); } else { numColors = 1; colors[0] = BlackPixel(display, screenNum); colors[1] = WhitePixel(display, screenNum); } // allocate colors in shared colormap } else { if (rgbCubeSize > maxRGBCube) { rgbCubeSize = maxRGBCube; } ok = gFalse; for (numColors = rgbCubeSize; numColors >= 2; --numColors) { ok = gTrue; n = 0; for (r = 0; r < numColors && ok; ++r) { for (g = 0; g < numColors && ok; ++g) { for (b = 0; b < numColors && ok; ++b) { if (n == 0) { colors[n] = BlackPixel(display, screenNum); redMap[colors[n] & 0xff] = 0; ++n; } else { xcolor.red = (r * 65535) / (numColors - 1); xcolor.green = (g * 65535) / (numColors - 1); xcolor.blue = (b * 65535) / (numColors - 1); if (XAllocColor(display, colormap, &xcolor)) { colors[n++] = xcolor.pixel; redMap[xcolor.pixel & 0xff] = xcolor.red / 65535.0; } else { ok = gFalse; } } } } } if (ok) { break; } XFreeColors(display, colormap, &colors[1], n-1, 0); } if (!ok) { numColors = 1; colors[0] = BlackPixel(display, screenNum); colors[1] = WhitePixel(display, screenNum); } } } // misc parameters reverseVideo = reverseVideoA; paperColor = paperColorA; // set up the font cache and fonts gfxFont = NULL; font = NULL; fontCache = new XOutputFontCache(display, depth, this, globalParams->getT1libControl(), globalParams->getFreeTypeControl()); nT3Fonts = 0; t3GlyphStack = NULL; // empty state stack save = NULL; // create text object text = new TextPage(gFalse);}XOutputDev::~XOutputDev() { int i; delete fontCache; for (i = 0; i < nT3Fonts; ++i) { delete t3FontCache[i]; } delete text;}void XOutputDev::startDoc(XRef *xrefA) { int i; xref = xrefA; fontCache->startDoc(screenNum, visual, colormap, trueColor, rMul, gMul, bMul, rShift, gShift, bShift, colors, numColors); for (i = 0; i < nT3Fonts; ++i) { delete t3FontCache[i]; } nT3Fonts = 0;}void XOutputDev::startPage(int pageNum, GfxState *state) { XGCValues gcValues; XRectangle rect; // default line flatness flatness = 0; // allocate GCs gcValues.foreground = BlackPixel(display, screenNum); gcValues.background = WhitePixel(display, screenNum); gcValues.line_width = 0; gcValues.line_style = LineSolid; strokeGC = XCreateGC(display, pixmap, GCForeground | GCBackground | GCLineWidth | GCLineStyle, &gcValues); fillGC = XCreateGC(display, pixmap, GCForeground | GCBackground | GCLineWidth | GCLineStyle, &gcValues); gcValues.foreground = paperColor; paperGC = XCreateGC(display, pixmap, GCForeground | GCBackground | GCLineWidth | GCLineStyle, &gcValues); // initialize clip region clipRegion = XCreateRegion(); rect.x = rect.y = 0; rect.width = pixmapW; rect.height = pixmapH; XUnionRectWithRegion(&rect, clipRegion, clipRegion); XSetRegion(display, strokeGC, clipRegion); XSetRegion(display, fillGC, clipRegion); // clear font gfxFont = NULL; font = NULL; // clear window XFillRectangle(display, pixmap, paperGC, 0, 0, pixmapW, pixmapH); // clear text object text->startPage(state);}void XOutputDev::endPage() { XOutputState *s; text->coalesce(); // clear state stack, free all GCs, free the clip region while (save) { s = save; save = save->next; XFreeGC(display, s->strokeGC); XFreeGC(display, s->fillGC); XDestroyRegion(s->clipRegion); delete s; } XFreeGC(display, strokeGC); XFreeGC(display, fillGC); XFreeGC(display, paperGC); XDestroyRegion(clipRegion);}void XOutputDev::drawLink(Link *link, Catalog *catalog) { double x1, y1, x2, y2, w; GfxRGB rgb; XPoint points[5]; int x, y; link->getBorder(&x1, &y1, &x2, &y2, &w); if (w > 0) { rgb.r = 0; rgb.g = 0; rgb.b = 1; XSetForeground(display, strokeGC, findColor(&rgb)); XSetLineAttributes(display, strokeGC, xoutRound(w), LineSolid, CapRound, JoinRound); cvtUserToDev(x1, y1, &x, &y); points[0].x = points[4].x = x; points[0].y = points[4].y = y; cvtUserToDev(x2, y1, &x, &y); points[1].x = x; points[1].y = y; cvtUserToDev(x2, y2, &x, &y); points[2].x = x; points[2].y = y; cvtUserToDev(x1, y2, &x, &y); points[3].x = x; points[3].y = y; XDrawLines(display, pixmap, strokeGC, points, 5, CoordModeOrigin); }}void XOutputDev::saveState(GfxState *state) { XOutputState *s; XGCValues values; // save current state s = new XOutputState; s->strokeGC = strokeGC; s->fillGC = fillGC; s->clipRegion = clipRegion; // push onto state stack s->next = save; save = s; // create a new current state by copying strokeGC = XCreateGC(display, pixmap, 0, &values); XCopyGC(display, s->strokeGC, 0xffffffff, strokeGC); fillGC = XCreateGC(display, pixmap, 0, &values); XCopyGC(display, s->fillGC, 0xffffffff, fillGC); clipRegion = XCreateRegion(); XUnionRegion(s->clipRegion, clipRegion, clipRegion); XSetRegion(display, strokeGC, clipRegion); XSetRegion(display, fillGC, clipRegion);}void XOutputDev::restoreState(GfxState *state) { XOutputState *s; if (save) { // kill current state XFreeGC(display, strokeGC); XFreeGC(display, fillGC); XDestroyRegion(clipRegion); // restore state flatness = state->getFlatness(); strokeGC = save->strokeGC; fillGC = save->fillGC; clipRegion = save->clipRegion; XSetRegion(display, strokeGC, clipRegion); XSetRegion(display, fillGC, clipRegion); // pop state stack s = save; save = save->next; delete s; // restore the font updateFont(state); }}void XOutputDev::updateAll(GfxState *state) { updateLineAttrs(state, gTrue); updateFlatness(state); updateMiterLimit(state); updateFillColor(state);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -