mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00
Cleaned up some comments in creator.
This commit is contained in:
parent
ffa7f9b482
commit
fefff56603
@ -51,8 +51,8 @@ func NewBlock(width float64, height float64) *Block {
|
||||
return b
|
||||
}
|
||||
|
||||
// NewBlockFromPage creates a Block from a PDF Page. Useful for loading template pages as blocks from a PDF document
|
||||
// and additional content with the creator.
|
||||
// NewBlockFromPage creates a Block from a PDF Page. Useful for loading template pages as blocks
|
||||
// from a PDF document and additional content with the creator.
|
||||
func NewBlockFromPage(page *model.PdfPage) (*Block, error) {
|
||||
b := &Block{}
|
||||
|
||||
|
@ -46,28 +46,31 @@ type Creator struct {
|
||||
acroForm *model.PdfAcroForm
|
||||
}
|
||||
|
||||
// SetForms Add Acroforms to a PDF file. Sets the specified form for writing.
|
||||
// SetForms adds an Acroform to a PDF file. Sets the specified form for writing.
|
||||
func (c *Creator) SetForms(form *model.PdfAcroForm) error {
|
||||
c.acroForm = form
|
||||
return nil
|
||||
}
|
||||
|
||||
// FrontpageFunctionArgs holds the input arguments to a front page drawing function.
|
||||
// It is designed as a struct, so additional parameters can be added in the future with backwards compatibility.
|
||||
// It is designed as a struct, so additional parameters can be added in the future with backwards
|
||||
// compatibility.
|
||||
type FrontpageFunctionArgs struct {
|
||||
PageNum int
|
||||
TotalPages int
|
||||
}
|
||||
|
||||
// HeaderFunctionArgs holds the input arguments to a header drawing function.
|
||||
// It is designed as a struct, so additional parameters can be added in the future with backwards compatibility.
|
||||
// It is designed as a struct, so additional parameters can be added in the future with backwards
|
||||
// compatibility.
|
||||
type HeaderFunctionArgs struct {
|
||||
PageNum int
|
||||
TotalPages int
|
||||
}
|
||||
|
||||
// FooterFunctionArgs holds the input arguments to a footer drawing function.
|
||||
// It is designed as a struct, so additional parameters can be added in the future with backwards compatibility.
|
||||
// It is designed as a struct, so additional parameters can be added in the future with backwards
|
||||
// compatibility.
|
||||
type FooterFunctionArgs struct {
|
||||
PageNum int
|
||||
TotalPages int
|
||||
@ -131,7 +134,8 @@ func (c *Creator) getActivePage() *model.PdfPage {
|
||||
return c.activePage
|
||||
}
|
||||
|
||||
// SetPageSize sets the Creator's page size. Pages that are added after this will be created with this Page size.
|
||||
// SetPageSize sets the Creator's page size. Pages that are added after this will be created with
|
||||
// this Page size.
|
||||
// Does not affect pages already created.
|
||||
//
|
||||
// Common page sizes are defined as constants.
|
||||
@ -238,8 +242,8 @@ func (c *Creator) AddPage(page *model.PdfPage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RotateDeg rotates the current active page by angle degrees. An error is returned on failure, which can be
|
||||
// if there is no currently active page, or the angleDeg is not a multiple of 90 degrees.
|
||||
// RotateDeg rotates the current active page by angle degrees. An error is returned on failure,
|
||||
// which can be if there is no currently active page, or the angleDeg is not a multiple of 90 degrees.
|
||||
func (c *Creator) RotateDeg(angleDeg int64) error {
|
||||
page := c.getActivePage()
|
||||
if page == nil {
|
||||
@ -247,7 +251,7 @@ func (c *Creator) RotateDeg(angleDeg int64) error {
|
||||
return errors.New("No page active")
|
||||
}
|
||||
if angleDeg%90 != 0 {
|
||||
common.Log.Debug("Error: Page rotation angle not a multiple of 90")
|
||||
common.Log.Debug("ERROR: Page rotation angle not a multiple of 90")
|
||||
return errors.New("Range check error")
|
||||
}
|
||||
|
||||
@ -267,8 +271,8 @@ func (c *Creator) Context() DrawContext {
|
||||
return c.context
|
||||
}
|
||||
|
||||
// Call before writing out. Takes care of adding headers and footers, as well as generating front Page and
|
||||
// table of contents.
|
||||
// Call before writing out. Takes care of adding headers and footers, as well as generating front
|
||||
// Page and table of contents.
|
||||
func (c *Creator) finalize() error {
|
||||
totPages := len(c.pages)
|
||||
|
||||
@ -356,8 +360,8 @@ func (c *Creator) finalize() error {
|
||||
c.setActivePage(page)
|
||||
if c.drawHeaderFunc != nil {
|
||||
// Prepare a block to draw on.
|
||||
// Header is drawn on the top of the page. Has width of the page, but height limited to the page
|
||||
// margin top height.
|
||||
// Header is drawn on the top of the page. Has width of the page, but height limited to
|
||||
// the page margin top height.
|
||||
headerBlock := NewBlock(c.pageWidth, c.pageMargins.top)
|
||||
args := HeaderFunctionArgs{
|
||||
PageNum: idx + 1,
|
||||
@ -374,8 +378,8 @@ func (c *Creator) finalize() error {
|
||||
}
|
||||
if c.drawFooterFunc != nil {
|
||||
// Prepare a block to draw on.
|
||||
// Footer is drawn on the bottom of the page. Has width of the page, but height limited to the page
|
||||
// margin bottom height.
|
||||
// Footer is drawn on the bottom of the page. Has width of the page, but height limited
|
||||
// to the page margin bottom height.
|
||||
footerBlock := NewBlock(c.pageWidth, c.pageMargins.bottom)
|
||||
args := FooterFunctionArgs{
|
||||
PageNum: idx + 1,
|
||||
@ -385,7 +389,7 @@ func (c *Creator) finalize() error {
|
||||
footerBlock.SetPos(0, c.pageHeight-footerBlock.height)
|
||||
err := c.Draw(footerBlock)
|
||||
if err != nil {
|
||||
common.Log.Debug("Error drawing footer: %v", err)
|
||||
common.Log.Debug("ERROR: drawing footer: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -422,8 +426,8 @@ func (c *Creator) MoveDown(dy float64) {
|
||||
c.context.Y += dy
|
||||
}
|
||||
|
||||
// Draw draws the Drawable widget to the document. This can span over 1 or more pages. Additional pages are added if
|
||||
// the contents go over the current Page.
|
||||
// Draw draws the Drawable widget to the document. This can span over 1 or more pages. Additional
|
||||
// pages are added if the contents go over the current Page.
|
||||
func (c *Creator) Draw(d Drawable) error {
|
||||
if c.getActivePage() == nil {
|
||||
// Add a new Page if none added already.
|
||||
@ -519,13 +523,7 @@ func (c *Creator) WriteToFile(outputPath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer fWrite.Close()
|
||||
|
||||
err = c.Write(fWrite)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return c.Write(fWrite)
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/qr"
|
||||
|
||||
"github.com/unidoc/unidoc/common"
|
||||
"github.com/unidoc/unidoc/pdf/core"
|
||||
"github.com/unidoc/unidoc/pdf/model"
|
||||
@ -232,7 +231,8 @@ func TestShapes1(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Example drawing image and line shape on a block and applying to pages, also demonstrating block rotation.
|
||||
// Example drawing image and line shape on a block and applying to pages, also demonstrating block
|
||||
// rotation.
|
||||
func TestShapesOnBlock(t *testing.T) {
|
||||
creator := New()
|
||||
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// Paragraph represents text drawn with a specified font and can wrap across lines and pages.
|
||||
// By default occupies the available width in the drawing context.
|
||||
// By default it occupies the available width in the drawing context.
|
||||
type Paragraph struct {
|
||||
// The input utf-8 text as a string (series of runes).
|
||||
text string
|
||||
@ -179,9 +179,8 @@ func (p *Paragraph) SetWidth(width float64) {
|
||||
func (p *Paragraph) Width() float64 {
|
||||
if p.enableWrap {
|
||||
return p.wrapWidth
|
||||
} else {
|
||||
return p.getTextWidth() / 1000.0
|
||||
}
|
||||
return p.getTextWidth() / 1000.0
|
||||
}
|
||||
|
||||
// Height returns the height of the Paragraph. The height is calculated based on the input text and
|
||||
@ -191,8 +190,7 @@ func (p *Paragraph) Height() float64 {
|
||||
p.wrapText()
|
||||
}
|
||||
|
||||
h := float64(len(p.textLines)) * p.lineHeight * p.fontSize
|
||||
return h
|
||||
return float64(len(p.textLines)) * p.lineHeight * p.fontSize
|
||||
}
|
||||
|
||||
// Calculate the text width (if not wrapped).
|
||||
@ -202,13 +200,13 @@ func (p *Paragraph) getTextWidth() float64 {
|
||||
for _, r := range p.text {
|
||||
glyph, found := p.textFont.Encoder().RuneToGlyph(r)
|
||||
if !found {
|
||||
common.Log.Debug("Error! Glyph not found for rune: %s", r)
|
||||
common.Log.Debug("ERROR: Glyph not found for rune: 0x%04x=%c", r, r)
|
||||
return -1 // XXX/FIXME: return error.
|
||||
}
|
||||
|
||||
metrics, found := p.textFont.GetGlyphCharMetrics(glyph)
|
||||
if !found {
|
||||
common.Log.Debug("Glyph char metrics not found! %s", glyph)
|
||||
common.Log.Debug("Glyph char metrics not found! %q (rune 0x04x=%c)", glyph, r, r)
|
||||
return -1 // XXX/FIXME: return error.
|
||||
}
|
||||
w += p.fontSize * metrics.Wx
|
||||
@ -226,7 +224,7 @@ func (p *Paragraph) wrapText() error {
|
||||
}
|
||||
|
||||
line := []rune{}
|
||||
lineWidth := float64(0.0)
|
||||
lineWidth := 0.0
|
||||
p.textLines = []string{}
|
||||
|
||||
runes := []rune(p.text)
|
||||
@ -236,52 +234,46 @@ func (p *Paragraph) wrapText() error {
|
||||
for _, val := range runes {
|
||||
glyph, found := p.textFont.Encoder().RuneToGlyph(val)
|
||||
if !found {
|
||||
common.Log.Debug("ERROR: Glyph not found for rune: %v", val)
|
||||
return errors.New("Glyph not found for rune") // XXX/FIXME: return error.
|
||||
common.Log.Debug("ERROR: Glyph not found for rune: %c", val)
|
||||
return errors.New("Glyph not found for rune")
|
||||
}
|
||||
|
||||
metrics, found := p.textFont.GetGlyphCharMetrics(glyph)
|
||||
if !found {
|
||||
common.Log.Debug("ERROR: Glyph char metrics not found! %s (%s)", glyph, string(val))
|
||||
common.Log.Debug("ERROR: Glyph char metrics not found! %q rune=0x%04x=%c font=%s",
|
||||
glyph, val, val, p.textFont.BaseFont())
|
||||
common.Log.Trace("Font: %#v", p.textFont)
|
||||
common.Log.Trace("Encoder: %#v", p.textFont.Encoder())
|
||||
return errors.New("Glyph char metrics missing") // XXX/FIXME: return error.
|
||||
return errors.New("Glyph char metrics missing")
|
||||
}
|
||||
|
||||
w := p.fontSize * metrics.Wx
|
||||
if lineWidth+w > p.wrapWidth*1000.0 {
|
||||
// Goes out of bounds: Wrap.
|
||||
// Breaks on the character.
|
||||
// XXX/TODO: when goes outside: back up to next space, otherwise break on the character.
|
||||
idx := -1
|
||||
for i := len(glyphs) - 1; i >= 0; i-- {
|
||||
if glyphs[i] == "space" {
|
||||
if glyphs[i] == "space" { // XXX: What about other space glyphs like controlHT?
|
||||
idx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if idx > 0 {
|
||||
// Back up to last space.
|
||||
p.textLines = append(p.textLines, string(line[0:idx+1]))
|
||||
|
||||
line = line[idx+1:]
|
||||
line = append(line, val)
|
||||
|
||||
glyphs = glyphs[idx+1:]
|
||||
glyphs = append(glyphs, glyph)
|
||||
widths = widths[idx+1:]
|
||||
widths = append(widths, w)
|
||||
|
||||
lineWidth = 0
|
||||
for _, width := range widths {
|
||||
lineWidth += width
|
||||
}
|
||||
// Remainder of line.
|
||||
line = append(line[idx+1:], val)
|
||||
glyphs = append(glyphs[idx+1:], glyph)
|
||||
widths = append(widths[idx+1:], w)
|
||||
lineWidth = sum(widths)
|
||||
|
||||
} else {
|
||||
p.textLines = append(p.textLines, string(line))
|
||||
line = []rune{val}
|
||||
lineWidth = w
|
||||
widths = []float64{w}
|
||||
glyphs = []string{glyph}
|
||||
widths = []float64{w}
|
||||
lineWidth = w
|
||||
}
|
||||
} else {
|
||||
line = append(line, val)
|
||||
@ -297,6 +289,15 @@ func (p *Paragraph) wrapText() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// sum returns the sums of the elements in `widths`.
|
||||
func sum(widths []float64) float64 {
|
||||
total := 0.0
|
||||
for _, w := range widths {
|
||||
total += w
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
// GeneratePageBlocks generates the page blocks. Multiple blocks are generated if the contents wrap
|
||||
// over multiple pages. Implements the Drawable interface.
|
||||
func (p *Paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
|
||||
@ -360,7 +361,8 @@ func (p *Paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Draw block on specified location on Page, adding to the content stream.
|
||||
// drawParagraphOnBlock draws Paragraph `p` on Block `blk` at the specified location on the page,
|
||||
// adding it to the content stream.
|
||||
func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContext, error) {
|
||||
// Find a free name for the font.
|
||||
num := 1
|
||||
@ -418,7 +420,7 @@ func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContex
|
||||
}
|
||||
metrics, found := p.textFont.GetGlyphCharMetrics(glyph)
|
||||
if !found {
|
||||
common.Log.Debug("Unsupported glyph %s in font\n", glyph)
|
||||
common.Log.Debug("Unsupported glyph %s in font", glyph)
|
||||
return ctx, errors.New("Unsupported text glyph")
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user