/*
6 * Derived from poppler
's Gfx.cc, which was derived from Xpdf by 1996-2003 Glyph & Cog, LLC
7 * Jon A. Cruz <jon@joncruz.org>
9 * Copyright (C) 2018 Authors
10 * Released under GNU GPL v2+, read the file 'COPYING
' for more information.
14# include "config.h" // only include where actually required!
17#include "pdf-parser.h"
27#include <mutex> // std::call_once()
30#include <2geom/transforms.h>
32#include <poppler/Annot.h>
33#include <poppler/Array.h>
34#include <poppler/CharTypes.h>
35#include <poppler/Dict.h>
36#include <poppler/Error.h>
37#include <poppler/Gfx.h>
38#include <poppler/GfxFont.h>
39#include <poppler/GfxState.h>
40#include <poppler/GlobalParams.h>
41#include <poppler/Lexer.h>
42#include <poppler/Object.h>
43#include <poppler/OutputDev.h>
44#include <poppler/PDFDoc.h>
45#include <poppler/Page.h>
46#include <poppler/Parser.h>
47#include <poppler/Stream.h>
48#include <poppler/glib/poppler-features.h>
49#include <poppler/goo/GooString.h>
50#include <poppler/goo/gmem.h>
52#include "poppler-cairo-font-engine.h"
53#include "poppler-transition-api.h"
54#include "poppler-utils.h"
55#include "svg-builder.h"
57// the MSVC math.h doesn't define
this
59#define M_PI 3.14159265358979323846
67#define defaultShadingColorDelta (dblToCol( 1 / 2.0 ))
70#define defaultShadingMaxDepth 6
73#define maxOperatorHistoryDepth 16
80 {
"\"", 3, {tchkNum, tchkNum, tchkString},
82 {
"'", 1, {tchkString},
88 {
"BDC", 2, {tchkName, tchkProps},
92 {
"BMC", 1, {tchkName},
100 {
"DP", 2, {tchkName, tchkProps},
102 {
"Do", 1, {tchkName},
104 {
"EI", 0, {tchkNone},
106 {
"EMC", 0, {tchkNone},
108 {
"ET", 0, {tchkNone},
110 {
"EX", 0, {tchkNone},
116 {
"ID", 0, {tchkNone},
120 {
"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
124 {
"MP", 1, {tchkName},
128 {
"RG", 3, {tchkNum, tchkNum, tchkNum},
132 {
"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum},
134 {
"SCN", -33, {tchkSCN, tchkSCN, tchkSCN, tchkSCN,
135 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
136 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
137 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
138 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
139 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
140 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
141 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
144 {
"T*", 0, {tchkNone},
146 {
"TD", 2, {tchkNum, tchkNum},
148 {
"TJ", 1, {tchkArray},
154 {
"Td", 2, {tchkNum, tchkNum},
156 {
"Tf", 2, {tchkName, tchkNum},
158 {
"Tj", 1, {tchkString},
160 {
"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
173 {
"W*", 0, {tchkNone},
177 {
"b*", 0, {tchkNone},
179 {
"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
182 {
"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
185 {
"cs", 1, {tchkName},
187 {
"d", 2, {tchkArray, tchkNum},
189 {
"d0", 2, {tchkNum, tchkNum},
191 {
"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
196 {
"f*", 0, {tchkNone},
200 {
"gs", 1, {tchkName},
208 {
"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
210 {
"l", 2, {tchkNum, tchkNum},
212 {
"m", 2, {tchkNum, tchkNum},
218 {
"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
220 {
"rg", 3, {tchkNum, tchkNum, tchkNum},
222 {
"ri", 1, {tchkName},
226 {
"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum},
228 {
"scn", -33, {tchkSCN, tchkSCN, tchkSCN, tchkSCN,
229 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
230 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
231 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
232 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
233 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
234 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
235 tchkSCN, tchkSCN, tchkSCN, tchkSCN,
238 {
"sh", 1, {tchkName},
240 {
"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
244 {
"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
248#define numOps (sizeof(opTab) / sizeof(PdfOperator))
255 memset(&patch, 0,
sizeof(patch));
266 _POPPLER_CONST PDFRectangle *cropBox)
268 , xref(pdf_doc->getXRef())
271 , printCommands(false)
272 , res(new GfxResources(xref,
page->getResourceDict(), nullptr))
274 state(new GfxState(96.0, 96.0,
page->getCropBox(),
page->getRotate(), true))
275 , fontChanged(gFalse)
282 , operatorHistory(nullptr)
291 Catalog *catalog = pdf_doc->getCatalog();
292 GooString *
label =
new GooString(
"");
293 catalog->indexToLabel(
page->getNum() - 1,
label);
303 state->getPageHeight() / page_box.height());
307 if (cropBox &&
getRect(cropBox) != page_box) {
311 if (
auto meta = pdf_doc->readMetadata()) {
329 _POPPLER_CONST PDFRectangle *box)
333 , printCommands(false)
334 , res(new GfxResources(xref, resDict, nullptr))
336 state(new GfxState(72, 72, box, 0, false))
337 , fontChanged(gFalse)
344 , operatorHistory(nullptr)
379 if (obj->isArray()) {
380 for (
int i = 0; i < obj->arrayGetLength(); ++i) {
381 _POPPLER_CALL_ARGS(obj2, obj->arrayGet, i);
382 if (!obj2.isStream()) {
383 error(errInternal, -1,
"Weird page contents");
389 }
else if (!obj->isStream()) {
390 error(errInternal, -1,
"Weird page contents");
402 Object args[maxArgs];
406 _POPPLER_CALL(obj,
parser->getObj);
407 while (!obj.isEOF()) {
413 for (
int i = 0; i < numArgs; ++i) {
415 args[i].print(stdout);
422 execOp(&obj, args, numArgs);
424#if !defined(POPPLER_NEW_OBJECT_API)
426 for (
int i = 0; i < numArgs; ++i)
427 _POPPLER_FREE(args[i]);
432 }
else if (numArgs < maxArgs) {
433 args[numArgs++] = std::move(obj);
437 error(errSyntaxError,
getPos(),
"Too many args in content stream");
439 printf(
"throwing away arg: ");
448 _POPPLER_CALL(obj,
parser->getObj);
454 error(errSyntaxError,
getPos(),
"Leftover args in content stream");
456 printf(
"%d leftovers:", numArgs);
457 for (
int i = 0; i < numArgs; ++i) {
459 args[i].print(stdout);
464#if !defined(POPPLER_NEW_OBJECT_API)
465 for (
int i = 0; i < numArgs; ++i)
466 _POPPLER_FREE(args[i]);
475 newEntry->
state =
nullptr;
484 while (curr && curr->
next !=
nullptr) {
490 if (curr->
state !=
nullptr)
493 prev->
next =
nullptr;
502 while (--look_back > 0 && prev !=
nullptr) {
506 if (prev !=
nullptr) {
520 name = cmd->getCmd();
523 error(errSyntaxError,
getPos(),
"Unknown operator '{0:s}'",
name);
530 if (numArgs < op->numArgs) {
531 error(errSyntaxError,
getPos(),
"Too few ({0:d}) args to '{1:d}' operator", numArgs,
name);
536 error(errSyntaxError,
getPos(),
"Too many ({0:d}) args to '{1:s}' operator", numArgs,
name);
538 argPtr += numArgs - op->
numArgs;
543 error(errSyntaxError,
getPos(),
"Too many ({0:d}) args to '{1:s}' operator",
548 for (i = 0; i < numArgs; ++i) {
550 error(errSyntaxError,
getPos(),
"Arg #{0:d} to '{1:s}' operator is wrong type ({2:s})",
551 i,
name, argPtr[i].getTypeName());
560 (this->*op->
func)(argPtr, numArgs);
569 const int m = (a + b) / 2;
586 case tchkBool:
return arg->isBool();
587 case tchkInt:
return arg->isInt();
588 case tchkNum:
return arg->isNum();
589 case tchkString:
return arg->isString();
590 case tchkName:
return arg->isName();
591 case tchkArray:
return arg->isArray();
592 case tchkProps:
return arg->isDict() || arg->isName();
593 case tchkSCN:
return arg->isNum() || arg->isName();
594 case tchkNone:
return gFalse;
623 state->concatCTM(args[0].getNum(), args[1].getNum(),
624 args[2].getNum(), args[3].getNum(),
625 args[4].getNum(), args[5].getNum());
634 double *dash =
nullptr;
636 Array *a = args[0].getArray();
637 int length = a->getLength();
639 dash = (
double *)gmallocn(length,
sizeof(
double));
640 for (
int i = 0; i < length; ++i) {
642 dash[i] = _POPPLER_CALL_ARGS_DEREF(obj, a->get, i).getNum();
646#if POPPLER_CHECK_VERSION(22, 9, 0)
647 state->setLineDash(std::vector<double> (dash, dash + length), args[1].getNum());
649 state->setLineDash(dash, length, args[1].getNum());
657 state->setFlatness((
int)args[0].getNum());
664 state->setLineJoin(args[0].getInt());
672 state->setLineCap(args[0].getInt());
680 state->setMiterLimit(args[0].getNum());
688 state->setLineWidth(args[0].getNum());
695 Object obj1, obj2, obj3, obj4, obj5;
696 Function *funcs[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
697 GfxColor backdropColor;
698 GBool haveBackdropColor = gFalse;
699 GBool alpha = gFalse;
701 _POPPLER_CALL_ARGS(obj1,
res->lookupGState, args[0].getName());
705 if (!obj1.isDict()) {
706 error(errSyntaxError,
getPos(),
"ExtGState '{0:s}' is wrong type"), args[0].getName();
711 printf(
" gfx state dict: ");
717 if (!_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"BM").isNull()) {
718 GfxBlendMode
mode = gfxBlendNormal;
719 if (
state->parseBlendMode(&obj2, &
mode)) {
722 error(errSyntaxError,
getPos(),
"Invalid blend mode in ExtGState");
725 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"ca").isNum()) {
726 state->setFillOpacity(obj2.getNum());
728 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"CA").isNum()) {
729 state->setStrokeOpacity(obj2.getNum());
733 GBool haveFillOP = gFalse;
734 if ((haveFillOP = _POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"op").isBool())) {
735 state->setFillOverprint(obj2.getBool());
737 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"OP").isBool()) {
738 state->setStrokeOverprint(obj2.getBool());
740 state->setFillOverprint(obj2.getBool());
745 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"SA").isBool()) {
746 state->setStrokeAdjust(obj2.getBool());
750 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"LW").isNum()) {
751 state->setLineWidth(obj2.getNum());
755 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"TR2").isNull()) {
756 _POPPLER_CALL_ARGS(obj2, obj1.dictLookup,
"TR");
758 if (obj2.isName(
const_cast<char *
>(
"Default")) || obj2.isName(
const_cast<char *
>(
"Identity"))) {
759 funcs[0] = funcs[1] = funcs[2] = funcs[3] =
nullptr;
760 state->setTransfer(funcs);
761 }
else if (obj2.isArray() && obj2.arrayGetLength() == 4) {
763 for (
int i = 0; i < 4; ++i) {
764 _POPPLER_CALL_ARGS(obj3, obj2.arrayGet, i);
765 funcs[i] = Function::parse(&obj3);
773 state->setTransfer(funcs);
775 }
else if (obj2.isName() || obj2.isDict() || obj2.isStream()) {
776 if ((funcs[0] = Function::parse(&obj2))) {
777 funcs[1] = funcs[2] = funcs[3] =
nullptr;
778 state->setTransfer(funcs);
780 }
else if (!obj2.isNull()) {
781 error(errSyntaxError,
getPos(),
"Invalid transfer function in ExtGState");
785 if (!_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"SMask").isNull()) {
786 if (obj2.isName(
const_cast<char *
>(
"None"))) {
788 }
else if (obj2.isDict()) {
789 if (_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup,
"S").isName(
"Alpha")) {
796 if (!_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup,
"TR").isNull()) {
797 funcs[0] = Function::parse(&obj3);
798 if (funcs[0]->getInputSize() != 1 || funcs[0]->getOutputSize() != 1) {
799 error(errSyntaxError,
getPos(),
"Invalid transfer function in soft mask in ExtGState");
805 if ((haveBackdropColor = _POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup,
"BC").isArray())) {
806 for (
int &i : backdropColor.c) {
809 for (
int i = 0; i < obj3.arrayGetLength() && i < gfxColorMaxComps; ++i) {
810 _POPPLER_CALL_ARGS(obj4, obj3.arrayGet, i);
812 backdropColor.c[i] = dblToCol(obj4.getNum());
818 if (_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup,
"G").isStream()) {
819 if (_POPPLER_CALL_ARGS_DEREF(obj4, obj3.streamGetDict()->lookup,
"Group").isDict()) {
820 std::unique_ptr<GfxColorSpace> blendingColorSpace;
821 GBool isolated = gFalse;
822 GBool knockout = gFalse;
823 if (!_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup,
"CS").isNull()) {
824 blendingColorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(
nullptr, &obj5,
nullptr,
state));
827 if (_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup,
"I").isBool()) {
828 isolated = obj5.getBool();
831 if (_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup,
"K").isBool()) {
832 knockout = obj5.getBool();
835 if (!haveBackdropColor) {
836 if (blendingColorSpace) {
837 blendingColorSpace->getDefaultColor(&backdropColor);
840 for (
int &i : backdropColor.c) {
845 doSoftMask(&obj3, alpha, blendingColorSpace.get(), isolated, knockout, funcs[0], &backdropColor);
850 error(errSyntaxError,
getPos(),
"Invalid soft mask in ExtGState - missing group");
854 error(errSyntaxError,
getPos(),
"Invalid soft mask in ExtGState - missing group");
857 }
else if (!obj2.isNull()) {
858 error(errSyntaxError,
getPos(),
"Invalid soft mask in ExtGState");
867 GfxColorSpace *blendingColorSpace,
869 Function *transferFunc, GfxColor *backdropColor) {
870 Dict *dict, *resDict;
871 double m[6], bbox[4];
881 dict = str->streamGetDict();
884 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"FormType");
885 if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
886 error(errSyntaxError,
getPos(),
"Unknown form type");
891 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"BBox");
892 if (!obj1.isArray()) {
894 error(errSyntaxError,
getPos(),
"Bad form bounding box");
897 for (i = 0; i < 4; ++i) {
898 _POPPLER_CALL_ARGS(obj2, obj1.arrayGet, i);
899 bbox[i] = obj2.getNum();
905 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Matrix");
906 if (obj1.isArray()) {
907 for (i = 0; i < 6; ++i) {
908 _POPPLER_CALL_ARGS(obj2, obj1.arrayGet, i);
909 m[i] = obj2.getNum();
920 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Resources");
921 resDict = obj1.isDict() ? obj1.getDict() : (Dict *)
nullptr;
925 doForm1(str, resDict, m, bbox, gTrue, gTrue,
926 blendingColorSpace, isolated, knockout,
927 alpha, transferFunc, backdropColor);
948 assert(!arg.isNull());
950 if (
char const *
name = arg.isName() ? arg.getName() :
nullptr) {
951 auto const cache_name = std::to_string(
formDepth) +
"-" +
name;
953 return std::unique_ptr<GfxColorSpace>(cached->copy());
956 std::unique_ptr<GfxColorSpace> colorSpace;
957 if (
auto obj =
res->lookupColorSpace(
name); !obj.isNull()) {
958 colorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(
res, &obj,
nullptr,
state));
960 colorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(
res, &arg,
nullptr,
state));
963 if (colorSpace && colorSpace->getMode() != csPattern) {
964 colorSpacesCache[cache_name] = std::unique_ptr<GfxColorSpace>(colorSpace->copy());
970 return std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(
res, &arg,
nullptr,
state));
979 if (!obj->isName()) {
982 return std::unique_ptr<GfxPattern>(
res->lookupPattern(obj->getName(),
nullptr,
state));
990 state->setFillPattern(
nullptr);
991 state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceGrayColorSpace>()));
992 color.c[0] = dblToCol(args[0].getNum());
993 state->setFillColor(&color);
1002 state->setStrokePattern(
nullptr);
1003 state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceGrayColorSpace>()));
1004 color.c[0] = dblToCol(args[0].getNum());
1005 state->setStrokeColor(&color);
1015 state->setFillPattern(
nullptr);
1016 state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceCMYKColorSpace>()));
1017 for (i = 0; i < 4; ++i) {
1018 color.c[i] = dblToCol(args[i].getNum());
1020 state->setFillColor(&color);
1029 state->setStrokePattern(
nullptr);
1030 state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceCMYKColorSpace>()));
1031 for (
int i = 0; i < 4; ++i) {
1032 color.c[i] = dblToCol(args[i].getNum());
1034 state->setStrokeColor(&color);
1043 state->setFillPattern(
nullptr);
1044 state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceRGBColorSpace>()));
1045 for (
int i = 0; i < 3; ++i) {
1046 color.c[i] = dblToCol(args[i].getNum());
1048 state->setFillColor(&color);
1056 state->setStrokePattern(
nullptr);
1057 state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceRGBColorSpace>()));
1058 for (
int i = 0; i < 3; ++i) {
1059 color.c[i] = dblToCol(args[i].getNum());
1061 state->setStrokeColor(&color);
1068 assert(numArgs >= 1);
1071 state->setFillPattern(
nullptr);
1075 colorSpace->getDefaultColor(&color);
1076 state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
1077 state->setFillColor(&color);
1080 error(errSyntaxError,
getPos(),
"Bad color space (fill)");
1087 assert(numArgs >= 1);
1092 state->setStrokePattern(
nullptr);
1096 colorSpace->getDefaultColor(&color);
1097 state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
1098 state->setStrokeColor(&color);
1101 error(errSyntaxError,
getPos(),
"Bad color space (stroke)");
1109 if (numArgs !=
state->getFillColorSpace()->getNComps()) {
1110 error(errSyntaxError,
getPos(),
"Incorrect number of arguments in 'sc' command");
1114 state->setFillPattern(
nullptr);
1115 for (i = 0; i < numArgs; ++i) {
1116 color.c[i] = dblToCol(args[i].getNum());
1118 state->setFillColor(&color);
1126 if (numArgs !=
state->getStrokeColorSpace()->getNComps()) {
1127 error(errSyntaxError,
getPos(),
"Incorrect number of arguments in 'SC' command");
1131 state->setStrokePattern(
nullptr);
1132 for (i = 0; i < numArgs; ++i) {
1133 color.c[i] = dblToCol(args[i].getNum());
1135 state->setStrokeColor(&color);
1143 if (
state->getFillColorSpace()->getMode() == csPattern) {
1145 if (!((GfxPatternColorSpace *)
state->getFillColorSpace())->getUnder() ||
1146 numArgs - 1 != ((GfxPatternColorSpace *)
state->getFillColorSpace())
1147 ->getUnder()->getNComps()) {
1148 error(errSyntaxError,
getPos(),
"Incorrect number of arguments in 'scn' command");
1151 for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
1152 if (args[i].isNum()) {
1153 color.c[i] = dblToCol(args[i].getNum());
1156 state->setFillColor(&color);
1160 state->setFillPattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern));
1165 if (numArgs !=
state->getFillColorSpace()->getNComps()) {
1166 error(errSyntaxError,
getPos(),
"Incorrect number of arguments in 'scn' command");
1169 state->setFillPattern(
nullptr);
1170 for (i = 0; i < numArgs && i < gfxColorMaxComps; ++i) {
1171 if (args[i].isNum()) {
1172 color.c[i] = dblToCol(args[i].getNum());
1175 state->setFillColor(&color);
1185 if (
state->getStrokeColorSpace()->getMode() == csPattern) {
1187 if (!((GfxPatternColorSpace *)
state->getStrokeColorSpace())
1189 numArgs - 1 != ((GfxPatternColorSpace *)
state->getStrokeColorSpace())
1190 ->getUnder()->getNComps()) {
1191 error(errSyntaxError,
getPos(),
"Incorrect number of arguments in 'SCN' command");
1194 for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
1195 if (args[i].isNum()) {
1196 color.c[i] = dblToCol(args[i].getNum());
1199 state->setStrokeColor(&color);
1203 state->setStrokePattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern));
1208 if (numArgs !=
state->getStrokeColorSpace()->getNComps()) {
1209 error(errSyntaxError,
getPos(),
"Incorrect number of arguments in 'SCN' command");
1212 state->setStrokePattern(
nullptr);
1213 for (i = 0; i < numArgs && i < gfxColorMaxComps; ++i) {
1214 if (args[i].isNum()) {
1215 color.c[i] = dblToCol(args[i].getNum());
1218 state->setStrokeColor(&color);
1230 state->moveTo(args[0].getNum(), args[1].getNum());
1236 if (!
state->isCurPt()) {
1237 error(errSyntaxError,
getPos(),
"No current point in lineto");
1240 state->lineTo(args[0].getNum(), args[1].getNum());
1246 if (!
state->isCurPt()) {
1247 error(errSyntaxError,
getPos(),
"No current point in curveto");
1250 double x1 = args[0].getNum();
1251 double y1 = args[1].getNum();
1252 double x2 = args[2].getNum();
1253 double y2 = args[3].getNum();
1254 double x3 = args[4].getNum();
1255 double y3 = args[5].getNum();
1256 state->curveTo(x1, y1, x2, y2, x3, y3);
1262 if (!
state->isCurPt()) {
1263 error(errSyntaxError,
getPos(),
"No current point in curveto1");
1266 double x1 =
state->getCurX();
1267 double y1 =
state->getCurY();
1268 double x2 = args[0].getNum();
1269 double y2 = args[1].getNum();
1270 double x3 = args[2].getNum();
1271 double y3 = args[3].getNum();
1272 state->curveTo(x1, y1, x2, y2, x3, y3);
1278 if (!
state->isCurPt()) {
1279 error(errSyntaxError,
getPos(),
"No current point in curveto2");
1282 double x1 = args[0].getNum();
1283 double y1 = args[1].getNum();
1284 double x2 = args[2].getNum();
1285 double y2 = args[3].getNum();
1288 state->curveTo(x1, y1, x2, y2, x3, y3);
1294 double x = args[0].getNum();
1295 double y = args[1].getNum();
1296 double w = args[2].getNum();
1297 double h = args[3].getNum();
1298 state->moveTo(x, y);
1300 state->lineTo(x +
w, y + h);
1301 state->lineTo(x, y + h);
1307 if (!
state->isCurPt()) {
1308 error(errSyntaxError,
getPos(),
"No current point in closepath");
1325 if (!
state->isCurPt()) {
1329 if (
state->isPath()) {
1330 if (
state->getStrokeColorSpace()->getMode() == csPattern &&
1341 if (!
state->isCurPt()) {
1346 if (
state->isPath()) {
1347 if (
state->getStrokeColorSpace()->getMode() == csPattern &&
1359 if (!
state->isCurPt()) {
1363 if (
state->isPath()) {
1364 if (
state->getFillColorSpace()->getMode() == csPattern &&
1376 if (!
state->isCurPt()) {
1380 if (
state->isPath()) {
1381 if (
state->getFillColorSpace()->getMode() == csPattern &&
1393 if (!
state->isCurPt()) {
1397 if (
state->isPath()) {
1407 if (!
state->isCurPt()) {
1411 if (
state->isPath()) {
1420 if (!
state->isCurPt()) {
1424 if (
state->isPath()) {
1432 if (!
state->isCurPt()) {
1436 if (
state->isPath()) {
1444 GBool fillOk = gTrue, strokeOk = gTrue;
1445 if (
state->getFillColorSpace()->getMode() == csPattern &&
1449 if (
state->getStrokeColorSpace()->getMode() == csPattern &&
1453 if (fillOk && strokeOk) {
1462 GfxPattern *pattern;
1464 if (!(pattern =
state->getFillPattern())) {
1467 switch (pattern->getType()) {
1474 error(errUnimplemented,
getPos(),
"Unimplemented pattern type (%d) in fill",
1475 pattern->getType());
1481 GfxPattern *pattern;
1483 if (!(pattern =
state->getStrokePattern())) {
1486 switch (pattern->getType()) {
1493 error(errUnimplemented,
getPos(),
"Unimplemented pattern type ({0:d}) in stroke",
1494 pattern->getType());
1501 GfxShading *shading;
1504 shading = sPat->getShading();
1507 savedPath =
state->getPath()->copy();
1525 state->clipToStrokePath();
1537 state->setFillColorSpace(shading->getColorSpace()->copy());
1540 if (shading->getHasBackground()) {
1541 state->setFillColor(shading->getBackground());
1551 state->concatCTM(m[0], m[1], m[2], m[3], m[4], m[5]);
1554 switch (shading->getType()) {
1574 state->setPath(savedPath);
1580 GfxPath *savedPath =
nullptr;
1581 bool savedState =
false;
1583 auto shading = std::unique_ptr<GfxShading>(
res->lookupShading(args[0].getName(),
nullptr,
state));
1589 if (shading->getType() != 2 && shading->getType() != 3) {
1590 savedPath =
state->getPath()->copy();
1611 state->setFillColorSpace(shading->getColorSpace()->copy());
1614 switch (shading->getType()) {
1635 state->setPath(savedPath);
1640 double x0, y0, x1, y1;
1643 shading->getDomain(&x0, &y0, &x1, &y1);
1644 shading->getColor(x0, y0, &colors[0]);
1645 shading->getColor(x0, y1, &colors[1]);
1646 shading->getColor(x1, y0, &colors[2]);
1647 shading->getColor(x1, y1, &colors[3]);
1652 double x0,
double y0,
1653 double x1,
double y1,
1654 GfxColor *colors,
int depth) {
1656 GfxColor color0M, color1M, colorM0, colorM1, colorMM;
1657 GfxColor colors2[4];
1658 double functionColorDelta =
colorDeltas[pdfFunctionShading-1];
1659 const double *matrix;
1663 nComps = shading->getColorSpace()->getNComps();
1664 matrix = shading->getMatrix();
1667 for (i = 0; i < 4; ++i) {
1668 for (j = 0; j < nComps; ++j) {
1669 if (abs(colors[i].
c[j] - colors[(i+1)&3].
c[j]) > functionColorDelta) {
1679 xM = 0.5 * (x0 + x1);
1680 yM = 0.5 * (y0 + y1);
1686 if ((i == 4 && depth > 0) || depth ==
maxDepths[pdfFunctionShading-1]) {
1689 shading->getColor(xM, yM, &fillColor);
1690 state->setFillColor(&fillColor);
1693 state->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4],
1694 x0 * matrix[1] + y0 * matrix[3] + matrix[5]);
1695 state->lineTo(x1 * matrix[0] + y0 * matrix[2] + matrix[4],
1696 x1 * matrix[1] + y0 * matrix[3] + matrix[5]);
1697 state->lineTo(x1 * matrix[0] + y1 * matrix[2] + matrix[4],
1698 x1 * matrix[1] + y1 * matrix[3] + matrix[5]);
1699 state->lineTo(x0 * matrix[0] + y1 * matrix[2] + matrix[4],
1700 x0 * matrix[1] + y1 * matrix[3] + matrix[5]);
1723 shading->getColor(x0, yM, &color0M);
1724 shading->getColor(x1, yM, &color1M);
1725 shading->getColor(xM, y0, &colorM0);
1726 shading->getColor(xM, y1, &colorM1);
1727 shading->getColor(xM, yM, &colorMM);
1730 colors2[0] = colors[0];
1731 colors2[1] = color0M;
1732 colors2[2] = colorM0;
1733 colors2[3] = colorMM;
1737 colors2[0] = color0M;
1738 colors2[1] = colors[1];
1739 colors2[2] = colorMM;
1740 colors2[3] = colorM1;
1744 colors2[0] = colorM0;
1745 colors2[1] = colorMM;
1746 colors2[2] = colors[2];
1747 colors2[3] = color1M;
1751 colors2[0] = colorMM;
1752 colors2[1] = colorM1;
1753 colors2[2] = color1M;
1754 colors2[3] = colors[3];
1760 double x0, y0, x1, y1, x2, y2;
1761 GfxColor color0, color1, color2;
1764 for (i = 0; i < shading->getNTriangles(); ++i) {
1765 shading->getTriangle(i, &x0, &y0, &color0,
1769 shading->getColorSpace()->getNComps(), 0);
1774 double x1,
double y1, GfxColor *color1,
1775 double x2,
double y2, GfxColor *color2,
1776 int nComps,
int depth) {
1777 double x01, y01, x12, y12, x20, y20;
1778 double gouraudColorDelta =
colorDeltas[pdfGouraudTriangleShading-1];
1779 GfxColor color01, color12, color20;
1782 for (i = 0; i < nComps; ++i) {
1783 if (abs(color0->c[i] - color1->c[i]) > gouraudColorDelta ||
1784 abs(color1->c[i] - color2->c[i]) > gouraudColorDelta) {
1788 if (i == nComps || depth ==
maxDepths[pdfGouraudTriangleShading-1]) {
1789 state->setFillColor(color0);
1790 state->moveTo(x0, y0);
1791 state->lineTo(x1, y1);
1792 state->lineTo(x2, y2);
1797 x01 = 0.5 * (x0 + x1);
1798 y01 = 0.5 * (y0 + y1);
1799 x12 = 0.5 * (x1 + x2);
1800 y12 = 0.5 * (y1 + y2);
1801 x20 = 0.5 * (x2 + x0);
1802 y20 = 0.5 * (y2 + y0);
1805 for (i = 0; i < nComps; ++i) {
1806 color01.c[i] = (color0->c[i] + color1->c[i]) / 2;
1807 color12.c[i] = (color1->c[i] + color2->c[i]) / 2;
1808 color20.c[i] = (color2->c[i] + color0->c[i]) / 2;
1811 x20, y20, &color20, nComps, depth + 1);
1813 x12, y12, &color12, nComps, depth + 1);
1815 x20, y20, &color20, nComps, depth + 1);
1817 x2, y2, color2, nComps, depth + 1);
1824 if (shading->getNPatches() > 128) {
1826 }
else if (shading->getNPatches() > 64) {
1828 }
else if (shading->getNPatches() > 16) {
1833 for (i = 0; i < shading->getNPatches(); ++i) {
1834 fillPatch(shading->getPatch(i), shading->getColorSpace()->getNComps(),
1840 GfxPatch patch00 = blankPatch();
1841 GfxPatch patch01 = blankPatch();
1842 GfxPatch patch10 = blankPatch();
1843 GfxPatch patch11 = blankPatch();
1844 GfxColor color = {{0}};
1849 double patchColorDelta =
colorDeltas[pdfPatchMeshShading - 1];
1853 for (i = 0; i < nComps; ++i) {
1854 if (std::abs(patch->color[0][0].c[i] - patch->color[0][1].c[i])
1855 > patchColorDelta ||
1856 std::abs(patch->color[0][1].c[i] - patch->color[1][1].c[i])
1857 > patchColorDelta ||
1858 std::abs(patch->color[1][1].c[i] - patch->color[1][0].c[i])
1859 > patchColorDelta ||
1860 std::abs(patch->color[1][0].c[i] - patch->color[0][0].c[i])
1861 > patchColorDelta) {
1864 color.c[i] = GfxColorComp(patch->color[0][0].c[i]);
1866 if (i == nComps || depth ==
maxDepths[pdfPatchMeshShading-1]) {
1867 state->setFillColor(&color);
1868 state->moveTo(patch->x[0][0], patch->y[0][0]);
1869 state->curveTo(patch->x[0][1], patch->y[0][1],
1870 patch->x[0][2], patch->y[0][2],
1871 patch->x[0][3], patch->y[0][3]);
1872 state->curveTo(patch->x[1][3], patch->y[1][3],
1873 patch->x[2][3], patch->y[2][3],
1874 patch->x[3][3], patch->y[3][3]);
1875 state->curveTo(patch->x[3][2], patch->y[3][2],
1876 patch->x[3][1], patch->y[3][1],
1877 patch->x[3][0], patch->y[3][0]);
1878 state->curveTo(patch->x[2][0], patch->y[2][0],
1879 patch->x[1][0], patch->y[1][0],
1880 patch->x[0][0], patch->y[0][0]);
1885 for (i = 0; i < 4; ++i) {
1886 xx[i][0] = patch->x[i][0];
1887 yy[i][0] = patch->y[i][0];
1888 xx[i][1] = 0.5 * (patch->x[i][0] + patch->x[i][1]);
1889 yy[i][1] = 0.5 * (patch->y[i][0] + patch->y[i][1]);
1890 xxm = 0.5 * (patch->x[i][1] + patch->x[i][2]);
1891 yym = 0.5 * (patch->y[i][1] + patch->y[i][2]);
1892 xx[i][6] = 0.5 * (patch->x[i][2] + patch->x[i][3]);
1893 yy[i][6] = 0.5 * (patch->y[i][2] + patch->y[i][3]);
1894 xx[i][2] = 0.5 * (xx[i][1] + xxm);
1895 yy[i][2] = 0.5 * (yy[i][1] + yym);
1896 xx[i][5] = 0.5 * (xxm + xx[i][6]);
1897 yy[i][5] = 0.5 * (yym + yy[i][6]);
1898 xx[i][3] = xx[i][4] = 0.5 * (xx[i][2] + xx[i][5]);
1899 yy[i][3] = yy[i][4] = 0.5 * (yy[i][2] + yy[i][5]);
1900 xx[i][7] = patch->x[i][3];
1901 yy[i][7] = patch->y[i][3];
1903 for (i = 0; i < 4; ++i) {
1904 patch00.x[0][i] = xx[0][i];
1905 patch00.y[0][i] = yy[0][i];
1906 patch00.x[1][i] = 0.5 * (xx[0][i] + xx[1][i]);
1907 patch00.y[1][i] = 0.5 * (yy[0][i] + yy[1][i]);
1908 xxm = 0.5 * (xx[1][i] + xx[2][i]);
1909 yym = 0.5 * (yy[1][i] + yy[2][i]);
1910 patch10.x[2][i] = 0.5 * (xx[2][i] + xx[3][i]);
1911 patch10.y[2][i] = 0.5 * (yy[2][i] + yy[3][i]);
1912 patch00.x[2][i] = 0.5 * (patch00.x[1][i] + xxm);
1913 patch00.y[2][i] = 0.5 * (patch00.y[1][i] + yym);
1914 patch10.x[1][i] = 0.5 * (xxm + patch10.x[2][i]);
1915 patch10.y[1][i] = 0.5 * (yym + patch10.y[2][i]);
1916 patch00.x[3][i] = 0.5 * (patch00.x[2][i] + patch10.x[1][i]);
1917 patch00.y[3][i] = 0.5 * (patch00.y[2][i] + patch10.y[1][i]);
1918 patch10.x[0][i] = patch00.x[3][i];
1919 patch10.y[0][i] = patch00.y[3][i];
1920 patch10.x[3][i] = xx[3][i];
1921 patch10.y[3][i] = yy[3][i];
1923 for (i = 4; i < 8; ++i) {
1924 patch01.x[0][i-4] = xx[0][i];
1925 patch01.y[0][i-4] = yy[0][i];
1926 patch01.x[1][i-4] = 0.5 * (xx[0][i] + xx[1][i]);
1927 patch01.y[1][i-4] = 0.5 * (yy[0][i] + yy[1][i]);
1928 xxm = 0.5 * (xx[1][i] + xx[2][i]);
1929 yym = 0.5 * (yy[1][i] + yy[2][i]);
1930 patch11.x[2][i-4] = 0.5 * (xx[2][i] + xx[3][i]);
1931 patch11.y[2][i-4] = 0.5 * (yy[2][i] + yy[3][i]);
1932 patch01.x[2][i-4] = 0.5 * (patch01.x[1][i-4] + xxm);
1933 patch01.y[2][i-4] = 0.5 * (patch01.y[1][i-4] + yym);
1934 patch11.x[1][i-4] = 0.5 * (xxm + patch11.x[2][i-4]);
1935 patch11.y[1][i-4] = 0.5 * (yym + patch11.y[2][i-4]);
1936 patch01.x[3][i-4] = 0.5 * (patch01.x[2][i-4] + patch11.x[1][i-4]);
1937 patch01.y[3][i-4] = 0.5 * (patch01.y[2][i-4] + patch11.y[1][i-4]);
1938 patch11.x[0][i-4] = patch01.x[3][i-4];
1939 patch11.y[0][i-4] = patch01.y[3][i-4];
1940 patch11.x[3][i-4] = xx[3][i];
1941 patch11.y[3][i-4] = yy[3][i];
1945 for (i = 0; i < nComps; ++i) {
1946 patch00.color[0][0].c[i] = patch->color[0][0].c[i];
1947 patch00.color[0][1].c[i] = (patch->color[0][0].c[i] +
1948 patch->color[0][1].c[i]) / 2;
1949 patch01.color[0][0].c[i] = patch00.color[0][1].c[i];
1950 patch01.color[0][1].c[i] = patch->color[0][1].c[i];
1951 patch01.color[1][1].c[i] = (patch->color[0][1].c[i] +
1952 patch->color[1][1].c[i]) / 2;
1953 patch11.color[0][1].c[i] = patch01.color[1][1].c[i];
1954 patch11.color[1][1].c[i] = patch->color[1][1].c[i];
1955 patch11.color[1][0].c[i] = (patch->color[1][1].c[i] +
1956 patch->color[1][0].c[i]) / 2;
1957 patch10.color[1][1].c[i] = patch11.color[1][0].c[i];
1958 patch10.color[1][0].c[i] = patch->color[1][0].c[i];
1959 patch10.color[0][0].c[i] = (patch->color[1][0].c[i] +
1960 patch->color[0][0].c[i]) / 2;
1961 patch00.color[1][0].c[i] = patch10.color[0][0].c[i];
1962 patch00.color[1][1].c[i] = (patch00.color[1][0].c[i] +
1963 patch01.color[1][1].c[i]) / 2;
1964 patch01.color[1][0].c[i] = patch00.color[1][1].c[i];
1965 patch11.color[0][0].c[i] = patch00.color[1][1].c[i];
1966 patch10.color[0][1].c[i] = patch00.color[1][1].c[i];
1976 if (
state->isCurPt() &&
clip != clipNone) {
2004 state->setTextMat(1, 0, 0, 1, 0, 0);
2005 state->textMoveTo(0, 0);
2023 state->setCharSpace(args[0].getNum());
2029 auto font =
res->lookupFont(args[0].getName());
2034 state->setFont(
nullptr, args[1].getNum());
2039 printf(
" font: tag=%s name='%s' %g\n",
2040#
if POPPLER_CHECK_VERSION(21,11,0)
2041 font->getTag().c_str(),
2043 font->getTag()->getCString(),
2045 font->getName() ? font->getName()->getCString() :
"???",
2050#if !POPPLER_CHECK_VERSION(22, 4, 0)
2053 state->setFont(font, args[1].getNum());
2060 state->setLeading(args[0].getNum());
2067 state->setRender(args[0].getInt());
2074 state->setRise(args[0].getNum());
2080 state->setWordSpace(args[0].getNum());
2086 state->setHorizScaling(args[0].getNum());
2100 tx =
state->getLineX() + args[0].getNum();
2101 ty =
state->getLineY() + args[1].getNum();
2102 state->textMoveTo(tx, ty);
2111 tx =
state->getLineX() + args[0].getNum();
2112 ty = args[1].getNum();
2113 state->setLeading(-ty);
2114 ty +=
state->getLineY();
2115 state->textMoveTo(tx, ty);
2122 state->setTextMat(args[0].getNum(), args[1].getNum(),
2123 args[2].getNum(), args[3].getNum(),
2124 args[4].getNum(), args[5].getNum());
2125 state->textMoveTo(0, 0);
2135 tx =
state->getLineX();
2136 ty =
state->getLineY() -
state->getLeading();
2137 state->textMoveTo(tx, ty);
2158 static FT_Library ft_lib;
2159 static std::once_flag ft_lib_once_flag;
2160 std::call_once(ft_lib_once_flag, FT_Init_FreeType, &ft_lib);
2164 _font_engine = std::make_shared<CairoFontEngine>(ft_lib);
2172 if (!
state->getFont()) {
2173 error(errSyntaxError,
getPos(),
"No font in show");
2186 if (!
state->getFont()) {
2187 error(errSyntaxError,
getPos(),
"No font in move/show");
2191 tx =
state->getLineX();
2192 ty =
state->getLineY() -
state->getLeading();
2193 state->textMoveTo(tx, ty);
2204 if (!
state->getFont()) {
2205 error(errSyntaxError,
getPos(),
"No font in move/set/show");
2209 state->setWordSpace(args[0].getNum());
2210 state->setCharSpace(args[1].getNum());
2211 tx =
state->getLineX();
2212 ty =
state->getLineY() -
state->getLeading();
2213 state->textMoveTo(tx, ty);
2225 if (!
state->getFont()) {
2226 error(errSyntaxError,
getPos(),
"No font in show/space");
2230 wMode =
state->getFont()->getWMode();
2231 a = args[0].getArray();
2232 for (
int i = 0; i < a->getLength(); ++i) {
2233 _POPPLER_CALL_ARGS(obj, a->get, i);
2238 state->textShift(0, -obj.getNum() * 0.001 *
2239 fabs(
state->getFontSize()));
2241 state->textShift(-obj.getNum() * 0.001 *
2242 fabs(
state->getFontSize()), 0);
2245 }
else if (obj.isString()) {
2248 error(errSyntaxError,
getPos(),
"Element of show/space array must be number or string");
2258#if POPPLER_CHECK_VERSION(0,64,0)
2263 auto font =
state->getFont();
2264 int wMode = font->getWMode();
2269 if (font->getType() == fontType3) {
2270 g_warning(
"PDF fontType3 information ignored.");
2273 double riseX, riseY;
2274 state->textTransformDelta(0,
state->getRise(), &riseX, &riseY);
2276 auto p = s->getCString();
2277 int len = s->getLength();
2282 Unicode _POPPLER_CONST_82 *u =
nullptr;
2285 double originX, originY;
2288 int n = font->getNextChar(p,
len, &code, &u, &uLen, &dx, &dy, &originX, &originY);
2290 dx *=
state->getFontSize();
2291 dy *=
state->getFontSize();
2292 originX *=
state->getFontSize();
2293 originY *=
state->getFontSize();
2301 dy +=
state->getCharSpace();
2302 if (n == 1 && *p ==
' ') {
2303 dy +=
state->getWordSpace();
2307 dx +=
state->getCharSpace();
2308 if (n == 1 && *p ==
' ') {
2309 dx +=
state->getWordSpace();
2311 dx *=
state->getHorizScaling();
2312 ax *=
state->getHorizScaling();
2316 state->textTransformDelta(dx, dy, &tdx, &tdy);
2318 double tOriginX, tOriginY;
2319 state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
2323 dx, dy, ax, ay, tOriginX, tOriginY, code, n, u, uLen);
2326 state->shift(tdx, tdy);
2342 Object obj1, obj2, obj3, refObj;
2343 bool layered =
false;
2346#if POPPLER_CHECK_VERSION(0,64,0)
2347 const char *
name = args[0].getName();
2349 char *
name = args[0].getName();
2351 _POPPLER_CALL_ARGS(obj1,
res->lookupXObject,
name);
2352 if (obj1.isNull()) {
2355 if (!obj1.isStream()) {
2356 error(errSyntaxError,
getPos(),
"XObject '{0:s}' is wrong type",
name);
2357 _POPPLER_FREE(obj1);
2362 _POPPLER_CALL_ARGS(obj2, obj1.streamGetDict()->lookup,
"OC");
2364 auto type_dict = obj2.getDict();
2365 if (type_dict->lookup(
"Type").isName(
"OCG")) {
2368 if (type_dict->lookup(
"Usage").isDict()){
2369 auto usage_dict = type_dict->lookup(
"Usage").getDict();
2370 if (usage_dict->lookup(
"Print").isDict()){
2371 auto print_dict = usage_dict->lookup(
"Print").getDict();
2372 visible = print_dict->lookup(
"PrintState").isName(
"ON");
2380 _POPPLER_CALL_ARGS(obj2, obj1.streamGetDict()->lookup,
"Subtype");
2381 if (obj2.isName(
const_cast<char*
>(
"Image"))) {
2382 _POPPLER_CALL_ARGS(refObj,
res->lookupXObjectNF,
name);
2383 doImage(&refObj, obj1.getStream(), gFalse);
2384 _POPPLER_FREE(refObj);
2385 }
else if (obj2.isName(
const_cast<char*
>(
"Form"))) {
2387 }
else if (obj2.isName(
const_cast<char*
>(
"PS"))) {
2388 _POPPLER_CALL_ARGS(obj3, obj1.streamGetDict()->lookup,
"Level1");
2389 }
else if (obj2.isName()) {
2390 error(errSyntaxError,
getPos(),
"Unknown XObject subtype '{0:s}'", obj2.getName());
2392 error(errSyntaxError,
getPos(),
"XObject subtype is missing or wrong type");
2400 _POPPLER_FREE(obj2);
2401 _POPPLER_FREE(obj1);
2410 StreamColorSpaceMode csMode;
2414 Object maskObj, smaskObj;
2415 GBool haveColorKeyMask, haveExplicitMask, haveSoftMask;
2417 GBool maskInterpolate;
2422 csMode = streamCSNone;
2424 str->_POPPLER_GET_IMAGE_PARAMS(&bits, &csMode, &hasAlpha);
2427 dict = str->getDict();
2430 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Width");
2431 if (obj1.isNull()) {
2432 _POPPLER_FREE(obj1);
2433 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"W");
2436 width = obj1.getInt();
2438 else if (obj1.isReal()) {
2439 width = (int)obj1.getReal();
2444 _POPPLER_FREE(obj1);
2445 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Height");
2446 if (obj1.isNull()) {
2447 _POPPLER_FREE(obj1);
2448 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"H");
2453 else if (obj1.isReal()){
2454 height =
static_cast<int>(obj1.getReal());
2459 _POPPLER_FREE(obj1);
2462 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Interpolate");
2463 if (obj1.isNull()) {
2464 _POPPLER_FREE(obj1);
2465 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"I");
2468 interpolate = obj1.getBool();
2470 interpolate = gFalse;
2471 _POPPLER_FREE(obj1);
2472 maskInterpolate = gFalse;
2475 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"ImageMask");
2476 if (obj1.isNull()) {
2477 _POPPLER_FREE(obj1);
2478 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"IM");
2481 if (obj1.isBool()) {
2482 mask = obj1.getBool();
2484 else if (!obj1.isNull()) {
2487 _POPPLER_FREE(obj1);
2491 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"BitsPerComponent");
2492 if (obj1.isNull()) {
2493 _POPPLER_FREE(obj1);
2494 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"BPC");
2497 bits = obj1.getInt();
2503 _POPPLER_FREE(obj1);
2513 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Decode");
2514 if (obj1.isNull()) {
2515 _POPPLER_FREE(obj1);
2516 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"D");
2518 if (obj1.isArray()) {
2519 _POPPLER_CALL_ARGS(obj2, obj1.arrayGet, 0);
2520 if (obj2.isInt() && obj2.getInt() == 1) {
2523 _POPPLER_FREE(obj2);
2524 }
else if (!obj1.isNull()) {
2527 _POPPLER_FREE(obj1);
2534 std::unique_ptr<GfxColorSpace> colorSpace;
2535 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"ColorSpace");
2536 if (obj1.isNull()) {
2537 _POPPLER_FREE(obj1);
2538 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"CS");
2540 if (!obj1.isNull()) {
2542 }
else if (csMode == streamCSDeviceGray) {
2543 colorSpace = std::make_unique<GfxDeviceGrayColorSpace>();
2544 }
else if (csMode == streamCSDeviceRGB) {
2545 colorSpace = std::make_unique<GfxDeviceRGBColorSpace>();
2546 }
else if (csMode == streamCSDeviceCMYK) {
2547 colorSpace = std::make_unique<GfxDeviceCMYKColorSpace>();
2549 _POPPLER_FREE(obj1);
2553 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"Decode");
2554 if (obj1.isNull()) {
2555 _POPPLER_FREE(obj1);
2556 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"D");
2558 auto colorMap = std::make_unique<GfxImageColorMap>(bits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
2559 _POPPLER_FREE(obj1);
2560 if (!colorMap->isOk()) {
2565 int maskColors[2*gfxColorMaxComps];
2566 haveColorKeyMask = haveExplicitMask = haveSoftMask = gFalse;
2567 Stream *maskStr =
nullptr;
2570 maskInvert = gFalse;
2571 std::unique_ptr<GfxImageColorMap> maskColorMap;
2572 _POPPLER_CALL_ARGS(maskObj, dict->lookup,
"Mask");
2573 _POPPLER_CALL_ARGS(smaskObj, dict->lookup,
"SMask");
2575 if (smaskObj.isStream()) {
2580 maskStr = smaskObj.getStream();
2581 maskDict = smaskObj.streamGetDict();
2582 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Width");
2583 if (obj1.isNull()) {
2584 _POPPLER_FREE(obj1);
2585 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"W");
2587 if (!obj1.isInt()) {
2590 maskWidth = obj1.getInt();
2591 _POPPLER_FREE(obj1);
2592 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Height");
2593 if (obj1.isNull()) {
2594 _POPPLER_FREE(obj1);
2595 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"H");
2597 if (!obj1.isInt()) {
2600 maskHeight = obj1.getInt();
2601 _POPPLER_FREE(obj1);
2602 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"BitsPerComponent");
2603 if (obj1.isNull()) {
2604 _POPPLER_FREE(obj1);
2605 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"BPC");
2607 if (!obj1.isInt()) {
2610 int maskBits = obj1.getInt();
2611 _POPPLER_FREE(obj1);
2612 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Interpolate");
2613 if (obj1.isNull()) {
2614 _POPPLER_FREE(obj1);
2615 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"I");
2618 maskInterpolate = obj1.getBool();
2620 maskInterpolate = gFalse;
2621 _POPPLER_FREE(obj1);
2622 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"ColorSpace");
2623 if (obj1.isNull()) {
2624 _POPPLER_FREE(obj1);
2625 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"CS");
2628 _POPPLER_FREE(obj1);
2629 if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) {
2632 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Decode");
2633 if (obj1.isNull()) {
2634 _POPPLER_FREE(obj1);
2635 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"D");
2637 maskColorMap = std::make_unique<GfxImageColorMap>(maskBits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(maskColorSpace));
2638 _POPPLER_FREE(obj1);
2639 if (!maskColorMap->isOk()) {
2643 haveSoftMask = gTrue;
2644 }
else if (maskObj.isArray()) {
2647 for (i = 0; i < maskObj.arrayGetLength() && i < 2*gfxColorMaxComps; ++i) {
2648 _POPPLER_CALL_ARGS(obj1, maskObj.arrayGet, i);
2649 maskColors[i] = obj1.getInt();
2650 _POPPLER_FREE(obj1);
2652 haveColorKeyMask = gTrue;
2653 }
else if (maskObj.isStream()) {
2658 maskStr = maskObj.getStream();
2659 maskDict = maskObj.streamGetDict();
2660 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Width");
2661 if (obj1.isNull()) {
2662 _POPPLER_FREE(obj1);
2663 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"W");
2665 if (!obj1.isInt()) {
2668 maskWidth = obj1.getInt();
2669 _POPPLER_FREE(obj1);
2670 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Height");
2671 if (obj1.isNull()) {
2672 _POPPLER_FREE(obj1);
2673 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"H");
2675 if (!obj1.isInt()) {
2678 maskHeight = obj1.getInt();
2679 _POPPLER_FREE(obj1);
2680 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"ImageMask");
2681 if (obj1.isNull()) {
2682 _POPPLER_FREE(obj1);
2683 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"IM");
2685 if (!obj1.isBool() || !obj1.getBool()) {
2688 _POPPLER_FREE(obj1);
2689 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Interpolate");
2690 if (obj1.isNull()) {
2691 _POPPLER_FREE(obj1);
2692 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"I");
2695 maskInterpolate = obj1.getBool();
2697 maskInterpolate = gFalse;
2698 _POPPLER_FREE(obj1);
2699 maskInvert = gFalse;
2700 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"Decode");
2701 if (obj1.isNull()) {
2702 _POPPLER_FREE(obj1);
2703 _POPPLER_CALL_ARGS(obj1, maskDict->lookup,
"D");
2705 if (obj1.isArray()) {
2706 _POPPLER_CALL_ARGS(obj2, obj1.arrayGet, 0);
2707 if (obj2.isInt() && obj2.getInt() == 1) {
2710 _POPPLER_FREE(obj2);
2711 }
else if (!obj1.isNull()) {
2714 _POPPLER_FREE(obj1);
2715 haveExplicitMask = gTrue;
2721 maskStr, maskWidth, maskHeight, maskColorMap.get(), maskInterpolate);
2722 }
else if (haveExplicitMask) {
2724 maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate);
2727 haveColorKeyMask ? maskColors :
nullptr);
2730 _POPPLER_FREE(maskObj);
2731 _POPPLER_FREE(smaskObj);
2737 _POPPLER_FREE(obj1);
2739 error(errSyntaxError,
getPos(),
"Bad image parameters");
2745 GBool transpGroup, isolated, knockout;
2746 Object matrixObj, bboxObj;
2747 double m[6], bbox[4];
2750 Object obj1, obj2, obj3;
2759 dict = str->streamGetDict();
2762 _POPPLER_CALL_ARGS(obj1, dict->lookup,
"FormType");
2763 if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
2764 error(errSyntaxError,
getPos(),
"Unknown form type");
2766 _POPPLER_FREE(obj1);
2769 _POPPLER_CALL_ARGS(bboxObj, dict->lookup,
"BBox");
2770 if (!bboxObj.isArray()) {
2771 _POPPLER_FREE(bboxObj);
2772 error(errSyntaxError,
getPos(),
"Bad form bounding box");
2775 for (i = 0; i < 4; ++i) {
2776 _POPPLER_CALL_ARGS(obj1, bboxObj.arrayGet, i);
2777 bbox[i] = obj1.getNum();
2778 _POPPLER_FREE(obj1);
2780 _POPPLER_FREE(bboxObj);
2783 _POPPLER_CALL_ARGS(matrixObj, dict->lookup,
"Matrix");
2784 if (matrixObj.isArray()) {
2785 for (i = 0; i < 6; ++i) {
2786 _POPPLER_CALL_ARGS(obj1, matrixObj.arrayGet, i);
2787 m[i] = obj1.getNum();
2788 _POPPLER_FREE(obj1);
2798 _POPPLER_FREE(matrixObj);
2806 _POPPLER_CALL_ARGS(resObj, dict->lookup,
"Resources");
2807 resDict = resObj.isDict() ? resObj.getDict() : (Dict *)
nullptr;
2810 transpGroup = isolated = knockout = gFalse;
2811 std::unique_ptr<GfxColorSpace> blendingColorSpace;
2812 if (_POPPLER_CALL_ARGS_DEREF(obj1, dict->lookup,
"Group").isDict()) {
2813 if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup,
"S").isName(
"Transparency")) {
2814 transpGroup = gTrue;
2815 if (!_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup,
"CS").isNull()) {
2816 blendingColorSpace = std::unique_ptr<GfxColorSpace>(GfxColorSpace::parse(
nullptr, &obj3,
nullptr,
state));
2818 _POPPLER_FREE(obj3);
2819 if (_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup,
"I").isBool()) {
2820 isolated = obj3.getBool();
2822 _POPPLER_FREE(obj3);
2823 if (_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup,
"K").isBool()) {
2824 knockout = obj3.getBool();
2826 _POPPLER_FREE(obj3);
2828 _POPPLER_FREE(obj2);
2830 _POPPLER_FREE(obj1);
2834 doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace.get(), isolated, knockout);
2837 _POPPLER_FREE(resObj);
2841 GfxColorSpace *blendingColorSpace,
GBool isolated,
GBool knockout,
GBool alpha,
2842 Function *transferFunc, GfxColor *backdropColor)
2862 state->concatCTM(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
2865 state->moveTo(bbox[0], bbox[1]);
2866 state->lineTo(bbox[2], bbox[1]);
2867 state->lineTo(bbox[2], bbox[3]);
2868 state->lineTo(bbox[0], bbox[3]);
2874 if (softMask || transpGroup) {
2875 if (
state->getBlendMode() != gfxBlendNormal) {
2876 state->setBlendMode(gfxBlendNormal);
2878 if (
state->getFillOpacity() != 1) {
2880 state->setFillOpacity(1);
2882 if (
state->getStrokeOpacity() != 1) {
2883 state->setStrokeOpacity(1);
2924 int c1 = str->getUndecodedStream()->getChar();
2925 int c2 = str->getUndecodedStream()->getChar();
2926 while (!(c1 ==
'E' && c2 ==
'I') && c2 != EOF) {
2928 c2 = str->getUndecodedStream()->getChar();
2940#if defined(POPPLER_NEW_OBJECT_API)
2941 dict = Object(
new Dict(
xref));
2943 dict.initDict(
xref);
2945 _POPPLER_CALL(obj,
parser->getObj);
2946 while (!obj.isCmd(
const_cast<char*
>(
"ID")) && !obj.isEOF()) {
2947 if (!obj.isName()) {
2948 error(errSyntaxError,
getPos(),
"Inline image dictionary key must be a name object");
2952 _POPPLER_CALL(obj2,
parser->getObj);
2953 if (obj2.isEOF() || obj2.isError()) {
2957 _POPPLER_DICTADD(dict, obj.getName(), obj2);
2959 _POPPLER_FREE(obj2);
2961 _POPPLER_CALL(obj,
parser->getObj);
2964 error(errSyntaxError,
getPos(),
"End of file in inline image");
2966 _POPPLER_FREE(dict);
2972#if defined(POPPLER_NEW_OBJECT_API)
2973 str =
new EmbedStream(
parser->getStream(), dict.copy(), gFalse, 0);
2974 str = str->addFilters(dict.getDict());
2976 str =
new EmbedStream(
parser->getStream(), &dict, gFalse, 0);
2977 str = str->addFilters(&dict);
2985 error(errInternal,
getPos(),
"Internal: got 'ID' operator");
2990 error(errInternal,
getPos(),
"Internal: got 'EI' operator");
3028 printf(
" marked content: %s ", args[0].getName());
3030 args[2].print(stdout);
3034 if (numArgs == 2 && args[1].isName()) {
3050 printf(
" mark point: %s ", args[0].getName());
3052 args[2].print(stdout);
3070 bool is_radial =
false;
3071 GfxPattern *pattern =
state->getFillPattern();
3073 if (pattern && pattern->getType() == 2) {
3074 GfxShadingPattern *shading_pattern =
static_cast<GfxShadingPattern *
>(pattern);
3075 GfxShading *shading = shading_pattern->getShading();
3076 if (shading->getType() == 3)
3097 GfxResources *resPtr;
3099 resPtr =
res->getNext();
3105 for (
int i = 1; i <= pdfNumShadingTypes; ++i) {
3113 if (shadingType > pdfNumShadingTypes || shadingType < 1) {
3116 colorDeltas[shadingType-1] = dblToCol(colorDelta);
3129 auto props = resources->lookup(
"Properties");
3130 if (!
props.isDict())
3134 auto ocgs = cat->getOptContentConfig();
3135 auto dict =
props.getDict();
3137 for (
auto j = 0; j < dict->getLength(); j++) {
3138 auto val = dict->getVal(j);
3141 auto dict2 = val.getDict();
3142 if (dict2->lookup(
"Type").isName(
"OCG") && ocgs) {
3147 for (
auto &[
ref, ocg] : ocgs->getOCGs()) {
3148 if (ocg->getName()->cmp(
label) == 0)
3149 visible = ocg->getState() == OptionalContentGroup::On;
3161 Object catDict =
xref->getCatalog();
3162 if (!catDict.isDict())
3165 Object outputIntents = catDict.dictLookup(
"OutputIntents");
3166 if (!outputIntents.isArray() || outputIntents.arrayGetLength() != 1)
3169 Object firstElement = outputIntents.arrayGet(0);
3170 if (!firstElement.isDict())
3173 Object profile = firstElement.dictLookup(
"DestOutputProfile");
3174 if (!profile.isStream())
3177 Stream *iccStream = profile.getStream();
3178#if POPPLER_CHECK_VERSION(22, 4, 0)
3179 std::vector<unsigned char> profBuf = iccStream->toUnsignedChars(65536, 65536);
3183 unsigned char *profBuf = iccStream->toUnsignedChars(&length, 65536, 65536);
3190 Object AP_obj, N_obj, Rect_obj, xy_obj, first_state_obj;
3195 if (!annot.isDict())
3197 annot_dict = annot.getDict();
3199 _POPPLER_CALL_ARGS(AP_obj, annot_dict->lookup,
"AP");
3201 if (AP_obj.isDict()) {
3202 _POPPLER_CALL_ARGS(N_obj, AP_obj.getDict()->lookup,
"N");
3203 if (N_obj.isDict()) {
3205 _POPPLER_CALL_ARGS(first_state_obj, N_obj.getDict()->getVal, 0);
3208 first_state_obj = N_obj.copy();
3210 if (first_state_obj.isStream()) {
3211 current_node =
builder->
beginLayer(std::to_string(page_num) +
" - Annotations",
true);
3212 _POPPLER_CALL_ARGS(Rect_obj, annot_dict->lookup,
"Rect");
3213 if (Rect_obj.isArray()) {
3214 for (
int i = 0; i < 2; i++) {
3215 _POPPLER_CALL_ARGS(xy_obj, Rect_obj.arrayGet, i);
3216 offset[i] = xy_obj.getNum();
3222 _POPPLER_FREE(AP_obj);
3223 _POPPLER_FREE(N_obj);
3224 _POPPLER_FREE(Rect_obj);
3225 _POPPLER_FREE(xy_obj);
3226 _POPPLER_FREE(first_state_obj);
3229 error(errInternal, -1,
"No inkscape handler for this annotation type");
static bool cmp(std::pair< Glib::ustring, Glib::ustring > const &a, std::pair< Glib::ustring, Glib::ustring > const &b)
Compare function.
static SPStyleProp const props[]
Lookup dictionary for attributes/properties.
Affine inverse() const
Compute the inverse matrix.
Builds the inner SVG representation using libpoppler from the calls of PdfParser.
void updateTextShift(GfxState *state, double shift)
Shifts the current text position by the given amount (specified in text space)
void updateTextMatrix(GfxState *state, bool flip)
Flushes the buffered characters.
void endTextObject(GfxState *state)
void beginTextObject(GfxState *state)
These text object functions are the outer most calls for begining and ending text.
void updateTextPosition(double tx, double ty)
Updates current text position.
void setDocumentSize(double width, double height)
void cropPage(const Geom::Rect &bbox)
Crop to this bounding box, do this before setMargins() but after setDocumentSize.
void addImageMask(GfxState *state, Stream *str, int width, int height, bool invert, bool interpolate)
void restoreState(GfxState *state)
void setClip(GfxState *state, GfxClipType clip, bool is_bbox=false)
Clips to the current path set in GfxState.
void setMetadata(char const *name, const std::string &content)
void addColorProfile(unsigned char *profBuf, int length)
void beginMarkedContent(const char *name=nullptr, const char *group=nullptr)
void setGroupOpacity(double opacity)
Sets the current container's opacity.
void saveState(GfxState *state)
bool isPatternTypeSupported(GfxPattern *pattern)
Checks whether the given pattern type can be represented in SVG Used by PdfParser to decide when to d...
void endLayer(Inkscape::XML::Node *save)
void addOptionalGroup(const std::string &oc, const std::string &label, bool visible=true)
void addSoftMaskedImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *color_map, bool interpolate, Stream *mask_str, int mask_width, int mask_height, GfxImageColorMap *mask_color_map, bool mask_interpolate)
void updateStyle(GfxState *state)
Sets _invalidated_style to true to indicate that styles have to be updated Used for text output when ...
void addPath(GfxState *state, bool fill, bool stroke, bool even_odd=false)
Emits the current path in poppler's GfxState data structure Can be used to do filling and stroking at...
void addClippedFill(GfxShading *shading, const Geom::Affine shading_tr)
void updateFont(GfxState *state, std::shared_ptr< CairoFont > cairo_font, bool flip)
Updates _css_font according to the font set in parameter state.
void setMargins(const Geom::Rect &page, const Geom::Rect &margins, const Geom::Rect &bleed)
Calculate the page margin size based on the pdf settings.
void addImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *color_map, bool interpolate, int *mask_colors)
void beforeStateChange(GfxState *old_state)
Notifies the svg builder the state will change.
void endString(GfxState *state)
void addMaskedImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *color_map, bool interpolate, Stream *mask_str, int mask_width, int mask_height, bool invert_mask, bool mask_interpolate)
void pushPage(const std::string &label, GfxState *state)
We're creating a multi-page document, push page number.
void addChar(GfxState *state, double x, double y, double dx, double dy, double ax, double ay, double originX, double originY, CharCode code, int nBytes, Unicode const *u, int uLen)
Adds the specified character to the text buffer Takes care of converting it to UTF-8 and generates a ...
Inkscape::XML::Node * beginLayer(const std::string &label, bool visible)
void beginString(GfxState *state, int len)
Begin and end string is the inner most text processing step which tells us we're about to have a cert...
void finishGroup(GfxState *state, bool for_softmask)
void startGroup(GfxState *state, double *bbox, GfxColorSpace *blending_color_space, bool isolated, bool knockout, bool for_softmask)
Starts building a new transparency group.
Interface for refcounted XML nodes.
void opMarkPoint(Object args[], int numArgs)
std::unique_ptr< GfxPattern > lookupPattern(Object *obj, GfxState *state)
Look up pattern/gradients from the GfxResource dictionary.
void build_annots(const Object &annot, int page_num)
void opSetFillColorSpace(Object args[], int numArgs)
void doPatternStrokeFallback()
void opSetTextMatrix(Object args[], int numArgs)
void opSetHorizScaling(Object args[], int numArgs)
std::map< std::string, std::unique_ptr< GfxColorSpace > > colorSpacesCache
Caches color spaces by name.
void doGouraudTriangleShFill(GfxGouraudTriangleShading *shading)
void opSetMiterLimit(Object args[], int numArgs)
void opShowSpaceText(Object args[], int numArgs)
void opSetLineJoin(Object args[], int numArgs)
void doPatternFillFallback(GBool eoFill)
void doForm(Object *str, double *offset=nullptr)
void opCloseStroke(Object args[], int numArgs)
void doSoftMask(Object *str, GBool alpha, GfxColorSpace *blendingColorSpace, GBool isolated, GBool knockout, Function *transferFunc, GfxColor *backdropColor)
void opEndText(Object args[], int numArgs)
int colorDeltas[pdfNumShadingTypes]
void opSetStrokeColor(Object args[], int numArgs)
void opSetCharSpacing(Object args[], int numArgs)
void execOp(Object *cmd, Object args[], int numArgs)
void opSetFillCMYKColor(Object args[], int numArgs)
void doPatchMeshShFill(GfxPatchMeshShading *shading)
void opFillStroke(Object args[], int numArgs)
GBool checkArg(Object *arg, TchkType type)
void doFillAndStroke(GBool eoFill)
void opBeginMarkedContent(Object args[], int numArgs)
void opSetFillGray(Object args[], int numArgs)
std::shared_ptr< PDFDoc > _pdf_doc
std::shared_ptr< CairoFontEngine > getFontEngine()
void opSetStrokeColorN(Object args[], int numArgs)
void gouraudFillTriangle(double x0, double y0, GfxColor *color0, double x1, double y1, GfxColor *color1, double x2, double y2, GfxColor *color2, int nComps, int depth)
void opCurveTo(Object args[], int numArgs)
void loadOptionalContentLayers(Dict *resources)
void opMoveShowText(Object args[], int numArgs)
void opSetFillColorN(Object args[], int numArgs)
void opEOClip(Object args[], int numArgs)
void pushResources(Dict *resDict)
void opSetRenderingIntent(Object args[], int numArgs)
void doShadingPatternFillFallback(GfxShadingPattern *sPat, GBool stroke, GBool eoFill)
void opTextMove(Object args[], int numArgs)
void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox, GBool transpGroup=gFalse, GBool softMask=gFalse, GfxColorSpace *blendingColorSpace=nullptr, GBool isolated=gFalse, GBool knockout=gFalse, GBool alpha=gFalse, Function *transferFunc=nullptr, GfxColor *backdropColor=nullptr)
void opTextMoveSet(Object args[], int numArgs)
void opBeginImage(Object args[], int numArgs)
void opShowText(Object args[], int numArgs)
void opSetLineCap(Object args[], int numArgs)
void opCloseFillStroke(Object args[], int numArgs)
void opRestore(Object args[], int numArgs)
PdfOperator * findOp(const char *name)
PdfParser(std::shared_ptr< PDFDoc > pdf_doc, SvgBuilder *builderA, Page *page, _POPPLER_CONST PDFRectangle *cropBox)
void opConcat(Object args[], int numArgs)
Concatenate transformation matrix to the current state.
void opBeginIgnoreUndef(Object args[], int numArgs)
void opSetDash(Object args[], int numArgs)
void opSave(Object args[], int numArgs)
void opSetFillColor(Object args[], int numArgs)
std::unique_ptr< GfxColorSpace > lookupColorSpaceCopy(Object &)
Get a newly allocated color space instance by CS operation argument.
std::shared_ptr< CairoFontEngine > _font_engine
void opSetTextRise(Object args[], int numArgs)
void opBeginText(Object args[], int numArgs)
void opMoveTo(Object args[], int numArgs)
void opCurveTo2(Object args[], int numArgs)
void opSetStrokeRGBColor(Object args[], int numArgs)
const char * getPreviousOperator(unsigned int look_back=1)
OpHistoryEntry * operatorHistory
void opRectangle(Object args[], int numArgs)
void opSetTextLeading(Object args[], int numArgs)
void opClip(Object args[], int numArgs)
void opSetCharWidth(Object args[], int numArgs)
void opCloseEOFillStroke(Object args[], int numArgs)
void doFunctionShFill(GfxFunctionShading *shading)
void doFunctionShFill1(GfxFunctionShading *shading, double x0, double y0, double x1, double y1, GfxColor *colors, int depth)
void doImage(Object *ref, Stream *str, GBool inlineImg)
void opSetFlat(Object args[], int numArgs)
void opSetTextRender(Object args[], int numArgs)
void opTextNextLine(Object args[], int numArgs)
void pushOperator(const char *name)
void opSetStrokeCMYKColor(Object args[], int numArgs)
void opStroke(Object args[], int numArgs)
void opSetFont(Object args[], int numArgs)
void opEndIgnoreUndef(Object args[], int numArgs)
void opSetLineWidth(Object args[], int numArgs)
void opEndPath(Object args[], int numArgs)
void opClosePath(Object args[], int numArgs)
void opSetCacheDevice(Object args[], int numArgs)
void opCurveTo1(Object args[], int numArgs)
void opSetFillRGBColor(Object args[], int numArgs)
void opImageData(Object args[], int numArgs)
void fillPatch(_POPPLER_CONST GfxPatch *patch, int nComps, int depth)
void opSetStrokeColorSpace(Object args[], int numArgs)
void opMoveSetShowText(Object args[], int numArgs)
void setApproximationPrecision(int shadingType, double colorDelta, int maxDepth)
void opEOFillStroke(Object args[], int numArgs)
void opShFill(Object args[], int numArgs)
void opEOFill(Object args[], int numArgs)
void opEndMarkedContent(Object args[], int numArgs)
void opXObject(Object args[], int numArgs)
Stream * buildImageStream()
void opSetExtGState(Object args[], int numArgs)
void setDefaultApproximationPrecision()
void parse(Object *obj, GBool topLevel=gTrue)
void doShowText(const GooString *s)
void opLineTo(Object args[], int numArgs)
static PdfOperator opTab[]
void opFill(Object args[], int numArgs)
void opSetStrokeGray(Object args[], int numArgs)
void opEndImage(Object args[], int numArgs)
int maxDepths[pdfNumShadingTypes]
void opSetWordSpacing(Object args[], int numArgs)
static T clip(T const &v, T const &a, T const &b)
Geom::Rect getRect(_POPPLER_CONST PDFRectangle *box)
Geom::Affine stateToAffine(GfxState *state)
Get the default transformation state from the GfxState.
std::string getString(const std::unique_ptr< GooString > &value)
std::string getDictString(Dict *dict, const char *key)
Get a string from a dictionary.
Geom::Affine ctmToAffine(const double *ctm)
Convert a transformation matrix to a lib2geom affine object.
void invert(const double v[16], double alpha[16])
void(PdfParser::* func)(Object args[], int numArgs)
TchkType tchk[maxOperatorArgs]
Glib::RefPtr< Gtk::Builder > builder