From e982ad5dfea40ff2cfd5d93deb99c82678b8f43e Mon Sep 17 00:00:00 2001 From: Kurt Jung Date: Fri, 6 Dec 2013 11:43:41 -0500 Subject: Added SplitLines function by Bruno Michel and demonstration of its use. --- fpdf.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fpdf_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/fpdf.go b/fpdf.go index e239a32..ff50b2f 100644 --- a/fpdf.go +++ b/fpdf.go @@ -1605,6 +1605,59 @@ func (f *Fpdf) Cellf(w, h float64, fmtStr string, args ...interface{}) { f.CellFormat(w, h, sprintf(fmtStr, args...), "", 0, "L", false, 0, "") } +// SplitLines splits text into several lines using the current font. Each line +// has its length limited to a maximum width given by w. This function can be +// used to determine the total height of wrapped text for vertical placement +// purposes. +// +// You can use MultiCell if you want to print a text on several lines in a +// simple way. +// +// See tutorial 19 for an example of this function. +func (f *Fpdf) SplitLines(txt []byte, w float64) [][]byte { + // Function contributed by Bruno Michel + lines := [][]byte{} + cw := &f.currentFont.Cw + wmax := (w - 2*f.cMargin) * 1000 / f.fontSize + s := bytes.Replace(txt, []byte("\r"), []byte{}, -1) + nb := len(s) + for nb > 0 && s[nb-1] == '\n' { + nb-- + } + s = s[0:nb] + sep := -1 + i := 0 + j := 0 + l := 0.0 + for i < nb { + c := s[i] + l += float64(cw[c]) + if c == ' ' || c == '\t' || c == '\n' { + sep = i + } + if c == '\n' || l > wmax { + if sep == -1 { + if i == j { + i++ + } + sep = i + } else { + i = sep + 1 + } + lines = append(lines, s[j:sep]) + sep = -1 + j = i + l = 0 + } else { + i++ + } + } + if i != j { + lines = append(lines, s[j:i]) + } + return lines +} + // MultiCell supports printing text with line breaks. They can be automatic (as // soon as the text reaches the right border of the cell) or explicit (via the // \n character). As many cells as necessary are output, one below the other. diff --git a/fpdf_test.go b/fpdf_test.go index 5edc6c8..d70875a 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -1131,3 +1131,30 @@ func ExampleFpdf_tutorial18() { // Output: // Successfully generated pdf/tutorial18.pdf } + +// Example to demonstrate Bruno Michel's line splitting function. +func ExampleFpdf_tutorial19() { + const ( + fontPtSize = 18.0 + lineHt = fontPtSize * 25.4 / 72.0 + wd = 100.0 + ) + pdf := gofpdf.New("P", "mm", "A4", cnFontDir) // A4 210.0 x 297.0 + pdf.SetFont("Times", "", fontPtSize) + pdf.AddPage() + pdf.SetMargins(10, 10, 10) + lines := pdf.SplitLines([]byte(lorem()), wd) + ht := float64(len(lines)) * lineHt + y := (297.0 - ht) / 2.0 + pdf.SetDrawColor(128, 128, 128) + pdf.SetFillColor(255, 255, 210) + x := (210.0 - (wd + 40.0)) / 2.0 + pdf.Rect(x, y-20.0, wd+40.0, ht+40.0, "FD") + pdf.SetY(y) + for _, line := range lines { + pdf.CellFormat(190.0, lineHt, string(line), "", 1, "C", false, 0, "") + } + pdf.OutputAndClose(docWriter(pdf, 19)) + // Output: + // Successfully generated pdf/tutorial19.pdf +} -- cgit v1.2.1-24-ge1ad