Annot.h 53.7 KB
Newer Older
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1
2
3
4
5
6
7
8
//========================================================================
//
// Annot.h
//
// Copyright 2000-2003 Glyph & Cog, LLC
//
//========================================================================

9
10
11
12
//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
13
14
15
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
16
17
// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
Albert Astals Cid's avatar
Albert Astals Cid committed
18
// Copyright (C) 2007-2011, 2013, 2015, 2018 Carlos Garcia Campos <carlosgc@gnome.org>
19
20
21
22
// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
// Copyright (C) 2008 Pino Toscano <pino@kde.org>
23
// Copyright (C) 2008 Tomas Are Haavet <tomasare@gmail.com>
24
// Copyright (C) 2009-2011, 2013, 2016-2019 Albert Astals Cid <aacid@kde.org>
25
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
Albert Astals Cid's avatar
add (C)    
Albert Astals Cid committed
26
// Copyright (C) 2012, 2015 Tobias Koenig <tokoe@kdab.com>
Thomas Freitag's avatar
Thomas Freitag committed
27
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
28
// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
29
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
Albert Astals Cid's avatar
Albert Astals Cid committed
30
31
// Copyright (C) 2018 Dileep Sankhla <sankhla.dileep96@gmail.com>
// Copyright (C) 2018 Tobias Deiminger <haxtibal@posteo.de>
32
// Copyright (C) 2018 Oliver Sander <oliver.sander@tu-dresden.de>
Albert Astals Cid's avatar
Albert Astals Cid committed
33
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
34
// Copyright (C) 2019 Umang Malik <umang99m@gmail.com>
35
36
37
38
39
40
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

Kristian Høgsberg's avatar
Kristian Høgsberg committed
41
42
43
#ifndef ANNOT_H
#define ANNOT_H

Tobias Deiminger's avatar
Tobias Deiminger committed
44
#include <memory>
45
46
#include <atomic>
#include <mutex>
47
#include <vector>
48

49
50
#include "Object.h"

Kristian Høgsberg's avatar
Kristian Høgsberg committed
51
52
class XRef;
class Gfx;
53
54
class CharCodeToUnicode;
class GfxFont;
55
class GfxResources;
56
class Page;
57
class PDFDoc;
58
class Form;
59
class FormWidget;
60
class FormField;
61
62
class FormFieldButton;
class FormFieldText;
63
class FormFieldChoice;
Inigo Martínez's avatar
Inigo Martínez committed
64
class PDFRectangle;
Hugo Mercier's avatar
Hugo Mercier committed
65
class Movie;
66
class LinkAction;
Pino Toscano's avatar
Pino Toscano committed
67
class Sound;
68
class FileSpec;
Inigo Martínez's avatar
Inigo Martínez committed
69

Inigo Martínez's avatar
Inigo Martínez committed
70
71
72
73
74
75
76
77
78
79
80
81
82
enum AnnotLineEndingStyle {
  annotLineEndingSquare,        // Square
  annotLineEndingCircle,        // Circle
  annotLineEndingDiamond,       // Diamond
  annotLineEndingOpenArrow,     // OpenArrow
  annotLineEndingClosedArrow,   // ClosedArrow
  annotLineEndingNone,          // None
  annotLineEndingButt,          // Butt
  annotLineEndingROpenArrow,    // ROpenArrow
  annotLineEndingRClosedArrow,  // RClosedArrow
  annotLineEndingSlash          // Slash
};

Inigo Martínez's avatar
Inigo Martínez committed
83
84
85
86
87
enum AnnotExternalDataType {
  annotExternalDataMarkupUnknown,
  annotExternalDataMarkup3D       // Markup3D
};

Inigo Martínez's avatar
Inigo Martínez committed
88
89
90
91
92
93
94
95
96
97
98
99
//------------------------------------------------------------------------
// AnnotCoord
//------------------------------------------------------------------------

class AnnotCoord {
public:

  AnnotCoord() : x(0), y(0) { }
  AnnotCoord(double _x, double _y) : x(_x), y(_y) { }

  double getX() const { return x; }
  double getY() const { return y; }
100

Inigo Martínez's avatar
Inigo Martínez committed
101
102
103
104
105
protected:

  double x, y;
};

Inigo Martínez's avatar
Inigo Martínez committed
106
107
108
109
110
111
//------------------------------------------------------------------------
// AnnotPath
//------------------------------------------------------------------------

class AnnotPath {
public:
112
  AnnotPath();
113
  AnnotPath(Array *array);
114
  AnnotPath(std::vector<AnnotCoord> &&coords);
115
  ~AnnotPath();
Inigo Martínez's avatar
Inigo Martínez committed
116

117
118
119
  AnnotPath(const AnnotPath &) = delete;
  AnnotPath& operator=(const AnnotPath &other) = delete;

120
121
  double getX(int coord) const;
  double getY(int coord) const;
122
123
  AnnotCoord *getCoord(int coord);
  int getCoordsLength() const { return coords.size(); }
Inigo Martínez's avatar
Inigo Martínez committed
124
protected:
125
  std::vector<AnnotCoord> coords;
126
127

  void parsePathArray(Array *array);
Inigo Martínez's avatar
Inigo Martínez committed
128
129
};
  
Inigo Martínez's avatar
Inigo Martínez committed
130
131
132
133
134
135
136
137
138
139
//------------------------------------------------------------------------
// AnnotCalloutLine
//------------------------------------------------------------------------

class AnnotCalloutLine {
public:

