~naesten/tex-live/trunk

« back to all changes in this revision

Viewing changes to libs/poppler/poppler-src/poppler/Annot.cc

  • Committer: karl
  • Date: 2018-01-09 18:53:05 UTC
  • Revision ID: svn-v4:c570f23f-e606-0410-a88d-b1316a301751:trunk/Build/source:46257
poppler 0.62.0, requiring C++11; luatex not updated yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
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>
38
39
//
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
76
77
#include <string.h>
77
78
#include <algorithm>
78
79
 
79
 
#if MULTITHREADED
 
80
#ifdef MULTITHREADED
80
81
#  define annotLocker()   MutexLocker locker(&mutex)
81
82
#  define annotCondLocker(X)  MutexLocker locker(&mutex, (X))
82
83
#else
112
113
// = (4 * (sqrt(2) - 1) / 3) * r
113
114
#define bezierCircle 0.55228475
114
115
 
115
 
AnnotLineEndingStyle parseAnnotLineEndingStyle(GooString *string) {
 
116
static AnnotLineEndingStyle parseAnnotLineEndingStyle(GooString *string) {
116
117
  if (string != NULL) {
117
118
    if (!string->cmp("Square")) {
118
119
      return annotLineEndingSquare;
140
141
  }  
141
142
}
142
143
 
143
 
const char* convertAnnotLineEndingStyle(AnnotLineEndingStyle style) {
 
144
static const char* convertAnnotLineEndingStyle(AnnotLineEndingStyle style) {
144
145
  switch (style) {
145
146
    case annotLineEndingSquare:
146
147
      return "Square";
166
167
}
167
168
 
168
169
static AnnotExternalDataType parseAnnotExternalData(Dict* dict) {
169
 
  Object obj1;
170
170
  AnnotExternalDataType type;
171
171
 
172
 
  if (dict->lookup("Subtype", &obj1)->isName()) {
 
172
  Object obj1 = dict->lookup("Subtype");
 
173
  if (obj1.isName()) {
173
174
    const char *typeName = obj1.getName();
174
175
 
175
176
    if (!strcmp(typeName, "Markup3D")) {
180
181
  } else {
181
182
    type = annotExternalDataMarkupUnknown;
182
183
  }
183
 
  obj1.free();
184
184
 
185
185
  return type;
186
186
}
187
187
 
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) {
191
191
    // deltas
192
192
    Object obj1;
193
 
    double dx1 = (array->get(0, &obj1)->isNum() ? obj1.getNum() : 0);
194
 
    obj1.free();
195
 
    double dy1 = (array->get(1, &obj1)->isNum() ? obj1.getNum() : 0);
196
 
    obj1.free();
197
 
    double dx2 = (array->get(2, &obj1)->isNum() ? obj1.getNum() : 0);
198
 
    obj1.free();
199
 
    double dy2 = (array->get(3, &obj1)->isNum() ? obj1.getNum() : 0);
200
 
    obj1.free();
 
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);
201
197
 
202
198
    // checking that the numbers are valid (i.e. >= 0),
203
199
    // and that applying the differences still give us a valid rect
215
211
}
216
212
 
217
213
static LinkAction* getAdditionalAction(Annot::AdditionalActionsType type, Object *additionalActions, PDFDoc *doc) {
218
 
  Object additionalActionsObject;
219
 
  LinkAction *linkAction = NULL;
 
214
  LinkAction *linkAction = nullptr;
 
215
  Object additionalActionsObject = additionalActions->fetch(doc->getXRef());
220
216
 
221
 
  if (additionalActions->fetch(doc->getXRef(), &additionalActionsObject)->isDict()) {
 
217
  if (additionalActionsObject.isDict()) {
222
218
    const char *key = (type == Annot::actionCursorEntering ? "E" :
223
219
                       type == Annot::actionCursorLeaving ?  "X" :
224
220
                       type == Annot::actionMousePressed ?   "D" :
230
226
                       type == Annot::actionPageVisible ?   "PV" :
231
227
                       type == Annot::actionPageInvisible ? "PI" : NULL);
232
228
 
233
 
    Object actionObject;
234
 
 
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());
237
 
    actionObject.free();
238
232
  }
239
233
 
240
 
  additionalActionsObject.free();
241
 
 
242
234
  return linkAction;
243
235
}
244
236
 
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());
248
240
 
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);
254
246
 
255
 
    Object actionObject;
256
 
 
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());
259
 
    actionObject.free();
260
250
  }
261
251
 
262
 
  additionalActionsObject.free();
263
 
 
264
252
  return linkAction;
265
253
}
266
254
 
271
259
AnnotBorderEffect::AnnotBorderEffect(Dict *dict) {
272
260
  Object obj1;
273
261
 
274
 
  if (dict->lookup("S", &obj1)->isName()) {
 
262
  obj1 = dict->lookup("S");
 
263
  if (obj1.isName()) {
275
264
    const char *effectName = obj1.getName();
276
265
 
277
266
    if (!strcmp(effectName, "C"))
281
270
  } else {
282
271
    effectType = borderEffectNoEffect;
283
272
  }
284
 
  obj1.free();
285
273
 
286
 
  if ((dict->lookup("I", &obj1)->isNum()) && effectType == borderEffectCloudy) {
 
274
  obj1 = dict->lookup("I");
 
275
  if (obj1.isNum() && effectType == borderEffectCloudy) {
287
276
    intensity = obj1.getNum();
288
277
  } else {
289
278
    intensity = 0;
290
279
  }
291
 
  obj1.free();
292
280
}
293
281
 
294
282
//------------------------------------------------------------------------
351
339
  tempCoords = (AnnotCoord **) gmallocn (tempLength, sizeof(AnnotCoord *));
352
340
  memset(tempCoords, 0, tempLength * sizeof(AnnotCoord *));
353
341
  for (int i = 0; i < tempLength && correct; i++) {
354
 
    Object obj1;
355
342
    double x = 0, y = 0;
356
343
 
357
 
    if (array->get(i * 2, &obj1)->isNum()) {
 
344
    Object obj1 = array->get(i * 2);
 
345
    if (obj1.isNum()) {
358
346
      x = obj1.getNum();
359
347
    } else {
360
348
      correct = gFalse;
361
349
    }
362
 
    obj1.free();
363
350
 
364
 
    if (array->get((i * 2) + 1, &obj1)->isNum()) {
 
351
    obj1 = array->get((i * 2) + 1);
 
352
    if (obj1.isNum()) {
365
353
      y = obj1.getNum();
366
354
    } else {
367
355
      correct = gFalse;
368
356
    }
369
 
    obj1.free();
370
357
 
371
358
    if (!correct) {
372
359
      for (int j = i - 1; j >= 0; j--)
424
411
 
425
412
    for (i = 0; i < quadsLength; i++) {
426
413
      for (int j = 0; j < 8; j++) {
427
 
        Object obj;
428
 
        if (array->get(i * 8 + j, &obj)->isNum()) {
 
414
        Object obj = array->get(i * 8 + j);
 
415
        if (obj.isNum()) {
429
416
          quadArray[j] = obj.getNum();
430
417
        } else {
431
418
            correct = gFalse;
432
 
            obj.free();
433
419
            error (errSyntaxError, -1, "Invalid QuadPoint in annot");
434
420
            break;
435
421
        }
436
 
        obj.free();
437
422
      }
438
423
 
439
424
      if (!correct)
540
525
 
541
526
  // TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
542
527
  for (int i = 0; i < tempLength && i < DASH_LIMIT && correct; i++) {
543
 
    Object obj1;
544
 
 
545
 
    if (dashObj->arrayGet(i, &obj1)->isNum()) {
 
528
    Object obj1 = dashObj->arrayGet(i);
 
529
    if (obj1.isNum()) {
546
530
      tempDash[i] = obj1.getNum();
547
531
 
548
532
      correct = tempDash[i] >= 0;
549
 
      obj1.free();
550
533
    }
551
534
  }
552
535
 
583
566
  if (arrayLength == 3 || arrayLength == 4) {
584
567
    // implementation note 81 in Appendix H.
585
568
 
586
 
    if (array->get(0, &obj1)->isNum())
 
569
    obj1 = array->get(0);
 
570
    if (obj1.isNum())
587
571
      horizontalCorner = obj1.getNum();
588
572
    else
589
573
      correct = gFalse;
590
 
    obj1.free();
591
574
 
592
 
    if (array->get(1, &obj1)->isNum())
 
575
    obj1 = array->get(1);
 
576
    if (obj1.isNum())
593
577
      verticalCorner = obj1.getNum();
594
578
    else
595
579
      correct = gFalse;
596
 
    obj1.free();
597
580
 
598
 
    if (array->get(2, &obj1)->isNum())
 
581
    obj1 = array->get(2);
 
582
    if (obj1.isNum())
599
583
      width = obj1.getNum();
600
584
    else
601
585
      correct = gFalse;
602
 
    obj1.free();
603
586
 
604
587
    if (arrayLength == 4) {
605
 
      if (array->get(3, &obj1)->isArray())
 
588
      obj1 = array->get(3);
 
589
      if (obj1.isArray())
606
590
        correct = parseDashArray(&obj1);
607
591
      else
608
592
        correct = gFalse;
609
 
      obj1.free();
610
593
    }
611
594
  } else {
612
595
    correct = gFalse;
617
600
  }
618
601
}
619
602
 
620
 
void AnnotBorderArray::writeToObject(XRef *xref, Object *obj1) const {
621
 
  Object obj2;
622
 
 
623
 
  obj1->initArray(xref);
624
 
  obj1->arrayAdd(obj2.initReal(horizontalCorner));
625
 
  obj1->arrayAdd(obj2.initReal(verticalCorner));
626
 
  obj1->arrayAdd(obj2.initReal(width));
 
603
Object AnnotBorderArray::writeToObject(XRef *xref) const {
 
604
  Array *borderArray = new Array(xref);
 
605
  borderArray->add(Object(horizontalCorner));
 
606
  borderArray->add(Object(verticalCorner));
 
607
  borderArray->add(Object(width));
627
608
 
628
609
  if (dashLength > 0) {
629
 
    Object obj3;
 
610
    Array *a = new Array(xref);
630
611
 
631
 
    obj1->arrayAdd(obj3.initArray(xref));
632
612
    for (int i = 0; i < dashLength; i++)
633
 
      obj3.arrayAdd(obj2.initReal(dash[i]));
 
613
      a->add(Object(dash[i]));
 
614
 
 
615
    borderArray->add(Object(a));
634
616
  }
 
617
 
 
618
  return Object(borderArray);
635
619
}
636
620
 
637
621
//------------------------------------------------------------------------
650
634
  // that behaviour by veryifying both entries exist
651
635
  // otherwise we set the borderWidth to 0
652
636
  // --jrmuizel
653
 
  dict->lookup("W", &obj1);
654
 
  dict->lookup("S", &obj2);
 
637
  obj1 = dict->lookup("W");
 
638
  obj2 = dict->lookup("S");
655
639
  if (obj1.isNum() && obj2.isName()) {
656
640
    const char *styleName = obj2.getName();
657
641
 
673
657
  } else {
674
658
    width = 0;
675
659
  }
676
 
  obj2.free();
677
 
  obj1.free();
678
660
 
679
661
  if (style == borderDashed) {
680
 
    if (dict->lookup("D", &obj1)->isArray())
 
662
    obj1 = dict->lookup("D");
 
663
  if (obj1.isArray())
681
664
      parseDashArray(&obj1);
682
 
    obj1.free();
683
665
 
684
666
    if (!dash) {
685
667
      dashLength = 1;
706
688
  return "S";
707
689
}
708
690
 
709
 
void AnnotBorderBS::writeToObject(XRef *xref, Object *obj1) const {
710
 
  Object obj2;
711
 
 
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) {
716
 
    Object obj3;
 
696
    Array *a = new Array(xref);
717
697
 
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));
721
701
  }
 
702
  return Object(dict);
722
703
}
723
704
 
724
705
//------------------------------------------------------------------------
763
744
    length = 4;
764
745
 
765
746
  for (i = 0; i < length; i++) {
766
 
    Object obj1;
767
 
 
768
 
    if (array->get(i, &obj1)->isNum()) {
 
747
    Object obj1 = array->get(i);
 
748
    if (obj1.isNum()) {
769
749
      values[i] = obj1.getNum();
770
750
 
771
751
      if (values[i] < 0 || values[i] > 1)
773
753
    } else {
774
754
      values[i] = 0;
775
755
    }
776
 
    obj1.free();
777
756
  }
778
757
 
779
758
  if (adjust != 0)
797
776
  }
798
777
}
799
778
 
800
 
void AnnotColor::writeToObject(XRef *xref, Object *obj1) const {
801
 
  Object obj2;
802
 
  int i;
803
 
 
 
779
Object AnnotColor::writeToObject(XRef *xref) const {
804
780
  if (length == 0) {
805
 
    obj1->initNull(); // Transparent (no color)
 
781
    return Object(objNull); // Transparent (no color)
806
782
  } else {
807
 
    obj1->initArray(xref);
808
 
    for (i = 0; i < length; ++i)
809
 
      obj1->arrayAdd( obj2.initReal( values[i] ) );
 
783
    Array *a = new Array(xref);
 
784
    for (int i = 0; i < length; ++i)
 
785
      a->add( Object( values[i] ) );
 
786
    return Object(a);
810
787
  }
811
788
}
812
789
 
817
794
AnnotIconFit::AnnotIconFit(Dict* dict) {
818
795
  Object obj1;
819
796
 
820
 
  if (dict->lookup("SW", &obj1)->isName()) {
 
797
  obj1 = dict->lookup("SW");
 
798
  if (obj1.isName()) {
821
799
    const char *scaleName = obj1.getName();
822
800
 
823
801
    if(!strcmp(scaleName, "B")) {
832
810
  } else {
833
811
    scaleWhen = scaleAlways;
834
812
  }
835
 
  obj1.free();
836
813
 
837
 
  if (dict->lookup("S", &obj1)->isName()) {
 
814
  obj1 = dict->lookup("S");
 
815
  if (obj1.isName()) {
838
816
    const char *scaleName = obj1.getName();
839
817
 
840
818
    if(!strcmp(scaleName, "A")) {
845
823
  } else {
846
824
    scale = scaleProportional;
847
825
  }
848
 
  obj1.free();
849
826
 
850
 
  if (dict->lookup("A", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
 
827
  obj1 = dict->lookup("A");
 
828
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
851
829
    Object obj2;
852
 
    (obj1.arrayGet(0, &obj2)->isNum() ? left = obj2.getNum() : left = 0);
853
 
    obj2.free();
854
 
    (obj1.arrayGet(1, &obj2)->isNum() ? bottom = obj2.getNum() : bottom = 0);
855
 
    obj2.free();
 
830
    (obj2 = obj1.arrayGet(0), obj2.isNum() ? left = obj2.getNum() : left = 0);
 
831
    (obj2 = obj1.arrayGet(1), obj2.isNum() ? bottom = obj2.getNum() : bottom = 0);
856
832
 
857
833
    if (left < 0 || left > 1)
858
834
      left = 0.5;
863
839
  } else {
864
840
    left = bottom = 0.5;
865
841
  }
866
 
  obj1.free();
867
842
 
868
 
  if (dict->lookup("FB", &obj1)->isBool()) {
 
843
  obj1 = dict->lookup("FB");
 
844
  if (obj1.isBool()) {
869
845
    fullyBounds = obj1.getBool();
870
846
  } else {
871
847
    fullyBounds = gFalse;
872
848
  }
873
 
  obj1.free();
874
849
}
875
850
 
876
851
//------------------------------------------------------------------------
881
856
  assert(dict->isDict());
882
857
  doc = docA;
883
858
  xref = docA->getXRef();
884
 
  dict->copy(&appearDict);
 
859
  appearDict = dict->copy();
885
860
}
886
861
 
887
862
AnnotAppearance::~AnnotAppearance() {
888
 
  appearDict.free();
889
863
}
890
864
 
891
 
void AnnotAppearance::getAppearanceStream(AnnotAppearanceType type, const char *state, Object *dest) {
892
 
  Object apData, stream;
893
 
  apData.initNull();
 
865
Object AnnotAppearance::getAppearanceStream(AnnotAppearanceType type, const char *state) {
 
866
  Object apData;
894
867
 
895
868
  // Obtain dictionary or stream associated to appearance type
896
869
  switch (type) {
897
870
  case appearRollover:
898
 
    if (appearDict.dictLookupNF("R", &apData)->isNull())
899
 
      appearDict.dictLookupNF("N", &apData);
 
871
    apData = appearDict.dictLookupNF("R");
 
872
    if (apData.isNull())
 
873
      apData = appearDict.dictLookupNF("N");
900
874
    break;
901
875
  case appearDown:
902
 
    if (appearDict.dictLookupNF("D", &apData)->isNull())
903
 
      appearDict.dictLookupNF("N", &apData);
 
876
    apData = appearDict.dictLookupNF("D");
 
877
    if (apData.isNull())
 
878
      apData = appearDict.dictLookupNF("N");
904
879
    break;
905
880
  case appearNormal:
906
 
    appearDict.dictLookupNF("N", &apData);
 
881
    apData = appearDict.dictLookupNF("N");
907
882
    break;
908
883
  }
909
884
 
910
 
  dest->initNull();
 
885
  Object res;
911
886
  if (apData.isDict() && state)
912
 
    apData.dictLookupNF(state, dest);
 
887
    res = apData.dictLookupNF(state);
913
888
  else if (apData.isRef())
914
 
    apData.copy(dest);
915
 
  apData.free();
 
889
    res = apData.copy();
 
890
 
 
891
  return res;
916
892
}
917
893
 
918
894
GooString * AnnotAppearance::getStateKey(int i) {
919
 
  Object obj1;
920
895
  GooString * res = NULL;
921
 
  if (appearDict.dictLookupNF("N", &obj1)->isDict())
 
896
  Object obj1 = appearDict.dictLookupNF("N");
 
897
  if (obj1.isDict())
922
898
    res = new GooString(obj1.dictGetKey(i));
923
 
  obj1.free();
924
899
  return res;
925
900
}
926
901
 
927
902
int AnnotAppearance::getNumStates() {
928
 
  Object obj1;
929
903
  int res = 0;
930
 
  if (appearDict.dictLookupNF("N", &obj1)->isDict())
 
904
  Object obj1 = appearDict.dictLookupNF("N");
 
905
  if (obj1.isDict())
931
906
    res = obj1.dictGetLength();
932
 
  obj1.free();
933
907
  return res;
934
908
}
935
909
 
943
917
  } else if (stateObj->isDict()) { // Test each value
944
918
    const int size = stateObj->dictGetLength();
945
919
    for (int i = 0; i < size; ++i) {
946
 
      Object obj1;
947
 
      stateObj->dictGetValNF(i, &obj1);
 
920
      Object obj1 = stateObj->dictGetValNF(i);
948
921
      if (obj1.isRef()) {
949
922
        Ref r = obj1.getRef();
950
923
        if (r.num == refToStream.num && r.gen == refToStream.gen) {
951
924
          return gTrue;
952
925
        }
953
926
      }
954
 
      obj1.free();
955
927
    }
956
928
  }
957
929
  return gFalse; // Not found
963
935
  GBool found;
964
936
 
965
937
  // Scan each state's ref/subdictionary
966
 
  appearDict.dictLookupNF("N", &obj1);
967
 
  found = referencesStream(&obj1, refToStream);
968
 
  obj1.free();
969
 
  if (found)
970
 
    return gTrue;
971
 
 
972
 
  appearDict.dictLookupNF("R", &obj1);
973
 
  found = referencesStream(&obj1, refToStream);
974
 
  obj1.free();
975
 
  if (found)
976
 
    return gTrue;
977
 
 
978
 
  appearDict.dictLookupNF("D", &obj1);
979
 
  found = referencesStream(&obj1, refToStream);
980
 
  obj1.free();
 
938
  obj1 = appearDict.dictLookupNF("N");
 
939
  found = referencesStream(&obj1, refToStream);
 
940
  if (found)
 
941
    return gTrue;
 
942
 
 
943
  obj1 = appearDict.dictLookupNF("R");
 
944
  found = referencesStream(&obj1, refToStream);
 
945
  if (found)
 
946
    return gTrue;
 
947
 
 
948
  obj1 = appearDict.dictLookupNF("D");
 
949
  found = referencesStream(&obj1, refToStream);
981
950
  return found;
982
951
}
983
952
 
1011
980
  } else if (obj1->isDict()) {
1012
981
    const int size = obj1->dictGetLength();
1013
982
    for (int i = 0; i < size; ++i) {
1014
 
      Object obj2;
1015
 
      obj1->dictGetValNF(i, &obj2);
 
983
      Object obj2 = obj1->dictGetValNF(i);
1016
984
      if (obj2.isRef()) {
1017
985
        removeStream(obj2.getRef());
1018
986
      }
1019
 
      obj2.free();
1020
987
    }
1021
988
  }
1022
989
}
1023
990
 
1024
991
void AnnotAppearance::removeAllStreams() {
1025
992
  Object obj1;
1026
 
  appearDict.dictLookupNF("N", &obj1);
1027
 
  removeStateStreams(&obj1);
1028
 
  obj1.free();
1029
 
  appearDict.dictLookupNF("R", &obj1);
1030
 
  removeStateStreams(&obj1);
1031
 
  obj1.free();
1032
 
  appearDict.dictLookupNF("D", &obj1);
1033
 
  removeStateStreams(&obj1);
1034
 
  obj1.free();
 
993
  obj1 = appearDict.dictLookupNF("N");
 
994
  removeStateStreams(&obj1);
 
995
  obj1 = appearDict.dictLookupNF("R");
 
996
  removeStateStreams(&obj1);
 
997
  obj1 = appearDict.dictLookupNF("D");
 
998
  removeStateStreams(&obj1);
1035
999
}
1036
1000
 
1037
1001
//------------------------------------------------------------------------
1041
1005
AnnotAppearanceCharacs::AnnotAppearanceCharacs(Dict *dict) {
1042
1006
  Object obj1;
1043
1007
 
1044
 
  if (dict->lookup("R", &obj1)->isInt()) {
 
1008
  obj1 = dict->lookup("R");
 
1009
  if (obj1.isInt()) {
1045
1010
    rotation = obj1.getInt();
1046
1011
  } else {
1047
1012
    rotation = 0;
1048
1013
  }
1049
 
  obj1.free();
1050
1014
 
1051
 
  if (dict->lookup("BC", &obj1)->isArray()) {
 
1015
  obj1 = dict->lookup("BC");
 
1016
  if (obj1.isArray()) {
1052
1017
    Array *colorComponents = obj1.getArray();
1053
1018
    if (colorComponents->getLength() > 0) {
1054
1019
      borderColor = new AnnotColor(colorComponents);
1058
1023
  } else {
1059
1024
    borderColor = NULL;
1060
1025
  }
1061
 
  obj1.free();
1062
1026
 
1063
 
  if (dict->lookup("BG", &obj1)->isArray()) {
 
1027
  obj1 = dict->lookup("BG");
 
1028
  if (obj1.isArray()) {
1064
1029
    Array *colorComponents = obj1.getArray();
1065
1030
    if (colorComponents->getLength() > 0) {
1066
1031
      backColor = new AnnotColor(colorComponents);
1070
1035
  } else {
1071
1036
    backColor = NULL;
1072
1037
  }
1073
 
  obj1.free();
1074
1038
 
1075
 
  if (dict->lookup("CA", &obj1)->isString()) {
 
1039
  obj1 = dict->lookup("CA");
 
1040
  if (obj1.isString()) {
1076
1041
    normalCaption = new GooString(obj1.getString());
1077
1042
  } else {
1078
1043
    normalCaption = NULL;
1079
1044
  }
1080
 
  obj1.free();
1081
1045
 
1082
 
  if (dict->lookup("RC", &obj1)->isString()) {
 
1046
  obj1 = dict->lookup("RC");
 
1047
  if (obj1.isString()) {
1083
1048
    rolloverCaption = new GooString(obj1.getString());
1084
1049
  } else {
1085
1050
    rolloverCaption = NULL;
1086
1051
  }
1087
 
  obj1.free();
1088
1052
 
1089
 
  if (dict->lookup("AC", &obj1)->isString()) {
 
1053
  obj1 = dict->lookup("AC");
 
1054
  if (obj1.isString()) {
1090
1055
    alternateCaption = new GooString(obj1.getString());
1091
1056
  } else {
1092
1057
    alternateCaption = NULL;
1093
1058
  }
1094
 
  obj1.free();
1095
1059
 
1096
 
  if (dict->lookup("IF", &obj1)->isDict()) {
 
1060
  obj1 = dict->lookup("IF");
 
1061
  if (obj1.isDict()) {
1097
1062
    iconFit = new AnnotIconFit(obj1.getDict());
1098
1063
  } else {
1099
1064
    iconFit = NULL;
1100
1065
  }
1101
 
  obj1.free();
1102
1066
 
1103
 
  if (dict->lookup("TP", &obj1)->isInt()) {
 
1067
  obj1 = dict->lookup("TP");
 
1068
  if (obj1.isInt()) {
1104
1069
    position = (AnnotAppearanceCharacsTextPos) obj1.getInt();
1105
1070
  } else {
1106
1071
    position = captionNoIcon;
1107
1072
  }
1108
 
  obj1.free();
1109
1073
}
1110
1074
 
1111
1075
AnnotAppearanceCharacs::~AnnotAppearanceCharacs() {
1185
1149
//------------------------------------------------------------------------
1186
1150
 
1187
1151
Annot::Annot(PDFDoc *docA, PDFRectangle *rectA) {
1188
 
  Object obj1;
1189
1152
 
1190
1153
  refCnt = 1;
1191
1154
  flags = flagUnknown;
1192
1155
  type = typeUnknown;
1193
1156
 
1194
 
  obj1.initArray (docA->getXRef());
1195
 
  Object obj2;
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));
1200
 
  obj2.free ();
 
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));
1201
1162
 
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));
1206
1166
 
1207
1167
  ref = docA->getXRef()->addIndirectObject (&annotObj);
1208
1168
 
1209
1169
  initialize (docA, annotObj.getDict());
1210
1170
}
1211
1171
 
1212
 
Annot::Annot(PDFDoc *docA, Dict *dict) {
 
1172
Annot::Annot(PDFDoc *docA, Object *dictObject) {
1213
1173
  refCnt = 1;
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());
1219
1179
}
1220
1180
 
1221
 
Annot::Annot(PDFDoc *docA, Dict *dict, Object *obj) {
 
1181
Annot::Annot(PDFDoc *docA, Object *dictObject, Object *obj) {
1222
1182
  refCnt = 1;
1223
1183
  if (obj->isRef()) {
1224
1184
    hasRef = gTrue;
1228
1188
  }
1229
1189
  flags = flagUnknown;
1230
1190
  type = typeUnknown;
1231
 
  annotObj.initDict (dict);
1232
 
  initialize (docA, dict);
 
1191
  annotObj = dictObject->copy();
 
1192
  initialize (docA, dictObject->getDict());
1233
1193
}
1234
1194
 
1235
1195
void Annot::initialize(PDFDoc *docA, Dict *dict) {
1236
 
  Object apObj, asObj, obj1, obj2;
 
1196
  Object apObj, asObj, obj1;
1237
1197
 
1238
1198
  ok = gTrue;
1239
1199
  doc = docA;
1244
1204
  appearBuf = NULL;
1245
1205
  fontSize = 0;
1246
1206
 
1247
 
  appearance.initNull();
 
1207
  appearance.setToNull();
1248
1208
 
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) {
1252
1213
    Object obj2;
1253
 
    (obj1.arrayGet(0, &obj2)->isNum() ? rect->x1 = obj2.getNum() : rect->x1 = 0);
1254
 
    obj2.free();
1255
 
    (obj1.arrayGet(1, &obj2)->isNum() ? rect->y1 = obj2.getNum() : rect->y1 = 0);
1256
 
    obj2.free();
1257
 
    (obj1.arrayGet(2, &obj2)->isNum() ? rect->x2 = obj2.getNum() : rect->x2 = 1);
1258
 
    obj2.free();
1259
 
    (obj1.arrayGet(3, &obj2)->isNum() ? rect->y2 = obj2.getNum() : rect->y2 = 1);
1260
 
    obj2.free();
 
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);
1261
1218
 
1262
1219
    if (rect->x1 > rect->x2) {
1263
1220
      double t = rect->x1;
1276
1233
    error(errSyntaxError, -1, "Bad bounding box for annotation");
1277
1234
    ok = gFalse;
1278
1235
  }
1279
 
  obj1.free();
1280
1236
 
1281
 
  if (dict->lookup("Contents", &obj1)->isString()) {
 
1237
  obj1 = dict->lookup("Contents");
 
1238
  if (obj1.isString()) {
1282
1239
    contents = obj1.getString()->copy();
1283
1240
  } else {
1284
1241
    contents = new GooString();
1285
1242
  }
1286
 
  obj1.free();
1287
1243
 
1288
1244
  // Note: This value is overwritten by Annots ctor
1289
 
  if (dict->lookupNF("P", &obj1)->isRef()) {
 
1245
  obj1 = dict->lookupNF("P");
 
1246
  if (obj1.isRef()) {
1290
1247
    Ref ref = obj1.getRef();
1291
1248
 
1292
1249
    page = doc->getCatalog()->findPage (ref.num, ref.gen);
1293
1250
  } else {
1294
1251
    page = 0;
1295
1252
  }
1296
 
  obj1.free();
1297
1253
 
1298
 
  if (dict->lookup("NM", &obj1)->isString()) {
 
1254
  obj1 = dict->lookup("NM");
 
1255
  if (obj1.isString()) {
1299
1256
    name = obj1.getString()->copy();
1300
1257
  } else {
1301
1258
    name = NULL;
1302
1259
  }
1303
 
  obj1.free();
1304
1260
 
1305
 
  if (dict->lookup("M", &obj1)->isString()) {
 
1261
  obj1 = dict->lookup("M");
 
1262
  if (obj1.isString()) {
1306
1263
    modified = obj1.getString()->copy();
1307
1264
  } else {
1308
1265
    modified = NULL;
1309
1266
  }
1310
 
  obj1.free();
1311
1267
 
1312
1268
  //----- get the flags
1313
 
  if (dict->lookup("F", &obj1)->isInt()) {
 
1269
  obj1 = dict->lookup("F");
 
1270
  if (obj1.isInt()) {
1314
1271
    flags |= obj1.getInt();
1315
1272
  } else {
1316
1273
    flags = flagUnknown;
1317
1274
  }
1318
 
  obj1.free();
1319
1275
 
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);
1324
1280
  }
1325
 
  apObj.free();
1326
1281
 
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) {
1340
1295
  if (!appearState) {
1341
1296
    appearState = new GooString("Off");
1342
1297
  }
1343
 
  asObj.free();
1344
1298
 
1345
1299
  //----- get the annotation appearance
1346
1300
  if (appearStreams) {
1347
 
    appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->getCString(), &appearance);
 
1301
    appearance = appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->getCString());
1348
1302
  }
1349
1303
 
1350
1304
  //----- parse the border style
1352
1306
  // the border shall be drawn as a solid line with a width of 1 point. But acroread
1353
1307
  // seems to ignore the Border entry for annots that can't have a BS entry. So, we only
1354
1308
  // follow this rule for annots tha can have a BS entry.
1355
 
  if (dict->lookup("Border", &obj1)->isArray())
 
1309
  obj1 = dict->lookup("Border");
 
1310
  if (obj1.isArray())
1356
1311
    border = new AnnotBorderArray(obj1.getArray());
1357
1312
  else
1358
1313
    border = NULL;
1359
 
  obj1.free();
1360
1314
 
1361
 
  if (dict->lookup("C", &obj1)->isArray()) {
 
1315
  obj1 = dict->lookup("C");
 
1316
  if (obj1.isArray()) {
1362
1317
    color = new AnnotColor(obj1.getArray());
1363
1318
  } else {
1364
1319
    color = NULL;
1365
1320
  }
1366
 
  obj1.free();
1367
1321
 
1368
 
  if (dict->lookup("StructParent", &obj1)->isInt()) {
 
1322
  obj1 = dict->lookup("StructParent");
 
1323
  if (obj1.isInt()) {
1369
1324
    treeKey = obj1.getInt();
1370
1325
  } else {
1371
1326
    treeKey = 0;
1372
1327
  }
1373
 
  obj1.free();
1374
 
 
1375
 
  dict->lookupNF("OC", &oc);
1376
 
 
1377
 
#if MULTITHREADED
 
1328
 
 
1329
  oc = dict->lookupNF("OC");
 
1330
 
 
1331
#ifdef MULTITHREADED
1378
1332
  gInitMutex(&mutex);
1379
1333
#endif
1380
1334
}
1391
1345
}
1392
1346
 
1393
1347
void Annot::setRect(double x1, double y1, double x2, double y2) {
1394
 
  Object obj1, obj2;
1395
 
 
1396
1348
  if (x1 < x2) {
1397
1349
    rect->x1 = x1;
1398
1350
    rect->x2 = x2;
1409
1361
    rect->y2 = y1;
1410
1362
  }
1411
1363
 
1412
 
  obj1.initArray (xref);
1413
 
  obj1.arrayAdd (obj2.initReal (rect->x1));
1414
 
  obj1.arrayAdd (obj2.initReal (rect->y1));
1415
 
  obj1.arrayAdd (obj2.initReal (rect->x2));
1416
 
  obj1.arrayAdd (obj2.initReal (rect->y2));
 
1364
  Array *a = new Array(xref);
 
1365
  a->add(Object(rect->x1));
 
1366
  a->add(Object(rect->y1));
 
1367
  a->add(Object(rect->x2));
 
1368
  a->add(Object(rect->y2));
1417
1369
 
1418
 
  update("Rect", &obj1);
 
1370
  update("Rect", Object(a));
1419
1371
  invalidateAppearance();
1420
1372
}
1421
1373
 
1423
1375
  return rect->contains(x, y);
1424
1376
}
1425
1377
 
1426
 
void Annot::update(const char *key, Object *value) {
 
1378
void Annot::update(const char *key, Object &&value) {
1427
1379
  annotLocker();
1428
1380
  /* Set M to current time, unless we are updating M itself */
1429
1381
  if (strcmp(key, "M") != 0) {
1430
1382
    delete modified;
1431
1383
    modified = timeToDateString(NULL);
1432
1384
 
1433
 
    Object obj1;
1434
 
    obj1.initString (modified->copy());
1435
 
    annotObj.dictSet("M", &obj1);
 
1385
    annotObj.dictSet("M", Object(modified->copy()));
1436
1386
  }
1437
1387
 
1438
 
  annotObj.dictSet(const_cast<char*>(key), value);
 
1388
  annotObj.dictSet(const_cast<char*>(key), std::move(value));
1439
1389
  
1440
1390
  xref->setModifiedObject(&annotObj, ref);
1441
1391
}
1448
1398
    contents = new GooString(new_content);
1449
1399
    //append the unicode marker <FE FF> if needed       
1450
1400
    if (!contents->hasUnicodeMarker()) {
1451
 
      contents->insert(0, 0xff);
1452
 
      contents->insert(0, 0xfe);
 
1401
      contents->prependUnicodeMarker();
1453
1402
    }
1454
1403
  } else {
1455
1404
    contents = new GooString();
1456
1405
  }
1457
1406
  
1458
 
  Object obj1;
1459
 
  obj1.initString(contents->copy());
1460
 
  update ("Contents", &obj1);
 
1407
  update ("Contents", Object(contents->copy()));
1461
1408
}
1462
1409
 
1463
1410
void Annot::setName(GooString *new_name) {
1470
1417
    name = new GooString();
1471
1418
  }
1472
1419
 
1473
 
  Object obj1;
1474
 
  obj1.initString(name->copy());
1475
 
  update ("NM", &obj1);
 
1420
  update ("NM", Object(name->copy()));
1476
1421
}
1477
1422
 
1478
1423
void Annot::setModified(GooString *new_modified) {
1484
1429
  else
1485
1430
    modified = new GooString();
1486
1431
 
1487
 
  Object obj1;
1488
 
  obj1.initString(modified->copy());
1489
 
  update ("M", &obj1);
 
1432
  update ("M", Object(modified->copy()));
1490
1433
}
1491
1434
 
1492
1435
void Annot::setFlags(Guint new_flags) {
1493
1436
  annotLocker();
1494
 
  Object obj1;
1495
1437
  flags = new_flags;
1496
 
  obj1.initInt(flags);
1497
 
  update ("F", &obj1);
 
1438
  update ("F", Object(int(flags)));
1498
1439
}
1499
1440
 
1500
1441
void Annot::setBorder(AnnotBorder *new_border) {
1502
1443
  delete border;
1503
1444
 
1504
1445
  if (new_border) {
1505
 
    Object obj1;
1506
 
    new_border->writeToObject(xref, &obj1);
1507
 
    update(new_border->getType() == AnnotBorder::typeArray ? "Border" : "BS", &obj1);
 
1446
    Object obj1 = new_border->writeToObject(xref);
 
1447
    update(new_border->getType() == AnnotBorder::typeArray ? "Border" : "BS", std::move(obj1));
1508
1448
    border = new_border;
1509
1449
  } else {
1510
1450
    border = NULL;
1517
1457
  delete color;
1518
1458
 
1519
1459
  if (new_color) {
1520
 
    Object obj1;
1521
 
    new_color->writeToObject(xref, &obj1);
1522
 
    update ("C", &obj1);
 
1460
    Object obj1 = new_color->writeToObject(xref);
 
1461
    update ("C", std::move(obj1));
1523
1462
    color = new_color;
1524
1463
  } else {
1525
1464
    color = NULL;
1530
1469
void Annot::setPage(int pageIndex, GBool updateP) {
1531
1470
  annotLocker();
1532
1471
  Page *pageobj = doc->getPage(pageIndex);
1533
 
  Object obj1;
 
1472
  Object obj1(objNull);
1534
1473
 
1535
1474
  if (pageobj) {
1536
1475
    Ref pageRef = pageobj->getRef();
1537
 
    obj1.initRef(pageRef.num, pageRef.gen);
 
1476
    obj1 = Object(pageRef.num, pageRef.gen);
1538
1477
    page = pageIndex;
1539
1478
  } else {
1540
 
    obj1.initNull();
1541
1479
    page = 0;
1542
1480
  }
1543
1481
 
1544
1482
  if (updateP) {
1545
 
    update("P", &obj1);
 
1483
    update("P", std::move(obj1));
1546
1484
  }
1547
1485
}
1548
1486
 
1557
1495
  delete appearBBox;
1558
1496
  appearBBox = NULL;
1559
1497
 
1560
 
  Object obj1;
1561
 
  obj1.initName(state);
1562
 
  update ("AS", &obj1);
 
1498
  update ("AS", Object(objName, state));
1563
1499
 
1564
1500
  // The appearance state determines the current appearance stream
1565
 
  appearance.free();
1566
1501
  if (appearStreams) {
1567
 
    appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->getCString(), &appearance);
 
1502
    appearance = appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->getCString());
1568
1503
  } else {
1569
 
    appearance.initNull();
 
1504
    appearance.setToNull();
1570
1505
  }
1571
1506
}
1572
1507
 
1584
1519
  delete appearBBox;
1585
1520
  appearBBox = NULL;
1586
1521
 
1587
 
  appearance.free();
1588
 
  appearance.initNull();
1589
 
 
1590
 
  Object obj1, obj2;
1591
 
  obj1.initNull();
1592
 
  if (!annotObj.dictLookup("AP", &obj2)->isNull())
1593
 
    update ("AP", &obj1); // Remove AP
1594
 
  obj2.free();
1595
 
 
1596
 
  if (!annotObj.dictLookup("AS", &obj2)->isNull())
1597
 
    update ("AS", &obj1); // Remove AS
1598
 
  obj2.free();
 
1522
  appearance.setToNull();
 
1523
 
 
1524
  Object obj2 = annotObj.dictLookup("AP");
 
1525
  if (!obj2.isNull())
 
1526
    update ("AP", Object(objNull)); // Remove AP
 
1527
 
 
1528
  obj2 = annotObj.dictLookup("AS");
 
1529
  if (!obj2.isNull())
 
1530
    update ("AS", Object(objNull)); // Remove AS
1599
1531
}
1600
1532
 
1601
1533
double Annot::getXMin() {
1615
1547
}
1616
1548
 
1617
1549
void Annot::readArrayNum(Object *pdfArray, int key, double *value) {
1618
 
  Object valueObject;
1619
 
 
1620
 
  pdfArray->arrayGet(key, &valueObject);
 
1550
  Object valueObject = pdfArray->arrayGet(key);
1621
1551
  if (valueObject.isNum()) {
1622
1552
    *value = valueObject.getNum();
1623
1553
  } else {
1624
1554
    *value = 0;
1625
1555
    ok = gFalse;
1626
1556
  }
1627
 
  valueObject.free();
1628
1557
}
1629
1558
 
1630
1559
void Annot::removeReferencedObjects() {
1638
1567
}
1639
1568
 
1640
1569
void Annot::decRefCnt() {
1641
 
#if MULTITHREADED
 
1570
#ifdef MULTITHREADED
1642
1571
  gLockMutex(&mutex);
1643
1572
#endif
1644
1573
  if (--refCnt == 0) {
1645
 
#if MULTITHREADED
 
1574
#ifdef MULTITHREADED
1646
1575
    gUnlockMutex(&mutex);
1647
1576
#endif
1648
1577
    delete this;
1649
1578
    return;
1650
1579
  }
1651
 
#if MULTITHREADED
 
1580
#ifdef MULTITHREADED
1652
1581
  gUnlockMutex(&mutex);
1653
1582
#endif
1654
1583
}
1655
1584
 
1656
1585
Annot::~Annot() {
1657
 
  annotObj.free();
1658
 
  
1659
1586
  delete rect;
1660
1587
  delete contents;
1661
1588
 
1667
1594
 
1668
1595
  delete appearStreams;
1669
1596
  delete appearBBox;
1670
 
  appearance.free();
1671
1597
 
1672
1598
  if (appearState)
1673
1599
    delete appearState;
1678
1604
  if (color)
1679
1605
    delete color;
1680
1606
 
1681
 
  oc.free();
1682
 
 
1683
 
#if MULTITHREADED
 
1607
#ifdef MULTITHREADED
1684
1608
    gDestroyMutex(&mutex);
1685
1609
#endif
1686
1610
}
1804
1728
  appearBuf->append("S\n");
1805
1729
}
1806
1730
 
1807
 
void Annot::createForm(double *bbox, GBool transparencyGroup, Object *resDict, Object *aStream) {
1808
 
  Object obj1, obj2;
1809
 
  Object appearDict;
 
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"));
1810
1735
 
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) {
1821
 
    Object transDict;
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));
1825
1746
  }
1826
1747
  if (resDict)
1827
 
    appearDict.dictSet("Resources", resDict);
 
1748
    appearDict->set("Resources", Object(resDict));
1828
1749
 
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));
1833
1754
}
1834
1755
 
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,
1838
 
                                Object *resDict) {
1839
 
  Object gsDict, stateDict, formDict, obj1;
1840
 
 
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));
1845
1763
  }
1846
1764
  if (blendMode)
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);
1852
 
 
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));
 
