📄 gfx.cc
字号:
formDepth = 0; abortCheckCbk = abortCheckCbkA; abortCheckCbkData = abortCheckCbkDataA; // set crop box if (cropBox) { 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()) { restoreState(); } 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); for (i = 0; i < numArgs; ++i) { printf(" "); args[i].print(stdout); } printf("\n"); fflush(stdout); } execOp(&obj, args, numArgs); obj.free(); for (i = 0; i < numArgs; ++i) args[i].free(); numArgs = 0; // periodically update display if (++updateLevel >= 20000) { out->dump(); updateLevel = 0; } // check for an abort if (abortCheckCbk) { if (updateLevel - lastAbortCheck > 10) { if ((*abortCheckCbk)(abortCheckCbkData)) { break; } lastAbortCheck = updateLevel; } } // got an argument - save it } else if (numArgs < maxArgs) { args[numArgs++] = obj; // too many arguments - something is wrong } else { error(getPos(), "Too many args in content stream"); if (printCommands) { printf("throwing away arg: "); obj.print(stdout); printf("\n"); fflush(stdout); } obj.free(); } // grab the next object parser->getObj(&obj); } obj.free(); // args at end with no command if (numArgs > 0) { error(getPos(), "Leftover args in content stream"); if (printCommands) { printf("%d leftovers:", numArgs); for (i = 0; i < numArgs; ++i) { printf(" "); args[i].print(stdout); } printf("\n"); fflush(stdout); } for (i = 0; i < numArgs; ++i) args[i].free(); } // update display if (topLevel && updateLevel > 0) { out->dump(); }}void Gfx::execOp(Object *cmd, Object args[], int numArgs) { Operator *op; char *name; Object *argPtr; int i; // find operator name = cmd->getCmd(); if (!(op = findOp(name))) { if (ignoreUndef == 0) error(getPos(), "Unknown operator '%s'", name); return; } // type check args argPtr = args; if (op->numArgs >= 0) { if (numArgs < op->numArgs) { error(getPos(), "Too few (%d) args to '%s' operator", numArgs, name); return; } if (numArgs > op->numArgs) {#if 0 error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name);#endif argPtr += numArgs - op->numArgs; numArgs = op->numArgs; } } else { if (numArgs > -op->numArgs) { error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name); return; } } for (i = 0; i < numArgs; ++i) { if (!checkArg(&argPtr[i], op->tchk[i])) { error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)", i, name, argPtr[i].getTypeName()); return; } } // do it (this->*op->func)(argPtr, numArgs);}Operator *Gfx::findOp(char *name) { int a, b, m, cmp; a = -1; b = numOps; // invariant: opTab[a] < name < opTab[b] while (b - a > 1) { m = (a + b) / 2; cmp = strcmp(opTab[m].name, name); if (cmp < 0) a = m; else if (cmp > 0) b = m; else a = b = m; } if (cmp != 0) return NULL; return &opTab[a];}GBool Gfx::checkArg(Object *arg, TchkType type) { switch (type) { case tchkBool: return arg->isBool(); case tchkInt: return arg->isInt(); case tchkNum: return arg->isNum(); case tchkString: return arg->isString(); case tchkName: return arg->isName(); case tchkArray: return arg->isArray(); case tchkProps: return arg->isDict() || arg->isName(); case tchkSCN: return arg->isNum() || arg->isName(); case tchkNone: return gFalse; } return gFalse;}int Gfx::getPos() { return parser ? parser->getPos() : -1;}//------------------------------------------------------------------------// graphics state operators//------------------------------------------------------------------------void Gfx::opSave(Object args[], int numArgs) { saveState();}void Gfx::opRestore(Object args[], int numArgs) { restoreState();}void Gfx::opConcat(Object args[], int numArgs) { state->concatCTM(args[0].getNum(), args[1].getNum(), args[2].getNum(), args[3].getNum(), args[4].getNum(), args[5].getNum()); out->updateCTM(state, args[0].getNum(), args[1].getNum(), args[2].getNum(), args[3].getNum(), args[4].getNum(), args[5].getNum()); fontChanged = gTrue;}void Gfx::opSetDash(Object args[], int numArgs) { Array *a; int length; Object obj; double *dash; int i; a = args[0].getArray(); length = a->getLength(); if (length == 0) { dash = NULL; } else { dash = (double *)gmallocn(length, sizeof(double)); for (i = 0; i < length; ++i) { dash[i] = a->get(i, &obj)->getNum(); obj.free(); } } state->setLineDash(dash, length, args[1].getNum()); out->updateLineDash(state);}void Gfx::opSetFlat(Object args[], int numArgs) { state->setFlatness((int)args[0].getNum()); out->updateFlatness(state);}void Gfx::opSetLineJoin(Object args[], int numArgs) { state->setLineJoin(args[0].getInt()); out->updateLineJoin(state);}void Gfx::opSetLineCap(Object args[], int numArgs) { state->setLineCap(args[0].getInt()); out->updateLineCap(state);}void Gfx::opSetMiterLimit(Object args[], int numArgs) { state->setMiterLimit(args[0].getNum()); out->updateMiterLimit(state);}void Gfx::opSetLineWidth(Object args[], int numArgs) { state->setLineWidth(args[0].getNum()); out->updateLineWidth(state);}void Gfx::opSetExtGState(Object args[], int numArgs) { Object obj1, obj2; GfxBlendMode mode; GBool haveFillOP; if (!res->lookupGState(args[0].getName(), &obj1)) { return; } if (!obj1.isDict()) { error(getPos(), "ExtGState '%s' is wrong type", args[0].getName()); obj1.free(); return; } // transparency support: blend mode, fill/stroke opacity if (!obj1.dictLookup("BM", &obj2)->isNull()) { if (state->parseBlendMode(&obj2, &mode)) { state->setBlendMode(mode); out->updateBlendMode(state); } else { error(getPos(), "Invalid blend mode in ExtGState"); } } obj2.free(); if (obj1.dictLookup("ca", &obj2)->isNum()) { state->setFillOpacity(obj2.getNum()); out->updateFillOpacity(state); } obj2.free(); if (obj1.dictLookup("CA", &obj2)->isNum()) { state->setStrokeOpacity(obj2.getNum()); out->updateStrokeOpacity(state); } obj2.free(); // fill/stroke overprint if ((haveFillOP = (obj1.dictLookup("op", &obj2)->isBool()))) { state->setFillOverprint(obj2.getBool()); out->updateFillOverprint(state); } obj2.free(); if (obj1.dictLookup("OP", &obj2)->isBool()) { state->setStrokeOverprint(obj2.getBool()); out->updateStrokeOverprint(state); if (!haveFillOP) { state->setFillOverprint(obj2.getBool()); out->updateFillOverprint(state); } } obj2.free(); obj1.free();}void Gfx::opSetRenderingIntent(Object args[], int numArgs) {}//------------------------------------------------------------------------// color operators//------------------------------------------------------------------------void Gfx::opSetFillGray(Object args[], int numArgs) { GfxColor color; state->setFillPattern(NULL); state->setFillColorSpace(new GfxDeviceGrayColorSpace()); out->updateFillColorSpace(state); color.c[0] = dblToCol(args[0].getNum()); state->setFillColor(&color); out->updateFillColor(state);}void Gfx::opSetStrokeGray(Object args[], int numArgs) { GfxColor color; state->setStrokePattern(NULL); state->setStrokeColorSpace(new GfxDeviceGrayColorSpace()); out->updateStrokeColorSpace(state); color.c[0] = dblToCol(args[0].getNum()); state->setStrokeColor(&color); out->updateStrokeColor(state);}void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { GfxColor color; int i; state->setFillPattern(NULL); state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); out->updateFillColorSpace(state); for (i = 0; i < 4; ++i) { color.c[i] = dblToCol(args[i].getNum()); } state->setFillColor(&color); out->updateFillColor(state);}void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) { GfxColor color; int i; state->setStrokePattern(NULL); state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace()); out->updateStrokeColorSpace(state); for (i = 0; i < 4; ++i) { color.c[i] = dblToCol(args[i].getNum()); } state->setStrokeColor(&color); out->updateStrokeColor(state);}void Gfx::opSetFillRGBColor(Object args[], int numArgs) { GfxColor color; int i; state->setFillPattern(NULL); state->setFillColorSpace(new GfxDeviceRGBColorSpace()); out->updateFillColorSpace(state); for (i = 0; i < 3; ++i) { color.c[i] = dblToCol(args[i].getNum()); } state->setFillColor(&color); out->updateFillColor(state);}void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) { GfxColor color; int i; state->setStrokePattern(NULL); state->setStrokeColorSpace(new GfxDeviceRGBColorSpace()); out->updateStrokeColorSpace(state); for (i = 0; i < 3; ++i) { color.c[i] = dblToCol(args[i].getNum()); } state->setStrokeColor(&color); out->updateStrokeColor(state);}void Gfx::opSetFillColorSpace(Object args[], int numArgs) { Object obj; GfxColorSpace *colorSpace; GfxColor color; int i; state->setFillPattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0]); } else { colorSpace = GfxColorSpace::parse(&obj); } obj.free(); if (colorSpace) { state->setFillColorSpace(colorSpace); out->updateFillColorSpace(state); } else { error(getPos(), "Bad color space (fill)"); } for (i = 0; i < gfxColorMaxComps; ++i) { color.c[i] = 0; } state->setFillColor(&color); out->updateFillColor(state);}void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) { Object obj; GfxColorSpace *colorSpace; GfxColor color; int i; state->setStrokePattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0]); } else { colorSpace = GfxColorSpace::parse(&obj); } obj.free(); if (colorSpace) { state->setStrokeColorSpace(colorSpace); out->updateStrokeColorSpace(state); } else { error(getPos(), "Bad color space (stroke)"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -