From 5349a52db6c5548880871ce76824b85443a4829a Mon Sep 17 00:00:00 2001 From: Horst Rutter Date: Sun, 3 Sep 2023 20:24:24 +0200 Subject: [PATCH] Fix layout ParsePageFormat --- pkg/api/test/create_test.go | 32 +++++++++++++-------------- pkg/pdfcpu/info.go | 2 ++ pkg/pdfcpu/model/page.go | 12 +++++++--- pkg/pdfcpu/model/xreftable.go | 2 +- pkg/pdfcpu/primitives/pdf.go | 41 +++++++++++++++++------------------ pkg/pdfcpu/types/layout.go | 16 +++++++------- 6 files changed, 56 insertions(+), 49 deletions(-) diff --git a/pkg/api/test/create_test.go b/pkg/api/test/create_test.go index 3abdaa0aa..aa941a8b6 100644 --- a/pkg/api/test/create_test.go +++ b/pkg/api/test/create_test.go @@ -303,7 +303,7 @@ func writeTextDemoAlignedWidthAndMargin( } func createTextDemoAlignedWidthAndMargin(xRefTable *model.XRefTable, mediaBox *types.Rectangle, hAlign types.HAlignment, w, mLeft, mRight, mTop, mBot float64) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextDemoAlignedWidthAndMargin(xRefTable, p, region, hAlign, w, mLeft, mRight, mTop, mBot) region = types.RectForWidthAndHeight(50, 70, 200, 200) @@ -485,7 +485,7 @@ func writeTextAlignJustifyColumnDemo(xRefTable *model.XRefTable, p model.Page, r } func createTextAlignJustifyDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle fontName := "Times-Roman" writeTextAlignJustifyDemo(xRefTable, p, region, fontName) @@ -495,7 +495,7 @@ func createTextAlignJustifyDemo(xRefTable *model.XRefTable, mediaBox *types.Rect } func createTextAlignJustifyColumnDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextAlignJustifyColumnDemo(xRefTable, p, region) region = types.RectForWidthAndHeight(0, 0, 200, 200) @@ -579,7 +579,7 @@ func writeTextDemoAnchors(xRefTable *model.XRefTable, p model.Page, region *type } func createTextDemoAnchors(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextDemoAnchors(xRefTable, p, region) region = types.RectForWidthAndHeight(50, 70, 200, 200) @@ -588,7 +588,7 @@ func createTextDemoAnchors(xRefTable *model.XRefTable, mediaBox *types.Rectangle } func createTextDemoAnchorsWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) dx, dy := 20., 20. var region *types.Rectangle writeTextDemoAnchorsWithOffset(xRefTable, p, region, dx, dy) @@ -695,7 +695,7 @@ func writeTextDemoColumnAnchored(xRefTable *model.XRefTable, p model.Page, regio } func createTextDemoColumnAnchored(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextDemoColumnAnchored(xRefTable, p, region) region = types.RectForWidthAndHeight(50, 70, 400, 400) @@ -704,7 +704,7 @@ func createTextDemoColumnAnchored(xRefTable *model.XRefTable, mediaBox *types.Re } func createTextDemoColumnAnchoredWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle dx, dy := 20., 20. writeTextDemoColumnAnchoredWithOffset(xRefTable, p, region, dx, dy) @@ -835,7 +835,7 @@ func writeTextRotateDemo(xRefTable *model.XRefTable, p model.Page, region *types } func createTextRotateDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextRotateDemo(xRefTable, p, region) region = types.RectForWidthAndHeight(150, 150, 300, 300) @@ -844,7 +844,7 @@ func createTextRotateDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) } func createTextRotateDemoWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle dx, dy := 20., 20. writeTextRotateDemoWithOffset(xRefTable, p, region, dx, dy) @@ -1030,7 +1030,7 @@ func writeTextScaleAbsoluteDemo(xRefTable *model.XRefTable, p model.Page, region } func createTextScaleAbsoluteDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextScaleAbsoluteDemo(xRefTable, p, region) region = types.RectForWidthAndHeight(20, 70, 180, 180) @@ -1039,7 +1039,7 @@ func createTextScaleAbsoluteDemo(xRefTable *model.XRefTable, mediaBox *types.Rec } func createTextScaleAbsoluteDemoWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) dx, dy := 20., 20. var region *types.Rectangle writeTextScaleAbsoluteDemoWithOffset(xRefTable, p, region, dx, dy) @@ -1241,7 +1241,7 @@ func writeTextScaleRelativeDemo(xRefTable *model.XRefTable, p model.Page, region } func createTextScaleRelativeDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writeTextScaleRelativeDemo(xRefTable, p, region) region = types.RectForWidthAndHeight(50, 70, 200, 200) @@ -1250,7 +1250,7 @@ func createTextScaleRelativeDemo(xRefTable *model.XRefTable, mediaBox *types.Rec } func createTextScaleRelativeDemoWithOffset(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle dx, dy := 20., 20. writeTextScaleRelativeDemoWithOffset(xRefTable, p, region, dx, dy) @@ -1803,7 +1803,7 @@ func writecreateTestRTLUserFont(xRefTable *model.XRefTable, p model.Page, region } func createTestRTLUserFont(xRefTable *model.XRefTable, mediaBox *types.Rectangle, language, fontName string) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle text := sampleTextRTL[language] writecreateTestRTLUserFont(xRefTable, p, region, fontName, text) @@ -1865,7 +1865,7 @@ func writecreateTestUserFontJustified(xRefTable *model.XRefTable, p model.Page, } func createTestUserFontJustified(xRefTable *model.XRefTable, mediaBox *types.Rectangle, rtl bool) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) var region *types.Rectangle writecreateTestUserFontJustified(xRefTable, p, region, rtl) return p @@ -1946,7 +1946,7 @@ func TestUserFontRTL(t *testing.T) { } func createCJKVDemo(xRefTable *model.XRefTable, mediaBox *types.Rectangle) model.Page { - p := model.NewPage(mediaBox) + p := model.NewPage(mediaBox, nil) mb := p.MediaBox textEnglish := `pdfcpu diff --git a/pkg/pdfcpu/info.go b/pkg/pdfcpu/info.go index 72a3286f8..c22a35952 100644 --- a/pkg/pdfcpu/info.go +++ b/pkg/pdfcpu/info.go @@ -225,6 +225,8 @@ func appendNotEqualMediaAndCropBoxInfo(ss *[]string, pb model.PageBoundaries, un bb := pb.BleedBox() ab := pb.ArtBox() + *ss = append(*ss, fmt.Sprintf(" MediaBox (%s) %v", unit, mb.Format(currUnit))) + s := trimBleedArtBoxString(cb, tb, bb, ab) *ss = append(*ss, fmt.Sprintf(" CropBox (%s) %v %s", unit, cb.Format(currUnit), s)) diff --git a/pkg/pdfcpu/model/page.go b/pkg/pdfcpu/model/page.go index 30f4927ad..f11a4fa0b 100644 --- a/pkg/pdfcpu/model/page.go +++ b/pkg/pdfcpu/model/page.go @@ -87,9 +87,15 @@ type Page struct { Fields types.Array } -// NewPage creates a page for a mediaBox. -func NewPage(mediaBox *types.Rectangle) Page { - return Page{MediaBox: mediaBox, Fm: FontMap{}, Im: ImageMap{}, Buf: new(bytes.Buffer)} +// NewPage creates a page for given mediaBox and cropBox. +func NewPage(mediaBox, cropBox *types.Rectangle) Page { + return Page{ + MediaBox: mediaBox, + CropBox: cropBox, + Fm: FontMap{}, + Im: ImageMap{}, + AnnotTabs: map[int]FieldAnnotation{}, + Buf: new(bytes.Buffer)} } // NewPageWithBg creates a page for a mediaBox. diff --git a/pkg/pdfcpu/model/xreftable.go b/pkg/pdfcpu/model/xreftable.go index 6e4045dba..3cc84e0f0 100644 --- a/pkg/pdfcpu/model/xreftable.go +++ b/pkg/pdfcpu/model/xreftable.go @@ -2226,7 +2226,7 @@ func (xRefTable *XRefTable) PageDims() ([]types.Dim, error) { dims := make([]types.Dim, len(pbs)) for i, pb := range pbs { - d := pb.CropBox().Dimensions() + d := pb.MediaBox().Dimensions() if pb.Rot%180 != 0 { d.Width, d.Height = d.Height, d.Width } diff --git a/pkg/pdfcpu/primitives/pdf.go b/pkg/pdfcpu/primitives/pdf.go index a2228c414..4174dcfd1 100644 --- a/pkg/pdfcpu/primitives/pdf.go +++ b/pkg/pdfcpu/primitives/pdf.go @@ -17,7 +17,6 @@ package primitives import ( - "bytes" "io" "net/http" "path/filepath" @@ -1027,15 +1026,29 @@ func (pdf *PDF) highlightPos(w io.Writer, x, y float64, cBox *types.Rectangle) { draw.DrawHairCross(w, x, y, cBox) } -func (pdf *PDF) renderPageBackground(page *PDFPage, w io.Writer, cropBox *types.Rectangle) { +func (pdf *PDF) renderPageBackground(page *PDFPage, w io.Writer) { if page.bgCol == nil { page.bgCol = pdf.bgCol } if page.bgCol != nil { - draw.FillRectNoBorder(w, cropBox, *page.bgCol) + draw.FillRectNoBorder(w, page.cropBox, *page.bgCol) } } +func (pdf *PDF) newModelPageforPDFPage(page *PDFPage) model.Page { + mediaBox := pdf.mediaBox + if page != nil && page.mediaBox != nil { + mediaBox = page.mediaBox + } + + cropBox := pdf.cropBox + if page != nil && page.cropBox != nil { + cropBox = page.cropBox + } + + return model.NewPage(mediaBox, cropBox) +} + // RenderPages renders page content into model.Pages func (pdf *PDF) RenderPages() ([]*model.Page, model.FontMap, error) { @@ -1048,19 +1061,8 @@ func (pdf *PDF) RenderPages() ([]*model.Page, model.FontMap, error) { for i, page := range pdf.pages { pageNr := i + 1 - mediaBox := pdf.mediaBox - cropBox := pdf.cropBox - // check taborders - - p := model.Page{ - MediaBox: mediaBox, - CropBox: cropBox, - Fm: model.FontMap{}, - Im: model.ImageMap{}, - AnnotTabs: map[int]model.FieldAnnotation{}, - Buf: new(bytes.Buffer), - } + p := pdf.newModelPageforPDFPage(page) if page == nil { if pageNr <= pdf.XRefTable.PageCount { @@ -1088,14 +1090,11 @@ func (pdf *PDF) RenderPages() ([]*model.Page, model.FontMap, error) { } pp = append(pp, &p) - continue - } - if page.cropBox != nil { - cropBox = page.cropBox + continue } - pdf.renderPageBackground(page, p.Buf, cropBox) + pdf.renderPageBackground(page, p.Buf) var headerHeight, headerDy float64 var footerHeight, footerDy float64 @@ -1119,7 +1118,7 @@ func (pdf *PDF) RenderPages() ([]*model.Page, model.FontMap, error) { } // Render page content. - r := cropBox.CroppedCopy(0) + r := page.cropBox.CroppedCopy(0) r.LL.Y += footerHeight + footerDy r.UR.Y -= headerHeight + headerDy page.Content.mediaBox = r diff --git a/pkg/pdfcpu/types/layout.go b/pkg/pdfcpu/types/layout.go index 76efa1120..174a1ed95 100644 --- a/pkg/pdfcpu/types/layout.go +++ b/pkg/pdfcpu/types/layout.go @@ -388,14 +388,13 @@ func ParsePageFormat(v string) (*Dim, string, error) { // eg. A4L means A4 in landscape mode whereas A4 defaults to A4P // The default mode is defined implicitly via PaperSize dimensions. - var landscape, portrait bool + portrait := true if strings.HasSuffix(v, "L") { v = v[:len(v)-1] - landscape = true - } else if strings.HasSuffix(v, "P") { - v = v[:len(v)-1] - portrait = true + portrait = false + } else { + v = strings.TrimSuffix(v, "P") } d, ok := PaperSize[v] @@ -403,9 +402,10 @@ func ParsePageFormat(v string) (*Dim, string, error) { return nil, v, errors.Errorf("pdfcpu: page format %s is unsupported.\n", v) } - if (d.Portrait() && landscape) || (d.Landscape() && portrait) { - d.Width, d.Height = d.Height, d.Width + dim := Dim{d.Width, d.Height} + if (d.Portrait() && !portrait) || (d.Landscape() && portrait) { + dim.Width, dim.Height = dim.Height, dim.Width } - return d, v, nil + return &dim, v, nil }