1770
 
 
1771
  Dict *resDict = new Dict(xref);
 
1772
  resDict->set("ExtGState", Object(stateDict));
 
1773
  resDict->set("XObject", Object(formDict));
 
1774
 
 
1775
  return resDict;
1856
1776
}
1857
1777
 
1858
 
Object *Annot::getAppearanceResDict(Object *dest) {
 
1778
Object Annot::getAppearanceResDict() {
1859
1779
  Object obj1, obj2;
1860
1780
 
1861
 
  dest->initNull(); // Default value
1862
 
 
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()) {
1868
 
      obj2.copy(dest);
 
1786
      return obj2;
1869
1787
    }
1870
 
    obj2.free();
1871
1788
  }
1872
 
  obj1.free();
1873
1789
 
1874
 
  return dest;
 
1790
  return Object(objNull);
1875
1791
}
1876
1792
 
1877
1793
GBool Annot::isVisible(GBool printing) {
1905
1821
}
1906
1822
 
1907
1823
void Annot::draw(Gfx *gfx, GBool printing) {
1908
 
  Object obj;
1909
 
 
1910
1824
  annotLocker();
1911
1825
  if (!isVisible (printing))
1912
1826
    return;
1913
1827
 
1914
1828
  // draw the appearance stream
1915
 
  appearance.fetch(gfx->getXRef(), &obj);
 
1829
  Object obj = appearance.fetch(gfx->getXRef());
1916
1830
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
1917
1831
      rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
1918
 
  obj.free();
1919
1832
}
1920
1833
 
1921
1834
//------------------------------------------------------------------------
1928
1841
 
1929
1842
  type = typePopup;
1930
1843
 
1931
 
  annotObj.dictSet ("Subtype", obj1.initName ("Popup"));
 
1844
  annotObj.dictSet ("Subtype", Object(objName, "Popup"));
1932
1845
  initialize (docA, annotObj.getDict());
1933
1846
}
1934
1847
 
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());
1939
1852
}
1940
1853
 
1941
1854
AnnotPopup::~AnnotPopup() {
1942
 
  parent.free();
1943
1855
}
1944
1856
 
1945
1857
void AnnotPopup::initialize(PDFDoc *docA, Dict *dict) {
1946
 
  Object obj1;
1947
 
 
1948
 
  if (!dict->lookupNF("Parent", &parent)->isRef()) {
1949
 
    parent.initNull();
 
1858
  parent = dict->lookupNF("Parent");
 
1859
  if (!parent.isRef()) {
 
1860
    parent.setToNull();
1950
1861
  }
1951
1862
 
1952
 
  if (dict->lookup("Open", &obj1)->isBool()) {
 
1863
  Object obj1 = dict->lookup("Open");
 
1864
  if (obj1.isBool()) {
1953
1865
    open = obj1.getBool();
1954
1866
  } else {
1955
1867
    open = gFalse;
1956
1868
  }
1957
 
  obj1.free();
1958
1869
}
1959
1870
 
1960
1871
void AnnotPopup::setParent(Object *parentA) {
1961
 
  parentA->copy(&parent);
1962
 
  update ("Parent", &parent);
 
1872
  update ("Parent", parentA->copy());
1963
1873
}
1964
1874
 
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));
1969
1878
}
1970
1879
 
1971
1880
void AnnotPopup::setOpen(GBool openA) {
1972
 
  Object obj1;
1973
 
 
1974
1881
  open = openA;
1975
 
  obj1.initBool(open);
1976
 
  update ("Open", &obj1);
 
1882
  update ("Open", Object(open));
1977
1883
}
1978
1884
 
1979
1885
//------------------------------------------------------------------------
1984
1890
  initialize(docA, annotObj.getDict(), &annotObj);
1985
1891
}
1986
1892
 
1987
 