  AnnotCalloutLine(double x1, double y1, double x2, double y2);
  virtual ~AnnotCalloutLine() { }

140
141
142
  AnnotCalloutLine(const AnnotCalloutLine &) = delete;
  AnnotCalloutLine& operator=(const AnnotCalloutLine &other) = delete;

Inigo Martínez's avatar
Inigo Martínez committed
143
144
145
146
  double getX1() const { return coord1.getX(); }
  double getY1() const { return coord1.getY(); }
  double getX2() const { return coord2.getX(); }
  double getY2() const { return coord2.getY(); }
Inigo Martínez's avatar
Inigo Martínez committed
147
148
149
  
protected:

Inigo Martínez's avatar
Inigo Martínez committed
150
  AnnotCoord coord1, coord2;
Inigo Martínez's avatar
Inigo Martínez committed
151
152
153
154
155
156
157
158
159
160
161
162
};

//------------------------------------------------------------------------
// AnnotCalloutMultiLine
//------------------------------------------------------------------------

class AnnotCalloutMultiLine: public AnnotCalloutLine {
public:

  AnnotCalloutMultiLine(double x1, double y1, double x2, double y2,
    double x3, double y3);

Inigo Martínez's avatar
Inigo Martínez committed
163
164
  double getX3() const { return coord3.getX(); }
  double getY3() const { return coord3.getY(); }
Inigo Martínez's avatar
Inigo Martínez committed
165
166
167

protected:

Inigo Martínez's avatar
Inigo Martínez committed
168
  AnnotCoord coord3;
Inigo Martínez's avatar
Inigo Martínez committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
};

//------------------------------------------------------------------------
// AnnotBorderEffect
//------------------------------------------------------------------------

class AnnotBorderEffect {
public:

  enum AnnotBorderEffectType {
    borderEffectNoEffect, // S
    borderEffectCloudy    // C
  };

  AnnotBorderEffect(Dict *dict);

  AnnotBorderEffectType getEffectType() const { return effectType; }
  double getIntensity() const { return intensity; }

private:

  AnnotBorderEffectType effectType; // S  (Default S)
  double intensity;                 // I  (Default 0)
};

Inigo Martínez's avatar
Inigo Martínez committed
194
//------------------------------------------------------------------------
195
// AnnotQuadrilateral
Inigo Martínez's avatar
Inigo Martínez committed
196
197
//------------------------------------------------------------------------

198
class AnnotQuadrilaterals {
199
public:
200
201
  class AnnotQuadrilateral {
  public:
202
    AnnotQuadrilateral();
203
    AnnotQuadrilateral(double x1, double y1, double x2, double y2, double x3,
Inigo Martínez's avatar
Inigo Martínez committed
204
205
      double y3, double x4, double y4);

Inigo Martínez's avatar
Inigo Martínez committed
206
    AnnotCoord coord1, coord2, coord3, coord4;
207
  };
Inigo Martínez's avatar
Inigo Martínez committed
208

209
  AnnotQuadrilaterals(Array *array, PDFRectangle *rect);
210
  AnnotQuadrilaterals(std::unique_ptr<AnnotQuadrilateral[]> &&quads, int quadsLength);
211
  ~AnnotQuadrilaterals();
212

213
214
215
  AnnotQuadrilaterals(const AnnotQuadrilaterals &) = delete;
  AnnotQuadrilaterals& operator=(const AnnotQuadrilaterals &other) = delete;

216
217
218
219
220
221
222
223
224
  double getX1(int quadrilateral);
  double getY1(int quadrilateral);
  double getX2(int quadrilateral);
  double getY2(int quadrilateral);
  double getX3(int quadrilateral);
  double getY3(int quadrilateral);
  double getX4(int quadrilateral);
  double getY4(int quadrilateral);
  int getQuadrilateralsLength() const { return quadrilateralsLength; }
Inigo Martínez's avatar
Inigo Martínez committed
225
protected:
226

227
  std::unique_ptr<AnnotQuadrilateral[]> quadrilaterals;
228
  int quadrilateralsLength;
Inigo Martínez's avatar
Inigo Martínez committed
229
230
};

Inigo Martínez's avatar
Inigo Martínez committed
231
232
233
234
235
236
//------------------------------------------------------------------------
// AnnotBorder
//------------------------------------------------------------------------

class AnnotBorder {
public:
237
238
  enum AnnotBorderType {
    typeArray,
239
    typeBS
240
241
  };

Inigo Martínez's avatar
Inigo Martínez committed
242
243
244
245
246
  enum AnnotBorderStyle {
    borderSolid,      // Solid
    borderDashed,     // Dashed
    borderBeveled,    // Beveled
    borderInset,      // Inset
247
    borderUnderlined  // Underlined
Inigo Martínez's avatar
Inigo Martínez committed
248
  };
Inigo Martínez's avatar
Inigo Martínez committed
249

Inigo Martínez's avatar
Inigo Martínez committed
250
251
  virtual ~AnnotBorder();

252
253
254
  AnnotBorder(const AnnotBorder &) = delete;
  AnnotBorder& operator=(const AnnotBorder &other) = delete;

255
256
  virtual void setWidth(double new_width) { width = new_width; }

257
  virtual AnnotBorderType getType() const = 0;
Inigo Martínez's avatar
Inigo Martínez committed
258
259
260
261
  virtual double getWidth() const { return width; }
  virtual int getDashLength() const { return dashLength; }
  virtual double *getDash() const { return dash; }
  virtual AnnotBorderStyle getStyle() const { return style; }
Inigo Martínez's avatar
Inigo Martínez committed
262

Albert Astals Cid's avatar
Albert Astals Cid committed
263
  virtual Object writeToObject(XRef *xref) const = 0;
264

Inigo Martínez's avatar
Inigo Martínez committed
265
protected:
266
267
  AnnotBorder();

268
  bool parseDashArray(Object *dashObj);
269

270
  AnnotBorderType type;
Inigo Martínez's avatar
Inigo Martínez committed
271
  double width;
272
  static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
Inigo Martínez's avatar
Inigo Martínez committed
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  int dashLength;
  double *dash;
  AnnotBorderStyle style;
};

