Change from paragraph to exported type Paragraph. Address golint issues in creator's chapter.go.

This commit is contained in:
Gunnsteinn Hall 2017-07-31 13:07:02 +00:00
parent 5bc9d83bb1
commit 12f09116a2
4 changed files with 54 additions and 59 deletions

View File

@ -13,10 +13,12 @@ import (
"github.com/unidoc/unidoc/pdf/model/fonts" "github.com/unidoc/unidoc/pdf/model/fonts"
) )
// Chapter is used to arrange multiple drawables (paragraphs, images, etc) into a single section. The concept is
// the same as a book or a report chapter.
type Chapter struct { type Chapter struct {
number int number int
title string title string
heading *paragraph heading *Paragraph
subchapters int subchapters int
@ -41,6 +43,7 @@ type Chapter struct {
toc *TableOfContents toc *TableOfContents
} }
// NewChapter creates a new chapter with the specified title as the heading.
func (c *Creator) NewChapter(title string) *Chapter { func (c *Creator) NewChapter(title string) *Chapter {
chap := &Chapter{} chap := &Chapter{}
@ -65,7 +68,7 @@ func (c *Creator) NewChapter(title string) *Chapter {
return chap return chap
} }
// Set flag to indicate whether or not to show chapter numbers as part of title. // SetShowNumbering sets a flag to indicate whether or not to show chapter numbers as part of title.
func (chap *Chapter) SetShowNumbering(show bool) { func (chap *Chapter) SetShowNumbering(show bool) {
if show { if show {
heading := fmt.Sprintf("%d. %s", chap.number, chap.title) heading := fmt.Sprintf("%d. %s", chap.number, chap.title)
@ -77,26 +80,18 @@ func (chap *Chapter) SetShowNumbering(show bool) {
chap.showNumbering = show chap.showNumbering = show
} }
// Set flag to indicate whether or not to include in tOC. // SetIncludeInTOC sets a flag to indicate whether or not to include in tOC.
func (chap *Chapter) SetIncludeInTOC(includeInTOC bool) { func (chap *Chapter) SetIncludeInTOC(includeInTOC bool) {
chap.includeInTOC = includeInTOC chap.includeInTOC = includeInTOC
} }
// Get access to the heading paragraph to address style etc. // GetHeading returns the chapter heading paragraph. Used to give access to address style: font, sizing etc.
func (chap *Chapter) GetHeading() *paragraph { func (chap *Chapter) GetHeading() *Paragraph {
return chap.heading return chap.heading
} }
/* // SetMargins sets the Chapter margins: left, right, top, bottom.
// Set absolute coordinates. // Typically not needed as the creator's page margins are used.
func (chap *Chapter) SetPos(x, y float64) {
chap.positioning = positionAbsolute
chap.xPos = x
chap.yPos = y
}
*/
// Set chapter Margins. Typically not needed as the Page Margins are used.
func (chap *Chapter) SetMargins(left, right, top, bottom float64) { func (chap *Chapter) SetMargins(left, right, top, bottom float64) {
chap.margins.left = left chap.margins.left = left
chap.margins.right = right chap.margins.right = right
@ -104,12 +99,12 @@ func (chap *Chapter) SetMargins(left, right, top, bottom float64) {
chap.margins.bottom = bottom chap.margins.bottom = bottom
} }
// Get chapter Margins: left, right, top, bottom. // GetMargins returns the Chapter's margin: left, right, top, bottom.
func (chap *Chapter) GetMargins() (float64, float64, float64, float64) { func (chap *Chapter) GetMargins() (float64, float64, float64, float64) {
return chap.margins.left, chap.margins.right, chap.margins.top, chap.margins.bottom return chap.margins.left, chap.margins.right, chap.margins.top, chap.margins.bottom
} }
// Add a new drawable to the chapter. // Add adds a new Drawable to the chapter.
func (chap *Chapter) Add(d Drawable) error { func (chap *Chapter) Add(d Drawable) error {
if Drawable(chap) == d { if Drawable(chap) == d {
common.Log.Debug("ERROR: Cannot add itself") common.Log.Debug("ERROR: Cannot add itself")
@ -120,7 +115,7 @@ func (chap *Chapter) Add(d Drawable) error {
case *Chapter: case *Chapter:
common.Log.Debug("Error: Cannot add chapter to a chapter") common.Log.Debug("Error: Cannot add chapter to a chapter")
return errors.New("Type check error") return errors.New("Type check error")
case *paragraph, *image, *Block, *subchapter, *Table: case *Paragraph, *image, *Block, *subchapter, *Table:
chap.contents = append(chap.contents, d) chap.contents = append(chap.contents, d)
default: default:
common.Log.Debug("Unsupported: %T", d) common.Log.Debug("Unsupported: %T", d)
@ -130,7 +125,7 @@ func (chap *Chapter) Add(d Drawable) error {
return nil return nil
} }
// Generate the Page blocks. Multiple blocks are generated if the contents wrap over // GeneratePageBlocks generate the Page blocks. Multiple blocks are generated if the contents wrap over
// multiple pages. // multiple pages.
func (chap *Chapter) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { func (chap *Chapter) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
origCtx := ctx origCtx := ctx

View File

@ -17,9 +17,9 @@ import (
"github.com/unidoc/unidoc/pdf/model/textencoding" "github.com/unidoc/unidoc/pdf/model/textencoding"
) )
// A paragraph represents text drawn with a specified font and can wrap across lines and pages. // 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 occupies the available width in the drawing context.
type paragraph struct { type Paragraph struct {
// The input utf-8 text as a string (series of runes). // The input utf-8 text as a string (series of runes).
text string text string
@ -67,8 +67,8 @@ type paragraph struct {
// Create a new text block. Uses default parameters: Helvetica, WinAnsiEncoding and wrap enabled // Create a new text block. Uses default parameters: Helvetica, WinAnsiEncoding and wrap enabled
// with a wrap width of 100 points. // with a wrap width of 100 points.
func NewParagraph(text string) *paragraph { func NewParagraph(text string) *Paragraph {
p := &paragraph{} p := &Paragraph{}
p.text = text p.text = text
p.textFont = fonts.NewFontHelvetica() p.textFont = fonts.NewFontHelvetica()
p.SetEncoder(textencoding.NewWinAnsiTextEncoder()) p.SetEncoder(textencoding.NewWinAnsiTextEncoder())
@ -89,54 +89,54 @@ func NewParagraph(text string) *paragraph {
return p return p
} }
func (p *paragraph) SetFont(font fonts.Font) { func (p *Paragraph) SetFont(font fonts.Font) {
p.textFont = font p.textFont = font
} }
func (p *paragraph) SetFontSize(fontSize float64) { func (p *Paragraph) SetFontSize(fontSize float64) {
p.fontSize = fontSize p.fontSize = fontSize
} }
// Alignment of the text within the width provided. // Alignment of the text within the width provided.
func (p *paragraph) SetTextAlignment(align TextAlignment) { func (p *Paragraph) SetTextAlignment(align TextAlignment) {
p.alignment = align p.alignment = align
} }
// Set text encoding. // Set text encoding.
func (p *paragraph) SetEncoder(encoder textencoding.TextEncoder) { func (p *Paragraph) SetEncoder(encoder textencoding.TextEncoder) {
p.encoder = encoder p.encoder = encoder
// Sync with the text font too. // Sync with the text font too.
// XXX/FIXME: Keep in 1 place only. // XXX/FIXME: Keep in 1 place only.
p.textFont.SetEncoder(encoder) p.textFont.SetEncoder(encoder)
} }
func (p *paragraph) SetLineHeight(lineheight float64) { func (p *Paragraph) SetLineHeight(lineheight float64) {
p.lineHeight = lineheight p.lineHeight = lineheight
} }
func (p *paragraph) SetText(text string) { func (p *Paragraph) SetText(text string) {
p.text = text p.text = text
} }
// Set line wrapping enabled flag. // Set line wrapping enabled flag.
func (p *paragraph) SetEnableWrap(enableWrap bool) { func (p *Paragraph) SetEnableWrap(enableWrap bool) {
p.enableWrap = enableWrap p.enableWrap = enableWrap
} }
// Set color of paragraph text. // Set color of Paragraph text.
// //
// Example: // Example:
// 1. p := NewParagraph("Red paragraph") // 1. p := NewParagraph("Red paragraph")
// // Set to red color with a hex code: // // Set to red color with a hex code:
// p.SetColor(creator.ColorRGBFromHex("#ff0000")) // p.SetColor(creator.ColorRGBFromHex("#ff0000"))
// //
// 2. Make paragraph green with 8-bit rgb values (0-255 each component) // 2. Make Paragraph green with 8-bit rgb values (0-255 each component)
// p.SetColor(creator.ColorRGBFrom8bit(0, 255, 0) // p.SetColor(creator.ColorRGBFrom8bit(0, 255, 0)
// //
// 3. Make paragraph blue with arithmetic (0-1) rgb components. // 3. Make Paragraph blue with arithmetic (0-1) rgb components.
// p.SetColor(creator.ColorRGBFromArithmetic(0, 0, 1.0) // p.SetColor(creator.ColorRGBFromArithmetic(0, 0, 1.0)
// //
func (p *paragraph) SetColor(col color) { func (p *Paragraph) SetColor(col color) {
pdfColor := model.NewPdfColorDeviceRGB(col.ToRGB()) pdfColor := model.NewPdfColorDeviceRGB(col.ToRGB())
p.color = *pdfColor p.color = *pdfColor
} }
@ -144,37 +144,37 @@ func (p *paragraph) SetColor(col color) {
// Drawable interface implementations. // Drawable interface implementations.
// Set absolute positioning with specified coordinates. // Set absolute positioning with specified coordinates.
func (p *paragraph) SetPos(x, y float64) { func (p *Paragraph) SetPos(x, y float64) {
p.positioning = positionAbsolute p.positioning = positionAbsolute
p.xPos = x p.xPos = x
p.yPos = y p.yPos = y
} }
// Set rotation angle. // Set rotation angle.
func (p *paragraph) SetAngle(angle float64) { func (p *Paragraph) SetAngle(angle float64) {
p.angle = angle p.angle = angle
} }
// Set paragraph Margins. // Set Paragraph Margins.
func (p *paragraph) SetMargins(left, right, top, bottom float64) { func (p *Paragraph) SetMargins(left, right, top, bottom float64) {
p.margins.left = left p.margins.left = left
p.margins.right = right p.margins.right = right
p.margins.top = top p.margins.top = top
p.margins.bottom = bottom p.margins.bottom = bottom
} }
// Get paragraph Margins: left, right, top, bottom. // Get Paragraph Margins: left, right, top, bottom.
func (p *paragraph) GetMargins() (float64, float64, float64, float64) { func (p *Paragraph) GetMargins() (float64, float64, float64, float64) {
return p.margins.left, p.margins.right, p.margins.top, p.margins.bottom return p.margins.left, p.margins.right, p.margins.top, p.margins.bottom
} }
// Set the paragraph width. Esentially the wrapping width, the width the text can extend to prior to wrapping. // Set the Paragraph width. Esentially the wrapping width, the width the text can extend to prior to wrapping.
func (p *paragraph) SetWidth(width float64) { func (p *Paragraph) SetWidth(width float64) {
p.wrapWidth = width p.wrapWidth = width
p.wrapText() p.wrapText()
} }
func (p *paragraph) Width() float64 { func (p *Paragraph) Width() float64 {
if p.enableWrap { if p.enableWrap {
return p.wrapWidth return p.wrapWidth
} else { } else {
@ -184,7 +184,7 @@ func (p *paragraph) Width() float64 {
// The height is calculated based on the input text and how it is wrapped within the container. // The height is calculated based on the input text and how it is wrapped within the container.
// Height does not include Margins. // Height does not include Margins.
func (p *paragraph) Height() float64 { func (p *Paragraph) Height() float64 {
if p.textLines == nil || len(p.textLines) == 0 { if p.textLines == nil || len(p.textLines) == 0 {
p.wrapText() p.wrapText()
} }
@ -193,23 +193,23 @@ func (p *paragraph) Height() float64 {
return h return h
} }
func (p *paragraph) Scale(sx, sy float64) { func (p *Paragraph) Scale(sx, sy float64) {
p.scaleX = sx p.scaleX = sx
p.scaleY = sy p.scaleY = sy
} }
func (p *paragraph) ScaleToHeight(h float64) { func (p *Paragraph) ScaleToHeight(h float64) {
ratio := h / p.Height() ratio := h / p.Height()
p.Scale(ratio, ratio) p.Scale(ratio, ratio)
} }
func (p *paragraph) ScaleToWidth(w float64) { func (p *Paragraph) ScaleToWidth(w float64) {
ratio := w / p.Width() ratio := w / p.Width()
p.Scale(ratio, ratio) p.Scale(ratio, ratio)
} }
// Calculate the text width (if not wrapped). // Calculate the text width (if not wrapped).
func (p *paragraph) getTextWidth() float64 { func (p *Paragraph) getTextWidth() float64 {
w := float64(0.0) w := float64(0.0)
for _, rune := range p.text { for _, rune := range p.text {
@ -232,7 +232,7 @@ func (p *paragraph) getTextWidth() float64 {
// Simple algorithm to wrap the text into lines (greedy algorithm - fill the lines). // Simple algorithm to wrap the text into lines (greedy algorithm - fill the lines).
// XXX/TODO: Consider the Knuth/Plass algorithm or an alternative. // XXX/TODO: Consider the Knuth/Plass algorithm or an alternative.
func (p *paragraph) wrapText() error { func (p *Paragraph) wrapText() error {
if !p.enableWrap { if !p.enableWrap {
p.textLines = []string{p.encoder.Encode(p.text)} p.textLines = []string{p.encoder.Encode(p.text)}
return nil return nil
@ -310,13 +310,13 @@ func (p *paragraph) wrapText() error {
// Generate the Page blocks. Multiple blocks are generated if the contents wrap over // Generate the Page blocks. Multiple blocks are generated if the contents wrap over
// multiple pages. // multiple pages.
func (p *paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { func (p *Paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
origContext := ctx origContext := ctx
blocks := []*Block{} blocks := []*Block{}
blk := NewBlock(ctx.PageWidth, ctx.PageHeight) blk := NewBlock(ctx.PageWidth, ctx.PageHeight)
if p.positioning.isRelative() { if p.positioning.isRelative() {
// Account for paragraph Margins. // Account for Paragraph Margins.
ctx.X += p.margins.left ctx.X += p.margins.left
ctx.Y += p.margins.top ctx.Y += p.margins.top
ctx.Width -= p.margins.left + p.margins.right ctx.Width -= p.margins.left + p.margins.right
@ -328,7 +328,7 @@ func (p *paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
if p.Height() > ctx.Height { if p.Height() > ctx.Height {
// Goes out of the bounds. Write on a new template instead and create a new context at upper // Goes out of the bounds. Write on a new template instead and create a new context at upper
// left corner. // left corner.
// XXX/TODO: Handle case when paragraph is larger than the Page... // XXX/TODO: Handle case when Paragraph is larger than the Page...
// Should be fine if we just break on the paragraph, i.e. splitting it up over 2+ pages // Should be fine if we just break on the paragraph, i.e. splitting it up over 2+ pages
blocks = append(blocks, blk) blocks = append(blocks, blk)
@ -353,7 +353,7 @@ func (p *paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
ctx.Y = p.yPos ctx.Y = p.yPos
} }
// Place the paragraph on the template at position (x,y) based on the ctx. // Place the Paragraph on the template at position (x,y) based on the ctx.
ctx, err := drawParagraphOnBlock(blk, p, ctx) ctx, err := drawParagraphOnBlock(blk, p, ctx)
if err != nil { if err != nil {
common.Log.Debug("ERROR: %v", err) common.Log.Debug("ERROR: %v", err)
@ -372,7 +372,7 @@ func (p *paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
} }
// Draw block on specified location on Page, adding to the content stream. // Draw block on specified location on Page, adding to the content stream.
func drawParagraphOnBlock(blk *Block, p *paragraph, ctx DrawContext) (DrawContext, error) { func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContext, error) {
// Find a free name for the font. // Find a free name for the font.
num := 1 num := 1
fontName := core.PdfObjectName(fmt.Sprintf("Font%d", num)) fontName := core.PdfObjectName(fmt.Sprintf("Font%d", num))

View File

@ -18,7 +18,7 @@ type subchapter struct {
chapterNum int chapterNum int
subchapterNum int subchapterNum int
title string title string
heading *paragraph heading *Paragraph
contents []Drawable contents []Drawable
@ -88,8 +88,8 @@ func (subchap *subchapter) SetIncludeInTOC(includeInTOC bool) {
subchap.includeInTOC = includeInTOC subchap.includeInTOC = includeInTOC
} }
// Get access to the heading paragraph to address style etc. // Get access to the heading Paragraph to address style etc.
func (subchap *subchapter) GetHeading() *paragraph { func (subchap *subchapter) GetHeading() *Paragraph {
return subchap.heading return subchap.heading
} }
@ -120,7 +120,7 @@ func (subchap *subchapter) Add(d Drawable) {
switch d.(type) { switch d.(type) {
case *Chapter, *subchapter: case *Chapter, *subchapter:
common.Log.Debug("Error: Cannot add chapter or subchapter to a subchapter") common.Log.Debug("Error: Cannot add chapter or subchapter to a subchapter")
case *paragraph, *image, *Block, *Table: case *Paragraph, *image, *Block, *Table:
subchap.contents = append(subchap.contents, d) subchap.contents = append(subchap.contents, d)
default: default:
common.Log.Debug("Unsupported: %T", d) common.Log.Debug("Unsupported: %T", d)

View File

@ -499,7 +499,7 @@ func (cell *tableCell) Width(ctx DrawContext) float64 {
// Set cell content. The content is a vector drawable, i.e. a drawable with a known height and width. // Set cell content. The content is a vector drawable, i.e. a drawable with a known height and width.
func (cell *tableCell) SetContent(vd VectorDrawable) error { func (cell *tableCell) SetContent(vd VectorDrawable) error {
switch t := vd.(type) { switch t := vd.(type) {
case *paragraph: case *Paragraph:
// Default paragraph settings in table: // Default paragraph settings in table:
t.SetEnableWrap(false) // No wrapping. t.SetEnableWrap(false) // No wrapping.
h := cell.table.rowHeights[cell.row-1] h := cell.table.rowHeights[cell.row-1]