AnnotMarkup::AnnotMarkup(PDFDoc *docA, Dict *dict, Object *obj) :
1988
 
    Annot(docA, dict, obj) {
1989
 
  initialize(docA, dict, obj);
 
1893
AnnotMarkup::AnnotMarkup(PDFDoc *docA, Object *dictObject, Object *obj) :
 
1894
    Annot(docA, dictObject, obj) {
 
1895
  initialize(docA, dictObject->getDict(), obj);
1990
1896
}
1991
1897
 
1992
1898
AnnotMarkup::~AnnotMarkup() {
2006
1912
void AnnotMarkup::initialize(PDFDoc *docA, Dict *dict, Object *obj) {
2007
1913
  Object obj1, obj2;
2008
1914
 
2009
 
  if (dict->lookup("T", &obj1)->isString()) {
 
1915
  obj1 = dict->lookup("T");
 
1916
  if (obj1.isString()) {
2010
1917
    label = obj1.getString()->copy();
2011
1918
  } else {
2012
1919
    label = NULL;
2013
1920
  }
2014
 
  obj1.free();
2015
1921
 
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);
2018
1926
  } else {
2019
1927
    popup = NULL;
2020
1928
  }
2021
 
  obj1.free();
2022
1929
 
2023
 
  if (dict->lookup("CA", &obj1)->isNum()) {
 
1930
  obj1 = dict->lookup("CA");
 
1931
  if (obj1.isNum()) {
2024
1932
    opacity = obj1.getNum();
2025
1933
  } else {
2026
1934
    opacity = 1.0;
2027
1935
  }
2028
 
  obj1.free();
2029
1936
 
2030
 
  if (dict->lookup("CreationDate", &obj1)->isString()) {
 
1937
  obj1 = dict->lookup("CreationDate");
 
1938
  if (obj1.isString()) {
2031
1939
    date = obj1.getString()->copy();
2032
1940
  } else {
2033
1941
    date = NULL;
2034
1942
  }
2035
 
  obj1.free();
2036
1943
 
2037
 
  if (dict->lookupNF("IRT", &obj1)->isRef()) {
 
1944
  obj1 = dict->lookupNF("IRT");
 
1945
  if (obj1.isRef()) {
2038
1946
    inReplyTo = obj1.getRef();
2039
1947
  } else {
2040
1948
    inReplyTo.num = 0;
2041
1949
    inReplyTo.gen = 0;
2042
1950
  }
2043
 
  obj1.free();
2044
1951
 
2045
 
  if (dict->lookup("Subj", &obj1)->isString()) {
 
1952
  obj1 = dict->lookup("Subj");
 
1953
  if (obj1.isString()) {
2046
1954
    subject = obj1.getString()->copy();
2047
1955
  } else {
2048
1956
    subject = NULL;
2049
1957
  }
2050
 
  obj1.free();
2051
1958
 
2052
 
  if (dict->lookup("RT", &obj1)->isName()) {
 
1959
  obj1 = dict->lookup("RT");
 
1960
  if (obj1.isName()) {
2053
1961
    const char *replyName = obj1.getName();
2054
1962
 
2055
1963
    if (!strcmp(replyName, "R")) {
2062
1970
  } else {
2063
1971
    replyTo = replyTypeR;
2064
1972
  }
2065
 
  obj1.free();
2066
1973
 
2067
 
  if (dict->lookup("ExData", &obj1)->isDict()) {
 
1974
  obj1 = dict->lookup("ExData");
 
1975
  if (obj1.isDict()) {
2068
1976
    exData = parseAnnotExternalData(obj1.getDict());
2069
1977
  } else {
2070
1978
    exData = annotExternalDataMarkupUnknown;
2071
1979
  }
2072
 
  obj1.free();
2073
1980
}
2074
1981
 
2075
1982
void AnnotMarkup::setLabel(GooString *new_label) {
2079
1986
    label = new GooString(new_label);
2080
1987
    //append the unicode marker <FE FF> if needed
2081
1988
    if (!label->hasUnicodeMarker()) {
2082
 
      label->insert(0, 0xff);
2083
 
      label->insert(0, 0xfe);
 
1989
      label->prependUnicodeMarker();
2084
1990
    }
2085
1991
  } else {
2086
1992
    label = new GooString();
2087
1993
  }
2088
1994
 
2089
 
  Object obj1;
2090
 
  obj1.initString(label->copy());
2091
 
  update ("T", &obj1);
 
1995
  update ("T", Object(label->copy()));
2092
1996
}
2093
1997
 
2094
1998
void AnnotMarkup::setPopup(AnnotPopup *new_popup) {
2105
2009
  delete popup;
2106
2010
 
2107
2011
  if (new_popup) {
2108
 
    Object obj1;
2109
 
    Ref popupRef = new_popup->getRef();
2110
 
 
2111
 
    obj1.initRef (popupRef.num, popupRef.gen);
2112
 
    update ("Popup", &obj1);
 
2012
    const Ref popupRef = new_popup->getRef();
 
2013
    update ("Popup", Object(popupRef.num, popupRef.gen));
2113
2014
 
2114
2015
    new_popup->setParent(this);
2115
2016
    popup = new_popup;
2128
2029
}
2129
2030
 
2130
2031
void AnnotMarkup::setOpacity(double opacityA) {
2131
 
  Object obj1;
2132
 
 
2133
2032
  opacity = opacityA;
2134
 
  obj1.initReal(opacity);
2135
 
  update ("CA", &obj1);
 
2033
  update ("CA", Object(opacity));
2136
2034
  invalidateAppearance();
2137
2035
}
2138
2036
 
2144
2042
  else
2145
2043
    date = new GooString();
2146
2044
 
2147
 
  Object obj1;
2148
 
  obj1.initString(date->copy());
2149
 
  update ("CreationDate", &obj1);
 
2045
  update ("CreationDate", Object(date->copy()));
2150
2046
}
2151
2047
 
2152
2048
void AnnotMarkup::removeReferencedObjects() {
2167
2063
 
2168
2064
AnnotText::AnnotText(PDFDoc *docA, PDFRectangle *rect) :
2169
2065
    AnnotMarkup(docA, rect) {
2170
 
  Object obj1;
2171
 
 
2172
2066
  type = typeText;
2173
2067
  flags |= flagNoZoom | flagNoRotate;
2174
2068
 
2175
 
  annotObj.dictSet ("Subtype", obj1.initName ("Text"));
 
2069
  annotObj.dictSet ("Subtype", Object(objName, "Text"));
2176
2070
  initialize (docA, annotObj.getDict());
2177
2071
}
2178
2072
 
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) {
2181
2075
 
2182
2076
  type = typeText;
2183
2077
  flags |= flagNoZoom | flagNoRotate;
2184
 
  initialize (docA, dict);
 
2078
  initialize (docA, dictObject->getDict());
2185
2079
}
2186
2080
 
2187
2081
AnnotText::~AnnotText() {
2191
2085
void AnnotText::initialize(PDFDoc *docA, Dict *dict) {
2192
2086
  Object obj1;
2193
2087
 
2194
 
  if (dict->lookup("Open", &obj1)->isBool())
 
2088
  obj1 = dict->lookup("Open");
 
2089
  if (obj1.isBool())
2195
2090
    open = obj1.getBool();
2196
2091
  else
2197
2092
    open = gFalse;
2198
 
  obj1.free();
2199
2093
 
2200
 
  if (dict->lookup("Name", &obj1)->isName()) {
 
2094
  obj1 = dict->lookup("Name");
 
2095
  if (obj1.isName()) {
2201
2096
    icon = new GooString(obj1.getName());
2202
2097
  } else {
2203
2098
    icon = new GooString("Note");
2204
2099
  }
2205
 
  obj1.free();
2206
2100
 
2207
 
  if (dict->lookup("StateModel", &obj1)->isString()) {
2208
 
    Object obj2;
 
2101
  obj1 = dict->lookup("StateModel");
 
2102
  if (obj1.isString()) {
2209
2103
    GooString *modelName = obj1.getString();
2210
2104
 
2211
 
    if (dict->lookup("State", &obj2)->isString()) {
 
2105
    Object obj2 = dict->lookup("State");
 
2106
    if (obj2.isString()) {
2212
2107
      GooString *stateName = obj2.getString();
2213
2108
 
2214
2109
      if (!stateName->cmp("Marked")) {
2231
2126
    } else {
2232
2127
      state = stateUnknown;
2233
2128
    }
2234
 
    obj2.free();
2235
2129
 
2236
2130
    if (!modelName->cmp("Marked")) {
2237
2131
      switch (state) {
2266
2160
  } else {
2267
2161
    state = stateUnknown;
2268
2162
  }
2269
 
  obj1.free();
2270
2163
}
2271
2164
 
2272
2165
void AnnotText::setOpen(GBool openA) {
2273
2166
  Object obj1;
2274
2167
 
2275
2168
  open = openA;
2276
 
  obj1.initBool(open);
2277
 
  update ("Open", &obj1);
 
2169
  update ("Open", Object(open));
2278
2170
}
2279
2171
 
2280
2172
void AnnotText::setIcon(GooString *new_icon) {
2289
2181
    icon = new GooString("Note");
2290
2182
  }
2291
2183
 
2292
 
  Object obj1;
2293
 
  obj1.initName (icon->getCString());
2294
 
  update("Name", &obj1);
 
2184
  update("Name", Object(objName, icon->getCString()));
2295
2185
  invalidateAppearance();
2296
2186
}
2297
2187
 
2540
2430
  "19.5 12.5 m S\n"
2541
2431
 
2542
2432
void AnnotText::draw(Gfx *gfx, GBool printing) {
2543
 
  Object obj;
2544
2433
  double ca = 1;
2545
2434
 
2546
2435
  if (!isVisible (printing))
2583
2472
    double bbox[4];
2584
2473
    appearBBox->getBBoxRect(bbox);
2585
2474
    if (ca == 1) {
2586
 
      createForm(bbox, gFalse, NULL, &appearance);
 
2475
      appearance = createForm(bbox, gFalse, nullptr);
2587
2476
    } else {
2588
 
      Object aStream, resDict;
2589
 
 
2590
 
      createForm(bbox, gTrue, NULL, &aStream);
 
2477
      Object aStream = createForm(bbox, gTrue, nullptr);
2591
2478
      delete appearBuf;
2592
2479
 
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);
2596
2483
    }
2597
2484
    delete appearBuf;
2598
2485
  }
2599
2486
 
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(),
2608
2495
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
2609
2496
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
2610
2497
  }
2611
 
  obj.free();
2612
2498
}
2613
2499
 
2614
2500
//------------------------------------------------------------------------
2619
2505
  Object obj1;
2620
2506
 
2621
2507
  type = typeLink;
2622
 
  annotObj.dictSet ("Subtype", obj1.initName ("Link"));
 
2508
  annotObj.dictSet ("Subtype", Object(objName, "Link"));
2623
2509
  initialize (docA, annotObj.getDict());
2624
2510
}
2625
2511
 
2626
 
AnnotLink::AnnotLink(PDFDoc *docA, Dict *dict, Object *obj) :
2627
 
    Annot(docA, dict, obj) {
 
2512
AnnotLink::AnnotLink(PDFDoc *docA, Object *dictObject, Object *obj) :
 
2513
    Annot(docA, dictObject, obj) {
2628
2514
 
2629
2515
  type = typeLink;
2630
 
  initialize (docA, dict);
 
2516
  initialize (docA, dictObject->getDict());
2631
2517
}
2632
2518
 
2633
2519
AnnotLink::~AnnotLink() {
2646
2532
  action = NULL;
2647
2533
 
2648
2534
  // look for destination
2649
 
  if (!dict->lookup("Dest", &obj1)->isNull()) {
 
2535
  obj1 = dict->lookup("Dest");
 
2536
  if (!obj1.isNull()) {
2650
2537
    action = LinkAction::parseDest(&obj1);
2651
2538
  // look for action
2652
2539
  } else {
2653
 
    obj1.free();
2654
 
    if (dict->lookup("A", &obj1)->isDict()) {
 
2540
    obj1 = dict->lookup("A");
 
2541
    if (obj1.isDict()) {
2655
2542
      action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
2656
2543
    }
2657
2544
  }
2658
 
  obj1.free();
2659
2545
 
2660
 
  if (dict->lookup("H", &obj1)->isName()) {
 
2546
  obj1 = dict->lookup("H");
 
2547
  if (obj1.isName()) {
2661
2548
    const char *effect = obj1.getName();
2662
2549
 
2663
2550
    if (!strcmp(effect, "N")) {
2674
2561
  } else {
2675
2562
    linkEffect = effectInvert;
2676
2563
  }
2677
 
  obj1.free();
2678
2564
  /*
2679
 
  if (dict->lookup("PA", &obj1)->isDict()) {
 
2565
  obj1 = dict->lookup("PA");
 
2566
  if (obj1.isDict()) {
2680
2567
    uriAction = NULL;
2681
2568
  } else {
2682
2569
    uriAction = NULL;
2683
2570
  }
2684
2571
  obj1.free();
2685
2572
  */
2686
 
  if (dict->lookup("QuadPoints", &obj1)->isArray()) {
 
2573
  obj1 = dict->lookup("QuadPoints");
 
2574
  if (obj1.isArray()) {
2687
2575
    quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
2688
2576
  } else {
2689
2577
    quadrilaterals = NULL;
2690
2578
  }
2691
 
  obj1.free();
2692
2579
 
2693
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
2580
  obj1 = dict->lookup("BS");
 
2581
  if (obj1.isDict()) {
2694
2582
    delete border;
2695
2583
    border = new AnnotBorderBS(obj1.getDict());
2696
2584
  } else if (!border) {
2697
2585
    border = new AnnotBorderBS();
2698
2586
  }
2699
 
  obj1.free();
2700
2587
}
2701
2588
 
2702
2589
void AnnotLink::draw(Gfx *gfx, GBool printing) {
2703
 
  Object obj;
2704
 
 
2705
2590
  if (!isVisible (printing))
2706
2591
    return;
2707
2592
 
2708
2593
  annotLocker();
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());
2713
 
  obj.free();
2714
2598
}
2715
2599
 
2716
2600
//------------------------------------------------------------------------
2722
2606
 
2723
2607
  type = typeFreeText;
2724
2608
 
2725
 
  annotObj.dictSet ("Subtype", obj1.initName ("FreeText"));
2726
 
 
2727
 
  Object obj2;
2728
 
  obj2.initString (da->copy());
2729
 
  annotObj.dictSet("DA", &obj2);
 
2609
  annotObj.dictSet ("Subtype", Object(objName, "FreeText"));
 
2610
  annotObj.dictSet("DA", Object(da->copy()));
2730
2611
 
2731
2612
  initialize (docA, annotObj.getDict());
2732
2613
}
2733
2614
 
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());
2738
2619
}
2739
2620
 
2740
2621
AnnotFreeText::~AnnotFreeText() {
2756
2637
void AnnotFreeText::initialize(PDFDoc *docA, Dict *dict) {
2757
2638
  Object obj1;
2758
2639
 
2759
 
  if (dict->lookup("DA", &obj1)->isString()) {
 
2640
  obj1 = dict->lookup("DA");
 
2641
  if (obj1.isString()) {
2760
2642
    appearanceString = obj1.getString()->copy();
2761
2643
  } else {
2762
2644
    appearanceString = new GooString();
2763
2645
    error(errSyntaxError, -1, "Bad appearance for annotation");
2764
2646
    ok = gFalse;
2765
2647
  }
2766
 
  obj1.free();
2767
2648
 
2768
 
  if (dict->lookup("Q", &obj1)->isInt()) {
 
2649
  obj1 = dict->lookup("Q");
 
2650
  if (obj1.isInt()) {
2769
2651
    quadding = (AnnotFreeTextQuadding) obj1.getInt();
2770
2652
  } else {
2771
2653
    quadding = quaddingLeftJustified;
2772
2654
  }
2773
 
  obj1.free();
2774
2655
 
2775
 
  if (dict->lookup("DS", &obj1)->isString()) {
 
2656
  obj1 = dict->lookup("DS");
 
2657
  if (obj1.isString()) {
2776
2658
    styleString = obj1.getString()->copy();
2777
2659
  } else {
2778
2660
    styleString = NULL;
2779
2661
  }
2780
 
  obj1.free();
2781
2662
 
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;
2784
2666
    Object obj2;
2785
2667
 
2786
 
    (obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
2787
 
    obj2.free();
2788
 
    (obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
2789
 
    obj2.free();
2790
 
    (obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
2791
 
    obj2.free();
2792
 
    (obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
2793
 
    obj2.free();
 
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);
2794
2672
 
2795
2673
    if (obj1.arrayGetLength() == 6) {
2796
2674
      double x3, y3;
2797
 
      (obj1.arrayGet(4, &obj2)->isNum() ? x3 = obj2.getNum() : x3 = 0);
2798
 
      obj2.free();
2799
 
      (obj1.arrayGet(5, &obj2)->isNum() ? y3 = obj2.getNum() : y3 = 0);
2800
 
      obj2.free();
 
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);
2802
2678
    } else {
2803
2679
      calloutLine = new AnnotCalloutLine(x1, y1, x2, y2);
2805
2681
  } else {
2806
2682
    calloutLine = NULL;
2807
2683
  }
2808
 
  obj1.free();
2809
2684
 
2810
 
  if (dict->lookup("IT", &obj1)->isName()) {
 
2685
  obj1 = dict->lookup("IT");
 
2686
  if (obj1.isName()) {
2811
2687
    const char *intentName = obj1.getName();
2812
2688
 
2813
2689
    if (!strcmp(intentName, "FreeText")) {
2822
2698
  } else {
2823
2699
    intent = intentFreeText;
2824
2700
  }
2825
 
  obj1.free();
2826
2701
 
2827
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
2702
  obj1 = dict->lookup("BS");
 
2703
  if (obj1.isDict()) {
2828
2704
    delete border;
2829
2705
    border = new AnnotBorderBS(obj1.getDict());
2830
2706
  } else if (!border) {
2831
2707
    border = new AnnotBorderBS();
2832
2708
  }
2833
 
  obj1.free();
2834
2709
 
2835
 
  if (dict->lookup("BE", &obj1)->isDict()) {
 
2710
  obj1 = dict->lookup("BE");
 
2711
  if (obj1.isDict()) {
2836
2712
    borderEffect = new AnnotBorderEffect(obj1.getDict());
2837
2713
  } else {
2838
2714
    borderEffect = NULL;
2839
2715
  }
2840
 
  obj1.free();
2841
2716
 
2842
 
  if (dict->lookup("RD", &obj1)->isArray()) {
 
2717
  obj1 = dict->lookup("RD");
 
2718
  if (obj1.isArray()) {
2843
2719
    rectangle = parseDiffRectangle(obj1.getArray(), rect);
2844
2720
  } else {
2845
2721
    rectangle = NULL;
2846
2722
  }
2847
 
  obj1.free();
2848
2723
 
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);
2852
2728
  } else {
2853
2729
    endStyle = annotLineEndingNone;
2854
2730
  }
2855
 
  obj1.free();
2856
2731
}
2857
2732
 
2858
2733
void AnnotFreeText::setContents(GooString *new_content) {
2869
2744
    appearanceString = new GooString();
2870
2745
  }
2871
2746
 
2872
 
  Object obj1;
2873
 
  obj1.initString(appearanceString->copy());
2874
 
  update ("DA", &obj1);
 
2747
  update ("DA", Object(appearanceString->copy()));
2875
2748
  invalidateAppearance();
2876
2749
}
2877
2750
 
2878
2751
void AnnotFreeText::setQuadding(AnnotFreeTextQuadding new_quadding) {
2879
2752
  Object obj1;
2880
2753
  quadding = new_quadding;
2881
 
  obj1.initInt((int)quadding);
2882
 
  update ("Q", &obj1);
 
2754
  update ("Q", Object((int)quadding));
2883
2755
  invalidateAppearance();
2884
2756
}
2885
2757
 
2890
2762
    styleString = new GooString(new_string);
2891
2763
    //append the unicode marker <FE FF> if needed
2892
2764
    if (!styleString->hasUnicodeMarker()) {
2893
 
      styleString->insert(0, 0xff);
2894
 
      styleString->insert(0, 0xfe);
 
2765
      styleString->prependUnicodeMarker();
2895
2766
    }
2896
2767
  } else {
2897
2768
    styleString = new GooString();
2898
2769
  }
2899
2770
 
2900
 
  Object obj1;
2901
 
  obj1.initString(styleString->copy());
2902
 
  update ("DS", &obj1);
 
2771
  update ("DS", Object(styleString->copy()));
2903
2772
}
2904
2773
 
2905
2774
void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line) {
2907
2776
 
2908
2777
  Object obj1;
2909
2778
  if (line == NULL) {
2910
 
    obj1.initNull();
 
2779
    obj1.setToNull();
2911
2780
    calloutLine = NULL;
2912
2781
  } else {
2913
2782
    double x1 = line->getX1(), y1 = line->getY1();
2914
2783
    double x2 = line->getX2(), y2 = line->getY2();
2915
 
    Object obj2;
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) );
2921
2789
 
2922
2790
    AnnotCalloutMultiLine *mline = dynamic_cast<AnnotCalloutMultiLine*>(line);
2923
2791
    if (mline) {
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);
2928
2796
    } else {
2929
2797
      calloutLine = new AnnotCalloutLine(x1, y1, x2, y2);
2930
2798
    }
2931
2799
  }
2932
2800
 
2933
 
  update("CL", &obj1);
 
2801
  update("CL", std::move(obj1));
2934
2802
  invalidateAppearance();
2935
2803
}
2936
2804
 
2937
2805
void AnnotFreeText::setIntent(AnnotFreeTextIntent new_intent) {
2938
 
  Object obj1;
 
2806
  const char *intentName;
2939
2807
 
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));
2948
2816
}
2949
2817
 
2950
 
static GfxFont * createAnnotDrawFont(XRef * xref, Object *fontResDict)
 
2818
static GfxFont * createAnnotDrawFont(XRef * xref, Dict *fontResDict)
2951
2819
{
2952
 
  Ref dummyRef = { -1, -1 };
2953
 
 
2954
 
  Object baseFontObj, subtypeObj, encodingObj;
2955
 
  baseFontObj.initName("Helvetica");
2956
 
  subtypeObj.initName("Type0");
2957
 
  encodingObj.initName("WinAnsiEncoding");
2958
 
 
2959
 
  Object fontDictObj;
 
2820
  const Ref dummyRef = { -1, -1 };
 
2821
 
2960
2822
  Dict *fontDict = new Dict(xref);
2961
 
  fontDict->decRef();
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"));
2966
2826
 
2967
 
  Object fontsDictObj;
2968
2827
  Dict *fontsDict = new Dict(xref);
2969
 
  fontsDict->decRef();
2970
 
  fontsDict->add(copyString("AnnotDrawFont"), &fontDictObj);
2971
 
  fontsDictObj.initDict(fontsDict);
2972
 
 
2973
 
  Dict *dict = new Dict(xref);
2974
 
  dict->add(copyString("Font"), &fontsDictObj);
2975
 
 
2976
 
  fontResDict->initDict(dict);
 
2828
  fontsDict->add(copyString("AnnotDrawFont"), Object(fontDict));
 
2829
 
 
2830
  fontResDict->add(copyString("Font"), Object(fontsDict));
 
2831
 
2977
2832
  return GfxFont::makeFont(xref, "AnnotDrawFont", dummyRef, fontDict);
2978
2833
}
2979
2834
 
2982
2837
  fontcolor = NULL;
2983
2838
  if (da) {
2984
2839
    GooList * daToks = new GooList();
2985
 
    int j, i = 0;
 
2840
    int i = FormFieldText::tokenizeDA(da, daToks, "Tf");
2986
2841
 
2987
 
    // Tokenize
2988
 
    while (i < da->getLength()) {
2989
 
      while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
2990
 
        ++i;
2991
 
      }
2992
 
      if (i < da->getLength()) {
2993
 
        for (j = i + 1; j < da->getLength() && !Lexer::isSpace(da->getChar(j)); ++j) {
2994
 
        }
2995
 
        daToks->append(new GooString(da, i, j - i));
2996
 
        i = j;
2997
 
      }
 
2842
    if (i >= 1) {
 
2843
      fontsize = gatof(( (GooString *)daToks->get(i-1) )->getCString());
 
2844
      // TODO: Font name
2998
2845
    }
2999
 
 
3000
2846
    // Scan backwards: we are looking for the last set value
3001
2847
    for (i = daToks->getLength()-1; i >= 0; --i) {
3002
 
      if (fontsize == -1) {
3003
 
        if (!((GooString *)daToks->get(i))->cmp("Tf") && i >= 2) {
3004
 
            // TODO: Font name
3005
 
            fontsize = gatof(( (GooString *)daToks->get(i-1) )->getCString());
3006
 
        }
3007
 
      }
3008
2848
      if (fontcolor == NULL) {
3009
2849
        if (!((GooString *)daToks->get(i))->cmp("g") && i >= 1) {
3010
2850
          fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-1) )->getCString()));
3072
2912
  const double textwidth = width - 2*textmargin;
3073
2913
  appearBuf->appendf ("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n", textmargin, textwidth, height - 2*textmargin);
3074
2914
 
3075
 
  Object fontResDict;
3076
 
  GfxFont *font = createAnnotDrawFont(xref, &fontResDict);
 
2915
  Dict *fontResDict = new Dict(xref);
 
2916
  GfxFont *font = createAnnotDrawFont(xref, fontResDict);
3077
2917
 
3078
2918
  // Set font state
3079
2919
  setColor(fontcolor, gTrue);
3114
2954
  bbox[3] = rect->y2 - rect->y1;
3115
2955
 
3116
2956
  if (ca == 1) {
3117
 
    createForm(bbox, gFalse, &fontResDict, &appearance);
 
2957
    appearance = createForm(bbox, gFalse, fontResDict);
3118
2958
  } else {
3119
 
    Object aStream, resDict;
3120
 
 
3121
 
    createForm(bbox, gTrue, &fontResDict, &aStream);
 
2959
    Object aStream = createForm(bbox, gTrue, fontResDict);
3122
2960
    delete appearBuf;
3123
2961
 
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);
3127
2965
  }
3128
2966
  delete appearBuf;
3129
2967
}
3130
2968
 
3131
2969
void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
3132
 
  Object obj;
3133
 
 
3134
2970
  if (!isVisible (printing))
3135
2971
    return;
3136
2972
 
3140
2976
  }
3141
2977
 
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());
3146
 
  obj.free();
3147
2982
}
3148
2983
 
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();
3154
2989
  }
3155
 
  return Annot::getAppearanceResDict(dest);
 
2990
  return Annot::getAppearanceResDict();
3156
2991
}
3157
2992
 
3158
2993
//------------------------------------------------------------------------
3164
2999
  Object obj1;
3165
3000
 
3166
3001
  type = typeLine;
3167
 
  annotObj.dictSet ("Subtype", obj1.initName ("Line"));
 
3002
  annotObj.dictSet ("Subtype", Object(objName, "Line"));
3168
3003
 
3169
3004
  initialize (docA, annotObj.getDict());
3170
3005
}
3171
3006
 
3172
 
AnnotLine::AnnotLine(PDFDoc *docA, Dict *dict, Object *obj) :
3173
 
    AnnotMarkup(docA, dict, obj) {
 
3007
AnnotLine::AnnotLine(PDFDoc *docA, Object *dictObject, Object *obj) :
 
3008
    AnnotMarkup(docA, dictObject, obj) {
3174
3009
  type = typeLine;
3175
 
  initialize(docA, dict);
 
3010
  initialize(docA, dictObject->getDict());
3176
3011
}
3177
3012
 
3178
3013
AnnotLine::~AnnotLine() {
3189
3024
void AnnotLine::initialize(PDFDoc *docA, Dict *dict) {
3190
3025
  Object obj1;
3191
3026
 
3192
 
  if (dict->lookup("L", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
 
3027
  obj1 = dict->lookup("L");
 
3028
  if (obj1.isArray() && obj1.arrayGetLength() == 4) {
3193
3029
    Object obj2;
3194
3030
    double x1, y1, x2, y2;
3195
3031
 
3196
 
    (obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
3197
 
    obj2.free();
3198
 
    (obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
3199
 
    obj2.free();
3200
 
    (obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
3201
 
    obj2.free();
3202
 
    (obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
3203
 
    obj2.free();
 
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);
3204
3036
 
3205
3037
    coord1 = new AnnotCoord(x1, y1);
3206
3038
    coord2 = new AnnotCoord(x2, y2);
3208
3040
    coord1 = new AnnotCoord();
3209
3041
    coord2 = new AnnotCoord();
3210
3042
  }
3211
 
  obj1.free();
3212
3043
 
3213
 
  if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
 
3044
  obj1 = dict->lookup("LE");
 
3045
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
3214
3046
    Object obj2;
3215
3047
 
3216
 
    if(obj1.arrayGet(0, &obj2)->isString())
 
3048
    obj2 = obj1.arrayGet(0);
 
3049
    if (obj2.isString())
3217
3050
      startStyle = parseAnnotLineEndingStyle(obj2.getString());
3218
3051
    else
3219
3052
      startStyle = annotLineEndingNone;
3220
 
    obj2.free();
3221
3053
 
3222
 
    if(obj1.arrayGet(1, &obj2)->isString())
 
3054
    obj2 = obj1.arrayGet(1);
 
3055
    if (obj2.isString())
3223
3056
      endStyle = parseAnnotLineEndingStyle(obj2.getString());
3224
3057
    else
3225
3058
      endStyle = annotLineEndingNone;
3226
 
    obj2.free();
3227
3059
 
3228
3060
  } else {
3229
3061
    startStyle = endStyle = annotLineEndingNone;
3230
3062
  }
3231
 
  obj1.free();
3232
3063
 
3233
 
  if (dict->lookup("IC", &obj1)->isArray()) {
 
3064
  obj1 = dict->lookup("IC");
 
3065
  if (obj1.isArray()) {
3234
3066
    interiorColor = new AnnotColor(obj1.getArray());
3235
3067
  } else {
3236
3068
    interiorColor = NULL;
3237
3069
  }
3238
 
  obj1.free();
3239
3070
 
3240
 
  if (dict->lookup("LL", &obj1)->isNum()) {
 
3071
  obj1 = dict->lookup("LL");
 
3072
  if (obj1.isNum()) {
3241
3073
    leaderLineLength = obj1.getNum();
3242
3074
  } else {
3243
3075
    leaderLineLength = 0;
3244
3076
  }
3245
 
  obj1.free();
3246
3077
 
3247
 
  if (dict->lookup("LLE", &obj1)->isNum()) {
 
3078
  obj1 = dict->lookup("LLE");
 
3079
  if (obj1.isNum()) {
3248
3080
    leaderLineExtension = obj1.getNum();
3249
3081
 
3250
3082
    if (leaderLineExtension < 0)
3252
3084
  } else {
3253
3085
    leaderLineExtension = 0;
3254
3086
  }
3255
 
  obj1.free();
3256
3087
 
3257
 
  if (dict->lookup("Cap", &obj1)->isBool()) {
 
3088
  obj1 = dict->lookup("Cap");
 
3089
  if (obj1.isBool()) {
3258
3090
    caption = obj1.getBool();
3259
3091
  } else {
3260
3092
    caption = gFalse;
3261
3093
  }
3262
 
  obj1.free();
3263
3094
 
3264
 
  if (dict->lookup("IT", &obj1)->isName()) {
 
3095
  obj1 = dict->lookup("IT");
 
3096
  if (obj1.isName()) {
3265
3097
    const char *intentName = obj1.getName();
3266
3098
 
3267
3099
    if(!strcmp(intentName, "LineArrow")) {
3274
3106
  } else {
3275
3107
    intent = intentLineArrow;
3276
3108
  }
3277
 
  obj1.free();
3278
3109
 
3279
 
  if (dict->lookup("LLO", &obj1)->isNum()) {
 
3110
  obj1 = dict->lookup("LLO");
 
3111
  if (obj1.isNum()) {
3280
3112
    leaderLineOffset = obj1.getNum();
3281
3113
 
3282
3114
    if (leaderLineOffset < 0)
3284
3116
  } else {
3285
3117
    leaderLineOffset = 0;
3286
3118
  }
3287
 
  obj1.free();
3288
3119
 
3289
 
  if (dict->lookup("CP", &obj1)->isName()) {
 
3120
  obj1 = dict->lookup("CP");
 
3121
  if (obj1.isName()) {
3290
3122
    const char *captionName = obj1.getName();
3291
3123
 
3292
3124
    if(!strcmp(captionName, "Inline")) {
3299
3131
  } else {
3300
3132
    captionPos = captionPosInline;
3301
3133
  }
3302
 
  obj1.free();
3303
3134
 
3304
 
  if (dict->lookup("Measure", &obj1)->isDict()) {
 
3135
  obj1 = dict->lookup("Measure");
 
3136
  if (obj1.isDict()) {
3305
3137
    measure = NULL;
3306
3138
  } else {
3307
3139
    measure = NULL;
3308
3140
  }
3309
 
  obj1.free();
3310
3141
 
3311
 
  if ((dict->lookup("CO", &obj1)->isArray()) && (obj1.arrayGetLength() == 2)) {
 
3142
  obj1 = dict->lookup("CO");
 
3143
  if (obj1.isArray() && (obj1.arrayGetLength() == 2)) {
3312
3144
    Object obj2;
3313
3145
 
3314
 
    (obj1.arrayGet(0, &obj2)->isNum() ? captionTextHorizontal = obj2.getNum() :
3315
 
      captionTextHorizontal = 0);
3316
 
    obj2.free();
3317
 
    (obj1.arrayGet(1, &obj2)->isNum() ? captionTextVertical = obj2.getNum() :
3318
 
      captionTextVertical = 0);
3319
 
    obj2.free();
 
3146
    obj2 = obj1.arrayGet(0);
 
3147
    captionTextHorizontal = obj2.isNum() ? obj2.getNum() : 0;
 
3148
    obj2 = obj1.arrayGet(1);
 
3149
    captionTextVertical = obj2.isNum() ? obj2.getNum() : 0;
3320
3150
  } else {
3321
3151
    captionTextHorizontal = captionTextVertical = 0;
3322
3152
  }
3323
 
  obj1.free();
3324
3153
 
3325
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
3154
  obj1 = dict->lookup("BS");
 
3155
  if (obj1.isDict()) {
3326
3156
    delete border;
3327
3157
    border = new AnnotBorderBS(obj1.getDict());
3328
3158
  } else if (!border) {
3329
3159
    border = new AnnotBorderBS();
3330
3160
  }
3331
 
  obj1.free();
3332
3161
}
3333
3162
 
3334
3163
void AnnotLine::setContents(GooString *new_content) {
3338
3167
}
3339
3168
 
3340
3169
void AnnotLine::setVertices(double x1, double y1, double x2, double y2) {
3341
 
  Object obj1, obj2;
3342
 
 
3343
3170
  delete coord1;
3344
3171
  coord1 = new AnnotCoord(x1, y1);
3345
3172
  delete coord2;
3346
3173
  coord2 = new AnnotCoord(x2, y2);
3347
3174
 
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) );
3353
3180
 
3354
 
  update("L", &obj1);
 
3181
  update("L", Object(lArray));
3355
3182
  invalidateAppearance();
3356
3183
}
3357
3184
 
3358
3185
void AnnotLine::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
3359
 
  Object obj1, obj2;
3360
 
 
3361
3186
  startStyle = start;
3362
3187
  endStyle = end;
3363
3188
 
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 )) );
3367
3192
 
3368
 
  update("LE", &obj1);
 
3193
  update("LE", Object(leArray));
3369
3194
  invalidateAppearance();
3370
3195
}
3371
3196
 
3373
3198
  delete interiorColor;
3374
3199
 
3375
3200
  if (new_color) {
3376
 
    Object obj1;
3377
 
    new_color->writeToObject(xref, &obj1);
3378
 
    update ("IC", &obj1);
 
3201
    Object obj1 = new_color->writeToObject(xref);
 
3202
    update ("IC", std::move(obj1));
3379
3203
    interiorColor = new_color;
3380
3204
  } else {
3381
3205
    interiorColor = NULL;
3384
3208
}
3385
3209
 
3386
3210
void AnnotLine::setLeaderLineLength(double len) {
3387
 
  Object obj1;
3388
 
 
3389
3211
  leaderLineLength = len;
3390
 
  obj1.initReal(len);
3391
 
  update ("LL", &obj1);
 
3212
  update ("LL", Object(len));
3392
3213
  invalidateAppearance();
3393
3214
}
3394
3215
 
3395
3216
void AnnotLine::setLeaderLineExtension(double len) {
3396
 
  Object obj1;
3397
 
 
3398
3217
  leaderLineExtension = len;
3399
 
  obj1.initReal(len);
3400
 
  update ("LLE", &obj1);
 
3218
  update ("LLE", Object(len));
3401
3219
 
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();
3406
3223
}
3407
3224
 
3408
3225
void AnnotLine::setCaption(bool new_cap) {
3409
 
  Object obj1;
3410
 
 
3411
3226
  caption = new_cap;
3412
 
  obj1.initBool(new_cap);
3413
 
  update ("Cap", &obj1);
 
3227
  update ("Cap", Object(new_cap));
3414
3228
  invalidateAppearance();
3415
3229
}
3416
3230
 
3417
3231
void AnnotLine::setIntent(AnnotLineIntent new_intent) {
3418
 
  Object obj1;
 
3232
  const char *intentName;
3419
3233
 
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));
3426
3240
}
3427
3241
 
3428
3242
void AnnotLine::generateLineAppearance()
3463
3277
  const double captionhmargin = 2; // Left and right margin (inline caption only)
3464
3278
  const double captionmaxwidth = main_len - 2 * captionhmargin;
3465
3279
 
3466
 
  Object fontResDict;
 
3280
  Dict *fontResDict;
3467
3281
  GfxFont *font;
3468
3282
 
3469
3283
  // Calculate caption width and height
3470
3284
  if (caption) {
3471
 
    font = createAnnotDrawFont(xref, &fontResDict);
 
3285
    fontResDict = new Dict(xref);
 
3286
    font = createAnnotDrawFont(xref, fontResDict);
3472
3287
    int lines = 0;
3473
3288
    int i = 0;
3474
3289
    while (i < contents->getLength()) {
3487
3302
      actualCaptionPos = captionPosTop;
3488
3303
    }
3489
3304
  } else {
3490
 
    fontResDict.initNull();
 
3305
    fontResDict = nullptr;
3491
3306
    font = NULL;
3492
3307
  }
3493
3308
 
3579
3394
  double bbox[4];
3580
3395
  appearBBox->getBBoxRect(bbox);
3581
3396
  if (ca == 1) {
3582
 
    createForm(bbox, gFalse, &fontResDict, &appearance);
 
3397
    appearance = createForm(bbox, gFalse, fontResDict);
3583
3398
  } else {
3584
 
    Object aStream, resDict;
3585
 
 
3586
 
    createForm(bbox, gTrue, &fontResDict, &aStream);
 
3399
    Object aStream = createForm(bbox, gTrue, fontResDict);
3587
3400
    delete appearBuf;
3588
3401
 
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);
3592
3405
  }
3593
3406
  delete appearBuf;
3594
3407
}
3595
3408
 
3596
3409
void AnnotLine::draw(Gfx *gfx, GBool printing) {
3597
 
  Object obj;
3598
 
 
3599
3410
  if (!isVisible (printing))
3600
3411
    return;
3601
3412
 
3605
3416
  }
3606
3417
 
3607
3418
  // draw the appearance stream
3608
 
  appearance.fetch(gfx->getXRef(), &obj);
 
3419
  Object obj = appearance.fetch(gfx->getXRef());
3609
3420
  if (appearBBox) {
3610
3421
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
3611
3422
                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
3615
3426
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
3616
3427
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
3617
3428
  }
3618
 
  obj.free();
3619
3429
}
3620
3430
 
3621
3431
// Before retrieving the res dict, regenerate the appearance stream if needed,
3622
3432
// because AnnotLine::draw may need to store font info in the res dict
3623
 
Object *AnnotLine::getAppearanceResDict(Object *dest) {
 
3433
Object AnnotLine::getAppearanceResDict() {
3624
3434
  if (appearance.isNull()) {
3625
3435
    generateLineAppearance();
3626
3436
  }
3627
 
  return Annot::getAppearanceResDict(dest);
 
3437
  return Annot::getAppearanceResDict();
3628
3438
}
3629
3439
 
3630
3440
//------------------------------------------------------------------------
3636
3446
 
3637
3447
  switch (subType) {
3638
3448
    case typeHighlight:
3639
 
      annotObj.dictSet ("Subtype", obj1.initName ("Highlight"));
 
3449
      annotObj.dictSet ("Subtype", Object(objName, "Highlight"));
3640
3450
      break;
3641
3451
    case typeUnderline:
3642
 
      annotObj.dictSet ("Subtype", obj1.initName ("Underline"));
 
3452
      annotObj.dictSet ("Subtype", Object(objName, "Underline"));
3643
3453
      break;
3644
3454
    case typeSquiggly:
3645
 
      annotObj.dictSet ("Subtype", obj1.initName ("Squiggly"));
 
3455
      annotObj.dictSet ("Subtype", Object(objName, "Squiggly"));
3646
3456
      break;
3647
3457
    case typeStrikeOut:
3648
 
      annotObj.dictSet ("Subtype", obj1.initName ("StrikeOut"));
 
3458
      annotObj.dictSet ("Subtype", Object(objName, "StrikeOut"));
3649
3459
      break;
3650
3460
    default:
3651
3461
      assert (0 && "Invalid subtype for AnnotTextMarkup\n");
3652
3462
  }
3653
3463
 
3654
3464
  // Store dummy quadrilateral with null coordinates
3655
 
  Object obj2, obj3;
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.));
3659
3468
  }
3660
 
  annotObj.dictSet ("QuadPoints", &obj2);
 
3469
  annotObj.dictSet ("QuadPoints", Object(quadPoints));
3661
3470
 
3662
3471
  initialize(docA, annotObj.getDict());
3663
3472
}
3664
3473
 
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());
3670
3479
}
3671
3480
 
3672
3481
void AnnotTextMarkup::initialize(PDFDoc *docA, Dict *dict) {
3673
3482
  Object obj1;
3674
3483
 
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;
3685
3495
    }
3686
3496
  }
3687
 
  obj1.free();
3688
3497
 
3689
 
  if(dict->lookup("QuadPoints", &obj1)->isArray()) {
 
3498
  obj1 = dict->lookup("QuadPoints");
 
3499
  if (obj1.isArray()) {
3690
3500
    quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
3691
3501
  } else {
3692
3502
    error(errSyntaxError, -1, "Bad Annot Text Markup QuadPoints");
3693
3503
    quadrilaterals = NULL;
3694
3504
    ok = gFalse;
3695
3505
  }
3696
 
  obj1.free();
3697
3506
}
3698
3507
 
3699
3508
AnnotTextMarkup::~AnnotTextMarkup() {
3700
 
  if(quadrilaterals) {
3701
 
    delete quadrilaterals;
3702
 
  }
 
3509
  delete quadrilaterals;
3703
3510
}
3704
3511
 
3705
3512
void AnnotTextMarkup::setType(AnnotSubtype new_type) {
3706
 
  Object obj1;
 
3513
  const char *typeName = nullptr; /* squelch bogus compiler warning */
3707
3514
 
3708
3515
  switch (new_type) {
3709
3516
    case typeHighlight:
3710
 
      obj1.initName("Highlight");
 
3517
      typeName = "Highlight";
3711
3518
      break;
3712
3519
    case typeUnderline:
3713
 
      obj1.initName("Underline");
 
3520
      typeName = "Underline";
3714
3521
      break;
3715
3522
    case typeSquiggly:
3716
 
      obj1.initName("Squiggly");
 
3523
      typeName = "Squiggly";
3717
3524
      break;
3718
3525
    case typeStrikeOut:
3719
 
      obj1.initName("StrikeOut");
 
3526
      typeName = "StrikeOut";
3720
3527
      break;
3721
3528
    default:
3722
3529
      assert(!"Invalid subtype");
3723
3530
  }
3724
3531
 
3725
3532
  type = new_type;
3726
 
  update("Subtype", &obj1);
 
3533
  update("Subtype", Object(objName, typeName));
3727
3534
  invalidateAppearance();
3728
3535
}
3729
3536
 
3730
3537
void AnnotTextMarkup::setQuadrilaterals(AnnotQuadrilaterals *quadPoints) {
3731
 
  Object obj1, obj2;
3732
 
  obj1.initArray (xref);
 
3538
  Array *a = new Array(xref);
3733
3539
 
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)));
3743
3549
  }
