pdf-parser.cpp revision 35636e0c762d50c37515a072b12bdc0197afd24c
842ae4bd224140319ae7feec1872b93dfd491143fielding * PDF parsing using libpoppler.
842ae4bd224140319ae7feec1872b93dfd491143fielding * Derived from poppler's Gfx.cc
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Jon A. Cruz <jon@joncruz.org>
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Copyright 2012 authors
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Copyright 1996-2003 Glyph & Cog, LLC
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingextern "C" {
29c30db45f6a469017e16b606611e460cc1a1f2caaron// the MSVC math.h doesn't define this
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding//------------------------------------------------------------------------
e33b627b40578d0166fdb79ce0487f9e46586befgstein// constants
e33b627b40578d0166fdb79ce0487f9e46586befgstein//------------------------------------------------------------------------
e33b627b40578d0166fdb79ce0487f9e46586befgstein// Default max delta allowed in any color component for a shading fill.
e33b627b40578d0166fdb79ce0487f9e46586befgstein#define defaultShadingColorDelta (dblToCol( 1 / 2.0 ))
e33b627b40578d0166fdb79ce0487f9e46586befgstein// Default max recursive depth for a shading fill.
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick// Max number of operators kept in the history list.
e9f8410b788ef1e6f1baed6c706ffdf3da395a16jerenkrantz//------------------------------------------------------------------------
e33b627b40578d0166fdb79ce0487f9e46586befgstein// Operator table
322b350d0f1ac750b112ec15481a33efc92d182cjerenkrantz//------------------------------------------------------------------------
97d20d37d21b8d427a920e211858172f0a82427epoirier#ifdef WIN32 // this works around a bug in the VC7 compiler
97d20d37d21b8d427a920e211858172f0a82427epoirier#ifdef WIN32 // this works around a bug in the VC7 compiler
97d20d37d21b8d427a920e211858172f0a82427epoirier//------------------------------------------------------------------------
97d20d37d21b8d427a920e211858172f0a82427epoirier// PdfParser
97d20d37d21b8d427a920e211858172f0a82427epoirier//------------------------------------------------------------------------
97d20d37d21b8d427a920e211858172f0a82427epoirierPdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
dc80439e9fba60c753cd145cb6799409ffea9b71ronald // start the resource stack
97d20d37d21b8d427a920e211858172f0a82427epoirier // initialize
dc80439e9fba60c753cd145cb6799409ffea9b71ronald state = new GfxState(72.0, 72.0, box, rotate, gTrue);
dc80439e9fba60c753cd145cb6799409ffea9b71ronald builder->setDocumentSize(Inkscape::Util::Quantity::convert(state->getPageWidth(), "pt", "px"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding Inkscape::Util::Quantity::convert(state->getPageHeight(), "pt", "px"));
dc80439e9fba60c753cd145cb6799409ffea9b71ronald for (int i = 0; i < 6; ++i) {
97d20d37d21b8d427a920e211858172f0a82427epoirier scaledCTM[i] = Inkscape::Util::Quantity::convert(ctm[i], "pt", "px");
97d20d37d21b8d427a920e211858172f0a82427epoirier // set crop box
97d20d37d21b8d427a920e211858172f0a82427epoirier printf("cropBox: %f %f %f %f\n", cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // do not clip if it's not needed
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding cropBox->x2 != state->getPageWidth() || cropBox->y2 != state->getPageHeight()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding clipHistory->setClip(state->getPath(), clipNormal);
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingPdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick // start the resource stack
8ea968d7e798635ab742673e5d5eef35798259c9sf // initialize
8ea968d7e798635ab742673e5d5eef35798259c9sf for (i = 0; i < 6; ++i) {
8ea968d7e798635ab742673e5d5eef35798259c9sf //out->endPage();
dc80439e9fba60c753cd145cb6799409ffea9b71ronald parser = new Parser(xref, new Lexer(xref, obj), gFalse);
97d20d37d21b8d427a920e211858172f0a82427epoirier // scan a sequence of objects
97d20d37d21b8d427a920e211858172f0a82427epoirier // got a command - execute it
29c30db45f6a469017e16b606611e460cc1a1f2caaron for (int i = 0; i < numArgs; ++i) {
29c30db45f6a469017e16b606611e460cc1a1f2caaron // Run the operation
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < numArgs; ++i)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // got an argument - save it
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // too many arguments - something is wrong
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Too many args in content stream");
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm error(getPos(), const_cast<char*>("Too many args in content stream"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // grab the next object
c7de1955eb0eaeabf7042902476397692672d549sf // args at end with no command
c7de1955eb0eaeabf7042902476397692672d549sf error(errSyntaxError, getPos(), "Leftover args in content stream");
c7de1955eb0eaeabf7042902476397692672d549sf error(getPos(), const_cast<char*>("Leftover args in content stream"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < numArgs; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < numArgs; ++i)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding newEntry->depth = (operatorHistory != NULL ? (operatorHistory->depth+1) : 0);
322b350d0f1ac750b112ec15481a33efc92d182cjerenkrantz // Truncate list if needed
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (operatorHistory->depth > maxOperatorHistoryDepth) {
bdfba727693ab86e9914ca90af68e62896946755jerenkrantzconst char *PdfParser::getPreviousOperator(unsigned int look_back) {
bdfba727693ab86e9914ca90af68e62896946755jerenkrantzvoid PdfParser::execOp(Object *cmd, Object args[], int numArgs) {
322b350d0f1ac750b112ec15481a33efc92d182cjerenkrantz // find operator
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Unknown operator '{0:s}'", name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Unknown operator '%s'"), name);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // type check args
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Too few ({0:d}) args to '{1:d}' operator", numArgs, name);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Too few (%d) args to '%s' operator"), numArgs, name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Too many ({0:d}) args to '{1:s}' operator", numArgs, name);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Too many ({0:d}) args to '{1:s}' operator",
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Too many (%d) args to '%s' operator"),
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron for (i = 0; i < numArgs; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Arg #{0:d} to '{1:s}' operator is wrong type ({2:s})",
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Arg #%d to '%s' operator is wrong type (%s)"),
ac2eb54bac2d978c323ab346161b8591d134100cpoirier // add to history
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int a = -1;
f7376afc33a9e035921be9114c0e246820d7c8besf // invariant: opTab[a] < name < opTab[b]
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron while (b - a > 1) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron const int m = (a + b) / 2;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (cmp > 0)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronGBool PdfParser::checkArg(Object *arg, TchkType type) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron case tchkProps: return arg->isDict() || arg->isName();
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron//------------------------------------------------------------------------
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// graphics state operators
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron//------------------------------------------------------------------------
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opSave(Object /*args*/[], int /*numArgs*/)
dc80439e9fba60c753cd145cb6799409ffea9b71ronaldvoid PdfParser::opRestore(Object /*args*/[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// TODO not good that numArgs is ignored but args[] is used:
dc80439e9fba60c753cd145cb6799409ffea9b71ronaldvoid PdfParser::opConcat(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding } else if (!strcmp(prevOp, "cm") || !strcmp(prevOp, "startPage")) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // multiply it with the previous transform
090a954a1fe65b29a6f4a696f0136ef12ea0f1b1rbb if (!builder->getTransform(otherMatrix)) { // invalid transform
1df208eeb79b689410598b0f6fd1ac3fb2401c44nd // construct identity matrix
e8f95a682820a599fe41b22977010636be5c2717jim otherMatrix[1] = otherMatrix[2] = otherMatrix[4] = otherMatrix[5] = 0.0;
e8f95a682820a599fe41b22977010636be5c2717jim double c4 = a4*otherMatrix[0] + a5*otherMatrix[2] + otherMatrix[4];
090a954a1fe65b29a6f4a696f0136ef12ea0f1b1rbb double c5 = a4*otherMatrix[1] + a5*otherMatrix[3] + otherMatrix[5];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetDash(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding double *dash = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < length; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding state->setLineDash(dash, length, args[1].getNum());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetFlat(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetLineJoin(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetLineCap(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetMiterLimit(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
b29f87f4b6c6886a04dccc296177a7033f70dfedtrawickvoid PdfParser::opSetLineWidth(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetExtGState(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!res->lookupGState(args[0].getName(), &obj1)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "ExtGState '{0:s}' is wrong type"), args[0].getName();
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("ExtGState '%s' is wrong type"), args[0].getName());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // transparency support: blend mode, fill/stroke opacity
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (!obj1.dictLookup(const_cast<char*>("BM"), &obj2)->isNull()) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Invalid blend mode in ExtGState");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Invalid blend mode in ExtGState"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj1.dictLookup(const_cast<char*>("ca"), &obj2)->isNum()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj1.dictLookup(const_cast<char*>("CA"), &obj2)->isNum()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // fill/stroke overprint
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if ((haveFillOP = (obj1.dictLookup(const_cast<char*>("op"), &obj2)->isBool()))) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (obj1.dictLookup(const_cast<char*>("OP"), &obj2)->isBool()) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // stroke adjust
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (obj1.dictLookup(const_cast<char*>("SA"), &obj2)->isBool()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // transfer function
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj1.dictLookup(const_cast<char*>("TR2"), &obj2)->isNull()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding } else if (obj2.isArray() && obj2.arrayGetLength() == 4) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < 4; ++i) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron } else if (obj2.isName() || obj2.isDict() || obj2.isStream()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Invalid transfer function in ExtGState");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Invalid transfer function in ExtGState"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // soft mask
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (!obj1.dictLookup(const_cast<char*>("SMask"), &obj2)->isNull()) {
185aa71728867671e105178b4c66fbc22b65ae26sf if (obj2.dictLookup(const_cast<char*>("S"), &obj3)->isName(const_cast<char*>("Alpha"))) {
97d20d37d21b8d427a920e211858172f0a82427epoirier } else { // "Luminosity"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!obj2.dictLookup(const_cast<char*>("TR"), &obj3)->isNull()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Invalid transfer function in soft mask in ExtGState");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Invalid transfer function in soft mask in ExtGState"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if ((haveBackdropColor = obj2.dictLookup(const_cast<char*>("BC"), &obj3)->isArray())) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < gfxColorMaxComps; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < obj3.arrayGetLength() && i < gfxColorMaxComps; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj2.dictLookup(const_cast<char*>("G"), &obj3)->isStream()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj3.streamGetDict()->lookup(const_cast<char*>("Group"), &obj4)->isDict()) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (!obj4.dictLookup(const_cast<char*>("CS"), &obj5)->isNull()) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding blendingColorSpace = GfxColorSpace::parse(&obj5, NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj4.dictLookup(const_cast<char*>("I"), &obj5)->isBool()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (obj4.dictLookup(const_cast<char*>("K"), &obj5)->isBool()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding blendingColorSpace->getDefaultColor(&backdropColor);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //~ need to get the parent or default color space (?)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron for (int i = 0; i < gfxColorMaxComps; ++i) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Invalid soft mask in ExtGState - missing group"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Invalid soft mask in ExtGState - missing group"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Invalid soft mask in ExtGState"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // check for excessive recursion
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // get stream dict
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // check form type
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Unknown form type"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // get bounding box
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Bad form bounding box");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Bad form bounding box"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < 4; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // get matrix
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < 6; ++i) {
d0a225bdac006f3361e80bfc1be7e6f9b0e81f80ronald // get resources
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding dict->lookup(const_cast<char*>("Resources"), &obj1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding resDict = obj1.isDict() ? obj1.getDict() : (Dict *)NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetRenderingIntent(Object /*args*/[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding//------------------------------------------------------------------------
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// color operators
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding//------------------------------------------------------------------------
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetFillGray(Object args[], int /*numArgs*/)
dc80439e9fba60c753cd145cb6799409ffea9b71ronald state->setFillColorSpace(new GfxDeviceGrayColorSpace());
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe// TODO not good that numArgs is ignored but args[] is used:
b980ad7fdc218b4855cde9f75a747527f50c554dwrowevoid PdfParser::opSetStrokeGray(Object args[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// TODO not good that numArgs is ignored but args[] is used:
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opSetFillCMYKColor(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < 4; ++i) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetStrokeCMYKColor(Object args[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace());
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron for (int i = 0; i < 4; ++i) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// TODO not good that numArgs is ignored but args[] is used:
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opSetFillRGBColor(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding state->setFillColorSpace(new GfxDeviceRGBColorSpace());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (int i = 0; i < 3; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
f7376afc33a9e035921be9114c0e246820d7c8besf for (int i = 0; i < 3; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
97d20d37d21b8d427a920e211858172f0a82427epoiriervoid PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Bad color space (fill)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Bad color space (fill)"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// TODO not good that numArgs is ignored but args[] is used:
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Bad color space (stroke)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Bad color space (stroke)"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetFillColor(Object args[], int numArgs) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (numArgs != state->getFillColorSpace()->getNComps()) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "Incorrect number of arguments in 'sc' command");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Incorrect number of arguments in 'sc' command"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron for (i = 0; i < numArgs; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opSetStrokeColor(Object args[], int numArgs) {
7af19efc4667363f74d332a8d010b49e88d56fd5trawick if (numArgs != state->getStrokeColorSpace()->getNComps()) {
820be4f3a1a5b0565a072b0bf582d19fb791b68dnd error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SC' command");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Incorrect number of arguments in 'SC' command"));
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm for (i = 0; i < numArgs; ++i) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opSetFillColorN(Object args[], int numArgs) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (state->getFillColorSpace()->getMode() == csPattern) {
a44d29a3794110c558c940bd903a1930d717a7d7sf if (!((GfxPatternColorSpace *)state->getFillColorSpace())->getUnder() ||
a44d29a3794110c558c940bd903a1930d717a7d7sf numArgs - 1 != ((GfxPatternColorSpace *)state->getFillColorSpace())
a44d29a3794110c558c940bd903a1930d717a7d7sf error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command");
a44d29a3794110c558c940bd903a1930d717a7d7sf error(getPos(), const_cast<char*>("Incorrect number of arguments in 'scn' command"));
a44d29a3794110c558c940bd903a1930d717a7d7sf for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
a44d29a3794110c558c940bd903a1930d717a7d7sf#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
a44d29a3794110c558c940bd903a1930d717a7d7sf (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) {
a44d29a3794110c558c940bd903a1930d717a7d7sf (pattern = res->lookupPattern(args[numArgs-1].getName()))) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (numArgs != state->getFillColorSpace()->getNComps()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command");
f78505c7d260473bf11002f5028186f27d0ed8a0geoff error(getPos(), const_cast<char*>("Incorrect number of arguments in 'scn' command"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < numArgs && i < gfxColorMaxComps; ++i) {
2e242dca7111f99d54dd144b7b8418d88d560032chrisdvoid PdfParser::opSetStrokeColorN(Object args[], int numArgs) {
185aa71728867671e105178b4c66fbc22b65ae26sf if (state->getStrokeColorSpace()->getMode() == csPattern) {
6e45872b4a23d493887830d82a2759b4c00b10b2wsanchez if (!((GfxPatternColorSpace *)state->getStrokeColorSpace())
6e45872b4a23d493887830d82a2759b4c00b10b2wsanchez numArgs - 1 != ((GfxPatternColorSpace *)state->getStrokeColorSpace())
bdfba727693ab86e9914ca90af68e62896946755jerenkrantz error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
33b444dee16ba708960701c5b1ceb69df1548017pquerna error(getPos(), const_cast<char*>("Incorrect number of arguments in 'SCN' command"));
bdfba727693ab86e9914ca90af68e62896946755jerenkrantz for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
bdfba727693ab86e9914ca90af68e62896946755jerenkrantz#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
bdfba727693ab86e9914ca90af68e62896946755jerenkrantz (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) {
bdfba727693ab86e9914ca90af68e62896946755jerenkrantz (pattern = res->lookupPattern(args[numArgs-1].getName()))) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (numArgs != state->getStrokeColorSpace()->getNComps()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("Incorrect number of arguments in 'SCN' command"));
e5db2522dbe503cbf5399094b6239c88c246a8c5poirier for (i = 0; i < numArgs && i < gfxColorMaxComps; ++i) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding//------------------------------------------------------------------------
fd9b4a0b713bc4816b9b80f52d567f5c2ac06bafsf// path segment operators
fd9b4a0b713bc4816b9b80f52d567f5c2ac06bafsf//------------------------------------------------------------------------
ec8b1faa56744b338f6d6421144b56c2bb3faae6poirier// TODO not good that numArgs is ignored but args[] is used:
ec8b1faa56744b338f6d6421144b56c2bb3faae6poirier// TODO not good that numArgs is ignored but args[] is used:
ec8b1faa56744b338f6d6421144b56c2bb3faae6poiriervoid PdfParser::opLineTo(Object args[], int /*numArgs*/)
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe error(errSyntaxError, getPos(), "No current point in lineto");
678a15e91d6a44569c956445442731bb64a98a63sf error(getPos(), const_cast<char*>("No current point in lineto"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
dc80439e9fba60c753cd145cb6799409ffea9b71ronaldvoid PdfParser::opCurveTo(Object args[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errSyntaxError, getPos(), "No current point in curveto");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("No current point in curveto"));
185aa71728867671e105178b4c66fbc22b65ae26sf// TODO not good that numArgs is ignored but args[] is used:
678a15e91d6a44569c956445442731bb64a98a63sfvoid PdfParser::opCurveTo1(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(errSyntaxError, getPos(), "No current point in curveto1");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding error(getPos(), const_cast<char*>("No current point in curveto1"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opCurveTo2(Object args[], int /*numArgs*/)
678a15e91d6a44569c956445442731bb64a98a63sf error(errSyntaxError, getPos(), "No current point in curveto2");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("No current point in curveto2"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opRectangle(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opClosePath(Object /*args*/[], int /*numArgs*/)
dc80439e9fba60c753cd145cb6799409ffea9b71ronald error(errSyntaxError, getPos(), "No current point in closepath");
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("No current point in closepath"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron//------------------------------------------------------------------------
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron// path painting operators
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding//------------------------------------------------------------------------
dc80439e9fba60c753cd145cb6799409ffea9b71ronaldvoid PdfParser::opEndPath(Object /*args*/[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opStroke(Object /*args*/[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //error(getPos(), const_cast<char*>("No path in stroke"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (state->getStrokeColorSpace()->getMode() == csPattern &&
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron !builder->isPatternTypeSupported(state->getStrokePattern())) {
8b99f2a316c5e2fa6ab208206fdd7fc2bfc4a921dougmvoid PdfParser::opCloseStroke(Object * /*args[]*/, int /*numArgs*/) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //error(getPos(), const_cast<char*>("No path in closepath/stroke"));
dc80439e9fba60c753cd145cb6799409ffea9b71ronald if (state->getStrokeColorSpace()->getMode() == csPattern &&
dc80439e9fba60c753cd145cb6799409ffea9b71ronald !builder->isPatternTypeSupported(state->getStrokePattern())) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opFill(Object /*args*/[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //error(getPos(), const_cast<char*>("No path in fill"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (state->getFillColorSpace()->getMode() == csPattern &&
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron !builder->isPatternTypeSupported(state->getFillPattern())) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::opEOFill(Object /*args*/[], int /*numArgs*/)
dc80439e9fba60c753cd145cb6799409ffea9b71ronald //error(getPos(), const_cast<char*>("No path in eofill"));
dc80439e9fba60c753cd145cb6799409ffea9b71ronald if (state->getFillColorSpace()->getMode() == csPattern &&
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding !builder->isPatternTypeSupported(state->getFillPattern())) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opFillStroke(Object /*args*/[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding //error(getPos(), const_cast<char*>("No path in fill/stroke"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opCloseFillStroke(Object /*args*/[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //error(getPos(), const_cast<char*>("No path in closepath/fill/stroke"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opEOFillStroke(Object /*args*/[], int /*numArgs*/)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //error(getPos(), const_cast<char*>("No path in eofill/stroke"));
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opCloseEOFillStroke(Object /*args*/[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding //error(getPos(), const_cast<char*>("No path in closepath/eofill/stroke"));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (state->getFillColorSpace()->getMode() == csPattern &&
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron !builder->isPatternTypeSupported(state->getFillPattern())) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (state->getStrokeColorSpace()->getMode() == csPattern &&
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron !builder->isPatternTypeSupported(state->getStrokePattern())) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::doPatternFillFallback(GBool eoFill) {
678a15e91d6a44569c956445442731bb64a98a63sf doShadingPatternFillFallback(static_cast<GfxShadingPattern *>(pattern), gFalse, eoFill);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(errUnimplemented, getPos(), "Unimplemented pattern type (%d) in fill",
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron error(getPos(), const_cast<char*>("Unimplemented pattern type (%d) in fill"),
e8f95a682820a599fe41b22977010636be5c2717jim doShadingPatternFillFallback(static_cast<GfxShadingPattern *>(pattern), gTrue, gFalse);
781888a651637edc0b043a6787cb0c2acf30a187geoff error(errUnimplemented, getPos(), "Unimplemented pattern type ({0:d}) in stroke",
781888a651637edc0b043a6787cb0c2acf30a187geoff error(getPos(), const_cast<char*>("Unimplemented pattern type (%d) in stroke"),
781888a651637edc0b043a6787cb0c2acf30a187geoffvoid PdfParser::doShadingPatternFillFallback(GfxShadingPattern *sPat,
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // save current graphics state
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // clip to bbox
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (0 ){//shading->getHasBBox()) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //builder->clip(state);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // clip to current path
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron //out->clipToStrokePath(state);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // set the color space
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding state->setFillColorSpace(shading->getColorSpace()->copy());
185aa71728867671e105178b4c66fbc22b65ae26sf // background color fill
aa6cb33e0279a72e5b5f482871844ebd85dfd527minfrin // construct a (pattern space) -> (current space) transform matrix
aa6cb33e0279a72e5b5f482871844ebd85dfd527minfrin // iCTM = invert CTM
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // m1 = PTM * BTM = PTM * base transform matrix
678a15e91d6a44569c956445442731bb64a98a63sf // m = m1 * iCTM = (PTM * BTM) * (iCTM)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
f78505c7d260473bf11002f5028186f27d0ed8a0geoff // set the new matrix
678a15e91d6a44569c956445442731bb64a98a63sf builder->setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // do shading type-specific operations
f78505c7d260473bf11002f5028186f27d0ed8a0geoff doFunctionShFill(static_cast<GfxFunctionShading *>(shading));
f769c33501f474aed3e0f7c769477c8c4f478783geoff // no need to implement these
f769c33501f474aed3e0f7c769477c8c4f478783geoff doGouraudTriangleShFill(static_cast<GfxGouraudTriangleShading *>(shading));
d8ea9d035301c33f3d9d3ecf3335f78ffcde1fb2covener doPatchMeshShFill(static_cast<GfxPatchMeshShading *>(shading));
f78505c7d260473bf11002f5028186f27d0ed8a0geoff // restore graphics state
e8f95a682820a599fe41b22977010636be5c2717jim// TODO not good that numArgs is ignored but args[] is used:
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid PdfParser::opShFill(Object args[], int /*numArgs*/)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (!(shading = res->lookupShading(args[0].getName(), NULL))) {
fd9b4a0b713bc4816b9b80f52d567f5c2ac06bafsf if (!(shading = res->lookupShading(args[0].getName()))) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // save current graphics state
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (shading->getType() != 2 && shading->getType() != 3) {
185aa71728867671e105178b4c66fbc22b65ae26sf } else { // get gradient transform if possible
678a15e91d6a44569c956445442731bb64a98a63sf // check proper operator sequence
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // first there should be one W(*) and then one 'cm' somewhere before 'sh'
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron builder->setTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); // remove transform
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // clip to bbox
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding xTemp = matrix[0]*xMin + matrix[2]*yMin + matrix[4];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding yTemp = matrix[1]*xMin + matrix[3]*yMin + matrix[5];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding xTemp = matrix[0]*xMax + matrix[2]*yMin + matrix[4];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding yTemp = matrix[1]*xMax + matrix[3]*yMin + matrix[5];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding xTemp = matrix[0]*xMax + matrix[2]*yMax + matrix[4];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding yTemp = matrix[1]*xMax + matrix[3]*yMax + matrix[5];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding xTemp = matrix[0]*xMin + matrix[2]*yMax + matrix[4];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding yTemp = matrix[1]*xMin + matrix[3]*yMax + matrix[5];
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // set the color space
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron state->setFillColorSpace(shading->getColorSpace()->copy());
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // do shading type-specific operations
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron doFunctionShFill(static_cast<GfxFunctionShading *>(shading));
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron builder->addShadedFill(shading, matrix, clipHistory->getClipPath(),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding doGouraudTriangleShFill(static_cast<GfxGouraudTriangleShading *>(shading));
fd9b4a0b713bc4816b9b80f52d567f5c2ac06bafsf doPatchMeshShFill(static_cast<GfxPatchMeshShading *>(shading));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // restore graphics state
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::doFunctionShFill(GfxFunctionShading *shading) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron doFunctionShFill1(shading, x0, y0, x1, y1, colors, 0);
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaronvoid PdfParser::doFunctionShFill1(GfxFunctionShading *shading,
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron double functionColorDelta = colorDeltas[pdfFunctionShading-1];
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron // compare the four corner colors
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron for (i = 0; i < 4; ++i) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron for (j = 0; j < nComps; ++j) {
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron if (abs(colors[i].c[j] - colors[(i+1)&3].c[j]) > functionColorDelta) {
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe // center of the rectangle
d0a225bdac006f3361e80bfc1be7e6f9b0e81f80ronald // the four corner colors are close (or we hit the recursive limit)
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick // -- fill the rectangle; but require at least one subdivision
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe // (depth==0) to avoid problems when the four outer corners of the
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe // shaded region are the same color
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe if ((i == 4 && depth > 0) || depth == maxDepths[pdfFunctionShading-1]) {
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd // use the center color
a44d29a3794110c558c940bd903a1930d717a7d7sf // fill the rectangle
a44d29a3794110c558c940bd903a1930d717a7d7sf state->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4],
d0a225bdac006f3361e80bfc1be7e6f9b0e81f80ronald state->lineTo(x1 * matrix[0] + y0 * matrix[2] + matrix[4],
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding state->lineTo(x1 * matrix[0] + y1 * matrix[2] + matrix[4],
0ec6007a40ac877a7c8d87767ca8e306d89f6595aaron state->lineTo(x0 * matrix[0] + y1 * matrix[2] + matrix[4],
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // the four corner colors are not close enough -- subdivide the
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding // rectangle
for (i = 0; i < nComps; ++i) {
for (i = 0; i < nComps; ++i) {
int start, i;
start = 0;
start);
#ifdef POPPLER_NEW_GFXPATCH
for (i = 0; i < nComps; ++i) {
> patchColorDelta ||
> patchColorDelta ||
> patchColorDelta ||
> patchColorDelta) {
#ifdef POPPLER_NEW_GFXPATCH
#ifdef POPPLER_NEW_GFXPATCH
for (i = 0; i < nComps; ++i) {
if (!font) {
if (printCommands) {
#ifdef POPPLER_NEW_ERRORAPI
if (fontChanged) {
double tx = 0;
double ty = 0;
#ifdef POPPLER_NEW_ERRORAPI
if (fontChanged) {
double tx = 0;
double ty = 0;
#ifdef POPPLER_NEW_ERRORAPI
if (fontChanged) {
Array *a = 0;
int wMode = 0;
#ifdef POPPLER_NEW_ERRORAPI
if (fontChanged) {
for (int i = 0; i < a->getLength(); ++i) {
if (wMode) {
#ifdef POPPLER_NEW_ERRORAPI
int wMode;
#ifdef POPPLER_NEW_GFXFONT
double *mat;
p = s->getCString();
while (len > 0) {
#ifdef POPPLER_NEW_GFXFONT
saveState();
#ifdef POPPLER_NEW_ERRORAPI
if (resDict) {
popResources();
restoreState();
len -= n;
p = s->getCString();
while (len > 0) {
#ifdef POPPLER_NEW_GFXFONT
if (wMode) {
len -= n;
#ifdef POPPLER_NEW_ERRORAPI
#ifdef POPPLER_NEW_ERRORAPI
#ifdef POPPLER_NEW_ERRORAPI
int bits;
bits = 0;
goto err2;
goto err2;
goto err2;
if (bits == 0) {
} else if (mask) {
goto err2;
if (mask) {
goto err1;
goto err2;
if (!colorSpace) {
goto err1;
delete colorMap;
goto err1;
int maskWidth = 0;
int maskHeight = 0;
if (inlineImg) {
goto err1;
goto err2;
goto err2;
goto err2;
goto err1;
delete maskColorMap;
goto err1;
if (inlineImg) {
goto err1;
goto err2;
goto err2;
goto err2;
goto err2;
if (haveSoftMask) {
delete maskColorMap;
} else if (haveExplicitMask) {
delete colorMap;
err2:
err1:
#ifdef POPPLER_NEW_ERRORAPI
#ifdef POPPLER_NEW_ERRORAPI
#ifdef POPPLER_NEW_ERRORAPI
++formDepth;
--formDepth;
if (blendingColorSpace) {
delete blendingColorSpace;
saveState();
restoreState();
popResources();
if (softMask) {
} else if (transpGroup) {
if (str) {
delete str;
char *key;
#ifdef POPPLER_NEW_ERRORAPI
#ifdef POPPLER_NEW_ERRORAPI
return NULL;
return str;
#ifdef POPPLER_NEW_ERRORAPI
#ifdef POPPLER_NEW_ERRORAPI
++ignoreUndef;
if (ignoreUndef > 0)
--ignoreUndef;
if (printCommands) {
if (printCommands) {
bool is_radial = false;
is_radial = true;
if (is_radial)
state->save(); // nasty hack to prevent GfxRadialShading from getting corrupted during copy operation
delete res;
int maxDepth) {
if (clipPathA) {
if (clipPath) {
delete clipPath;
if (clipPath) {
delete clipPath;
if (clipPathA) {
return newEntry;
if (saved) {
oldEntry = this;
return oldEntry;