Improved functions to check and work with page resources. Page duplication enabled.

This commit is contained in:
Gunnsteinn Hall 2017-06-28 15:15:44 +00:00
parent 53b9e8b99c
commit 9a06eec2db
2 changed files with 141 additions and 19 deletions

View File

@ -75,6 +75,15 @@ func (this *PdfPage) setContainer(container *PdfIndirectObject) {
this.primitive = container
}
func (this *PdfPage) Duplicate() *PdfPage {
var dup PdfPage
dup = *this
dup.pageDict = &PdfObjectDictionary{}
dup.primitive = MakeIndirectObject(dup.pageDict)
return &dup
}
// Build a PdfPage based on the underlying dictionary.
// Used in loading existing PDF files.
// Note that a new container is created (indirect object).
@ -538,8 +547,8 @@ func (this *PdfPage) AddImageResource(name PdfObjectName, ximg *XObjectImage) er
return nil
}
// Check if has image resource by name.
func (this *PdfPage) HasImageResource(name PdfObjectName) bool {
// Check if has XObject resource by name.
func (this *PdfPage) HasXObjectByName(name PdfObjectName) bool {
resources, err := this.GetResources()
if err != nil {
return false
@ -555,7 +564,26 @@ func (this *PdfPage) HasImageResource(name PdfObjectName) bool {
} else {
return false
}
}
// Get XObject by name.
func (this *PdfPage) GetXObjectByName(name PdfObjectName) (PdfObject, bool) {
resources, err := this.GetResources()
if err != nil {
return nil, false
}
xresDict, has := resources.XObject.(*PdfObjectDictionary)
if !has {
return nil, false
}
if obj, has := (*xresDict)[name]; has {
return obj, true
} else {
return nil, false
}
}
// Check if has font resource by name.
@ -621,7 +649,7 @@ func (this *PdfPage) AddExtGState(name PdfObjectName, egs *PdfObjectDictionary)
}
// Add a font dictionary to the Font resources.
func (this *PdfPage) AddFont(name PdfObjectName, font *PdfObjectDictionary) error {
func (this *PdfPage) AddFont(name PdfObjectName, font PdfObject) error {
if this.Resources == nil {
this.Resources = NewPdfPageResources()
}
@ -671,10 +699,14 @@ func (this *PdfPage) AddWatermarkImage(ximg *XObjectImage, opt WatermarkImageOpt
yOffset = (pHeight - wHeight) / 2
}
if this.Resources == nil {
this.Resources = NewPdfPageResources()
}
// Find available image name for this page.
i := 0
imgName := PdfObjectName(fmt.Sprintf("Imw%d", i))
for this.HasImageResource(imgName) {
for this.Resources.HasXObjectByName(imgName) {
i++
imgName = PdfObjectName(fmt.Sprintf("Imw%d", i))
}
@ -847,6 +879,22 @@ type PdfPageResourcesColorspaces struct {
container *PdfIndirectObject
}
func NewPdfPageResourcesColorspaces() *PdfPageResourcesColorspaces {
colorspaces := &PdfPageResourcesColorspaces{}
colorspaces.Names = []string{}
colorspaces.Colorspaces = map[string]PdfColorspace{}
colorspaces.container = &PdfIndirectObject{}
return colorspaces
}
// Set the colorspace corresponding to key. Add to Names if not set.
func (this *PdfPageResourcesColorspaces) Set(key PdfObjectName, val PdfColorspace) {
if _, has := this.Colorspaces[string(key)]; !has {
this.Names = append(this.Names, string(key))
}
this.Colorspaces[string(key)] = val
}
func newPdfPageResourcesColorspacesFromPdfObject(obj PdfObject) (*PdfPageResourcesColorspaces, error) {
colorspaces := &PdfPageResourcesColorspaces{}

View File

@ -108,7 +108,7 @@ func (r *PdfPageResources) AddExtGState(gsName PdfObjectName, gsDict PdfObject)
// Get the shading specified by keyName. Returns nil if not existing. The bool flag indicated whether it was found
// or not.
func (r *PdfPageResources) GetShadingByName(keyName string) (*PdfShading, bool) {
func (r *PdfPageResources) GetShadingByName(keyName PdfObjectName) (*PdfShading, bool) {
if r.Shading == nil {
return nil, false
}
@ -132,7 +132,7 @@ func (r *PdfPageResources) GetShadingByName(keyName string) (*PdfShading, bool)
}
// Set a shading resource specified by keyName.
func (r *PdfPageResources) SetShadingByName(keyName string, shadingObj PdfObject) error {
func (r *PdfPageResources) SetShadingByName(keyName PdfObjectName, shadingObj PdfObject) error {
if r.Shading == nil {
r.Shading = &PdfObjectDictionary{}
}
@ -148,7 +148,7 @@ func (r *PdfPageResources) SetShadingByName(keyName string, shadingObj PdfObject
// Get the pattern specified by keyName. Returns nil if not existing. The bool flag indicated whether it was found
// or not.
func (r *PdfPageResources) GetPatternByName(keyName string) (*PdfPattern, bool) {
func (r *PdfPageResources) GetPatternByName(keyName PdfObjectName) (*PdfPattern, bool) {
if r.Pattern == nil {
return nil, false
}
@ -173,7 +173,7 @@ func (r *PdfPageResources) GetPatternByName(keyName string) (*PdfPattern, bool)
}
// Set a pattern resource specified by keyName.
func (r *PdfPageResources) SetPatternByName(keyName string, pattern PdfObject) error {
func (r *PdfPageResources) SetPatternByName(keyName PdfObjectName, pattern PdfObject) error {
if r.Pattern == nil {
r.Pattern = &PdfObjectDictionary{}
}
@ -183,12 +183,86 @@ func (r *PdfPageResources) SetPatternByName(keyName string, pattern PdfObject) e
return ErrTypeError
}
(*patternDict)[PdfObjectName(keyName)] = pattern
(*patternDict)[keyName] = pattern
return nil
}
// Get the font specified by keyName. Returns the PdfObject which the entry refers to.
// Returns a bool value indicating whether or not the entry was found.
func (r *PdfPageResources) GetFontByName(keyName PdfObjectName) (PdfObject, bool) {
if r.Font == nil {
return nil, false
}
fontDict, has := TraceToDirectObject(r.Font).(*PdfObjectDictionary)
if !has {
common.Log.Debug("ERROR: Font not a dictionary! (got %T)", TraceToDirectObject(r.Font))
return nil, false
}
if obj, has := (*fontDict)[keyName]; has {
return obj, true
} else {
return nil, false
}
}
// Check whether a font is defined by the specified keyName.
func (r *PdfPageResources) HasFontByName(keyName PdfObjectName) bool {
_, has := r.GetFontByName(keyName)
return has
}
// Set the font specified by keyName to the given object.
func (r *PdfPageResources) SetFontByName(keyName PdfObjectName, obj PdfObject) error {
if r.Font == nil {
// Create if not existing.
r.Font = &PdfObjectDictionary{}
}
fontDict, has := TraceToDirectObject(r.Font).(*PdfObjectDictionary)
if !has {
common.Log.Debug("ERROR: Font not a dictionary! (got %T)", TraceToDirectObject(r.Font))
return ErrTypeError
}
fontDict.Set(keyName, obj)
return nil
}
func (r *PdfPageResources) GetColorspaceByName(keyName PdfObjectName) (PdfColorspace, bool) {
if r.ColorSpace == nil {
return nil, false
}
cs, has := r.ColorSpace.Colorspaces[string(keyName)]
if !has {
return nil, false
}
return cs, true
}
func (r *PdfPageResources) HasColorspaceByName(keyName PdfObjectName) bool {
if r.ColorSpace == nil {
return false
}
_, has := r.ColorSpace.Colorspaces[string(keyName)]
return has
}
func (r *PdfPageResources) SetColorspaceByName(keyName PdfObjectName, cs PdfColorspace) error {
if r.ColorSpace == nil {
r.ColorSpace = NewPdfPageResourcesColorspaces()
}
r.ColorSpace.Set(keyName, cs)
return nil
}
// Check if an XObject with a specified keyName is defined.
func (r *PdfPageResources) HasXObjectByName(keyName string) bool {
func (r *PdfPageResources) HasXObjectByName(keyName PdfObjectName) bool {
obj, _ := r.GetXObjectByName(keyName)
if obj != nil {
return true
@ -208,7 +282,7 @@ const (
)
// Returns the XObject with the specified keyName and the object type.
func (r *PdfPageResources) GetXObjectByName(keyName string) (*PdfObjectStream, XObjectType) {
func (r *PdfPageResources) GetXObjectByName(keyName PdfObjectName) (*PdfObjectStream, XObjectType) {
if r.XObject == nil {
return nil, XObjectTypeUndefined
}
@ -219,7 +293,7 @@ func (r *PdfPageResources) GetXObjectByName(keyName string) (*PdfObjectStream, X
return nil, XObjectTypeUndefined
}
if obj, has := (*xresDict)[PdfObjectName(keyName)]; has {
if obj, has := (*xresDict)[keyName]; has {
stream, ok := obj.(*PdfObjectStream)
if !ok {
common.Log.Debug("XObject not pointing to a stream %T", obj)
@ -248,7 +322,7 @@ func (r *PdfPageResources) GetXObjectByName(keyName string) (*PdfObjectStream, X
}
}
func (r *PdfPageResources) setXObjectByName(keyName string, stream *PdfObjectStream) error {
func (r *PdfPageResources) SetXObjectByName(keyName PdfObjectName, stream *PdfObjectStream) error {
if r.XObject == nil {
r.XObject = &PdfObjectDictionary{}
}
@ -264,7 +338,7 @@ func (r *PdfPageResources) setXObjectByName(keyName string, stream *PdfObjectStr
return nil
}
func (r *PdfPageResources) GetXObjectImageByName(keyName string) (*XObjectImage, error) {
func (r *PdfPageResources) GetXObjectImageByName(keyName PdfObjectName) (*XObjectImage, error) {
stream, xtype := r.GetXObjectByName(keyName)
if stream == nil {
return nil, nil
@ -281,13 +355,13 @@ func (r *PdfPageResources) GetXObjectImageByName(keyName string) (*XObjectImage,
return ximg, nil
}
func (r *PdfPageResources) SetXObjectImageByName(keyName string, ximg *XObjectImage) error {
func (r *PdfPageResources) SetXObjectImageByName(keyName PdfObjectName, ximg *XObjectImage) error {
stream := ximg.ToPdfObject().(*PdfObjectStream)
err := r.setXObjectByName(keyName, stream)
err := r.SetXObjectByName(keyName, stream)
return err
}
func (r *PdfPageResources) GetXObjectFormByName(keyName string) (*XObjectForm, error) {
func (r *PdfPageResources) GetXObjectFormByName(keyName PdfObjectName) (*XObjectForm, error) {
stream, xtype := r.GetXObjectByName(keyName)
if stream == nil {
return nil, nil
@ -304,8 +378,8 @@ func (r *PdfPageResources) GetXObjectFormByName(keyName string) (*XObjectForm, e
return xform, nil
}
func (r *PdfPageResources) SetXObjectFormByName(keyName string, xform *XObjectForm) error {
func (r *PdfPageResources) SetXObjectFormByName(keyName PdfObjectName, xform *XObjectForm) error {
stream := xform.ToPdfObject().(*PdfObjectStream)
err := r.setXObjectByName(keyName, stream)
err := r.SetXObjectByName(keyName, stream)
return err
}