3744
3550
 
3745
3551
  delete quadrilaterals;
3746
 
  quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
 
3552
  quadrilaterals = new AnnotQuadrilaterals(a, rect);
3747
3553
 
3748
 
  annotObj.dictSet ("QuadPoints", &obj1);
 
3554
  annotObj.dictSet ("QuadPoints", Object(a));
3749
3555
  invalidateAppearance();
3750
3556
}
3751
3557
 
3752
3558
void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
3753
 
  Object obj;
3754
3559
  double ca = 1;
3755
3560
  int i;
3756
 
  Object obj1, obj2;
3757
3561
 
3758
3562
  if (!isVisible (printing))
3759
3563
    return;
3850
3654
      break;
3851
3655
    default:
3852
3656
    case typeHighlight:
3853
 
      appearance.free();
3854
 
 
3855
3657
      if (color)
3856
3658
        setColor(color, gTrue);
3857
3659
 
3887
3689
    }
3888
3690
    appearBuf->append ("Q\n");
3889
3691
 
3890
 
    Object aStream, resDict;
 
3692
    Object aStream;
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;
3898
3700
 
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);
3901
3703
    if (ca == 1) {
3902
 
      createForm(bbox, gFalse, &resDict, &appearance);
 
3704
      appearance = createForm(bbox, gFalse, resDict);
3903
3705
    } else {
3904
 
      createForm(bbox, gTrue, &resDict, &aStream);
 
3706
      aStream = createForm(bbox, gTrue, resDict);
3905
3707
      delete appearBuf;
3906
3708
 
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);
3910
3712
    }
3911
3713
    delete appearBuf;
3912
3714
  }
3913
3715
 
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());
3924
3726
  }
3925
 
  obj.free();
3926
3727
}
3927
3728
 
3928
3729
//------------------------------------------------------------------------
3929
3730
// AnnotWidget
3930
3731
//------------------------------------------------------------------------
3931
3732
 
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;
3935
3736
  field = NULL;
3936
 
  initialize(docA, dict);
 
3737
  initialize(docA, dictObject->getDict());
3937
3738
}
3938
3739
 
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());
3944
3745
}
3945
3746
 
3946
3747
AnnotWidget::~AnnotWidget() {
3950
3751
  if (action)
3951
3752
    delete action;
3952
3753
 
3953
 
  additionalActions.free();
3954
 
 
3955
3754
  if (parent)
3956
3755
    delete parent;
3957
3756
}
3961
3760
 
3962
3761
  form = doc->getCatalog()->getForm();
3963
3762
 
3964
 
  if(dict->lookup("H", &obj1)->isName()) {
 
3763
  obj1 = dict->lookup("H");
 
3764
  if (obj1.isName()) {
3965
3765
    const char *modeName = obj1.getName();
3966
3766
 
3967
3767
    if(!strcmp(modeName, "N")) {
3976
3776
  } else {
3977
3777
    mode = highlightModeInvert;
3978
3778
  }
3979
 
  obj1.free();
3980
3779
 
3981
 
  if(dict->lookup("MK", &obj1)->isDict()) {
 
3780
  obj1 = dict->lookup("MK");
 
3781
  if (obj1.isDict()) {
3982
3782
    appearCharacs = new AnnotAppearanceCharacs(obj1.getDict());
3983
3783
  } else {
3984
3784
    appearCharacs = NULL;
3985
3785
  }
3986
 
  obj1.free();
3987
3786
 
3988
3787
  action = 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());
3991
3791
  }
3992
 
  obj1.free();
3993
 
 
3994
 
  dict->lookupNF("AA", &additionalActions);
3995
 
 
3996
 
  if(dict->lookup("Parent", &obj1)->isDict()) {
 
3792
 
 
3793
  additionalActions = dict->lookupNF("AA");
 
3794
 
 
3795
  obj1 = dict->lookup("Parent");
 
3796
  if (obj1.isDict()) {
3997
3797
    parent = NULL;
3998
3798
  } else {
3999
3799
    parent = NULL;
4000
3800
  }
4001
 
  obj1.free();
4002
3801
 
4003
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
3802
  obj1 = dict->lookup("BS");
 
3803
  if (obj1.isDict()) {
4004
3804
    delete border;
4005
3805
    border = new AnnotBorderBS(obj1.getDict());
4006
3806
  }
4007
 
  obj1.free();
4008
3807
 
4009
3808
  updatedAppearanceStream.num = updatedAppearanceStream.gen = -1;
4010
3809
}
4882
4681
        appearBuf->appendf(" {0:.2f}", dash[i]);
4883
4682
      }
4884
4683
      appearBuf->append("] 0 d\n");
4885
 
      // fall through to the solid case
 
4684
      // fallthrough
4886
4685
    case AnnotBorder::borderSolid:
4887
4686
    case AnnotBorder::borderUnderlined:
4888
4687
      appearBuf->appendf("{0:.2f} w\n", w);
