summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Jung <kurt.w.jung@code.google.com>2013-12-06 11:43:41 -0500
committerKurt Jung <kurt.w.jung@code.google.com>2013-12-06 11:43:41 -0500
commite982ad5dfea40ff2cfd5d93deb99c82678b8f43e (patch)
tree37b7c5fe6d875734e0fee70596faff814535a04a
parent41616d85f464af97732fb32ba891847003c8c082 (diff)
Added SplitLines function by Bruno Michel and demonstration of its use.
-rw-r--r--fpdf.go53
-rw-r--r--fpdf_test.go27
2 files changed, 80 insertions, 0 deletions
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
+}