//------------------------------------------------------------------------
// AnnotBorderArray
//------------------------------------------------------------------------

class AnnotBorderArray: public AnnotBorder {
public:
  AnnotBorderArray();
  AnnotBorderArray(Array *array);

287
288
289
  void setHorizontalCorner(double hc) { horizontalCorner = hc; }
  void setVerticalCorner(double vc) { verticalCorner = vc; }

290
291
  double getHorizontalCorner() const { return horizontalCorner; }
  double getVerticalCorner() const { return verticalCorner; }
Inigo Martínez's avatar
Inigo Martínez committed
292

293
private:
Albert Astals Cid's avatar
Albert Astals Cid committed
294
  AnnotBorderType getType() const override { return typeArray; }
Albert Astals Cid's avatar
Albert Astals Cid committed
295
  Object writeToObject(XRef *xref) const override;
296

Inigo Martínez's avatar
Inigo Martínez committed
297
298
299
300
301
302
303
304
305
306
307
  double horizontalCorner;          // (Default 0)
  double verticalCorner;            // (Default 0)
  // double width;                  // (Default 1)  (inherited from AnnotBorder)
};

//------------------------------------------------------------------------
// AnnotBorderBS
//------------------------------------------------------------------------

class AnnotBorderBS: public AnnotBorder {
public:
Inigo Martínez's avatar
Inigo Martínez committed
308

Inigo Martínez's avatar
Inigo Martínez committed
309
310
311
312
  AnnotBorderBS();
  AnnotBorderBS(Dict *dict);

private:
Albert Astals Cid's avatar
Albert Astals Cid committed
313
  AnnotBorderType getType() const override { return typeBS; }
Albert Astals Cid's avatar
Albert Astals Cid committed
314
  Object writeToObject(XRef *xref) const override;
315
316

  const char *getStyleName() const;
317

Inigo Martínez's avatar
Inigo Martínez committed
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  // double width;           // W  (Default 1)   (inherited from AnnotBorder)
  // AnnotBorderStyle style; // S  (Default S)   (inherited from AnnotBorder)
  // double *dash;           // D  (Default [3]) (inherited from AnnotBorder)
};

//------------------------------------------------------------------------
// AnnotColor
//------------------------------------------------------------------------

class AnnotColor {
public:

  enum AnnotColorSpace {
    colorTransparent = 0,
    colorGray        = 1,
    colorRGB         = 3,
    colorCMYK        = 4
  };
Inigo Martínez's avatar
Inigo Martínez committed
336

Inigo Martínez's avatar
Inigo Martínez committed
337
  AnnotColor();
338
339
340
  AnnotColor(double gray);
  AnnotColor(double r, double g, double b);
  AnnotColor(double c, double m, double y, double k);
341
  AnnotColor(Array *array, int adjust = 0);
Inigo Martínez's avatar
Inigo Martínez committed
342

343
344
  void adjustColor(int adjust);

345
  AnnotColorSpace getSpace() const { return (AnnotColorSpace) length; }
346
  const double *getValues() const { return values; }
Inigo Martínez's avatar
Inigo Martínez committed
347

Albert Astals Cid's avatar
Albert Astals Cid committed
348
  Object writeToObject(XRef *xref) const;
349

Inigo Martínez's avatar
Inigo Martínez committed
350
351
private:

352
  double values[4];
Inigo Martínez's avatar
Inigo Martínez committed
353
354
  int length;
};
355

Dileep Sankhla's avatar
Dileep Sankhla committed
356
357
358
359
360
361
362
//------------------------------------------------------------------------
// DefaultAppearance
//------------------------------------------------------------------------

class DefaultAppearance {
public:

Albert Astals Cid's avatar
Albert Astals Cid committed
363
  DefaultAppearance(Object &&fontNameA, double fontPtSizeA, std::unique_ptr<AnnotColor> fontColorA);
Tobias Deiminger's avatar
Tobias Deiminger committed
364
365
366
367
368
369
370
371
372
  DefaultAppearance(GooString *da);
  void setFontName(Object &&fontNameA);
  const Object &getFontName() const { return fontName; }
  void setFontPtSize(double fontPtSizeA);
  double getFontPtSize() const { return fontPtSize; }
  void setFontColor(std::unique_ptr<AnnotColor> fontColorA);
  const AnnotColor *getFontColor() const { return fontColor.get(); }
  GooString *toAppearanceString() const;

Albert Astals Cid's avatar
Albert Astals Cid committed
373
  DefaultAppearance(const DefaultAppearance &) = delete;
374
  DefaultAppearance& operator=(const DefaultAppearance&) = delete;
Tobias Deiminger's avatar
Tobias Deiminger committed
375

Dileep Sankhla's avatar
Dileep Sankhla committed
376
377
private:

Tobias Deiminger's avatar
Tobias Deiminger committed
378
379
380
  Object fontName;
  double fontPtSize;
  std::unique_ptr<AnnotColor> fontColor;
Dileep Sankhla's avatar
Dileep Sankhla committed
381
382
};

383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
//------------------------------------------------------------------------
// AnnotIconFit
//------------------------------------------------------------------------

class AnnotIconFit {
public:

  enum AnnotIconFitScaleWhen {
    scaleAlways,  // A
    scaleBigger,  // B
    scaleSmaller, // S
    scaleNever    // N
  };