4914
4713
        appearBuf->appendf(" {0:.2f}", dash[i]);
4915
4714
      }
4916
4715
      appearBuf->append("] 0 d\n");
4917
 
      // fall through to the solid case
 
4716
      // fallthrough
4918
4717
    case AnnotBorder::borderSolid:
4919
4718
      appearBuf->appendf("{0:.2f} w\n", w);
4920
4719
      setColor(aColor, gFalse);
5037
4836
}
5038
4837
 
5039
4838
void AnnotWidget::generateFieldAppearance() {
5040
 
  Object appearDict, obj1, obj2;
5041
4839
  GfxResources *resources;
5042
 
  MemStream *appearStream;
5043
4840
  GooString *da;
5044
4841
 
5045
4842
  appearBuf = new GooString ();
5084
4881
  }
5085
4882
 
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));
5097
4893
 
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());
5102
4898
  }
5103
4899
 
5104
4900
  // build the appearance stream
5105
 
  appearStream = new MemStream(copyString(appearBuf->getCString()), 0,
5106
 
      appearBuf->getLength(), &appearDict);
5107
 
  appearance.free();
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;
5110
4905
 
5111
4906
  appearStream->setNeedFree(gTrue);
5128
4923
  generateFieldAppearance();
5129
4924
 
5130
4925
  // Fetch the appearance stream we've just created
5131
 
  Object obj1;
5132
 
  appearance.fetch(xref, &obj1);
 
4926
  Object obj1 = appearance.fetch(xref);
5133
4927
 
5134
4928
  // If this the first time updateAppearanceStream() is called on this widget,
5135
4929
  // create a new AP dictionary containing the new appearance stream.
5137
4931
  if (updatedAppearanceStream.num == -1) {
5138
4932
    // Write the appearance stream
5139
4933
    updatedAppearanceStream = xref->addIndirectObject(&obj1);
5140
 
    obj1.free();
5141
4934
 
5142
4935
    // Write the AP dictionary
5143
 
    Object obj2;
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));
5147
4938
 
5148
4939
    // Update our internal pointers to the appearance dictionary
5149
4940
    appearStreams = new AnnotAppearance(doc, &obj1);
 
4941
 
 
4942
    update("AP", std::move(obj1));
5150
4943
  } else {
5151
4944
    // Replace the existing appearance stream
5152
4945
    xref->setModifiedObject(&obj1, updatedAppearanceStream);
5153
 
    obj1.free();
5154
4946
  }
5155
4947
}
5156
4948
 
5157
4949
void AnnotWidget::draw(Gfx *gfx, GBool printing) {
5158
 
  Object obj;
5159
 
 
5160
4950
  if (!isVisible (printing))
5161
4951
    return;
5162
4952
 
5172
4962
  }
5173
4963
 
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");
5182
 
 
5183
 
    Object fontDictObj;
5184
4969
    Dict *fontDict = new Dict(gfx->getXRef());
5185
 
    fontDict->decRef();
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"));
5189
4972
 
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));
5195
4975
 
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);
5199
4979
    delete dict;
5200
4980
  }
5203
4983
  if (addDingbatsResource) {
5204
4984
    gfx->popResources();
5205
4985
  }
5206
 
  obj.free();
5207
4986
}
5208
4987
 
5209
4988
 
5215
4994
  Object obj1;
5216
4995
 
5217
4996
  type = typeMovie;
5218
 
  annotObj.dictSet ("Subtype", obj1.initName ("Movie"));
 
4997
  annotObj.dictSet ("Subtype", Object(objName, "Movie"));
5219
4998
 
5220
4999
  movie = movieA->copy();
5221
5000
  // TODO: create movie dict from movieA
5223
5002
  initialize(docA, annotObj.getDict());
5224
5003
}
5225
5004
 
5226
 
AnnotMovie::AnnotMovie(PDFDoc *docA, Dict *dict, Object *obj) :
5227
 
  Annot(docA, dict, obj) {
 
5005
AnnotMovie::AnnotMovie(PDFDoc *docA, Object *dictObject, Object *obj) :
 
5006
  Annot(docA, dictObject, obj) {
5228
5007
  type = typeMovie;
5229
 
  initialize(docA, dict);
 
5008
  initialize(docA, dictObject->getDict());
5230
5009
}
5231
5010
 
5232
5011
AnnotMovie::~AnnotMovie() {
5238
5017
void AnnotMovie::initialize(PDFDoc *docA, Dict* dict) {
5239
5018
  Object obj1;
5240
5019
 
5241
 
  if (dict->lookup("T", &obj1)->isString()) {
 
5020
  obj1 = dict->lookup("T");
 
5021
  if (obj1.isString()) {
5242
5022
    title = obj1.getString()->copy();
5243
5023
  } else {
5244
5024
    title = NULL;
5245
5025
  }
5246
 
  obj1.free();
5247
5026
 
5248
 
  Object movieDict;
5249
 
  if (dict->lookup("Movie", &movieDict)->isDict()) {
5250
 
    Object obj2;
5251
 
    dict->lookup("A", &obj2);
 
5027
  Object movieDict = dict->lookup("Movie");
 
5028
  if (movieDict.isDict()) {
 
5029
    Object obj2 = dict->lookup("A");
5252
5030
    if (obj2.isDict())
5253
5031
      movie = new Movie (&movieDict, &obj2);
5254
5032
    else
5258
5036
      movie = NULL;
5259
5037
      ok = gFalse;
5260
5038
    }
5261
 
    obj2.free();
5262
5039
  } else {
5263
5040
    error(errSyntaxError, -1, "Bad Annot Movie");
5264
5041
    movie = NULL;
5265
5042
    ok = gFalse;
5266
5043
  }
5267
 
  movieDict.free();
5268
5044
}
5269
5045
 
5270
5046
void AnnotMovie::draw(Gfx *gfx, GBool printing) {
5271
 
  Object obj;
5272
 
 
5273
5047
  if (!isVisible (printing))
5274
5048
    return;
5275
5049
 
5276
5050
  annotLocker();
5277
5051
  if (appearance.isNull() && movie->getShowPoster()) {
5278
5052
    int width, height;
5279
 
    Object poster;
5280
 
    movie->getPoster(&poster);
 
5053
    Object poster = movie->getPoster();
5281
5054
    movie->getAspect(&width, &height);
5282
5055
 
5283
5056
    if (width != -1 && height != -1 && !poster.isNone()) {
5284
 
      MemStream *mStream;
5285
 
 
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");
5291
5062
 
5292
 
      Object imgDict;
5293
 
      imgDict.initDict(gfx->getXRef());
5294
 
      imgDict.dictSet ("MImg", &poster);
5295
 
 
5296
 
      Object resDict;
5297
 
      resDict.initDict(gfx->getXRef());
5298
 
      resDict.dictSet ("XObject", &imgDict);
5299
 
 
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);
5320
 
 
5321
 
      Object aStream;
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));
 
5065
 
 
5066
      Dict *resDict = new Dict(gfx->getXRef());
 
5067
      resDict->set("XObject", Object(imgDict));
 
5068
 
 
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));
 
5088
 
 
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;
5327
5093
 
5328
 
      Object objDict;
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)));
5331
5096
 
5332
 
      resDict.initDict(gfx->getXRef());
5333
 
      resDict.dictSet ("XObject", &objDict);
 
5097
      Dict *resDict2 = new Dict(gfx->getXRef());
 
5098
      resDict2->set("XObject", Object(dict));
5334
5099
 
5335
5100
      appearBuf = new GooString ();
5336
5101
      appearBuf->append ("q\n");
5346
5111
      bbox[0] = bbox[1] = 0;
5347
5112
      bbox[2] = width;
5348
5113
      bbox[3] = height;
5349
 
      createForm(bbox, gFalse, &resDict, &appearance);
 
5114
      appearance = createForm(bbox, gFalse, resDict2);
5350
5115
      delete appearBuf;
5351
5116
    }
5352
 
    poster.free();
5353
5117
  }
5354
5118
 
5355
5119
  // draw the appearance stream
5356
 
  appearance.fetch(gfx->getXRef(), &obj);
 
5120
  Object obj = appearance.fetch(gfx->getXRef());
5357
5121
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
5358
5122
                 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
5359
 
  obj.free();
5360
5123
}
5361
5124
 
5362
5125
//------------------------------------------------------------------------
5368
5131
 
5369
5132
  type = typeScreen;
5370
5133
 
5371
 
  annotObj.dictSet ("Subtype", obj1.initName ("Screen"));
 
5134
  annotObj.dictSet ("Subtype", Object(objName, "Screen"));
5372
5135
  initialize(docA, annotObj.getDict());
5373
5136
}
5374
5137
 
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());
5379
5142
}
5380
5143
 
5381
5144
AnnotScreen::~AnnotScreen() {
5382
 
  if (title)
5383
 
    delete title;
5384
 
  if (appearCharacs)
5385
 
    delete appearCharacs;
5386
 
  if (action)
5387
 
    delete action;
5388
 
 
5389
 
  additionalActions.free();
 
5145
  delete title;
 
5146
  delete appearCharacs;
 
5147
  delete action;
5390
5148
}
5391
5149
 
5392
5150
void AnnotScreen::initialize(PDFDoc *docA, Dict* dict) {
5393
5151
  Object obj1;
5394
5152
 
5395
5153
  title = NULL;
5396
 
  if (dict->lookup("T", &obj1)->isString()) {
 
5154
  obj1 = dict->lookup("T");
 
5155
  if (obj1.isString()) {
5397
5156
    title = obj1.getString()->copy();
5398
5157
  }
5399
 
  obj1.free();
5400
5158
 
5401
5159
  action = NULL;
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");
5406
5165
      delete action;
5407
5166
      action = NULL;
5408
5167
      ok = gFalse;
5409
5168
    }
5410
5169
  }
5411
 
  obj1.free();
5412
5170
 
5413
 
  dict->lookupNF("AA", &additionalActions);
 
5171
  additionalActions = dict->lookupNF("AA");
5414
5172
 
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());
5418
5177
  }
5419
 
  obj1.free();
5420
5178
}
5421
5179
 
5422
5180
LinkAction* AnnotScreen::getAdditionalAction(AdditionalActionsType type)
5435
5193
  Object obj1;
5436
5194
 
5437
5195
  type = typeStamp;
5438
 
  annotObj.dictSet ("Subtype", obj1.initName ("Stamp"));
 
5196
  annotObj.dictSet ("Subtype", Object(objName, "Stamp"));
5439
5197
  initialize(docA, annotObj.getDict());
5440
5198
}
5441
5199
 
5442
 
AnnotStamp::AnnotStamp(PDFDoc *docA, Dict *dict, Object *obj) :
5443
 
  AnnotMarkup(docA, dict, obj) {
 
5200
AnnotStamp::AnnotStamp(PDFDoc *docA, Object *dictObject, Object *obj) :
 
5201
  AnnotMarkup(docA, dictObject, obj) {
5444
5202
  type = typeStamp;
5445
 
  initialize(docA, dict);
 
5203
  initialize(docA, dictObject->getDict());
5446
5204
}
5447
5205
 
5448
5206
AnnotStamp::~AnnotStamp() {
5450
5208
}
5451
5209
 
5452
5210
void AnnotStamp::initialize(PDFDoc *docA, Dict* dict) {
5453
 
  Object obj1;
5454
 
 
5455
 
  if (dict->lookup("Name", &obj1)->isName()) {
 
5211
  Object obj1 = dict->lookup("Name");
 
5212
  if (obj1.isName()) {
5456
5213
    icon = new GooString(obj1.getName());
5457
5214
  } else {
5458
5215
    icon = new GooString("Draft");
5459
5216
  }
5460
 
  obj1.free();
5461
5217
 
5462
5218
}
5463
5219
 
5470
5226
    icon = new GooString();
5471
5227
  }
5472
5228
 
5473
 
  Object obj1;
5474
 
  obj1.initName (icon->getCString());
5475
 
  update("Name", &obj1);
 
5229
  update("Name", Object(objName, icon->getCString()));
5476
5230
  invalidateAppearance();
5477
5231
}
5478
5232
 
5485
5239
 
5486
5240
  switch (subType) {
5487
5241
    case typeSquare:
5488
 
      annotObj.dictSet ("Subtype", obj1.initName ("Square"));
 
5242
      annotObj.dictSet ("Subtype", Object(objName, "Square"));
5489
5243
      break;
5490
5244
    case typeCircle:
5491
 
      annotObj.dictSet ("Subtype", obj1.initName ("Circle"));
 
5245
      annotObj.dictSet ("Subtype", Object(objName, "Circle"));
5492
5246
      break;
5493
5247
    default:
5494
5248
      assert (0 && "Invalid subtype for AnnotGeometry\n");
5497
5251
  initialize(docA, annotObj.getDict());
5498
5252
}
5499
5253
 
5500
 
AnnotGeometry::AnnotGeometry(PDFDoc *docA, Dict *dict, Object *obj) :
5501
 
  AnnotMarkup(docA, dict, obj) {
 
5254
AnnotGeometry::AnnotGeometry(PDFDoc *docA, Object *dictObject, Object *obj) :
 
5255
  AnnotMarkup(docA, dictObject, obj) {
5502
5256
  // the real type will be read in initialize()
5503
5257
  type = typeSquare;
5504
 
  initialize(docA, dict);
 
5258
  initialize(docA, dictObject->getDict());
5505
5259
}
5506
5260
 
5507
5261
AnnotGeometry::~AnnotGeometry() {
5513
5267
void AnnotGeometry::initialize(PDFDoc *docA, Dict* dict) {
5514
5268
  Object obj1;
5515
5269
 
5516
 
  if (dict->lookup("Subtype", &obj1)->isName()) {
 
5270
  obj1 = dict->lookup("Subtype");
 
5271
  if (obj1.isName()) {
5517
5272
    GooString typeName(obj1.getName());
5518
5273
    if (!typeName.cmp("Square")) {
5519
5274
      type = typeSquare;
5521
5276
      type = typeCircle;
5522
5277
    }
5523
5278
  }
5524
 
  obj1.free();
5525
5279
 
5526
 
  if (dict->lookup("IC", &obj1)->isArray()) {
 
5280
  obj1 = dict->lookup("IC");
 
5281
  if (obj1.isArray()) {
5527
5282
    interiorColor = new AnnotColor(obj1.getArray());
5528
5283
  } else {
5529
5284
    interiorColor = NULL;
5530
5285
  }
5531
 
  obj1.free();
5532
5286
 
5533
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
5287
  obj1 = dict->lookup("BS");
 
5288
  if (obj1.isDict()) {
5534
5289
    delete border;
5535
5290
    border = new AnnotBorderBS(obj1.getDict());
5536
5291
  } else if (!border) {
5537
5292
    border = new AnnotBorderBS();
5538
5293
  }
5539
 
  obj1.free();
5540
5294
 
5541
 
  if (dict->lookup("BE", &obj1)->isDict()) {
 
5295
  obj1 = dict->lookup("BE");
 
5296
  if (obj1.isDict()) {
5542
5297
    borderEffect = new AnnotBorderEffect(obj1.getDict());
5543
5298
  } else {
5544
5299
    borderEffect = NULL;
5545
5300
  }
5546
 
  obj1.free();
5547
5301
 
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);
5551
5306
  }
5552
 
  obj1.free();
5553
 
 
5554
5307
}
5555
5308
 
5556
5309
void AnnotGeometry::setType(AnnotSubtype new_type) {
5557
 
  Object obj1;
 
5310
  const char *typeName = nullptr; /* squelch bogus compiler warning */
5558
5311
 
5559
5312
  switch (new_type) {
5560
5313
    case typeSquare:
5561
 
      obj1.initName("Square");
 
5314
      typeName = "Square";
5562
5315
      break;
5563
5316
    case typeCircle:
5564
 
      obj1.initName("Circle");
 
5317
      typeName = "Circle";
5565
5318
      break;
5566
5319
    default:
5567
5320
      assert(!"Invalid subtype");
5568
5321
  }
5569
5322
 
5570
5323
  type = new_type;
5571
 
  update("Subtype", &obj1);
 
5324
  update("Subtype", Object(objName, typeName));
5572
5325
  invalidateAppearance();
5573
5326
}
5574
5327
 
5576
5329
  delete interiorColor;
5577
5330
 
5578
5331
  if (new_color) {
5579
 
    Object obj1;
5580
 
    new_color->writeToObject(xref, &obj1);
5581
 
    update ("IC", &obj1);
 
5332
    Object obj1 = new_color->writeToObject(xref);
 
5333
    update ("IC", std::move(obj1));
5582
5334
    interiorColor = new_color;
5583
5335
  } else {
5584
5336
    interiorColor = NULL;
5587
5339
}
5588
5340
 
5589
5341
void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
5590
 
  Object obj;
5591
5342
  double ca = 1;
5592
5343
 
5593
5344
  if (!isVisible (printing))
5673
5424
    bbox[2] = rect->x2 - rect->x1;
5674
5425
    bbox[3] = rect->y2 - rect->y1;
5675
5426
    if (ca == 1) {
5676
 
      createForm(bbox, gFalse, NULL, &appearance);
 
5427
      appearance = createForm(bbox, gFalse, nullptr);
5677
5428
    } else {
5678
 
      Object aStream;
5679
 
 
5680
 
      createForm(bbox, gTrue, NULL, &aStream);
 
5429
      Object aStream = createForm(bbox, gTrue, nullptr);
5681
5430
      delete appearBuf;
5682
5431
 
5683
 
      Object resDict;
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);
5687
5435
    }
5688
5436
    delete appearBuf;
5689
5437
  }
5690
5438
 
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());
5695
 
  obj.free();
5696
5443
}
5697
5444
 
5698
5445
//------------------------------------------------------------------------
5704
5451
 
5705
5452
  switch (subType) {
5706
5453
    case typePolygon:
5707
 
      annotObj.dictSet ("Subtype", obj1.initName ("Polygon"));
 
5454
      annotObj.dictSet ("Subtype", Object(objName, "Polygon"));
5708
5455
      break;
5709
5456
    case typePolyLine:
5710
 
      annotObj.dictSet ("Subtype", obj1.initName ("PolyLine"));
 
5457
      annotObj.dictSet ("Subtype", Object(objName, "PolyLine"));
5711
5458
      break;
5712
5459
    default:
5713
5460
      assert (0 && "Invalid subtype for AnnotGeometry\n");
5714
5461
  }
5715
5462
 
5716
5463
  // Store dummy path with one null vertex only
5717
 
  Object obj2, obj3;
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());
 
5465
  a->add(Object(0.));
 
5466
  a->add(Object(0.));
 
5467
  annotObj.dictSet("Vertices", Object(a));
5722
5468
 
5723
5469
  initialize(docA, annotObj.getDict());
5724
5470
}
5725
5471
 
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());
5731
5477
}
5732
5478
 
