github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/model/annotations.go (about)

     1  /*
     2   * This file is subject to the terms and conditions defined in
     3   * file 'LICENSE.md', which is part of this source code package.
     4   */
     5  
     6  package model
     7  
     8  import (
     9  	"errors"
    10  	"fmt"
    11  
    12  	"github.com/unidoc/unidoc/common"
    13  	. "github.com/unidoc/unidoc/pdf/core"
    14  )
    15  
    16  // PDFAnnotation contains common attributes of an annotation.  The context object contains the subannotation,
    17  // which can be a markup annotation or other types.
    18  type PdfAnnotation struct {
    19  	context      PdfModel // Sub-annotation.
    20  	Rect         PdfObject
    21  	Contents     PdfObject
    22  	P            PdfObject // Reference to page object.
    23  	NM           PdfObject
    24  	M            PdfObject
    25  	F            PdfObject
    26  	AP           PdfObject
    27  	AS           PdfObject
    28  	Border       PdfObject
    29  	C            PdfObject
    30  	StructParent PdfObject
    31  	OC           PdfObject
    32  
    33  	primitive *PdfIndirectObject
    34  }
    35  
    36  // Context in this case is a reference to the subannotation.
    37  func (this *PdfAnnotation) GetContext() PdfModel {
    38  	return this.context
    39  }
    40  
    41  // Set the sub annotation (context).
    42  func (this *PdfAnnotation) SetContext(ctx PdfModel) {
    43  	this.context = ctx
    44  }
    45  
    46  func (this *PdfAnnotation) String() string {
    47  	s := ""
    48  
    49  	obj, ok := this.ToPdfObject().(*PdfIndirectObject)
    50  	if ok {
    51  		s = fmt.Sprintf("%T: %s", this.context, obj.PdfObject.String())
    52  	}
    53  
    54  	return s
    55  }
    56  
    57  // Additional elements for mark-up annotations.
    58  type PdfAnnotationMarkup struct {
    59  	T            PdfObject
    60  	Popup        *PdfAnnotationPopup
    61  	CA           PdfObject
    62  	RC           PdfObject
    63  	CreationDate PdfObject
    64  	IRT          PdfObject
    65  	Subj         PdfObject
    66  	RT           PdfObject
    67  	IT           PdfObject
    68  	ExData       PdfObject
    69  }
    70  
    71  // Subtype: Text
    72  type PdfAnnotationText struct {
    73  	*PdfAnnotation
    74  	*PdfAnnotationMarkup
    75  	Open       PdfObject
    76  	Name       PdfObject
    77  	State      PdfObject
    78  	StateModel PdfObject
    79  }
    80  
    81  // Subtype: Link
    82  type PdfAnnotationLink struct {
    83  	*PdfAnnotation
    84  	A          PdfObject
    85  	Dest       PdfObject
    86  	H          PdfObject
    87  	PA         PdfObject
    88  	QuadPoints PdfObject
    89  	BS         PdfObject
    90  }
    91  
    92  // Subtype: FreeText
    93  type PdfAnnotationFreeText struct {
    94  	*PdfAnnotation
    95  	*PdfAnnotationMarkup
    96  	DA PdfObject
    97  	Q  PdfObject
    98  	RC PdfObject
    99  	DS PdfObject
   100  	CL PdfObject
   101  	IT PdfObject
   102  	BE PdfObject
   103  	RD PdfObject
   104  	BS PdfObject
   105  	LE PdfObject
   106  }
   107  
   108  // Subtype: Line
   109  type PdfAnnotationLine struct {
   110  	*PdfAnnotation
   111  	*PdfAnnotationMarkup
   112  	L       PdfObject
   113  	BS      PdfObject
   114  	LE      PdfObject
   115  	IC      PdfObject
   116  	LL      PdfObject
   117  	LLE     PdfObject
   118  	Cap     PdfObject
   119  	IT      PdfObject
   120  	LLO     PdfObject
   121  	CP      PdfObject
   122  	Measure PdfObject
   123  	CO      PdfObject
   124  }
   125  
   126  // Subtype: Square
   127  type PdfAnnotationSquare struct {
   128  	*PdfAnnotation
   129  	*PdfAnnotationMarkup
   130  	BS PdfObject
   131  	IC PdfObject
   132  	BE PdfObject
   133  	RD PdfObject
   134  }
   135  
   136  // Subtype: Circle
   137  type PdfAnnotationCircle struct {
   138  	*PdfAnnotation
   139  	*PdfAnnotationMarkup
   140  	BS PdfObject
   141  	IC PdfObject
   142  	BE PdfObject
   143  	RD PdfObject
   144  }
   145  
   146  // Subtype: Polygon
   147  type PdfAnnotationPolygon struct {
   148  	*PdfAnnotation
   149  	*PdfAnnotationMarkup
   150  	Vertices PdfObject
   151  	LE       PdfObject
   152  	BS       PdfObject
   153  	IC       PdfObject
   154  	BE       PdfObject
   155  	IT       PdfObject
   156  	Measure  PdfObject
   157  }
   158  
   159  // Subtype: PolyLine
   160  type PdfAnnotationPolyLine struct {
   161  	*PdfAnnotation
   162  	*PdfAnnotationMarkup
   163  	Vertices PdfObject
   164  	LE       PdfObject
   165  	BS       PdfObject
   166  	IC       PdfObject
   167  	BE       PdfObject
   168  	IT       PdfObject
   169  	Measure  PdfObject
   170  }
   171  
   172  // Subtype: Highlight
   173  type PdfAnnotationHighlight struct {
   174  	*PdfAnnotation
   175  	*PdfAnnotationMarkup
   176  	QuadPoints PdfObject
   177  }
   178  
   179  // Subtype: Underline
   180  type PdfAnnotationUnderline struct {
   181  	*PdfAnnotation
   182  	*PdfAnnotationMarkup
   183  	QuadPoints PdfObject
   184  }
   185  
   186  // Subtype: Squiggly
   187  type PdfAnnotationSquiggly struct {
   188  	*PdfAnnotation
   189  	*PdfAnnotationMarkup
   190  	QuadPoints PdfObject
   191  }
   192  
   193  // Subtype: StrikeOut
   194  type PdfAnnotationStrikeOut struct {
   195  	*PdfAnnotation
   196  	*PdfAnnotationMarkup
   197  	QuadPoints PdfObject
   198  }
   199  
   200  // Subtype: Caret
   201  type PdfAnnotationCaret struct {
   202  	*PdfAnnotation
   203  	*PdfAnnotationMarkup
   204  	RD PdfObject
   205  	Sy PdfObject
   206  }
   207  
   208  // Subtype: Stamp
   209  type PdfAnnotationStamp struct {
   210  	*PdfAnnotation
   211  	*PdfAnnotationMarkup
   212  	Name PdfObject
   213  }
   214  
   215  // Subtype: Ink
   216  type PdfAnnotationInk struct {
   217  	*PdfAnnotation
   218  	*PdfAnnotationMarkup
   219  	InkList PdfObject
   220  	BS      PdfObject
   221  }
   222  
   223  // Subtype: Popup
   224  type PdfAnnotationPopup struct {
   225  	*PdfAnnotation
   226  	Parent PdfObject
   227  	Open   PdfObject
   228  }
   229  
   230  // Subtype: FileAttachment
   231  type PdfAnnotationFileAttachment struct {
   232  	*PdfAnnotation
   233  	*PdfAnnotationMarkup
   234  	FS   PdfObject
   235  	Name PdfObject
   236  }
   237  
   238  // Subtype: Sound
   239  type PdfAnnotationSound struct {
   240  	*PdfAnnotation
   241  	*PdfAnnotationMarkup
   242  	Sound PdfObject
   243  	Name  PdfObject
   244  }
   245  
   246  // Subtype: Rich Media
   247  type PdfAnnotationRichMedia struct {
   248  	*PdfAnnotation
   249  	RichMediaSettings PdfObject
   250  	RichMediaContent  PdfObject
   251  }
   252  
   253  // Subtype: Movie
   254  type PdfAnnotationMovie struct {
   255  	*PdfAnnotation
   256  	T     PdfObject
   257  	Movie PdfObject
   258  	A     PdfObject
   259  }
   260  
   261  // Subtype: Screen
   262  type PdfAnnotationScreen struct {
   263  	*PdfAnnotation
   264  	T  PdfObject
   265  	MK PdfObject
   266  	A  PdfObject
   267  	AA PdfObject
   268  }
   269  
   270  // Subtype: Widget
   271  type PdfAnnotationWidget struct {
   272  	*PdfAnnotation
   273  	H      PdfObject
   274  	MK     PdfObject
   275  	A      PdfObject
   276  	AA     PdfObject
   277  	BS     PdfObject
   278  	Parent PdfObject
   279  }
   280  
   281  // Subtype: Watermark
   282  type PdfAnnotationWatermark struct {
   283  	*PdfAnnotation
   284  	FixedPrint PdfObject
   285  }
   286  
   287  // Subtype: PrinterMark
   288  type PdfAnnotationPrinterMark struct {
   289  	*PdfAnnotation
   290  	MN PdfObject
   291  }
   292  
   293  // Subtype: TrapNet
   294  type PdfAnnotationTrapNet struct {
   295  	*PdfAnnotation
   296  }
   297  
   298  // Subtype: 3D
   299  type PdfAnnotation3D struct {
   300  	*PdfAnnotation
   301  	T3DD PdfObject
   302  	T3DV PdfObject
   303  	T3DA PdfObject
   304  	T3DI PdfObject
   305  	T3DB PdfObject
   306  }
   307  
   308  // Subtype: Projection
   309  type PdfAnnotationProjection struct {
   310  	*PdfAnnotation
   311  	*PdfAnnotationMarkup
   312  }
   313  
   314  // Subtype: Redact
   315  type PdfAnnotationRedact struct {
   316  	*PdfAnnotation
   317  	*PdfAnnotationMarkup
   318  	QuadPoints  PdfObject
   319  	IC          PdfObject
   320  	RO          PdfObject
   321  	OverlayText PdfObject
   322  	Repeat      PdfObject
   323  	DA          PdfObject
   324  	Q           PdfObject
   325  }
   326  
   327  // Construct a new PDF annotation model and initializes the underlying PDF primitive.
   328  func NewPdfAnnotation() *PdfAnnotation {
   329  	annot := &PdfAnnotation{}
   330  
   331  	container := &PdfIndirectObject{}
   332  	container.PdfObject = MakeDict()
   333  
   334  	annot.primitive = container
   335  	return annot
   336  }
   337  
   338  // Create a new text annotation.
   339  func NewPdfAnnotationText() *PdfAnnotationText {
   340  	annotation := NewPdfAnnotation()
   341  	textAnnotation := &PdfAnnotationText{}
   342  	textAnnotation.PdfAnnotation = annotation
   343  	textAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   344  	annotation.SetContext(textAnnotation)
   345  	return textAnnotation
   346  }
   347  
   348  // Create a new link annotation.
   349  func NewPdfAnnotationLink() *PdfAnnotationLink {
   350  	annotation := NewPdfAnnotation()
   351  	linkAnnotation := &PdfAnnotationLink{}
   352  	linkAnnotation.PdfAnnotation = annotation
   353  	annotation.SetContext(linkAnnotation)
   354  	return linkAnnotation
   355  }
   356  
   357  // Create a new free text annotation.
   358  func NewPdfAnnotationFreeText() *PdfAnnotationFreeText {
   359  	annotation := NewPdfAnnotation()
   360  	freetextAnnotation := &PdfAnnotationFreeText{}
   361  	freetextAnnotation.PdfAnnotation = annotation
   362  	freetextAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   363  	annotation.SetContext(freetextAnnotation)
   364  	return freetextAnnotation
   365  }
   366  
   367  // Create a new line annotation.
   368  func NewPdfAnnotationLine() *PdfAnnotationLine {
   369  	annotation := NewPdfAnnotation()
   370  	lineAnnotation := &PdfAnnotationLine{}
   371  	lineAnnotation.PdfAnnotation = annotation
   372  	lineAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   373  	annotation.SetContext(lineAnnotation)
   374  	return lineAnnotation
   375  }
   376  
   377  // Create a new square annotation.
   378  func NewPdfAnnotationSquare() *PdfAnnotationSquare {
   379  	annotation := NewPdfAnnotation()
   380  	rectAnnotation := &PdfAnnotationSquare{}
   381  	rectAnnotation.PdfAnnotation = annotation
   382  	rectAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   383  	annotation.SetContext(rectAnnotation)
   384  	return rectAnnotation
   385  }
   386  
   387  // Create a new circle annotation.
   388  func NewPdfAnnotationCircle() *PdfAnnotationCircle {
   389  	annotation := NewPdfAnnotation()
   390  	circAnnotation := &PdfAnnotationCircle{}
   391  	circAnnotation.PdfAnnotation = annotation
   392  	circAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   393  	annotation.SetContext(circAnnotation)
   394  	return circAnnotation
   395  }
   396  
   397  // Create a new polygon annotation.
   398  func NewPdfAnnotationPolygon() *PdfAnnotationPolygon {
   399  	annotation := NewPdfAnnotation()
   400  	polygonAnnotation := &PdfAnnotationPolygon{}
   401  	polygonAnnotation.PdfAnnotation = annotation
   402  	polygonAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   403  	annotation.SetContext(polygonAnnotation)
   404  	return polygonAnnotation
   405  }
   406  
   407  // Create a new polyline annotation.
   408  func NewPdfAnnotationPolyLine() *PdfAnnotationPolyLine {
   409  	annotation := NewPdfAnnotation()
   410  	polylineAnnotation := &PdfAnnotationPolyLine{}
   411  	polylineAnnotation.PdfAnnotation = annotation
   412  	polylineAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   413  	annotation.SetContext(polylineAnnotation)
   414  	return polylineAnnotation
   415  }
   416  
   417  // Create a new text highlight annotation.
   418  func NewPdfAnnotationHighlight() *PdfAnnotationHighlight {
   419  	annotation := NewPdfAnnotation()
   420  	highlightAnnotation := &PdfAnnotationHighlight{}
   421  	highlightAnnotation.PdfAnnotation = annotation
   422  	highlightAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   423  	annotation.SetContext(highlightAnnotation)
   424  	return highlightAnnotation
   425  }
   426  
   427  // Create a new text underline annotation.
   428  func NewPdfAnnotationUnderline() *PdfAnnotationUnderline {
   429  	annotation := NewPdfAnnotation()
   430  	underlineAnnotation := &PdfAnnotationUnderline{}
   431  	underlineAnnotation.PdfAnnotation = annotation
   432  	underlineAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   433  	annotation.SetContext(underlineAnnotation)
   434  	return underlineAnnotation
   435  }
   436  
   437  // Create a new text squiggly annotation.
   438  func NewPdfAnnotationSquiggly() *PdfAnnotationSquiggly {
   439  	annotation := NewPdfAnnotation()
   440  	squigglyAnnotation := &PdfAnnotationSquiggly{}
   441  	squigglyAnnotation.PdfAnnotation = annotation
   442  	squigglyAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   443  	annotation.SetContext(squigglyAnnotation)
   444  	return squigglyAnnotation
   445  }
   446  
   447  // Create a new text strikeout annotation.
   448  func NewPdfAnnotationStrikeOut() *PdfAnnotationStrikeOut {
   449  	annotation := NewPdfAnnotation()
   450  	strikeoutAnnotation := &PdfAnnotationStrikeOut{}
   451  	strikeoutAnnotation.PdfAnnotation = annotation
   452  	strikeoutAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   453  	annotation.SetContext(strikeoutAnnotation)
   454  	return strikeoutAnnotation
   455  }
   456  
   457  // Create a new caret annotation.
   458  func NewPdfAnnotationCaret() *PdfAnnotationCaret {
   459  	annotation := NewPdfAnnotation()
   460  	caretAnnotation := &PdfAnnotationCaret{}
   461  	caretAnnotation.PdfAnnotation = annotation
   462  	caretAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   463  	annotation.SetContext(caretAnnotation)
   464  	return caretAnnotation
   465  }
   466  
   467  // Create a new stamp annotation.
   468  func NewPdfAnnotationStamp() *PdfAnnotationStamp {
   469  	annotation := NewPdfAnnotation()
   470  	stampAnnotation := &PdfAnnotationStamp{}
   471  	stampAnnotation.PdfAnnotation = annotation
   472  	stampAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   473  	annotation.SetContext(stampAnnotation)
   474  	return stampAnnotation
   475  }
   476  
   477  // Create a new ink annotation.
   478  func NewPdfAnnotationInk() *PdfAnnotationInk {
   479  	annotation := NewPdfAnnotation()
   480  	inkAnnotation := &PdfAnnotationInk{}
   481  	inkAnnotation.PdfAnnotation = annotation
   482  	inkAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   483  	annotation.SetContext(inkAnnotation)
   484  	return inkAnnotation
   485  }
   486  
   487  // Create a new popup annotation.
   488  func NewPdfAnnotationPopup() *PdfAnnotationPopup {
   489  	annotation := NewPdfAnnotation()
   490  	popupAnnotation := &PdfAnnotationPopup{}
   491  	popupAnnotation.PdfAnnotation = annotation
   492  	annotation.SetContext(popupAnnotation)
   493  	return popupAnnotation
   494  }
   495  
   496  // Create a new file attachment annotation.
   497  func NewPdfAnnotationFileAttachment() *PdfAnnotationFileAttachment {
   498  	annotation := NewPdfAnnotation()
   499  	fileAnnotation := &PdfAnnotationFileAttachment{}
   500  	fileAnnotation.PdfAnnotation = annotation
   501  	fileAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   502  	annotation.SetContext(fileAnnotation)
   503  	return fileAnnotation
   504  }
   505  
   506  // Create a new sound annotation.
   507  func NewPdfAnnotationSound() *PdfAnnotationSound {
   508  	annotation := NewPdfAnnotation()
   509  	soundAnnotation := &PdfAnnotationSound{}
   510  	soundAnnotation.PdfAnnotation = annotation
   511  	soundAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   512  	annotation.SetContext(soundAnnotation)
   513  	return soundAnnotation
   514  }
   515  
   516  // Create a new rich media annotation.
   517  func NewPdfAnnotationRichMedia() *PdfAnnotationRichMedia {
   518  	annotation := NewPdfAnnotation()
   519  	richmediaAnnotation := &PdfAnnotationRichMedia{}
   520  	richmediaAnnotation.PdfAnnotation = annotation
   521  	annotation.SetContext(richmediaAnnotation)
   522  	return richmediaAnnotation
   523  }
   524  
   525  // Create a new movie annotation.
   526  func NewPdfAnnotationMovie() *PdfAnnotationMovie {
   527  	annotation := NewPdfAnnotation()
   528  	movieAnnotation := &PdfAnnotationMovie{}
   529  	movieAnnotation.PdfAnnotation = annotation
   530  	annotation.SetContext(movieAnnotation)
   531  	return movieAnnotation
   532  }
   533  
   534  // Create a new screen annotation.
   535  func NewPdfAnnotationScreen() *PdfAnnotationScreen {
   536  	annotation := NewPdfAnnotation()
   537  	screenAnnotation := &PdfAnnotationScreen{}
   538  	screenAnnotation.PdfAnnotation = annotation
   539  	annotation.SetContext(screenAnnotation)
   540  	return screenAnnotation
   541  }
   542  
   543  // Create a new watermark annotation.
   544  func NewPdfAnnotationWatermark() *PdfAnnotationWatermark {
   545  	annotation := NewPdfAnnotation()
   546  	watermarkAnnotation := &PdfAnnotationWatermark{}
   547  	watermarkAnnotation.PdfAnnotation = annotation
   548  	annotation.SetContext(watermarkAnnotation)
   549  	return watermarkAnnotation
   550  }
   551  
   552  // Create a new printermark annotation.
   553  func NewPdfAnnotationPrinterMark() *PdfAnnotationPrinterMark {
   554  	annotation := NewPdfAnnotation()
   555  	printermarkAnnotation := &PdfAnnotationPrinterMark{}
   556  	printermarkAnnotation.PdfAnnotation = annotation
   557  	annotation.SetContext(printermarkAnnotation)
   558  	return printermarkAnnotation
   559  }
   560  
   561  // Create a new trapnet annotation.
   562  func NewPdfAnnotationTrapNet() *PdfAnnotationTrapNet {
   563  	annotation := NewPdfAnnotation()
   564  	trapnetAnnotation := &PdfAnnotationTrapNet{}
   565  	trapnetAnnotation.PdfAnnotation = annotation
   566  	annotation.SetContext(trapnetAnnotation)
   567  	return trapnetAnnotation
   568  }
   569  
   570  // Create a new 3d annotation.
   571  func NewPdfAnnotation3D() *PdfAnnotation3D {
   572  	annotation := NewPdfAnnotation()
   573  	x3dAnnotation := &PdfAnnotation3D{}
   574  	x3dAnnotation.PdfAnnotation = annotation
   575  	annotation.SetContext(x3dAnnotation)
   576  	return x3dAnnotation
   577  }
   578  
   579  // Create a new projection annotation.
   580  func NewPdfAnnotationProjection() *PdfAnnotationProjection {
   581  	annotation := NewPdfAnnotation()
   582  	projectionAnnotation := &PdfAnnotationProjection{}
   583  	projectionAnnotation.PdfAnnotation = annotation
   584  	projectionAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   585  	annotation.SetContext(projectionAnnotation)
   586  	return projectionAnnotation
   587  }
   588  
   589  // Create a new redact annotation.
   590  func NewPdfAnnotationRedact() *PdfAnnotationRedact {
   591  	annotation := NewPdfAnnotation()
   592  	redactAnnotation := &PdfAnnotationRedact{}
   593  	redactAnnotation.PdfAnnotation = annotation
   594  	redactAnnotation.PdfAnnotationMarkup = &PdfAnnotationMarkup{}
   595  	annotation.SetContext(redactAnnotation)
   596  	return redactAnnotation
   597  }
   598  
   599  // Create a new annotation widget and initializes the underlying primitive.
   600  func NewPdfAnnotationWidget() *PdfAnnotationWidget {
   601  	annotation := NewPdfAnnotation()
   602  	annotationWidget := &PdfAnnotationWidget{}
   603  	annotationWidget.PdfAnnotation = annotation
   604  	annotation.SetContext(annotationWidget)
   605  	return annotationWidget
   606  }
   607  
   608  // Used for PDF parsing.  Loads a PDF annotation model from a PDF primitive dictionary object.
   609  // Loads the common PDF annotation dictionary, and anything needed for the annotation subtype.
   610  func (r *PdfReader) newPdfAnnotationFromIndirectObject(container *PdfIndirectObject) (*PdfAnnotation, error) {
   611  	d, isDict := container.PdfObject.(*PdfObjectDictionary)
   612  	if !isDict {
   613  		return nil, fmt.Errorf("Annotation indirect object not containing a dictionary")
   614  	}
   615  
   616  	// Check if cached, return cached model if exists.
   617  	if model := r.modelManager.GetModelFromPrimitive(d); model != nil {
   618  		annot, ok := model.(*PdfAnnotation)
   619  		if !ok {
   620  			return nil, fmt.Errorf("Cached model not a PDF annotation")
   621  		}
   622  		return annot, nil
   623  	}
   624  
   625  	annot := &PdfAnnotation{}
   626  	annot.primitive = container
   627  	r.modelManager.Register(d, annot)
   628  
   629  	if obj := d.Get("Type"); obj != nil {
   630  		str, ok := obj.(*PdfObjectName)
   631  		if !ok {
   632  			common.Log.Trace("Incompatibility! Invalid type of Type (%T) - should be Name", obj)
   633  		} else {
   634  			if *str != "Annot" {
   635  				// Log a debug message.
   636  				// Not returning an error on this.
   637  				common.Log.Trace("Unsuspected Type != Annot (%s)", *str)
   638  			}
   639  		}
   640  	}
   641  
   642  	if obj := d.Get("Rect"); obj != nil {
   643  		annot.Rect = obj
   644  	}
   645  
   646  	if obj := d.Get("Contents"); obj != nil {
   647  		annot.Contents = obj
   648  	}
   649  
   650  	if obj := d.Get("P"); obj != nil {
   651  		annot.P = obj
   652  	}
   653  
   654  	if obj := d.Get("NM"); obj != nil {
   655  		annot.NM = obj
   656  	}
   657  
   658  	if obj := d.Get("M"); obj != nil {
   659  		annot.M = obj
   660  	}
   661  
   662  	if obj := d.Get("F"); obj != nil {
   663  		annot.F = obj
   664  	}
   665  
   666  	if obj := d.Get("AP"); obj != nil {
   667  		annot.AP = obj
   668  	}
   669  
   670  	if obj := d.Get("AS"); obj != nil {
   671  		annot.AS = obj
   672  	}
   673  
   674  	if obj := d.Get("Border"); obj != nil {
   675  		annot.Border = obj
   676  	}
   677  
   678  	if obj := d.Get("C"); obj != nil {
   679  		annot.C = obj
   680  	}
   681  
   682  	if obj := d.Get("StructParent"); obj != nil {
   683  		annot.StructParent = obj
   684  	}
   685  
   686  	if obj := d.Get("OC"); obj != nil {
   687  		annot.OC = obj
   688  	}
   689  
   690  	subtypeObj := d.Get("Subtype")
   691  	if subtypeObj == nil {
   692  		common.Log.Debug("WARNING: Compatibility issue - annotation Subtype missing - assuming no subtype")
   693  		annot.context = nil
   694  		return annot, nil
   695  	}
   696  	subtype, ok := subtypeObj.(*PdfObjectName)
   697  	if !ok {
   698  		common.Log.Debug("ERROR: Invalid Subtype object type != name (%T)", subtypeObj)
   699  		return nil, fmt.Errorf("Invalid Subtype object type != name (%T)", subtypeObj)
   700  	}
   701  	switch *subtype {
   702  	case "Text":
   703  		ctx, err := r.newPdfAnnotationTextFromDict(d)
   704  		if err != nil {
   705  			return nil, err
   706  		}
   707  		ctx.PdfAnnotation = annot
   708  		annot.context = ctx
   709  		return annot, nil
   710  	case "Link":
   711  		ctx, err := r.newPdfAnnotationLinkFromDict(d)
   712  		if err != nil {
   713  			return nil, err
   714  		}
   715  		ctx.PdfAnnotation = annot
   716  		annot.context = ctx
   717  		return annot, nil
   718  	case "FreeText":
   719  		ctx, err := r.newPdfAnnotationFreeTextFromDict(d)
   720  		if err != nil {
   721  			return nil, err
   722  		}
   723  		ctx.PdfAnnotation = annot
   724  		annot.context = ctx
   725  		return annot, nil
   726  	case "Line":
   727  		ctx, err := r.newPdfAnnotationLineFromDict(d)
   728  		if err != nil {
   729  			return nil, err
   730  		}
   731  		ctx.PdfAnnotation = annot
   732  		annot.context = ctx
   733  		common.Log.Trace("LINE ANNOTATION: annot (%T): %+v\n", annot, annot)
   734  		common.Log.Trace("LINE ANNOTATION: ctx (%T): %+v\n", ctx, ctx)
   735  		common.Log.Trace("LINE ANNOTATION Markup: ctx (%T): %+v\n", ctx.PdfAnnotationMarkup, ctx.PdfAnnotationMarkup)
   736  
   737  		return annot, nil
   738  	case "Square":
   739  		ctx, err := r.newPdfAnnotationSquareFromDict(d)
   740  		if err != nil {
   741  			return nil, err
   742  		}
   743  		ctx.PdfAnnotation = annot
   744  		annot.context = ctx
   745  		return annot, nil
   746  	case "Circle":
   747  		ctx, err := r.newPdfAnnotationCircleFromDict(d)
   748  		if err != nil {
   749  			return nil, err
   750  		}
   751  		ctx.PdfAnnotation = annot
   752  		annot.context = ctx
   753  		return annot, nil
   754  	case "Polygon":
   755  		ctx, err := r.newPdfAnnotationPolygonFromDict(d)
   756  		if err != nil {
   757  			return nil, err
   758  		}
   759  		ctx.PdfAnnotation = annot
   760  		annot.context = ctx
   761  		return annot, nil
   762  	case "PolyLine":
   763  		ctx, err := r.newPdfAnnotationPolyLineFromDict(d)
   764  		if err != nil {
   765  			return nil, err
   766  		}
   767  		ctx.PdfAnnotation = annot
   768  		annot.context = ctx
   769  		return annot, nil
   770  	case "Highlight":
   771  		ctx, err := r.newPdfAnnotationHighlightFromDict(d)
   772  		if err != nil {
   773  			return nil, err
   774  		}
   775  		ctx.PdfAnnotation = annot
   776  		annot.context = ctx
   777  		return annot, nil
   778  	case "Underline":
   779  		ctx, err := r.newPdfAnnotationUnderlineFromDict(d)
   780  		if err != nil {
   781  			return nil, err
   782  		}
   783  		ctx.PdfAnnotation = annot
   784  		annot.context = ctx
   785  		return annot, nil
   786  	case "Squiggly":
   787  		ctx, err := r.newPdfAnnotationSquigglyFromDict(d)
   788  		if err != nil {
   789  			return nil, err
   790  		}
   791  		ctx.PdfAnnotation = annot
   792  		annot.context = ctx
   793  		return annot, nil
   794  	case "StrikeOut":
   795  		ctx, err := r.newPdfAnnotationStrikeOut(d)
   796  		if err != nil {
   797  			return nil, err
   798  		}
   799  		ctx.PdfAnnotation = annot
   800  		annot.context = ctx
   801  		return annot, nil
   802  	case "Caret":
   803  		ctx, err := r.newPdfAnnotationCaretFromDict(d)
   804  		if err != nil {
   805  			return nil, err
   806  		}
   807  		ctx.PdfAnnotation = annot
   808  		annot.context = ctx
   809  		return annot, nil
   810  	case "Stamp":
   811  		ctx, err := r.newPdfAnnotationStampFromDict(d)
   812  		if err != nil {
   813  			return nil, err
   814  		}
   815  		ctx.PdfAnnotation = annot
   816  		annot.context = ctx
   817  		return annot, nil
   818  	case "Ink":
   819  		ctx, err := r.newPdfAnnotationInkFromDict(d)
   820  		if err != nil {
   821  			return nil, err
   822  		}
   823  		ctx.PdfAnnotation = annot
   824  		annot.context = ctx
   825  		return annot, nil
   826  	case "Popup":
   827  		ctx, err := r.newPdfAnnotationPopupFromDict(d)
   828  		if err != nil {
   829  			return nil, err
   830  		}
   831  		ctx.PdfAnnotation = annot
   832  		annot.context = ctx
   833  		return annot, nil
   834  	case "FileAttachment":
   835  		ctx, err := r.newPdfAnnotationFileAttachmentFromDict(d)
   836  		if err != nil {
   837  			return nil, err
   838  		}
   839  		ctx.PdfAnnotation = annot
   840  		annot.context = ctx
   841  		return annot, nil
   842  	case "Sound":
   843  		ctx, err := r.newPdfAnnotationSoundFromDict(d)
   844  		if err != nil {
   845  			return nil, err
   846  		}
   847  		ctx.PdfAnnotation = annot
   848  		annot.context = ctx
   849  		return annot, nil
   850  	case "RichMedia":
   851  		ctx, err := r.newPdfAnnotationRichMediaFromDict(d)
   852  		if err != nil {
   853  			return nil, err
   854  		}
   855  		ctx.PdfAnnotation = annot
   856  		annot.context = ctx
   857  		return annot, nil
   858  	case "Movie":
   859  		ctx, err := r.newPdfAnnotationMovieFromDict(d)
   860  		if err != nil {
   861  			return nil, err
   862  		}
   863  		ctx.PdfAnnotation = annot
   864  		annot.context = ctx
   865  		return annot, nil
   866  	case "Screen":
   867  		ctx, err := r.newPdfAnnotationScreenFromDict(d)
   868  		if err != nil {
   869  			return nil, err
   870  		}
   871  		ctx.PdfAnnotation = annot
   872  		annot.context = ctx
   873  		return annot, nil
   874  	case "Widget":
   875  		ctx, err := r.newPdfAnnotationWidgetFromDict(d)
   876  		if err != nil {
   877  			return nil, err
   878  		}
   879  		ctx.PdfAnnotation = annot
   880  		annot.context = ctx
   881  		return annot, nil
   882  	case "PrinterMark":
   883  		ctx, err := r.newPdfAnnotationPrinterMarkFromDict(d)
   884  		if err != nil {
   885  			return nil, err
   886  		}
   887  		ctx.PdfAnnotation = annot
   888  		annot.context = ctx
   889  		return annot, nil
   890  	case "TrapNet":
   891  		ctx, err := r.newPdfAnnotationTrapNetFromDict(d)
   892  		if err != nil {
   893  			return nil, err
   894  		}
   895  		ctx.PdfAnnotation = annot
   896  		annot.context = ctx
   897  		return annot, nil
   898  	case "Watermark":
   899  		ctx, err := r.newPdfAnnotationWatermarkFromDict(d)
   900  		if err != nil {
   901  			return nil, err
   902  		}
   903  		ctx.PdfAnnotation = annot
   904  		annot.context = ctx
   905  		return annot, nil
   906  	case "3D":
   907  		ctx, err := r.newPdfAnnotation3DFromDict(d)
   908  		if err != nil {
   909  			return nil, err
   910  		}
   911  		ctx.PdfAnnotation = annot
   912  		annot.context = ctx
   913  		return annot, nil
   914  	case "Projection":
   915  		ctx, err := r.newPdfAnnotationProjectionFromDict(d)
   916  		if err != nil {
   917  			return nil, err
   918  		}
   919  		ctx.PdfAnnotation = annot
   920  		annot.context = ctx
   921  		return annot, nil
   922  	case "Redact":
   923  		ctx, err := r.newPdfAnnotationRedactFromDict(d)
   924  		if err != nil {
   925  			return nil, err
   926  		}
   927  		ctx.PdfAnnotation = annot
   928  		annot.context = ctx
   929  		return annot, nil
   930  	}
   931  
   932  	err := fmt.Errorf("Unknown annotation (%s)", *subtype)
   933  	return nil, err
   934  }
   935  
   936  // Load data for markup annotation subtypes.
   937  func (r *PdfReader) newPdfAnnotationMarkupFromDict(d *PdfObjectDictionary) (*PdfAnnotationMarkup, error) {
   938  	annot := &PdfAnnotationMarkup{}
   939  
   940  	if obj := d.Get("T"); obj != nil {
   941  		annot.T = obj
   942  	}
   943  
   944  	if obj := d.Get("Popup"); obj != nil {
   945  		indObj, isIndirect := obj.(*PdfIndirectObject)
   946  		if !isIndirect {
   947  			if _, isNull := obj.(*PdfObjectNull); !isNull {
   948  				return nil, fmt.Errorf("Popup should point to an indirect object")
   949  			}
   950  		} else {
   951  			popupAnnotObj, err := r.newPdfAnnotationFromIndirectObject(indObj)
   952  			if err != nil {
   953  				return nil, err
   954  			}
   955  			popupAnnot, isPopupAnnot := popupAnnotObj.context.(*PdfAnnotationPopup)
   956  			if !isPopupAnnot {
   957  				return nil, fmt.Errorf("Popup not referring to a popup annotation!")
   958  			}
   959  
   960  			annot.Popup = popupAnnot
   961  		}
   962  	}
   963  
   964  	if obj := d.Get("CA"); obj != nil {
   965  		annot.CA = obj
   966  	}
   967  	if obj := d.Get("RC"); obj != nil {
   968  		annot.RC = obj
   969  	}
   970  	if obj := d.Get("CreationDate"); obj != nil {
   971  		annot.CreationDate = obj
   972  	}
   973  	if obj := d.Get("IRT"); obj != nil {
   974  		annot.IRT = obj
   975  	}
   976  	if obj := d.Get("Subj"); obj != nil {
   977  		annot.Subj = obj
   978  	}
   979  	if obj := d.Get("RT"); obj != nil {
   980  		annot.RT = obj
   981  	}
   982  	if obj := d.Get("IT"); obj != nil {
   983  		annot.IT = obj
   984  	}
   985  	if obj := d.Get("ExData"); obj != nil {
   986  		annot.ExData = obj
   987  	}
   988  
   989  	return annot, nil
   990  }
   991  
   992  func (r *PdfReader) newPdfAnnotationTextFromDict(d *PdfObjectDictionary) (*PdfAnnotationText, error) {
   993  	annot := PdfAnnotationText{}
   994  
   995  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
   996  	if err != nil {
   997  		return nil, err
   998  	}
   999  	annot.PdfAnnotationMarkup = markup
  1000  
  1001  	annot.Open = d.Get("Open")
  1002  	annot.Name = d.Get("Name")
  1003  	annot.State = d.Get("State")
  1004  	annot.StateModel = d.Get("StateModel")
  1005  
  1006  	return &annot, nil
  1007  }
  1008  
  1009  func (r *PdfReader) newPdfAnnotationLinkFromDict(d *PdfObjectDictionary) (*PdfAnnotationLink, error) {
  1010  	annot := PdfAnnotationLink{}
  1011  
  1012  	annot.A = d.Get("A")
  1013  	annot.Dest = d.Get("Dest")
  1014  	annot.H = d.Get("H")
  1015  	annot.PA = d.Get("PA")
  1016  	annot.QuadPoints = d.Get("QuadPoints")
  1017  	annot.BS = d.Get("BS")
  1018  
  1019  	return &annot, nil
  1020  }
  1021  
  1022  func (r *PdfReader) newPdfAnnotationFreeTextFromDict(d *PdfObjectDictionary) (*PdfAnnotationFreeText, error) {
  1023  	annot := PdfAnnotationFreeText{}
  1024  
  1025  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1026  	if err != nil {
  1027  		return nil, err
  1028  	}
  1029  	annot.PdfAnnotationMarkup = markup
  1030  
  1031  	annot.DA = d.Get("DA")
  1032  	annot.Q = d.Get("Q")
  1033  	annot.RC = d.Get("RC")
  1034  	annot.DS = d.Get("DS")
  1035  	annot.CL = d.Get("CL")
  1036  	annot.IT = d.Get("IT")
  1037  	annot.BE = d.Get("BE")
  1038  	annot.RD = d.Get("RD")
  1039  	annot.BS = d.Get("BS")
  1040  	annot.LE = d.Get("LE")
  1041  
  1042  	return &annot, nil
  1043  }
  1044  
  1045  func (r *PdfReader) newPdfAnnotationLineFromDict(d *PdfObjectDictionary) (*PdfAnnotationLine, error) {
  1046  	annot := PdfAnnotationLine{}
  1047  
  1048  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1049  	if err != nil {
  1050  		return nil, err
  1051  	}
  1052  	annot.PdfAnnotationMarkup = markup
  1053  
  1054  	annot.L = d.Get("L")
  1055  	annot.BS = d.Get("BS")
  1056  	annot.LE = d.Get("LE")
  1057  	annot.IC = d.Get("IC")
  1058  	annot.LL = d.Get("LL")
  1059  	annot.LLE = d.Get("LLE")
  1060  	annot.Cap = d.Get("Cap")
  1061  	annot.IT = d.Get("IT")
  1062  	annot.LLO = d.Get("LLO")
  1063  	annot.CP = d.Get("CP")
  1064  	annot.Measure = d.Get("Measure")
  1065  	annot.CO = d.Get("CO")
  1066  
  1067  	return &annot, nil
  1068  }
  1069  
  1070  func (r *PdfReader) newPdfAnnotationSquareFromDict(d *PdfObjectDictionary) (*PdfAnnotationSquare, error) {
  1071  	annot := PdfAnnotationSquare{}
  1072  
  1073  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1074  	if err != nil {
  1075  		return nil, err
  1076  	}
  1077  	annot.PdfAnnotationMarkup = markup
  1078  
  1079  	annot.BS = d.Get("BS")
  1080  	annot.IC = d.Get("IC")
  1081  	annot.BE = d.Get("BE")
  1082  	annot.RD = d.Get("RD")
  1083  
  1084  	return &annot, nil
  1085  }
  1086  
  1087  func (r *PdfReader) newPdfAnnotationCircleFromDict(d *PdfObjectDictionary) (*PdfAnnotationCircle, error) {
  1088  	annot := PdfAnnotationCircle{}
  1089  
  1090  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1091  	if err != nil {
  1092  		return nil, err
  1093  	}
  1094  	annot.PdfAnnotationMarkup = markup
  1095  
  1096  	annot.BS = d.Get("BS")
  1097  	annot.IC = d.Get("IC")
  1098  	annot.BE = d.Get("BE")
  1099  	annot.RD = d.Get("RD")
  1100  
  1101  	return &annot, nil
  1102  }
  1103  
  1104  func (r *PdfReader) newPdfAnnotationPolygonFromDict(d *PdfObjectDictionary) (*PdfAnnotationPolygon, error) {
  1105  	annot := PdfAnnotationPolygon{}
  1106  
  1107  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1108  	if err != nil {
  1109  		return nil, err
  1110  	}
  1111  	annot.PdfAnnotationMarkup = markup
  1112  
  1113  	annot.Vertices = d.Get("Vertices")
  1114  	annot.LE = d.Get("LE")
  1115  	annot.BS = d.Get("BS")
  1116  	annot.IC = d.Get("IC")
  1117  	annot.BE = d.Get("BE")
  1118  	annot.IT = d.Get("IT")
  1119  	annot.Measure = d.Get("Measure")
  1120  
  1121  	return &annot, nil
  1122  }
  1123  
  1124  func (r *PdfReader) newPdfAnnotationPolyLineFromDict(d *PdfObjectDictionary) (*PdfAnnotationPolyLine, error) {
  1125  	annot := PdfAnnotationPolyLine{}
  1126  
  1127  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1128  	if err != nil {
  1129  		return nil, err
  1130  	}
  1131  	annot.PdfAnnotationMarkup = markup
  1132  
  1133  	annot.Vertices = d.Get("Vertices")
  1134  	annot.LE = d.Get("LE")
  1135  	annot.BS = d.Get("BS")
  1136  	annot.IC = d.Get("IC")
  1137  	annot.BE = d.Get("BE")
  1138  	annot.IT = d.Get("IT")
  1139  	annot.Measure = d.Get("Measure")
  1140  
  1141  	return &annot, nil
  1142  }
  1143  
  1144  func (r *PdfReader) newPdfAnnotationHighlightFromDict(d *PdfObjectDictionary) (*PdfAnnotationHighlight, error) {
  1145  	annot := PdfAnnotationHighlight{}
  1146  
  1147  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1148  	if err != nil {
  1149  		return nil, err
  1150  	}
  1151  	annot.PdfAnnotationMarkup = markup
  1152  
  1153  	annot.QuadPoints = d.Get("QuadPoints")
  1154  
  1155  	return &annot, nil
  1156  }
  1157  
  1158  func (r *PdfReader) newPdfAnnotationUnderlineFromDict(d *PdfObjectDictionary) (*PdfAnnotationUnderline, error) {
  1159  	annot := PdfAnnotationUnderline{}
  1160  
  1161  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1162  	if err != nil {
  1163  		return nil, err
  1164  	}
  1165  	annot.PdfAnnotationMarkup = markup
  1166  
  1167  	annot.QuadPoints = d.Get("QuadPoints")
  1168  
  1169  	return &annot, nil
  1170  }
  1171  
  1172  func (r *PdfReader) newPdfAnnotationSquigglyFromDict(d *PdfObjectDictionary) (*PdfAnnotationSquiggly, error) {
  1173  	annot := PdfAnnotationSquiggly{}
  1174  
  1175  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1176  	if err != nil {
  1177  		return nil, err
  1178  	}
  1179  	annot.PdfAnnotationMarkup = markup
  1180  
  1181  	annot.QuadPoints = d.Get("QuadPoints")
  1182  
  1183  	return &annot, nil
  1184  }
  1185  
  1186  func (r *PdfReader) newPdfAnnotationStrikeOut(d *PdfObjectDictionary) (*PdfAnnotationStrikeOut, error) {
  1187  	annot := PdfAnnotationStrikeOut{}
  1188  
  1189  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1190  	if err != nil {
  1191  		return nil, err
  1192  	}
  1193  	annot.PdfAnnotationMarkup = markup
  1194  
  1195  	annot.QuadPoints = d.Get("QuadPoints")
  1196  
  1197  	return &annot, nil
  1198  }
  1199  
  1200  func (r *PdfReader) newPdfAnnotationCaretFromDict(d *PdfObjectDictionary) (*PdfAnnotationCaret, error) {
  1201  	annot := PdfAnnotationCaret{}
  1202  
  1203  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1204  	if err != nil {
  1205  		return nil, err
  1206  	}
  1207  	annot.PdfAnnotationMarkup = markup
  1208  
  1209  	annot.RD = d.Get("RD")
  1210  	annot.Sy = d.Get("Sy")
  1211  
  1212  	return &annot, nil
  1213  }
  1214  func (r *PdfReader) newPdfAnnotationStampFromDict(d *PdfObjectDictionary) (*PdfAnnotationStamp, error) {
  1215  	annot := PdfAnnotationStamp{}
  1216  
  1217  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1218  	if err != nil {
  1219  		return nil, err
  1220  	}
  1221  	annot.PdfAnnotationMarkup = markup
  1222  
  1223  	annot.Name = d.Get("Name")
  1224  
  1225  	return &annot, nil
  1226  }
  1227  
  1228  func (r *PdfReader) newPdfAnnotationInkFromDict(d *PdfObjectDictionary) (*PdfAnnotationInk, error) {
  1229  	annot := PdfAnnotationInk{}
  1230  
  1231  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1232  	if err != nil {
  1233  		return nil, err
  1234  	}
  1235  	annot.PdfAnnotationMarkup = markup
  1236  
  1237  	annot.InkList = d.Get("InkList")
  1238  	annot.BS = d.Get("BS")
  1239  
  1240  	return &annot, nil
  1241  }
  1242  
  1243  func (r *PdfReader) newPdfAnnotationPopupFromDict(d *PdfObjectDictionary) (*PdfAnnotationPopup, error) {
  1244  	annot := PdfAnnotationPopup{}
  1245  
  1246  	annot.Parent = d.Get("Parent")
  1247  	annot.Open = d.Get("Open")
  1248  
  1249  	return &annot, nil
  1250  }
  1251  
  1252  func (r *PdfReader) newPdfAnnotationFileAttachmentFromDict(d *PdfObjectDictionary) (*PdfAnnotationFileAttachment, error) {
  1253  	annot := PdfAnnotationFileAttachment{}
  1254  
  1255  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1256  	if err != nil {
  1257  		return nil, err
  1258  	}
  1259  	annot.PdfAnnotationMarkup = markup
  1260  
  1261  	annot.FS = d.Get("FS")
  1262  	annot.Name = d.Get("Name")
  1263  
  1264  	return &annot, nil
  1265  }
  1266  
  1267  func (r *PdfReader) newPdfAnnotationSoundFromDict(d *PdfObjectDictionary) (*PdfAnnotationSound, error) {
  1268  	annot := PdfAnnotationSound{}
  1269  
  1270  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1271  	if err != nil {
  1272  		return nil, err
  1273  	}
  1274  	annot.PdfAnnotationMarkup = markup
  1275  
  1276  	annot.Name = d.Get("Name")
  1277  	annot.Sound = d.Get("Sound")
  1278  
  1279  	return &annot, nil
  1280  }
  1281  
  1282  func (r *PdfReader) newPdfAnnotationRichMediaFromDict(d *PdfObjectDictionary) (*PdfAnnotationRichMedia, error) {
  1283  	annot := &PdfAnnotationRichMedia{}
  1284  
  1285  	annot.RichMediaSettings = d.Get("RichMediaSettings")
  1286  	annot.RichMediaContent = d.Get("RichMediaContent")
  1287  
  1288  	return annot, nil
  1289  }
  1290  
  1291  func (r *PdfReader) newPdfAnnotationMovieFromDict(d *PdfObjectDictionary) (*PdfAnnotationMovie, error) {
  1292  	annot := PdfAnnotationMovie{}
  1293  
  1294  	annot.T = d.Get("T")
  1295  	annot.Movie = d.Get("Movie")
  1296  	annot.A = d.Get("A")
  1297  
  1298  	return &annot, nil
  1299  }
  1300  
  1301  func (r *PdfReader) newPdfAnnotationScreenFromDict(d *PdfObjectDictionary) (*PdfAnnotationScreen, error) {
  1302  	annot := PdfAnnotationScreen{}
  1303  
  1304  	annot.T = d.Get("T")
  1305  	annot.MK = d.Get("MK")
  1306  	annot.A = d.Get("A")
  1307  	annot.AA = d.Get("AA")
  1308  
  1309  	return &annot, nil
  1310  }
  1311  
  1312  func (r *PdfReader) newPdfAnnotationWidgetFromDict(d *PdfObjectDictionary) (*PdfAnnotationWidget, error) {
  1313  	annot := PdfAnnotationWidget{}
  1314  
  1315  	annot.H = d.Get("H")
  1316  
  1317  	annot.MK = d.Get("MK")
  1318  	// MK can be an indirect object...
  1319  	// Expected to be a dictionary.
  1320  
  1321  	annot.A = d.Get("A")
  1322  	annot.AA = d.Get("AA")
  1323  	annot.BS = d.Get("BS")
  1324  	annot.Parent = d.Get("Parent")
  1325  
  1326  	return &annot, nil
  1327  }
  1328  
  1329  func (r *PdfReader) newPdfAnnotationPrinterMarkFromDict(d *PdfObjectDictionary) (*PdfAnnotationPrinterMark, error) {
  1330  	annot := PdfAnnotationPrinterMark{}
  1331  
  1332  	annot.MN = d.Get("MN")
  1333  
  1334  	return &annot, nil
  1335  }
  1336  
  1337  func (r *PdfReader) newPdfAnnotationTrapNetFromDict(d *PdfObjectDictionary) (*PdfAnnotationTrapNet, error) {
  1338  	annot := PdfAnnotationTrapNet{}
  1339  	// empty?e
  1340  	return &annot, nil
  1341  }
  1342  
  1343  func (r *PdfReader) newPdfAnnotationWatermarkFromDict(d *PdfObjectDictionary) (*PdfAnnotationWatermark, error) {
  1344  	annot := PdfAnnotationWatermark{}
  1345  
  1346  	annot.FixedPrint = d.Get("FixedPrint")
  1347  
  1348  	return &annot, nil
  1349  }
  1350  
  1351  func (r *PdfReader) newPdfAnnotation3DFromDict(d *PdfObjectDictionary) (*PdfAnnotation3D, error) {
  1352  	annot := PdfAnnotation3D{}
  1353  
  1354  	annot.T3DD = d.Get("3DD")
  1355  	annot.T3DV = d.Get("3DV")
  1356  	annot.T3DA = d.Get("3DA")
  1357  	annot.T3DI = d.Get("3DI")
  1358  	annot.T3DB = d.Get("3DB")
  1359  
  1360  	return &annot, nil
  1361  }
  1362  
  1363  func (r *PdfReader) newPdfAnnotationProjectionFromDict(d *PdfObjectDictionary) (*PdfAnnotationProjection, error) {
  1364  	annot := &PdfAnnotationProjection{}
  1365  
  1366  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1367  	if err != nil {
  1368  		return nil, err
  1369  	}
  1370  	annot.PdfAnnotationMarkup = markup
  1371  
  1372  	return annot, nil
  1373  }
  1374  
  1375  func (r *PdfReader) newPdfAnnotationRedactFromDict(d *PdfObjectDictionary) (*PdfAnnotationRedact, error) {
  1376  	annot := PdfAnnotationRedact{}
  1377  
  1378  	markup, err := r.newPdfAnnotationMarkupFromDict(d)
  1379  	if err != nil {
  1380  		return nil, err
  1381  	}
  1382  	annot.PdfAnnotationMarkup = markup
  1383  
  1384  	annot.QuadPoints = d.Get("QuadPoints")
  1385  	annot.IC = d.Get("IC")
  1386  	annot.RO = d.Get("RO")
  1387  	annot.OverlayText = d.Get("OverlayText")
  1388  	annot.Repeat = d.Get("Repeat")
  1389  	annot.DA = d.Get("DA")
  1390  	annot.Q = d.Get("Q")
  1391  
  1392  	return &annot, nil
  1393  }
  1394  
  1395  func (this *PdfAnnotation) GetContainingPdfObject() PdfObject {
  1396  	return this.primitive
  1397  }
  1398  
  1399  // Note: Call the sub-annotation's ToPdfObject to set both the generic and non-generic information.
  1400  // TODO/FIXME: Consider doing it here instead.
  1401  func (this *PdfAnnotation) ToPdfObject() PdfObject {
  1402  	container := this.primitive
  1403  	d := container.PdfObject.(*PdfObjectDictionary)
  1404  
  1405  	d.Set("Type", MakeName("Annot"))
  1406  	d.SetIfNotNil("Rect", this.Rect)
  1407  	d.SetIfNotNil("Contents", this.Contents)
  1408  	d.SetIfNotNil("P", this.P)
  1409  	d.SetIfNotNil("NM", this.NM)
  1410  	d.SetIfNotNil("M", this.M)
  1411  	d.SetIfNotNil("F", this.F)
  1412  	d.SetIfNotNil("AP", this.AP)
  1413  	d.SetIfNotNil("AS", this.AS)
  1414  	d.SetIfNotNil("Border", this.Border)
  1415  	d.SetIfNotNil("C", this.C)
  1416  	d.SetIfNotNil("StructParent", this.StructParent)
  1417  	d.SetIfNotNil("OC", this.OC)
  1418  
  1419  	return container
  1420  }
  1421  
  1422  // Markup portion of the annotation.
  1423  func (this *PdfAnnotationMarkup) appendToPdfDictionary(d *PdfObjectDictionary) {
  1424  	d.SetIfNotNil("T", this.T)
  1425  	if this.Popup != nil {
  1426  		d.Set("Popup", this.Popup.ToPdfObject())
  1427  	}
  1428  	d.SetIfNotNil("CA", this.CA)
  1429  	d.SetIfNotNil("RC", this.RC)
  1430  	d.SetIfNotNil("CreationDate", this.CreationDate)
  1431  	d.SetIfNotNil("IRT", this.IRT)
  1432  	d.SetIfNotNil("Subj", this.Subj)
  1433  	d.SetIfNotNil("RT", this.RT)
  1434  	d.SetIfNotNil("IT", this.IT)
  1435  	d.SetIfNotNil("ExData", this.ExData)
  1436  }
  1437  
  1438  func (this *PdfAnnotationText) ToPdfObject() PdfObject {
  1439  	this.PdfAnnotation.ToPdfObject()
  1440  	container := this.primitive
  1441  	d := container.PdfObject.(*PdfObjectDictionary)
  1442  	if this.PdfAnnotationMarkup != nil {
  1443  		this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1444  	}
  1445  
  1446  	d.SetIfNotNil("Subtype", MakeName("Text"))
  1447  	d.SetIfNotNil("Open", this.Open)
  1448  	d.SetIfNotNil("Name", this.Name)
  1449  	d.SetIfNotNil("State", this.State)
  1450  	d.SetIfNotNil("StateModel", this.StateModel)
  1451  	return container
  1452  }
  1453  
  1454  func (this *PdfAnnotationLink) ToPdfObject() PdfObject {
  1455  	this.PdfAnnotation.ToPdfObject()
  1456  	container := this.primitive
  1457  	d := container.PdfObject.(*PdfObjectDictionary)
  1458  
  1459  	d.SetIfNotNil("Subtype", MakeName("Link"))
  1460  	d.SetIfNotNil("A", this.A)
  1461  	d.SetIfNotNil("Dest", this.Dest)
  1462  	d.SetIfNotNil("H", this.H)
  1463  	d.SetIfNotNil("PA", this.PA)
  1464  	d.SetIfNotNil("QuadPoints", this.QuadPoints)
  1465  	d.SetIfNotNil("BS", this.BS)
  1466  	return container
  1467  }
  1468  
  1469  func (this *PdfAnnotationFreeText) ToPdfObject() PdfObject {
  1470  	this.PdfAnnotation.ToPdfObject()
  1471  	container := this.primitive
  1472  	d := container.PdfObject.(*PdfObjectDictionary)
  1473  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1474  
  1475  	d.SetIfNotNil("Subtype", MakeName("FreeText"))
  1476  	d.SetIfNotNil("DA", this.DA)
  1477  	d.SetIfNotNil("Q", this.Q)
  1478  	d.SetIfNotNil("RC", this.RC)
  1479  	d.SetIfNotNil("DS", this.DS)
  1480  	d.SetIfNotNil("CL", this.CL)
  1481  	d.SetIfNotNil("IT", this.IT)
  1482  	d.SetIfNotNil("BE", this.BE)
  1483  	d.SetIfNotNil("RD", this.RD)
  1484  	d.SetIfNotNil("BS", this.BS)
  1485  	d.SetIfNotNil("LE", this.LE)
  1486  
  1487  	return container
  1488  }
  1489  func (this *PdfAnnotationLine) ToPdfObject() PdfObject {
  1490  	this.PdfAnnotation.ToPdfObject()
  1491  	container := this.primitive
  1492  	d := container.PdfObject.(*PdfObjectDictionary)
  1493  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1494  
  1495  	d.SetIfNotNil("Subtype", MakeName("Line"))
  1496  	d.SetIfNotNil("L", this.L)
  1497  	d.SetIfNotNil("BS", this.BS)
  1498  	d.SetIfNotNil("LE", this.LE)
  1499  	d.SetIfNotNil("IC", this.IC)
  1500  	d.SetIfNotNil("LL", this.LL)
  1501  	d.SetIfNotNil("LLE", this.LLE)
  1502  	d.SetIfNotNil("Cap", this.Cap)
  1503  	d.SetIfNotNil("IT", this.IT)
  1504  	d.SetIfNotNil("LLO", this.LLO)
  1505  	d.SetIfNotNil("CP", this.CP)
  1506  	d.SetIfNotNil("Measure", this.Measure)
  1507  	d.SetIfNotNil("CO", this.CO)
  1508  
  1509  	return container
  1510  }
  1511  
  1512  func (this *PdfAnnotationSquare) ToPdfObject() PdfObject {
  1513  	this.PdfAnnotation.ToPdfObject()
  1514  	container := this.primitive
  1515  	d := container.PdfObject.(*PdfObjectDictionary)
  1516  	if this.PdfAnnotationMarkup != nil {
  1517  		this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1518  	}
  1519  
  1520  	d.SetIfNotNil("Subtype", MakeName("Square"))
  1521  	d.SetIfNotNil("BS", this.BS)
  1522  	d.SetIfNotNil("IC", this.IC)
  1523  	d.SetIfNotNil("BE", this.BE)
  1524  	d.SetIfNotNil("RD", this.RD)
  1525  
  1526  	return container
  1527  }
  1528  
  1529  func (this *PdfAnnotationCircle) ToPdfObject() PdfObject {
  1530  	this.PdfAnnotation.ToPdfObject()
  1531  	container := this.primitive
  1532  	d := container.PdfObject.(*PdfObjectDictionary)
  1533  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1534  
  1535  	d.SetIfNotNil("Subtype", MakeName("Circle"))
  1536  	d.SetIfNotNil("BS", this.BS)
  1537  	d.SetIfNotNil("IC", this.IC)
  1538  	d.SetIfNotNil("BE", this.BE)
  1539  	d.SetIfNotNil("RD", this.RD)
  1540  
  1541  	return container
  1542  }
  1543  
  1544  func (this *PdfAnnotationPolygon) ToPdfObject() PdfObject {
  1545  	this.PdfAnnotation.ToPdfObject()
  1546  	container := this.primitive
  1547  	d := container.PdfObject.(*PdfObjectDictionary)
  1548  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1549  
  1550  	d.SetIfNotNil("Subtype", MakeName("Polygon"))
  1551  	d.SetIfNotNil("Vertices", this.Vertices)
  1552  	d.SetIfNotNil("LE", this.LE)
  1553  	d.SetIfNotNil("BS", this.BS)
  1554  	d.SetIfNotNil("IC", this.IC)
  1555  	d.SetIfNotNil("BE", this.BE)
  1556  	d.SetIfNotNil("IT", this.IT)
  1557  	d.SetIfNotNil("Measure", this.Measure)
  1558  
  1559  	return container
  1560  }
  1561  
  1562  func (this *PdfAnnotationPolyLine) ToPdfObject() PdfObject {
  1563  	this.PdfAnnotation.ToPdfObject()
  1564  	container := this.primitive
  1565  	d := container.PdfObject.(*PdfObjectDictionary)
  1566  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1567  
  1568  	d.SetIfNotNil("Subtype", MakeName("PolyLine"))
  1569  	d.SetIfNotNil("Vertices", this.Vertices)
  1570  	d.SetIfNotNil("LE", this.LE)
  1571  	d.SetIfNotNil("BS", this.BS)
  1572  	d.SetIfNotNil("IC", this.IC)
  1573  	d.SetIfNotNil("BE", this.BE)
  1574  	d.SetIfNotNil("IT", this.IT)
  1575  	d.SetIfNotNil("Measure", this.Measure)
  1576  
  1577  	return container
  1578  }
  1579  
  1580  func (this *PdfAnnotationHighlight) ToPdfObject() PdfObject {
  1581  	this.PdfAnnotation.ToPdfObject()
  1582  	container := this.primitive
  1583  	d := container.PdfObject.(*PdfObjectDictionary)
  1584  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1585  
  1586  	d.SetIfNotNil("Subtype", MakeName("Highlight"))
  1587  	d.SetIfNotNil("QuadPoints", this.QuadPoints)
  1588  	return container
  1589  }
  1590  
  1591  func (this *PdfAnnotationUnderline) ToPdfObject() PdfObject {
  1592  	this.PdfAnnotation.ToPdfObject()
  1593  	container := this.primitive
  1594  	d := container.PdfObject.(*PdfObjectDictionary)
  1595  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1596  
  1597  	d.SetIfNotNil("Subtype", MakeName("Underline"))
  1598  	d.SetIfNotNil("QuadPoints", this.QuadPoints)
  1599  	return container
  1600  }
  1601  
  1602  func (this *PdfAnnotationSquiggly) ToPdfObject() PdfObject {
  1603  	this.PdfAnnotation.ToPdfObject()
  1604  	container := this.primitive
  1605  	d := container.PdfObject.(*PdfObjectDictionary)
  1606  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1607  
  1608  	d.SetIfNotNil("Subtype", MakeName("Squiggly"))
  1609  	d.SetIfNotNil("QuadPoints", this.QuadPoints)
  1610  	return container
  1611  }
  1612  
  1613  func (this *PdfAnnotationStrikeOut) ToPdfObject() PdfObject {
  1614  	this.PdfAnnotation.ToPdfObject()
  1615  	container := this.primitive
  1616  	d := container.PdfObject.(*PdfObjectDictionary)
  1617  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1618  
  1619  	d.SetIfNotNil("Subtype", MakeName("StrikeOut"))
  1620  	d.SetIfNotNil("QuadPoints", this.QuadPoints)
  1621  	return container
  1622  }
  1623  
  1624  func (this *PdfAnnotationCaret) ToPdfObject() PdfObject {
  1625  	this.PdfAnnotation.ToPdfObject()
  1626  	container := this.primitive
  1627  	d := container.PdfObject.(*PdfObjectDictionary)
  1628  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1629  
  1630  	d.SetIfNotNil("Subtype", MakeName("Caret"))
  1631  	d.SetIfNotNil("RD", this.RD)
  1632  	d.SetIfNotNil("Sy", this.Sy)
  1633  	return container
  1634  }
  1635  
  1636  func (this *PdfAnnotationStamp) ToPdfObject() PdfObject {
  1637  	this.PdfAnnotation.ToPdfObject()
  1638  	container := this.primitive
  1639  	d := container.PdfObject.(*PdfObjectDictionary)
  1640  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1641  
  1642  	d.SetIfNotNil("Subtype", MakeName("Stamp"))
  1643  	d.SetIfNotNil("Name", this.Name)
  1644  	return container
  1645  }
  1646  
  1647  func (this *PdfAnnotationInk) ToPdfObject() PdfObject {
  1648  	this.PdfAnnotation.ToPdfObject()
  1649  	container := this.primitive
  1650  	d := container.PdfObject.(*PdfObjectDictionary)
  1651  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1652  
  1653  	d.SetIfNotNil("Subtype", MakeName("Ink"))
  1654  	d.SetIfNotNil("InkList", this.InkList)
  1655  	d.SetIfNotNil("BS", this.BS)
  1656  	return container
  1657  }
  1658  
  1659  func (this *PdfAnnotationPopup) ToPdfObject() PdfObject {
  1660  	this.PdfAnnotation.ToPdfObject()
  1661  	container := this.primitive
  1662  	d := container.PdfObject.(*PdfObjectDictionary)
  1663  
  1664  	d.SetIfNotNil("Subtype", MakeName("Popup"))
  1665  	d.SetIfNotNil("Parent", this.Parent)
  1666  	d.SetIfNotNil("Open", this.Open)
  1667  	return container
  1668  }
  1669  
  1670  func (this *PdfAnnotationFileAttachment) ToPdfObject() PdfObject {
  1671  	this.PdfAnnotation.ToPdfObject()
  1672  	container := this.primitive
  1673  	d := container.PdfObject.(*PdfObjectDictionary)
  1674  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1675  
  1676  	d.SetIfNotNil("Subtype", MakeName("FileAttachment"))
  1677  	d.SetIfNotNil("FS", this.FS)
  1678  	d.SetIfNotNil("Name", this.Name)
  1679  	return container
  1680  }
  1681  
  1682  func (this *PdfAnnotationRichMedia) ToPdfObject() PdfObject {
  1683  	this.PdfAnnotation.ToPdfObject()
  1684  	container := this.primitive
  1685  	d := container.PdfObject.(*PdfObjectDictionary)
  1686  
  1687  	d.SetIfNotNil("Subtype", MakeName("RichMedia"))
  1688  	d.SetIfNotNil("RichMediaSettings", this.RichMediaSettings)
  1689  	d.SetIfNotNil("RichMediaContent", this.RichMediaContent)
  1690  	return container
  1691  }
  1692  
  1693  func (this *PdfAnnotationSound) ToPdfObject() PdfObject {
  1694  	this.PdfAnnotation.ToPdfObject()
  1695  	container := this.primitive
  1696  	d := container.PdfObject.(*PdfObjectDictionary)
  1697  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1698  
  1699  	d.SetIfNotNil("Subtype", MakeName("Sound"))
  1700  	d.SetIfNotNil("Sound", this.Sound)
  1701  	d.SetIfNotNil("Name", this.Name)
  1702  	return container
  1703  }
  1704  
  1705  func (this *PdfAnnotationMovie) ToPdfObject() PdfObject {
  1706  	this.PdfAnnotation.ToPdfObject()
  1707  	container := this.primitive
  1708  	d := container.PdfObject.(*PdfObjectDictionary)
  1709  
  1710  	d.SetIfNotNil("Subtype", MakeName("Movie"))
  1711  	d.SetIfNotNil("T", this.T)
  1712  	d.SetIfNotNil("Movie", this.Movie)
  1713  	d.SetIfNotNil("A", this.A)
  1714  	return container
  1715  }
  1716  
  1717  func (this *PdfAnnotationScreen) ToPdfObject() PdfObject {
  1718  	this.PdfAnnotation.ToPdfObject()
  1719  	container := this.primitive
  1720  	d := container.PdfObject.(*PdfObjectDictionary)
  1721  
  1722  	d.SetIfNotNil("Subtype", MakeName("Screen"))
  1723  	d.SetIfNotNil("T", this.T)
  1724  	d.SetIfNotNil("MK", this.MK)
  1725  	d.SetIfNotNil("A", this.A)
  1726  	d.SetIfNotNil("AA", this.AA)
  1727  	return container
  1728  }
  1729  
  1730  func (this *PdfAnnotationWidget) ToPdfObject() PdfObject {
  1731  	this.PdfAnnotation.ToPdfObject()
  1732  	container := this.primitive
  1733  	d := container.PdfObject.(*PdfObjectDictionary)
  1734  
  1735  	d.SetIfNotNil("Subtype", MakeName("Widget"))
  1736  	d.SetIfNotNil("H", this.H)
  1737  	d.SetIfNotNil("MK", this.MK)
  1738  	d.SetIfNotNil("A", this.A)
  1739  	d.SetIfNotNil("AA", this.AA)
  1740  	d.SetIfNotNil("BS", this.BS)
  1741  	d.SetIfNotNil("Parent", this.Parent)
  1742  
  1743  	return container
  1744  }
  1745  
  1746  func (this *PdfAnnotationPrinterMark) ToPdfObject() PdfObject {
  1747  	this.PdfAnnotation.ToPdfObject()
  1748  	container := this.primitive
  1749  	d := container.PdfObject.(*PdfObjectDictionary)
  1750  
  1751  	d.SetIfNotNil("Subtype", MakeName("PrinterMark"))
  1752  	d.SetIfNotNil("MN", this.MN)
  1753  	return container
  1754  }
  1755  
  1756  func (this *PdfAnnotationTrapNet) ToPdfObject() PdfObject {
  1757  	this.PdfAnnotation.ToPdfObject()
  1758  	container := this.primitive
  1759  	d := container.PdfObject.(*PdfObjectDictionary)
  1760  
  1761  	d.SetIfNotNil("Subtype", MakeName("TrapNet"))
  1762  	return container
  1763  }
  1764  
  1765  func (this *PdfAnnotationWatermark) ToPdfObject() PdfObject {
  1766  	this.PdfAnnotation.ToPdfObject()
  1767  	container := this.primitive
  1768  	d := container.PdfObject.(*PdfObjectDictionary)
  1769  
  1770  	d.SetIfNotNil("Subtype", MakeName("Watermark"))
  1771  	d.SetIfNotNil("FixedPrint", this.FixedPrint)
  1772  
  1773  	return container
  1774  }
  1775  
  1776  func (this *PdfAnnotation3D) ToPdfObject() PdfObject {
  1777  	this.PdfAnnotation.ToPdfObject()
  1778  	container := this.primitive
  1779  	d := container.PdfObject.(*PdfObjectDictionary)
  1780  	d.SetIfNotNil("Subtype", MakeName("3D"))
  1781  	d.SetIfNotNil("3DD", this.T3DD)
  1782  	d.SetIfNotNil("3DV", this.T3DV)
  1783  	d.SetIfNotNil("3DA", this.T3DA)
  1784  	d.SetIfNotNil("3DI", this.T3DI)
  1785  	d.SetIfNotNil("3DB", this.T3DB)
  1786  	return container
  1787  }
  1788  
  1789  func (this *PdfAnnotationProjection) ToPdfObject() PdfObject {
  1790  	this.PdfAnnotation.ToPdfObject()
  1791  	container := this.primitive
  1792  	d := container.PdfObject.(*PdfObjectDictionary)
  1793  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1794  	return container
  1795  }
  1796  
  1797  func (this *PdfAnnotationRedact) ToPdfObject() PdfObject {
  1798  	this.PdfAnnotation.ToPdfObject()
  1799  	container := this.primitive
  1800  	d := container.PdfObject.(*PdfObjectDictionary)
  1801  	this.PdfAnnotationMarkup.appendToPdfDictionary(d)
  1802  
  1803  	d.SetIfNotNil("Subtype", MakeName("Redact"))
  1804  	d.SetIfNotNil("QuadPoints", this.QuadPoints)
  1805  	d.SetIfNotNil("IC", this.IC)
  1806  	d.SetIfNotNil("RO", this.RO)
  1807  	d.SetIfNotNil("OverlayText", this.OverlayText)
  1808  	d.SetIfNotNil("Repeat", this.Repeat)
  1809  	d.SetIfNotNil("DA", this.DA)
  1810  	d.SetIfNotNil("Q", this.Q)
  1811  	return container
  1812  }
  1813  
  1814  // Border definitions.
  1815  
  1816  type BorderStyle int
  1817  
  1818  const (
  1819  	BorderStyleSolid     BorderStyle = iota
  1820  	BorderStyleDashed    BorderStyle = iota
  1821  	BorderStyleBeveled   BorderStyle = iota
  1822  	BorderStyleInset     BorderStyle = iota
  1823  	BorderStyleUnderline BorderStyle = iota
  1824  )
  1825  
  1826  func (this *BorderStyle) GetPdfName() string {
  1827  	switch *this {
  1828  	case BorderStyleSolid:
  1829  		return "S"
  1830  	case BorderStyleDashed:
  1831  		return "D"
  1832  	case BorderStyleBeveled:
  1833  		return "B"
  1834  	case BorderStyleInset:
  1835  		return "I"
  1836  	case BorderStyleUnderline:
  1837  		return "U"
  1838  	}
  1839  
  1840  	return "" // Should not happen.
  1841  }
  1842  
  1843  // Border style
  1844  type PdfBorderStyle struct {
  1845  	W *float64     // Border width
  1846  	S *BorderStyle // Border style
  1847  	D *[]int       // Dash array.
  1848  
  1849  	container PdfObject
  1850  }
  1851  
  1852  func NewBorderStyle() *PdfBorderStyle {
  1853  	bs := &PdfBorderStyle{}
  1854  	return bs
  1855  }
  1856  
  1857  func (this *PdfBorderStyle) SetBorderWidth(width float64) {
  1858  	this.W = &width
  1859  }
  1860  
  1861  func (this *PdfBorderStyle) GetBorderWidth() float64 {
  1862  	if this.W == nil {
  1863  		return 1 // Default.
  1864  	}
  1865  	return *this.W
  1866  }
  1867  
  1868  func newPdfBorderStyleFromPdfObject(obj PdfObject) (*PdfBorderStyle, error) {
  1869  	bs := &PdfBorderStyle{}
  1870  	bs.container = obj
  1871  
  1872  	var d *PdfObjectDictionary
  1873  	obj = TraceToDirectObject(obj)
  1874  	d, ok := obj.(*PdfObjectDictionary)
  1875  	if !ok {
  1876  		return nil, errors.New("Type check")
  1877  	}
  1878  
  1879  	// Type.
  1880  	if obj := d.Get("Type"); obj != nil {
  1881  		name, ok := obj.(*PdfObjectName)
  1882  		if !ok {
  1883  			common.Log.Debug("Incompatibility with Type not a name object: %T", obj)
  1884  		} else {
  1885  			if *name != "Border" {
  1886  				common.Log.Debug("Warning, Type != Border: %s", *name)
  1887  			}
  1888  		}
  1889  	}
  1890  
  1891  	// Border width.
  1892  	if obj := d.Get("W"); obj != nil {
  1893  		val, err := getNumberAsFloat(obj)
  1894  		if err != nil {
  1895  			common.Log.Debug("Error retrieving W: %v", err)
  1896  			return nil, err
  1897  		}
  1898  		bs.W = &val
  1899  	}
  1900  
  1901  	// Border style.
  1902  	if obj := d.Get("S"); obj != nil {
  1903  		name, ok := obj.(*PdfObjectName)
  1904  		if !ok {
  1905  			return nil, errors.New("Border S not a name object")
  1906  		}
  1907  
  1908  		var style BorderStyle
  1909  		switch *name {
  1910  		case "S":
  1911  			style = BorderStyleSolid
  1912  		case "D":
  1913  			style = BorderStyleDashed
  1914  		case "B":
  1915  			style = BorderStyleBeveled
  1916  		case "I":
  1917  			style = BorderStyleInset
  1918  		case "U":
  1919  			style = BorderStyleUnderline
  1920  		default:
  1921  			common.Log.Debug("Invalid style name %s", *name)
  1922  			return nil, errors.New("Style type range check")
  1923  		}
  1924  
  1925  		bs.S = &style
  1926  	}
  1927  
  1928  	// Dash array.
  1929  	if obj := d.Get("D"); obj != nil {
  1930  		vec, ok := obj.(*PdfObjectArray)
  1931  		if !ok {
  1932  			common.Log.Debug("Border D dash not an array: %T", obj)
  1933  			return nil, errors.New("Border D type check error")
  1934  		}
  1935  
  1936  		vals, err := vec.ToIntegerArray()
  1937  		if err != nil {
  1938  			common.Log.Debug("Border D Problem converting to integer array: %v", err)
  1939  			return nil, err
  1940  		}
  1941  
  1942  		bs.D = &vals
  1943  	}
  1944  
  1945  	return bs, nil
  1946  }
  1947  
  1948  func (this *PdfBorderStyle) ToPdfObject() PdfObject {
  1949  	d := MakeDict()
  1950  	if this.container != nil {
  1951  		if indObj, is := this.container.(*PdfIndirectObject); is {
  1952  			indObj.PdfObject = d
  1953  		}
  1954  	}
  1955  
  1956  	d.Set("Subtype", MakeName("Border"))
  1957  	if this.W != nil {
  1958  		d.Set("W", MakeFloat(*this.W))
  1959  	}
  1960  	if this.S != nil {
  1961  		d.Set("S", MakeName(this.S.GetPdfName()))
  1962  	}
  1963  	if this.D != nil {
  1964  		d.Set("D", MakeArrayFromIntegers(*this.D))
  1965  	}
  1966  
  1967  	if this.container != nil {
  1968  		return this.container
  1969  	} else {
  1970  		return d
  1971  	}
  1972  }
  1973  
  1974  // Border effect
  1975  type BorderEffect int
  1976  
  1977  const (
  1978  	BorderEffectNoEffect BorderEffect = iota
  1979  	BorderEffectCloudy   BorderEffect = iota
  1980  )
  1981  
  1982  type PdfBorderEffect struct {
  1983  	S *BorderEffect // Border effect type
  1984  	I *float64      // Intensity of the effect
  1985  }