Cleaned up some comments in creator.

This commit is contained in:
Peter Williams 2018-08-15 17:36:42 +10:00
parent ffa7f9b482
commit fefff56603
4 changed files with 58 additions and 58 deletions

View File

@ -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{}

View File

@ -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)
}

View File

@ -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()

View File

@ -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")
}