  enum AnnotIconFitScale {
    scaleAnamorphic,  // A
    scaleProportional // P
  };

  AnnotIconFit(Dict *dict);

  AnnotIconFitScaleWhen getScaleWhen() { return scaleWhen; }
  AnnotIconFitScale getScale() { return scale; }
  double getLeft() { return left; }
  double getBottom() { return bottom; }
  bool getFullyBounds() { return fullyBounds; }

protected:

  AnnotIconFitScaleWhen scaleWhen;  // SW (Default A)
  AnnotIconFitScale scale;          // S  (Default P)
  double left;                      // A  (Default [0.5 0.5]
  double bottom;                    // Only if scale is P
  bool fullyBounds;                 // FB (Default false)
};

//------------------------------------------------------------------------
// AnnotAppearance
//------------------------------------------------------------------------

class AnnotAppearance {
public:

  enum AnnotAppearanceType {
    appearNormal,
    appearRollover,
    appearDown
  };

432
433
434
435
  AnnotAppearance(PDFDoc *docA, Object *dict);
  ~AnnotAppearance();

  // State is ignored if no subdictionary is present
Albert Astals Cid's avatar
Albert Astals Cid committed
436
  Object getAppearanceStream(AnnotAppearanceType type, const char *state);
437
438

  // Access keys in normal appearance subdictionary (N)
439
  std::unique_ptr<GooString> getStateKey(int i);
440
441
442
443
444
445
  int getNumStates();

  // Removes all associated streams in the xref table. Caller is required to
  // reset parent annotation's AP and AS after this call.
  void removeAllStreams();

446
  // Test if this AnnotAppearance references the specified stream
447
  bool referencesStream(Ref targetStreamRef);
448

449
private:
450
  static bool referencesStream(const Object *stateObj, Ref targetStreamRef);
451
  void removeStream(Ref refToStream);
452
  void removeStateStreams(const Object *state);
453
454

protected:
455
  PDFDoc *doc;
456
457
  XRef *xref;                   // the xref table for this PDF file
  Object appearDict;            // Annotation's AP
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
};

//------------------------------------------------------------------------
// AnnotAppearanceCharacs
//------------------------------------------------------------------------

class AnnotAppearanceCharacs {
public:

  enum AnnotAppearanceCharacsTextPos {
    captionNoIcon,    // 0
    captionNoCaption, // 1
    captionBelow,     // 2
    captionAbove,     // 3
    captionRight,     // 4
    captionLeft,      // 5
    captionOverlaid   // 6
  };

  AnnotAppearanceCharacs(Dict *dict);
478
  ~AnnotAppearanceCharacs();
479

480
481
482
  AnnotAppearanceCharacs(const AnnotAppearanceCharacs &) = delete;
  AnnotAppearanceCharacs& operator=(const AnnotAppearanceCharacs &) = delete;

Albert Astals Cid's avatar
Albert Astals Cid committed
483
  int getRotation() const { return rotation; }
484
485
486
487
488
489
  const AnnotColor *getBorderColor() const { return borderColor.get(); }
  const AnnotColor *getBackColor() const { return backColor.get(); }
  const GooString *getNormalCaption() const { return normalCaption.get(); }
  const GooString *getRolloverCaption() { return rolloverCaption.get(); }
  const GooString *getAlternateCaption() { return alternateCaption.get(); }
  const AnnotIconFit *getIconFit() { return iconFit.get(); }
Albert Astals Cid's avatar
Albert Astals Cid committed
490
  AnnotAppearanceCharacsTextPos getPosition() const { return position; }
491
492
493

protected:

494
495
496
497
498
499
  int rotation;                                // R  (Default 0)
  std::unique_ptr<AnnotColor> borderColor;     // BC
  std::unique_ptr<AnnotColor> backColor;       // BG
  std::unique_ptr<GooString> normalCaption;    // CA
  std::unique_ptr<GooString> rolloverCaption;  // RC
  std::unique_ptr<GooString> alternateCaption; // AC
500
501
502
  // I
  // RI
  // IX
503
504
  std::unique_ptr<AnnotIconFit> iconFit;       // IF
  AnnotAppearanceCharacsTextPos position;      // TP (Default 0)
505
506
};

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
//------------------------------------------------------------------------
// AnnotAppearanceBBox
//------------------------------------------------------------------------

class AnnotAppearanceBBox
{
public:
  AnnotAppearanceBBox(PDFRectangle *init);

  void setBorderWidth(double w) { borderWidth = w; }

  // The following functions operate on coords relative to [origX origY]
  void extendTo(double x, double y);
  void getBBoxRect(double bbox[4]) const;

  // Get boundaries in page coordinates
  double getPageXMin() const;
  double getPageYMin() const;
  double getPageXMax() const;
  double getPageYMax() const;

private:
  double origX, origY, borderWidth;
  double minX, minY, maxX, maxY;
};

533
534
535
//------------------------------------------------------------------------
// AnnotAppearanceBuilder
//------------------------------------------------------------------------
536
class Matrix;
537
538
539
540
541
542
543
544
class AnnotAppearanceBuilder {
public:
  AnnotAppearanceBuilder();
  ~AnnotAppearanceBuilder();

