gfx.cc
来自「source code: Covert TXT to PDF」· CC 代码 · 共 2,586 行 · 第 1/5 页
CC
2,586 行
//========================================================================//// Gfx.cc//// Copyright 1996-2002 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdio.h>#include <stddef.h>#include <string.h>#include <math.h>#include "gmem.h"#include "GlobalParams.h"#include "CharTypes.h"#include "Object.h"#include "Array.h"#include "Dict.h"#include "Stream.h"#include "Lexer.h"#include "Parser.h"#include "GfxFont.h"#include "GfxState.h"#include "OutputDev.h"#include "Page.h"#include "Error.h"#include "Gfx.h"// the MSVC math.h doesn't define this#ifndef M_PI#define M_PI 3.14159265358979323846#endif//------------------------------------------------------------------------// constants//------------------------------------------------------------------------// Max number of splits along the t axis for an axial shading fill.#define axialMaxSplits 256// Max delta allowed in any color component for an axial shading fill.#define axialColorDelta (1 / 256.0)// Max number of splits along the t axis for a radial shading fill.#define radialMaxSplits 256// Max delta allowed in any color component for a radial shading fill.#define radialColorDelta (1 / 256.0)//------------------------------------------------------------------------// Operator table//------------------------------------------------------------------------Operator Gfx::opTab[] = { {"\"", 3, {tchkNum, tchkNum, tchkString}, &Gfx::opMoveSetShowText}, {"'", 1, {tchkString}, &Gfx::opMoveShowText}, {"B", 0, {tchkNone}, &Gfx::opFillStroke}, {"B*", 0, {tchkNone}, &Gfx::opEOFillStroke}, {"BDC", 2, {tchkName, tchkProps}, &Gfx::opBeginMarkedContent}, {"BI", 0, {tchkNone}, &Gfx::opBeginImage}, {"BMC", 1, {tchkName}, &Gfx::opBeginMarkedContent}, {"BT", 0, {tchkNone}, &Gfx::opBeginText}, {"BX", 0, {tchkNone}, &Gfx::opBeginIgnoreUndef}, {"CS", 1, {tchkName}, &Gfx::opSetStrokeColorSpace}, {"DP", 2, {tchkName, tchkProps}, &Gfx::opMarkPoint}, {"Do", 1, {tchkName}, &Gfx::opXObject}, {"EI", 0, {tchkNone}, &Gfx::opEndImage}, {"EMC", 0, {tchkNone}, &Gfx::opEndMarkedContent}, {"ET", 0, {tchkNone}, &Gfx::opEndText}, {"EX", 0, {tchkNone}, &Gfx::opEndIgnoreUndef}, {"F", 0, {tchkNone}, &Gfx::opFill}, {"G", 1, {tchkNum}, &Gfx::opSetStrokeGray}, {"ID", 0, {tchkNone}, &Gfx::opImageData}, {"J", 1, {tchkInt}, &Gfx::opSetLineCap}, {"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opSetStrokeCMYKColor}, {"M", 1, {tchkNum}, &Gfx::opSetMiterLimit}, {"MP", 1, {tchkName}, &Gfx::opMarkPoint}, {"Q", 0, {tchkNone}, &Gfx::opRestore}, {"RG", 3, {tchkNum, tchkNum, tchkNum}, &Gfx::opSetStrokeRGBColor}, {"S", 0, {tchkNone}, &Gfx::opStroke}, {"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opSetStrokeColor}, {"SCN", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, tchkSCN}, &Gfx::opSetStrokeColorN}, {"T*", 0, {tchkNone}, &Gfx::opTextNextLine}, {"TD", 2, {tchkNum, tchkNum}, &Gfx::opTextMoveSet}, {"TJ", 1, {tchkArray}, &Gfx::opShowSpaceText}, {"TL", 1, {tchkNum}, &Gfx::opSetTextLeading}, {"Tc", 1, {tchkNum}, &Gfx::opSetCharSpacing}, {"Td", 2, {tchkNum, tchkNum}, &Gfx::opTextMove}, {"Tf", 2, {tchkName, tchkNum}, &Gfx::opSetFont}, {"Tj", 1, {tchkString}, &Gfx::opShowText}, {"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opSetTextMatrix}, {"Tr", 1, {tchkInt}, &Gfx::opSetTextRender}, {"Ts", 1, {tchkNum}, &Gfx::opSetTextRise}, {"Tw", 1, {tchkNum}, &Gfx::opSetWordSpacing}, {"Tz", 1, {tchkNum}, &Gfx::opSetHorizScaling}, {"W", 0, {tchkNone}, &Gfx::opClip}, {"W*", 0, {tchkNone}, &Gfx::opEOClip}, {"b", 0, {tchkNone}, &Gfx::opCloseFillStroke}, {"b*", 0, {tchkNone}, &Gfx::opCloseEOFillStroke}, {"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opCurveTo}, {"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opConcat}, {"cs", 1, {tchkName}, &Gfx::opSetFillColorSpace}, {"d", 2, {tchkArray, tchkNum}, &Gfx::opSetDash}, {"d0", 2, {tchkNum, tchkNum}, &Gfx::opSetCharWidth}, {"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opSetCacheDevice}, {"f", 0, {tchkNone}, &Gfx::opFill}, {"f*", 0, {tchkNone}, &Gfx::opEOFill}, {"g", 1, {tchkNum}, &Gfx::opSetFillGray}, {"gs", 1, {tchkName}, &Gfx::opSetExtGState}, {"h", 0, {tchkNone}, &Gfx::opClosePath}, {"i", 1, {tchkNum}, &Gfx::opSetFlat}, {"j", 1, {tchkInt}, &Gfx::opSetLineJoin}, {"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opSetFillCMYKColor}, {"l", 2, {tchkNum, tchkNum}, &Gfx::opLineTo}, {"m", 2, {tchkNum, tchkNum}, &Gfx::opMoveTo}, {"n", 0, {tchkNone}, &Gfx::opEndPath}, {"q", 0, {tchkNone}, &Gfx::opSave}, {"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opRectangle}, {"rg", 3, {tchkNum, tchkNum, tchkNum}, &Gfx::opSetFillRGBColor}, {"ri", 1, {tchkName}, &Gfx::opSetRenderingIntent}, {"s", 0, {tchkNone}, &Gfx::opCloseStroke}, {"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opSetFillColor}, {"scn", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, tchkSCN}, &Gfx::opSetFillColorN}, {"sh", 1, {tchkName}, &Gfx::opShFill}, {"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opCurveTo1}, {"w", 1, {tchkNum}, &Gfx::opSetLineWidth}, {"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, &Gfx::opCurveTo2},};#define numOps (sizeof(opTab) / sizeof(Operator))//------------------------------------------------------------------------// GfxResources//------------------------------------------------------------------------GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) { Object obj1; if (resDict) { // build font dictionary fonts = NULL; resDict->lookup("Font", &obj1); if (obj1.isDict()) { fonts = new GfxFontDict(xref, obj1.getDict()); } obj1.free(); // get XObject dictionary resDict->lookup("XObject", &xObjDict); // get color space dictionary resDict->lookup("ColorSpace", &colorSpaceDict); // get pattern dictionary resDict->lookup("Pattern", &patternDict); // get shading dictionary resDict->lookup("Shading", &shadingDict); // get graphics state parameter dictionary resDict->lookup("ExtGState", &gStateDict); } else { fonts = NULL; xObjDict.initNull(); colorSpaceDict.initNull(); patternDict.initNull(); gStateDict.initNull(); } next = nextA;}GfxResources::~GfxResources() { if (fonts) { delete fonts; } xObjDict.free(); colorSpaceDict.free(); patternDict.free(); shadingDict.free(); gStateDict.free();}GfxFont *GfxResources::lookupFont(char *name) { GfxFont *font; GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->fonts) { if ((font = resPtr->fonts->lookup(name))) return font; } } error(-1, "Unknown font tag '%s'", name); return NULL;}GBool GfxResources::lookupXObject(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->xObjDict.isDict()) { if (!resPtr->xObjDict.dictLookup(name, obj)->isNull()) return gTrue; obj->free(); } } error(-1, "XObject '%s' is unknown", name); return gFalse;}GBool GfxResources::lookupXObjectNF(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->xObjDict.isDict()) { if (!resPtr->xObjDict.dictLookupNF(name, obj)->isNull()) return gTrue; obj->free(); } } error(-1, "XObject '%s' is unknown", name); return gFalse;}void GfxResources::lookupColorSpace(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->colorSpaceDict.isDict()) { if (!resPtr->colorSpaceDict.dictLookup(name, obj)->isNull()) { return; } obj->free(); } } obj->initNull();}GfxPattern *GfxResources::lookupPattern(char *name) { GfxResources *resPtr; GfxPattern *pattern; Object obj; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->patternDict.isDict()) { if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) { pattern = GfxPattern::parse(&obj); obj.free(); return pattern; } obj.free(); } } error(-1, "Unknown pattern '%s'", name); return NULL;}GfxShading *GfxResources::lookupShading(char *name) { GfxResources *resPtr; GfxShading *shading; Object obj; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->shadingDict.isDict()) { if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) { shading = GfxShading::parse(&obj); obj.free(); return shading; } obj.free(); } } error(-1, "Unknown shading '%s'", name); return NULL;}GBool GfxResources::lookupGState(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->gStateDict.isDict()) { if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) { return gTrue; } obj->free(); } } error(-1, "ExtGState '%s' is unknown", name); return gFalse;}//------------------------------------------------------------------------// Gfx//------------------------------------------------------------------------Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double dpi, PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, GBool (*abortCheckCbkA)(void *data), void *abortCheckCbkDataA) { int i; xref = xrefA; subPage = gFalse; printCommands = globalParams->getPrintCommands(); // start the resource stack res = new GfxResources(xref, resDict, NULL); // initialize out = outA; state = new GfxState(dpi, box, rotate, out->upsideDown()); fontChanged = gFalse; clip = clipNone; ignoreUndef = 0; out->startPage(pageNum, state); out->setDefaultCTM(state->getCTM()); out->updateAll(state); for (i = 0; i < 6; ++i) { baseMatrix[i] = state->getCTM()[i]; } abortCheckCbk = abortCheckCbkA; abortCheckCbkData = abortCheckCbkDataA; // set crop box if (crop) { state->moveTo(cropBox->x1, cropBox->y1); state->lineTo(cropBox->x2, cropBox->y1); state->lineTo(cropBox->x2, cropBox->y2); state->lineTo(cropBox->x1, cropBox->y2); state->closePath(); state->clip(); out->clip(state); state->clearPath(); }}Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, PDFRectangle *box, GBool crop, PDFRectangle *cropBox, GBool (*abortCheckCbkA)(void *data), void *abortCheckCbkDataA) { int i; xref = xrefA; subPage = gTrue; printCommands = globalParams->getPrintCommands(); // start the resource stack res = new GfxResources(xref, resDict, NULL); // initialize out = outA; state = new GfxState(72, box, 0, gFalse); fontChanged = gFalse; clip = clipNone; ignoreUndef = 0; for (i = 0; i < 6; ++i) { baseMatrix[i] = state->getCTM()[i]; } abortCheckCbk = abortCheckCbkA; abortCheckCbkData = abortCheckCbkDataA; // set crop box if (crop) { state->moveTo(cropBox->x1, cropBox->y1); state->lineTo(cropBox->x2, cropBox->y1); state->lineTo(cropBox->x2, cropBox->y2); state->lineTo(cropBox->x1, cropBox->y2); state->closePath(); state->clip(); out->clip(state); state->clearPath(); }}Gfx::~Gfx() { while (state->hasSaves()) { state = state->restore(); out->restoreState(state); } if (!subPage) { out->endPage(); } while (res) { popResources(); } if (state) { delete state; }}void Gfx::display(Object *obj, GBool topLevel) { Object obj2; int i; if (obj->isArray()) { for (i = 0; i < obj->arrayGetLength(); ++i) { obj->arrayGet(i, &obj2); if (!obj2.isStream()) { error(-1, "Weird page contents"); obj2.free(); return; } obj2.free(); } } else if (!obj->isStream()) { error(-1, "Weird page contents"); return; } parser = new Parser(xref, new Lexer(xref, obj)); go(topLevel); delete parser; parser = NULL;}void Gfx::go(GBool topLevel) { Object obj; Object args[maxArgs]; int numArgs, i; int lastAbortCheck; // scan a sequence of objects updateLevel = lastAbortCheck = 0; numArgs = 0; parser->getObj(&obj); while (!obj.isEOF()) { // got a command - execute it if (obj.isCmd()) { if (printCommands) { obj.print(stdout);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?