1 Star 0 Fork 0

coodder / unipdf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
form_field.go 8.52 KB
一键复制 编辑 原始数据 按行查看 历史
jhonm 提交于 2023-08-07 22:37 . 签章优化
package annotator
import (
"bytes"
"errors"
"image"
"gitee.com/coodder/unipdf/contentstream"
"gitee.com/coodder/unipdf/core"
"gitee.com/coodder/unipdf/model"
)
// TextFieldOptions defines optional parameter for a text field in a form.
type TextFieldOptions struct {
MaxLen int // Ignored if <= 0.
Value string // Ignored if empty ("").
}
// NewTextField generates a new text field with partial name `name` at location
// specified by `rect` on given `page` and with field specific options `opt`.
func NewTextField(page *model.PdfPage, name string, rect []float64, opt TextFieldOptions) (*model.PdfFieldText, error) {
if page == nil {
return nil, errors.New("page not specified")
}
if len(name) <= 0 {
return nil, errors.New("required attribute not specified")
}
if len(rect) != 4 {
return nil, errors.New("invalid range")
}
field := model.NewPdfField()
textfield := &model.PdfFieldText{}
field.SetContext(textfield)
textfield.PdfField = field
textfield.T = core.MakeString(name)
if opt.MaxLen > 0 {
textfield.MaxLen = core.MakeInteger(int64(opt.MaxLen))
}
if len(opt.Value) > 0 {
textfield.V = core.MakeString(opt.Value)
}
widget := model.NewPdfAnnotationWidget()
widget.Rect = core.MakeArrayFromFloats(rect) //[]float64{144.0, 595.89, 294.0, 617.9})
widget.P = page.ToPdfObject()
widget.F = core.MakeInteger(4) // 4 (100 -> Print/show annotations).
widget.Parent = textfield.ToPdfObject()
textfield.Annotations = append(textfield.Annotations, widget)
return textfield, nil
}
// CheckboxFieldOptions defines optional parameters for a checkbox field a form.
type CheckboxFieldOptions struct {
Checked bool
}
// NewCheckboxField generates a new checkbox field with partial name `name` at location `rect`
// on specified `page` and with field specific options `opt`.
func NewCheckboxField(page *model.PdfPage, name string, rect []float64, opt CheckboxFieldOptions) (*model.PdfFieldButton, error) {
if page == nil {
return nil, errors.New("page not specified")
}
if len(name) <= 0 {
return nil, errors.New("required attribute not specified")
}
if len(rect) != 4 {
return nil, errors.New("invalid range")
}
zapfdb, err := model.NewStandard14Font(model.ZapfDingbatsName)
if err != nil {
return nil, err
}
field := model.NewPdfField()
buttonfield := &model.PdfFieldButton{}
field.SetContext(buttonfield)
buttonfield.PdfField = field
buttonfield.T = core.MakeString(name)
buttonfield.SetType(model.ButtonTypeCheckbox)
state := "Off"
if opt.Checked {
state = "Yes"
}
buttonfield.V = core.MakeName(state)
widget := model.NewPdfAnnotationWidget()
widget.Rect = core.MakeArrayFromFloats(rect)
widget.P = page.ToPdfObject()
widget.F = core.MakeInteger(4)
widget.Parent = buttonfield.ToPdfObject()
w := rect[2] - rect[0]
h := rect[3] - rect[1]
// Off state.
var cs bytes.Buffer
cs.WriteString("q\n")
cs.WriteString("0 0 1 rg\n")
cs.WriteString("BT\n")
cs.WriteString("/ZaDb 12 Tf\n")
cs.WriteString("ET\n")
cs.WriteString("Q\n")
cc := contentstream.NewContentCreator()
cc.Add_q()
cc.Add_rg(0, 0, 1)
cc.Add_BT()
cc.Add_Tf(*core.MakeName("ZaDb"), 12)
cc.Add_Td(0, 0)
cc.Add_ET()
cc.Add_Q()
xformOff := model.NewXObjectForm()
xformOff.SetContentStream(cc.Bytes(), core.NewRawEncoder())
xformOff.BBox = core.MakeArrayFromFloats([]float64{0, 0, w, h})
xformOff.Resources = model.NewPdfPageResources()
xformOff.Resources.SetFontByName("ZaDb", zapfdb.ToPdfObject())
// On state (Yes).
cc = contentstream.NewContentCreator()
cc.Add_q()
cc.Add_re(0, 0, w, h)
cc.Add_W().Add_n()
cc.Add_rg(0, 0, 1)
cc.Translate(0, 3.0)
cc.Add_BT()
cc.Add_Tf(*core.MakeName("ZaDb"), 12)
cc.Add_Td(0, 0)
cc.Add_Tj(*core.MakeString("\064"))
cc.Add_ET()
cc.Add_Q()
xformOn := model.NewXObjectForm()
xformOn.SetContentStream(cc.Bytes(), core.NewRawEncoder())
xformOn.BBox = core.MakeArrayFromFloats([]float64{0, 0, w, h})
xformOn.Resources = model.NewPdfPageResources()
xformOn.Resources.SetFontByName("ZaDb", zapfdb.ToPdfObject())
dchoiceapp := core.MakeDict()
dchoiceapp.Set("Off", xformOff.ToPdfObject())
dchoiceapp.Set("Yes", xformOn.ToPdfObject())
appearance := core.MakeDict()
appearance.Set("N", dchoiceapp)
widget.AP = appearance
widget.AS = core.MakeName(state)
buttonfield.Annotations = append(buttonfield.Annotations, widget)
return buttonfield, nil
}
// ComboboxFieldOptions defines optional parameters for a combobox form field.
type ComboboxFieldOptions struct {
// Choices is the list of string values that can be selected.
Choices []string
}
// NewComboboxField generates a new combobox form field with partial name `name` at location `rect`
// on specified `page` and with field specific options `opt`.
func NewComboboxField(page *model.PdfPage, name string, rect []float64, opt ComboboxFieldOptions) (*model.PdfFieldChoice, error) {
if page == nil {
return nil, errors.New("page not specified")
}
if len(name) <= 0 {
return nil, errors.New("required attribute not specified")
}
if len(rect) != 4 {
return nil, errors.New("invalid range")
}
field := model.NewPdfField()
chfield := &model.PdfFieldChoice{}
field.SetContext(chfield)
chfield.PdfField = field
chfield.T = core.MakeString(name)
chfield.Opt = core.MakeArray()
for _, choicestr := range opt.Choices {
chfield.Opt.Append(core.MakeString(choicestr))
}
chfield.SetFlag(model.FieldFlagCombo)
widget := model.NewPdfAnnotationWidget()
widget.Rect = core.MakeArrayFromFloats(rect)
widget.P = page.ToPdfObject()
widget.F = core.MakeInteger(4) // TODO: Make flags for these values and a way to set.
widget.Parent = chfield.ToPdfObject()
chfield.Annotations = append(chfield.Annotations, widget)
return chfield, nil
}
// SignatureLine represents a line of information in the signature field appearance.
type SignatureLine struct {
Desc string
Text string
}
// NewSignatureLine returns a new signature line displayed as a part of the
// signature field appearance.
func NewSignatureLine(desc, text string) *SignatureLine {
return &SignatureLine{
Desc: desc,
Text: text,
}
}
// SignatureFieldOpts represents a set of options used to configure
// an appearance widget dictionary.
type SignatureFieldOpts struct {
// Rect represents the area the signature annotation is displayed on.
Rect []float64
// AutoSize specifies if the content of the appearance should be
// scaled to fit in the annotation rectangle.
AutoSize bool
// Font specifies the font of the text content.
Font *model.PdfFont
// FontSize specifies the size of the text content.
FontSize float64
// LineHeight specifies the height of a line of text in the appearance annotation.
LineHeight float64
// TextColor represents the color of the text content displayed.
TextColor model.PdfColor
// FillColor represents the background color of the appearance annotation area.
FillColor model.PdfColor
// BorderSize represents border size of the appearance annotation area.
BorderSize float64
// BorderColor represents the border color of the appearance annotation area.
BorderColor model.PdfColor
// WatermarkImage specifies the image used as a watermark that will be rendered
// behind the signature.
WatermarkImage image.Image
// Image represents the image used for the signature appearance.
Image image.Image
// Encoder specifies the image encoder used for image signature. Defaults to flate encoder.
Encoder core.StreamEncoder
// ImagePosition specifies the image location relative to the text signature.
ImagePosition SignatureImagePosition
}
// NewSignatureFieldOpts returns a new initialized instance of options
// used to generate a signature appearance.
func NewSignatureFieldOpts() *SignatureFieldOpts {
return &SignatureFieldOpts{
Font: model.DefaultFont(),
FontSize: 10,
LineHeight: 1,
AutoSize: true,
TextColor: model.NewPdfColorDeviceGray(0),
BorderColor: model.NewPdfColorDeviceGray(0),
FillColor: model.NewPdfColorDeviceGray(1),
Encoder: core.NewFlateEncoder(),
ImagePosition: SignatureImageLeft,
}
}
// NewSignatureField returns a new signature field with a visible appearance
// containing the specified signature lines and styled according to the
// specified options.
func NewSignatureField(signature *model.PdfSignature, lines []*SignatureLine, opts *SignatureFieldOpts) (*model.PdfFieldSignature, error) {
if signature == nil {
return nil, errors.New("signature cannot be nil")
}
apDict, err := genFieldSignatureAppearance(lines, opts)
if err != nil {
return nil, err
}
field := model.NewPdfFieldSignature(signature)
field.Rect = core.MakeArrayFromFloats(opts.Rect)
field.AP = apDict
return field, nil
}
Go
1
https://gitee.com/coodder/unipdf.git
git@gitee.com:coodder/unipdf.git
coodder
unipdf
unipdf
v1.2.0

搜索帮助

53164aa7 5694891 3bd8fe86 5694891