  AnnotAppearanceBuilder(const AnnotAppearanceBuilder &) = delete;
  AnnotAppearanceBuilder& operator=(const AnnotAppearanceBuilder &) = delete;

545
  void setDrawColor(const AnnotColor *color, bool fill);
546
  void setLineStyleForBorder(const AnnotBorder *border);
Tobias Deiminger's avatar
Tobias Deiminger committed
547
  void setTextFont(const Object &fontName, double fontSize);
548
  void drawCircle(double cx, double cy, double r, bool fill);
549
550
  void drawCircleTopLeft(double cx, double cy, double r);
  void drawCircleBottomRight(double cx, double cy, double r);
551
  void drawLineEnding(AnnotLineEndingStyle endingStyle, double x, double y, double size, bool fill, const Matrix& m);
552
553
554
555
556
  void drawLineEndSquare(double x, double y, double size, bool fill, const Matrix& m);
  void drawLineEndCircle(double x, double y, double size, bool fill, const Matrix& m);
  void drawLineEndDiamond(double x, double y, double size, bool fill, const Matrix& m);
  void drawLineEndArrow(double x, double y, double size, int orientation, bool isOpen, bool fill, const Matrix& m);
  void drawLineEndSlash(double x, double y, double size, const Matrix& m);
557
  void drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
558
  bool drawFormField(const FormField *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);
559
  static double shortenLineSegmentForEnding(AnnotLineEndingStyle endingStyle, double x, double size);
560
561
562
563
564
565
566
567
568

  void writeString(const GooString &str);

  void append(const char *text);
  void appendf(const char *fmt, ...) GOOSTRING_FORMAT;

  const GooString *buffer() const;

private:
569
570
571
572
573
574
575
  bool drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
		   const GooString *da, const GfxResources *resources, int quadding);
  bool drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);
  bool drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
  bool drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
  bool drawText(const GooString *text, const GooString *da, const GfxResources *resources,
		const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect,
576
577
		bool multiline, int comb, int quadding,
		bool txField, bool forceZapfDingbats,
578
		XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed
579
		bool password);
580
  void drawArrowPath(double x, double y, const Matrix& m, int orientation=1);
581

582
583
584
  GooString *appearBuf;
};

Kristian Høgsberg's avatar
Kristian Høgsberg committed
585
586
587
588
589
//------------------------------------------------------------------------
// Annot
//------------------------------------------------------------------------

class Annot {
590
591
  friend class Annots;
  friend class Page;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
592
public:
Inigo Martínez's avatar
Inigo Martínez committed
593
594
595
596
597
598
599
600
601
602
603
604
605
  enum AnnotFlag {
    flagUnknown        = 0x0000,
    flagInvisible      = 0x0001,
    flagHidden         = 0x0002,
    flagPrint          = 0x0004,
    flagNoZoom         = 0x0008,
    flagNoRotate       = 0x0010,
    flagNoView         = 0x0020,
    flagReadOnly       = 0x0040,
    flagLocked         = 0x0080,
    flagToggleNoView   = 0x0100,
    flagLockedContents = 0x0200
  };
Kristian Høgsberg's avatar
Kristian Høgsberg committed
606

607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
  enum AnnotSubtype {
    typeUnknown,        //                 0
    typeText,           // Text            1
    typeLink,           // Link            2
    typeFreeText,       // FreeText        3
    typeLine,           // Line            4
    typeSquare,         // Square          5
    typeCircle,         // Circle          6
    typePolygon,        // Polygon         7
    typePolyLine,       // PolyLine        8
    typeHighlight,      // Highlight       9
    typeUnderline,      // Underline      10
    typeSquiggly,       // Squiggly       11
    typeStrikeOut,      // StrikeOut      12
    typeStamp,          // Stamp          13
    typeCaret,          // Caret          14
    typeInk,            // Ink            15
    typePopup,          // Popup          16
    typeFileAttachment, // FileAttachment 17
    typeSound,          // Sound          18
    typeMovie,          // Movie          19
    typeWidget,         // Widget         20
    typeScreen,         // Screen         21
    typePrinterMark,    // PrinterMark    22
    typeTrapNet,        // TrapNet        23
    typeWatermark,      // Watermark      24
633
634
    type3D,             // 3D             25
    typeRichMedia       // RichMedia      26
635
636
  };

637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
  /**
   * Describes the additional actions of a screen or widget annotation.
   */
  enum AdditionalActionsType {
    actionCursorEntering, ///< Performed when the cursor enters the annotation's active area
    actionCursorLeaving,  ///< Performed when the cursor exists the annotation's active area
    actionMousePressed,   ///< Performed when the mouse button is pressed inside the annotation's active area
    actionMouseReleased,  ///< Performed when the mouse button is released inside the annotation's active area
    actionFocusIn,        ///< Performed when the annotation receives the input focus
    actionFocusOut,       ///< Performed when the annotation loses the input focus
    actionPageOpening,    ///< Performed when the page containing the annotation is opened
    actionPageClosing,    ///< Performed when the page containing the annotation is closed
    actionPageVisible,    ///< Performed when the page containing the annotation becomes visible
    actionPageInvisible   ///< Performed when the page containing the annotation becomes invisible
  };

653
654
655
656
657
658
659
  enum FormAdditionalActionsType {
    actionFieldModified,   ///< Performed when the when the user modifies the field
    actionFormatField,     ///< Performed before the field is formatted to display its value
    actionValidateField,   ///< Performed when the field value changes
    actionCalculateField,  ///< Performed when the field needs to be recalculated
  };

660
  Annot(PDFDoc *docA, PDFRectangle *rectA);
661
662
  Annot(PDFDoc *docA, Object &&dictObject);
  Annot(PDFDoc *docA, Object &&dictObject, const Object *obj);
663
  bool isOk() { return ok; }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
664

665
666
667
  void incRefCnt();
  void decRefCnt();

668
  virtual void draw(Gfx *gfx, bool printing);
669
  // Get the resource dict of the appearance stream
Albert Astals Cid's avatar
Albert Astals Cid committed
670
  virtual Object getAppearanceResDict();
Kristian Høgsberg's avatar
Kristian Høgsberg committed
671

672
  bool match(Ref *refA)
673
674
    { return ref.num == refA->num && ref.gen == refA->gen; }

Inigo Martínez's avatar
Inigo Martínez committed
675
676
  double getXMin();
  double getYMin();
677
678
  double getXMax();
  double getYMax();
679

680
681
682
  void setRect(PDFRectangle *rect);
  void setRect(double x1, double y1, double x2, double y2);

683
  // Sets the annot contents to new_content
684
  // new_content should never be NULL
685
  virtual void setContents(GooString *new_content);
686
687
  void setName(GooString *new_name);
  void setModified(GooString *new_date);
Oliver Sander's avatar
Oliver Sander committed
688
  void setFlags(unsigned int new_flags);
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
689

690
691
  void setBorder(std::unique_ptr<AnnotBorder> &&new_border);
  void setColor(std::unique_ptr<AnnotColor> &&new_color);
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
692

Albert Astals Cid's avatar
Albert Astals Cid committed
693
  void setAppearanceState(const char *state);
694

695
  // getters
696
  PDFDoc *getDoc() const { return doc; }
697
  XRef *getXRef() const { return xref; }
698
  bool getHasRef() const { return hasRef; }
699
  Ref getRef() const { return ref; }
Inigo Martínez's avatar
Inigo Martínez committed
700
  AnnotSubtype getType() const { return type; }
701
  PDFRectangle *getRect() const { return rect.get(); }
702
  void getRect(double *x1, double *y1, double *x2, double *y2) const;
703
  const GooString *getContents() const { return contents.get(); }
704
  int getPageNum() const { return page; }
705
706
  const GooString *getName() const { return name.get(); }
  const GooString *getModified() const { return modified.get(); }
Oliver Sander's avatar
Oliver Sander committed
707
  unsigned int getFlags() const { return flags; }
708
709
710
711
  AnnotAppearance *getAppearStreams() const { return appearStreams.get(); }
  const GooString *getAppearState() const { return appearState.get(); }
  AnnotBorder *getBorder() const { return border.get(); }
  AnnotColor *getColor() const { return color.get(); }
Inigo Martínez's avatar
Inigo Martínez committed
712
  int getTreeKey() const { return treeKey; }
713

Hugo Mercier's avatar
Hugo Mercier committed
714
715
  int getId() { return ref.num; }

716
  // Check if point is inside the annot rectangle.
717
  bool inRect(double x, double y) const;
718

719
720
  static void layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont *font,
		  double *width, double widthLimit, int *charCount,
721
		  bool noReencode);
