28
28
// Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
29
29
// Copyright (C) 2012, 2015 Tobias Koenig <tokoe@kdab.com>
30
30
// Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
31
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
31
// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
32
32
// Copyright (C) 2014, 2015 Marek Kasik <mkasik@redhat.com>
33
33
// Copyright (C) 2014 Jiri Slaby <jirislaby@gmail.com>
34
34
// Copyright (C) 2014 Anuj Khare <khareanuj18@gmail.com>
35
35
// Copyright (C) 2015 Petr Gajdos <pgajdos@suse.cz>
36
36
// Copyright (C) 2015 Philipp Reinkemeier <philipp.reinkemeier@offis.de>
37
37
// Copyright (C) 2015 Tamas Szekeres <szekerest@gmail.com>
38
// Copyright (C) 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
39
40
// To see a description of the changes please see the Changelog file that
40
41
// came with your tarball or type make ChangeLog if you are building from git
181
182
type = annotExternalDataMarkupUnknown;
188
PDFRectangle *parseDiffRectangle(Array *array, PDFRectangle *rect) {
188
static PDFRectangle *parseDiffRectangle(Array *array, PDFRectangle *rect) {
189
189
PDFRectangle *newRect = NULL;
190
190
if (array->getLength() == 4) {
193
double dx1 = (array->get(0, &obj1)->isNum() ? obj1.getNum() : 0);
195
double dy1 = (array->get(1, &obj1)->isNum() ? obj1.getNum() : 0);
197
double dx2 = (array->get(2, &obj1)->isNum() ? obj1.getNum() : 0);
199
double dy2 = (array->get(3, &obj1)->isNum() ? obj1.getNum() : 0);
193
double dx1 = (obj1 = array->get(0), obj1.isNum() ? obj1.getNum() : 0);
194
double dy1 = (obj1 = array->get(1), obj1.isNum() ? obj1.getNum() : 0);
195
double dx2 = (obj1 = array->get(2), obj1.isNum() ? obj1.getNum() : 0);
196
double dy2 = (obj1 = array->get(3), obj1.isNum() ? obj1.getNum() : 0);
202
198
// checking that the numbers are valid (i.e. >= 0),
203
199
// and that applying the differences still give us a valid rect
230
226
type == Annot::actionPageVisible ? "PV" :
231
227
type == Annot::actionPageInvisible ? "PI" : NULL);
235
if (additionalActionsObject.dictLookup(key, &actionObject)->isDict())
229
Object actionObject = additionalActionsObject.dictLookup(key);
230
if (actionObject.isDict())
236
231
linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI());
240
additionalActionsObject.free();
242
234
return linkAction;
245
237
static LinkAction* getFormAdditionalAction(Annot::FormAdditionalActionsType type, Object *additionalActions, PDFDoc *doc) {
246
Object additionalActionsObject;
247
LinkAction *linkAction = NULL;
238
LinkAction *linkAction = nullptr;
239
Object additionalActionsObject = additionalActions->fetch(doc->getXRef());
249
if (additionalActions->fetch(doc->getXRef(), &additionalActionsObject)->isDict()) {
241
if (additionalActionsObject.isDict()) {
250
242
const char *key = (type == Annot::actionFieldModified ? "K" :
251
243
type == Annot::actionFormatField ? "F" :
252
244
type == Annot::actionValidateField ? "V" :
253
245
type == Annot::actionCalculateField ? "C" : NULL);
257
if (additionalActionsObject.dictLookup(key, &actionObject)->isDict())
247
Object actionObject = additionalActionsObject.dictLookup(key);
248
if (actionObject.isDict())
258
249
linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI());
262
additionalActionsObject.free();
264
252
return linkAction;
709
void AnnotBorderBS::writeToObject(XRef *xref, Object *obj1) const {
712
obj1->initDict(xref);
713
obj1->dictSet("W", obj2.initReal(width));
714
obj1->dictSet("S", obj2.initName(getStyleName()));
691
Object AnnotBorderBS::writeToObject(XRef *xref) const {
692
Dict *dict = new Dict(xref);
693
dict->set("W", Object(width));
694
dict->set("S", Object(objName, getStyleName()));
715
695
if (style == borderDashed && dashLength > 0) {
696
Array *a = new Array(xref);
718
obj1->dictSet("D", obj3.initArray(xref));
719
698
for (int i = 0; i < dashLength; i++)
720
obj3.arrayAdd(obj2.initReal(dash[i]));
699
a->add(Object(dash[i]));
700
dict->set("D", Object(a));
724
705
//------------------------------------------------------------------------
881
856
assert(dict->isDict());
883
858
xref = docA->getXRef();
884
dict->copy(&appearDict);
859
appearDict = dict->copy();
887
862
AnnotAppearance::~AnnotAppearance() {
891
void AnnotAppearance::getAppearanceStream(AnnotAppearanceType type, const char *state, Object *dest) {
892
Object apData, stream;
865
Object AnnotAppearance::getAppearanceStream(AnnotAppearanceType type, const char *state) {
895
868
// Obtain dictionary or stream associated to appearance type
897
870
case appearRollover:
898
if (appearDict.dictLookupNF("R", &apData)->isNull())
899
appearDict.dictLookupNF("N", &apData);
871
apData = appearDict.dictLookupNF("R");
873
apData = appearDict.dictLookupNF("N");
902
if (appearDict.dictLookupNF("D", &apData)->isNull())
903
appearDict.dictLookupNF("N", &apData);
876
apData = appearDict.dictLookupNF("D");
878
apData = appearDict.dictLookupNF("N");
905
880
case appearNormal:
906
appearDict.dictLookupNF("N", &apData);
881
apData = appearDict.dictLookupNF("N");
911
886
if (apData.isDict() && state)
912
apData.dictLookupNF(state, dest);
887
res = apData.dictLookupNF(state);
913
888
else if (apData.isRef())
918
894
GooString * AnnotAppearance::getStateKey(int i) {
920
895
GooString * res = NULL;
921
if (appearDict.dictLookupNF("N", &obj1)->isDict())
896
Object obj1 = appearDict.dictLookupNF("N");
922
898
res = new GooString(obj1.dictGetKey(i));
927
902
int AnnotAppearance::getNumStates() {
930
if (appearDict.dictLookupNF("N", &obj1)->isDict())
904
Object obj1 = appearDict.dictLookupNF("N");
931
906
res = obj1.dictGetLength();
1011
980
} else if (obj1->isDict()) {
1012
981
const int size = obj1->dictGetLength();
1013
982
for (int i = 0; i < size; ++i) {
1015
obj1->dictGetValNF(i, &obj2);
983
Object obj2 = obj1->dictGetValNF(i);
1016
984
if (obj2.isRef()) {
1017
985
removeStream(obj2.getRef());
1024
991
void AnnotAppearance::removeAllStreams() {
1026
appearDict.dictLookupNF("N", &obj1);
1027
removeStateStreams(&obj1);
1029
appearDict.dictLookupNF("R", &obj1);
1030
removeStateStreams(&obj1);
1032
appearDict.dictLookupNF("D", &obj1);
1033
removeStateStreams(&obj1);
993
obj1 = appearDict.dictLookupNF("N");
994
removeStateStreams(&obj1);
995
obj1 = appearDict.dictLookupNF("R");
996
removeStateStreams(&obj1);
997
obj1 = appearDict.dictLookupNF("D");
998
removeStateStreams(&obj1);
1037
1001
//------------------------------------------------------------------------
1071
1036
backColor = NULL;
1075
if (dict->lookup("CA", &obj1)->isString()) {
1039
obj1 = dict->lookup("CA");
1040
if (obj1.isString()) {
1076
1041
normalCaption = new GooString(obj1.getString());
1078
1043
normalCaption = NULL;
1082
if (dict->lookup("RC", &obj1)->isString()) {
1046
obj1 = dict->lookup("RC");
1047
if (obj1.isString()) {
1083
1048
rolloverCaption = new GooString(obj1.getString());
1085
1050
rolloverCaption = NULL;
1089
if (dict->lookup("AC", &obj1)->isString()) {
1053
obj1 = dict->lookup("AC");
1054
if (obj1.isString()) {
1090
1055
alternateCaption = new GooString(obj1.getString());
1092
1057
alternateCaption = NULL;
1096
if (dict->lookup("IF", &obj1)->isDict()) {
1060
obj1 = dict->lookup("IF");
1061
if (obj1.isDict()) {
1097
1062
iconFit = new AnnotIconFit(obj1.getDict());
1099
1064
iconFit = NULL;
1103
if (dict->lookup("TP", &obj1)->isInt()) {
1067
obj1 = dict->lookup("TP");
1104
1069
position = (AnnotAppearanceCharacsTextPos) obj1.getInt();
1106
1071
position = captionNoIcon;
1111
1075
AnnotAppearanceCharacs::~AnnotAppearanceCharacs() {
1185
1149
//------------------------------------------------------------------------
1187
1151
Annot::Annot(PDFDoc *docA, PDFRectangle *rectA) {
1191
1154
flags = flagUnknown;
1192
1155
type = typeUnknown;
1194
obj1.initArray (docA->getXRef());
1196
obj1.arrayAdd (obj2.initReal (rectA->x1));
1197
obj1.arrayAdd (obj2.initReal (rectA->y1));
1198
obj1.arrayAdd (obj2.initReal (rectA->x2));
1199
obj1.arrayAdd (obj2.initReal (rectA->y2));
1157
Array *a = new Array(docA->getXRef());
1158
a->add(Object(rectA->x1));
1159
a->add(Object(rectA->y1));
1160
a->add(Object(rectA->x2));
1161
a->add(Object(rectA->y2));
1202
annotObj.initDict (docA->getXRef());
1203
annotObj.dictSet ("Type", obj2.initName ("Annot"));
1204
annotObj.dictSet ("Rect", &obj1);
1205
// obj1 is owned by the dict
1163
annotObj = Object(new Dict(docA->getXRef()));
1164
annotObj.dictSet ("Type", Object(objName, "Annot"));
1165
annotObj.dictSet ("Rect", Object(a));
1207
1167
ref = docA->getXRef()->addIndirectObject (&annotObj);
1209
1169
initialize (docA, annotObj.getDict());
1212
Annot::Annot(PDFDoc *docA, Dict *dict) {
1172
Annot::Annot(PDFDoc *docA, Object *dictObject) {
1214
1174
hasRef = false;
1215
1175
flags = flagUnknown;
1216
1176
type = typeUnknown;
1217
annotObj.initDict (dict);
1218
initialize (docA, dict);
1177
annotObj = dictObject->copy();
1178
initialize (docA, dictObject->getDict());
1221
Annot::Annot(PDFDoc *docA, Dict *dict, Object *obj) {
1181
Annot::Annot(PDFDoc *docA, Object *dictObject, Object *obj) {
1223
1183
if (obj->isRef()) {
1224
1184
hasRef = gTrue;
1244
1204
appearBuf = NULL;
1247
appearance.initNull();
1207
appearance.setToNull();
1249
1209
//----- parse the rectangle
1250
1210
rect = new PDFRectangle();
1251
if (dict->lookup("Rect", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
1211
obj1 = dict->lookup("Rect");
1212
if (obj1.isArray() && obj1.arrayGetLength() == 4) {
1253
(obj1.arrayGet(0, &obj2)->isNum() ? rect->x1 = obj2.getNum() : rect->x1 = 0);
1255
(obj1.arrayGet(1, &obj2)->isNum() ? rect->y1 = obj2.getNum() : rect->y1 = 0);
1257
(obj1.arrayGet(2, &obj2)->isNum() ? rect->x2 = obj2.getNum() : rect->x2 = 1);
1259
(obj1.arrayGet(3, &obj2)->isNum() ? rect->y2 = obj2.getNum() : rect->y2 = 1);
1214
(obj2 = obj1.arrayGet(0), obj2.isNum() ? rect->x1 = obj2.getNum() : rect->x1 = 0);
1215
(obj2 = obj1.arrayGet(1), obj2.isNum() ? rect->y1 = obj2.getNum() : rect->y1 = 0);
1216
(obj2 = obj1.arrayGet(2), obj2.isNum() ? rect->x2 = obj2.getNum() : rect->x2 = 1);
1217
(obj2 = obj1.arrayGet(3), obj2.isNum() ? rect->y2 = obj2.getNum() : rect->y2 = 1);
1262
1219
if (rect->x1 > rect->x2) {
1263
1220
double t = rect->x1;
1276
1233
error(errSyntaxError, -1, "Bad bounding box for annotation");
1281
if (dict->lookup("Contents", &obj1)->isString()) {
1237
obj1 = dict->lookup("Contents");
1238
if (obj1.isString()) {
1282
1239
contents = obj1.getString()->copy();
1284
1241
contents = new GooString();
1288
1244
// Note: This value is overwritten by Annots ctor
1289
if (dict->lookupNF("P", &obj1)->isRef()) {
1245
obj1 = dict->lookupNF("P");
1290
1247
Ref ref = obj1.getRef();
1292
1249
page = doc->getCatalog()->findPage (ref.num, ref.gen);
1298
if (dict->lookup("NM", &obj1)->isString()) {
1254
obj1 = dict->lookup("NM");
1255
if (obj1.isString()) {
1299
1256
name = obj1.getString()->copy();
1305
if (dict->lookup("M", &obj1)->isString()) {
1261
obj1 = dict->lookup("M");
1262
if (obj1.isString()) {
1306
1263
modified = obj1.getString()->copy();
1308
1265
modified = NULL;
1312
1268
//----- get the flags
1313
if (dict->lookup("F", &obj1)->isInt()) {
1269
obj1 = dict->lookup("F");
1314
1271
flags |= obj1.getInt();
1316
1273
flags = flagUnknown;
1320
1276
//----- get the annotation appearance dictionary
1321
dict->lookup("AP", &apObj);
1277
apObj = dict->lookup("AP");
1322
1278
if (apObj.isDict()) {
1323
1279
appearStreams = new AnnotAppearance(doc, &apObj);
1327
1282
//----- get the appearance state
1328
dict->lookup("AS", &asObj);
1283
asObj = dict->lookup("AS");
1329
1284
if (asObj.isName()) {
1330
1285
appearState = new GooString(asObj.getName());
1331
1286
} else if (appearStreams && appearStreams->getNumStates() != 0) {
1804
1728
appearBuf->append("S\n");
1807
void Annot::createForm(double *bbox, GBool transparencyGroup, Object *resDict, Object *aStream) {
1731
Object Annot::createForm(double *bbox, GBool transparencyGroup, Dict *resDict) {
1732
Dict *appearDict = new Dict(xref);
1733
appearDict->set("Length", Object(appearBuf->getLength()));
1734
appearDict->set("Subtype", Object(objName, "Form"));
1811
appearDict.initDict(xref);
1812
appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
1813
appearDict.dictSet("Subtype", obj1.initName("Form"));
1814
obj1.initArray(xref);
1815
obj1.arrayAdd(obj2.initReal(bbox[0]));
1816
obj1.arrayAdd(obj2.initReal(bbox[1]));
1817
obj1.arrayAdd(obj2.initReal(bbox[2]));
1818
obj1.arrayAdd(obj2.initReal(bbox[3]));
1819
appearDict.dictSet("BBox", &obj1);
1736
Array *a = new Array(xref);
1737
a->add(Object(bbox[0]));
1738
a->add(Object(bbox[1]));
1739
a->add(Object(bbox[2]));
1740
a->add(Object(bbox[3]));
1741
appearDict->set("BBox", Object(a));
1820
1742
if (transparencyGroup) {
1822
transDict.initDict(xref);
1823
transDict.dictSet("S", obj1.initName("Transparency"));
1824
appearDict.dictSet("Group", &transDict);
1743
Dict *d = new Dict(xref);
1744
d->set("S", Object(objName, "Transparency"));
1745
appearDict->set("Group", Object(d));
1827
appearDict.dictSet("Resources", resDict);
1748
appearDict->set("Resources", Object(resDict));
1829
1750
MemStream *mStream = new MemStream(copyString(appearBuf->getCString()), 0,
1830
appearBuf->getLength(), &appearDict);
1751
appearBuf->getLength(), Object(appearDict));
1831
1752
mStream->setNeedFree(gTrue);
1832
aStream->initStream(mStream);
1753
return Object(static_cast<Stream*>(mStream));
1835
void Annot::createResourcesDict(const char *formName, Object *formStream,
1756
Dict *Annot::createResourcesDict(const char *formName, Object &&formStream,
1836
1757
const char *stateName,
1837
double opacity, const char *blendMode,
1839
Object gsDict, stateDict, formDict, obj1;
1841
gsDict.initDict(xref);
1758
double opacity, const char *blendMode) {
1759
Dict *gsDict = new Dict(xref);
1842
1760
if (opacity != 1) {
1843
gsDict.dictSet("CA", obj1.initReal(opacity));
1844
gsDict.dictSet("ca", obj1.initReal(opacity));
1761
gsDict->set("CA", Object(opacity));
1762
gsDict->set("ca", Object(opacity));
1847
gsDict.dictSet("BM", obj1.initName(blendMode));
1848
stateDict.initDict(xref);
1849
stateDict.dictSet(stateName, &gsDict);
1850
formDict.initDict(xref);
1851
formDict.dictSet(formName, formStream);
1853
resDict->initDict(xref);
1854
resDict->dictSet("ExtGState", &stateDict);
1855
resDict->dictSet("XObject", &formDict);
1765
gsDict->set("BM", Object(objName, blendMode));
1766
Dict *stateDict = new Dict(xref);
1767
stateDict->set(stateName, Object(gsDict));
1768
Dict *formDict = new Dict(xref);
1769
formDict->set(formName, std::move(formStream));
1771
Dict *resDict = new Dict(xref);
1772
resDict->set("ExtGState", Object(stateDict));
1773
resDict->set("XObject", Object(formDict));
1858
Object *Annot::getAppearanceResDict(Object *dest) {
1778
Object Annot::getAppearanceResDict() {
1859
1779
Object obj1, obj2;
1861
dest->initNull(); // Default value
1863
1781
// Fetch appearance's resource dict (if any)
1864
appearance.fetch(xref, &obj1);
1782
obj1 = appearance.fetch(xref);
1865
1783
if (obj1.isStream()) {
1866
obj1.streamGetDict()->lookup("Resources", &obj2);
1784
obj2 = obj1.streamGetDict()->lookup("Resources");
1867
1785
if (obj2.isDict()) {
1790
return Object(objNull);
1877
1793
GBool Annot::isVisible(GBool printing) {
1929
1842
type = typePopup;
1931
annotObj.dictSet ("Subtype", obj1.initName ("Popup"));
1844
annotObj.dictSet ("Subtype", Object(objName, "Popup"));
1932
1845
initialize (docA, annotObj.getDict());
1935
AnnotPopup::AnnotPopup(PDFDoc *docA, Dict *dict, Object *obj) :
1936
Annot(docA, dict, obj) {
1848
AnnotPopup::AnnotPopup(PDFDoc *docA, Object *dictObject, Object *obj) :
1849
Annot(docA, dictObject, obj) {
1937
1850
type = typePopup;
1938
initialize(docA, dict);
1851
initialize(docA, dictObject->getDict());
1941
1854
AnnotPopup::~AnnotPopup() {
1945
1857
void AnnotPopup::initialize(PDFDoc *docA, Dict *dict) {
1948
if (!dict->lookupNF("Parent", &parent)->isRef()) {
1858
parent = dict->lookupNF("Parent");
1859
if (!parent.isRef()) {
1952
if (dict->lookup("Open", &obj1)->isBool()) {
1863
Object obj1 = dict->lookup("Open");
1864
if (obj1.isBool()) {
1953
1865
open = obj1.getBool();
1960
1871
void AnnotPopup::setParent(Object *parentA) {
1961
parentA->copy(&parent);
1962
update ("Parent", &parent);
1872
update ("Parent", parentA->copy());
1965
1875
void AnnotPopup::setParent(Annot *parentA) {
1966
Ref parentRef = parentA->getRef();
1967
parent.initRef(parentRef.num, parentRef.gen);
1968
update ("Parent", &parent);
1876
const Ref parentRef = parentA->getRef();
1877
update ("Parent", Object(parentRef.num, parentRef.gen));
1971
1880
void AnnotPopup::setOpen(GBool openA) {
1975
obj1.initBool(open);
1976
update ("Open", &obj1);
1882
update ("Open", Object(open));
1979
1885
//------------------------------------------------------------------------
2006
1912
void AnnotMarkup::initialize(PDFDoc *docA, Dict *dict, Object *obj) {
2007
1913
Object obj1, obj2;
2009
if (dict->lookup("T", &obj1)->isString()) {
1915
obj1 = dict->lookup("T");
1916
if (obj1.isString()) {
2010
1917
label = obj1.getString()->copy();
2016
if (dict->lookup("Popup", &obj1)->isDict() && dict->lookupNF("Popup", &obj2)->isRef()) {
2017
popup = new AnnotPopup(docA, obj1.getDict(), &obj2);
1922
obj1 = dict->lookup("Popup");
1923
obj2 = dict->lookupNF("Popup");
1924
if (obj1.isDict() && obj2.isRef()) {
1925
popup = new AnnotPopup(docA, &obj1, &obj2);
2023
if (dict->lookup("CA", &obj1)->isNum()) {
1930
obj1 = dict->lookup("CA");
2024
1932
opacity = obj1.getNum();
2030
if (dict->lookup("CreationDate", &obj1)->isString()) {
1937
obj1 = dict->lookup("CreationDate");
1938
if (obj1.isString()) {
2031
1939
date = obj1.getString()->copy();
2037
if (dict->lookupNF("IRT", &obj1)->isRef()) {
1944
obj1 = dict->lookupNF("IRT");
2038
1946
inReplyTo = obj1.getRef();
2040
1948
inReplyTo.num = 0;
2041
1949
inReplyTo.gen = 0;
2045
if (dict->lookup("Subj", &obj1)->isString()) {
1952
obj1 = dict->lookup("Subj");
1953
if (obj1.isString()) {
2046
1954
subject = obj1.getString()->copy();
2048
1956
subject = NULL;
2052
if (dict->lookup("RT", &obj1)->isName()) {
1959
obj1 = dict->lookup("RT");
1960
if (obj1.isName()) {
2053
1961
const char *replyName = obj1.getName();
2055
1963
if (!strcmp(replyName, "R")) {
2168
2064
AnnotText::AnnotText(PDFDoc *docA, PDFRectangle *rect) :
2169
2065
AnnotMarkup(docA, rect) {
2172
2066
type = typeText;
2173
2067
flags |= flagNoZoom | flagNoRotate;
2175
annotObj.dictSet ("Subtype", obj1.initName ("Text"));
2069
annotObj.dictSet ("Subtype", Object(objName, "Text"));
2176
2070
initialize (docA, annotObj.getDict());
2179
AnnotText::AnnotText(PDFDoc *docA, Dict *dict, Object *obj) :
2180
AnnotMarkup(docA, dict, obj) {
2073
AnnotText::AnnotText(PDFDoc *docA, Object *dictObject, Object *obj) :
2074
AnnotMarkup(docA, dictObject, obj) {
2182
2076
type = typeText;
2183
2077
flags |= flagNoZoom | flagNoRotate;
2184
initialize (docA, dict);
2078
initialize (docA, dictObject->getDict());
2187
2081
AnnotText::~AnnotText() {
2583
2472
double bbox[4];
2584
2473
appearBBox->getBBoxRect(bbox);
2586
createForm(bbox, gFalse, NULL, &appearance);
2475
appearance = createForm(bbox, gFalse, nullptr);
2588
Object aStream, resDict;
2590
createForm(bbox, gTrue, NULL, &aStream);
2477
Object aStream = createForm(bbox, gTrue, nullptr);
2591
2478
delete appearBuf;
2593
2480
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
2594
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
2595
createForm(bbox, gFalse, &resDict, &appearance);
2481
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
2482
appearance = createForm(bbox, gFalse, resDict);
2597
2484
delete appearBuf;
2600
2487
// draw the appearance stream
2601
appearance.fetch(gfx->getXRef(), &obj);
2488
Object obj = appearance.fetch(gfx->getXRef());
2602
2489
if (appearBBox) {
2603
2490
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
2604
2491
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
2675
2562
linkEffect = effectInvert;
2679
if (dict->lookup("PA", &obj1)->isDict()) {
2565
obj1 = dict->lookup("PA");
2566
if (obj1.isDict()) {
2680
2567
uriAction = NULL;
2682
2569
uriAction = NULL;
2686
if (dict->lookup("QuadPoints", &obj1)->isArray()) {
2573
obj1 = dict->lookup("QuadPoints");
2574
if (obj1.isArray()) {
2687
2575
quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
2689
2577
quadrilaterals = NULL;
2693
if (dict->lookup("BS", &obj1)->isDict()) {
2580
obj1 = dict->lookup("BS");
2581
if (obj1.isDict()) {
2695
2583
border = new AnnotBorderBS(obj1.getDict());
2696
2584
} else if (!border) {
2697
2585
border = new AnnotBorderBS();
2702
2589
void AnnotLink::draw(Gfx *gfx, GBool printing) {
2705
2590
if (!isVisible (printing))
2709
2594
// draw the appearance stream
2710
appearance.fetch(gfx->getXRef(), &obj);
2595
Object obj = appearance.fetch(gfx->getXRef());
2711
2596
gfx->drawAnnot(&obj, border, color,
2712
2597
rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
2716
2600
//------------------------------------------------------------------------
2723
2607
type = typeFreeText;
2725
annotObj.dictSet ("Subtype", obj1.initName ("FreeText"));
2728
obj2.initString (da->copy());
2729
annotObj.dictSet("DA", &obj2);
2609
annotObj.dictSet ("Subtype", Object(objName, "FreeText"));
2610
annotObj.dictSet("DA", Object(da->copy()));
2731
2612
initialize (docA, annotObj.getDict());
2734
AnnotFreeText::AnnotFreeText(PDFDoc *docA, Dict *dict, Object *obj) :
2735
AnnotMarkup(docA, dict, obj) {
2615
AnnotFreeText::AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj) :
2616
AnnotMarkup(docA, dictObject, obj) {
2736
2617
type = typeFreeText;
2737
initialize(docA, dict);
2618
initialize(docA, dictObject->getDict());
2740
2621
AnnotFreeText::~AnnotFreeText() {
2756
2637
void AnnotFreeText::initialize(PDFDoc *docA, Dict *dict) {
2759
if (dict->lookup("DA", &obj1)->isString()) {
2640
obj1 = dict->lookup("DA");
2641
if (obj1.isString()) {
2760
2642
appearanceString = obj1.getString()->copy();
2762
2644
appearanceString = new GooString();
2763
2645
error(errSyntaxError, -1, "Bad appearance for annotation");
2768
if (dict->lookup("Q", &obj1)->isInt()) {
2649
obj1 = dict->lookup("Q");
2769
2651
quadding = (AnnotFreeTextQuadding) obj1.getInt();
2771
2653
quadding = quaddingLeftJustified;
2775
if (dict->lookup("DS", &obj1)->isString()) {
2656
obj1 = dict->lookup("DS");
2657
if (obj1.isString()) {
2776
2658
styleString = obj1.getString()->copy();
2778
2660
styleString = NULL;
2782
if (dict->lookup("CL", &obj1)->isArray() && obj1.arrayGetLength() >= 4) {
2663
obj1 = dict->lookup("CL");
2664
if (obj1.isArray() && obj1.arrayGetLength() >= 4) {
2783
2665
double x1, y1, x2, y2;
2786
(obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
2788
(obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
2790
(obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
2792
(obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
2668
(obj2 = obj1.arrayGet(0), obj2.isNum() ? x1 = obj2.getNum() : x1 = 0);
2669
(obj2 = obj1.arrayGet(1), obj2.isNum() ? y1 = obj2.getNum() : y1 = 0);
2670
(obj2 = obj1.arrayGet(2), obj2.isNum() ? x2 = obj2.getNum() : x2 = 0);
2671
(obj2 = obj1.arrayGet(3), obj2.isNum() ? y2 = obj2.getNum() : y2 = 0);
2795
2673
if (obj1.arrayGetLength() == 6) {
2797
(obj1.arrayGet(4, &obj2)->isNum() ? x3 = obj2.getNum() : x3 = 0);
2799
(obj1.arrayGet(5, &obj2)->isNum() ? y3 = obj2.getNum() : y3 = 0);
2675
(obj2 = obj1.arrayGet(4), obj2.isNum() ? x3 = obj2.getNum() : x3 = 0);
2676
(obj2 = obj1.arrayGet(5), obj2.isNum() ? y3 = obj2.getNum() : y3 = 0);
2801
2677
calloutLine = new AnnotCalloutMultiLine(x1, y1, x2, y2, x3, y3);
2803
2679
calloutLine = new AnnotCalloutLine(x1, y1, x2, y2);
2823
2699
intent = intentFreeText;
2827
if (dict->lookup("BS", &obj1)->isDict()) {
2702
obj1 = dict->lookup("BS");
2703
if (obj1.isDict()) {
2829
2705
border = new AnnotBorderBS(obj1.getDict());
2830
2706
} else if (!border) {
2831
2707
border = new AnnotBorderBS();
2835
if (dict->lookup("BE", &obj1)->isDict()) {
2710
obj1 = dict->lookup("BE");
2711
if (obj1.isDict()) {
2836
2712
borderEffect = new AnnotBorderEffect(obj1.getDict());
2838
2714
borderEffect = NULL;
2842
if (dict->lookup("RD", &obj1)->isArray()) {
2717
obj1 = dict->lookup("RD");
2718
if (obj1.isArray()) {
2843
2719
rectangle = parseDiffRectangle(obj1.getArray(), rect);
2845
2721
rectangle = NULL;
2849
if (dict->lookup("LE", &obj1)->isName()) {
2724
obj1 = dict->lookup("LE");
2725
if (obj1.isName()) {
2850
2726
GooString styleName(obj1.getName());
2851
2727
endStyle = parseAnnotLineEndingStyle(&styleName);
2853
2729
endStyle = annotLineEndingNone;
2858
2733
void AnnotFreeText::setContents(GooString *new_content) {
2909
2778
if (line == NULL) {
2911
2780
calloutLine = NULL;
2913
2782
double x1 = line->getX1(), y1 = line->getY1();
2914
2783
double x2 = line->getX2(), y2 = line->getY2();
2916
obj1.initArray(xref);
2917
obj1.arrayAdd( obj2.initReal(x1) );
2918
obj1.arrayAdd( obj2.initReal(y1) );
2919
obj1.arrayAdd( obj2.initReal(x2) );
2920
obj1.arrayAdd( obj2.initReal(y2) );
2784
obj1 = Object( new Array(xref) );
2785
obj1.arrayAdd( Object(x1) );
2786
obj1.arrayAdd( Object(y1) );
2787
obj1.arrayAdd( Object(x2) );
2788
obj1.arrayAdd( Object(y2) );
2922
2790
AnnotCalloutMultiLine *mline = dynamic_cast<AnnotCalloutMultiLine*>(line);
2924
2792
double x3 = mline->getX3(), y3 = mline->getY3();
2925
obj1.arrayAdd( obj2.initReal(x3) );
2926
obj1.arrayAdd( obj2.initReal(y3) );
2793
obj1.arrayAdd( Object(x3) );
2794
obj1.arrayAdd( Object(y3) );
2927
2795
calloutLine = new AnnotCalloutMultiLine(x1, y1, x2, y2, x3, y3);
2929
2797
calloutLine = new AnnotCalloutLine(x1, y1, x2, y2);
2933
update("CL", &obj1);
2801
update("CL", std::move(obj1));
2934
2802
invalidateAppearance();
2937
2805
void AnnotFreeText::setIntent(AnnotFreeTextIntent new_intent) {
2806
const char *intentName;
2940
2808
intent = new_intent;
2941
2809
if (new_intent == intentFreeText)
2942
obj1.initName("FreeText");
2810
intentName = "FreeText";
2943
2811
else if (new_intent == intentFreeTextCallout)
2944
obj1.initName("FreeTextCallout");
2812
intentName = "FreeTextCallout";
2945
2813
else // intentFreeTextTypeWriter
2946
obj1.initName("FreeTextTypeWriter");
2947
update ("IT", &obj1);
2814
intentName = "FreeTextTypeWriter";
2815
update ("IT", Object(objName, intentName));
2950
static GfxFont * createAnnotDrawFont(XRef * xref, Object *fontResDict)
2818
static GfxFont * createAnnotDrawFont(XRef * xref, Dict *fontResDict)
2952
Ref dummyRef = { -1, -1 };
2954
Object baseFontObj, subtypeObj, encodingObj;
2955
baseFontObj.initName("Helvetica");
2956
subtypeObj.initName("Type0");
2957
encodingObj.initName("WinAnsiEncoding");
2820
const Ref dummyRef = { -1, -1 };
2960
2822
Dict *fontDict = new Dict(xref);
2962
fontDict->add(copyString("BaseFont"), &baseFontObj);
2963
fontDict->add(copyString("Subtype"), &subtypeObj);
2964
fontDict->add(copyString("Encoding"), &encodingObj);
2965
fontDictObj.initDict(fontDict);
2823
fontDict->add(copyString("BaseFont"), Object(objName, "Helvetica"));
2824
fontDict->add(copyString("Subtype"), Object(objName, "Type0"));
2825
fontDict->add(copyString("Encoding"), Object(objName, "WinAnsiEncoding"));
2967
Object fontsDictObj;
2968
2827
Dict *fontsDict = new Dict(xref);
2969
fontsDict->decRef();
2970
fontsDict->add(copyString("AnnotDrawFont"), &fontDictObj);
2971
fontsDictObj.initDict(fontsDict);
2973
Dict *dict = new Dict(xref);
2974
dict->add(copyString("Font"), &fontsDictObj);
2976
fontResDict->initDict(dict);
2828
fontsDict->add(copyString("AnnotDrawFont"), Object(fontDict));
2830
fontResDict->add(copyString("Font"), Object(fontsDict));
2977
2832
return GfxFont::makeFont(xref, "AnnotDrawFont", dummyRef, fontDict);
3114
2954
bbox[3] = rect->y2 - rect->y1;
3117
createForm(bbox, gFalse, &fontResDict, &appearance);
2957
appearance = createForm(bbox, gFalse, fontResDict);
3119
Object aStream, resDict;
3121
createForm(bbox, gTrue, &fontResDict, &aStream);
2959
Object aStream = createForm(bbox, gTrue, fontResDict);
3122
2960
delete appearBuf;
3124
2962
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
3125
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
3126
createForm(bbox, gFalse, &resDict, &appearance);
2963
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
2964
appearance = createForm(bbox, gFalse, resDict);
3128
2966
delete appearBuf;
3131
2969
void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
3134
2970
if (!isVisible (printing))
3142
2978
// draw the appearance stream
3143
appearance.fetch(gfx->getXRef(), &obj);
2979
Object obj = appearance.fetch(gfx->getXRef());
3144
2980
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
3145
2981
rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
3149
2984
// Before retrieving the res dict, regenerate the appearance stream if needed,
3150
2985
// because AnnotFreeText::draw needs to store font info in the res dict
3151
Object *AnnotFreeText::getAppearanceResDict(Object *dest) {
2986
Object AnnotFreeText::getAppearanceResDict() {
3152
2987
if (appearance.isNull()) {
3153
2988
generateFreeTextAppearance();
3155
return Annot::getAppearanceResDict(dest);
2990
return Annot::getAppearanceResDict();
3158
2993
//------------------------------------------------------------------------
3189
3024
void AnnotLine::initialize(PDFDoc *docA, Dict *dict) {
3192
if (dict->lookup("L", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
3027
obj1 = dict->lookup("L");
3028
if (obj1.isArray() && obj1.arrayGetLength() == 4) {
3194
3030
double x1, y1, x2, y2;
3196
(obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
3198
(obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
3200
(obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
3202
(obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
3032
(obj2 = obj1.arrayGet(0), obj2.isNum() ? x1 = obj2.getNum() : x1 = 0);
3033
(obj2 = obj1.arrayGet(1), obj2.isNum() ? y1 = obj2.getNum() : y1 = 0);
3034
(obj2 = obj1.arrayGet(2), obj2.isNum() ? x2 = obj2.getNum() : x2 = 0);
3035
(obj2 = obj1.arrayGet(3), obj2.isNum() ? y2 = obj2.getNum() : y2 = 0);
3205
3037
coord1 = new AnnotCoord(x1, y1);
3206
3038
coord2 = new AnnotCoord(x2, y2);
3208
3040
coord1 = new AnnotCoord();
3209
3041
coord2 = new AnnotCoord();
3213
if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
3044
obj1 = dict->lookup("LE");
3045
if (obj1.isArray() && obj1.arrayGetLength() == 2) {
3216
if(obj1.arrayGet(0, &obj2)->isString())
3048
obj2 = obj1.arrayGet(0);
3049
if (obj2.isString())
3217
3050
startStyle = parseAnnotLineEndingStyle(obj2.getString());
3219
3052
startStyle = annotLineEndingNone;
3222
if(obj1.arrayGet(1, &obj2)->isString())
3054
obj2 = obj1.arrayGet(1);
3055
if (obj2.isString())
3223
3056
endStyle = parseAnnotLineEndingStyle(obj2.getString());
3225
3058
endStyle = annotLineEndingNone;
3229
3061
startStyle = endStyle = annotLineEndingNone;
3233
if (dict->lookup("IC", &obj1)->isArray()) {
3064
obj1 = dict->lookup("IC");
3065
if (obj1.isArray()) {
3234
3066
interiorColor = new AnnotColor(obj1.getArray());
3236
3068
interiorColor = NULL;
3240
if (dict->lookup("LL", &obj1)->isNum()) {
3071
obj1 = dict->lookup("LL");
3241
3073
leaderLineLength = obj1.getNum();
3243
3075
leaderLineLength = 0;
3247
if (dict->lookup("LLE", &obj1)->isNum()) {
3078
obj1 = dict->lookup("LLE");
3248
3080
leaderLineExtension = obj1.getNum();
3250
3082
if (leaderLineExtension < 0)
3300
3132
captionPos = captionPosInline;
3304
if (dict->lookup("Measure", &obj1)->isDict()) {
3135
obj1 = dict->lookup("Measure");
3136
if (obj1.isDict()) {
3305
3137
measure = NULL;
3307
3139
measure = NULL;
3311
if ((dict->lookup("CO", &obj1)->isArray()) && (obj1.arrayGetLength() == 2)) {
3142
obj1 = dict->lookup("CO");
3143
if (obj1.isArray() && (obj1.arrayGetLength() == 2)) {
3314
(obj1.arrayGet(0, &obj2)->isNum() ? captionTextHorizontal = obj2.getNum() :
3315
captionTextHorizontal = 0);
3317
(obj1.arrayGet(1, &obj2)->isNum() ? captionTextVertical = obj2.getNum() :
3318
captionTextVertical = 0);
3146
obj2 = obj1.arrayGet(0);
3147
captionTextHorizontal = obj2.isNum() ? obj2.getNum() : 0;
3148
obj2 = obj1.arrayGet(1);
3149
captionTextVertical = obj2.isNum() ? obj2.getNum() : 0;
3321
3151
captionTextHorizontal = captionTextVertical = 0;
3325
if (dict->lookup("BS", &obj1)->isDict()) {
3154
obj1 = dict->lookup("BS");
3155
if (obj1.isDict()) {
3327
3157
border = new AnnotBorderBS(obj1.getDict());
3328
3158
} else if (!border) {
3329
3159
border = new AnnotBorderBS();
3334
3163
void AnnotLine::setContents(GooString *new_content) {
3340
3169
void AnnotLine::setVertices(double x1, double y1, double x2, double y2) {
3344
3171
coord1 = new AnnotCoord(x1, y1);
3346
3173
coord2 = new AnnotCoord(x2, y2);
3348
obj1.initArray(xref);
3349
obj1.arrayAdd( obj2.initReal(x1) );
3350
obj1.arrayAdd( obj2.initReal(y1) );
3351
obj1.arrayAdd( obj2.initReal(x2) );
3352
obj1.arrayAdd( obj2.initReal(y2) );
3175
Array *lArray = new Array(xref);
3176
lArray->add( Object(x1) );
3177
lArray->add( Object(y1) );
3178
lArray->add( Object(x2) );
3179
lArray->add( Object(y2) );
3181
update("L", Object(lArray));
3355
3182
invalidateAppearance();
3358
3185
void AnnotLine::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
3361
3186
startStyle = start;
3362
3187
endStyle = end;
3364
obj1.initArray(xref);
3365
obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( startStyle )) );
3366
obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( endStyle )) );
3189
Array *leArray = new Array(xref);
3190
leArray->add( Object(objName, convertAnnotLineEndingStyle( startStyle )) );
3191
leArray->add( Object(objName, convertAnnotLineEndingStyle( endStyle )) );
3368
update("LE", &obj1);
3193
update("LE", Object(leArray));
3369
3194
invalidateAppearance();
3386
3210
void AnnotLine::setLeaderLineLength(double len) {
3389
3211
leaderLineLength = len;
3391
update ("LL", &obj1);
3212
update ("LL", Object(len));
3392
3213
invalidateAppearance();
3395
3216
void AnnotLine::setLeaderLineExtension(double len) {
3398
3217
leaderLineExtension = len;
3400
update ("LLE", &obj1);
3218
update ("LLE", Object(len));
3402
3220
// LL is required if LLE is present
3403
obj1.initReal(leaderLineLength);
3404
update ("LL", &obj1);
3221
update ("LL", Object(leaderLineLength));
3405
3222
invalidateAppearance();
3408
3225
void AnnotLine::setCaption(bool new_cap) {
3411
3226
caption = new_cap;
3412
obj1.initBool(new_cap);
3413
update ("Cap", &obj1);
3227
update ("Cap", Object(new_cap));
3414
3228
invalidateAppearance();
3417
3231
void AnnotLine::setIntent(AnnotLineIntent new_intent) {
3232
const char *intentName;
3420
3234
intent = new_intent;
3421
3235
if (new_intent == intentLineArrow)
3422
obj1.initName("LineArrow");
3236
intentName = "LineArrow";
3423
3237
else // intentLineDimension
3424
obj1.initName("LineDimension");
3425
update ("IT", &obj1);
3238
intentName = "LineDimension";
3239
update ("IT", Object(objName, intentName));
3428
3242
void AnnotLine::generateLineAppearance()
3579
3394
double bbox[4];
3580
3395
appearBBox->getBBoxRect(bbox);
3582
createForm(bbox, gFalse, &fontResDict, &appearance);
3397
appearance = createForm(bbox, gFalse, fontResDict);
3584
Object aStream, resDict;
3586
createForm(bbox, gTrue, &fontResDict, &aStream);
3399
Object aStream = createForm(bbox, gTrue, fontResDict);
3587
3400
delete appearBuf;
3589
3402
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
3590
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
3591
createForm(bbox, gFalse, &resDict, &appearance);
3403
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
3404
appearance = createForm(bbox, gFalse, resDict);
3593
3406
delete appearBuf;
3596
3409
void AnnotLine::draw(Gfx *gfx, GBool printing) {
3599
3410
if (!isVisible (printing))
3637
3447
switch (subType) {
3638
3448
case typeHighlight:
3639
annotObj.dictSet ("Subtype", obj1.initName ("Highlight"));
3449
annotObj.dictSet ("Subtype", Object(objName, "Highlight"));
3641
3451
case typeUnderline:
3642
annotObj.dictSet ("Subtype", obj1.initName ("Underline"));
3452
annotObj.dictSet ("Subtype", Object(objName, "Underline"));
3644
3454
case typeSquiggly:
3645
annotObj.dictSet ("Subtype", obj1.initName ("Squiggly"));
3455
annotObj.dictSet ("Subtype", Object(objName, "Squiggly"));
3647
3457
case typeStrikeOut:
3648
annotObj.dictSet ("Subtype", obj1.initName ("StrikeOut"));
3458
annotObj.dictSet ("Subtype", Object(objName, "StrikeOut"));
3651
3461
assert (0 && "Invalid subtype for AnnotTextMarkup\n");
3654
3464
// Store dummy quadrilateral with null coordinates
3656
obj2.initArray (doc->getXRef());
3465
Array *quadPoints = new Array(doc->getXRef());
3657
3466
for (int i = 0; i < 4*2; ++i) {
3658
obj2.arrayAdd (obj3.initReal (0));
3467
quadPoints->add(Object(0.));
3660
annotObj.dictSet ("QuadPoints", &obj2);
3469
annotObj.dictSet ("QuadPoints", Object(quadPoints));
3662
3471
initialize(docA, annotObj.getDict());
3665
AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, Dict *dict, Object *obj) :
3666
AnnotMarkup(docA, dict, obj) {
3474
AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, Object *dictObject, Object *obj) :
3475
AnnotMarkup(docA, dictObject, obj) {
3667
3476
// the real type will be read in initialize()
3668
3477
type = typeHighlight;
3669
initialize(docA, dict);
3478
initialize(docA, dictObject->getDict());
3672
3481
void AnnotTextMarkup::initialize(PDFDoc *docA, Dict *dict) {
3675
if (dict->lookup("Subtype", &obj1)->isName()) {
3484
obj1 = dict->lookup("Subtype");
3485
if (obj1.isName()) {
3676
3486
GooString typeName(obj1.getName());
3677
3487
if (!typeName.cmp("Highlight")) {
3678
3488
type = typeHighlight;
3684
3494
type = typeStrikeOut;
3689
if(dict->lookup("QuadPoints", &obj1)->isArray()) {
3498
obj1 = dict->lookup("QuadPoints");
3499
if (obj1.isArray()) {
3690
3500
quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
3692
3502
error(errSyntaxError, -1, "Bad Annot Text Markup QuadPoints");
3693
3503
quadrilaterals = NULL;
3699
3508
AnnotTextMarkup::~AnnotTextMarkup() {
3700
if(quadrilaterals) {
3701
delete quadrilaterals;
3509
delete quadrilaterals;
3705
3512
void AnnotTextMarkup::setType(AnnotSubtype new_type) {
3513
const char *typeName = nullptr; /* squelch bogus compiler warning */
3708
3515
switch (new_type) {
3709
3516
case typeHighlight:
3710
obj1.initName("Highlight");
3517
typeName = "Highlight";
3712
3519
case typeUnderline:
3713
obj1.initName("Underline");
3520
typeName = "Underline";
3715
3522
case typeSquiggly:
3716
obj1.initName("Squiggly");
3523
typeName = "Squiggly";
3718
3525
case typeStrikeOut:
3719
obj1.initName("StrikeOut");
3526
typeName = "StrikeOut";
3722
3529
assert(!"Invalid subtype");
3725
3532
type = new_type;
3726
update("Subtype", &obj1);
3533
update("Subtype", Object(objName, typeName));
3727
3534
invalidateAppearance();
3730
3537
void AnnotTextMarkup::setQuadrilaterals(AnnotQuadrilaterals *quadPoints) {
3732
obj1.initArray (xref);
3538
Array *a = new Array(xref);
3734
3540
for (int i = 0; i < quadPoints->getQuadrilateralsLength(); ++i) {
3735
obj1.arrayAdd (obj2.initReal (quadPoints->getX1(i)));
3736
obj1.arrayAdd (obj2.initReal (quadPoints->getY1(i)));
3737
obj1.arrayAdd (obj2.initReal (quadPoints->getX2(i)));
3738
obj1.arrayAdd (obj2.initReal (quadPoints->getY2(i)));
3739
obj1.arrayAdd (obj2.initReal (quadPoints->getX3(i)));
3740
obj1.arrayAdd (obj2.initReal (quadPoints->getY3(i)));
3741
obj1.arrayAdd (obj2.initReal (quadPoints->getX4(i)));
3742
obj1.arrayAdd (obj2.initReal (quadPoints->getY4(i)));
3541
a->add(Object(quadPoints->getX1(i)));
3542
a->add(Object(quadPoints->getY1(i)));
3543
a->add(Object(quadPoints->getX2(i)));
3544
a->add(Object(quadPoints->getY2(i)));
3545
a->add(Object(quadPoints->getX3(i)));
3546
a->add(Object(quadPoints->getY3(i)));
3547
a->add(Object(quadPoints->getX4(i)));
3548
a->add(Object(quadPoints->getY4(i)));
3745
3551
delete quadrilaterals;
3746
quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
3552
quadrilaterals = new AnnotQuadrilaterals(a, rect);
3748
annotObj.dictSet ("QuadPoints", &obj1);
3554
annotObj.dictSet ("QuadPoints", Object(a));
3749
3555
invalidateAppearance();
3752
3558
void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
3758
3562
if (!isVisible (printing))
3888
3690
appearBuf->append ("Q\n");
3890
Object aStream, resDict;
3891
3693
double bbox[4];
3892
3694
bbox[0] = appearBBox->getPageXMin();
3893
3695
bbox[1] = appearBBox->getPageYMin();
3894
3696
bbox[2] = appearBBox->getPageXMax();
3895
3697
bbox[3] = appearBBox->getPageYMax();
3896
createForm(bbox, gTrue, NULL, &aStream);
3698
aStream = createForm(bbox, gTrue, NULL);
3897
3699
delete appearBuf;
3899
3701
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
3900
createResourcesDict("Fm0", &aStream, "GS0", 1, blendMultiply ? "Multiply" : NULL, &resDict);
3702
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", 1, blendMultiply ? "Multiply" : NULL);
3902
createForm(bbox, gFalse, &resDict, &appearance);
3704
appearance = createForm(bbox, gFalse, resDict);
3904
createForm(bbox, gTrue, &resDict, &aStream);
3706
aStream = createForm(bbox, gTrue, resDict);
3905
3707
delete appearBuf;
3907
3709
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
3908
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
3909
createForm(bbox, gFalse, &resDict, &appearance);
3710
Dict *resDict2 = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
3711
appearance = createForm(bbox, gFalse, resDict2);
3911
3713
delete appearBuf;
3914
3716
// draw the appearance stream
3915
appearance.fetch(gfx->getXRef(), &obj);
3717
Object obj = appearance.fetch(gfx->getXRef());
3916
3718
if (appearBBox) {
3917
3719
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
3918
3720
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
3922
3724
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
3923
3725
rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
3928
3729
//------------------------------------------------------------------------
3930
3731
//------------------------------------------------------------------------
3932
AnnotWidget::AnnotWidget(PDFDoc *docA, Dict *dict, Object *obj) :
3933
Annot(docA, dict, obj) {
3733
AnnotWidget::AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj) :
3734
Annot(docA, dictObject, obj) {
3934
3735
type = typeWidget;
3936
initialize(docA, dict);
3737
initialize(docA, dictObject->getDict());
3939
AnnotWidget::AnnotWidget(PDFDoc *docA, Dict *dict, Object *obj, FormField *fieldA) :
3940
Annot(docA, dict, obj) {
3740
AnnotWidget::AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj, FormField *fieldA) :
3741
Annot(docA, dictObject, obj) {
3941
3742
type = typeWidget;
3942
3743
field = fieldA;
3943
initialize(docA, dict);
3744
initialize(docA, dictObject->getDict());
3946
3747
AnnotWidget::~AnnotWidget() {
3977
3777
mode = highlightModeInvert;
3981
if(dict->lookup("MK", &obj1)->isDict()) {
3780
obj1 = dict->lookup("MK");
3781
if (obj1.isDict()) {
3982
3782
appearCharacs = new AnnotAppearanceCharacs(obj1.getDict());
3984
3784
appearCharacs = NULL;
3989
if(dict->lookup("A", &obj1)->isDict()) {
3788
obj1 = dict->lookup("A");
3789
if (obj1.isDict()) {
3990
3790
action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
3994
dict->lookupNF("AA", &additionalActions);
3996
if(dict->lookup("Parent", &obj1)->isDict()) {
3793
additionalActions = dict->lookupNF("AA");
3795
obj1 = dict->lookup("Parent");
3796
if (obj1.isDict()) {
4003
if (dict->lookup("BS", &obj1)->isDict()) {
3802
obj1 = dict->lookup("BS");
3803
if (obj1.isDict()) {
4005
3805
border = new AnnotBorderBS(obj1.getDict());
4009
3808
updatedAppearanceStream.num = updatedAppearanceStream.gen = -1;
5086
4883
// build the appearance stream dictionary
5087
appearDict.initDict(xref);
5088
appearDict.dictAdd(copyString("Length"),
5089
obj1.initInt(appearBuf->getLength()));
5090
appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
5091
obj1.initArray(xref);
5092
obj1.arrayAdd(obj2.initReal(0));
5093
obj1.arrayAdd(obj2.initReal(0));
5094
obj1.arrayAdd(obj2.initReal(rect->x2 - rect->x1));
5095
obj1.arrayAdd(obj2.initReal(rect->y2 - rect->y1));
5096
appearDict.dictAdd(copyString("BBox"), &obj1);
4884
Dict *appearDict = new Dict(xref);
4885
appearDict->add(copyString("Length"), Object(appearBuf->getLength()));
4886
appearDict->add(copyString("Subtype"), Object(objName, "Form"));
4887
Array *bbox = new Array(xref);
4888
bbox->add(Object(0));
4889
bbox->add(Object(0));
4890
bbox->add(Object(rect->x2 - rect->x1));
4891
bbox->add(Object(rect->y2 - rect->y1));
4892
appearDict->add(copyString("BBox"), Object(bbox));
5098
4894
// set the resource dictionary
5099
4895
Object *resDict = form->getDefaultResourcesObj();
5100
4896
if (resDict->isDict()) {
5101
appearDict.dictAdd(copyString("Resources"), resDict->copy(&obj1));
4897
appearDict->add(copyString("Resources"), resDict->copy());
5104
4900
// build the appearance stream
5105
appearStream = new MemStream(copyString(appearBuf->getCString()), 0,
5106
appearBuf->getLength(), &appearDict);
5108
appearance.initStream(appearStream);
4901
MemStream *appearStream = new MemStream(copyString(appearBuf->getCString()), 0,
4902
appearBuf->getLength(), Object(appearDict));
4903
appearance = Object(static_cast<Stream*>(appearStream));
5109
4904
delete appearBuf;
5111
4906
appearStream->setNeedFree(gTrue);
5137
4931
if (updatedAppearanceStream.num == -1) {
5138
4932
// Write the appearance stream
5139
4933
updatedAppearanceStream = xref->addIndirectObject(&obj1);
5142
4935
// Write the AP dictionary
5144
obj1.initDict(xref);
5145
obj1.dictAdd(copyString("N"), obj2.initRef(updatedAppearanceStream.num, updatedAppearanceStream.gen));
5146
update("AP", &obj1);
4936
obj1 = Object(new Dict(xref));
4937
obj1.dictAdd(copyString("N"), Object(updatedAppearanceStream.num, updatedAppearanceStream.gen));
5148
4939
// Update our internal pointers to the appearance dictionary
5149
4940
appearStreams = new AnnotAppearance(doc, &obj1);
4942
update("AP", std::move(obj1));
5151
4944
// Replace the existing appearance stream
5152
4945
xref->setModifiedObject(&obj1, updatedAppearanceStream);
5157
4949
void AnnotWidget::draw(Gfx *gfx, GBool printing) {
5160
4950
if (!isVisible (printing))
5174
4964
// draw the appearance stream
5175
appearance.fetch(gfx->getXRef(), &obj);
4965
Object obj = appearance.fetch(gfx->getXRef());
5176
4966
if (addDingbatsResource) {
5177
4967
// We are forcing ZaDb but the font does not exist
5178
4968
// so create a fake one
5179
Object baseFontObj, subtypeObj;
5180
baseFontObj.initName("ZapfDingbats");
5181
subtypeObj.initName("Type1");
5184
4969
Dict *fontDict = new Dict(gfx->getXRef());
5186
fontDict->add(copyString("BaseFont"), &baseFontObj);
5187
fontDict->add(copyString("Subtype"), &subtypeObj);
5188
fontDictObj.initDict(fontDict);
4970
fontDict->add(copyString("BaseFont"), Object(objName, "ZapfDingbats"));
4971
fontDict->add(copyString("Subtype"), Object(objName, "Type1"));
5190
Object fontsDictObj;
5191
4973
Dict *fontsDict = new Dict(gfx->getXRef());
5192
fontsDict->decRef();
5193
fontsDict->add(copyString("ZaDb"), &fontDictObj);
5194
fontsDictObj.initDict(fontsDict);
4974
fontsDict->add(copyString("ZaDb"), Object(fontDict));
5196
4976
Dict *dict = new Dict(gfx->getXRef());
5197
dict->add(copyString("Font"), &fontsDictObj);
4977
dict->add(copyString("Font"), Object(fontsDict));
5198
4978
gfx->pushResources(dict);
5263
5040
error(errSyntaxError, -1, "Bad Annot Movie");
5270
5046
void AnnotMovie::draw(Gfx *gfx, GBool printing) {
5273
5047
if (!isVisible (printing))
5277
5051
if (appearance.isNull() && movie->getShowPoster()) {
5278
5052
int width, height;
5280
movie->getPoster(&poster);
5053
Object poster = movie->getPoster();
5281
5054
movie->getAspect(&width, &height);
5283
5056
if (width != -1 && height != -1 && !poster.isNone()) {
5286
5057
appearBuf = new GooString ();
5287
5058
appearBuf->append ("q\n");
5288
5059
appearBuf->appendf ("{0:d} 0 0 {1:d} 0 0 cm\n", width, height);
5289
5060
appearBuf->append ("/MImg Do\n");
5290
5061
appearBuf->append ("Q\n");
5293
imgDict.initDict(gfx->getXRef());
5294
imgDict.dictSet ("MImg", &poster);
5297
resDict.initDict(gfx->getXRef());
5298
resDict.dictSet ("XObject", &imgDict);
5300
Object formDict, obj1, obj2;
5301
formDict.initDict(gfx->getXRef());
5302
formDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
5303
formDict.dictSet("Subtype", obj1.initName("Form"));
5304
formDict.dictSet("Name", obj1.initName("FRM"));
5305
obj1.initArray(gfx->getXRef());
5306
obj1.arrayAdd(obj2.initInt(0));
5307
obj1.arrayAdd(obj2.initInt(0));
5308
obj1.arrayAdd(obj2.initInt(width));
5309
obj1.arrayAdd(obj2.initInt(height));
5310
formDict.dictSet("BBox", &obj1);
5311
obj1.initArray(gfx->getXRef());
5312
obj1.arrayAdd(obj2.initInt(1));
5313
obj1.arrayAdd(obj2.initInt(0));
5314
obj1.arrayAdd(obj2.initInt(0));
5315
obj1.arrayAdd(obj2.initInt(1));
5316
obj1.arrayAdd(obj2.initInt(-width / 2));
5317
obj1.arrayAdd(obj2.initInt(-height / 2));
5318
formDict.dictSet("Matrix", &obj1);
5319
formDict.dictSet("Resources", &resDict);
5322
mStream = new MemStream(copyString(appearBuf->getCString()), 0,
5323
appearBuf->getLength(), &formDict);
5063
Dict *imgDict = new Dict(gfx->getXRef());
5064
imgDict->set("MImg", std::move(poster));
5066
Dict *resDict = new Dict(gfx->getXRef());
5067
resDict->set("XObject", Object(imgDict));
5069
Dict *formDict = new Dict(gfx->getXRef());
5070
formDict->set("Length", Object(appearBuf->getLength()));
5071
formDict->set("Subtype", Object(objName, "Form"));
5072
formDict->set("Name", Object(objName, "FRM"));
5073
Array *bboxArray = new Array(gfx->getXRef());
5074
bboxArray->add(Object(0));
5075
bboxArray->add(Object(0));
5076
bboxArray->add(Object(width));
5077
bboxArray->add(Object(height));
5078
formDict->set("BBox", Object(bboxArray));
5079
Array *matrix = new Array(gfx->getXRef());
5080
matrix->add(Object(1));
5081
matrix->add(Object(0));
5082
matrix->add(Object(0));
5083
matrix->add(Object(1));
5084
matrix->add(Object(-width / 2));
5085
matrix->add(Object(-height / 2));
5086
formDict->set("Matrix", Object(matrix));
5087
formDict->set("Resources", Object(resDict));
5089
MemStream *mStream = new MemStream(copyString(appearBuf->getCString()), 0,
5090
appearBuf->getLength(), Object(formDict));
5324
5091
mStream->setNeedFree(gTrue);
5325
aStream.initStream(mStream);
5326
5092
delete appearBuf;
5329
objDict.initDict(gfx->getXRef());
5330
objDict.dictSet ("FRM", &aStream);
5094
Dict *dict = new Dict(gfx->getXRef());
5095
dict->set("FRM", Object(static_cast<Stream*>(mStream)));
5332
resDict.initDict(gfx->getXRef());
5333
resDict.dictSet ("XObject", &objDict);
5097
Dict *resDict2 = new Dict(gfx->getXRef());
5098
resDict2->set("XObject", Object(dict));
5335
5100
appearBuf = new GooString ();
5336
5101
appearBuf->append ("q\n");
5369
5132
type = typeScreen;
5371
annotObj.dictSet ("Subtype", obj1.initName ("Screen"));
5134
annotObj.dictSet ("Subtype", Object(objName, "Screen"));
5372
5135
initialize(docA, annotObj.getDict());
5375
AnnotScreen::AnnotScreen(PDFDoc *docA, Dict *dict, Object *obj) :
5376
Annot(docA, dict, obj) {
5138
AnnotScreen::AnnotScreen(PDFDoc *docA, Object *dictObject, Object *obj) :
5139
Annot(docA, dictObject, obj) {
5377
5140
type = typeScreen;
5378
initialize(docA, dict);
5141
initialize(docA, dictObject->getDict());
5381
5144
AnnotScreen::~AnnotScreen() {
5385
delete appearCharacs;
5389
additionalActions.free();
5146
delete appearCharacs;
5392
5150
void AnnotScreen::initialize(PDFDoc *docA, Dict* dict) {
5396
if (dict->lookup("T", &obj1)->isString()) {
5154
obj1 = dict->lookup("T");
5155
if (obj1.isString()) {
5397
5156
title = obj1.getString()->copy();
5402
if (dict->lookup("A", &obj1)->isDict()) {
5160
obj1 = dict->lookup("A");
5161
if (obj1.isDict()) {
5403
5162
action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
5404
if (action->getKind() == actionRendition && page == 0) {
5163
if (action && action->getKind() == actionRendition && page == 0) {
5405
5164
error (errSyntaxError, -1, "Invalid Rendition action: associated screen annotation without P");
5413
dict->lookupNF("AA", &additionalActions);
5171
additionalActions = dict->lookupNF("AA");
5415
5173
appearCharacs = NULL;
5416
if(dict->lookup("MK", &obj1)->isDict()) {
5174
obj1 = dict->lookup("MK");
5175
if (obj1.isDict()) {
5417
5176
appearCharacs = new AnnotAppearanceCharacs(obj1.getDict());
5422
5180
LinkAction* AnnotScreen::getAdditionalAction(AdditionalActionsType type)
5521
5276
type = typeCircle;
5526
if (dict->lookup("IC", &obj1)->isArray()) {
5280
obj1 = dict->lookup("IC");
5281
if (obj1.isArray()) {
5527
5282
interiorColor = new AnnotColor(obj1.getArray());
5529
5284
interiorColor = NULL;
5533
if (dict->lookup("BS", &obj1)->isDict()) {
5287
obj1 = dict->lookup("BS");
5288
if (obj1.isDict()) {
5535
5290
border = new AnnotBorderBS(obj1.getDict());
5536
5291
} else if (!border) {
5537
5292
border = new AnnotBorderBS();
5541
if (dict->lookup("BE", &obj1)->isDict()) {
5295
obj1 = dict->lookup("BE");
5296
if (obj1.isDict()) {
5542
5297
borderEffect = new AnnotBorderEffect(obj1.getDict());
5544
5299
borderEffect = NULL;
5548
5302
geometryRect = NULL;
5549
if (dict->lookup("RD", &obj1)->isArray()) {
5303
obj1 = dict->lookup("RD");
5304
if (obj1.isArray()) {
5550
5305
geometryRect = parseDiffRectangle(obj1.getArray(), rect);
5556
5309
void AnnotGeometry::setType(AnnotSubtype new_type) {
5310
const char *typeName = nullptr; /* squelch bogus compiler warning */
5559
5312
switch (new_type) {
5560
5313
case typeSquare:
5561
obj1.initName("Square");
5314
typeName = "Square";
5563
5316
case typeCircle:
5564
obj1.initName("Circle");
5317
typeName = "Circle";
5567
5320
assert(!"Invalid subtype");
5570
5323
type = new_type;
5571
update("Subtype", &obj1);
5324
update("Subtype", Object(objName, typeName));
5572
5325
invalidateAppearance();
5673
5424
bbox[2] = rect->x2 - rect->x1;
5674
5425
bbox[3] = rect->y2 - rect->y1;
5676
createForm(bbox, gFalse, NULL, &appearance);
5427
appearance = createForm(bbox, gFalse, nullptr);
5680
createForm(bbox, gTrue, NULL, &aStream);
5429
Object aStream = createForm(bbox, gTrue, nullptr);
5681
5430
delete appearBuf;
5684
5432
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
5685
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
5686
createForm(bbox, gFalse, &resDict, &appearance);
5433
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
5434
appearance = createForm(bbox, gFalse, resDict);
5688
5436
delete appearBuf;
5691
5439
// draw the appearance stream
5692
appearance.fetch(gfx->getXRef(), &obj);
5440
Object obj = appearance.fetch(gfx->getXRef());
5693
5441
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
5694
5442
rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
5698
5445
//------------------------------------------------------------------------
5705
5452
switch (subType) {
5706
5453
case typePolygon:
5707
annotObj.dictSet ("Subtype", obj1.initName ("Polygon"));
5454
annotObj.dictSet ("Subtype", Object(objName, "Polygon"));
5709
5456
case typePolyLine:
5710
annotObj.dictSet ("Subtype", obj1.initName ("PolyLine"));
5457
annotObj.dictSet ("Subtype", Object(objName, "PolyLine"));
5713
5460
assert (0 && "Invalid subtype for AnnotGeometry\n");
5716
5463
// Store dummy path with one null vertex only
5718
obj2.initArray (doc->getXRef());
5719
obj2.arrayAdd (obj3.initReal (0));
5720
obj2.arrayAdd (obj3.initReal (0));
5721
annotObj.dictSet ("Vertices", &obj2);
5464
Array *a = new Array(doc->getXRef());
5467
annotObj.dictSet("Vertices", Object(a));
5723
5469
initialize(docA, annotObj.getDict());
5726
AnnotPolygon::AnnotPolygon(PDFDoc *docA, Dict *dict, Object *obj) :
5727
AnnotMarkup(docA, dict, obj) {
5472
AnnotPolygon::AnnotPolygon(PDFDoc *docA, Object *dictObject, Object *obj) :
5473
AnnotMarkup(docA, dictObject, obj) {
5728
5474
// the real type will be read in initialize()
5729
5475
type = typePolygon;
5730
initialize(docA, dict);
5476
initialize(docA, dictObject->getDict());
5733
5479
AnnotPolygon::~AnnotPolygon() {
5751
5498
type = typePolyLine;
5756
if (dict->lookup("Vertices", &obj1)->isArray()) {
5502
obj1 = dict->lookup("Vertices");
5503
if (obj1.isArray()) {
5757
5504
vertices = new AnnotPath(obj1.getArray());
5759
5506
vertices = new AnnotPath();
5760
5507
error(errSyntaxError, -1, "Bad Annot Polygon Vertices");
5765
if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
5768
if(obj1.arrayGet(0, &obj2)->isString())
5511
obj1 = dict->lookup("LE");
5512
if (obj1.isArray() && obj1.arrayGetLength() == 2) {
5513
Object obj2 = obj1.arrayGet(0);
5769
5515
startStyle = parseAnnotLineEndingStyle(obj2.getString());
5771
5517
startStyle = annotLineEndingNone;
5774
if(obj1.arrayGet(1, &obj2)->isString())
5519
obj2 = obj1.arrayGet(1);
5775
5521
endStyle = parseAnnotLineEndingStyle(obj2.getString());
5777
5523
endStyle = annotLineEndingNone;
5781
5526
startStyle = endStyle = annotLineEndingNone;
5785
if (dict->lookup("IC", &obj1)->isArray()) {
5529
obj1 = dict->lookup("IC");
5530
if (obj1.isArray()) {
5786
5531
interiorColor = new AnnotColor(obj1.getArray());
5788
5533
interiorColor = NULL;
5792
if (dict->lookup("BS", &obj1)->isDict()) {
5536
obj1 = dict->lookup("BS");
5537
if (obj1.isDict()) {
5794
5539
border = new AnnotBorderBS(obj1.getDict());
5795
5540
} else if (!border) {
5796
5541
border = new AnnotBorderBS();
5800
if (dict->lookup("BE", &obj1)->isDict()) {
5544
obj1 = dict->lookup("BE");
5545
if (obj1.isDict()) {
5801
5546
borderEffect = new AnnotBorderEffect(obj1.getDict());
5803
5548
borderEffect = NULL;
5807
if (dict->lookup("IT", &obj1)->isName()) {
5551
obj1 = dict->lookup("IT");
5552
if (obj1.isName()) {
5808
5553
const char *intentName = obj1.getName();
5810
5555
if(!strcmp(intentName, "PolygonCloud")) {
5818
5563
intent = polygonCloud;
5823
5567
void AnnotPolygon::setType(AnnotSubtype new_type) {
5568
const char *typeName = nullptr; /* squelch bogus compiler warning */
5826
5570
switch (new_type) {
5827
5571
case typePolygon:
5828
obj1.initName("Polygon");
5572
typeName = "Polygon";
5830
5574
case typePolyLine:
5831
obj1.initName("PolyLine");
5575
typeName = "PolyLine";
5834
5578
assert(!"Invalid subtype");
5837
5581
type = new_type;
5838
update("Subtype", &obj1);
5582
update("Subtype", Object(objName, typeName));
5839
5583
invalidateAppearance();
5842
5586
void AnnotPolygon::setVertices(AnnotPath *path) {
5844
5587
delete vertices;
5846
obj1.initArray(xref);
5589
Array *a = new Array(xref);
5848
5590
for (int i = 0; i < path->getCoordsLength(); i++) {
5849
obj1.arrayAdd (obj2.initReal (path->getX(i)));
5850
obj1.arrayAdd (obj2.initReal (path->getY(i)));
5591
a->add(Object(path->getX(i)));
5592
a->add(Object(path->getY(i)));
5853
vertices = new AnnotPath(obj1.getArray());
5595
vertices = new AnnotPath(a);
5855
update("Vertices", &obj1);
5597
update("Vertices", Object(a));
5856
5598
invalidateAppearance();
5859
5601
void AnnotPolygon::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
5862
5602
startStyle = start;
5863
5603
endStyle = end;
5865
obj1.initArray(xref);
5866
obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( startStyle )) );
5867
obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( endStyle )) );
5605
Array *a = new Array(xref);
5606
a->add( Object(objName, convertAnnotLineEndingStyle( startStyle )) );
5607
a->add( Object(objName, convertAnnotLineEndingStyle( endStyle )) );
5869
update("LE", &obj1);
5609
update("LE", Object(a));
5870
5610
invalidateAppearance();
5948
5686
double bbox[4];
5949
5687
appearBBox->getBBoxRect(bbox);
5951
createForm(bbox, gFalse, NULL, &appearance);
5689
appearance = createForm(bbox, gFalse, nullptr);
5953
Object aStream, resDict;
5955
createForm(bbox, gTrue, NULL, &aStream);
5691
Object aStream = createForm(bbox, gTrue, nullptr);
5956
5692
delete appearBuf;
5958
5694
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
5959
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
5960
createForm(bbox, gFalse, &resDict, &appearance);
5695
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
5696
appearance = createForm(bbox, gFalse, resDict);
5962
5698
delete appearBuf;
5965
5701
// draw the appearance stream
5966
appearance.fetch(gfx->getXRef(), &obj);
5702
Object obj = appearance.fetch(gfx->getXRef());
5967
5703
if (appearBBox) {
5968
5704
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
5969
5705
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
6040
5772
type = typeInk;
6042
annotObj.dictSet ("Subtype", obj1.initName ("Ink"));
5774
annotObj.dictSet ("Subtype", Object(objName, "Ink"));
6044
5776
// Store dummy path with one null vertex only
6045
Object obj2, obj3, obj4;
6046
obj2.initArray (doc->getXRef());
6047
obj2.arrayAdd (obj3.initArray (doc->getXRef()));
6048
obj3.arrayAdd (obj4.initReal (0));
6049
obj3.arrayAdd (obj4.initReal (0));
6050
annotObj.dictSet ("InkList", &obj2);
5778
Array *inkList = new Array(doc->getXRef());
5779
Array *vList = new Array(doc->getXRef());
5780
vList->add(Object(0.));
5781
vList->add(Object(0.));
5782
inkList->add(Object(vList));
5783
annotObj.dictSet("InkList", Object(inkList));
6052
5785
initialize(docA, annotObj.getDict());
6055
AnnotInk::AnnotInk(PDFDoc *docA, Dict *dict, Object *obj) :
6056
AnnotMarkup(docA, dict, obj) {
5788
AnnotInk::AnnotInk(PDFDoc *docA, Object *dictObject, Object *obj) :
5789
AnnotMarkup(docA, dictObject, obj) {
6057
5790
type = typeInk;
6058
initialize(docA, dict);
5791
initialize(docA, dictObject->getDict());
6061
5794
AnnotInk::~AnnotInk() {
6073
5807
error(errSyntaxError, -1, "Bad Annot Ink List");
6078
if (dict->lookup("BS", &obj1)->isDict()) {
5811
obj1 = dict->lookup("BS");
5812
if (obj1.isDict()) {
6080
5814
border = new AnnotBorderBS(obj1.getDict());
6081
5815
} else if (!border) {
6082
5816
border = new AnnotBorderBS();
6087
5820
void AnnotInk::writeInkList(AnnotPath **paths, int n_paths, Array *dest_array) {
6089
5821
for (int i = 0; i < n_paths; ++i) {
6090
5822
AnnotPath *path = paths[i];
6091
obj1.initArray (xref);
5823
Array *a = new Array(xref);
6092
5824
for (int j = 0; j < path->getCoordsLength(); ++j) {
6093
obj1.arrayAdd (obj2.initReal (path->getX(j)));
6094
obj1.arrayAdd (obj2.initReal (path->getY(j)));
5825
a->add(Object(path->getX(j)));
5826
a->add(Object(path->getY(j)));
6096
dest_array->add (&obj1);
5828
dest_array->add(Object(a));
6172
5900
double bbox[4];
6173
5901
appearBBox->getBBoxRect(bbox);
6175
createForm(bbox, gFalse, NULL, &appearance);
5903
appearance = createForm(bbox, gFalse, nullptr);
6177
Object aStream, resDict;
6179
createForm(bbox, gTrue, NULL, &aStream);
5905
Object aStream = createForm(bbox, gTrue, nullptr);
6180
5906
delete appearBuf;
6182
5908
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
6183
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
6184
createForm(bbox, gFalse, &resDict, &appearance);
5909
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
5910
appearance = createForm(bbox, gFalse, resDict);
6186
5912
delete appearBuf;
6189
5915
// draw the appearance stream
6190
appearance.fetch(gfx->getXRef(), &obj);
5916
Object obj = appearance.fetch(gfx->getXRef());
6191
5917
if (appearBBox) {
6192
5918
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
6193
5919
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
6210
5935
type = typeFileAttachment;
6212
annotObj.dictSet ("Subtype", obj1.initName ("FileAttachment"));
6215
obj2.initString(filename->copy());
6216
annotObj.dictSet ("FS", &obj2);
5937
annotObj.dictSet("Subtype", Object(objName, "FileAttachment"));
5938
annotObj.dictSet("FS", Object(filename->copy()));
6218
5940
initialize(docA, annotObj.getDict());
6221
AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, Dict *dict, Object *obj) :
6222
AnnotMarkup(docA, dict, obj) {
5943
AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, Object *dictObject, Object *obj) :
5944
AnnotMarkup(docA, dictObject, obj) {
6223
5945
type = typeFileAttachment;
6224
initialize(docA, dict);
5946
initialize(docA, dictObject->getDict());
6227
5949
AnnotFileAttachment::~AnnotFileAttachment() {
6234
5953
void AnnotFileAttachment::initialize(PDFDoc *docA, Dict* dict) {
6237
if (dict->lookup("FS", &obj1)->isDict() || dict->lookup("FS", &obj1)->isString()) {
5956
obj1 = dict->lookup("FS");
5957
if (obj1.isDict() || obj1.isString()) {
6240
5960
error(errSyntaxError, -1, "Bad Annot File Attachment");
6245
if (dict->lookup("Name", &obj1)->isName()) {
5964
obj1 = dict->lookup("Name");
5965
if (obj1.isName()) {
6246
5966
name = new GooString(obj1.getName());
6248
5968
name = new GooString("PushPin");
6253
5972
#define ANNOT_FILE_ATTACHMENT_AP_PUSHPIN \
6394
6112
bbox[0] = bbox[1] = 0;
6395
6113
bbox[2] = bbox[3] = 24;
6397
createForm (bbox, gFalse, NULL, &appearance);
6115
appearance = createForm (bbox, gFalse, nullptr);
6401
createForm (bbox, gTrue, NULL, &aStream);
6117
Object aStream = createForm (bbox, gTrue, nullptr);
6402
6118
delete appearBuf;
6405
6120
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
6406
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
6407
createForm(bbox, gFalse, &resDict, &appearance);
6121
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
6122
appearance = createForm(bbox, gFalse, resDict);
6409
6124
delete appearBuf;
6412
6127
// draw the appearance stream
6413
appearance.fetch(gfx->getXRef(), &obj);
6128
Object obj = appearance.fetch(gfx->getXRef());
6414
6129
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
6415
6130
rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
6419
6133
//------------------------------------------------------------------------
6426
6140
type = typeSound;
6428
annotObj.dictSet ("Subtype", obj1.initName ("Sound"));
6431
Stream *str = soundA->getStream();
6432
obj2.initStream (str);
6433
str->incRef(); //FIXME: initStream should do this?
6434
annotObj.dictSet ("Sound", &obj2);
6142
annotObj.dictSet ("Subtype", Object(objName, "Sound"));
6143
annotObj.dictSet ("Sound", soundA->getObject()->copy());
6436
6145
initialize(docA, annotObj.getDict());
6439
AnnotSound::AnnotSound(PDFDoc *docA, Dict *dict, Object *obj) :
6440
AnnotMarkup(docA, dict, obj) {
6148
AnnotSound::AnnotSound(PDFDoc *docA, Object *dictObject, Object *obj) :
6149
AnnotMarkup(docA, dictObject, obj) {
6441
6150
type = typeSound;
6442
initialize(docA, dict);
6151
initialize(docA, dictObject->getDict());
6445
6154
AnnotSound::~AnnotSound() {
6557
6265
bbox[0] = bbox[1] = 0;
6558
6266
bbox[2] = bbox[3] = 24;
6560
createForm(bbox, gFalse, NULL, &appearance);
6268
appearance = createForm(bbox, gFalse, nullptr);
6562
Object aStream, resDict;
6564
createForm(bbox, gTrue, NULL, &aStream);
6270
Object aStream = createForm(bbox, gTrue, nullptr);
6565
6271
delete appearBuf;
6567
6273
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
6568
createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
6569
createForm(bbox, gFalse, &resDict, &appearance);
6274
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, NULL);
6275
appearance = createForm(bbox, gFalse, resDict);
6571
6277
delete appearBuf;
6574
6280
// draw the appearance stream
6575
appearance.fetch(gfx->getXRef(), &obj);
6281
obj = appearance.fetch(gfx->getXRef());
6576
6282
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
6577
6283
rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
6581
6286
//------------------------------------------------------------------------
6833
6528
AnnotRichMedia::Content::Content(Dict *dict) {
6836
if (dict->lookup("Configurations", &obj1)->isArray()) {
6529
Object obj1 = dict->lookup("Configurations");
6530
if (obj1.isArray()) {
6837
6531
nConfigurations = obj1.arrayGetLength();
6839
6533
configurations = (Configuration **)gmallocn(nConfigurations, sizeof(Configuration *));
6841
6535
for (int i = 0; i < nConfigurations; ++i) {
6844
if (obj1.arrayGet(i, &obj2)->isDict()) {
6536
Object obj2 = obj1.arrayGet(i);
6537
if (obj2.isDict()) {
6845
6538
configurations[i] = new AnnotRichMedia::Configuration(obj2.getDict());
6847
6540
configurations[i] = NULL;
6852
6544
nConfigurations = 0;
6853
6545
configurations = NULL;
6859
if (dict->lookup("Assets", &obj1)->isDict()) {
6862
if (obj1.getDict()->lookup("Names", &obj2)->isArray()) {
6550
obj1 = dict->lookup("Assets");
6551
if (obj1.isDict()) {
6552
Object obj2 = obj1.getDict()->lookup("Names");
6553
if (obj2.isArray()) {
6863
6554
nAssets = obj2.arrayGetLength() / 2;
6865
6556
assets = (Asset **)gmallocn(nAssets, sizeof(Asset *));
6867
6558
int counter = 0;
6868
for (int i = 0; i < obj2.arrayGetLength(); i += 2) {
6559
for (int i = 0; i < nAssets; ++i) {
6871
6560
assets[counter] = new AnnotRichMedia::Asset;
6873
obj2.arrayGet(i, &objKey);
6874
obj2.arrayGet(i + 1, &assets[counter]->fileSpec);
6562
Object objKey = obj2.arrayGet(i * 2);
6563
assets[counter]->fileSpec = obj2.arrayGet(i * 2 + 1);
6876
6565
assets[counter]->name = new GooString( objKey.getString() );
6887
6573
AnnotRichMedia::Content::~Content() {
6942
6627
AnnotRichMedia::Configuration::Configuration(Dict *dict)
6946
if (dict->lookup("Instances", &obj1)->isArray()) {
6629
Object obj1 = dict->lookup("Instances");
6630
if (obj1.isArray()) {
6947
6631
nInstances = obj1.arrayGetLength();
6949
6633
instances = (Instance **)gmallocn(nInstances, sizeof(Instance *));
6951
6635
for (int i = 0; i < nInstances; ++i) {
6954
if (obj1.arrayGet(i, &obj2)->isDict()) {
6636
Object obj2 = obj1.arrayGet(i);
6637
if (obj2.isDict()) {
6955
6638
instances[i] = new AnnotRichMedia::Instance(obj2.getDict());
6957
6640
instances[i] = NULL;
6962
6644
instances = NULL;
6966
if (dict->lookup("Name", &obj1)->isString()) {
6647
obj1 = dict->lookup("Name");
6648
if (obj1.isString()) {
6967
6649
name = new GooString(obj1.getString());
6973
if (dict->lookup("Subtype", &obj1)->isName()) {
6654
obj1 = dict->lookup("Subtype");
6655
if (obj1.isName()) {
6974
6656
const char *name = obj1.getName();
6976
6658
if (!strcmp(name, "3D")) {
6982
6664
} else if (!strcmp(name, "Video")) {
6983
6665
type = typeVideo;
6985
// determine from first instance
6667
// determine from first non null instance
6668
type = typeFlash; // default in case all instances are null
6986
6669
if (instances && nInstances > 0) {
6987
AnnotRichMedia::Instance *instance = instances[0];
6988
switch (instance->getType()) {
6989
case AnnotRichMedia::Instance::type3D:
6992
case AnnotRichMedia::Instance::typeFlash:
6995
case AnnotRichMedia::Instance::typeSound:
6998
case AnnotRichMedia::Instance::typeVideo:
6670
for (int i = 0; i < nInstances; ++i) {
6671
AnnotRichMedia::Instance *instance = instances[i];
6673
switch (instance->getType()) {
6674
case AnnotRichMedia::Instance::type3D:
6677
case AnnotRichMedia::Instance::typeFlash:
6680
case AnnotRichMedia::Instance::typeSound:
6683
case AnnotRichMedia::Instance::typeVideo:
6687
// break the loop since we found the first non null instance
7011
6696
AnnotRichMedia::Configuration::~Configuration()
7169
Annot *Annots::createAnnot(Dict* dict, Object *obj) {
7170
Annot *annot = NULL;
7173
if (dict->lookup("Subtype", &obj1)->isName()) {
6846
Annot *Annots::createAnnot(Object* dictObject, Object *obj) {
6847
Annot *annot = nullptr;
6848
Object obj1 = dictObject->dictLookup("Subtype");
6849
if (obj1.isName()) {
7174
6850
const char *typeName = obj1.getName();
7176
6852
if (!strcmp(typeName, "Text")) {
7177
annot = new AnnotText(doc, dict, obj);
6853
annot = new AnnotText(doc, dictObject, obj);
7178
6854
} else if (!strcmp(typeName, "Link")) {
7179
annot = new AnnotLink(doc, dict, obj);
6855
annot = new AnnotLink(doc, dictObject, obj);
7180
6856
} else if (!strcmp(typeName, "FreeText")) {
7181
annot = new AnnotFreeText(doc, dict, obj);
6857
annot = new AnnotFreeText(doc, dictObject, obj);
7182
6858
} else if (!strcmp(typeName, "Line")) {
7183
annot = new AnnotLine(doc, dict, obj);
6859
annot = new AnnotLine(doc, dictObject, obj);
7184
6860
} else if (!strcmp(typeName, "Square")) {
7185
annot = new AnnotGeometry(doc, dict, obj);
6861
annot = new AnnotGeometry(doc, dictObject, obj);
7186
6862
} else if (!strcmp(typeName, "Circle")) {
7187
annot = new AnnotGeometry(doc, dict, obj);
6863
annot = new AnnotGeometry(doc, dictObject, obj);
7188
6864
} else if (!strcmp(typeName, "Polygon")) {
7189
annot = new AnnotPolygon(doc, dict, obj);
6865
annot = new AnnotPolygon(doc, dictObject, obj);
7190
6866
} else if (!strcmp(typeName, "PolyLine")) {
7191
annot = new AnnotPolygon(doc, dict, obj);
6867
annot = new AnnotPolygon(doc, dictObject, obj);
7192
6868
} else if (!strcmp(typeName, "Highlight")) {
7193
annot = new AnnotTextMarkup(doc, dict, obj);
6869
annot = new AnnotTextMarkup(doc, dictObject, obj);
7194
6870
} else if (!strcmp(typeName, "Underline")) {
7195
annot = new AnnotTextMarkup(doc, dict, obj);
6871
annot = new AnnotTextMarkup(doc, dictObject, obj);
7196
6872
} else if (!strcmp(typeName, "Squiggly")) {
7197
annot = new AnnotTextMarkup(doc, dict, obj);
6873
annot = new AnnotTextMarkup(doc, dictObject, obj);
7198
6874
} else if (!strcmp(typeName, "StrikeOut")) {
7199
annot = new AnnotTextMarkup(doc, dict, obj);
6875
annot = new AnnotTextMarkup(doc, dictObject, obj);
7200
6876
} else if (!strcmp(typeName, "Stamp")) {
7201
annot = new AnnotStamp(doc, dict, obj);
6877
annot = new AnnotStamp(doc, dictObject, obj);
7202
6878
} else if (!strcmp(typeName, "Caret")) {
7203
annot = new AnnotCaret(doc, dict, obj);
6879
annot = new AnnotCaret(doc, dictObject, obj);
7204
6880
} else if (!strcmp(typeName, "Ink")) {
7205
annot = new AnnotInk(doc, dict, obj);
6881
annot = new AnnotInk(doc, dictObject, obj);
7206
6882
} else if (!strcmp(typeName, "FileAttachment")) {
7207
annot = new AnnotFileAttachment(doc, dict, obj);
6883
annot = new AnnotFileAttachment(doc, dictObject, obj);
7208
6884
} else if (!strcmp(typeName, "Sound")) {
7209
annot = new AnnotSound(doc, dict, obj);
6885
annot = new AnnotSound(doc, dictObject, obj);
7210
6886
} else if(!strcmp(typeName, "Movie")) {
7211
annot = new AnnotMovie(doc, dict, obj);
6887
annot = new AnnotMovie(doc, dictObject, obj);
7212
6888
} else if(!strcmp(typeName, "Widget")) {
7213
6889
// Find the annot in forms
7214
6890
if (obj->isRef()) {
7225
annot = new AnnotWidget(doc, dict, obj);
6901
annot = new AnnotWidget(doc, dictObject, obj);
7226
6902
} else if(!strcmp(typeName, "Screen")) {
7227
annot = new AnnotScreen(doc, dict, obj);
6903
annot = new AnnotScreen(doc, dictObject, obj);
7228
6904
} else if(!strcmp(typeName, "PrinterMark")) {
7229
annot = new Annot(doc, dict, obj);
6905
annot = new Annot(doc, dictObject, obj);
7230
6906
} else if (!strcmp(typeName, "TrapNet")) {
7231
annot = new Annot(doc, dict, obj);
6907
annot = new Annot(doc, dictObject, obj);
7232
6908
} else if (!strcmp(typeName, "Watermark")) {
7233
annot = new Annot(doc, dict, obj);
6909
annot = new Annot(doc, dictObject, obj);
7234
6910
} else if (!strcmp(typeName, "3D")) {
7235
annot = new Annot3D(doc, dict, obj);
6911
annot = new Annot3D(doc, dictObject, obj);
7236
6912
} else if (!strcmp(typeName, "RichMedia")) {
7237
annot = new AnnotRichMedia(doc, dict, obj);
6913
annot = new AnnotRichMedia(doc, dictObject, obj);
7238
6914
} else if (!strcmp(typeName, "Popup")) {
7239
6915
/* Popup annots are already handled by markup annots
7240
6916
* Here we only care about popup annots without a
7241
6917
* markup annotation associated
7245
if (dict->lookup("Parent", &obj2)->isNull())
7246
annot = new AnnotPopup(doc, dict, obj);
6919
Object obj2 = dictObject->dictLookup("Parent");
6921
annot = new AnnotPopup(doc, dictObject, obj);
7252
annot = new Annot(doc, dict, obj);
6925
annot = new Annot(doc, dictObject, obj);