diff --git a/pdf/creator/chapters.go b/pdf/creator/chapters.go index 5b99d72c..b0c86459 100644 --- a/pdf/creator/chapters.go +++ b/pdf/creator/chapters.go @@ -115,7 +115,7 @@ func (chap *Chapter) Add(d Drawable) error { case *Chapter: common.Log.Debug("Error: Cannot add chapter to a chapter") return errors.New("Type check error") - case *Paragraph, *Image, *Block, *subchapter, *Table: + case *Paragraph, *Image, *Block, *Subchapter, *Table: chap.contents = append(chap.contents, d) default: common.Log.Debug("Unsupported: %T", d) diff --git a/pdf/creator/paragraph.go b/pdf/creator/paragraph.go index babb71ec..80a4b071 100644 --- a/pdf/creator/paragraph.go +++ b/pdf/creator/paragraph.go @@ -65,7 +65,7 @@ type Paragraph struct { textLines []string } -// Create a new text block. Uses default parameters: Helvetica, WinAnsiEncoding and wrap enabled +// NewParagraph create a new text paragraph. Uses default parameters: Helvetica, WinAnsiEncoding and wrap enabled // with a wrap width of 100 points. func NewParagraph(text string) *Paragraph { p := &Paragraph{} @@ -89,20 +89,22 @@ func NewParagraph(text string) *Paragraph { return p } +// SetFont sets the Paragraph's font. func (p *Paragraph) SetFont(font fonts.Font) { p.textFont = font } +// SetFontSize sets the font size in document units (points). func (p *Paragraph) SetFontSize(fontSize float64) { p.fontSize = fontSize } -// Alignment of the text within the width provided. +// SetTextAlignment sets the horizontal alignment of the text within the space provided. func (p *Paragraph) SetTextAlignment(align TextAlignment) { p.alignment = align } -// Set text encoding. +// SetEncoder sets the text encoding. func (p *Paragraph) SetEncoder(encoder textencoding.TextEncoder) { p.encoder = encoder // Sync with the text font too. @@ -110,20 +112,22 @@ func (p *Paragraph) SetEncoder(encoder textencoding.TextEncoder) { p.textFont.SetEncoder(encoder) } +// SetLineHeight sets the line height (1.0 default). func (p *Paragraph) SetLineHeight(lineheight float64) { p.lineHeight = lineheight } +// SetText sets the text content of the Paragraph. func (p *Paragraph) SetText(text string) { p.text = text } -// Set line wrapping enabled flag. +// SetEnableWrap sets the line wrapping enabled flag. func (p *Paragraph) SetEnableWrap(enableWrap bool) { p.enableWrap = enableWrap } -// Set color of Paragraph text. +// SetColor set the color of the Paragraph text. // // Example: // 1. p := NewParagraph("Red paragraph") @@ -141,21 +145,19 @@ func (p *Paragraph) SetColor(col Color) { p.color = *pdfColor } -// Drawable interface implementations. - -// Set absolute positioning with specified coordinates. +// SetPos sets absolute positioning with specified coordinates. func (p *Paragraph) SetPos(x, y float64) { p.positioning = positionAbsolute p.xPos = x p.yPos = y } -// Set rotation angle. +// SetAngle sets the rotation angle of the text. func (p *Paragraph) SetAngle(angle float64) { p.angle = angle } -// Set Paragraph Margins. +// SetMargins sets the Paragraph's margins. func (p *Paragraph) SetMargins(left, right, top, bottom float64) { p.margins.left = left p.margins.right = right @@ -163,17 +165,19 @@ func (p *Paragraph) SetMargins(left, right, top, bottom float64) { p.margins.bottom = bottom } -// Get Paragraph Margins: left, right, top, bottom. +// GetMargins returns the Paragraph's margins: left, right, top, bottom. func (p *Paragraph) GetMargins() (float64, float64, float64, float64) { 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. +// SetWidth sets the the Paragraph width. This is essentially the wrapping width, i.e. the width the text can extend to +// prior to wrapping over to next line. func (p *Paragraph) SetWidth(width float64) { p.wrapWidth = width p.wrapText() } +// Width returns the width of the Paragraph. func (p *Paragraph) Width() float64 { if p.enableWrap { return p.wrapWidth @@ -182,8 +186,8 @@ func (p *Paragraph) Width() float64 { } } -// The height is calculated based on the input text and how it is wrapped within the container. -// Height does not include Margins. +// Height returns the height of the Paragraph. The height is calculated based on the input text and how it is wrapped +// within the container. Does not include Margins. func (p *Paragraph) Height() float64 { if p.textLines == nil || len(p.textLines) == 0 { p.wrapText() @@ -193,21 +197,6 @@ func (p *Paragraph) Height() float64 { return h } -func (p *Paragraph) Scale(sx, sy float64) { - p.scaleX = sx - p.scaleY = sy -} - -func (p *Paragraph) ScaleToHeight(h float64) { - ratio := h / p.Height() - p.Scale(ratio, ratio) -} - -func (p *Paragraph) ScaleToWidth(w float64) { - ratio := w / p.Width() - p.Scale(ratio, ratio) -} - // Calculate the text width (if not wrapped). func (p *Paragraph) getTextWidth() float64 { w := float64(0.0) @@ -308,8 +297,8 @@ func (p *Paragraph) wrapText() error { return nil } -// Generate the Page blocks. Multiple blocks are generated if the contents wrap over -// multiple pages. +// 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) { origContext := ctx blocks := []*Block{} diff --git a/pdf/creator/rectangle.go b/pdf/creator/rectangle.go index ca6bf5e9..35ac6db5 100644 --- a/pdf/creator/rectangle.go +++ b/pdf/creator/rectangle.go @@ -10,12 +10,10 @@ import ( "github.com/unidoc/unidoc/pdf/model" ) -// -// Defines a rectangle with upper left corner at (x,y) and a specified width and height. The rectangle +// Rectangle defines a rectangle with upper left corner at (x,y) and a specified width and height. The rectangle // can have a colored fill and/or border with a specified width. // Implements the Drawable interface and can be drawn on PDF using the Creator. -// -type rectangle struct { +type Rectangle struct { x float64 // Upper left corner y float64 width float64 @@ -25,9 +23,9 @@ type rectangle struct { borderWidth float64 } -// Generate a new line with default parameters between (x1,y1) to (x2,y2). -func NewRectangle(x, y, width, height float64) *rectangle { - rect := &rectangle{} +// NewRectangle creates a new Rectangle with default parameters with left corner at (x,y) and width, height as specified. +func NewRectangle(x, y, width, height float64) *Rectangle { + rect := &Rectangle{} rect.x = x rect.y = y @@ -40,28 +38,28 @@ func NewRectangle(x, y, width, height float64) *rectangle { return rect } -// Get the coords of the upper left corner (x,y). -func (rect *rectangle) GetCoords() (float64, float64) { +// GetCoords returns coordinates of the Rectangle's upper left corner (x,y). +func (rect *Rectangle) GetCoords() (float64, float64) { return rect.x, rect.y } -// Set border width. -func (rect *rectangle) SetBorderWidth(bw float64) { +// SetBorderWidth sets the border width. +func (rect *Rectangle) SetBorderWidth(bw float64) { rect.borderWidth = bw } -// Set border color. -func (rect *rectangle) SetBorderColor(col Color) { +// SetBorderColor sets border color. +func (rect *Rectangle) SetBorderColor(col Color) { rect.borderColor = model.NewPdfColorDeviceRGB(col.ToRGB()) } -// Set fill color. -func (rect *rectangle) SetFillColor(col Color) { +// SetFillColor sets the fill color. +func (rect *Rectangle) SetFillColor(col Color) { rect.fillColor = model.NewPdfColorDeviceRGB(col.ToRGB()) } -// Draws the rectangle on a new block representing the page. -func (rect *rectangle) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { +// GeneratePageBlocks draws the rectangle on a new block representing the page. Implements the Drawable interface. +func (rect *Rectangle) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { block := NewBlock(ctx.PageWidth, ctx.PageHeight) drawrect := draw.Rectangle{ diff --git a/pdf/creator/subchapter.go b/pdf/creator/subchapter.go index f39372ad..f38c7b3e 100644 --- a/pdf/creator/subchapter.go +++ b/pdf/creator/subchapter.go @@ -12,9 +12,9 @@ import ( "github.com/unidoc/unidoc/pdf/model/fonts" ) -// A subchapter simply represents a subchapter pertaining to a specific chapter. It can contain multiple -// drawables, just like a chapter. -type subchapter struct { +// Subchapter simply represents a sub chapter pertaining to a specific Chapter. It can contain multiple +// Drawables, just like a chapter. +type Subchapter struct { chapterNum int subchapterNum int title string @@ -41,8 +41,10 @@ type subchapter struct { toc *TableOfContents } -func (c *Creator) NewSubchapter(ch *Chapter, title string) *subchapter { - subchap := &subchapter{} +// NewSubchapter creates a new Subchapter under Chapter ch with specified title. +// All other parameters are set to their defaults. +func (c *Creator) NewSubchapter(ch *Chapter, title string) *Subchapter { + subchap := &Subchapter{} ch.subchapters++ subchap.subchapterNum = ch.subchapters @@ -71,8 +73,8 @@ func (c *Creator) NewSubchapter(ch *Chapter, title string) *subchapter { return subchap } -// Set flag to indicate whether or not to show chapter numbers as part of title. -func (subchap *subchapter) SetShowNumbering(show bool) { +// SetShowNumbering sets a flag to indicate whether or not to show chapter numbers as part of title. +func (subchap *Subchapter) SetShowNumbering(show bool) { if show { heading := fmt.Sprintf("%d.%d. %s", subchap.chapterNum, subchap.subchapterNum, subchap.title) subchap.heading.SetText(heading) @@ -83,13 +85,13 @@ func (subchap *subchapter) SetShowNumbering(show bool) { subchap.showNumbering = show } -// Set flag to indicate whether or not to include in the table of contents. -func (subchap *subchapter) SetIncludeInTOC(includeInTOC bool) { +// SetIncludeInTOC sets a flag to indicate whether or not to include in the table of contents. +func (subchap *Subchapter) SetIncludeInTOC(includeInTOC bool) { subchap.includeInTOC = includeInTOC } -// Get access to the heading Paragraph to address style etc. -func (subchap *subchapter) GetHeading() *Paragraph { +// GetHeading returns the Subchapter's heading Paragraph to address style (font type, size, etc). +func (subchap *Subchapter) GetHeading() *Paragraph { return subchap.heading } @@ -102,23 +104,25 @@ func (subchap *subchapter) SetPos(x, y float64) { } */ -// Set chapter Margins. Typically not needed as the Page Margins are used. -func (subchap *subchapter) SetMargins(left, right, top, bottom float64) { +// SetMargins sets the Subchapter's margins (left, right, top, bottom). +// These margins are typically not needed as the Creator's page margins are used preferably. +func (subchap *Subchapter) SetMargins(left, right, top, bottom float64) { subchap.margins.left = left subchap.margins.right = right subchap.margins.top = top subchap.margins.bottom = bottom } -// Get the subchapter Margins: left, right, top, bototm. -func (subchap *subchapter) GetMargins() (float64, float64, float64, float64) { +// GetMargins returns the Subchapter's margins: left, right, top, bottom. +func (subchap *Subchapter) GetMargins() (float64, float64, float64, float64) { return subchap.margins.left, subchap.margins.right, subchap.margins.top, subchap.margins.bottom } -// Add a new drawable to the chapter. -func (subchap *subchapter) Add(d Drawable) { +// Add adds a new Drawable to the chapter. +// The currently supported Drawables are: *Paragraph, *Image, *Block, *Table. +func (subchap *Subchapter) Add(d Drawable) { switch d.(type) { - case *Chapter, *subchapter: + case *Chapter, *Subchapter: common.Log.Debug("Error: Cannot add chapter or subchapter to a subchapter") case *Paragraph, *Image, *Block, *Table: subchap.contents = append(subchap.contents, d) @@ -127,9 +131,9 @@ func (subchap *subchapter) Add(d Drawable) { } } -// Generate the Page blocks. Multiple blocks are generated if the contents wrap over -// multiple pages. -func (subchap *subchapter) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { +// GeneratePageBlocks generates the page blocks. Multiple blocks are generated if the contents wrap over +// multiple pages. Implements the Drawable interface. +func (subchap *Subchapter) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { origCtx := ctx if subchap.positioning.isRelative() { diff --git a/pdf/creator/table.go b/pdf/creator/table.go index d78c0006..a38d006b 100644 --- a/pdf/creator/table.go +++ b/pdf/creator/table.go @@ -33,7 +33,7 @@ type Table struct { defaultRowHeight float64 // Content cells. - cells []*tableCell + cells []*TableCell // Positioning: relative / absolute. positioning positioning @@ -45,7 +45,7 @@ type Table struct { margins margins } -// Create a new table with a fixed rows and column size. +// NewTable create a new Table with a specified number of columns. func NewTable(cols int) *Table { t := &Table{} t.rows = 0 @@ -66,13 +66,14 @@ func NewTable(cols int) *Table { // XXX/TODO: Base on contents instead? t.defaultRowHeight = 10.0 - t.cells = []*tableCell{} + t.cells = []*TableCell{} return t } -// Set the fractional column widths. Number of width inputs must match number of columns. +// SetColumnWidths sets the fractional column widths. // Each width should be in the range 0-1 and is a fraction of the table width. +// The number of width inputs must match number of columns, otherwise an error is returned. func (table *Table) SetColumnWidths(widths ...float64) error { if len(widths) != table.cols { common.Log.Debug("Mismatching number of widths and columns") @@ -84,7 +85,7 @@ func (table *Table) SetColumnWidths(widths ...float64) error { return nil } -// Total height of all rows. +// Height returns the total height of all rows. func (table *Table) Height() float64 { sum := float64(0.0) for _, h := range table.rowHeights { @@ -94,7 +95,7 @@ func (table *Table) Height() float64 { return sum } -// Set the left, right, top, bottom Margins. +// SetMargins sets the Table's left, right, top, bottom margins. func (table *Table) SetMargins(left, right, top, bottom float64) { table.margins.left = left table.margins.right = right @@ -102,12 +103,12 @@ func (table *Table) SetMargins(left, right, top, bottom float64) { table.margins.bottom = bottom } -// Get the left, right, top, bottom Margins. +// GetMargins returns the left, right, top, bottom Margins. func (table *Table) GetMargins() (float64, float64, float64, float64) { return table.margins.left, table.margins.right, table.margins.top, table.margins.bottom } -// Set the height for a specified row. +// SetRowHeight sets the height for a specified row. func (table *Table) SetRowHeight(row int, h float64) error { if row < 1 || row > len(table.rowHeights) { return errors.New("Range check error") @@ -117,30 +118,30 @@ func (table *Table) SetRowHeight(row int, h float64) error { return nil } -// Get row of the current cell position. +// CurRow returns the currently active cell's row number. func (table *Table) CurRow() int { curRow := (table.curCell-1)/table.cols + 1 return curRow } -// Get column of the current cell position. +// CurCol returns the currently active cell's column number. func (table *Table) CurCol() int { curCol := (table.curCell-1)%(table.cols) + 1 return curCol } -// Set absolute coordinates. +// SetPos sets the Table's positioning to absolute mode and specifies the upper-left corner coordinates as (x,y). // Note that this is only sensible to use when the table does not wrap over multiple pages. -// XXX/TODO: Should be able to set width too (not just based on context/relative positioning mode). +// TODO: Should be able to set width too (not just based on context/relative positioning mode). func (table *Table) SetPos(x, y float64) { table.positioning = positionAbsolute table.xPos = x table.yPos = y } -// Generate the Page blocks. Multiple blocks are generated if the contents wrap over multiple pages. +// GeneratePageBlocks generate the page blocks. Multiple blocks are generated if the contents wrap over multiple pages. +// Implements the Drawable interface. func (table *Table) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { - blocks := []*Block{} block := NewBlock(ctx.PageWidth, ctx.PageHeight) @@ -311,7 +312,7 @@ func (table *Table) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, return blocks, ctx, nil } -// Define table cell's border style. +// CellBorderStyle defines the table cell's border style. type CellBorderStyle int // Currently supported table styles are: None (no border) and boxed (line along each side). @@ -323,9 +324,10 @@ const ( CellBorderStyleBox ) -// Define table cell's horizontal alignment. +// CellHorizontalAlignment defines the table cell's horizontal alignment. type CellHorizontalAlignment int +// Table cells have three horizontal alignment modes: left, center and right. const ( // Align cell content on the left (with specified indent); unused space on the right. CellHorizontalAlignmentLeft CellHorizontalAlignment = iota @@ -337,9 +339,10 @@ const ( CellHorizontalAlignmentRight ) -// Define table cell's vertical alignment. +// CellVerticalAlignment defines the table cell's vertical alignment. type CellVerticalAlignment int +// Table cells have three vertical alignment modes: top, middle and bottom. const ( // Align cell content vertically to the top; unused space below. CellVerticalAlignmentTop CellVerticalAlignment = iota @@ -351,8 +354,8 @@ const ( CellVerticalAlignmentBottom ) -// Table cell -type tableCell struct { +// TableCell defines a table cell which can contain a Drawable as content. +type TableCell struct { // Background backgroundColor *model.PdfColorDeviceRGB @@ -382,8 +385,8 @@ type tableCell struct { table *Table } -// Make a new cell and insert into the table at current position in the table. -func (table *Table) NewCell() *tableCell { +// NewCell makes a new cell and inserts into the table at current position in the table. +func (table *Table) NewCell() *TableCell { table.curCell++ curRow := (table.curCell-1)/table.cols + 1 @@ -393,7 +396,7 @@ func (table *Table) NewCell() *tableCell { } curCol := (table.curCell-1)%(table.cols) + 1 - cell := &tableCell{} + cell := &TableCell{} cell.row = curRow cell.col = curCol @@ -418,7 +421,7 @@ func (table *Table) NewCell() *tableCell { return cell } -// Skip over a specified number of cells. +// SkipCells skips over a specified number of cells in the table. func (table *Table) SkipCells(num int) { if num < 0 { common.Log.Debug("Table: cannot skip back to previous cells") @@ -427,7 +430,7 @@ func (table *Table) SkipCells(num int) { table.curCell += num } -// Skip over a specified number of rows. +// SkipRows skips over a specified number of rows in the table. func (table *Table) SkipRows(num int) { ncells := num*table.cols - 1 if ncells < 0 { @@ -437,7 +440,7 @@ func (table *Table) SkipRows(num int) { table.curCell += ncells } -// Skip over rows, cols. +// SkipOver skips over a specified number of rows and cols. func (table *Table) SkipOver(rows, cols int) { ncells := rows*table.cols + cols - 1 if ncells < 0 { @@ -447,47 +450,47 @@ func (table *Table) SkipOver(rows, cols int) { table.curCell += ncells } -// Set cell's left indent. -func (cell *tableCell) SetIndent(indent float64) { +// SetIndent sets the cell's left indent. +func (cell *TableCell) SetIndent(indent float64) { cell.indent = indent } -// Set cell's horizontal alignment of content. +// SetHorizontalAlignment sets the cell's horizontal alignment of content. // Can be one of: // - CellHorizontalAlignmentLeft // - CellHorizontalAlignmentCenter // - CellHorizontalAlignmentRight -func (cell *tableCell) SetHorizontalAlignment(halign CellHorizontalAlignment) { +func (cell *TableCell) SetHorizontalAlignment(halign CellHorizontalAlignment) { cell.horizontalAlignment = halign } -// Set cell's vertical alignment of content. +// SetVerticalAlignment set the cell's vertical alignment of content. // Can be one of: // - CellHorizontalAlignmentTop // - CellHorizontalAlignmentMiddle // - CellHorizontalAlignmentBottom -func (cell *tableCell) SetVerticalAlignment(valign CellVerticalAlignment) { +func (cell *TableCell) SetVerticalAlignment(valign CellVerticalAlignment) { cell.verticalAlignment = valign } -// Set cell's border style. -func (cell *tableCell) SetBorder(style CellBorderStyle, width float64) { +// SetBorder sets the cell's border style. +func (cell *TableCell) SetBorder(style CellBorderStyle, width float64) { cell.borderStyle = style cell.borderWidth = width } -// Set border color. -func (cell *tableCell) SetBorderColor(color rgbColor) { +// SetBorderColor sets the cell's border color. +func (cell *TableCell) SetBorderColor(color rgbColor) { cell.borderColor = model.NewPdfColorDeviceRGB(color.r, color.g, color.b) } -// Set cell's background color. -func (cell *tableCell) SetBackgroundColor(col Color) { +// SetBackgroundColor sets the cell's background color. +func (cell *TableCell) SetBackgroundColor(col Color) { cell.backgroundColor = model.NewPdfColorDeviceRGB(col.ToRGB()) } -// Get cell width based on input draw context. -func (cell *tableCell) Width(ctx DrawContext) float64 { +// Width returns the cell's width based on the input draw context. +func (cell *TableCell) Width(ctx DrawContext) float64 { fraction := float64(0.0) for j := 0; j < cell.colspan; j++ { fraction += cell.table.colWidths[cell.col+j-1] @@ -496,8 +499,10 @@ func (cell *tableCell) Width(ctx DrawContext) float64 { return w } -// 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 { +// SetContent sets the cell's content. The content is a VectorDrawable, i.e. a Drawable with a known height and width. +// The currently supported VectorDrawable is: *Paragraph. +// TODO: Add support for *Image, *Block. +func (cell *TableCell) SetContent(vd VectorDrawable) error { switch t := vd.(type) { case *Paragraph: // Default paragraph settings in table: diff --git a/pdf/creator/toc.go b/pdf/creator/toc.go index 4c8390a7..108ee460 100644 --- a/pdf/creator/toc.go +++ b/pdf/creator/toc.go @@ -5,26 +5,26 @@ package creator -// The table of contents has overview over chapters and subchapters. +// TableOfContents provides an overview over chapters and subchapters when creating a document with Creator. type TableOfContents struct { - entries []tableOfContentsEntry + entries []TableOfContentsEntry } // Make a new table of contents. func newTableOfContents() *TableOfContents { toc := TableOfContents{} - toc.entries = []tableOfContentsEntry{} + toc.entries = []TableOfContentsEntry{} return &toc } -// Get table of content entries. -func (toc *TableOfContents) Entries() []tableOfContentsEntry { +// Entries returns the table of content entries. +func (toc *TableOfContents) Entries() []TableOfContentsEntry { return toc.entries } // Add a TOC entry. func (toc *TableOfContents) add(title string, chapter, subchapter, pageNum int) { - entry := tableOfContentsEntry{} + entry := TableOfContentsEntry{} entry.Title = title entry.Chapter = chapter entry.Subchapter = subchapter @@ -33,8 +33,9 @@ func (toc *TableOfContents) add(title string, chapter, subchapter, pageNum int) toc.entries = append(toc.entries, entry) } -// Each TOC entry has title, chapter number, sub chapter (0 if chapter) and the page number. -type tableOfContentsEntry struct { +// TableOfContentsEntry defines a single entry in the TableOfContents. +// Each entry has a title, chapter number, sub chapter (0 if chapter) and the page number. +type TableOfContentsEntry struct { Title string Chapter int Subchapter int // 0 if chapter