unidoc / unipdf

Golang PDF library for creating and processing PDF files (pure go)
https://unidoc.io
Other
2.46k stars 250 forks source link

[BUG] Page break between subchapters #531

Closed ricardogama closed 9 months ago

ricardogama commented 9 months ago

Description

I'm trying to use chapters and subchapters to include them in the TOC, and I need each subchapter to start in a new page.

Expected Behavior

By using c.NewPage() or c.Draw(c.NewPageBreak()), I expect to have a new page, and in this case right before a new subchapter.

Actual Behavior

The page break only seems to work on a new chapter, but not on a new subchapter.

I tried having the page breaks before and after creating the subchapter, but neither seems to work.

Steps to reproduce the behavior:

  1. go run main.go
  2. open result.pdf
  3. See both subchapters 2 and 3 are on the same page (page 13)

Attachments

main.go

package main

import (
    "bytes"
    "fmt"
    "os"

    "github.com/unidoc/unipdf/v3/common/license"
    "github.com/unidoc/unipdf/v3/creator"
    "github.com/unidoc/unipdf/v3/model"
)

var (
    regularFont *model.PdfFont
    boldFont    *model.PdfFont
)

func main() {
    if err := license.SetMeteredKey(os.Getenv("UNIDOC_KEY")); err != nil {
        panic(err)
    }

    var err error
    regularFont, err = model.NewStandard14Font("Helvetica")
    if err != nil {
        panic(err)
    }

    boldFont, err = model.NewStandard14Font("Helvetica-Bold")
    if err != nil {
        panic(err)
    }

    c := creator.New()
    c.SetPageMargins(30, 30, 30, 30)

    c.DrawFooter(func(block *creator.Block, args creator.FooterFunctionArgs) {
        p := c.NewStyledParagraph()
        p.SetTextAlignment(creator.TextAlignmentCenter)

        chunk := p.Append(fmt.Sprintf("Page %d of %d", args.PageNum, args.TotalPages))
        chunk.Style.Font = regularFont
        chunk.Style.FontSize = 8
        chunk.Style.Color = creator.ColorBlack

        if err := block.Draw(p); err != nil {
            panic(err)
        }
    })

    chapters := map[string][]string{
        "chapter 1": {
            "subchapter 1",
        },
        "chapter 2": {
            "subchapter 2",
            "subchapter 3",
        },
    }

    c.AddTOC = true
    toc := c.TOC()

    hstyle := c.NewTextStyle()
    hstyle.Color = creator.ColorRGBFromArithmetic(0.2, 0.2, 0.2)
    hstyle.Font = boldFont
    hstyle.FontSize = 21
    toc.SetHeading("Index", hstyle)

    lstyle := c.NewTextStyle()
    lstyle.Font = regularFont
    toc.SetLineStyle(lstyle)
    toc.SetLineMargins(0, 0, 10, 0)

    for chapter, subchapters := range chapters {
        ch := newChapter(c, chapter)

                 for _, subchapter := range subchapters {
            c.NewPage()
            c.Draw(c.NewPageBreak())

            sc := newSubchapter(ch, subchapter)
            p := newParagraph(c, regularFont, creator.ColorBlack, subchapter)

            c.NewPage()
            c.Draw(c.NewPageBreak())

            sc.Add(p)
        }

        c.Draw(ch)
    }

    var content bytes.Buffer
    if err := c.Write(&content); err != nil {
        panic(err)
    }

    f, err := os.Create("./result.pdf")
    if err != nil {
        panic(err)
    }
    _, err = f.Write(content.Bytes())
    if err != nil {
        panic(err)
    }
    err = f.Close()
    if err != nil {
        panic(err)
    }

    fmt.Println("result.pdf created")
}

func newChapter(c *creator.Creator, title string) *creator.Chapter {
    ch := c.NewChapter(title)
    ch.GetHeading().SetFontSize(0)
    return ch
}

func newSubchapter(ch *creator.Chapter, title string) *creator.Chapter {
    sc := ch.NewSubchapter(title)
    sc.GetHeading().SetFontSize(0)
    return sc
}

func newParagraph(c *creator.Creator, font *model.PdfFont, color creator.Color, text string) *creator.StyledParagraph {
    p := c.NewStyledParagraph()
    p.SetMargins(2, 2, 5, 5)
    chunk := p.Append(text)
    chunk.Style.Font = font
    chunk.Style.Color = color
    return p
}

result.pdf

ricardogama commented 9 months ago

Adding the line break to the chapter instead of *Creator fixed it:


chapter.Add(c.NewPageBreak())