722

723
private:
Albert Astals Cid's avatar
Albert Astals Cid committed
724
  void readArrayNum(Object *pdfArray, int key, double *value);
725
  // write vStr[i:j[ in appearBuf
726

727
  void initialize (PDFDoc *docA, Dict *dict);
728
  void setPage (int new_page, bool updateP); // Called by Page::addAnnot and Annots ctor
729

Hugo Mercier's avatar
Hugo Mercier committed
730

Inigo Martínez's avatar
Inigo Martínez committed
731
protected:
732
  virtual ~Annot();
733
  virtual void removeReferencedObjects(); // Called by Page::removeAnnot
734
735
  Object createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Dict *resDict);
  Object createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Object &&resDictObject); // overload to support incRef/decRef
Albert Astals Cid's avatar
Albert Astals Cid committed
736
737
  Dict *createResourcesDict(const char *formName, Object &&formStream, const char *stateName,
			   double opacity, const char *blendMode);
738
  bool isVisible(bool printing);
739
  int getRotation() const;
740

741
742
  // Updates the field key of the annotation dictionary
  // and sets M to the current time
Albert Astals Cid's avatar
Albert Astals Cid committed
743
  void update(const char *key, Object &&value);
744

745
746
747
  // Delete appearance streams and reset appearance state
  void invalidateAppearance();

748
  Object annotObj;
749

750
  std::atomic_int refCnt;
751
  
Inigo Martínez's avatar
Inigo Martínez committed
752
  // required data
753
754
  AnnotSubtype type;                                // Annotation type
  std::unique_ptr<PDFRectangle> rect;               // Rect
Inigo Martínez's avatar
Inigo Martínez committed
755
756

  // optional data
757
758
759
760
  std::unique_ptr<GooString> contents;              // Contents
  std::unique_ptr<GooString> name;                  // NM
  std::unique_ptr<GooString> modified;              // M
  int       page;                                   // P
Oliver Sander's avatar
Oliver Sander committed
761
  unsigned int flags;                                      // F (must be a 32 bit unsigned int)
762
763
764
765
766
767
768
  std::unique_ptr<AnnotAppearance> appearStreams;   // AP
  Object appearance;                                // a reference to the Form XObject stream
                                                    //   for the normal appearance
  std::unique_ptr<AnnotAppearanceBBox> appearBBox;  // BBox of generated appearance
  std::unique_ptr<GooString> appearState;           // AS
  int treeKey;                                      // Struct Parent;
  Object oc;                                        // OC
Inigo Martínez's avatar
Inigo Martínez committed
769

770
  PDFDoc *doc;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
771
  XRef *xref;			// the xref table for this PDF file
772
  Ref ref;                      // object ref identifying this annotation
773
774
  std::unique_ptr<AnnotBorder> border;              // Border, BS
  std::unique_ptr<AnnotColor> color;                // C
775
  bool ok;
Inigo Martínez's avatar
Inigo Martínez committed
776

777
  bool hasRef;
778
  mutable std::recursive_mutex mutex;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
779
780
};

