diff --git a/pdf/annotator/annotator.go b/pdf/annotator/annotator.go index ea429539..a990d333 100644 --- a/pdf/annotator/annotator.go +++ b/pdf/annotator/annotator.go @@ -10,171 +10,8 @@ import ( pdf "github.com/unidoc/unidoc/pdf/model" ) -// The currently supported line ending styles are None, Arrow (ClosedArrow) and Butt. -type LineEndingStyle int -const ( - LineEndingStyleNone LineEndingStyle = 0 - LineEndingStyleArrow LineEndingStyle = 1 - LineEndingStyleButt LineEndingStyle = 2 -) -// Defines a line between point 1 (X1,Y1) and point 2 (X2,Y2). The line ending styles can be none (regular line), -// or arrows at either end. The line also has a specified width, color and opacity. -type LineAnnotationDef struct { - X1 float64 - Y1 float64 - X2 float64 - Y2 float64 - LineColor *pdf.PdfColorDeviceRGB - Opacity float64 // Alpha value (0-1). - LineWidth float64 - LineEndingStyle1 LineEndingStyle // Line ending style of point 1. - LineEndingStyle2 LineEndingStyle // Line ending style of point 2. -} -// Creates a line annotation object that can be added to page PDF annotations. -func CreateLineAnnotation(lineDef LineAnnotationDef) (*pdf.PdfAnnotation, error) { - // Line annotation. - lineAnnotation := pdf.NewPdfAnnotationLine() - // Line endpoint locations. - lineAnnotation.L = pdfcore.MakeArrayFromFloats([]float64{lineDef.X1, lineDef.Y1, lineDef.X2, lineDef.Y2}) - // Line endings. - le1 := pdfcore.MakeName("None") - if lineDef.LineEndingStyle1 == LineEndingStyleArrow { - le1 = pdfcore.MakeName("ClosedArrow") - } - le2 := pdfcore.MakeName("None") - if lineDef.LineEndingStyle2 == LineEndingStyleArrow { - le2 = pdfcore.MakeName("ClosedArrow") - } - lineAnnotation.LE = pdfcore.MakeArray(le1, le2) - - // Opacity. - if lineDef.Opacity < 1.0 { - lineAnnotation.CA = pdfcore.MakeFloat(lineDef.Opacity) - } - - r, g, b := lineDef.LineColor.R(), lineDef.LineColor.G(), lineDef.LineColor.B() - lineAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // fill color of line endings, rgb 0-1. - lineAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // line color, rgb 0-1. - bs := pdf.NewBorderStyle() - bs.SetBorderWidth(lineDef.LineWidth) // Line width: 3 points. - lineAnnotation.BS = bs.ToPdfObject() - - // Make the appearance stream (for uniform appearance). - apDict, bbox, err := makeLineAnnotationAppearanceStream(lineDef) - if err != nil { - return nil, err - } - lineAnnotation.AP = apDict - - // The rect specifies the location and dimensions of the annotation. Technically if the annotation could not - // be displayed if it goes outside these bounds, although rarely enforced. - lineAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury}) - - return lineAnnotation.PdfAnnotation, nil -} - -// A rectangle defined with a specified Width and Height and a lower left corner at (X,Y). The rectangle can -// optionally have a border and a filling color. -// The Width/Height includes the border (if any specified). -type RectangleAnnotationDef struct { - X float64 - Y float64 - Width float64 - Height float64 - FillEnabled bool // Show fill? - FillColor *pdf.PdfColorDeviceRGB - BorderEnabled bool // Show border? - BorderWidth float64 - BorderColor *pdf.PdfColorDeviceRGB - Opacity float64 // Alpha value (0-1). -} - -// Creates a rectangle annotation object that can be added to page PDF annotations. -func CreateRectangleAnnotation(rectDef RectangleAnnotationDef) (*pdf.PdfAnnotation, error) { - rectAnnotation := pdf.NewPdfAnnotationSquare() - - if rectDef.BorderEnabled { - r, g, b := rectDef.BorderColor.R(), rectDef.BorderColor.G(), rectDef.BorderColor.B() - rectAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) - bs := pdf.NewBorderStyle() - bs.SetBorderWidth(rectDef.BorderWidth) - rectAnnotation.BS = bs.ToPdfObject() - } - - if rectDef.FillEnabled { - r, g, b := rectDef.FillColor.R(), rectDef.FillColor.G(), rectDef.FillColor.B() - rectAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) - } else { - rectAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill. - } - - if rectDef.Opacity < 1.0 { - rectAnnotation.CA = pdfcore.MakeFloat(rectDef.Opacity) - } - - // Make the appearance stream (for uniform appearance). - apDict, bbox, err := makeRectangleAnnotationAppearanceStream(rectDef) - if err != nil { - return nil, err - } - - rectAnnotation.AP = apDict - rectAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury}) - - return rectAnnotation.PdfAnnotation, nil - -} - -type CircleAnnotationDef struct { - X float64 - Y float64 - Width float64 - Height float64 - FillEnabled bool // Show fill? - FillColor *pdf.PdfColorDeviceRGB - BorderEnabled bool // Show border? - BorderWidth float64 - BorderColor *pdf.PdfColorDeviceRGB - Opacity float64 // Alpha value (0-1). -} - -// Creates a circle/ellipse annotation object with appearance stream that can be added to page PDF annotations. -func CreateCircleAnnotation(circDef CircleAnnotationDef) (*pdf.PdfAnnotation, error) { - circAnnotation := pdf.NewPdfAnnotationCircle() - - if circDef.BorderEnabled { - r, g, b := circDef.BorderColor.R(), circDef.BorderColor.G(), circDef.BorderColor.B() - circAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) - bs := pdf.NewBorderStyle() - bs.SetBorderWidth(circDef.BorderWidth) - circAnnotation.BS = bs.ToPdfObject() - } - - if circDef.FillEnabled { - r, g, b := circDef.FillColor.R(), circDef.FillColor.G(), circDef.FillColor.B() - circAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) - } else { - circAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill. - } - - if circDef.Opacity < 1.0 { - circAnnotation.CA = pdfcore.MakeFloat(circDef.Opacity) - } - - // Make the appearance stream (for uniform appearance). - apDict, bbox, err := makeCircleAnnotationAppearanceStream(circDef) - if err != nil { - return nil, err - } - - circAnnotation.AP = apDict - circAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury}) - - return circAnnotation.PdfAnnotation, nil - -} diff --git a/pdf/annotator/circle.go b/pdf/annotator/circle.go index 53863311..643c71d8 100644 --- a/pdf/annotator/circle.go +++ b/pdf/annotator/circle.go @@ -14,14 +14,53 @@ import ( pdf "github.com/unidoc/unidoc/pdf/model" ) -// Make the bezier path with the content creator. -func drawBezierPathWithCreator(bpath draw.CubicBezierPath, creator *pdfcontent.ContentCreator) { - for idx, c := range bpath.Curves { - if idx == 0 { - creator.Add_m(c.P0.X, c.P0.Y) - } - creator.Add_c(c.P1.X, c.P1.Y, c.P2.X, c.P2.Y, c.P3.X, c.P3.Y) +type CircleAnnotationDef struct { + X float64 + Y float64 + Width float64 + Height float64 + FillEnabled bool // Show fill? + FillColor *pdf.PdfColorDeviceRGB + BorderEnabled bool // Show border? + BorderWidth float64 + BorderColor *pdf.PdfColorDeviceRGB + Opacity float64 // Alpha value (0-1). +} + +// Creates a circle/ellipse annotation object with appearance stream that can be added to page PDF annotations. +func CreateCircleAnnotation(circDef CircleAnnotationDef) (*pdf.PdfAnnotation, error) { + circAnnotation := pdf.NewPdfAnnotationCircle() + + if circDef.BorderEnabled { + r, g, b := circDef.BorderColor.R(), circDef.BorderColor.G(), circDef.BorderColor.B() + circAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) + bs := pdf.NewBorderStyle() + bs.SetBorderWidth(circDef.BorderWidth) + circAnnotation.BS = bs.ToPdfObject() } + + if circDef.FillEnabled { + r, g, b := circDef.FillColor.R(), circDef.FillColor.G(), circDef.FillColor.B() + circAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) + } else { + circAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill. + } + + if circDef.Opacity < 1.0 { + circAnnotation.CA = pdfcore.MakeFloat(circDef.Opacity) + } + + // Make the appearance stream (for uniform appearance). + apDict, bbox, err := makeCircleAnnotationAppearanceStream(circDef) + if err != nil { + return nil, err + } + + circAnnotation.AP = apDict + circAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury}) + + return circAnnotation.PdfAnnotation, nil + } func makeCircleAnnotationAppearanceStream(circDef CircleAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) { diff --git a/pdf/annotator/line.go b/pdf/annotator/line.go index fc9a9b77..5605637e 100644 --- a/pdf/annotator/line.go +++ b/pdf/annotator/line.go @@ -15,15 +15,72 @@ import ( pdf "github.com/unidoc/unidoc/pdf/model" ) -// Make the path with the content creator. -func drawPathWithCreator(path draw.Path, creator *pdfcontent.ContentCreator) { - for idx, p := range path.Points { - if idx == 0 { - creator.Add_m(p.X, p.Y) - } else { - creator.Add_l(p.X, p.Y) - } +// The currently supported line ending styles are None, Arrow (ClosedArrow) and Butt. +type LineEndingStyle int + +const ( + LineEndingStyleNone LineEndingStyle = 0 + LineEndingStyleArrow LineEndingStyle = 1 + LineEndingStyleButt LineEndingStyle = 2 +) + +// Defines a line between point 1 (X1,Y1) and point 2 (X2,Y2). The line ending styles can be none (regular line), +// or arrows at either end. The line also has a specified width, color and opacity. +type LineAnnotationDef struct { + X1 float64 + Y1 float64 + X2 float64 + Y2 float64 + LineColor *pdf.PdfColorDeviceRGB + Opacity float64 // Alpha value (0-1). + LineWidth float64 + LineEndingStyle1 LineEndingStyle // Line ending style of point 1. + LineEndingStyle2 LineEndingStyle // Line ending style of point 2. +} + +// Creates a line annotation object that can be added to page PDF annotations. +func CreateLineAnnotation(lineDef LineAnnotationDef) (*pdf.PdfAnnotation, error) { + // Line annotation. + lineAnnotation := pdf.NewPdfAnnotationLine() + + // Line endpoint locations. + lineAnnotation.L = pdfcore.MakeArrayFromFloats([]float64{lineDef.X1, lineDef.Y1, lineDef.X2, lineDef.Y2}) + + // Line endings. + le1 := pdfcore.MakeName("None") + if lineDef.LineEndingStyle1 == LineEndingStyleArrow { + le1 = pdfcore.MakeName("ClosedArrow") } + le2 := pdfcore.MakeName("None") + if lineDef.LineEndingStyle2 == LineEndingStyleArrow { + le2 = pdfcore.MakeName("ClosedArrow") + } + lineAnnotation.LE = pdfcore.MakeArray(le1, le2) + + // Opacity. + if lineDef.Opacity < 1.0 { + lineAnnotation.CA = pdfcore.MakeFloat(lineDef.Opacity) + } + + r, g, b := lineDef.LineColor.R(), lineDef.LineColor.G(), lineDef.LineColor.B() + lineAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // fill color of line endings, rgb 0-1. + lineAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // line color, rgb 0-1. + bs := pdf.NewBorderStyle() + bs.SetBorderWidth(lineDef.LineWidth) // Line width: 3 points. + lineAnnotation.BS = bs.ToPdfObject() + + // Make the appearance stream (for uniform appearance). + apDict, bbox, err := makeLineAnnotationAppearanceStream(lineDef) + if err != nil { + return nil, err + } + lineAnnotation.AP = apDict + + // The rect specifies the location and dimensions of the annotation. Technically if the annotation could not + // be displayed if it goes outside these bounds, although rarely enforced. + lineAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury}) + + return lineAnnotation.PdfAnnotation, nil } func makeLineAnnotationAppearanceStream(lineDef LineAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) { diff --git a/pdf/annotator/rectangle.go b/pdf/annotator/rectangle.go index e7aee4f2..0c4b5bb0 100644 --- a/pdf/annotator/rectangle.go +++ b/pdf/annotator/rectangle.go @@ -14,6 +14,58 @@ import ( pdf "github.com/unidoc/unidoc/pdf/model" ) +// A rectangle defined with a specified Width and Height and a lower left corner at (X,Y). The rectangle can +// optionally have a border and a filling color. +// The Width/Height includes the border (if any specified). +type RectangleAnnotationDef struct { + X float64 + Y float64 + Width float64 + Height float64 + FillEnabled bool // Show fill? + FillColor *pdf.PdfColorDeviceRGB + BorderEnabled bool // Show border? + BorderWidth float64 + BorderColor *pdf.PdfColorDeviceRGB + Opacity float64 // Alpha value (0-1). +} + +// Creates a rectangle annotation object that can be added to page PDF annotations. +func CreateRectangleAnnotation(rectDef RectangleAnnotationDef) (*pdf.PdfAnnotation, error) { + rectAnnotation := pdf.NewPdfAnnotationSquare() + + if rectDef.BorderEnabled { + r, g, b := rectDef.BorderColor.R(), rectDef.BorderColor.G(), rectDef.BorderColor.B() + rectAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) + bs := pdf.NewBorderStyle() + bs.SetBorderWidth(rectDef.BorderWidth) + rectAnnotation.BS = bs.ToPdfObject() + } + + if rectDef.FillEnabled { + r, g, b := rectDef.FillColor.R(), rectDef.FillColor.G(), rectDef.FillColor.B() + rectAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) + } else { + rectAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill. + } + + if rectDef.Opacity < 1.0 { + rectAnnotation.CA = pdfcore.MakeFloat(rectDef.Opacity) + } + + // Make the appearance stream (for uniform appearance). + apDict, bbox, err := makeRectangleAnnotationAppearanceStream(rectDef) + if err != nil { + return nil, err + } + + rectAnnotation.AP = apDict + rectAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury}) + + return rectAnnotation.PdfAnnotation, nil + +} + func makeRectangleAnnotationAppearanceStream(rectDef RectangleAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) { form := pdf.NewXObjectForm() form.Resources = pdf.NewPdfPageResources() diff --git a/pdf/annotator/utils.go b/pdf/annotator/utils.go new file mode 100644 index 00000000..106764f8 --- /dev/null +++ b/pdf/annotator/utils.go @@ -0,0 +1,27 @@ +package annotator + +import ( + pdfcontent "github.com/unidoc/unidoc/pdf/contentstream" + "github.com/unidoc/unidoc/pdf/contentstream/draw" +) + +// Make the path with the content creator. +func drawPathWithCreator(path draw.Path, creator *pdfcontent.ContentCreator) { + for idx, p := range path.Points { + if idx == 0 { + creator.Add_m(p.X, p.Y) + } else { + creator.Add_l(p.X, p.Y) + } + } +} + +// Make the bezier path with the content creator. +func drawBezierPathWithCreator(bpath draw.CubicBezierPath, creator *pdfcontent.ContentCreator) { + for idx, c := range bpath.Curves { + if idx == 0 { + creator.Add_m(c.P0.X, c.P0.Y) + } + creator.Add_c(c.P1.X, c.P1.Y, c.P2.X, c.P2.Y, c.P3.X, c.P3.Y) + } +} diff --git a/pdf/contentstream/creator.go b/pdf/contentstream/creator.go index c237bea0..dea02c8c 100644 --- a/pdf/contentstream/creator.go +++ b/pdf/contentstream/creator.go @@ -414,7 +414,6 @@ func (this *ContentCreator) Add_k(c, m, y, k float64) *ContentCreator { /* Shading operators. */ -// sh: Paint the shape and color described by a shading dictionary. func (this *ContentCreator) Add_sh(name PdfObjectName) *ContentCreator { op := ContentStreamOperation{} op.Operand = "sh" @@ -422,3 +421,163 @@ func (this *ContentCreator) Add_sh(name PdfObjectName) *ContentCreator { this.operands = append(this.operands, &op) return this } + +/* Text related operators */ + +/* Text state operators */ + +// BT: Begin text. +func (this *ContentCreator) Add_BT() *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "BT" + this.operands = append(this.operands, &op) + return this +} + +// ET: End text. +func (this *ContentCreator) Add_ET() *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "ET" + this.operands = append(this.operands, &op) + return this +} + +// Tc: Set character spacing. +func (this *ContentCreator) Add_Tc(charSpace float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tc" + op.Params = makeParamsFromFloats([]float64{charSpace}) + this.operands = append(this.operands, &op) + return this +} + +// Tw: Set word spacing. +func (this *ContentCreator) Add_Tw(wordSpace float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tw" + op.Params = makeParamsFromFloats([]float64{wordSpace}) + this.operands = append(this.operands, &op) + return this +} + +// Tz: Set horizontal scaling. +func (this *ContentCreator) Add_Tz(scale float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tz" + op.Params = makeParamsFromFloats([]float64{scale}) + this.operands = append(this.operands, &op) + return this +} + +// TL: Set leading. +func (this *ContentCreator) Add_Tl(leading float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tl" + op.Params = makeParamsFromFloats([]float64{leading}) + this.operands = append(this.operands, &op) + return this +} + +// Tf: Set font and font size. +func (this *ContentCreator) Add_Tf(fontName PdfObjectName, fontSize float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tf" + op.Params = makeParamsFromNames([]PdfObjectName{fontName}) + op.Params = append(op.Params, makeParamsFromFloats([]float64{fontSize})...) + this.operands = append(this.operands, &op) + return this +} + +// Tr: Set text rendering mode. +func (this *ContentCreator) Add_Tr(render int64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tr" + op.Params = makeParamsFromInts([]int64{render}) + this.operands = append(this.operands, &op) + return this +} + +// Ts: Set text rise. +func (this *ContentCreator) Add_Ts(rise float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Ts" + op.Params = makeParamsFromFloats([]float64{rise}) + this.operands = append(this.operands, &op) + return this +} + +/* Text positioning operators. */ + +// Td: Move to start of next line with offset (tx, ty). +func (this *ContentCreator) Add_Td(tx, ty float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Td" + op.Params = makeParamsFromFloats([]float64{tx, ty}) + this.operands = append(this.operands, &op) + return this +} + +// TD: Move to start of next line with offset (tx, ty). +func (this *ContentCreator) Add_TD(tx, ty float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "TD" + op.Params = makeParamsFromFloats([]float64{tx, ty}) + this.operands = append(this.operands, &op) + return this +} + +// Tm: Set the text line matrix. +func (this *ContentCreator) Add_Tm(a, b, c, d, e, f float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tm" + op.Params = makeParamsFromFloats([]float64{a, b, c, d, e, f}) + this.operands = append(this.operands, &op) + return this +} + +// T*: Move to the start of next line. +func (this *ContentCreator) Add_Tstar() *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "T*" + this.operands = append(this.operands, &op) + return this +} + +/* Text showing operators */ + +// Tj: Show a text string. +func (this *ContentCreator) Add_Tj(textstr PdfObjectString) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "Tj" + op.Params = makeParamsFromStrings([]PdfObjectString{textstr}) + this.operands = append(this.operands, &op) + return this +} + +// ': Move to next line and show a string. +func (this *ContentCreator) Add_quote(textstr PdfObjectString) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "'" + op.Params = makeParamsFromStrings([]PdfObjectString{textstr}) + this.operands = append(this.operands, &op) + return this +} + +// '': Move to next line and show a string, using aw and ac as word and character spacing respectively. +func (this *ContentCreator) Add_quotes(textstr PdfObjectString, aw, ac float64) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "''" + op.Params = makeParamsFromFloats([]float64{aw, ac}) + op.Params = append(op.Params, makeParamsFromStrings([]PdfObjectString{textstr})...) + this.operands = append(this.operands, &op) + return this +} + +// TJ. Show one or more text string. Array of numbers (displacement) and strings. +func (this *ContentCreator) Add_TJ(vals ...PdfObject) *ContentCreator { + op := ContentStreamOperation{} + op.Operand = "TJ" + op.Params = vals + this.operands = append(this.operands, &op) + return this +} diff --git a/pdf/contentstream/utils.go b/pdf/contentstream/utils.go index ff920e30..b1125d8d 100644 --- a/pdf/contentstream/utils.go +++ b/pdf/contentstream/utils.go @@ -23,6 +23,14 @@ func makeParamsFromNames(vals []PdfObjectName) []PdfObject { return params } +func makeParamsFromStrings(vals []PdfObjectString) []PdfObject { + params := []PdfObject{} + for _, val := range vals { + params = append(params, MakeString(string(val))) + } + return params +} + func makeParamsFromInts(vals []int64) []PdfObject { params := []PdfObject{} for _, val := range vals { diff --git a/pdf/model/page.go b/pdf/model/page.go index 76d18df6..5c1ca3f9 100644 --- a/pdf/model/page.go +++ b/pdf/model/page.go @@ -554,6 +554,26 @@ func (this *PdfPage) HasImageResource(name PdfObjectName) bool { } else { return false } + +} + +// Check if has font resource by name. +func (this *PdfPage) HasFontByName(name PdfObjectName) bool { + resources, err := this.GetResources() + if err != nil { + return false + } + + fontDict, has := resources.Font.(*PdfObjectDictionary) + if !has { + return false + } + + if _, has := (*fontDict)[name]; has { + return true + } else { + return false + } } // Add a graphics state to the XObject resources. diff --git a/pdf/model/resources.go b/pdf/model/resources.go index cc479f53..260229eb 100644 --- a/pdf/model/resources.go +++ b/pdf/model/resources.go @@ -15,8 +15,7 @@ import ( // Page resources model. // Implements PdfModel. type PdfPageResources struct { - ExtGState PdfObject - //ColorSpace PdfObject + ExtGState PdfObject ColorSpace *PdfPageResourcesColorspaces Pattern PdfObject Shading PdfObject