5733
5479
AnnotPolygon::~AnnotPolygon() {
5743
5489
void AnnotPolygon::initialize(PDFDoc *docA, Dict* dict) {
5744
5490
  Object obj1;
5745
5491
 
5746
 
  if (dict->lookup("Subtype", &obj1)->isName()) {
 
5492
  obj1 = dict->lookup("Subtype");
 
5493
  if (obj1.isName()) {
5747
5494
    GooString typeName(obj1.getName());
5748
5495
    if (!typeName.cmp("Polygon")) {
5749
5496
      type = typePolygon;
5751
5498
      type = typePolyLine;
5752
5499
    }
5753
5500
  }
5754
 
  obj1.free();
5755
5501
 
5756
 
  if (dict->lookup("Vertices", &obj1)->isArray()) {
 
5502
  obj1 = dict->lookup("Vertices");
 
5503
  if (obj1.isArray()) {
5757
5504
    vertices = new AnnotPath(obj1.getArray());
5758
5505
  } else {
5759
5506
    vertices = new AnnotPath();
5760
5507
    error(errSyntaxError, -1, "Bad Annot Polygon Vertices");
5761
5508
    ok = gFalse;
5762
5509
  }
5763
 
  obj1.free();
5764
 
 
5765
 
  if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
5766
 
    Object obj2;
5767
 
 
5768
 
    if(obj1.arrayGet(0, &obj2)->isString())
 
5510
 
 
5511
  obj1 = dict->lookup("LE");
 
5512
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
 
5513
    Object obj2 = obj1.arrayGet(0);
 
5514
    if(obj2.isString())
5769
5515
      startStyle = parseAnnotLineEndingStyle(obj2.getString());
5770
5516
    else
5771
5517
      startStyle = annotLineEndingNone;
5772
 
    obj2.free();
5773
5518
 
5774
 
    if(obj1.arrayGet(1, &obj2)->isString())
 
5519
    obj2 = obj1.arrayGet(1);
 
5520
    if(obj2.isString())
5775
5521
      endStyle = parseAnnotLineEndingStyle(obj2.getString());
5776
5522
    else
5777
5523
      endStyle = annotLineEndingNone;
5778
 
    obj2.free();
5779
5524
 
5780
5525
  } else {
5781
5526
    startStyle = endStyle = annotLineEndingNone;
5782
5527
  }
5783
 
  obj1.free();
5784
5528
 
5785
 
  if (dict->lookup("IC", &obj1)->isArray()) {
 
5529
  obj1 = dict->lookup("IC");
 
5530
  if (obj1.isArray()) {
5786
5531
    interiorColor = new AnnotColor(obj1.getArray());
5787
5532
  } else {
5788
5533
    interiorColor = NULL;
5789
5534
  }
5790
 
  obj1.free();
5791
5535
 
5792
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
5536
  obj1 = dict->lookup("BS");
 
5537
  if (obj1.isDict()) {
5793
5538
    delete border;
5794
5539
    border = new AnnotBorderBS(obj1.getDict());
5795
5540
  } else if (!border) {
5796
5541
    border = new AnnotBorderBS();
5797
5542
  }
5798
 
  obj1.free();
5799
5543
 
5800
 
  if (dict->lookup("BE", &obj1)->isDict()) {
 
5544
  obj1 = dict->lookup("BE");
 
5545
  if (obj1.isDict()) {
5801
5546
    borderEffect = new AnnotBorderEffect(obj1.getDict());
5802
5547
  } else {
5803
5548
    borderEffect = NULL;
5804
5549
  }
5805
 
  obj1.free();
5806
5550
 
5807
 
  if (dict->lookup("IT", &obj1)->isName()) {
 
5551
  obj1 = dict->lookup("IT");
 
5552
  if (obj1.isName()) {
5808
5553
    const char *intentName = obj1.getName();
5809
5554
 
5810
5555
    if(!strcmp(intentName, "PolygonCloud")) {
5817
5562
  } else {
5818
5563
    intent = polygonCloud;
5819
5564
  }
5820
 
  obj1.free();
5821
5565
}
5822
5566
 
5823
5567
void AnnotPolygon::setType(AnnotSubtype new_type) {
5824
 
  Object obj1;
 
5568
  const char *typeName = nullptr; /* squelch bogus compiler warning */
5825
5569
 
5826
5570
  switch (new_type) {
5827
5571
    case typePolygon:
5828
 
      obj1.initName("Polygon");
 
5572
      typeName = "Polygon";
5829
5573
      break;
5830
5574
    case typePolyLine:
5831
 
      obj1.initName("PolyLine");
 
5575
      typeName = "PolyLine";
5832
5576
      break;
5833
5577
    default:
5834
5578
      assert(!"Invalid subtype");
5835
5579
  }
5836
5580
 
5837
5581
  type = new_type;
5838
 
  update("Subtype", &obj1);
 
5582
  update("Subtype", Object(objName, typeName));
5839
5583
  invalidateAppearance();
5840
5584
}
5841
5585
 
5842
5586
void AnnotPolygon::setVertices(AnnotPath *path) {
5843
 
  Object obj1, obj2;
5844
5587
  delete vertices;
5845
5588
 
5846
 
  obj1.initArray(xref);
5847
 
 
 
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)));
5851
5593
  }
5852
5594
 
5853
 
  vertices = new AnnotPath(obj1.getArray());
 
5595
  vertices = new AnnotPath(a);
5854
5596
 
5855
 
  update("Vertices", &obj1);
 
5597
  update("Vertices", Object(a));
5856
5598
  invalidateAppearance();
5857
5599
}
5858
5600
 
5859
5601
void AnnotPolygon::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
5860
 
  Object obj1, obj2;
5861
 
 
5862
5602
  startStyle = start;
5863
5603
  endStyle = end;
5864
5604
 
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 )) );
5868
5608
 
5869
 
  update("LE", &obj1);
 
5609
  update("LE", Object(a));
5870
5610
  invalidateAppearance();
5871
5611
}
5872
5612
 
5874
5614
  delete interiorColor;
5875
5615
 
5876
5616
  if (new_color) {
5877
 
    Object obj1;
5878
 
    new_color->writeToObject(xref, &obj1);
5879
 
    update ("IC", &obj1);
 
5617
    Object obj1 = new_color->writeToObject(xref);
 
5618
    update ("IC", std::move(obj1));
5880
5619
    interiorColor = new_color;
5881
5620
  } else {
5882
5621
    interiorColor = NULL;
5885
5624
}
5886
5625
 
5887
5626
void AnnotPolygon::setIntent(AnnotPolygonIntent new_intent) {
5888
 
  Object obj1;
 
5627
  const char *intentName;
5889
5628
 
5890
5629
  intent = new_intent;
5891
5630
  if (new_intent == polygonCloud)
5892
 
    obj1.initName("PolygonCloud");
 
5631
    intentName = "PolygonCloud";
5893
5632
  else if (new_intent == polylineDimension)
5894
 
    obj1.initName("PolyLineDimension");
 
5633
    intentName = "PolyLineDimension";
5895
5634
  else // polygonDimension
5896
 
    obj1.initName("PolygonDimension");
5897
 
  update ("IT", &obj1);
 
5635
    intentName = "PolygonDimension";
 
5636
  update ("IT", Object(objName, intentName));
5898
5637
}
5899
5638
 
5900
5639
void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
5901
 
  Object obj;
5902
5640
  double ca = 1;
5903
5641
 
5904
5642
  if (!isVisible (printing))
5948
5686
    double bbox[4];
5949
5687
    appearBBox->getBBoxRect(bbox);
5950
5688
    if (ca == 1) {
5951
 
      createForm(bbox, gFalse, NULL, &appearance);
 
5689
      appearance = createForm(bbox, gFalse, nullptr);
5952
5690
    } else {
5953
 
      Object aStream, resDict;
5954
 
 
5955
 
      createForm(bbox, gTrue, NULL, &aStream);
 
5691
      Object aStream = createForm(bbox, gTrue, nullptr);
5956
5692
      delete appearBuf;
5957
5693
 
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);
5961
5697
    }
5962
5698
    delete appearBuf;
5963
5699
  }
5964
5700
 
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(),
5973
5709
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
5974
5710
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
5975
5711
  }
5976
 
  obj.free();
5977
5712
}
5978
5713
 
5979
5714
//------------------------------------------------------------------------
5985
5720
 
5986
5721
  type = typeCaret;
5987
5722
 
5988
 
  annotObj.dictSet ("Subtype", obj1.initName ("Caret"));
 
5723
  annotObj.dictSet ("Subtype", Object(objName, "Caret"));
5989
5724
  initialize(docA, annotObj.getDict());
5990
5725
}
5991
5726
 
5992
 
AnnotCaret::AnnotCaret(PDFDoc *docA, Dict *dict, Object *obj) :
5993
 
  AnnotMarkup(docA, dict, obj) {
 
5727
AnnotCaret::AnnotCaret(PDFDoc *docA, Object *dictObject, Object *obj) :
 
5728
  AnnotMarkup(docA, dictObject, obj) {
5994
5729
  type = typeCaret;
5995
 
  initialize(docA, dict);
 
5730
  initialize(docA, dictObject->getDict());
5996
5731
}
5997
5732
 
5998
5733
AnnotCaret::~AnnotCaret() {
6003
5738
  Object obj1;
6004
5739
 
6005
5740
  symbol = symbolNone;
6006
 
  if (dict->lookup("Sy", &obj1)->isName()) {
 
5741
  obj1 = dict->lookup("Sy");
 
5742
  if (obj1.isName()) {
6007
5743
    GooString typeName(obj1.getName());
6008
5744
    if (!typeName.cmp("P")) {
6009
5745
      symbol = symbolP;
6011
5747
      symbol = symbolNone;
6012
5748
    }
6013
5749
  }
6014
 
  obj1.free();
6015
5750
 
6016
 
  if (dict->lookup("RD", &obj1)->isArray()) {
 
5751
  obj1 = dict->lookup("RD");
 
5752
  if (obj1.isArray()) {
6017
5753
    caretRect = parseDiffRectangle(obj1.getArray(), rect);
6018
5754
  } else {
6019
5755
    caretRect = NULL;
6020
5756
  }
6021
 
  obj1.free();
6022
 
 
6023
5757
}
6024
5758
 
6025
5759
void AnnotCaret::setSymbol(AnnotCaretSymbol new_symbol) {
6026
 
  Object obj1;
6027
 
  obj1.initName( new_symbol == symbolP ? "P" : "None" );
6028
5760
  symbol = new_symbol;
6029
 
  update("Sy", &obj1);
 
5761
  update("Sy", Object(objName, new_symbol == symbolP ? "P" : "None"));
6030
5762
  invalidateAppearance();
6031
5763
}
6032
5764
 
6039
5771
 
6040
5772
  type = typeInk;
6041
5773
 
6042
 
  annotObj.dictSet ("Subtype", obj1.initName ("Ink"));
 
5774
  annotObj.dictSet ("Subtype", Object(objName, "Ink"));
6043
5775
 
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);
 
5777
  Object obj3, obj4;
 
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));
6051
5784
 
6052
5785
  initialize(docA, annotObj.getDict());
6053
5786
}
6054
5787
 
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());
6059
5792
}
6060
5793
 
6061
5794
AnnotInk::~AnnotInk() {
6065
5798
void AnnotInk::initialize(PDFDoc *docA, Dict* dict) {
6066
5799
  Object obj1;
6067
5800
 
6068
 
  if (dict->lookup("InkList", &obj1)->isArray()) {
 
5801
  obj1 = dict->lookup("InkList");
 
5802
  if (obj1.isArray()) {
6069
5803
    parseInkList(obj1.getArray());
6070
5804
  } else {
6071
5805
    inkListLength = 0;
6073
5807
    error(errSyntaxError, -1, "Bad Annot Ink List");
6074
5808
    ok = gFalse;
6075
5809
  }
6076
 
  obj1.free();
6077
5810
 
6078
 
  if (dict->lookup("BS", &obj1)->isDict()) {
 
5811
  obj1 = dict->lookup("BS");
 
5812
  if (obj1.isDict()) {
6079
5813
    delete border;
6080
5814
    border = new AnnotBorderBS(obj1.getDict());
6081
5815
  } else if (!border) {
6082
5816
    border = new AnnotBorderBS();
6083
5817
  }
6084
 
  obj1.free();
6085
5818
}
6086
5819
 
6087
5820
void AnnotInk::writeInkList(AnnotPath **paths, int n_paths, Array *dest_array) {
6088
 
  Object obj1, obj2;
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)));
6095
5827
    }
6096
 
    dest_array->add (&obj1);
 
5828
    dest_array->add(Object(a));
6097
5829
  }
6098
5830
}
6099
5831
 
6102
5834
  inkList = (AnnotPath **) gmallocn ((inkListLength), sizeof(AnnotPath *));
6103
5835
  memset(inkList, 0, inkListLength * sizeof(AnnotPath *));
6104
5836
  for (int i = 0; i < inkListLength; i++) {
6105
 
    Object obj2;
6106
 
    if (array->get(i, &obj2)->isArray())
 
5837
    Object obj2 = array->get(i);
 
5838
    if (obj2.isArray())
6107
5839
      inkList[i] = new AnnotPath(obj2.getArray());
6108
 
    obj2.free();
6109
5840
  }
6110
5841
}
6111
5842
 
6118
5849
}
6119
5850
 
6120
5851
void AnnotInk::setInkList(AnnotPath **paths, int n_paths) {
6121
 
  Object obj1;
6122
 
 
6123
5852
  freeInkList();
6124
5853
 
6125
 
  obj1.initArray (xref);
6126
 
  writeInkList(paths, n_paths, obj1.getArray());
 
5854
  Array *a = new Array(xref);
 
5855
  writeInkList(paths, n_paths, a);
6127
5856
 
6128
 
  parseInkList(obj1.getArray());
6129
 
  annotObj.dictSet ("InkList", &obj1);
 
5857
  parseInkList(a);
 
5858
  annotObj.dictSet ("InkList", Object(a));
6130
5859
  invalidateAppearance();
6131
5860
}
6132
5861
 
6133
5862
void AnnotInk::draw(Gfx *gfx, GBool printing) {
6134
 
  Object obj;
6135
5863
  double ca = 1;
6136
5864
 
6137
5865
  if (!isVisible (printing))
6172
5900
    double bbox[4];
6173
5901
    appearBBox->getBBoxRect(bbox);
6174
5902
    if (ca == 1) {
6175
 
      createForm(bbox, gFalse, NULL, &appearance);
 
5903
      appearance = createForm(bbox, gFalse, nullptr);
6176
5904
    } else {
6177
 
      Object aStream, resDict;
6178
 
 
6179
 
      createForm(bbox, gTrue, NULL, &aStream);
 
5905
      Object aStream = createForm(bbox, gTrue, nullptr);
6180
5906
      delete appearBuf;
6181
5907
 
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);
6185
5911
    }
6186
5912
    delete appearBuf;
6187
5913
  }
6188
5914
 
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(),
6197
5923
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
6198
5924
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
6199
5925
  }
6200
 
  obj.free();
6201
5926
}
6202
5927
 
6203
5928
//------------------------------------------------------------------------
6209
5934
 
6210
5935
  type = typeFileAttachment;
6211
5936
 
6212
 
  annotObj.dictSet ("Subtype", obj1.initName ("FileAttachment"));
6213
 
 
6214
 
  Object obj2;
6215
 
  obj2.initString(filename->copy());
6216
 
  annotObj.dictSet ("FS", &obj2);
 
5937
  annotObj.dictSet("Subtype", Object(objName, "FileAttachment"));
 
5938
  annotObj.dictSet("FS", Object(filename->copy()));
6217
5939
 
6218
5940
  initialize(docA, annotObj.getDict());
6219
5941
}
6220
5942
 
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());
6225
5947
}
6226
5948
 
6227
5949
AnnotFileAttachment::~AnnotFileAttachment() {
6228
 
  file.free();
6229
 
 
6230
 
  if (name)
6231
 
    delete name;
 
5950
  delete name;
6232
5951
}
6233
5952
 
6234
5953
void AnnotFileAttachment::initialize(PDFDoc *docA, Dict* dict) {
6235
5954
  Object obj1;
6236
5955
 
6237
 
  if (dict->lookup("FS", &obj1)->isDict() || dict->lookup("FS", &obj1)->isString()) {
6238
 
    obj1.copy(&file);
 
5956
  obj1 = dict->lookup("FS");
 
5957
  if (obj1.isDict() || obj1.isString()) {
 
5958
    file = obj1.copy();
6239
5959
  } else {
6240
5960
    error(errSyntaxError, -1, "Bad Annot File Attachment");
6241
5961
    ok = gFalse;
6242
5962
  }
6243
 
  obj1.free();
6244
5963
 
6245
 
  if (dict->lookup("Name", &obj1)->isName()) {
 
5964
  obj1 = dict->lookup("Name");
 
5965
  if (obj1.isName()) {
6246
5966
    name = new GooString(obj1.getName());
6247
5967
  } else {
6248
5968
    name = new GooString("PushPin");
6249
5969
  }
6250
 
  obj1.free();
6251
5970
}
6252
5971
 
6253
5972
#define ANNOT_FILE_ATTACHMENT_AP_PUSHPIN                                         \
6363
6082
  "19.5 17.699 20.91 17.418 22.5 17.5 c S\n"
6364
6083
 
6365
6084
void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) {
6366
 
  Object obj;
6367
6085
  double ca = 1;
6368
6086
 
6369
6087
  if (!isVisible (printing))
6394
6112
    bbox[0] = bbox[1] = 0;
6395
6113
    bbox[2] = bbox[3] = 24;
6396
6114
    if (ca == 1) {
6397
 
      createForm (bbox, gFalse, NULL, &appearance);
 
6115
      appearance = createForm (bbox, gFalse, nullptr);
6398
6116
    } else {
6399
 
      Object aStream;
6400
 
 
6401
 
      createForm (bbox, gTrue, NULL, &aStream);
 
6117
      Object aStream = createForm (bbox, gTrue, nullptr);
6402
6118
      delete appearBuf;
6403
6119
 
6404
 
      Object resDict;
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);
6408
6123
    }
6409
6124
    delete appearBuf;
6410
6125
  }
6411
6126
 
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());
6416
 
  obj.free();
6417
6131
}
6418
6132
 
6419
6133
//------------------------------------------------------------------------
6425
6139
 
6426
6140
  type = typeSound;
6427
6141
 
6428
 
  annotObj.dictSet ("Subtype", obj1.initName ("Sound"));
6429
 
 
6430
 
  Object obj2;
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());
6435
6144
 
6436
6145
  initialize(docA, annotObj.getDict());
6437
6146
}
6438
6147
 
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());
6443
6152
}
6444
6153
 
6445
6154
AnnotSound::~AnnotSound() {
6449
6158
}
6450
6159
 
6451
6160
void AnnotSound::initialize(PDFDoc *docA, Dict* dict) {
6452
 
  Object obj1;
 
6161
  Object obj1 = dict->lookup("Sound");
6453
6162
 
6454
 
  sound = Sound::parseSound(dict->lookup("Sound", &obj1));
 
6163
  sound = Sound::parseSound(&obj1);
6455
6164
  if (!sound) {
6456
6165
    error(errSyntaxError, -1, "Bad Annot Sound");
6457
6166
    ok = gFalse;
6458
6167
  }
6459
 
  obj1.free();
6460
6168
 
6461
 
  if (dict->lookup("Name", &obj1)->isName()) {
 
6169
  obj1 = dict->lookup("Name");
 
6170
  if (obj1.isName()) {
6462
6171
    name = new GooString(obj1.getName());
6463
6172
  } else {
6464
6173
    name = new GooString("Speaker");
6465
6174
  }
6466
 
  obj1.free();
6467
6175
}
6468
6176
 
6469
6177
#define ANNOT_SOUND_AP_SPEAKER                                               \
6557
6265
    bbox[0] = bbox[1] = 0;
6558
6266
    bbox[2] = bbox[3] = 24;
6559
6267
    if (ca == 1) {
6560
 
      createForm(bbox, gFalse, NULL, &appearance);
 
6268
      appearance = createForm(bbox, gFalse, nullptr);
6561
6269
    } else {
6562
 
      Object aStream, resDict;
6563
 
 
6564
 
      createForm(bbox, gTrue, NULL, &aStream);
 
6270
      Object aStream = createForm(bbox, gTrue, nullptr);
6565
6271
      delete appearBuf;
6566
6272
 
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);
6570
6276
    }