Inigo Martínez's avatar
Inigo Martínez committed
781
782
783
784
785
786
//------------------------------------------------------------------------
// AnnotPopup
//------------------------------------------------------------------------

class AnnotPopup: public Annot {
public:
787
  AnnotPopup(PDFDoc *docA, PDFRectangle *rect);
788
  AnnotPopup(PDFDoc *docA, Object &&dictObject, const Object *obj);
789
  ~AnnotPopup();
Inigo Martínez's avatar
Inigo Martínez committed
790

791
  Object *getParentNF() { return &parent; }
792
  void setParent(Annot *parentA);
793
794
  bool getOpen() const { return open; }
  void setOpen(bool openA);
Inigo Martínez's avatar
Inigo Martínez committed
795
796

protected:
797
  void initialize(PDFDoc *docA, Dict *dict);
Inigo Martínez's avatar
Inigo Martínez committed
798

799
  Object parent; // Parent
800
  bool open;   // Open
Inigo Martínez's avatar
Inigo Martínez committed
801
802
};

Inigo Martínez's avatar
Inigo Martínez committed
803
804
805
806
//------------------------------------------------------------------------
// AnnotMarkup
//------------------------------------------------------------------------

807
class AnnotMarkup: public Annot {
Inigo Martínez's avatar
Inigo Martínez committed
808
809
810
811
812
813
public:
  enum  AnnotMarkupReplyType {
    replyTypeR,     // R
    replyTypeGroup  // Group
  };

814
  AnnotMarkup(PDFDoc *docA, PDFRectangle *rect);
815
  AnnotMarkup(PDFDoc *docA, Object &&dictObject, const Object *obj);
816
  ~AnnotMarkup();
Inigo Martínez's avatar
Inigo Martínez committed
817
818

  // getters
819
820
  const GooString *getLabel() const { return label.get(); }
  AnnotPopup *getPopup() const { return popup.get(); }
Inigo Martínez's avatar
Inigo Martínez committed
821
  double getOpacity() const { return opacity; }
Inigo Martínez's avatar
Inigo Martínez committed
822
  // getRC
823
  const GooString *getDate() const { return date.get(); }
824
  int getInReplyToID() const { return inReplyTo.num; }
825
  const GooString *getSubject() const { return subject.get(); }
Inigo Martínez's avatar
Inigo Martínez committed
826
827
  AnnotMarkupReplyType getReplyTo() const { return replyTo; }
  AnnotExternalDataType getExData() const { return exData; }
Inigo Martínez's avatar
Inigo Martínez committed
828

829
  // The annotation takes the ownership of new_popup
830
  void setPopup(std::unique_ptr<AnnotPopup> &&new_popup);
831
  void setLabel(GooString *new_label);
832
  void setOpacity(double opacityA);
833
  void setDate(GooString *new_date);
834

Inigo Martínez's avatar
Inigo Martínez committed
835
protected:
Albert Astals Cid's avatar
Albert Astals Cid committed
836
  void removeReferencedObjects() override;
837

Yuri Chornoivan's avatar
Yuri Chornoivan committed
838
  std::unique_ptr<GooString> label;   // T            (Default author)
839
840
  std::unique_ptr<AnnotPopup> popup;  // Popup
  double opacity;                     // CA           (Default 1.0)
Inigo Martínez's avatar
Inigo Martínez committed
841
  // RC
842
843
844
845
  std::unique_ptr<GooString> date;    // CreationDate
  Ref inReplyTo;                      // IRT
  std::unique_ptr<GooString> subject; // Subj
  AnnotMarkupReplyType replyTo;       // RT           (Default R)
Yuri Chornoivan's avatar
Yuri Chornoivan committed
846
  // this object is overridden by the custom intent fields defined in some
Inigo Martínez's avatar
Inigo Martínez committed
847
  // annotation types.
848
849
  //GooString *intent;                // IT
  AnnotExternalDataType exData;       // ExData
Inigo Martínez's avatar
Inigo Martínez committed
850
851

private:
852
  void initialize(PDFDoc *docA, Dict *dict);
Inigo Martínez's avatar
Inigo Martínez committed
853
854
};

Inigo Martínez's avatar
Inigo Martínez committed
855
856
857
858
//------------------------------------------------------------------------
// AnnotText
//------------------------------------------------------------------------

859
class AnnotText: public AnnotMarkup {
Inigo Martínez's avatar
Inigo Martínez committed
860
861
862
863
864
865
866
867
868
869
870
871
872
873
public:
  enum AnnotTextState {
    stateUnknown,
    // Marked state model
    stateMarked,    // Marked
    stateUnmarked,  // Unmarked
    // Review state model
    stateAccepted,  // Accepted
    stateRejected,  // Rejected
    stateCancelled, // Cancelled
    stateCompleted, // Completed
    stateNone       // None
  };

874
  AnnotText(PDFDoc *docA, PDFRectangle *rect);
875
  AnnotText(PDFDoc *docA, Object &&dictObject, const Object *obj);
876
  ~AnnotText();
Inigo Martínez's avatar
Inigo Martínez committed
877

878
  void draw(Gfx *gfx, bool printing) override;
879

Inigo Martínez's avatar
Inigo Martínez committed
880
  // getters
881
  bool getOpen() const { return open; }
882
  const GooString *getIcon() const { return icon.get(); }
Inigo Martínez's avatar
Inigo Martínez committed
883
  AnnotTextState getState() const { return state; }
Inigo Martínez's avatar
Inigo Martínez committed
884

885
  void setOpen(bool openA);
886
887
  void setIcon(GooString *new_icon);

Inigo Martínez's avatar
Inigo Martínez committed
888
889
private:

890
  void initialize(PDFDoc *docA, Dict *dict);
Inigo Martínez's avatar
Inigo Martínez committed
891

892
  bool open;                       // Open       (Default false)
893
  std::unique_ptr<GooString> icon;  // Name       (Default Note)
Inigo Martínez's avatar
Inigo Martínez committed
894
895
896
897
898
  AnnotTextState state;             // State      (Default Umarked if
                                    //             StateModel Marked
                                    //             None if StareModel Review)
};

