Ai
1 Star 0 Fork 1

gzlwz/golang-pdfcpu

forked from Deeao/golang-pdfcpu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
content.go 27.12 KB
一键复制 编辑 原始数据 按行查看 历史
liuweizhi 提交于 2024-12-10 16:33 +08:00 . fix: 全局替换module名称
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320
/*
Copyright 2021 The pdfcpu Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package primitives
import (
"gitee.com/gzlwz/golang-pdfcpu/pkg/pdfcpu/color"
"gitee.com/gzlwz/golang-pdfcpu/pkg/pdfcpu/draw"
"gitee.com/gzlwz/golang-pdfcpu/pkg/pdfcpu/model"
"gitee.com/gzlwz/golang-pdfcpu/pkg/pdfcpu/types"
"github.com/pkg/errors"
)
// Content represents page content.
type Content struct {
parent *Content
page *PDFPage
BackgroundColor string `json:"bgCol"`
bgCol *color.SimpleColor // page background color
Fonts map[string]*FormFont // named fonts
Margins map[string]*Margin // named margins
Borders map[string]*Border // named borders
Paddings map[string]*Padding // named paddings
Margin *Margin // content margin
Border *Border // content border
Padding *Padding // content padding
Regions *Regions
mediaBox *types.Rectangle
borderRect *types.Rectangle
box *types.Rectangle
Guides []*Guide // hor/vert guidelines for layout
Bars []*Bar `json:"bar"`
SimpleBoxes []*SimpleBox `json:"box"`
SimpleBoxPool map[string]*SimpleBox `json:"boxes"`
TextBoxes []*TextBox `json:"text"`
TextBoxPool map[string]*TextBox `json:"texts"`
ImageBoxes []*ImageBox `json:"image"`
ImageBoxPool map[string]*ImageBox `json:"images"`
Tables []*Table `json:"table"`
TablePool map[string]*Table `json:"tables"`
// Form elements
TextFields []*TextField `json:"textfield"` // input text fields with optional label
DateFields []*DateField `json:"datefield"` // input date fields with optional label
CheckBoxes []*CheckBox `json:"checkbox"` // input checkboxes with optional label
RadioButtonGroups []*RadioButtonGroup `json:"radiobuttongroup"` // input radiobutton groups with optional label
ComboBoxes []*ComboBox `json:"combobox"`
ListBoxes []*ListBox `json:"listbox"`
FieldGroups []*FieldGroup `json:"fieldgroup"` // rectangular container holding form elements
FieldGroupPool map[string]*FieldGroup `json:"fieldgroups"`
}
func (c *Content) validateBackgroundColor() error {
if c.BackgroundColor != "" {
sc, err := c.page.pdf.parseColor(c.BackgroundColor)
if err != nil {
return err
}
c.bgCol = sc
}
return nil
}
func (c *Content) validateBorders() error {
pdf := c.page.pdf
if c.Border != nil {
if len(c.Borders) > 0 {
return errors.New("pdfcpu: Please supply either content \"border\" or \"borders\"")
}
c.Border.pdf = pdf
if err := c.Border.validate(); err != nil {
return err
}
c.Borders = map[string]*Border{}
c.Borders["border"] = c.Border
}
for _, b := range c.Borders {
b.pdf = pdf
if err := b.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validateMargins() error {
if c.Margin != nil {
if len(c.Margins) > 0 {
return errors.New("pdfcpu: Please supply either page \"margin\" or \"margins\"")
}
if err := c.Margin.validate(); err != nil {
return err
}
c.Margins = map[string]*Margin{}
c.Margins["margin"] = c.Margin
}
for _, m := range c.Margins {
if err := m.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validatePaddings() error {
if c.Padding != nil {
if len(c.Paddings) > 0 {
return errors.New("pdfcpu: Please supply either page \"padding\" or \"paddings\"")
}
if err := c.Padding.validate(); err != nil {
return err
}
c.Paddings = map[string]*Padding{}
c.Paddings["padding"] = c.Padding
}
for _, p := range c.Paddings {
if err := p.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validatePrimitives(s string) error {
if len(c.SimpleBoxPool) > 0 {
return errors.Errorf("pdfcpu: \"boxes\" %s", s)
}
if len(c.SimpleBoxes) > 0 {
return errors.Errorf("pdfcpu: \"box\" %s", s)
}
if len(c.TextBoxPool) > 0 {
return errors.Errorf("pdfcpu: \"texts\" %s", s)
}
if len(c.TextBoxes) > 0 {
return errors.Errorf("pdfcpu: \"text\" %s", s)
}
if len(c.ImageBoxPool) > 0 {
return errors.Errorf("pdfcpu: \"images\" %s", s)
}
if len(c.ImageBoxes) > 0 {
return errors.Errorf("pdfcpu: \"image\" %s", s)
}
if len(c.TablePool) > 0 {
return errors.Errorf("pdfcpu: \"tables\" %s", s)
}
if len(c.Tables) > 0 {
return errors.Errorf("pdfcpu: \"table\" %s", s)
}
return nil
}
func (c *Content) validateFormPrimitives(s string) error {
if len(c.FieldGroupPool) > 0 {
return errors.Errorf("pdfcpu: \"fieldgroups\" %s", s)
}
if len(c.FieldGroups) > 0 {
return errors.Errorf("pdfcpu: \"fieldgroup\" %s", s)
}
if len(c.TextFields) > 0 {
return errors.Errorf("pdfcpu: \"textfield\" %s", s)
}
if len(c.DateFields) > 0 {
return errors.Errorf("pdfcpu: \"datefield\" %s", s)
}
if len(c.CheckBoxes) > 0 {
return errors.Errorf("pdfcpu: \"checkbox\" %s", s)
}
if len(c.RadioButtonGroups) > 0 {
return errors.Errorf("pdfcpu: \"radiobuttongroup\" %s", s)
}
if len(c.ComboBoxes) > 0 {
return errors.Errorf("pdfcpu: \"combobox\" %s", s)
}
if len(c.ListBoxes) > 0 {
return errors.Errorf("pdfcpu: \"listbox\" %s", s)
}
return nil
}
func (c *Content) validateRegions() error {
s := "must be defined within region content"
if err := c.validatePrimitives(s); err != nil {
return err
}
if err := c.validateFormPrimitives(s); err != nil {
return err
}
c.Regions.page = c.page
c.Regions.parent = c
return c.Regions.validate()
}
func (c *Content) validateBars() error {
// bars
for _, b := range c.Bars {
b.pdf = c.page.pdf
b.content = c
if err := b.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validateSimpleBoxPool() error {
// boxes
for _, sb := range c.SimpleBoxPool {
sb.pdf = c.page.pdf
sb.content = c
if err := sb.validate(); err != nil {
return err
}
}
for _, sb := range c.SimpleBoxes {
sb.pdf = c.page.pdf
sb.content = c
if err := sb.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validateTextBoxPool() error {
// text
for _, tb := range c.TextBoxPool {
tb.pdf = c.page.pdf
tb.content = c
if err := tb.validate(); err != nil {
return err
}
}
for _, tb := range c.TextBoxes {
tb.pdf = c.page.pdf
tb.content = c
if err := tb.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validateImageBoxPool() error {
// images
for _, ib := range c.ImageBoxPool {
ib.pdf = c.page.pdf
ib.content = c
if err := ib.validate(); err != nil {
return err
}
}
for _, ib := range c.ImageBoxes {
ib.pdf = c.page.pdf
ib.content = c
if err := ib.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validateTablePool() error {
// tables
for _, t := range c.TablePool {
t.pdf = c.page.pdf
t.content = c
if err := t.validate(); err != nil {
return err
}
}
for _, t := range c.Tables {
t.pdf = c.page.pdf
t.content = c
if err := t.validate(); err != nil {
return err
}
}
return nil
}
func (c *Content) validateFieldGroupPool() error {
// textfield groups
for _, fg := range c.FieldGroupPool {
fg.pdf = c.page.pdf
fg.content = c
if err := fg.validate(); err != nil {
return err
}
}
return c.validateFieldGroups()
}
func (c *Content) validatePools() error {
if err := c.validateSimpleBoxPool(); err != nil {
return err
}
if err := c.validateTextBoxPool(); err != nil {
return err
}
if err := c.validateImageBoxPool(); err != nil {
return err
}
if err := c.validateTablePool(); err != nil {
return err
}
return c.validateFieldGroupPool()
}
func (c *Content) validateTextFields() error {
pdf := c.page.pdf
if len(c.TextFields) > 0 {
for _, tf := range c.TextFields {
tf.pdf = pdf
tf.content = c
if err := tf.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validateDateFields() error {
pdf := c.page.pdf
if len(c.DateFields) > 0 {
for _, df := range c.DateFields {
df.pdf = pdf
df.content = c
if err := df.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validateFieldGroups() error {
pdf := c.page.pdf
if len(c.FieldGroups) > 0 {
for _, fg := range c.FieldGroups {
fg.pdf = pdf
fg.content = c
if err := fg.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validateCheckBoxes() error {
pdf := c.page.pdf
if len(c.CheckBoxes) > 0 {
for _, cb := range c.CheckBoxes {
cb.pdf = pdf
cb.content = c
if err := cb.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validateRadioButtonGroups() error {
pdf := c.page.pdf
if len(c.RadioButtonGroups) > 0 {
for _, rbg := range c.RadioButtonGroups {
rbg.pdf = pdf
rbg.content = c
if err := rbg.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validateComboBoxes() error {
pdf := c.page.pdf
if len(c.ComboBoxes) > 0 {
for _, cb := range c.ComboBoxes {
cb.pdf = pdf
cb.content = c
if err := cb.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validateListBoxes() error {
pdf := c.page.pdf
if len(c.ListBoxes) > 0 {
for _, lb := range c.ListBoxes {
lb.pdf = pdf
lb.content = c
if err := lb.validate(); err != nil {
return err
}
}
}
return nil
}
func (c *Content) validate() error {
if err := c.validateBackgroundColor(); err != nil {
return err
}
for _, g := range c.Guides {
g.validate()
}
if err := c.validateBorders(); err != nil {
return err
}
if err := c.validateMargins(); err != nil {
return err
}
if err := c.validatePaddings(); err != nil {
return err
}
if c.Regions != nil {
return c.validateRegions()
}
if err := c.validateBars(); err != nil {
return err
}
if err := c.validatePools(); err != nil {
return err
}
if err := c.validateTextFields(); err != nil {
return err
}
if err := c.validateDateFields(); err != nil {
return err
}
if err := c.validateCheckBoxes(); err != nil {
return err
}
if err := c.validateRadioButtonGroups(); err != nil {
return err
}
if err := c.validateComboBoxes(); err != nil {
return err
}
return c.validateListBoxes()
}
func (c *Content) namedFont(id string) *FormFont {
f := c.Fonts[id]
if f != nil {
return f
}
if c.parent != nil {
return c.parent.namedFont(id)
}
return c.page.namedFont(id)
}
func (c *Content) namedMargin(id string) *Margin {
m := c.Margins[id]
if m != nil {
return m
}
if c.parent != nil {
return c.parent.namedMargin(id)
}
return c.page.namedMargin(id)
}
func (c *Content) margin() *Margin {
return c.namedMargin("margin")
}
func (c *Content) namedBorder(id string) *Border {
b := c.Borders[id]
if b != nil {
return b
}
if c.parent != nil {
return c.parent.namedBorder(id)
}
return c.page.namedBorder(id)
}
func (c *Content) border() *Border {
return c.namedBorder("border")
}
func (c *Content) namedPadding(id string) *Padding {
p := c.Paddings[id]
if p != nil {
return p
}
if c.parent != nil {
return c.parent.namedPadding(id)
}
return c.page.namedPadding(id)
}
func (c *Content) padding() *Padding {
return c.namedPadding("padding")
}
func (c *Content) namedSimpleBox(id string) *SimpleBox {
sb := c.SimpleBoxPool[id]
if sb != nil {
return sb
}
if c.parent != nil {
return c.parent.namedSimpleBox(id)
}
return c.page.namedSimpleBox(id)
}
func (c *Content) namedImageBox(id string) *ImageBox {
ib := c.ImageBoxPool[id]
if ib != nil {
return ib
}
if c.parent != nil {
return c.parent.namedImageBox(id)
}
return c.page.namedImageBox(id)
}
func (c *Content) namedTextBox(id string) *TextBox {
tb := c.TextBoxPool[id]
if tb != nil {
return tb
}
if c.parent != nil {
return c.parent.namedTextBox(id)
}
return c.page.namedTextBox(id)
}
func (c *Content) namedTable(id string) *Table {
t := c.TablePool[id]
if t != nil {
return t
}
if c.parent != nil {
return c.parent.namedTable(id)
}
return c.page.namedTable(id)
}
func (c *Content) namedFieldGroup(id string) *FieldGroup {
fg := c.FieldGroupPool[id]
if fg != nil {
return fg
}
if c.parent != nil {
return c.parent.namedFieldGroup(id)
}
return c.page.namedFieldGroup(id)
}
func (c *Content) calcFont(ff map[string]*FormFont) {
fff := map[string]*FormFont{}
for id, f0 := range ff {
fff[id] = f0
f1 := c.Fonts[id]
if f1 != nil {
f1.mergeIn(f0)
fff[id] = f1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcFont(fff)
c.Regions.Right.calcFont(fff)
} else {
c.Regions.Top.calcFont(fff)
c.Regions.Bottom.calcFont(fff)
}
}
}
func (c *Content) mergeIn(fName string, f *FormFont) error {
f0 := c.namedFont(fName)
if f0 == nil {
return errors.Errorf("pdfcpu: missing named font \"input\"")
}
f.Name = f0.Name
if f.Size == 0 {
f.Size = f0.Size
}
if f.col == nil {
f.col = f0.col
}
if f.Lang == "" {
f.Lang = f0.Lang
}
if f.Script == "" {
f.Script = f0.Script
}
return nil
}
func (c *Content) calcInputFont(f *FormFont) (*FormFont, error) {
if f != nil {
if f.Name == "" {
// Inherited named font "input".
if err := c.mergeIn("input", f); err != nil {
return nil, err
}
}
if f.Name != "" && f.Name[0] == '$' {
// Inherit some other named font.
fName := f.Name[1:]
if err := c.mergeIn(fName, f); err != nil {
return nil, err
}
}
} else {
// Use inherited named font "input".
f = c.namedFont("input")
if f == nil {
return nil, errors.Errorf("pdfcpu: missing named font \"input\"")
}
}
if f.col == nil {
f.col = &color.Black
}
return f, nil
}
func (c *Content) calcLabelFont(f *FormFont) (*FormFont, error) {
if f != nil {
var f0 *FormFont
if f.Name == "" {
// Use inherited named font "label".
f0 = c.namedFont("label")
if f0 == nil {
return nil, errors.Errorf("pdfcpu: missing named font \"label\"")
}
f.Name = f0.Name
if f.Size == 0 {
f.Size = f0.Size
}
if f.col == nil {
f.col = f0.col
}
if f.Script == "" {
f.Script = f0.Script
}
}
if f.Name != "" && f.Name[0] == '$' {
// use named font
fName := f.Name[1:]
f0 := c.namedFont(fName)
if f0 == nil {
return nil, errors.Errorf("pdfcpu: unknown font name %s", fName)
}
f.Name = f0.Name
if f.Size == 0 {
f.Size = f0.Size
}
if f.col == nil {
f.col = f0.col
}
if f.Script == "" {
f.Script = f0.Script
}
}
} else {
// Use inherited named font "label".
f = c.namedFont("label")
if f == nil {
return nil, errors.Errorf("pdfcpu: missing named font \"label\"")
}
}
if f.col == nil {
f.col = &color.Black
}
return f, nil
}
func (c *Content) calcBorder(bb map[string]*Border) {
bbb := map[string]*Border{}
for id, b0 := range bb {
bbb[id] = b0
b1 := c.Borders[id]
if b1 != nil {
b1.mergeIn(b0)
bbb[id] = b1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcBorder(bbb)
c.Regions.Right.calcBorder(bb)
} else {
c.Regions.Top.calcBorder(bbb)
c.Regions.Bottom.calcBorder(bbb)
}
}
}
func (c *Content) calcMargin(mm map[string]*Margin) {
mmm := map[string]*Margin{}
for id, m0 := range mm {
mmm[id] = m0
m1 := c.Margins[id]
if m1 != nil {
m1.mergeIn(m0)
mmm[id] = m1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcMargin(mmm)
c.Regions.Right.calcMargin(mmm)
} else {
c.Regions.Top.calcMargin(mmm)
c.Regions.Bottom.calcMargin(mmm)
}
}
}
func (c *Content) calcPadding(pp map[string]*Padding) {
ppp := map[string]*Padding{}
for id, p0 := range pp {
ppp[id] = p0
p1 := c.Paddings[id]
if p1 != nil {
p1.mergeIn(p0)
ppp[id] = p1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcPadding(ppp)
c.Regions.Right.calcPadding(ppp)
} else {
c.Regions.Top.calcPadding(ppp)
c.Regions.Bottom.calcPadding(ppp)
}
}
}
func (c *Content) calcSimpleBoxes(bb map[string]*SimpleBox) {
bbb := map[string]*SimpleBox{}
for id, sb0 := range bb {
bbb[id] = sb0
sb1 := c.SimpleBoxPool[id]
if sb1 != nil {
sb1.mergeIn(sb0)
bbb[id] = sb1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcSimpleBoxes(bbb)
c.Regions.Right.calcSimpleBoxes(bbb)
} else {
c.Regions.Top.calcSimpleBoxes(bbb)
c.Regions.Bottom.calcSimpleBoxes(bbb)
}
}
}
func (c *Content) calcTextBoxes(bb map[string]*TextBox) {
bbb := map[string]*TextBox{}
for id, tb0 := range bb {
bbb[id] = tb0
tb1 := c.TextBoxPool[id]
if tb1 != nil {
tb1.mergeIn(tb0)
bbb[id] = tb1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcTextBoxes(bbb)
c.Regions.Right.calcTextBoxes(bbb)
} else {
c.Regions.Top.calcTextBoxes(bbb)
c.Regions.Bottom.calcTextBoxes(bbb)
}
}
}
func (c *Content) calcImageBoxes(bb map[string]*ImageBox) {
bbb := map[string]*ImageBox{}
for id, ib0 := range bb {
bbb[id] = ib0
ib1 := c.ImageBoxPool[id]
if ib1 != nil {
ib1.mergeIn(ib0)
bbb[id] = ib1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcImageBoxes(bbb)
c.Regions.Right.calcImageBoxes(bbb)
} else {
c.Regions.Top.calcImageBoxes(bbb)
c.Regions.Bottom.calcImageBoxes(bbb)
}
}
}
func (c *Content) calcTables(bb map[string]*Table) {
bbb := map[string]*Table{}
for id, t0 := range bb {
bbb[id] = t0
t1 := c.TablePool[id]
if t1 != nil {
t1.mergeIn(t0)
bbb[id] = t1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcTables(bbb)
c.Regions.Right.calcTables(bbb)
} else {
c.Regions.Top.calcTables(bbb)
c.Regions.Bottom.calcTables(bbb)
}
}
}
func (c *Content) calcFieldGroups(bb map[string]*FieldGroup) {
bbb := map[string]*FieldGroup{}
for id, fg0 := range bb {
bbb[id] = fg0
fg1 := c.FieldGroupPool[id]
if fg1 != nil {
fg1.mergeIn(fg0)
bbb[id] = fg1
}
}
if c.Regions != nil {
if c.Regions.horizontal {
c.Regions.Left.calcFieldGroups(bbb)
c.Regions.Right.calcFieldGroups(bbb)
} else {
c.Regions.Top.calcFieldGroups(bbb)
c.Regions.Bottom.calcFieldGroups(bbb)
}
}
}
// BorderRect returns the border rect for c.
func (c *Content) BorderRect() *types.Rectangle {
if c.borderRect == nil {
mLeft, mRight, mTop, mBottom, borderWidth := 0., 0., 0., 0., 0.
m := c.margin()
if m != nil {
mTop = m.Top
mRight = m.Right
mBottom = m.Bottom
mLeft = m.Left
}
b := c.border()
if b != nil && b.col != nil && b.Width >= 0 {
borderWidth = float64(b.Width)
}
c.borderRect = types.RectForWidthAndHeight(
c.mediaBox.LL.X+mLeft+borderWidth/2,
c.mediaBox.LL.Y+mBottom+borderWidth/2,
c.mediaBox.Width()-mLeft-mRight-borderWidth,
c.mediaBox.Height()-mTop-mBottom-borderWidth)
}
return c.borderRect
}
func (c *Content) Box() *types.Rectangle {
if c.box == nil {
var mTop, mRight, mBottom, mLeft float64
var pTop, pRight, pBottom, pLeft float64
var borderWidth float64
m := c.margin()
if m != nil {
if m.Width > 0 {
mTop, mRight, mBottom, mLeft = m.Width, m.Width, m.Width, m.Width
} else {
mTop = m.Top
mRight = m.Right
mBottom = m.Bottom
mLeft = m.Left
}
}
b := c.border()
if b != nil && b.col != nil && b.Width >= 0 {
borderWidth = float64(b.Width)
}
p := c.padding()
if p != nil {
if p.Width > 0 {
pTop, pRight, pBottom, pLeft = p.Width, p.Width, p.Width, p.Width
} else {
pTop = p.Top
pRight = p.Right
pBottom = p.Bottom
pLeft = p.Left
}
}
llx := c.mediaBox.LL.X + mLeft + borderWidth + pLeft
lly := c.mediaBox.LL.Y + mBottom + borderWidth + pBottom
w := c.mediaBox.Width() - mLeft - mRight - 2*borderWidth - pLeft - pRight
h := c.mediaBox.Height() - mTop - mBottom - 2*borderWidth - pTop - pBottom
c.box = types.RectForWidthAndHeight(llx, lly, w, h)
}
return c.box
}
func (c *Content) calcPosition(x, y, dx, dy, mTop, mRight, mBottom, mLeft float64) (float64, float64) {
cBox := c.Box()
r := cBox.CroppedCopy(0)
r.LL.X += mLeft
r.LL.Y += mBottom
r.UR.X -= mRight
r.UR.Y -= mTop
pdf := c.page.pdf
x, y = types.NormalizeCoord(x, y, cBox, pdf.origin, false)
if x == -1 {
// Center horizontally
x = cBox.Center().X - r.LL.X
} else if x > 0 {
x -= mLeft
if x < 0 {
x = 0
}
}
if y == -1 {
// Center vertically
y = cBox.Center().Y - r.LL.Y
} else if y > 0 {
y -= mBottom
if y < 0 {
y = 0
}
}
if x >= 0 {
x = r.LL.X + x
}
if y >= 0 {
y = r.LL.Y + y
}
// Position text horizontally centered for x < 0.
if x < 0 {
x = r.LL.X + r.Width()/2
}
// Position text vertically centered for y < 0.
if y < 0 {
y = r.LL.Y + r.Height()/2
}
// Apply offset.
x += dx
y += dy
return x, y
}
func (c *Content) renderBars(p *model.Page) error {
for _, b := range c.Bars {
if b.Hide {
continue
}
if err := b.render(p); err != nil {
return err
}
}
return nil
}
func (c *Content) renderSimpleBoxes(p *model.Page) error {
for _, sb := range c.SimpleBoxes {
if sb.Hide {
continue
}
if sb.Name != "" && sb.Name[0] == '$' {
// Use named simplebox
sbName := sb.Name[1:]
sb0 := c.namedSimpleBox(sbName)
if sb0 == nil {
return errors.Errorf("pdfcpu: unknown named box %s", sbName)
}
sb.mergeIn(sb0)
}
if err := sb.render(p); err != nil {
return err
}
}
return nil
}
func (c *Content) renderTextBoxes(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, tb := range c.TextBoxes {
if tb.Hide {
continue
}
if tb.Name != "" && tb.Name[0] == '$' {
// Use named textbox
tbName := tb.Name[1:]
tb0 := c.namedTextBox(tbName)
if tb0 == nil {
return errors.Errorf("pdfcpu: unknown named text %s", tbName)
}
tb.mergeIn(tb0)
}
if err := tb.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderImageBoxes(p *model.Page, pageNr int, images model.ImageMap) error {
for _, ib := range c.ImageBoxes {
if ib.Hide {
continue
}
if ib.Name != "" && ib.Name[0] == '$' {
// Use named imagebox
ibName := ib.Name[1:]
ib0 := c.namedImageBox(ibName)
if ib0 == nil {
return errors.Errorf("pdfcpu: unknown named image %s", ibName)
}
ib.mergeIn(ib0)
}
if err := ib.render(p, pageNr, images); err != nil {
return err
}
}
return nil
}
func (c *Content) renderTables(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, t := range c.Tables {
if t.Hide {
continue
}
if t.Name != "" && t.Name[0] == '$' {
// Use named table
tName := t.Name[1:]
t0 := c.namedTable(tName)
if t0 == nil {
return errors.Errorf("pdfcpu: unknown named table %s", tName)
}
t.mergeIn(t0)
}
if err := t.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderTextFields(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, tf := range c.TextFields {
if tf.Hide {
continue
}
if err := tf.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderDateFields(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, df := range c.DateFields {
if df.Hide {
continue
}
if err := df.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderCheckBoxes(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, cb := range c.CheckBoxes {
if cb.Hide {
continue
}
if err := cb.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderRadioButtonGroups(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, rbg := range c.RadioButtonGroups {
if rbg.Hide {
continue
}
if err := rbg.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderComboBoxes(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, cb := range c.ComboBoxes {
if cb.Hide {
continue
}
if err := cb.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderListBoxes(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, lb := range c.ListBoxes {
if lb.Hide {
continue
}
if err := lb.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderFieldGroups(p *model.Page, pageNr int, fonts model.FontMap) error {
for _, fg := range c.FieldGroups {
if fg.Hide {
continue
}
if fg.Name != "" && fg.Name[0] == '$' {
// Use named field group
fgName := fg.Name[1:]
fg0 := c.namedFieldGroup(fgName)
if fg0 == nil {
return errors.Errorf("pdfcpu: unknown named field group %s", fgName)
}
fg.mergeIn(fg0)
}
if err := fg.render(p, pageNr, fonts); err != nil {
return err
}
}
return nil
}
func (c *Content) renderBoxesAndGuides(p *model.Page) {
pdf := c.page.pdf
// Render mediaBox & contentBox
if pdf.ContentBox {
draw.DrawRect(p.Buf, c.mediaBox, 0, &color.Green, nil)
draw.DrawRect(p.Buf, c.Box(), 0, &color.Red, nil)
}
// Render guides
if pdf.Guides {
for _, g := range c.Guides {
g.render(p.Buf, c.Box(), pdf)
}
}
}
func (c *Content) renderPrimitives(p *model.Page, pageNr int, fonts model.FontMap, images model.ImageMap) error {
if err := c.renderBars(p); err != nil {
return err
}
if err := c.renderSimpleBoxes(p); err != nil {
return err
}
if err := c.renderTextBoxes(p, pageNr, fonts); err != nil {
return err
}
if err := c.renderImageBoxes(p, pageNr, images); err != nil {
return err
}
return c.renderTables(p, pageNr, fonts)
}
func (c *Content) renderFormPrimitives(p *model.Page, pageNr int, fonts model.FontMap) error {
if err := c.renderTextFields(p, pageNr, fonts); err != nil {
return err
}
if err := c.renderDateFields(p, pageNr, fonts); err != nil {
return err
}
if err := c.renderCheckBoxes(p, pageNr, fonts); err != nil {
return err
}
if err := c.renderRadioButtonGroups(p, pageNr, fonts); err != nil {
return err
}
if err := c.renderComboBoxes(p, pageNr, fonts); err != nil {
return err
}
if err := c.renderListBoxes(p, pageNr, fonts); err != nil {
return err
}
return c.renderFieldGroups(p, pageNr, fonts)
}
func (c *Content) render(p *model.Page, pageNr int, fonts model.FontMap, images model.ImageMap) error {
if c.Regions != nil {
c.Regions.mediaBox = c.mediaBox
c.Regions.page = c.page
return c.Regions.render(p, pageNr, fonts, images)
}
// Render background
if c.bgCol != nil {
draw.FillRectNoBorder(p.Buf, c.BorderRect(), *c.bgCol)
}
// Render border
b := c.border()
if b != nil && b.col != nil && b.Width >= 0 {
draw.DrawRect(p.Buf, c.BorderRect(), float64(b.Width), b.col, &b.style)
}
if err := c.renderPrimitives(p, pageNr, fonts, images); err != nil {
return err
}
if err := c.renderFormPrimitives(p, pageNr, fonts); err != nil {
return err
}
c.renderBoxesAndGuides(p)
return nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/gzlwz/golang-pdfcpu.git
git@gitee.com:gzlwz/golang-pdfcpu.git
gzlwz
golang-pdfcpu
golang-pdfcpu
v0.0.2

搜索帮助