From ac7d2d72ff6ecf0d26235b607d59213a47174981 Mon Sep 17 00:00:00 2001 From: Adrian-George Bostan Date: Fri, 12 Oct 2018 19:35:04 +0300 Subject: [PATCH 1/4] Change font rename scheme on name collision --- pdf/creator/block.go | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/pdf/creator/block.go b/pdf/creator/block.go index 9903612e..6fba2a84 100644 --- a/pdf/creator/block.go +++ b/pdf/creator/block.go @@ -8,6 +8,8 @@ package creator import ( "errors" "fmt" + "strings" + "unicode" "github.com/unidoc/unidoc/common" "github.com/unidoc/unidoc/pdf/contentstream" @@ -391,18 +393,12 @@ func mergeContents(contents *contentstream.ContentStreamOperations, resources *m if len(op.Params) == 2 { if name, ok := op.Params[0].(*core.PdfObjectName); ok { if _, processed := fontMap[*name]; !processed { - var useName core.PdfObjectName // Process if not already processed. obj, found := resourcesToAdd.GetFontByName(*name) - if found { - useName = *name - for { - obj2, found := resources.GetFontByName(useName) - if !found || obj2 == obj { - break - } - useName = useName + "0" - } + + useName := *name + if found && obj != nil { + useName = resourcesNextUnusedFontName(name.String(), obj, resources) } resources.SetFontByName(useName, obj) @@ -548,3 +544,27 @@ func mergeContents(contents *contentstream.ContentStreamOperations, resources *m return nil } + +func resourcesNextUnusedFontName(name string, font core.PdfObject, resources *model.PdfPageResources) core.PdfObjectName { + prefix := strings.TrimRightFunc(strings.TrimSpace(name), func(r rune) bool { + return unicode.IsNumber(r) + }) + if prefix == "" { + prefix = "Font" + } + + num := 0 + fontName := core.PdfObjectName(name) + + for { + f, found := resources.GetFontByName(fontName) + if !found || f == font { + break + } + + num++ + fontName = core.PdfObjectName(fmt.Sprintf("%s%d", prefix, num)) + } + + return fontName +} From 90ba15f56d3a354839ae034d1b9141d2c2ee872a Mon Sep 17 00:00:00 2001 From: Adrian-George Bostan Date: Fri, 12 Oct 2018 23:00:02 +0300 Subject: [PATCH 2/4] Instantiate component only through creator and cache default fonts --- pdf/creator/chapters.go | 36 +-- pdf/creator/const.go | 3 +- pdf/creator/creator.go | 160 +++++++++- pdf/creator/creator_test.go | 461 ++++++++++++++------------- pdf/creator/curve.go | 4 +- pdf/creator/curve_test.go | 28 +- pdf/creator/division.go | 4 +- pdf/creator/division_test.go | 82 +++-- pdf/creator/ellipse.go | 4 +- pdf/creator/filled_curve.go | 4 +- pdf/creator/filled_curve_test.go | 5 +- pdf/creator/image.go | 22 +- pdf/creator/line.go | 4 +- pdf/creator/pagebreak.go | 4 +- pdf/creator/paragraph.go | 5 +- pdf/creator/rectangle.go | 4 +- pdf/creator/styled_paragraph.go | 94 ++---- pdf/creator/styled_paragraph_test.go | 108 +++++-- pdf/creator/subchapter.go | 42 +-- pdf/creator/table.go | 15 +- pdf/creator/table_test.go | 20 +- pdf/creator/text_style.go | 14 +- pdf/creator/toc.go | 29 +- pdf/creator/toc_line.go | 35 +- pdf/creator/toc_test.go | 10 +- 25 files changed, 687 insertions(+), 510 deletions(-) diff --git a/pdf/creator/chapters.go b/pdf/creator/chapters.go index 2502ab0c..92af7960 100644 --- a/pdf/creator/chapters.go +++ b/pdf/creator/chapters.go @@ -11,7 +11,6 @@ import ( "strconv" "github.com/unidoc/unidoc/common" - "github.com/unidoc/unidoc/pdf/model" ) // Chapter is used to arrange multiple drawables (paragraphs, images, etc) into a single section. @@ -44,30 +43,21 @@ type Chapter struct { toc *TOC } -// NewChapter creates a new chapter with the specified title as the heading. -func (c *Creator) NewChapter(title string) *Chapter { - chap := &Chapter{} - - c.chapters++ - chap.number = c.chapters - chap.title = title - - chap.showNumbering = true - chap.includeInTOC = true - - heading := fmt.Sprintf("%d. %s", c.chapters, title) - p := NewParagraph(heading) +// newChapter creates a new chapter with the specified title as the heading. +func newChapter(toc *TOC, title string, number int, style TextStyle) *Chapter { + p := newParagraph(fmt.Sprintf("%d. %s", number, title), style) + p.SetFont(style.Font) p.SetFontSize(16) - helvetica := model.NewStandard14FontMustCompile(model.Helvetica) - p.SetFont(helvetica) // bold? - chap.heading = p - chap.contents = []Drawable{} - - // Keep a reference for toc. - chap.toc = c.toc - - return chap + return &Chapter{ + number: number, + title: title, + showNumbering: true, + includeInTOC: true, + toc: toc, + heading: p, + contents: []Drawable{}, + } } // SetShowNumbering sets a flag to indicate whether or not to show chapter numbers as part of title. diff --git a/pdf/creator/const.go b/pdf/creator/const.go index b923c67f..d75e7b26 100644 --- a/pdf/creator/const.go +++ b/pdf/creator/const.go @@ -12,7 +12,8 @@ type PageSize [2]float64 var PPI float64 = 72 // Points per inch. (Default resolution). // PPMM specifies the default PDF resolution in points/mm. -var PPMM float64 = 72 * 1.0 / 25.4 // Points per mm. (Default resolution). +// Points per mm. (Default resolution). +var PPMM = float64(72 * 1.0 / 25.4) // // Commonly used page sizes diff --git a/pdf/creator/creator.go b/pdf/creator/creator.go index 89b15a37..669a525c 100644 --- a/pdf/creator/creator.go +++ b/pdf/creator/creator.go @@ -7,12 +7,14 @@ package creator import ( "errors" + goimage "image" "io" "os" "strconv" "github.com/unidoc/unidoc/common" "github.com/unidoc/unidoc/pdf/model" + "github.com/unidoc/unidoc/pdf/model/textencoding" ) // Creator is a wrapper around functionality for creating PDF reports and/or adding new @@ -51,6 +53,13 @@ type Creator struct { acroForm *model.PdfAcroForm optimizer model.Optimizer + + // Default fonts used by all components instantiated through the creator. + defaultFontRegular *model.PdfFont + defaultFontBold *model.PdfFont + + // Default encoder used by all components instantiated through the creator. + defaultTextEncoder textencoding.TextEncoder } // SetForms adds an Acroform to a PDF file. Sets the specified form for writing. @@ -103,7 +112,26 @@ func New() *Creator { c.pageMargins.top = m c.pageMargins.bottom = m - c.toc = NewTOC("Table of Contents") + // Initialize default text encoder. + c.defaultTextEncoder = textencoding.NewWinAnsiTextEncoder() + + // Initialize default fonts. + var err error + + c.defaultFontRegular, err = model.NewStandard14Font(model.Helvetica) + if err != nil { + c.defaultFontRegular = model.DefaultFont() + } + c.defaultFontRegular.SetEncoder(c.defaultTextEncoder) + + c.defaultFontBold, err = model.NewStandard14Font(model.HelveticaBold) + if err != nil { + c.defaultFontRegular = model.DefaultFont() + } + c.defaultFontBold.SetEncoder(c.defaultTextEncoder) + + // Initialize creator table of contents. + c.toc = c.NewTOC("Table of Contents") return c } @@ -288,7 +316,7 @@ func (c *Creator) RotateDeg(angleDeg int64) error { } // Do the rotation. - var rotation int64 = 0 + var rotation int64 if page.Rotate != nil { rotation = *(page.Rotate) } @@ -566,3 +594,131 @@ func (c *Creator) WriteToFile(outputPath string) error { return c.Write(fWrite) } + +/* +Component creation methods. +*/ + +// NewTextStyle creates a new text style object which can be used to style +// chunks of text. +// Default attributes: +// Font: Helvetica +// Font size: 10 +// Encoding: WinAnsiEncoding +// Text color: black +func (c *Creator) NewTextStyle() TextStyle { + return newTextStyle(c.defaultFontRegular) +} + +// NewParagraph creates a new text paragraph. +// Default attributes: +// Font: Helvetica, +// Font size: 10 +// Encoding: WinAnsiEncoding +// Wrap: enabled +// Text color: black +func (c *Creator) NewParagraph(text string) *Paragraph { + return newParagraph(text, c.NewTextStyle()) +} + +// NewStyledParagraph creates a new styled paragraph. +// Default attributes: +// Font: Helvetica, +// Font size: 10 +// Encoding: WinAnsiEncoding +// Wrap: enabled +// Text color: black +func (c *Creator) NewStyledParagraph() *StyledParagraph { + return newStyledParagraph(c.NewTextStyle()) +} + +// NewTable create a new Table with a specified number of columns. +func (c *Creator) NewTable(cols int) *Table { + return newTable(cols) +} + +// NewDivision returns a new Division container component. +func (c *Creator) NewDivision() *Division { + return newDivision() +} + +// NewTOC creates a new table of contents. +func (c *Creator) NewTOC(title string) *TOC { + headingStyle := c.NewTextStyle() + headingStyle.Font = c.defaultFontBold + + return newTOC(title, c.NewTextStyle(), headingStyle) +} + +// NewTOCLine creates a new table of contents line with the default style. +func (c *Creator) NewTOCLine(number, title, page string, level uint) *TOCLine { + return newTOCLine(number, title, page, level, c.NewTextStyle()) +} + +// NewStyledTOCLine creates a new table of contents line with the provided style. +func (c *Creator) NewStyledTOCLine(number, title, page TextChunk, level uint, style TextStyle) *TOCLine { + return newStyledTOCLine(number, title, page, level, style) +} + +// NewChapter creates a new chapter with the specified title as the heading. +func (c *Creator) NewChapter(title string) *Chapter { + c.chapters++ + return newChapter(c.toc, title, c.chapters, c.NewTextStyle()) +} + +// 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 { + return newSubchapter(ch, title, c.NewTextStyle()) +} + +// NewRectangle creates a new Rectangle with default parameters +// with left corner at (x,y) and width, height as specified. +func (c *Creator) NewRectangle(x, y, width, height float64) *Rectangle { + return newRectangle(x, y, width, height) +} + +// NewPageBreak create a new page break. +func (c *Creator) NewPageBreak() *PageBreak { + return newPageBreak() +} + +// NewLine creates a new Line with default parameters between (x1,y1) to (x2,y2). +func (c *Creator) NewLine(x1, y1, x2, y2 float64) *Line { + return newLine(x1, y1, x2, y2) +} + +// NewFilledCurve returns a instance of filled curve. +func (c *Creator) NewFilledCurve() *FilledCurve { + return newFilledCurve() +} + +// NewEllipse creates a new ellipse centered at (xc,yc) with a width and height specified. +func (c *Creator) NewEllipse(xc, yc, width, height float64) *Ellipse { + return newEllipse(xc, yc, width, height) +} + +// NewCurve returns new instance of Curve between points (x1,y1) and (x2, y2) with control point (cx,cy). +func (c *Creator) NewCurve(x1, y1, cx, cy, x2, y2 float64) *Curve { + return newCurve(x1, y1, cx, cy, x2, y2) +} + +// NewImage create a new image from a unidoc image (model.Image). +func (c *Creator) NewImage(img *model.Image) (*Image, error) { + return newImage(img) +} + +// NewImageFromData creates an Image from image data. +func (c *Creator) NewImageFromData(data []byte) (*Image, error) { + return newImageFromData(data) +} + +// NewImageFromFile creates an Image from a file. +func (c *Creator) NewImageFromFile(path string) (*Image, error) { + return newImageFromFile(path) +} + +// NewImageFromGoImage creates an Image from a go image.Image data structure. +func NewImageFromGoImage(goimg goimage.Image) (*Image, error) { + return newImageFromGoImage(goimg) +} diff --git a/pdf/creator/creator_test.go b/pdf/creator/creator_test.go index edf29520..9f117f4b 100644 --- a/pdf/creator/creator_test.go +++ b/pdf/creator/creator_test.go @@ -92,7 +92,7 @@ func TestImage1(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -124,7 +124,7 @@ func TestImageWithEncoder(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -162,7 +162,7 @@ func TestShapes1(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -178,7 +178,7 @@ func TestShapes1(t *testing.T) { } // Add line. - line := NewLine(0, 0, 100, 100) + line := creator.NewLine(0, 0, 100, 100) line.SetLineWidth(3.0) line.SetColor(ColorRGBFromHex("#ff0000")) err = creator.Draw(line) @@ -188,7 +188,7 @@ func TestShapes1(t *testing.T) { } // Add rect with default params. - rect := NewRectangle(100, 100, 100, 100) + rect := creator.NewRectangle(100, 100, 100, 100) err = creator.Draw(rect) if err != nil { t.Errorf("Fail: %v\n", err) @@ -196,7 +196,7 @@ func TestShapes1(t *testing.T) { } // Add rect with fill and large border - rect = NewRectangle(100, 500, 100, 100) + rect = creator.NewRectangle(100, 500, 100, 100) rect.SetBorderColor(ColorRGBFromHex("#00ff00")) // Green border rect.SetBorderWidth(15.0) rect.SetFillColor(ColorRGBFromHex("#0000ff")) // Blue fill @@ -207,7 +207,7 @@ func TestShapes1(t *testing.T) { } // Draw a circle. (inscribed inside the previous rectangle). - ell := NewEllipse(100, 100, 100, 100) + ell := creator.NewEllipse(100, 100, 100, 100) err = creator.Draw(ell) if err != nil { t.Errorf("Fail: %v\n", err) @@ -215,7 +215,7 @@ func TestShapes1(t *testing.T) { } // Draw a circle around upper right page corner. - ell = NewEllipse(creator.Width(), 0, 100, 100) + ell = creator.NewEllipse(creator.Width(), 0, 100, 100) err = creator.Draw(ell) if err != nil { t.Errorf("Fail: %v\n", err) @@ -223,7 +223,7 @@ func TestShapes1(t *testing.T) { } // Draw an ellipse with fill and border. - ell = NewEllipse(500, 100, 100, 200) + ell = creator.NewEllipse(500, 100, 100, 200) ell.SetFillColor(ColorRGBFromHex("#ccc")) // Gray fill ell.SetBorderWidth(10.0) err = creator.Draw(ell) @@ -252,7 +252,7 @@ func TestShapesOnBlock(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -263,7 +263,7 @@ func TestShapesOnBlock(t *testing.T) { block.Draw(img) // Add line. - line := NewLine(0, 180, creator.Width(), 180) + line := creator.NewLine(0, 180, creator.Width(), 180) line.SetLineWidth(10.0) line.SetColor(ColorRGBFromHex("#ff0000")) block.Draw(line) @@ -298,7 +298,7 @@ func TestImageWrapping(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -331,7 +331,7 @@ func TestImageRotation(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -372,7 +372,7 @@ func TestImageRotationAndWrap(t *testing.T) { return } - img, err := NewImageFromData(imgData) + img, err := creator.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -407,7 +407,7 @@ func TestImageRotationAndWrap(t *testing.T) { func TestParagraph1(t *testing.T) { creator := New() - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + + p := creator.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore" + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -434,7 +434,7 @@ func TestParagraph1(t *testing.T) { func TestParagraphWrapping(t *testing.T) { creator := New() - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + + p := creator.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore" + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -465,7 +465,7 @@ func TestParagraphWrapping(t *testing.T) { func TestParagraphWrapping2(t *testing.T) { creator := New() - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + + p := creator.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore" + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -512,7 +512,7 @@ func TestParagraphFonts(t *testing.T) { fonts := []*model.PdfFont{roboto, robotoBold, helvetica, roboto, robotoBold, helvetica} for _, font := range fonts { - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + + p := creator.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore" + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -579,7 +579,7 @@ func TestParagraphStandardFonts(t *testing.T) { } for idx, name := range names { - p := NewParagraph(texts[idx]) + p := creator.NewParagraph(texts[idx]) font := model.NewStandard14FontMustCompile(name) p.SetFont(font) p.SetFontSize(12) @@ -619,7 +619,7 @@ func TestParagraphChinese(t *testing.T) { } for _, line := range lines { - p := NewParagraph(line) + p := creator.NewParagraph(line) font, err := model.NewCompositePdfFontFromTTFFile(testWts11TTFFile) if err != nil { @@ -685,7 +685,7 @@ func TestParagraphUnicode(t *testing.T) { for _, text := range texts { fmt.Printf("Text: %s\n", text) - p := NewParagraph(text) + p := creator.NewParagraph(text) p.SetFont(font) err = creator.Draw(p) @@ -708,7 +708,7 @@ func TestChapter(t *testing.T) { ch1 := c.NewChapter("Introduction") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -738,7 +738,7 @@ func TestChapterMargins(t *testing.T) { ch.SetMargins(3*float64(j), 3*float64(j), 5+float64(j), 0) } - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -763,7 +763,7 @@ func TestSubchaptersSimple(t *testing.T) { // Enable table of contents and set the style of the lines. c.AddTOC = true - lineStyle := NewTextStyle() + lineStyle := c.NewTextStyle() lineStyle.Font = model.NewStandard14FontMustCompile(model.HelveticaBold) toc := c.TOC() @@ -777,7 +777,7 @@ func TestSubchaptersSimple(t *testing.T) { //subCh1 := NewSubchapter(ch1, "Workflow") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -815,7 +815,7 @@ func TestSubchaptersSimple(t *testing.T) { // Set a function to create the front Page. c.CreateFrontPage(func(args FrontpageFunctionArgs) { - p := NewParagraph("Example Report") + p := c.NewParagraph("Example Report") p.SetWidth(c.Width()) p.SetTextAlignment(TextAlignmentCenter) p.SetFontSize(32) @@ -833,14 +833,14 @@ func TestSubchaptersSimple(t *testing.T) { // This function is used just to customize the style of the TOC. c.CreateTableOfContents(func(toc *TOC) error { // Set style of TOC heading just before render. - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFromArithmetic(0.5, 0.5, 0.5) style.FontSize = 20 toc.SetHeading("Table of Contents", style) // Set style of TOC lines just before render. - lineStyle := NewTextStyle() + lineStyle := c.NewTextStyle() lineStyle.FontSize = 14 pageStyle := lineStyle @@ -870,7 +870,7 @@ func TestSubchapters(t *testing.T) { // Enable table of contents and set the style of the lines. c.AddTOC = true - lineStyle := NewTextStyle() + lineStyle := c.NewTextStyle() lineStyle.Font = model.NewStandard14FontMustCompile(model.Helvetica) lineStyle.FontSize = 14 lineStyle.Color = ColorRGBFromArithmetic(0.5, 0.5, 0.5) @@ -886,7 +886,7 @@ func TestSubchapters(t *testing.T) { //subCh1 := NewSubchapter(ch1, "Workflow") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -928,7 +928,7 @@ func TestSubchapters(t *testing.T) { // Set a function to create the front Page. c.CreateFrontPage(func(args FrontpageFunctionArgs) { - p := NewParagraph("Example Report") + p := c.NewParagraph("Example Report") p.SetWidth(c.Width()) p.SetTextAlignment(TextAlignmentCenter) p.SetFontSize(32) @@ -946,14 +946,14 @@ func TestSubchapters(t *testing.T) { // This function is used just to customize the style of the TOC. c.CreateTableOfContents(func(toc *TOC) error { // Set style of TOC heading just before render. - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFromArithmetic(0.5, 0.5, 0.5) style.FontSize = 20 toc.SetHeading("Table of Contents", style) // Set style of TOC lines just before render. - pageStyle := NewTextStyle() + pageStyle := c.NewTextStyle() pageStyle.Font = model.NewStandard14FontMustCompile(model.HelveticaBold) pageStyle.FontSize = 10 @@ -976,54 +976,55 @@ func TestSubchapters(t *testing.T) { // Test creating and drawing a table. func TestTable(t *testing.T) { - table := NewTable(4) // Mx4 table + c := New() + + table := c.NewTable(4) // Mx4 table // Default, equal column sizes (4x0.25)... table.SetColumnWidths(0.5, 0.2, 0.2, 0.1) cell := table.NewCell() - p := NewParagraph("1,1") + p := c.NewParagraph("1,1") cell.SetContent(p) cell = table.NewCell() - p = NewParagraph("1,2") + p = c.NewParagraph("1,2") cell.SetContent(p) cell = table.NewCell() - p = NewParagraph("1,3") + p = c.NewParagraph("1,3") cell.SetContent(p) cell = table.NewCell() - p = NewParagraph("1,4") + p = c.NewParagraph("1,4") cell.SetContent(p) cell = table.NewCell() - p = NewParagraph("2,1") + p = c.NewParagraph("2,1") cell.SetContent(p) cell = table.NewCell() - p = NewParagraph("2,2") + p = c.NewParagraph("2,2") cell.SetContent(p) table.SkipCells(1) // Skip over 2,3. cell = table.NewCell() - p = NewParagraph("2,4") + p = c.NewParagraph("2,4") cell.SetContent(p) // Skip over two rows. table.SkipRows(2) cell = table.NewCell() - p = NewParagraph("4,4") + p = c.NewParagraph("4,4") cell.SetContent(p) // Move down 3 rows, 2 to the left. table.SkipOver(3, -2) cell = table.NewCell() - p = NewParagraph("7,2") + p = c.NewParagraph("7,2") cell.SetContent(p) cell.SetBackgroundColor(ColorRGBFrom8bit(255, 0, 0)) - c := New() c.Draw(table) err := c.WriteToFile("/tmp/4_table.pdf") @@ -1037,12 +1038,12 @@ func TestTableCellWrapping(t *testing.T) { c := New() c.NewPage() - table := NewTable(4) // Mx4 table + table := c.NewTable(4) // Mx4 table // Default, equal column sizes (4x0.25)... table.SetColumnWidths(0.5, 0.2, 0.2, 0.1) cell := table.NewCell() - p := NewParagraph("A Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") + p := c.NewParagraph("A Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") cell.SetContent(p) cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) p.SetEnableWrap(true) @@ -1051,34 +1052,34 @@ func TestTableCellWrapping(t *testing.T) { cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) - p = NewParagraph("B Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.") + p = c.NewParagraph("B Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.") p.SetEnableWrap(true) p.SetTextAlignment(TextAlignmentRight) cell.SetContent(p) cell = table.NewCell() - p = NewParagraph("C Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") + p = c.NewParagraph("C Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") p.SetEnableWrap(true) cell.SetContent(p) cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell = table.NewCell() - p = NewParagraph("1,4") + p = c.NewParagraph("1,4") cell.SetContent(p) cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell = table.NewCell() - p = NewParagraph("2,1") + p = c.NewParagraph("2,1") cell.SetContent(p) cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell = table.NewCell() - p = NewParagraph("2,2") + p = c.NewParagraph("2,2") cell.SetContent(p) cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell = table.NewCell() - p = NewParagraph("2,2") + p = c.NewParagraph("2,2") cell.SetContent(p) cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) @@ -1087,7 +1088,7 @@ func TestTableCellWrapping(t *testing.T) { cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) //p = NewParagraph("D Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") - p = NewParagraph("X") + p = c.NewParagraph("X") p.SetEnableWrap(true) cell.SetContent(p) @@ -1095,20 +1096,20 @@ func TestTableCellWrapping(t *testing.T) { table.SkipRows(2) cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) - p = NewParagraph("4,4") + p = c.NewParagraph("4,4") cell.SetContent(p) // Move down 3 rows, 2 to the left. table.SkipOver(3, -2) cell = table.NewCell() - p = NewParagraph("7,2") + p = c.NewParagraph("7,2") cell.SetContent(p) cell.SetBackgroundColor(ColorRGBFrom8bit(255, 0, 0)) table.SkipRows(1) cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) - p = NewParagraph("This is\nnewline\nwrapped\n\nmulti") + p = c.NewParagraph("This is\nnewline\nwrapped\n\nmulti") p.SetEnableWrap(true) cell.SetContent(p) @@ -1125,12 +1126,14 @@ func TestTableCellWrapping(t *testing.T) { // Test creating and drawing a table. func TestBorderedTable1(t *testing.T) { - table := NewTable(4) // Mx4 table + c := New() + + table := c.NewTable(4) // Mx4 table // Default, equal column sizes (4x0.25)... table.SetColumnWidths(0.5, 0.2, 0.2, 0.1) cell1 := table.NewCell() - p := NewParagraph("A") + p := c.NewParagraph("A") cell1.SetContent(p) cell1.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) // border will be on left cell1.SetBorderLineStyle(draw.LineStyleDashed) @@ -1138,7 +1141,7 @@ func TestBorderedTable1(t *testing.T) { table.SkipCells(1) cell2 := table.NewCell() - p = NewParagraph("B") + p = c.NewParagraph("B") cell2.SetContent(p) cell2.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) // border will be around cell2.SetBorderLineStyle(draw.LineStyleSolid) @@ -1149,12 +1152,11 @@ func TestBorderedTable1(t *testing.T) { // Skip over two rows. table.SkipRows(2) cell8 := table.NewCell() - p = NewParagraph("H") + p = c.NewParagraph("H") cell8.SetContent(p) cell8.SetBorder(CellBorderSideRight, CellBorderStyleSingle, 1) // border will be on right cell8.SetBorderLineStyle(draw.LineStyleSolid) - c := New() c.Draw(table) err := c.WriteToFile("/tmp/4_table_bordered.pdf") @@ -1166,18 +1168,20 @@ func TestBorderedTable1(t *testing.T) { // Test creating and drawing a table. func TestBorderedTable2(t *testing.T) { - table := NewTable(4) // Mx4 table + c := New() + + table := c.NewTable(4) // Mx4 table // Default, equal column sizes (4x0.25)... table.SetColumnWidths(0.5, 0.2, 0.2, 0.1) cell1 := table.NewCell() - p := NewParagraph("A") + p := c.NewParagraph("A") cell1.SetContent(p) cell1.SetBorder(CellBorderSideLeft, CellBorderStyleSingle, 1) // border will be on left cell1.SetBorderLineStyle(draw.LineStyleSolid) cell2 := table.NewCell() - p = NewParagraph("B") + p = c.NewParagraph("B") cell2.SetContent(p) cell2.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) // border will be around cell2.SetBorderLineStyle(draw.LineStyleSolid) @@ -1185,7 +1189,7 @@ func TestBorderedTable2(t *testing.T) { table.SkipCells(1) cell4 := table.NewCell() - p = NewParagraph("D") + p = c.NewParagraph("D") cell4.SetContent(p) cell4.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) // border will be around cell4.SetBorderLineStyle(draw.LineStyleSolid) @@ -1193,7 +1197,7 @@ func TestBorderedTable2(t *testing.T) { table.SkipCells(1) cell6 := table.NewCell() - p = NewParagraph("F") + p = c.NewParagraph("F") cell6.SetContent(p) cell6.SetBorder(CellBorderSideLeft, CellBorderStyleSingle, 1) // border will be on left cell6.SetBorderLineStyle(draw.LineStyleSolid) @@ -1201,7 +1205,7 @@ func TestBorderedTable2(t *testing.T) { table.SkipCells(1) // Skip over 2,3. cell7 := table.NewCell() - p = NewParagraph("G") + p = c.NewParagraph("G") cell7.SetContent(p) cell7.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) // border will be around cell7.SetBorderLineStyle(draw.LineStyleSolid) @@ -1209,12 +1213,11 @@ func TestBorderedTable2(t *testing.T) { // Skip over two rows. table.SkipRows(2) cell8 := table.NewCell() - p = NewParagraph("H") + p = c.NewParagraph("H") cell8.SetContent(p) cell8.SetBorder(CellBorderSideRight, CellBorderStyleSingle, 1) // border will be on right cell8.SetBorderLineStyle(draw.LineStyleSolid) - c := New() c.Draw(table) err := c.WriteToFile("/tmp/4_table_bordered.pdf") @@ -1224,8 +1227,8 @@ func TestBorderedTable2(t *testing.T) { } } -func newContent(text string, alignment TextAlignment, font *model.PdfFont, fontSize float64, color Color) *Paragraph { - p := NewParagraph(text) +func newContent(c *Creator, text string, alignment TextAlignment, font *model.PdfFont, fontSize float64, color Color) *Paragraph { + p := c.NewParagraph(text) p.SetFontSize(fontSize) p.SetTextAlignment(alignment) p.SetFont(font) @@ -1233,32 +1236,34 @@ func newContent(text string, alignment TextAlignment, font *model.PdfFont, fontS return p } -func newBillItem(t *Table, no, date, notes, amount, con, retApplied, ret, netBill string) { +func newBillItem(c *Creator, t *Table, no, date, notes, amount, con, retApplied, ret, netBill string) { timesBold := model.NewStandard14FontMustCompile(model.TimesBold) billNo := t.NewCell() - billNo.SetContent(newContent(no, TextAlignmentLeft, timesBold, 8, ColorBlack)) + billNo.SetContent(newContent(c, no, TextAlignmentLeft, timesBold, 8, ColorBlack)) billDate := t.NewCell() - billDate.SetContent(newContent(date, TextAlignmentCenter, timesBold, 8, ColorBlack)) + billDate.SetContent(newContent(c, date, TextAlignmentCenter, timesBold, 8, ColorBlack)) billNotes := t.NewCell() - billNotes.SetContent(newContent(notes, TextAlignmentLeft, timesBold, 8, ColorBlack)) + billNotes.SetContent(newContent(c, notes, TextAlignmentLeft, timesBold, 8, ColorBlack)) billAmount := t.NewCell() - billAmount.SetContent(newContent(amount, TextAlignmentRight, timesBold, 8, ColorBlack)) + billAmount.SetContent(newContent(c, amount, TextAlignmentRight, timesBold, 8, ColorBlack)) billCon := t.NewCell() - billCon.SetContent(newContent(con, TextAlignmentLeft, timesBold, 8, ColorBlack)) + billCon.SetContent(newContent(c, con, TextAlignmentLeft, timesBold, 8, ColorBlack)) billRetApplied := t.NewCell() - billRetApplied.SetContent(newContent(retApplied, TextAlignmentRight, timesBold, 8, ColorBlack)) + billRetApplied.SetContent(newContent(c, retApplied, TextAlignmentRight, timesBold, 8, ColorBlack)) billRet := t.NewCell() - billRet.SetContent(newContent(ret, TextAlignmentLeft, timesBold, 8, ColorBlack)) + billRet.SetContent(newContent(c, ret, TextAlignmentLeft, timesBold, 8, ColorBlack)) billNetBill := t.NewCell() - billNetBill.SetContent(newContent(netBill, TextAlignmentRight, timesBold, 8, ColorBlack)) + billNetBill.SetContent(newContent(c, netBill, TextAlignmentRight, timesBold, 8, ColorBlack)) } // Test creating and drawing a table. func TestCreatorHendricksReq1(t *testing.T) { + c := New() + timesRoman := model.NewStandard14FontMustCompile(model.TimesRoman) timesBold := model.NewStandard14FontMustCompile(model.TimesBold) - table := NewTable(3) // Mx4 table + table := c.NewTable(3) // Mx4 table // Default, equal column sizes (4x0.25)... table.SetColumnWidths(0.35, 0.30, 0.35) @@ -1266,183 +1271,182 @@ func TestCreatorHendricksReq1(t *testing.T) { projectColorTwo := ColorRed companyTitle := table.NewCell() - companyTitle.SetContent(newContent("Hendricks Consulting LLC", TextAlignmentLeft, timesBold, 12, projectColorOne)) + companyTitle.SetContent(newContent(c, "Hendricks Consulting LLC", TextAlignmentLeft, timesBold, 12, projectColorOne)) table.SkipCells(1) pageHeader := table.NewCell() - pageHeader.SetContent(newContent("Billing Schedule by Project", TextAlignmentCenter, timesBold, 12, ColorBlack)) + pageHeader.SetContent(newContent(c, "Billing Schedule by Project", TextAlignmentCenter, timesBold, 12, ColorBlack)) pageHeader.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 3) pageHeader.SetBorderLineStyle(draw.LineStyleSolid) companyAddress := table.NewCell() - companyAddress.SetContent(newContent("2666 Airport Drive, Apt. 309", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + companyAddress.SetContent(newContent(c, "2666 Airport Drive, Apt. 309", TextAlignmentLeft, timesRoman, 8, ColorBlack)) table.SkipCells(2) companyLocation := table.NewCell() - companyLocation.SetContent(newContent("Portland, Oregon, 92019", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + companyLocation.SetContent(newContent(c, "Portland, Oregon, 92019", TextAlignmentLeft, timesRoman, 8, ColorBlack)) table.SkipCells(1) printingDate := table.NewCell() - printingDate.SetContent(newContent("Printed on: 22/02/2011", TextAlignmentRight, timesRoman, 8, ColorBlack)) + printingDate.SetContent(newContent(c, "Printed on: 22/02/2011", TextAlignmentRight, timesRoman, 8, ColorBlack)) companyTelAndFax := table.NewCell() - companyTelAndFax.SetContent(newContent("Tel: (999) 609-4032 Fax: (999) 999-9922", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + companyTelAndFax.SetContent(newContent(c, "Tel: (999) 609-4032 Fax: (999) 999-9922", TextAlignmentLeft, timesRoman, 8, ColorBlack)) table.SkipCells(1) pageOf := table.NewCell() - pageOf.SetContent(newContent("Page 10 of 10", TextAlignmentRight, timesRoman, 8, ColorBlack)) + pageOf.SetContent(newContent(c, "Page 10 of 10", TextAlignmentRight, timesRoman, 8, ColorBlack)) email := table.NewCell() - email.SetContent(newContent("admin@hendricks.com", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + email.SetContent(newContent(c, "admin@hendricks.com", TextAlignmentLeft, timesRoman, 8, ColorBlack)) table.SkipCells(2) website := table.NewCell() - website.SetContent(newContent("www.hendricks.com", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + website.SetContent(newContent(c, "www.hendricks.com", TextAlignmentLeft, timesRoman, 8, ColorBlack)) - table2 := NewTable(5) + table2 := c.NewTable(5) table2.SetColumnWidths(0.20, 0.20, 0.20, 0.20, 0.20) table2.SkipCells(5) projectName := table2.NewCell() - projectName.SetContent(newContent("Project Name (ID):", TextAlignmentLeft, timesBold, 8, projectColorOne)) + projectName.SetContent(newContent(c, "Project Name (ID):", TextAlignmentLeft, timesBold, 8, projectColorOne)) projectNameValue := table2.NewCell() - projectNameValue.SetContent(newContent("Biggi Group", TextAlignmentLeft, timesBold, 8, ColorBlack)) + projectNameValue.SetContent(newContent(c, "Biggi Group", TextAlignmentLeft, timesBold, 8, ColorBlack)) table2.SkipCells(3) projectID := table2.NewCell() - projectID.SetContent(newContent("Project ID:", TextAlignmentLeft, timesBold, 8, projectColorOne)) + projectID.SetContent(newContent(c, "Project ID:", TextAlignmentLeft, timesBold, 8, projectColorOne)) projectIDValue := table2.NewCell() - projectIDValue.SetContent(newContent("BG:01", TextAlignmentLeft, timesBold, 8, ColorBlack)) + projectIDValue.SetContent(newContent(c, "BG:01", TextAlignmentLeft, timesBold, 8, ColorBlack)) table2.SkipCells(1) contractType := table2.NewCell() - contractType.SetContent(newContent("Contract Type:", TextAlignmentRight, timesBold, 8, projectColorOne)) + contractType.SetContent(newContent(c, "Contract Type:", TextAlignmentRight, timesBold, 8, projectColorOne)) contractTypeValue := table2.NewCell() - contractTypeValue.SetContent(newContent("Percentage", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + contractTypeValue.SetContent(newContent(c, "Percentage", TextAlignmentLeft, timesRoman, 8, ColorBlack)) projectManager := table2.NewCell() - projectManager.SetContent(newContent("Manager:", TextAlignmentLeft, timesBold, 8, projectColorOne)) + projectManager.SetContent(newContent(c, "Manager:", TextAlignmentLeft, timesBold, 8, projectColorOne)) projectManagerValue := table2.NewCell() - projectManagerValue.SetContent(newContent("SHH", TextAlignmentLeft, timesBold, 8, ColorBlack)) + projectManagerValue.SetContent(newContent(c, "SHH", TextAlignmentLeft, timesBold, 8, ColorBlack)) table2.SkipCells(1) contractAmount := table2.NewCell() - contractAmount.SetContent(newContent("Contract Amount:", TextAlignmentRight, timesBold, 8, projectColorOne)) + contractAmount.SetContent(newContent(c, "Contract Amount:", TextAlignmentRight, timesBold, 8, projectColorOne)) contractAmountValue := table2.NewCell() - contractAmountValue.SetContent(newContent("$2,975.00", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + contractAmountValue.SetContent(newContent(c, "$2,975.00", TextAlignmentLeft, timesRoman, 8, ColorBlack)) clientID := table2.NewCell() - clientID.SetContent(newContent("Client ID:", TextAlignmentLeft, timesBold, 8, projectColorOne)) + clientID.SetContent(newContent(c, "Client ID:", TextAlignmentLeft, timesBold, 8, projectColorOne)) clientIDValue := table2.NewCell() - clientIDValue.SetContent(newContent("Baggi ehf", TextAlignmentLeft, timesBold, 8, ColorBlack)) + clientIDValue.SetContent(newContent(c, "Baggi ehf", TextAlignmentLeft, timesBold, 8, ColorBlack)) table2.SkipCells(1) retainerAmount := table2.NewCell() - retainerAmount.SetContent(newContent("Retainer Amount:", TextAlignmentRight, timesBold, 8, projectColorOne)) + retainerAmount.SetContent(newContent(c, "Retainer Amount:", TextAlignmentRight, timesBold, 8, projectColorOne)) retainerAmountValue := table2.NewCell() - retainerAmountValue.SetContent(newContent("", TextAlignmentLeft, timesRoman, 8, ColorBlack)) + retainerAmountValue.SetContent(newContent(c, "", TextAlignmentLeft, timesRoman, 8, ColorBlack)) - table3 := NewTable(8) + table3 := c.NewTable(8) table3.SetColumnWidths(0.05, 0.10, 0.35, 0.10, 0.10, 0.10, 0.10, 0.10) table3.SkipCells(8) billNo := table3.NewCell() - billNo.SetContent(newContent("Bill #", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billNo.SetContent(newContent(c, "Bill #", TextAlignmentLeft, timesBold, 8, projectColorOne)) billNo.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billNo.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billNo.SetBorderColor(projectColorOne) billDate := table3.NewCell() - billDate.SetContent(newContent("Date", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billDate.SetContent(newContent(c, "Date", TextAlignmentLeft, timesBold, 8, projectColorOne)) billDate.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billDate.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billDate.SetBorderColor(projectColorOne) billNotes := table3.NewCell() - billNotes.SetContent(newContent("Notes", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billNotes.SetContent(newContent(c, "Notes", TextAlignmentLeft, timesBold, 8, projectColorOne)) billNotes.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billNotes.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billNotes.SetBorderColor(projectColorOne) billAmount := table3.NewCell() - billAmount.SetContent(newContent("Bill Amount", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billAmount.SetContent(newContent(c, "Bill Amount", TextAlignmentLeft, timesBold, 8, projectColorOne)) billAmount.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billAmount.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billAmount.SetBorderColor(projectColorOne) billCon := table3.NewCell() - billCon.SetContent(newContent("% Con", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billCon.SetContent(newContent(c, "% Con", TextAlignmentLeft, timesBold, 8, projectColorOne)) billCon.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billCon.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billCon.SetBorderColor(projectColorOne) billRetApplied := table3.NewCell() - billRetApplied.SetContent(newContent("Ret Applied", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billRetApplied.SetContent(newContent(c, "Ret Applied", TextAlignmentLeft, timesBold, 8, projectColorOne)) billRetApplied.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billRetApplied.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billRetApplied.SetBorderColor(projectColorOne) billRet := table3.NewCell() - billRet.SetContent(newContent("% Ret", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billRet.SetContent(newContent(c, "% Ret", TextAlignmentLeft, timesBold, 8, projectColorOne)) billRet.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billRet.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billRet.SetBorderColor(projectColorOne) billNetBill := table3.NewCell() - billNetBill.SetContent(newContent("Net Bill Amt", TextAlignmentLeft, timesBold, 8, projectColorOne)) + billNetBill.SetContent(newContent(c, "Net Bill Amt", TextAlignmentLeft, timesBold, 8, projectColorOne)) billNetBill.SetBorder(CellBorderSideTop, CellBorderStyleSingle, 2) billNetBill.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) billNetBill.SetBorderColor(projectColorOne) - newBillItem(table3, "1", "1/2/2012", "", "$297.50", "", "$0.00", "", "$297.50") - newBillItem(table3, "2", "1/2/2012", "", "$595.00", "", "$0.00", "", "$595.00") - newBillItem(table3, "3", "1/3/2012", "", "$446.25", "", "$0.00", "", "$446.25") - newBillItem(table3, "4", "1/4/2012", "", "$595.00", "", "$0.00", "", "$595.00") - newBillItem(table3, "5", "1/5/2012", "", "$446.25", "", "$0.00", "", "$446.25") - newBillItem(table3, "6", "1/6/2012", "", "$892.50", "", "$0.00", "", "$892.50") + newBillItem(c, table3, "1", "1/2/2012", "", "$297.50", "", "$0.00", "", "$297.50") + newBillItem(c, table3, "2", "1/2/2012", "", "$595.00", "", "$0.00", "", "$595.00") + newBillItem(c, table3, "3", "1/3/2012", "", "$446.25", "", "$0.00", "", "$446.25") + newBillItem(c, table3, "4", "1/4/2012", "", "$595.00", "", "$0.00", "", "$595.00") + newBillItem(c, table3, "5", "1/5/2012", "", "$446.25", "", "$0.00", "", "$446.25") + newBillItem(c, table3, "6", "1/6/2012", "", "$892.50", "", "$0.00", "", "$892.50") table3.SkipCells(2 + 8) totalBill := table3.NewCell() - totalBill.SetContent(newContent("Total: ", TextAlignmentRight, timesBold, 8, projectColorTwo)) + totalBill.SetContent(newContent(c, "Total: ", TextAlignmentRight, timesBold, 8, projectColorTwo)) totalBillAmount := table3.NewCell() - totalBillAmount.SetContent(newContent("$3,272.50", TextAlignmentRight, timesBold, 8, projectColorTwo)) + totalBillAmount.SetContent(newContent(c, "$3,272.50", TextAlignmentRight, timesBold, 8, projectColorTwo)) totalBillAmount.SetBorder(CellBorderSideTop, CellBorderStyleDouble, 1) totalBillAmount.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) table3.SkipCells(1) totalRetAmount := table3.NewCell() - totalRetAmount.SetContent(newContent("$0.00", TextAlignmentRight, timesBold, 8, projectColorTwo)) + totalRetAmount.SetContent(newContent(c, "$0.00", TextAlignmentRight, timesBold, 8, projectColorTwo)) totalRetAmount.SetBorder(CellBorderSideTop, CellBorderStyleDouble, 1) totalRetAmount.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) table3.SkipCells(1) totalNetAmount := table3.NewCell() - totalNetAmount.SetContent(newContent("$3,272.50", TextAlignmentRight, timesBold, 8, projectColorTwo)) + totalNetAmount.SetContent(newContent(c, "$3,272.50", TextAlignmentRight, timesBold, 8, projectColorTwo)) totalNetAmount.SetBorder(CellBorderSideTop, CellBorderStyleDouble, 1) totalNetAmount.SetBorder(CellBorderSideBottom, CellBorderStyleSingle, 1) totalNetAmount.SetBorderLineStyle(draw.LineStyleSolid) - c := New() c.Draw(table) c.Draw(table2) c.Draw(table3) @@ -1455,317 +1459,318 @@ func TestCreatorHendricksReq1(t *testing.T) { } func TestCreatorTableBorderReq1(t *testing.T) { + c := New() + timesRoman := model.NewStandard14FontMustCompile(model.TimesRoman) - table := NewTable(1) // Mx4 table + table := c.NewTable(1) // Mx4 table table.SetColumnWidths(1) fullLengthCell := table.NewCell() - fullLengthCell.SetContent(newContent("boxed, solid, default width", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + fullLengthCell.SetContent(newContent(c, "boxed, solid, default width", TextAlignmentLeft, timesRoman, 10, ColorBlack)) fullLengthCell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) - table2 := NewTable(4) // Mx4 table + table2 := c.NewTable(4) // Mx4 table table2.SetColumnWidths(.25, .25, .25, .25) table2.SkipCells(4) a := table2.NewCell() - a.SetContent(newContent("A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + a.SetContent(newContent(c, "A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) a.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) b := table2.NewCell() - b.SetContent(newContent("B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + b.SetContent(newContent(c, "B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) b.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cc := table2.NewCell() - cc.SetContent(newContent("C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + cc.SetContent(newContent(c, "C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) cc.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) d := table2.NewCell() - d.SetContent(newContent("D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + d.SetContent(newContent(c, "D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) d.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) e := table2.NewCell() - e.SetContent(newContent("E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + e.SetContent(newContent(c, "E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) e.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) f := table2.NewCell() - f.SetContent(newContent("F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + f.SetContent(newContent(c, "F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) f.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) g := table2.NewCell() - g.SetContent(newContent("G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + g.SetContent(newContent(c, "G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) g.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) h := table2.NewCell() - h.SetContent(newContent("H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + h.SetContent(newContent(c, "H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) h.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) i := table2.NewCell() - i.SetContent(newContent("I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + i.SetContent(newContent(c, "I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) i.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) j := table2.NewCell() - j.SetContent(newContent("J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + j.SetContent(newContent(c, "J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) j.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) - table3 := NewTable(1) // Mx4 table + table3 := c.NewTable(1) // Mx4 table table3.SetColumnWidths(1) table3.SkipCells(1) dash := table3.NewCell() - dash.SetContent(newContent("boxed, dashed, default width", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + dash.SetContent(newContent(c, "boxed, dashed, default width", TextAlignmentLeft, timesRoman, 10, ColorBlack)) dash.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) dash.SetBorderLineStyle(draw.LineStyleDashed) - table4 := NewTable(4) // Mx4 table + table4 := c.NewTable(4) // Mx4 table table4.SetColumnWidths(.25, .25, .25, .25) table4.SkipCells(4) ad := table4.NewCell() - ad.SetContent(newContent("A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + ad.SetContent(newContent(c, "A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) ad.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) ad.SetBorderLineStyle(draw.LineStyleDashed) bd := table4.NewCell() - bd.SetContent(newContent("B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + bd.SetContent(newContent(c, "B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) bd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) bd.SetBorderLineStyle(draw.LineStyleDashed) table4.SkipCells(2) ccd := table4.NewCell() - ccd.SetContent(newContent("C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + ccd.SetContent(newContent(c, "C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) ccd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) ccd.SetBorderLineStyle(draw.LineStyleDashed) dd := table4.NewCell() - dd.SetContent(newContent("D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + dd.SetContent(newContent(c, "D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) dd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) dd.SetBorderLineStyle(draw.LineStyleDashed) table4.SkipCells(2) ed := table4.NewCell() - ed.SetContent(newContent("E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + ed.SetContent(newContent(c, "E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) ed.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) ed.SetBorderLineStyle(draw.LineStyleDashed) fd := table4.NewCell() - fd.SetContent(newContent("F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + fd.SetContent(newContent(c, "F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) fd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) fd.SetBorderLineStyle(draw.LineStyleDashed) gd := table4.NewCell() - gd.SetContent(newContent("G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + gd.SetContent(newContent(c, "G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) gd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) gd.SetBorderLineStyle(draw.LineStyleDashed) hd := table4.NewCell() - hd.SetContent(newContent("H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + hd.SetContent(newContent(c, "H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) hd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) hd.SetBorderLineStyle(draw.LineStyleDashed) id := table4.NewCell() - id.SetContent(newContent("I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + id.SetContent(newContent(c, "I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) id.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) id.SetBorderLineStyle(draw.LineStyleDashed) jd := table4.NewCell() - jd.SetContent(newContent("J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + jd.SetContent(newContent(c, "J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) jd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) jd.SetBorderLineStyle(draw.LineStyleDashed) kd := table4.NewCell() - kd.SetContent(newContent("K", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + kd.SetContent(newContent(c, "K", TextAlignmentLeft, timesRoman, 10, ColorBlack)) kd.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) kd.SetBorderLineStyle(draw.LineStyleDashed) ld := table4.NewCell() - ld.SetContent(newContent("L", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + ld.SetContent(newContent(c, "L", TextAlignmentLeft, timesRoman, 10, ColorBlack)) ld.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) ld.SetBorderLineStyle(draw.LineStyleDashed) md := table4.NewCell() - md.SetContent(newContent("M", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + md.SetContent(newContent(c, "M", TextAlignmentLeft, timesRoman, 10, ColorBlack)) md.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) md.SetBorderLineStyle(draw.LineStyleDashed) - table5 := NewTable(1) // Mx4 table + table5 := c.NewTable(1) // Mx4 table table5.SetColumnWidths(1) table5.SkipCells(1) doubled := table5.NewCell() - doubled.SetContent(newContent("boxed, double, default width", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + doubled.SetContent(newContent(c, "boxed, double, default width", TextAlignmentLeft, timesRoman, 10, ColorBlack)) doubled.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) - table6 := NewTable(4) // Mx4 table + table6 := c.NewTable(4) // Mx4 table table6.SetColumnWidths(.25, .25, .25, .25) table6.SkipCells(4) add := table6.NewCell() - add.SetContent(newContent("A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + add.SetContent(newContent(c, "A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) add.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) bdd := table6.NewCell() - bdd.SetContent(newContent("B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + bdd.SetContent(newContent(c, "B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) bdd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) ccdd := table6.NewCell() - ccdd.SetContent(newContent("C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + ccdd.SetContent(newContent(c, "C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) ccdd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) ddd := table6.NewCell() - ddd.SetContent(newContent("D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + ddd.SetContent(newContent(c, "D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) ddd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) edd := table6.NewCell() - edd.SetContent(newContent("E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + edd.SetContent(newContent(c, "E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) edd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) fdd := table6.NewCell() - fdd.SetContent(newContent("F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + fdd.SetContent(newContent(c, "F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) fdd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) gdd := table6.NewCell() - gdd.SetContent(newContent("G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + gdd.SetContent(newContent(c, "G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) gdd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) hdd := table6.NewCell() - hdd.SetContent(newContent("H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + hdd.SetContent(newContent(c, "H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) hdd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) idd := table6.NewCell() - idd.SetContent(newContent("I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + idd.SetContent(newContent(c, "I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) idd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) jdd := table6.NewCell() - jdd.SetContent(newContent("J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + jdd.SetContent(newContent(c, "J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) jdd.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) - table7 := NewTable(1) // Mx4 table + table7 := c.NewTable(1) // Mx4 table table7.SetColumnWidths(1) table7.SkipCells(1) fullLengthCell7 := table7.NewCell() - fullLengthCell7.SetContent(newContent("boxed, solid, thick", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + fullLengthCell7.SetContent(newContent(c, "boxed, solid, thick", TextAlignmentLeft, timesRoman, 10, ColorBlack)) fullLengthCell7.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) - table8 := NewTable(4) // Mx4 table + table8 := c.NewTable(4) // Mx4 table table8.SetColumnWidths(.25, .25, .25, .25) table8.SkipCells(4) a8 := table8.NewCell() - a8.SetContent(newContent("A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + a8.SetContent(newContent(c, "A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) a8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) b8 := table8.NewCell() - b8.SetContent(newContent("B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + b8.SetContent(newContent(c, "B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) b8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) cc8 := table8.NewCell() - cc8.SetContent(newContent("C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + cc8.SetContent(newContent(c, "C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) cc8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) d8 := table8.NewCell() - d8.SetContent(newContent("D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + d8.SetContent(newContent(c, "D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) d8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) e8 := table8.NewCell() - e8.SetContent(newContent("E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + e8.SetContent(newContent(c, "E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) e8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) f8 := table8.NewCell() - f8.SetContent(newContent("F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + f8.SetContent(newContent(c, "F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) f8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) g8 := table8.NewCell() - g8.SetContent(newContent("G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + g8.SetContent(newContent(c, "G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) g8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) h8 := table8.NewCell() - h8.SetContent(newContent("H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + h8.SetContent(newContent(c, "H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) h8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) i8 := table8.NewCell() - i8.SetContent(newContent("I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + i8.SetContent(newContent(c, "I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) i8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) j8 := table8.NewCell() - j8.SetContent(newContent("J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + j8.SetContent(newContent(c, "J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) j8.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) - table9 := NewTable(1) // Mx4 table + table9 := c.NewTable(1) // Mx4 table table9.SetColumnWidths(1) table9.SkipCells(1) fullLengthCell9 := table9.NewCell() - fullLengthCell9.SetContent(newContent("boxed, dashed, thick", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + fullLengthCell9.SetContent(newContent(c, "boxed, dashed, thick", TextAlignmentLeft, timesRoman, 10, ColorBlack)) fullLengthCell9.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) fullLengthCell9.SetBorderLineStyle(draw.LineStyleDashed) - table10 := NewTable(4) // Mx4 table + table10 := c.NewTable(4) // Mx4 table table10.SetColumnWidths(.25, .25, .25, .25) table10.SkipCells(4) a10 := table10.NewCell() - a10.SetContent(newContent("A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + a10.SetContent(newContent(c, "A", TextAlignmentLeft, timesRoman, 10, ColorBlack)) a10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) a10.SetBorderLineStyle(draw.LineStyleDashed) b10 := table10.NewCell() - b10.SetContent(newContent("B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + b10.SetContent(newContent(c, "B", TextAlignmentLeft, timesRoman, 10, ColorBlack)) b10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) b10.SetBorderLineStyle(draw.LineStyleDashed) cc10 := table10.NewCell() - cc10.SetContent(newContent("C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + cc10.SetContent(newContent(c, "C", TextAlignmentLeft, timesRoman, 10, ColorBlack)) cc10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) cc10.SetBorderLineStyle(draw.LineStyleDashed) d10 := table10.NewCell() - d10.SetContent(newContent("D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + d10.SetContent(newContent(c, "D", TextAlignmentLeft, timesRoman, 10, ColorBlack)) d10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) d10.SetBorderLineStyle(draw.LineStyleDashed) e10 := table10.NewCell() - e10.SetContent(newContent("E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + e10.SetContent(newContent(c, "E", TextAlignmentLeft, timesRoman, 10, ColorBlack)) e10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) e10.SetBorderLineStyle(draw.LineStyleDashed) f10 := table10.NewCell() - f10.SetContent(newContent("F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + f10.SetContent(newContent(c, "F", TextAlignmentLeft, timesRoman, 10, ColorBlack)) f10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) f10.SetBorderLineStyle(draw.LineStyleDashed) g10 := table10.NewCell() - g10.SetContent(newContent("G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + g10.SetContent(newContent(c, "G", TextAlignmentLeft, timesRoman, 10, ColorBlack)) g10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) g10.SetBorderLineStyle(draw.LineStyleDashed) h10 := table10.NewCell() - h10.SetContent(newContent("H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + h10.SetContent(newContent(c, "H", TextAlignmentLeft, timesRoman, 10, ColorBlack)) h10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) h10.SetBorderLineStyle(draw.LineStyleDashed) i10 := table10.NewCell() - i10.SetContent(newContent("I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + i10.SetContent(newContent(c, "I", TextAlignmentLeft, timesRoman, 10, ColorBlack)) i10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) i10.SetBorderLineStyle(draw.LineStyleDashed) j10 := table10.NewCell() - j10.SetContent(newContent("J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) + j10.SetContent(newContent(c, "J", TextAlignmentLeft, timesRoman, 10, ColorBlack)) j10.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 2) j10.SetBorderLineStyle(draw.LineStyleDashed) - c := New() c.Draw(table) c.Draw(table2) c.Draw(table3) @@ -1785,16 +1790,17 @@ func TestCreatorTableBorderReq1(t *testing.T) { } func TestCellBorder(t *testing.T) { + c := New() + timesBold := model.NewStandard14FontMustCompile(model.TimesBold) - table := NewTable(2) + table := c.NewTable(2) table.SetColumnWidths(0.50, 0.50) cell1 := table.NewCell() - cell1.SetContent(newContent("Cell 1", TextAlignmentLeft, timesBold, 8, ColorRed)) + cell1.SetContent(newContent(c, "Cell 1", TextAlignmentLeft, timesBold, 8, ColorRed)) cell1.SetBorder(CellBorderSideAll, CellBorderStyleDouble, 1) - c := New() c.Draw(table) err := c.WriteToFile("/tmp/cell.pdf") @@ -1822,9 +1828,9 @@ func TestTableInSubchapter(t *testing.T) { sc.GetHeading().SetFontSize(18) sc.GetHeading().SetColor(ColorRGBFrom8bit(72, 86, 95)) - issuerTable := NewTable(2) + issuerTable := c.NewTable(2) - p := NewParagraph("Non-Disclosure") + p := c.NewParagraph("Non-Disclosure") p.SetFont(fontBold) p.SetFontSize(10) p.SetColor(ColorWhite) @@ -1834,7 +1840,7 @@ func TestTableInSubchapter(t *testing.T) { cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1.0) cell.SetIndent(5) - p = NewParagraph("Company Inc.") + p = c.NewParagraph("Company Inc.") p.SetFont(fontRegular) p.SetFontSize(10) p.SetColor(ColorGreen) @@ -1844,7 +1850,7 @@ func TestTableInSubchapter(t *testing.T) { cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1.0) cell.SetIndent(5) - p = NewParagraph("Belongs to") + p = c.NewParagraph("Belongs to") p.SetFont(fontBold) p.SetFontSize(10) p.SetColor(ColorWhite) @@ -1854,7 +1860,7 @@ func TestTableInSubchapter(t *testing.T) { cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1.0) cell.SetIndent(5) - p = NewParagraph("Bezt business bureu") + p = c.NewParagraph("Bezt business bureu") p.SetFont(fontRegular) p.SetFontSize(10) p.SetColor(ColorGreen) @@ -1882,7 +1888,7 @@ func TestTableInSubchapter(t *testing.T) { "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + "mollit anim id est laborum." - myPara := NewParagraph(myText) + myPara := c.NewParagraph(myText) myPara.SetFont(fontRegular) myPara.SetFontSize(10) myPara.SetColor(ColorRGBFrom8bit(72, 86, 95)) @@ -1914,12 +1920,12 @@ func addHeadersAndFooters(c *Creator) { */ // Add Page number - p := NewParagraph(fmt.Sprintf("Page %d / %d", args.PageNum, args.TotalPages)) + p := c.NewParagraph(fmt.Sprintf("Page %d / %d", args.PageNum, args.TotalPages)) p.SetPos(0.8*header.Width(), 20) header.Draw(p) // Draw on the template... - img, err := NewImageFromFile(testImageFile1) + img, err := c.NewImageFromFile(testImageFile1) if err != nil { fmt.Printf("ERROR : %v\n", err) } @@ -1939,11 +1945,11 @@ func addHeadersAndFooters(c *Creator) { // Add company name. companyName := "Company inc." - p := NewParagraph(companyName) + p := c.NewParagraph(companyName) p.SetPos(0.1*footer.Width(), 10) footer.Draw(p) - p = NewParagraph("July 2017") + p = c.NewParagraph("July 2017") p.SetPos(0.8*footer.Width(), 10) footer.Draw(p) }) @@ -1955,7 +1961,7 @@ func TestHeadersAndFooters(t *testing.T) { ch1 := c.NewChapter("Introduction") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -2102,7 +2108,7 @@ func TestEncrypting1(t *testing.T) { ch1 := c.NewChapter("Introduction") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -2207,7 +2213,7 @@ func TestOptimizeImageQuality(t *testing.T) { return } - imgJpeg, err := NewImageFromData(imgDataJpeg) + imgJpeg, err := c.NewImageFromData(imgDataJpeg) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -2261,7 +2267,7 @@ func TestOptimizeImageQuality(t *testing.T) { func createPdf4Optimization(t *testing.T) *Creator { c := New() - p := NewParagraph("Test text1") + p := c.NewParagraph("Test text1") // Change to times bold font (default is helvetica). font, err := model.NewStandard14Font(model.CourierBold) if err != nil { @@ -2280,7 +2286,7 @@ func createPdf4Optimization(t *testing.T) *Creator { return nil } - img, err := NewImageFromData(imgData) + img, err := c.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) t.FailNow() @@ -2297,7 +2303,7 @@ func createPdf4Optimization(t *testing.T) *Creator { return nil } - img1, err := NewImageFromData(imgData) + img1, err := c.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) t.FailNow() @@ -2321,7 +2327,7 @@ func createPdf4Optimization(t *testing.T) *Creator { return nil } - img2, err := NewImageFromData(imgData2) + img2, err := c.NewImageFromData(imgData2) if err != nil { t.Errorf("Fail: %v\n", err) t.FailNow() @@ -2332,7 +2338,7 @@ func createPdf4Optimization(t *testing.T) *Creator { img2.ScaleToWidth(1.0 * c.Width()) c.NewPage() - p = NewParagraph("Test text2") + p = c.NewParagraph("Test text2") // Change to times bold font (default is helvetica). font, err = model.NewStandard14Font(model.Helvetica) if err != nil { @@ -2401,7 +2407,7 @@ func TestCombineDuplicateDirectObjects(t *testing.T) { //subCh1 := NewSubchapter(ch1, "Workflow") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -2446,7 +2452,7 @@ func TestCombineDuplicateDirectObjects(t *testing.T) { // Set a function to create the front Page. c.CreateFrontPage(func(args FrontpageFunctionArgs) { - p := NewParagraph("Example Report") + p := c.NewParagraph("Example Report") p.SetWidth(c.Width()) p.SetTextAlignment(TextAlignmentCenter) p.SetFontSize(32) @@ -2463,7 +2469,7 @@ func TestCombineDuplicateDirectObjects(t *testing.T) { // AddTOC property of the creator is set to true. // This function is used just to customize the style of the TOC. c.CreateTableOfContents(func(toc *TOC) error { - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFromArithmetic(0.5, 0.5, 0.5) style.FontSize = 20 @@ -2517,7 +2523,7 @@ func TestOptimizeImagePPI(t *testing.T) { return } - imgJpeg, err := NewImageFromData(imgDataJpeg) + imgJpeg, err := c.NewImageFromData(imgDataJpeg) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -2547,7 +2553,7 @@ func TestOptimizeImagePPI(t *testing.T) { t.FailNow() } - img, err := NewImageFromData(imgData) + img, err := c.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) t.FailNow() @@ -2608,7 +2614,7 @@ func TestCombineIdenticalIndirectObjects(t *testing.T) { //subCh1 := NewSubchapter(ch1, "Workflow") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -2650,7 +2656,7 @@ func TestCombineIdenticalIndirectObjects(t *testing.T) { // Set a function to create the front Page. c.CreateFrontPage(func(args FrontpageFunctionArgs) { - p := NewParagraph("Example Report") + p := c.NewParagraph("Example Report") p.SetWidth(c.Width()) p.SetTextAlignment(TextAlignmentCenter) p.SetFontSize(32) @@ -2667,7 +2673,7 @@ func TestCombineIdenticalIndirectObjects(t *testing.T) { // AddTOC property of the creator is set to true. // This function is used just to customize the style of the TOC. c.CreateTableOfContents(func(toc *TOC) error { - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFromArithmetic(0.5, 0.5, 0.5) style.FontSize = 20 @@ -2710,7 +2716,8 @@ func TestCombineIdenticalIndirectObjects(t *testing.T) { func TestCompressStreams(t *testing.T) { createDoc := func() *Creator { c := New() - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore" + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -2788,7 +2795,7 @@ func TestAllOptimizations(t *testing.T) { //subCh1 := NewSubchapter(ch1, "Workflow") - p := NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + + p := c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " + "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore " + "eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + @@ -2830,7 +2837,7 @@ func TestAllOptimizations(t *testing.T) { // Set a function to create the front Page. c.CreateFrontPage(func(args FrontpageFunctionArgs) { - p := NewParagraph("Example Report") + p := c.NewParagraph("Example Report") p.SetWidth(c.Width()) p.SetTextAlignment(TextAlignmentCenter) p.SetFontSize(32) @@ -2847,7 +2854,7 @@ func TestAllOptimizations(t *testing.T) { // AddTOC property of the creator is set to true. // This function is used just to customize the style of the TOC. c.CreateTableOfContents(func(toc *TOC) error { - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFromArithmetic(0.5, 0.5, 0.5) style.FontSize = 20 diff --git a/pdf/creator/curve.go b/pdf/creator/curve.go index 072be42c..4c3d583d 100644 --- a/pdf/creator/curve.go +++ b/pdf/creator/curve.go @@ -12,8 +12,8 @@ import ( "github.com/unidoc/unidoc/pdf/model" ) -// NewCurve returns new instance of Curve between points (x1,y1) and (x2, y2) with control point (cx,cy). -func NewCurve(x1, y1, cx, cy, x2, y2 float64) *Curve { +// newCurve returns new instance of Curve between points (x1,y1) and (x2, y2) with control point (cx,cy). +func newCurve(x1, y1, cx, cy, x2, y2 float64) *Curve { c := &Curve{} c.x1 = x1 diff --git a/pdf/creator/curve_test.go b/pdf/creator/curve_test.go index 338ac41e..d5a2df50 100644 --- a/pdf/creator/curve_test.go +++ b/pdf/creator/curve_test.go @@ -10,7 +10,7 @@ import "testing" func TestNewCurve(t *testing.T) { creator := New() creator.NewPage() - curve := NewCurve(20, 20, 15, 35, 40, 150) + curve := creator.NewCurve(20, 20, 15, 35, 40, 150) curve.SetWidth(3.0) curve.SetColor(ColorGreen) err := creator.Draw(curve) @@ -26,15 +26,15 @@ func TestNewCurve(t *testing.T) { } } -func CreateCurve(x1, y1, cx, cy, x2, y2 float64, color Color) *Curve { - curve := NewCurve(x1, y1, cx, cy, x2, y2) +func CreateCurve(c *Creator, x1, y1, cx, cy, x2, y2 float64, color Color) *Curve { + curve := c.NewCurve(x1, y1, cx, cy, x2, y2) curve.SetWidth(1) curve.SetColor(color) return curve } -func CreateLine(x1, y1, x2, y2, width float64) *Line { - line := NewLine(x1, y1, x2, y2) +func CreateLine(c *Creator, x1, y1, x2, y2, width float64) *Line { + line := c.NewLine(x1, y1, x2, y2) line.SetLineWidth(width) line.SetColor(ColorRed) return line @@ -45,23 +45,23 @@ func TestNewCurveWithGlass(t *testing.T) { creator.NewPage() // Width 200 - creator.Draw(CreateLine(30, 200, 270, 200, 1)) + creator.Draw(CreateLine(creator, 30, 200, 270, 200, 1)) // Curve up - creator.Draw(CreateCurve(50, 200, 75, 145, 150, 150, ColorRed)) - creator.Draw(CreateCurve(150, 150, 205, 145, 250, 200, ColorGreen)) + creator.Draw(CreateCurve(creator, 50, 200, 75, 145, 150, 150, ColorRed)) + creator.Draw(CreateCurve(creator, 150, 150, 205, 145, 250, 200, ColorGreen)) // Curve down - creator.Draw(CreateCurve(50, 200, 75, 245, 150, 250, ColorBlue)) - creator.Draw(CreateCurve(150, 250, 225, 245, 250, 200, ColorBlack)) + creator.Draw(CreateCurve(creator, 50, 200, 75, 245, 150, 250, ColorBlue)) + creator.Draw(CreateCurve(creator, 150, 250, 225, 245, 250, 200, ColorBlack)) // Vertical line - creator.Draw(CreateLine(50, 200, 51, 400, 1)) - creator.Draw(CreateLine(250, 200, 251, 400, 1)) + creator.Draw(CreateLine(creator, 50, 200, 51, 400, 1)) + creator.Draw(CreateLine(creator, 250, 200, 251, 400, 1)) // Curve down - creator.Draw(CreateCurve(51, 399, 75, 445, 150, 450, ColorRed)) - creator.Draw(CreateCurve(150, 450, 225, 445, 251, 399, ColorGreen)) + creator.Draw(CreateCurve(creator, 51, 399, 75, 445, 150, 450, ColorRed)) + creator.Draw(CreateCurve(creator, 150, 450, 225, 445, 251, 399, ColorGreen)) err := creator.WriteToFile("/tmp/curve_glass.pdf") if err != nil { diff --git a/pdf/creator/division.go b/pdf/creator/division.go index a09265de..58fb0873 100644 --- a/pdf/creator/division.go +++ b/pdf/creator/division.go @@ -29,8 +29,8 @@ type Division struct { inline bool } -// NewDivision returns a new Division container component. -func NewDivision() *Division { +// newDivision returns a new Division container component. +func newDivision() *Division { return &Division{ components: []VectorDrawable{}, } diff --git a/pdf/creator/division_test.go b/pdf/creator/division_test.go index dcea574f..24921090 100644 --- a/pdf/creator/division_test.go +++ b/pdf/creator/division_test.go @@ -42,7 +42,7 @@ func TestDivVertical(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("Regular division component") + p := c.NewParagraph("Regular division component") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -52,28 +52,31 @@ func TestDivVertical(t *testing.T) { } // Draw division. - div := NewDivision() + div := c.NewDivision() if div.Inline() { t.Fatal("Fail: Incorrect inline mode value") } - p = NewParagraph("Components are stacked vertically ") + p = c.NewParagraph("Components are stacked vertically ") p.SetFont(fontRegular) div.Add(p) - p = NewParagraph("but not horizontally") + p = c.NewParagraph("but not horizontally") p.SetFont(fontBold) div.Add(p) // Add styled paragraph - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFrom8bit(0, 0, 255) - s := NewStyledParagraph("Not even with a styled ", style) + s := c.NewStyledParagraph() + chunk := s.Append("Not even with a styled ") + chunk.Style = style style.Color = ColorRGBFrom8bit(255, 0, 0) - s.Append("paragraph", style) + chunk = s.Append("paragraph") + chunk.Style = style div.Add(s) @@ -97,7 +100,7 @@ func TestDivInline(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("Inline division component") + p := c.NewParagraph("Inline division component") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -107,46 +110,51 @@ func TestDivInline(t *testing.T) { } // Draw division. - div := NewDivision() + div := c.NewDivision() div.SetInline(true) if !div.Inline() { t.Fatal("Fail: Incorrect inline mode value") } - p = NewParagraph("Components are stacked both vertically ") + p = c.NewParagraph("Components are stacked both vertically ") p.SetEnableWrap(false) p.SetFont(fontRegular) div.Add(p) - p = NewParagraph("and horizontally. ") + p = c.NewParagraph("and horizontally. ") p.SetEnableWrap(false) p.SetFont(fontBold) div.Add(p) - p = NewParagraph("Only if they fit right!") + p = c.NewParagraph("Only if they fit right!") p.SetEnableWrap(false) p.SetFont(fontRegular) div.Add(p) - p = NewParagraph("This one did not fit in the available line space. ") + p = c.NewParagraph("This one did not fit in the available line space. ") p.SetEnableWrap(false) p.SetFont(fontBold) div.Add(p) // Add styled paragraph - style := NewTextStyle() + style := c.NewTextStyle() style.Color = ColorRGBFrom8bit(0, 0, 255) - s := NewStyledParagraph("This styled paragraph should ", style) + s := c.NewStyledParagraph() s.SetEnableWrap(false) + chunk := s.Append("This styled paragraph should ") + chunk.Style = style + style.Color = ColorRGBFrom8bit(255, 0, 0) - s.Append("fit", style) + chunk = s.Append("fit") + chunk.Style = style style.Color = ColorRGBFrom8bit(0, 255, 0) style.Font = fontBold - s.Append(" in.", style) + chunk = s.Append(" in.") + chunk.Style = style div.Add(s) @@ -170,7 +178,7 @@ func TestDivNumberMatrix(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("A list of numbers in an inline division") + p := c.NewParagraph("A list of numbers in an inline division") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -180,7 +188,7 @@ func TestDivNumberMatrix(t *testing.T) { } // Draw division. - div := NewDivision() + div := c.NewDivision() div.SetInline(true) for i := 0; i < 100; i++ { @@ -188,7 +196,7 @@ func TestDivNumberMatrix(t *testing.T) { g := byte(seed.Intn(200)) b := byte(seed.Intn(200)) - p := NewParagraph(strconv.Itoa(i) + " ") + p := c.NewParagraph(strconv.Itoa(i) + " ") p.SetEnableWrap(false) p.SetColor(ColorRGBFrom8bit(r, g, b)) @@ -221,7 +229,7 @@ func TestDivRandomSequences(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("Inline division of random sequences on multiple pages") + p := c.NewParagraph("Inline division of random sequences on multiple pages") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -231,10 +239,10 @@ func TestDivRandomSequences(t *testing.T) { } // Draw division. - div := NewDivision() + div := c.NewDivision() div.SetInline(true) - style := NewTextStyle() + style := c.NewTextStyle() for i := 0; i < 350; i++ { r := byte(seed.Intn(200)) @@ -245,7 +253,7 @@ func TestDivRandomSequences(t *testing.T) { fontSize := float64(11 + seed.Intn(3)) if seed.Intn(2)%2 == 0 { - p := NewParagraph(word) + p := c.NewParagraph(word) p.SetEnableWrap(false) p.SetColor(ColorRGBFrom8bit(r, g, b)) p.SetFontSize(fontSize) @@ -267,8 +275,12 @@ func TestDivRandomSequences(t *testing.T) { style.Font = fontRegular } - s := NewStyledParagraph(word, style) + s := c.NewStyledParagraph() s.SetEnableWrap(false) + + chunk := s.Append(word) + chunk.Style = style + div.Add(s) } } @@ -293,7 +305,7 @@ func TestTableDivisions(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("Table containing division components") + p := c.NewParagraph("Table containing division components") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -302,17 +314,17 @@ func TestTableDivisions(t *testing.T) { t.Fatalf("Error drawing: %v", err) } - table := NewTable(2) + table := c.NewTable(2) table.SetColumnWidths(0.35, 0.65) // Add regular division to table. - divRegular := NewDivision() + divRegular := c.NewDivision() - p = NewParagraph("Components are stacked vertically ") + p = c.NewParagraph("Components are stacked vertically ") p.SetFont(fontRegular) divRegular.Add(p) - p = NewParagraph("but not horizontally") + p = c.NewParagraph("but not horizontally") p.SetFont(fontBold) divRegular.Add(p) @@ -321,25 +333,25 @@ func TestTableDivisions(t *testing.T) { cell.SetContent(divRegular) // Add inline division to table. - divInline := NewDivision() + divInline := c.NewDivision() divInline.SetInline(true) - p = NewParagraph("Components are stacked vertically ") + p = c.NewParagraph("Components are stacked vertically ") p.SetEnableWrap(false) p.SetFont(fontRegular) divInline.Add(p) - p = NewParagraph("and horizontally. ") + p = c.NewParagraph("and horizontally. ") p.SetEnableWrap(false) p.SetFont(fontBold) divInline.Add(p) - p = NewParagraph("Only if they fit!") + p = c.NewParagraph("Only if they fit!") p.SetEnableWrap(false) p.SetFont(fontRegular) divInline.Add(p) - p = NewParagraph("This one did not fit in the available line space") + p = c.NewParagraph("This one did not fit in the available line space") p.SetEnableWrap(false) p.SetFont(fontBold) divInline.Add(p) diff --git a/pdf/creator/ellipse.go b/pdf/creator/ellipse.go index 863d2a89..f4eabfde 100644 --- a/pdf/creator/ellipse.go +++ b/pdf/creator/ellipse.go @@ -23,8 +23,8 @@ type Ellipse struct { borderWidth float64 } -// NewEllipse creates a new ellipse centered at (xc,yc) with a width and height specified. -func NewEllipse(xc, yc, width, height float64) *Ellipse { +// newEllipse creates a new ellipse centered at (xc,yc) with a width and height specified. +func newEllipse(xc, yc, width, height float64) *Ellipse { ell := &Ellipse{} ell.xc = xc diff --git a/pdf/creator/filled_curve.go b/pdf/creator/filled_curve.go index 1b5e1a25..56bd07de 100644 --- a/pdf/creator/filled_curve.go +++ b/pdf/creator/filled_curve.go @@ -22,8 +22,8 @@ type FilledCurve struct { borderColor *pdf.PdfColorDeviceRGB } -// NewFilledCurve returns a instance of filled curve. -func NewFilledCurve() *FilledCurve { +// newFilledCurve returns a instance of filled curve. +func newFilledCurve() *FilledCurve { curve := FilledCurve{} curve.curves = []draw.CubicBezierCurve{} return &curve diff --git a/pdf/creator/filled_curve_test.go b/pdf/creator/filled_curve_test.go index dc38e014..a767918a 100644 --- a/pdf/creator/filled_curve_test.go +++ b/pdf/creator/filled_curve_test.go @@ -16,7 +16,9 @@ func CreateFillCurve(x0, y0, x1, y1, x2, y2, x3, y3 float64) draw.CubicBezierCur } func TestNewFilledCurve(t *testing.T) { - filledCurve := NewFilledCurve() + creator := New() + + filledCurve := creator.NewFilledCurve() filledCurve.FillEnabled = true filledCurve.BorderEnabled = true filledCurve.BorderWidth = 2 @@ -34,7 +36,6 @@ func TestNewFilledCurve(t *testing.T) { // Leaf filledCurve.AppendCurve(CreateFillCurve(300, 300, 290, 350, 295, 370, 300, 390)) - creator := New() creator.NewPage() creator.Draw(filledCurve) diff --git a/pdf/creator/image.go b/pdf/creator/image.go index 1b2c860d..42031ec8 100644 --- a/pdf/creator/image.go +++ b/pdf/creator/image.go @@ -52,8 +52,8 @@ type Image struct { encoder core.StreamEncoder } -// NewImage create a new image from a unidoc image (model.Image). -func NewImage(img *model.Image) (*Image, error) { +// newImage create a new image from a unidoc image (model.Image). +func newImage(img *model.Image) (*Image, error) { image := &Image{} image.img = img @@ -70,8 +70,8 @@ func NewImage(img *model.Image) (*Image, error) { return image, nil } -// NewImageFromData creates an Image from image data. -func NewImageFromData(data []byte) (*Image, error) { +// newImageFromData creates an Image from image data. +func newImageFromData(data []byte) (*Image, error) { imgReader := bytes.NewReader(data) // Load the image with default handler. @@ -81,17 +81,17 @@ func NewImageFromData(data []byte) (*Image, error) { return nil, err } - return NewImage(img) + return newImage(img) } -// NewImageFromFile creates an Image from a file. -func NewImageFromFile(path string) (*Image, error) { +// newImageFromFile creates an Image from a file. +func newImageFromFile(path string) (*Image, error) { imgData, err := ioutil.ReadFile(path) if err != nil { return nil, err } - img, err := NewImageFromData(imgData) + img, err := newImageFromData(imgData) if err != nil { return nil, err } @@ -99,14 +99,14 @@ func NewImageFromFile(path string) (*Image, error) { return img, nil } -// NewImageFromGoImage creates an Image from a go image.Image datastructure. -func NewImageFromGoImage(goimg goimage.Image) (*Image, error) { +// newImageFromGoImage creates an Image from a go image.Image data structure. +func newImageFromGoImage(goimg goimage.Image) (*Image, error) { img, err := model.ImageHandling.NewImageFromGoImage(goimg) if err != nil { return nil, err } - return NewImage(img) + return newImage(img) } // SetEncoder sets the encoding/compression mechanism for the image. diff --git a/pdf/creator/line.go b/pdf/creator/line.go index ab908b13..84ce09dd 100644 --- a/pdf/creator/line.go +++ b/pdf/creator/line.go @@ -24,8 +24,8 @@ type Line struct { lineWidth float64 } -// NewLine creates a new Line with default parameters between (x1,y1) to (x2,y2). -func NewLine(x1, y1, x2, y2 float64) *Line { +// newLine creates a new Line with default parameters between (x1,y1) to (x2,y2). +func newLine(x1, y1, x2, y2 float64) *Line { l := &Line{} l.x1 = x1 diff --git a/pdf/creator/pagebreak.go b/pdf/creator/pagebreak.go index 40abfe39..94e51251 100644 --- a/pdf/creator/pagebreak.go +++ b/pdf/creator/pagebreak.go @@ -4,8 +4,8 @@ package creator type PageBreak struct { } -// NewPageBreak create a new page break. -func NewPageBreak() *PageBreak { +// newPageBreak create a new page break. +func newPageBreak() *PageBreak { return &PageBreak{} } diff --git a/pdf/creator/paragraph.go b/pdf/creator/paragraph.go index 4cb90297..61e0761b 100644 --- a/pdf/creator/paragraph.go +++ b/pdf/creator/paragraph.go @@ -66,9 +66,9 @@ type Paragraph struct { textLines []string } -// NewParagraph create a new text paragraph. Uses default parameters: Helvetica, WinAnsiEncoding and +// 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 { +func newParagraph(text string, style TextStyle) *Paragraph { p := &Paragraph{} p.text = text @@ -84,7 +84,6 @@ func NewParagraph(text string) *Paragraph { p.lineHeight = 1.0 // TODO: Can we wrap intellectually, only if given width is known? - p.enableWrap = true p.defaultWrap = true p.SetColor(ColorRGBFrom8bit(0, 0, 0)) diff --git a/pdf/creator/rectangle.go b/pdf/creator/rectangle.go index 35ac6db5..0f51dc05 100644 --- a/pdf/creator/rectangle.go +++ b/pdf/creator/rectangle.go @@ -23,8 +23,8 @@ type Rectangle struct { borderWidth float64 } -// 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 { +// 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 diff --git a/pdf/creator/styled_paragraph.go b/pdf/creator/styled_paragraph.go index d22bfbae..a4ed8a3f 100644 --- a/pdf/creator/styled_paragraph.go +++ b/pdf/creator/styled_paragraph.go @@ -14,21 +14,17 @@ import ( "github.com/unidoc/unidoc/common" "github.com/unidoc/unidoc/pdf/contentstream" "github.com/unidoc/unidoc/pdf/core" - "github.com/unidoc/unidoc/pdf/model/textencoding" ) // StyledParagraph represents text drawn with a specified font and can wrap across lines and pages. // By default occupies the available width in the drawing context. type StyledParagraph struct { // Text chunks with styles that compose the paragraph. - chunks []TextChunk + chunks []*TextChunk // Style used for the paragraph for spacing and offsets. defaultStyle TextStyle - // The text encoder which can convert the text (as runes) into a series of glyphs and get character metrics. - encoder textencoding.TextEncoder - // Text alignment: Align left/right/center/justify. alignment TextAlignment @@ -62,25 +58,18 @@ type StyledParagraph struct { scaleY float64 // Text chunk lines after wrapping to available width. - lines [][]TextChunk + lines [][]*TextChunk // Before render callback. beforeRender func(p *StyledParagraph, ctx DrawContext) } -// NewStyledParagraph creates a new styled paragraph. -// Uses default parameters: Helvetica, WinAnsiEncoding and wrap enabled -// with a wrap width of 100 points. -func NewStyledParagraph(text string, style TextStyle) *StyledParagraph { +// newStyledParagraph creates a new styled paragraph. +func newStyledParagraph(style TextStyle) *StyledParagraph { // TODO: Can we wrap intellectually, only if given width is known? p := &StyledParagraph{ - chunks: []TextChunk{ - TextChunk{ - Text: text, - Style: style, - }, - }, - defaultStyle: NewTextStyle(), + chunks: []*TextChunk{}, + defaultStyle: style, lineHeight: 1.0, alignment: TextAlignmentLeft, enableWrap: true, @@ -91,44 +80,43 @@ func NewStyledParagraph(text string, style TextStyle) *StyledParagraph { positioning: positionRelative, } - p.SetEncoder(textencoding.NewWinAnsiTextEncoder()) return p } -// Append adds a new text chunk with a specified style to the paragraph. -func (p *StyledParagraph) Append(text string, style TextStyle) { - chunk := TextChunk{ +// Append adds a new text chunk to the paragraph. +func (p *StyledParagraph) Append(text string) *TextChunk { + chunk := &TextChunk{ Text: text, - Style: style, + Style: p.defaultStyle, } - chunk.Style.Font.SetEncoder(p.encoder) p.chunks = append(p.chunks, chunk) p.wrapText() + + return chunk } // Insert adds a new text chunk at the specified position in the paragraph. -func (p *StyledParagraph) Insert(index uint, text string, style TextStyle) { +func (p *StyledParagraph) Insert(index uint, text string) *TextChunk { l := uint(len(p.chunks)) if index > l { index = l } - chunk := TextChunk{ + chunk := &TextChunk{ Text: text, - Style: style, + Style: p.defaultStyle, } - chunk.Style.Font.SetEncoder(p.encoder) - p.chunks = append(p.chunks[:index], append([]TextChunk{chunk}, p.chunks[index:]...)...) + p.chunks = append(p.chunks[:index], append([]*TextChunk{chunk}, p.chunks[index:]...)...) p.wrapText() + + return chunk } -// Reset sets the entire text and also the style of the paragraph -// to those specified. It behaves as if the paragraph was a new one. +// Reset removes all the text chunks the paragraph contains. func (p *StyledParagraph) Reset(text string, style TextStyle) { - p.chunks = []TextChunk{} - p.Append(text, style) + p.chunks = []*TextChunk{} } // SetTextAlignment sets the horizontal alignment of the text within the space provided. @@ -136,18 +124,6 @@ func (p *StyledParagraph) SetTextAlignment(align TextAlignment) { p.alignment = align } -// SetEncoder sets the text encoding. -func (p *StyledParagraph) SetEncoder(encoder textencoding.TextEncoder) { - p.encoder = encoder - p.defaultStyle.Font.SetEncoder(encoder) - - // Sync with the text font too. - // XXX/FIXME: Keep in 1 place only. - for _, chunk := range p.chunks { - chunk.Style.Font.SetEncoder(encoder) - } -} - // SetLineHeight sets the line height (1.0 default). func (p *StyledParagraph) SetLineHeight(lineheight float64) { p.lineHeight = lineheight @@ -230,7 +206,7 @@ func (p *StyledParagraph) getTextWidth() float64 { style := &chunk.Style for _, rune := range chunk.Text { - glyph, found := p.encoder.RuneToGlyph(rune) + glyph, found := style.Font.Encoder().RuneToGlyph(rune) if !found { common.Log.Debug("Error! Glyph not found for rune: %s\n", rune) @@ -259,13 +235,13 @@ func (p *StyledParagraph) getTextWidth() float64 { } // getTextLineWidth calculates the text width of a provided collection of text chunks. -func (p *StyledParagraph) getTextLineWidth(line []TextChunk) float64 { +func (p *StyledParagraph) getTextLineWidth(line []*TextChunk) float64 { var width float64 for _, chunk := range line { style := &chunk.Style for _, r := range chunk.Text { - glyph, found := p.encoder.RuneToGlyph(r) + glyph, found := style.Font.Encoder().RuneToGlyph(r) if !found { common.Log.Debug("Error! Glyph not found for rune: %s\n", r) @@ -328,12 +304,12 @@ func (p *StyledParagraph) getTextHeight() float64 { // XXX/TODO: Consider the Knuth/Plass algorithm or an alternative. func (p *StyledParagraph) wrapText() error { if !p.enableWrap || int(p.wrapWidth) <= 0 { - p.lines = [][]TextChunk{p.chunks} + p.lines = [][]*TextChunk{p.chunks} return nil } - p.lines = [][]TextChunk{} - var line []TextChunk + p.lines = [][]*TextChunk{} + var line []*TextChunk var lineWidth float64 for _, chunk := range p.chunks { @@ -344,7 +320,7 @@ func (p *StyledParagraph) wrapText() error { var widths []float64 for _, r := range chunk.Text { - glyph, found := p.encoder.RuneToGlyph(r) + glyph, found := style.Font.Encoder().RuneToGlyph(r) if !found { common.Log.Debug("Error! Glyph not found for rune: %v\n", r) @@ -355,12 +331,12 @@ func (p *StyledParagraph) wrapText() error { // newline wrapping. if glyph == "controlLF" { // moves to next line. - line = append(line, TextChunk{ + line = append(line, &TextChunk{ Text: strings.TrimRightFunc(string(part), unicode.IsSpace), Style: style, }) p.lines = append(p.lines, line) - line = []TextChunk{} + line = []*TextChunk{} lineWidth = 0 part = []rune{} @@ -413,12 +389,12 @@ func (p *StyledParagraph) wrapText() error { widths = []float64{w} } - line = append(line, TextChunk{ + line = append(line, &TextChunk{ Text: strings.TrimRightFunc(string(text), unicode.IsSpace), Style: style, }) p.lines = append(p.lines, line) - line = []TextChunk{} + line = []*TextChunk{} } else { lineWidth += w part = append(part, r) @@ -428,7 +404,7 @@ func (p *StyledParagraph) wrapText() error { } if len(part) > 0 { - line = append(line, TextChunk{ + line = append(line, &TextChunk{ Text: string(part), Style: style, }) @@ -588,7 +564,7 @@ func drawStyledParagraphOnBlock(blk *Block, p *StyledParagraph, ctx DrawContext) var chunkSpaces uint for _, r := range chunk.Text { - glyph, found := p.encoder.RuneToGlyph(r) + glyph, found := style.Font.Encoder().RuneToGlyph(r) if !found { common.Log.Debug("Rune 0x%x not supported by text encoder", r) return ctx, errors.New("Unsupported rune in text encoding") @@ -661,7 +637,7 @@ func drawStyledParagraphOnBlock(blk *Block, p *StyledParagraph, ctx DrawContext) var encStr []byte for _, rn := range chunk.Text { - glyph, found := p.encoder.RuneToGlyph(rn) + glyph, found := style.Font.Encoder().RuneToGlyph(rn) if !found { common.Log.Debug("Rune 0x%x not supported by text encoder", r) return ctx, errors.New("Unsupported rune in text encoding") @@ -686,7 +662,7 @@ func drawStyledParagraphOnBlock(blk *Block, p *StyledParagraph, ctx DrawContext) Add_TL(fontSize * p.lineHeight). Add_TJ([]core.PdfObject{core.MakeFloat(-spaceWidth)}...) } else { - encStr = append(encStr, p.encoder.Encode(string(rn))...) + encStr = append(encStr, style.Font.Encoder().Encode(string(rn))...) } } diff --git a/pdf/creator/styled_paragraph_test.go b/pdf/creator/styled_paragraph_test.go index c756fd8c..ed7a19ad 100644 --- a/pdf/creator/styled_paragraph_test.go +++ b/pdf/creator/styled_paragraph_test.go @@ -19,7 +19,7 @@ func TestParagraphRegularVsStyled(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("Regular paragraph vs styled paragraph (should be identical)") + p := c.NewParagraph("Regular paragraph vs styled paragraph (should be identical)") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -28,11 +28,11 @@ func TestParagraphRegularVsStyled(t *testing.T) { t.Fatalf("Error drawing: %v", err) } - table := NewTable(2) + table := c.NewTable(2) table.SetColumnWidths(0.5, 0.5) // Add regular paragraph to table. - p = NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + p = c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") p.SetMargins(10, 10, 5, 10) p.SetFont(fontBold) p.SetEnableWrap(true) @@ -43,20 +43,23 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetContent(p) // Add styled paragraph to table. - style := NewTextStyle() + style := c.NewTextStyle() style.Font = fontBold - s := NewStyledParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.", style) + s := c.NewStyledParagraph() s.SetMargins(10, 10, 5, 10) s.SetEnableWrap(true) s.SetTextAlignment(TextAlignmentLeft) + chunk := s.Append("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetContent(s) // Add regular paragraph to table. - p = NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + p = c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") p.SetMargins(10, 10, 5, 10) p.SetFont(fontRegular) p.SetEnableWrap(true) @@ -71,17 +74,20 @@ func TestParagraphRegularVsStyled(t *testing.T) { style.Font = fontRegular style.Color = ColorRGBFrom8bit(0, 0, 255) - s = NewStyledParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.", style) + s = c.NewStyledParagraph() s.SetMargins(10, 10, 5, 10) s.SetEnableWrap(true) s.SetTextAlignment(TextAlignmentJustify) + chunk = s.Append("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetContent(s) // Add regular paragraph to table. - p = NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + p = c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") p.SetMargins(10, 10, 5, 10) p.SetFont(fontRegular) p.SetEnableWrap(true) @@ -95,17 +101,20 @@ func TestParagraphRegularVsStyled(t *testing.T) { style.Font = fontRegular style.Color = ColorRGBFrom8bit(0, 0, 0) - s = NewStyledParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.", style) + s = c.NewStyledParagraph() s.SetMargins(10, 10, 5, 10) s.SetEnableWrap(true) s.SetTextAlignment(TextAlignmentRight) + chunk = s.Append("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetContent(s) // Add regular paragraph to table. - p = NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + p = c.NewParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") p.SetMargins(10, 10, 5, 10) p.SetFont(fontBold) p.SetEnableWrap(true) @@ -119,20 +128,23 @@ func TestParagraphRegularVsStyled(t *testing.T) { style.Font = fontBold style.Color = ColorRGBFrom8bit(0, 0, 0) - s = NewStyledParagraph("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.", style) + s = c.NewStyledParagraph() s.SetMargins(10, 10, 5, 10) s.SetEnableWrap(true) s.SetTextAlignment(TextAlignmentCenter) + chunk = s.Append("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetContent(s) // Test table cell alignment. - style = NewTextStyle() + style = c.NewTextStyle() // Test left alignment with paragraph wrapping enabled. - p = NewParagraph("Wrap enabled. This text should be left aligned.") + p = c.NewParagraph("Wrap enabled. This text should be left aligned.") p.SetEnableWrap(true) cell = table.NewCell() @@ -140,16 +152,19 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetHorizontalAlignment(CellHorizontalAlignmentLeft) cell.SetContent(p) - s = NewStyledParagraph("Wrap enabled. This text should be left aligned.", style) + s = c.NewStyledParagraph() s.SetEnableWrap(true) + chunk = s.Append("Wrap enabled. This text should be left aligned.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetHorizontalAlignment(CellHorizontalAlignmentLeft) cell.SetContent(s) // Test left alignment with paragraph wrapping disabled. - p = NewParagraph("Wrap disabled. This text should be left aligned.") + p = c.NewParagraph("Wrap disabled. This text should be left aligned.") p.SetEnableWrap(false) cell = table.NewCell() @@ -157,16 +172,19 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetHorizontalAlignment(CellHorizontalAlignmentLeft) cell.SetContent(p) - s = NewStyledParagraph("Wrap disabled. This text should be left aligned.", style) + s = c.NewStyledParagraph() s.SetEnableWrap(false) + chunk = s.Append("Wrap disabled. This text should be left aligned.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetHorizontalAlignment(CellHorizontalAlignmentLeft) cell.SetContent(s) // Test center alignment with paragraph wrapping enabled. - p = NewParagraph("Wrap enabled. This text should be center aligned.") + p = c.NewParagraph("Wrap enabled. This text should be center aligned.") p.SetEnableWrap(true) cell = table.NewCell() @@ -174,16 +192,19 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetHorizontalAlignment(CellHorizontalAlignmentCenter) cell.SetContent(p) - s = NewStyledParagraph("Wrap enabled. This text should be center aligned.", style) + s = c.NewStyledParagraph() s.SetEnableWrap(true) + chunk = s.Append("Wrap enabled. This text should be center aligned.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetHorizontalAlignment(CellHorizontalAlignmentCenter) cell.SetContent(s) // Test center alignment with paragraph wrapping disabled. - p = NewParagraph("Wrap disabled. This text should be center aligned.") + p = c.NewParagraph("Wrap disabled. This text should be center aligned.") p.SetEnableWrap(false) cell = table.NewCell() @@ -191,16 +212,19 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetHorizontalAlignment(CellHorizontalAlignmentCenter) cell.SetContent(p) - s = NewStyledParagraph("Wrap disabled. This text should be center aligned.", style) + s = c.NewStyledParagraph() s.SetEnableWrap(false) + chunk = s.Append("Wrap disabled. This text should be center aligned.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetHorizontalAlignment(CellHorizontalAlignmentCenter) cell.SetContent(s) // Test right alignment with paragraph wrapping enabled. - p = NewParagraph("Wrap enabled. This text should be right aligned.") + p = c.NewParagraph("Wrap enabled. This text should be right aligned.") p.SetEnableWrap(true) cell = table.NewCell() @@ -208,16 +232,19 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetHorizontalAlignment(CellHorizontalAlignmentRight) cell.SetContent(p) - s = NewStyledParagraph("Wrap enabled. This text should be right aligned.", style) + s = c.NewStyledParagraph() s.SetEnableWrap(true) + chunk = s.Append("Wrap enabled. This text should be right aligned.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetHorizontalAlignment(CellHorizontalAlignmentRight) cell.SetContent(s) // Test right alignment with paragraph wrapping disabled. - p = NewParagraph("Wrap disabled. This text should be right aligned.") + p = c.NewParagraph("Wrap disabled. This text should be right aligned.") p.SetEnableWrap(false) cell = table.NewCell() @@ -225,9 +252,12 @@ func TestParagraphRegularVsStyled(t *testing.T) { cell.SetHorizontalAlignment(CellHorizontalAlignmentRight) cell.SetContent(p) - s = NewStyledParagraph("Wrap disabled. This text should be right aligned.", style) + s = c.NewStyledParagraph() s.SetEnableWrap(false) + chunk = s.Append("Wrap disabled. This text should be right aligned.") + chunk.Style = style + cell = table.NewCell() cell.SetBorder(CellBorderSideAll, CellBorderStyleSingle, 1) cell.SetHorizontalAlignment(CellHorizontalAlignmentRight) @@ -255,7 +285,7 @@ func TestStyledParagraph(t *testing.T) { c.NewPage() // Draw section title. - p := NewParagraph("Styled paragraph") + p := c.NewParagraph("Styled paragraph") p.SetMargins(0, 0, 20, 10) p.SetFont(fontBold) @@ -264,38 +294,47 @@ func TestStyledParagraph(t *testing.T) { t.Fatalf("Error drawing: %v", err) } - style := NewTextStyle() + style := c.NewTextStyle() style.Font = fontRegular - s := NewStyledParagraph("This is a paragraph ", style) + s := c.NewStyledParagraph() s.SetEnableWrap(true) s.SetTextAlignment(TextAlignmentJustify) s.SetMargins(0, 0, 10, 0) + chunk := s.Append("This is a paragraph ") + chunk.Style = style + style.Color = ColorRGBFrom8bit(255, 0, 0) - s.Append("with different colors ", style) + chunk = s.Append("with different colors ") + chunk.Style = style style.Color = ColorRGBFrom8bit(0, 0, 0) style.FontSize = 14 - s.Append("and with different font sizes ", style) + chunk = s.Append("and with different font sizes ") + chunk.Style = style style.FontSize = 10 style.Font = fontBold - s.Append("and with different font styles ", style) + chunk = s.Append("and with different font styles ") + chunk.Style = style style.Font = fontHelvetica style.FontSize = 13 - s.Append("and with different fonts ", style) + chunk = s.Append("and with different fonts ") + chunk.Style = style style.Font = fontBold style.Color = ColorRGBFrom8bit(0, 0, 255) style.FontSize = 15 - s.Append("and with the changed properties all at once. ", style) + chunk = s.Append("and with the changed properties all at once. ") + chunk.Style = style style.Color = ColorRGBFrom8bit(127, 255, 0) style.FontSize = 12 style.Font = fontHelvetica - s.Append("And maybe try a different color again.", style) + chunk = s.Append("And maybe try a different color again.") + chunk.Style = style err = c.Draw(s) if err != nil { @@ -312,7 +351,8 @@ func TestStyledParagraph(t *testing.T) { style.Color = ColorRGBFrom8bit(0, 0, 255) style.FontSize = 15 style.Font = fontHelvetica - s.Append("And maybe try a different color again.", style) + chunk = s.Append("And maybe try a different color again.") + chunk.Style = style err = c.Draw(s) if err != nil { diff --git a/pdf/creator/subchapter.go b/pdf/creator/subchapter.go index 49371617..b35a3ccc 100644 --- a/pdf/creator/subchapter.go +++ b/pdf/creator/subchapter.go @@ -10,7 +10,6 @@ import ( "strconv" "github.com/unidoc/unidoc/common" - "github.com/unidoc/unidoc/pdf/model" ) // Subchapter simply represents a sub chapter pertaining to a specific Chapter. It can contain @@ -42,37 +41,30 @@ type Subchapter struct { toc *TOC } -// NewSubchapter creates a new Subchapter under Chapter ch with specified title. +// 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{} - +func newSubchapter(ch *Chapter, title string, style TextStyle) *Subchapter { ch.subchapters++ - subchap.subchapterNum = ch.subchapters - - subchap.chapterNum = ch.number - subchap.title = title - - heading := fmt.Sprintf("%d.%d %s", subchap.chapterNum, subchap.subchapterNum, title) - p := NewParagraph(heading) + p := newParagraph(fmt.Sprintf("%d.%d %s", ch.number, ch.subchapters, title), style) + p.SetFont(style.Font) // bold? p.SetFontSize(14) - helvetica := model.NewStandard14FontMustCompile(model.Helvetica) - p.SetFont(helvetica) // bold? - subchap.showNumbering = true - subchap.includeInTOC = true + subchapter := &Subchapter{ + subchapterNum: ch.subchapters, + chapterNum: ch.number, + title: title, + showNumbering: true, + includeInTOC: true, + heading: p, + contents: []Drawable{}, + toc: ch.toc, + } - subchap.heading = p - subchap.contents = []Drawable{} + // Add subchapter to chapter. + ch.Add(subchapter) - // Add subchapter to ch. - ch.Add(subchap) - - // Keep a reference for toc. - subchap.toc = c.toc - - return subchap + return subchapter } // SetShowNumbering sets a flag to indicate whether or not to show chapter numbers as part of title. diff --git a/pdf/creator/table.go b/pdf/creator/table.go index d7deca77..e6ff5dab 100644 --- a/pdf/creator/table.go +++ b/pdf/creator/table.go @@ -47,8 +47,8 @@ type Table struct { margins margins } -// NewTable create a new Table with a specified number of columns. -func NewTable(cols int) *Table { +// newTable create a new Table with a specified number of columns. +func newTable(cols int) *Table { t := &Table{} t.rows = 0 t.cols = cols @@ -454,12 +454,19 @@ const ( type CellBorderSide int const ( - // Left side border. + // CellBorderSideLeft adds border on the left side of the table. CellBorderSideLeft CellBorderSide = iota + + // CellBorderSideRight adds a border on the right side of the table. CellBorderSideRight + + // CellBorderSideTop adds a border on the top side of the table. CellBorderSideTop + + // CellBorderSideBottom adds a border on the bottom side of the table. CellBorderSideBottom - // Border on all sides. + + // CellBorderSideAll adds borders on all sides of the table. CellBorderSideAll ) diff --git a/pdf/creator/table_test.go b/pdf/creator/table_test.go index effb6130..45c20e05 100644 --- a/pdf/creator/table_test.go +++ b/pdf/creator/table_test.go @@ -21,7 +21,7 @@ var ( func TestTableMultiParagraphWrapped(t *testing.T) { c := New() - pageHistoryTable := NewTable(4) + pageHistoryTable := c.NewTable(4) pageHistoryTable.SetColumnWidths(0.1, 0.6, 0.15, 0.15) content := [][]string{ {"1", "FullText Search Highlight the Term in Results \n\nissues 60", "120", "130"}, @@ -33,7 +33,7 @@ func TestTableMultiParagraphWrapped(t *testing.T) { for _, rows := range content { for _, txt := range rows { - p := NewParagraph(txt) + p := c.NewParagraph(txt) p.SetFontSize(12) p.SetFont(fontHelvetica) p.SetColor(ColorBlack) @@ -59,7 +59,7 @@ func TestTableMultiParagraphWrapped(t *testing.T) { func TestTableWithImage(t *testing.T) { c := New() - pageHistoryTable := NewTable(4) + pageHistoryTable := c.NewTable(4) pageHistoryTable.SetColumnWidths(0.1, 0.6, 0.15, 0.15) content := [][]string{ {"1", "FullText Search Highlight the Term in Results \n\nissues 60", "120", "130"}, @@ -70,7 +70,7 @@ func TestTableWithImage(t *testing.T) { } for _, rows := range content { for _, txt := range rows { - p := NewParagraph(txt) + p := c.NewParagraph(txt) p.SetFontSize(12) p.SetFont(fontHelvetica) p.SetColor(ColorBlack) @@ -93,7 +93,7 @@ func TestTableWithImage(t *testing.T) { t.Errorf("Fail: %v\n", err) return } - img, err := NewImageFromData(imgData) + img, err := c.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -124,7 +124,7 @@ func TestTableWithImage(t *testing.T) { func TestTableWithDiv(t *testing.T) { c := New() - pageHistoryTable := NewTable(4) + pageHistoryTable := c.NewTable(4) pageHistoryTable.SetColumnWidths(0.1, 0.6, 0.15, 0.15) headings := []string{ @@ -155,7 +155,7 @@ func TestTableWithDiv(t *testing.T) { } for _, rows := range content { for colIdx, txt := range rows { - p := NewParagraph(txt) + p := c.NewParagraph(txt) p.SetFontSize(12) p.SetFont(fontHelvetica) p.SetColor(ColorBlack) @@ -167,10 +167,10 @@ func TestTableWithDiv(t *testing.T) { } // Place cell contents (header and text) inside a div. - div := NewDivision() + div := c.NewDivision() if len(headings[colIdx]) > 0 { - heading := NewParagraph(headings[colIdx]) + heading := c.NewParagraph(headings[colIdx]) heading.SetFontSize(14) heading.SetFont(fontHelveticaBold) heading.SetColor(ColorRed) @@ -203,7 +203,7 @@ func TestTableWithDiv(t *testing.T) { t.Errorf("Fail: %v\n", err) return } - img, err := NewImageFromData(imgData) + img, err := c.NewImageFromData(imgData) if err != nil { t.Errorf("Fail: %v\n", err) return diff --git a/pdf/creator/text_style.go b/pdf/creator/text_style.go index e831e367..64532dcb 100644 --- a/pdf/creator/text_style.go +++ b/pdf/creator/text_style.go @@ -6,8 +6,7 @@ package creator import ( - "github.com/unidoc/unidoc/pdf/model/fonts" - "github.com/unidoc/unidoc/pdf/model/textencoding" + "github.com/unidoc/unidoc/pdf/model" ) // TextStyle is a collection of properties that can be assigned to a chunk of text. @@ -16,19 +15,14 @@ type TextStyle struct { Color Color // The font the text will use. - Font fonts.Font + Font *model.PdfFont // The size of the font. FontSize float64 } -// NewTextStyle creates a new text style object which can be used with chunks -// of text. Uses default parameters: Helvetica, WinAnsiEncoding and wrap -// enabled with a wrap width of 100 points. -func NewTextStyle() TextStyle { - font := fonts.NewFontHelvetica() - font.SetEncoder(textencoding.NewWinAnsiTextEncoder()) - +// newTextStyle creates a new text style object using the specified font. +func newTextStyle(font *model.PdfFont) TextStyle { return TextStyle{ Color: ColorRGBFrom8bit(0, 0, 0), Font: font, diff --git a/pdf/creator/toc.go b/pdf/creator/toc.go index 082b7cb8..db2dea94 100644 --- a/pdf/creator/toc.go +++ b/pdf/creator/toc.go @@ -5,8 +5,6 @@ package creator -import "github.com/unidoc/unidoc/pdf/model/fonts" - // TOC represents a table of contents component. // It consists of a paragraph heading and a collection of // table of contents lines. @@ -43,32 +41,36 @@ type TOC struct { // Positioning: relative/absolute. positioning positioning + + // Default style used for internal operations. + defaultStyle TextStyle } -// NewTOC creates a new table of contents. -func NewTOC(title string) *TOC { - headingStyle := NewTextStyle() - headingStyle.Font = fonts.NewFontHelveticaBold() +// newTOC creates a new table of contents. +func newTOC(title string, style, styleHeading TextStyle) *TOC { + headingStyle := styleHeading headingStyle.FontSize = 14 - heading := NewStyledParagraph(title, headingStyle) + heading := newStyledParagraph(headingStyle) heading.SetEnableWrap(true) heading.SetTextAlignment(TextAlignmentLeft) heading.SetMargins(0, 0, 0, 5) - lineStyle := NewTextStyle() + chunk := heading.Append(title) + chunk.Style = headingStyle return &TOC{ heading: heading, lines: []*TOCLine{}, - lineNumberStyle: lineStyle, - lineTitleStyle: lineStyle, - lineSeparatorStyle: lineStyle, - linePageStyle: lineStyle, + lineNumberStyle: style, + lineTitleStyle: style, + lineSeparatorStyle: style, + linePageStyle: style, lineSeparator: ".", lineLevelOffset: 10, lineMargins: margins{0, 0, 2, 2}, positioning: positionRelative, + defaultStyle: style, } } @@ -89,7 +91,7 @@ func (t *TOC) SetHeading(text string, style TextStyle) { // Add adds a new line with the default style to the table of contents. func (t *TOC) Add(number, title, page string, level uint) *TOCLine { - tl := t.AddLine(NewStyledTOCLine( + tl := t.AddLine(newStyledTOCLine( TextChunk{ Text: number, Style: t.lineNumberStyle, @@ -103,6 +105,7 @@ func (t *TOC) Add(number, title, page string, level uint) *TOCLine { Style: t.linePageStyle, }, level, + t.defaultStyle, )) if tl == nil { diff --git a/pdf/creator/toc_line.go b/pdf/creator/toc_line.go index 4b0f85db..7a56d8a4 100644 --- a/pdf/creator/toc_line.go +++ b/pdf/creator/toc_line.go @@ -44,11 +44,9 @@ type TOCLine struct { positioning positioning } -// NewTOCLine creates a new table of contents line with the default style. -func NewTOCLine(number, title, page string, level uint) *TOCLine { - style := NewTextStyle() - - return NewStyledTOCLine( +// newTOCLine creates a new table of contents line with the default style. +func newTOCLine(number, title, page string, level uint, style TextStyle) *TOCLine { + return newStyledTOCLine( TextChunk{ Text: number, Style: style, @@ -62,14 +60,13 @@ func NewTOCLine(number, title, page string, level uint) *TOCLine { Style: style, }, level, + style, ) } -// NewStyledTOCLine creates a new table of contents line with the provided style. -func NewStyledTOCLine(number, title, page TextChunk, level uint) *TOCLine { - style := NewTextStyle() - - sp := NewStyledParagraph("", style) +// newStyledTOCLine creates a new table of contents line with the provided style. +func newStyledTOCLine(number, title, page TextChunk, level uint, style TextStyle) *TOCLine { + sp := newStyledParagraph(style) sp.SetEnableWrap(true) sp.SetTextAlignment(TextAlignmentLeft) sp.SetMargins(0, 0, 2, 2) @@ -157,19 +154,18 @@ func (tl *TOCLine) prepareParagraph(sp *StyledParagraph, ctx DrawContext) { page = " " + page } - sp.chunks = []TextChunk{ - tl.Number, - TextChunk{ + sp.chunks = []*TextChunk{ + &tl.Number, + &TextChunk{ Text: title, Style: tl.Title.Style, }, - TextChunk{ + &TextChunk{ Text: page, Style: tl.Page.Style, }, } - sp.SetEncoder(sp.encoder) sp.wrapText() // Insert separator. @@ -179,12 +175,13 @@ func (tl *TOCLine) prepareParagraph(sp *StyledParagraph, ctx DrawContext) { } availWidth := ctx.Width*1000 - sp.getTextLineWidth(sp.lines[l-1]) - sepWidth := sp.getTextLineWidth([]TextChunk{tl.Separator}) + sepWidth := sp.getTextLineWidth([]*TextChunk{&tl.Separator}) sepCount := int(availWidth / sepWidth) sepText := strings.Repeat(tl.Separator.Text, sepCount) sepStyle := tl.Separator.Style - sp.Insert(2, sepText, sepStyle) + chunk := sp.Insert(2, sepText) + chunk.Style = sepStyle // Push page numbers to the end of the line. availWidth = availWidth - float64(sepCount)*sepWidth @@ -195,7 +192,9 @@ func (tl *TOCLine) prepareParagraph(sp *StyledParagraph, ctx DrawContext) { if spaces > 0 { style := sepStyle style.FontSize = 1 - sp.Insert(2, strings.Repeat(" ", spaces), style) + + chunk = sp.Insert(2, strings.Repeat(" ", spaces)) + chunk.Style = style } } } diff --git a/pdf/creator/toc_test.go b/pdf/creator/toc_test.go index 12234dfc..f4e6f66e 100644 --- a/pdf/creator/toc_test.go +++ b/pdf/creator/toc_test.go @@ -7,17 +7,17 @@ package creator import ( "testing" - "github.com/unidoc/unidoc/pdf/model/fonts" + "github.com/unidoc/unidoc/pdf/model" ) func TestTOCAdvanced(t *testing.T) { - fontHelvetica := fonts.NewFontHelvetica() - fontHelveticaBold := fonts.NewFontHelveticaBold() + fontHelvetica := model.NewStandard14FontMustCompile(model.Helvetica) + fontHelveticaBold := model.NewStandard14FontMustCompile(model.HelveticaBold) c := New() c.NewPage() - toc := NewTOC("Table of Contents") + toc := c.NewTOC("Table of Contents") // Set separator and margins for all the lines. toc.SetLineSeparator(".") @@ -25,7 +25,7 @@ func TestTOCAdvanced(t *testing.T) { toc.SetLineLevelOffset(12) // Set style for all line numbers. - style := NewTextStyle() + style := c.NewTextStyle() style.Font = fontHelveticaBold style.Color = ColorRGBFrom8bit(100, 100, 100) toc.SetLineNumberStyle(style) From d2ed3db2c21deacf2b7a2e7e336452068481345e Mon Sep 17 00:00:00 2001 From: Adrian-George Bostan Date: Fri, 12 Oct 2018 23:33:50 +0300 Subject: [PATCH 3/4] Fix StyledParagraph Reset method prototype --- pdf/creator/styled_paragraph.go | 2 +- pdf/creator/styled_paragraph_test.go | 5 ++++- pdf/creator/toc.go | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pdf/creator/styled_paragraph.go b/pdf/creator/styled_paragraph.go index a4ed8a3f..e79f37cd 100644 --- a/pdf/creator/styled_paragraph.go +++ b/pdf/creator/styled_paragraph.go @@ -115,7 +115,7 @@ func (p *StyledParagraph) Insert(index uint, text string) *TextChunk { } // Reset removes all the text chunks the paragraph contains. -func (p *StyledParagraph) Reset(text string, style TextStyle) { +func (p *StyledParagraph) Reset() { p.chunks = []*TextChunk{} } diff --git a/pdf/creator/styled_paragraph_test.go b/pdf/creator/styled_paragraph_test.go index ed7a19ad..550be8d7 100644 --- a/pdf/creator/styled_paragraph_test.go +++ b/pdf/creator/styled_paragraph_test.go @@ -345,9 +345,12 @@ func TestStyledParagraph(t *testing.T) { style.Color = ColorRGBFrom8bit(255, 0, 0) style.Font = fontRegular - s.Reset("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar. ", style) + s.Reset() s.SetTextAlignment(TextAlignmentJustify) + chunk = s.Append("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacus viverra vitae congue eu consequat. Cras adipiscing enim eu turpis. Lectus magna fringilla urna porttitor. Condimentum id venenatis a condimentum. Quis ipsum suspendisse ultrices gravida dictum fusce. In fermentum posuere urna nec tincidunt. Dis parturient montes nascetur ridiculus mus. Pharetra diam sit amet nisl suscipit adipiscing. Proin fermentum leo vel orci porta. Id diam vel quam elementum pulvinar. ") + chunk.Style = style + style.Color = ColorRGBFrom8bit(0, 0, 255) style.FontSize = 15 style.Font = fontHelvetica diff --git a/pdf/creator/toc.go b/pdf/creator/toc.go index db2dea94..6fd10fa0 100644 --- a/pdf/creator/toc.go +++ b/pdf/creator/toc.go @@ -86,7 +86,11 @@ func (t *TOC) Lines() []*TOCLine { // SetHeading sets the text and the style of the heading of the TOC component. func (t *TOC) SetHeading(text string, style TextStyle) { - t.heading.Reset(text, style) + h := t.Heading() + + h.Reset() + chunk := h.Append(text) + chunk.Style = style } // Add adds a new line with the default style to the table of contents. From 0b3a67486a4002158261d58f1326359c523beaab Mon Sep 17 00:00:00 2001 From: Adrian-George Bostan Date: Sun, 14 Oct 2018 14:50:12 +0300 Subject: [PATCH 4/4] Add NewImageFromGoImage method to the creator --- pdf/creator/creator.go | 2 +- pdf/creator/creator_test.go | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pdf/creator/creator.go b/pdf/creator/creator.go index 669a525c..a3108abb 100644 --- a/pdf/creator/creator.go +++ b/pdf/creator/creator.go @@ -719,6 +719,6 @@ func (c *Creator) NewImageFromFile(path string) (*Image, error) { } // NewImageFromGoImage creates an Image from a go image.Image data structure. -func NewImageFromGoImage(goimg goimage.Image) (*Image, error) { +func (c *Creator) NewImageFromGoImage(goimg goimage.Image) (*Image, error) { return newImageFromGoImage(goimg) } diff --git a/pdf/creator/creator_test.go b/pdf/creator/creator_test.go index 9f117f4b..8802d3d5 100644 --- a/pdf/creator/creator_test.go +++ b/pdf/creator/creator_test.go @@ -2008,7 +2008,7 @@ func TestQRCodeOnNewPage(t *testing.T) { return } - img, err := NewImageFromGoImage(qrCode) + img, err := creator.NewImageFromGoImage(qrCode) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -2027,6 +2027,8 @@ func TestQRCodeOnNewPage(t *testing.T) { // Example of using a template Page, generating and applying QR func TestQRCodeOnTemplate(t *testing.T) { + creator := New() + pages, err := loadPagesFromFile(testPdfTemplatesFile1) if err != nil { t.Errorf("Fail: %v\n", err) @@ -2053,7 +2055,7 @@ func TestQRCodeOnTemplate(t *testing.T) { } // Prepare content image. - image, err := NewImageFromGoImage(qrCode) + image, err := creator.NewImageFromGoImage(qrCode) if err != nil { t.Errorf("Fail: %v\n", err) return @@ -2064,7 +2066,6 @@ func TestQRCodeOnTemplate(t *testing.T) { tpl.Draw(image) - creator := New() creator.NewPage() creator.Draw(tpl)