Hugo Mercier's avatar
Hugo Mercier committed
899
900
901
902
903
904
905
906
//------------------------------------------------------------------------
// AnnotMovie
//------------------------------------------------------------------------



class AnnotMovie: public Annot {
 public:
907
  AnnotMovie(PDFDoc *docA, PDFRectangle *rect, Movie *movieA);
908
  AnnotMovie(PDFDoc *docA, Object &&dictObject, const Object *obj);
909
  ~AnnotMovie();
Hugo Mercier's avatar
Hugo Mercier committed
910

911
  void draw(Gfx *gfx, bool printing) override;
912

913
914
  const GooString* getTitle() const { return title.get(); }
  Movie* getMovie() { return movie.get(); }
Hugo Mercier's avatar
Hugo Mercier committed
915
916

 private:
917
  void initialize(PDFDoc *docA, Dict *dict);
Hugo Mercier's avatar
Hugo Mercier committed
918

919
920
  std::unique_ptr<GooString> title; // T
  std::unique_ptr<Movie> movie;     // Movie + A
Hugo Mercier's avatar
Hugo Mercier committed
921
922
923
924
925
926
927
928
929
930
};


//------------------------------------------------------------------------
// AnnotScreen
//------------------------------------------------------------------------

class AnnotScreen: public Annot {
 public:

931
  AnnotScreen(PDFDoc *docA, PDFRectangle *rect);
932
  AnnotScreen(PDFDoc *docA, Object &&dictObject, const Object *obj);
933
  ~AnnotScreen();
Hugo Mercier's avatar
Hugo Mercier committed
934

935
  const GooString* getTitle() const { return title.get(); }
Hugo Mercier's avatar
Hugo Mercier committed
936

937
  AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); }
Oliver Sander's avatar
Oliver Sander committed
938
  LinkAction *getAction() { return action.get(); } // The caller should not delete the result
939
  LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result
Hugo Mercier's avatar
Hugo Mercier committed
940
941

 private:
942
  void initialize(PDFDoc *docA, Dict *dict);
Hugo Mercier's avatar
Hugo Mercier committed
943
944


945
  std::unique_ptr<GooString> title;                      // T
Hugo Mercier's avatar
Hugo Mercier committed
946

947
  std::unique_ptr<AnnotAppearanceCharacs> appearCharacs; // MK
Hugo Mercier's avatar
Hugo Mercier committed
948

949
950
  std::unique_ptr<LinkAction> action;                    // A
  Object additionalActions;                              // AA
Hugo Mercier's avatar
Hugo Mercier committed
951
952
};

953
954
955
956
957
958
959
//------------------------------------------------------------------------
// AnnotLink
//------------------------------------------------------------------------

class AnnotLink: public Annot {
public:

Inigo Martínez's avatar
Inigo Martínez committed
960
961
962
963
964
965
966
  enum AnnotLinkEffect {
    effectNone,     // N
    effectInvert,   // I
    effectOutline,  // O
    effectPush      // P
  };

967
  AnnotLink(PDFDoc *docA, PDFRectangle *rect);
968
  AnnotLink(PDFDoc *docA, Object &&dictObject, const Object *obj);
969
  ~AnnotLink();
Inigo Martínez's avatar
Inigo Martínez committed
970

971
  void draw(Gfx *gfx, bool printing) override;
972

Inigo Martínez's avatar
Inigo Martínez committed
973
  // getters
974
  LinkAction *getAction() const { return action.get(); }
Inigo Martínez's avatar
Inigo Martínez committed
975
  AnnotLinkEffect getLinkEffect() const { return linkEffect; }
976
  AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals.get(); }
Inigo Martínez's avatar
Inigo Martínez committed
977
978
979

protected:

980
  void initialize(PDFDoc *docA, Dict *dict);
Inigo Martínez's avatar
Inigo Martínez committed
981

982
983
984
  std::unique_ptr<LinkAction> action;                  // A, Dest
  AnnotLinkEffect linkEffect;                          // H          (Default I)
  //Dict *uriAction;                                   // PA
Inigo Martínez's avatar
Inigo Martínez committed
985

986
  std::unique_ptr<AnnotQuadrilaterals> quadrilaterals; // QuadPoints
987
988
};

Inigo Martínez's avatar
Inigo Martínez committed
989
990
991
992
//------------------------------------------------------------------------
// AnnotFreeText
//------------------------------------------------------------------------

993
class AnnotFreeText: public AnnotMarkup {
Inigo Martínez's avatar
Inigo Martínez committed
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
public:

  enum AnnotFreeTextQuadding {
    quaddingLeftJustified,  // 0
    quaddingCentered,       // 1
    quaddingRightJustified  // 2
  };

  enum AnnotFreeTextIntent {
    intentFreeText,           // FreeText
    intentFreeTextCallout,    // FreeTextCallout
    intentFreeTextTypeWriter  // FreeTextTypeWriter
  };

1008
1009
  static const double undefinedFontPtSize;

Dileep Sankhla's avatar
Dileep Sankhla committed
1010
  AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, const DefaultAppearance &da);
1011
  AnnotFreeText(PDFDoc *docA, Object &&dictObject, const Object *obj);
1012
  ~AnnotFreeText();