6571
6277
    delete appearBuf;
6572
6278
  }
6573
6279
 
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());
6578
 
  obj.free();
6579
6284
}
6580
6285
 
6581
6286
//------------------------------------------------------------------------
6587
6292
 
6588
6293
  type = type3D;
6589
6294
 
6590
 
  annotObj.dictSet ("Subtype", obj1.initName ("3D"));
 
6295
  annotObj.dictSet ("Subtype", Object(objName, "3D"));
6591
6296
 
6592
6297
  initialize(docA, annotObj.getDict());
6593
6298
}
6594
6299
 
6595
 
Annot3D::Annot3D(PDFDoc *docA, Dict *dict, Object *obj) :
6596
 
  Annot(docA, dict, obj) {
 
6300
Annot3D::Annot3D(PDFDoc *docA, Object *dictObject, Object *obj) :
 
6301
  Annot(docA, dictObject, obj) {
6597
6302
  type = type3D;
6598
 
  initialize(docA, dict);
 
6303
  initialize(docA, dictObject->getDict());
6599
6304
}
6600
6305
 
6601
6306
Annot3D::~Annot3D() {
6604
6309
}
6605
6310
 
6606
6311
void Annot3D::initialize(PDFDoc *docA, Dict* dict) {
6607
 
  Object obj1;
6608
 
 
6609
 
  if (dict->lookup("3DA", &obj1)->isDict()) {
 
6312
  Object obj1 = dict->lookup("3DA");
 
6313
  if (obj1.isDict()) {
6610
6314
    activation = new Activation(obj1.getDict());
6611
6315
  } else {
6612
6316
    activation = NULL;
6613
6317
  }
6614
 
  obj1.free();
6615
6318
}
6616
6319
 
6617
6320
Annot3D::Activation::Activation(Dict *dict) {
6618
6321
  Object obj1;
6619
6322
 
6620
 
  if (dict->lookup("A", &obj1)->isName()) {
 
6323
  obj1 = dict->lookup("A");
 
6324
  if (obj1.isName()) {
6621
6325
    const char *name = obj1.getName();
6622
6326
 
6623
6327
    if(!strcmp(name, "PO")) {
6632
6336
  } else {
6633
6337
    aTrigger = aTriggerUnknown;
6634
6338
  }
6635
 
  obj1.free();
6636
6339
 
6637
 
  if(dict->lookup("AIS", &obj1)->isName()) {
 
6340
  obj1 = dict->lookup("AIS");
 
6341
  if (obj1.isName()) {
6638
6342
    const char *name = obj1.getName();
6639
6343
 
6640
6344
    if(!strcmp(name, "I")) {
6647
6351
  } else {
6648
6352
    aState = aStateUnknown;
6649
6353
  }
6650
 
  obj1.free();
6651
6354
 
6652
 
  if(dict->lookup("D", &obj1)->isName()) {
 
6355
  obj1 = dict->lookup("D");
 
6356
  if (obj1.isName()) {
6653
6357
    const char *name = obj1.getName();
6654
6358
 
6655
6359
    if(!strcmp(name, "PC")) {
6664
6368
  } else {
6665
6369
    dTrigger = dTriggerUnknown;
6666
6370
  }
6667
 
  obj1.free();
6668
6371
 
6669
 
  if(dict->lookup("DIS", &obj1)->isName()) {
 
6372
  obj1 = dict->lookup("DIS");
 
6373
  if (obj1.isName()) {
6670
6374
    const char *name = obj1.getName();
6671
6375
 
6672
6376
    if(!strcmp(name, "U")) {
6681
6385
  } else {
6682
6386
    dState = dStateUnknown;
6683
6387
  }
6684
 
  obj1.free();
6685
6388
 
6686
 
  if (dict->lookup("TB", &obj1)->isBool()) {
 
6389
  obj1 = dict->lookup("TB");
 
6390
  if (obj1.isBool()) {
6687
6391
    displayToolbar = obj1.getBool();
6688
6392
  } else {
6689
6393
    displayToolbar = gTrue;
6690
6394
  }
6691
 
  obj1.free();
6692
6395
 
6693
 
  if (dict->lookup("NP", &obj1)->isBool()) {
 
6396
  obj1 = dict->lookup("NP");
 
6397
  if (obj1.isBool()) {
6694
6398
    displayNavigation = obj1.getBool();
6695
6399
  } else {
6696
6400
    displayNavigation = gFalse;
6697
6401
  }
6698
 
  obj1.free();
6699
6402
}
6700
6403
 
6701
6404
//------------------------------------------------------------------------
6707
6410
 
6708
6411
  type = typeRichMedia;
6709
6412
 
6710
 
  annotObj.dictSet ("Subtype", obj1.initName ("RichMedia"));
 
6413
  annotObj.dictSet ("Subtype", Object(objName, "RichMedia"));
6711
6414
 
6712
6415
  initialize(docA, annotObj.getDict());
6713
6416
}
6714
6417
 
6715
 
AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj) :
6716
 
  Annot(docA, dict, obj) {
 
6418
AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Object *dictObject, Object *obj) :
 
6419
  Annot(docA, dictObject, obj) {
6717
6420
  type = typeRichMedia;
6718
 
  initialize(docA, dict);
 
6421
  initialize(docA, dictObject->getDict());
6719
6422
}
6720
6423
 
6721
6424
AnnotRichMedia::~AnnotRichMedia() {
6724
6427
}
6725
6428
 
6726
6429
void AnnotRichMedia::initialize(PDFDoc *docA, Dict* dict) {
6727
 
  Object obj1;
6728
 
 
6729
 
  if (dict->lookup("RichMediaContent", &obj1)->isDict()) {
 
6430
  Object obj1 = dict->lookup("RichMediaContent");
 
6431
  if (obj1.isDict()) {
6730
6432
    content = new AnnotRichMedia::Content(obj1.getDict());
6731
6433
  } else {
6732
6434
    content = NULL;
6733
6435
  }
6734
 
  obj1.free();
6735
6436
 
6736
 
  if (dict->lookup("RichMediaSettings", &obj1)->isDict()) {
 
6437
  obj1 = dict->lookup("RichMediaSettings");
 
6438
  if (obj1.isDict()) {
6737
6439
    settings = new AnnotRichMedia::Settings(obj1.getDict());
6738
6440
  } else {
6739
6441
    settings = NULL;
6740
6442
  }
6741
 
  obj1.free();
6742
6443
}
6743
6444
 
6744
6445
AnnotRichMedia::Content* AnnotRichMedia::getContent() const {
6750
6451
}
6751
6452
 
6752
6453
AnnotRichMedia::Settings::Settings(Dict *dict) {
6753
 
  Object obj1;
6754
 
 
6755
 
  if (dict->lookup("Activation", &obj1)->isDict()) {
 
6454
  Object obj1 = dict->lookup("Activation");
 
6455
  if (obj1.isDict()) {
6756
6456
    activation = new AnnotRichMedia::Activation(obj1.getDict());
6757
6457
  } else {
6758
6458
    activation = NULL;
6759
6459
  }
6760
 
  obj1.free();
6761
6460
 
6762
 
  if (dict->lookup("Deactivation", &obj1)->isDict()) {
 
6461
  obj1 = dict->lookup("Deactivation");
 
6462
  if (obj1.isDict()) {
6763
6463
    deactivation = new AnnotRichMedia::Deactivation(obj1.getDict());
6764
6464
  } else {
6765
6465
    deactivation = NULL;
6766
6466
  }
6767
 
  obj1.free();
6768
6467
}
6769
6468
 
6770
6469
AnnotRichMedia::Settings::~Settings() {
6781
6480
}
6782
6481
 
6783
6482
AnnotRichMedia::Activation::Activation(Dict *dict) {
6784
 
  Object obj1;
6785
 
 
6786
 
  if (dict->lookup("Condition", &obj1)->isName()) {
 
6483
  Object obj1 = dict->lookup("Condition");
 
6484
  if (obj1.isName()) {
6787
6485
    const char *name = obj1.getName();
6788
6486
 
6789
6487
    if (!strcmp(name, "PO")) {
6798
6496
  } else {
6799
6497
    condition = conditionUserAction;
6800
6498
  }
6801
 
  obj1.free();
6802
6499
}
6803
6500
 
6804
6501
AnnotRichMedia::Activation::Condition AnnotRichMedia::Activation::getCondition() const {
6806
6503
}
6807
6504
 
6808
6505
AnnotRichMedia::Deactivation::Deactivation(Dict *dict) {
6809
 
  Object obj1;
6810
 
 
6811
 
  if (dict->lookup("Condition", &obj1)->isName()) {
 
6506
  Object obj1 = dict->lookup("Condition");
 
6507
  if (obj1.isName()) {
6812
6508
    const char *name = obj1.getName();
6813
6509
 
6814
6510
    if (!strcmp(name, "PC")) {
6823
6519
  } else {
6824
6520
    condition = conditionUserAction;
6825
6521
  }
6826
 
  obj1.free();
6827
6522
}
6828
6523
 
6829
6524
AnnotRichMedia::Deactivation::Condition AnnotRichMedia::Deactivation::getCondition() const {
6831
6526
}
6832
6527
 
6833
6528
AnnotRichMedia::Content::Content(Dict *dict) {
6834
 
  Object obj1;
6835
 
 
6836
 
  if (dict->lookup("Configurations", &obj1)->isArray()) {
 
6529
  Object obj1 = dict->lookup("Configurations");
 
6530
  if (obj1.isArray()) {
6837
6531
    nConfigurations = obj1.arrayGetLength();
6838
6532
 
6839
6533
    configurations = (Configuration **)gmallocn(nConfigurations, sizeof(Configuration *));
6840
6534
 
6841
6535
    for (int i = 0; i < nConfigurations; ++i) {
6842
 
      Object obj2;
6843
 
 
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());
6846
6539
      } else {
6847
6540
        configurations[i] = NULL;
6848
6541
      }
6849
 
      obj2.free();
6850
6542
    }
6851
6543
  } else {
6852
6544
    nConfigurations = 0;
6853
6545
    configurations = NULL;
6854
6546
  }
6855
 
  obj1.free();
6856
6547
 
6857
6548
  nAssets = 0;
6858
6549
  assets = NULL;
6859
 
  if (dict->lookup("Assets", &obj1)->isDict()) {
6860
 
    Object obj2;
6861
 
 
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;
6864
6555
 
6865
6556
      assets = (Asset **)gmallocn(nAssets, sizeof(Asset *));
6866
6557
 
6867
6558
      int counter = 0;
6868
 
      for (int i = 0; i < obj2.arrayGetLength(); i += 2) {
6869
 
        Object objKey;
6870
 
 
 
6559
      for (int i = 0; i < nAssets; ++i) {
6871
6560
        assets[counter] = new AnnotRichMedia::Asset;
6872
6561
 
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);
6875
6564
 
6876
6565
        assets[counter]->name = new GooString( objKey.getString() );
6877
6566
        ++counter;
6878
6567
 
6879
 
        objKey.free();
6880
6568
      }
6881
6569
    }
6882
 
    obj2.free();
6883
6570
  }
6884
 
  obj1.free();
6885
6571
}
6886
6572
 
6887
6573
AnnotRichMedia::Content::~Content() {
6928
6614
AnnotRichMedia::Asset::~Asset()
6929
6615
{
6930
6616
  delete name;
6931
 
  fileSpec.free();
6932
6617
}
6933
6618
 
6934
6619
GooString* AnnotRichMedia::Asset::getName() const {
6941
6626
 
6942
6627
AnnotRichMedia::Configuration::Configuration(Dict *dict)
6943
6628
{
6944
 
  Object obj1;
6945
 
 
6946
 
  if (dict->lookup("Instances", &obj1)->isArray()) {
 
6629
  Object obj1 = dict->lookup("Instances");
 
6630
  if (obj1.isArray()) {
6947
6631
    nInstances = obj1.arrayGetLength();
6948
6632
 
6949
6633
    instances = (Instance **)gmallocn(nInstances, sizeof(Instance *));
6950
6634
 
6951
6635
    for (int i = 0; i < nInstances; ++i) {
6952
 
      Object obj2;
6953
 
 
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());
6956
6639
      } else {
6957
6640
        instances[i] = NULL;
6958
6641
      }
6959
 
      obj2.free();
6960
6642
    }
6961
6643
  } else {
6962
6644
    instances = NULL;
6963
6645
  }
6964
 
  obj1.free();
6965
6646
 
6966
 
  if (dict->lookup("Name", &obj1)->isString()) {
 
6647
  obj1 = dict->lookup("Name");
 
6648
  if (obj1.isString()) {
6967
6649
    name = new GooString(obj1.getString());
6968
6650
  } else {
6969
6651
    name = NULL;
6970
6652
  }
6971
 
  obj1.free();
6972
6653
 
6973
 
  if (dict->lookup("Subtype", &obj1)->isName()) {
 
6654
  obj1 = dict->lookup("Subtype");
 
6655
  if (obj1.isName()) {
6974
6656
    const char *name = obj1.getName();
6975
6657
 
6976
6658
    if (!strcmp(name, "3D")) {
6982
6664
    } else if (!strcmp(name, "Video")) {
6983
6665
      type = typeVideo;
6984
6666
    } else {
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:
6990
 
            type = type3D;
6991
 
            break;
6992
 
          case AnnotRichMedia::Instance::typeFlash:
6993
 
            type = typeFlash;
6994
 
            break;
6995
 
          case AnnotRichMedia::Instance::typeSound:
6996
 
            type = typeSound;
6997
 
            break;
6998
 
          case AnnotRichMedia::Instance::typeVideo:
6999
 
            type = typeVideo;
7000
 
            break;
7001
 
          default:
7002
 
            type = typeFlash;
7003
 
            break;
7004
 
        }
 
6670
        for (int i = 0; i < nInstances; ++i) {
 
6671
          AnnotRichMedia::Instance *instance = instances[i];
 
6672
          if (instance) {
 
6673
            switch (instance->getType()) {
 
6674
              case AnnotRichMedia::Instance::type3D:
 
6675
                type = type3D;
 
6676
                break;
 
6677
              case AnnotRichMedia::Instance::typeFlash:
 
6678
                type = typeFlash;
 
6679
                break;
 
6680
              case AnnotRichMedia::Instance::typeSound:
 
6681
                type = typeSound;
 
6682
                break;
 
6683
              case AnnotRichMedia::Instance::typeVideo:
 
6684
                type = typeVideo;
 
6685
                break;
 
6686
            }
 
6687
            // break the loop since we found the first non null instance
 
6688
            break;
 
6689
          }
 
6690
        }
7005
6691
      }
7006
6692
    }
7007
6693
  }
7008
 
  obj1.free();
7009
6694
}
7010
6695
 
7011
6696
AnnotRichMedia::Configuration::~Configuration()
7040
6725
 
7041
6726
AnnotRichMedia::Instance::Instance(Dict *dict)
7042
6727
{
7043
 
  Object obj1;
7044
 
 
7045
 
  dict->lookup("Subtype", &obj1);
 
6728
  Object obj1 = dict->lookup("Subtype");
7046
6729
  const char *name = obj1.isName() ? obj1.getName() : "";
7047
6730
 
7048
6731
  if (!strcmp(name, "3D")) {
7056
6739
  } else {
7057
6740
    type = typeFlash;
7058
6741
  }
7059
 
  obj1.free();
7060
6742
 
7061
 
  if (dict->lookup("Params", &obj1)->isDict()) {
 
6743
  obj1 = dict->lookup("Params");
 
6744
  if (obj1.isDict()) {
7062
6745
    params = new AnnotRichMedia::Params(obj1.getDict());
7063
6746
  } else {
7064
6747
    params = NULL;
7065
6748
  }
7066
 
  obj1.free();
7067
6749
}
7068
6750
 
7069
6751
AnnotRichMedia::Instance::~Instance()
7081
6763
 
7082
6764
AnnotRichMedia::Params::Params(Dict *dict)
7083
6765
{
7084
 
  Object obj1;
7085
 
 
7086
 
  if (dict->lookup("FlashVars", &obj1)->isString()) {
 
6766
  Object obj1 = dict->lookup("FlashVars");
 
6767
  if (obj1.isString()) {
7087
6768
    flashVars = new GooString(obj1.getString());
7088
6769
  } else {
7089
6770
    flashVars = NULL;
7090
6771
  }
7091
 
  obj1.free();
7092
6772
}
7093
6773
 
7094
6774
AnnotRichMedia::Params::~Params()
7106
6786
 
7107
6787
Annots::Annots(PDFDoc *docA, int page, Object *annotsObj) {
7108
6788
  Annot *annot;
7109
 
  Object obj1;
7110
6789
  int i;
7111
6790
 
7112
6791
  doc = docA;
7119
6798
      //get the Ref to this annot and pass it to Annot constructor 
7120
6799
      //this way, it'll be possible for the annot to retrieve the corresponding
7121
6800
      //form widget
7122
 
      Object obj2;
7123
 
      if (annotsObj->arrayGet(i, &obj1)->isDict()) {
7124
 
        annotsObj->arrayGetNF(i, &obj2);
7125
 
        annot = createAnnot (obj1.getDict(), &obj2);
 
6801
      Object obj1 = annotsObj->arrayGet(i);
 
6802
      if (obj1.isDict()) {
 
6803
        Object obj2 = annotsObj->arrayGetNF(i);
 
6804
        annot = createAnnot (&obj1, &obj2);
7126
6805
        if (annot) {
7127
6806
          if (annot->isOk()) {
7128
6807
            annot->setPage(page, gFalse); // Don't change /P
7131
6810
          annot->decRefCnt();
7132
6811
        }
7133
6812
      }
7134
 
      obj2.free();
7135
 
      obj1.free();
7136
6813
    }
7137
6814
  }
7138
6815
}
7166
6843
  }
7167
6844
}
7168
6845
 
7169
 
Annot *Annots::createAnnot(Dict* dict, Object *obj) {
7170
 
  Annot *annot = NULL;
7171
 
  Object obj1;
7172
 
 
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();
7175
6851
 
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()) {
7222
6898
        }
7223
6899
      }
7224
6900
      if (!annot)
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
7242
6918
       */
7243
 
      Object obj2;
7244
 
 
7245
 
      if (dict->lookup("Parent", &obj2)->isNull())
7246
 
        annot = new AnnotPopup(doc, dict, obj);
 
6919
      Object obj2 = dictObject->dictLookup("Parent");
 
6920
      if (obj2.isNull())
 
6921
        annot = new AnnotPopup(doc, dictObject, obj);
7247
6922
      else
7248
6923
        annot = NULL;
7249
 
      
7250
 
      obj2.free();
7251
6924
    } else {
7252
 
      annot = new Annot(doc, dict, obj);
 
6925
      annot = new Annot(doc, dictObject, obj);
7253
6926
    }
7254
6927
  }
7255
 
  obj1.free();
7256
6928
 
7257
6929
  return annot;
7258
6930
}