From fefff56603b4de6c84955b6018bc203a0ac74ecf Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Wed, 15 Aug 2018 17:36:42 +1000 Subject: [PATCH] Cleaned up some comments in creator. --- pdf/creator/block.go | 4 +-- pdf/creator/creator.go | 46 +++++++++++++-------------- pdf/creator/creator_test.go | 4 +-- pdf/creator/paragraph.go | 62 +++++++++++++++++++------------------ 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/pdf/creator/block.go b/pdf/creator/block.go index 53106818..2ee6f289 100644 --- a/pdf/creator/block.go +++ b/pdf/creator/block.go @@ -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{} diff --git a/pdf/creator/creator.go b/pdf/creator/creator.go index 417f7492..f24803bb 100644 --- a/pdf/creator/creator.go +++ b/pdf/creator/creator.go @@ -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) } diff --git a/pdf/creator/creator_test.go b/pdf/creator/creator_test.go index 49203da5..a5f74f70 100644 --- a/pdf/creator/creator_test.go +++ b/pdf/creator/creator_test.go @@ -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() diff --git a/pdf/creator/paragraph.go b/pdf/creator/paragraph.go index f7af5cc9..a4bb4d72 100644 --- a/pdf/creator/paragraph.go +++ b/pdf/creator/paragraph.go @@ -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") }