2016-09-08 17:53:45 +00:00
|
|
|
/*
|
|
|
|
* This file is subject to the terms and conditions defined in
|
|
|
|
* file 'LICENSE.md', which is part of this source code package.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
2019-05-16 23:44:51 +03:00
|
|
|
"github.com/unidoc/unipdf/v3/core"
|
2016-09-08 17:53:45 +00:00
|
|
|
)
|
|
|
|
|
2018-08-02 00:29:47 +00:00
|
|
|
// PdfModel is a higher level PDF construct which can be collapsed into a PdfObject.
|
|
|
|
// Each PdfModel has an underlying PdfObject and vice versa (one-to-one).
|
|
|
|
// Under normal circumstances there should only be one copy of each.
|
|
|
|
// Copies can be made, but care must be taken to do it properly.
|
2016-09-08 17:53:45 +00:00
|
|
|
type PdfModel interface {
|
2018-08-02 00:29:47 +00:00
|
|
|
ToPdfObject() core.PdfObject
|
|
|
|
GetContainingPdfObject() core.PdfObject
|
2016-09-08 17:53:45 +00:00
|
|
|
}
|
|
|
|
|
2018-08-02 00:29:47 +00:00
|
|
|
// modelManager is used to cache primitive PdfObject <-> Model mappings where needed (one-to-one).
|
2018-07-14 03:15:54 +00:00
|
|
|
// In many cases only Model -> PdfObject mapping is needed and only a reference to the PdfObject
|
2018-08-02 00:29:47 +00:00
|
|
|
// is stored in the Model. In some cases, the Model needs to be found from the PdfObject,
|
2018-07-14 03:07:24 +00:00
|
|
|
// and that is where the modelManager can be used (in both directions).
|
2016-09-12 17:59:45 +00:00
|
|
|
//
|
2018-08-02 00:29:47 +00:00
|
|
|
// Note that it is not always used, the PdfObject <-> Model mapping needs to be registered
|
2016-09-12 17:59:45 +00:00
|
|
|
// for each time it is used. Thus, it is only used for special cases, commonly where the same
|
2018-08-02 00:29:47 +00:00
|
|
|
// object is used by two higher level objects. (Example PDF Widgets owned by both Page Annotations,
|
|
|
|
// and the interactive form - AcroForm).
|
2018-07-14 03:07:24 +00:00
|
|
|
type modelManager struct {
|
2018-08-02 00:29:47 +00:00
|
|
|
primitiveCache map[PdfModel]core.PdfObject
|
|
|
|
modelCache map[core.PdfObject]PdfModel
|
2016-09-08 17:53:45 +00:00
|
|
|
}
|
|
|
|
|
2018-08-02 00:29:47 +00:00
|
|
|
// newModelManager returns a new initialized modelManager.
|
2018-07-14 03:07:24 +00:00
|
|
|
func newModelManager() *modelManager {
|
|
|
|
mm := modelManager{}
|
2018-08-02 00:29:47 +00:00
|
|
|
mm.primitiveCache = map[PdfModel]core.PdfObject{}
|
|
|
|
mm.modelCache = map[core.PdfObject]PdfModel{}
|
2016-09-08 17:53:45 +00:00
|
|
|
return &mm
|
|
|
|
}
|
|
|
|
|
2018-08-02 00:29:47 +00:00
|
|
|
// Register registers (caches) a model to primitive object relationship.
|
|
|
|
func (mm *modelManager) Register(primitive core.PdfObject, model PdfModel) {
|
2018-07-14 03:07:24 +00:00
|
|
|
mm.primitiveCache[model] = primitive
|
|
|
|
mm.modelCache[primitive] = model
|
2016-09-08 17:53:45 +00:00
|
|
|
}
|
|
|
|
|
2018-08-02 00:29:47 +00:00
|
|
|
// GetPrimitiveFromModel returns the primitive object corresponding to the input `model`.
|
|
|
|
func (mm *modelManager) GetPrimitiveFromModel(model PdfModel) core.PdfObject {
|
2018-07-14 03:07:24 +00:00
|
|
|
primitive, has := mm.primitiveCache[model]
|
2016-09-08 17:53:45 +00:00
|
|
|
if !has {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return primitive
|
|
|
|
}
|
|
|
|
|
2018-08-02 00:29:47 +00:00
|
|
|
// GetModelFromPrimitive returns the model corresponding to the `primitive` PdfObject.
|
|
|
|
func (mm *modelManager) GetModelFromPrimitive(primitive core.PdfObject) PdfModel {
|
2018-07-14 03:07:24 +00:00
|
|
|
model, has := mm.modelCache[primitive]
|
2016-09-08 17:53:45 +00:00
|
|
|
if !has {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return model
|
|
|
|
}
|