From 8f080922446313698730071fd92ca15900e6a941 Mon Sep 17 00:00:00 2001 From: Kurt Date: Fri, 10 May 2019 17:47:17 -0400 Subject: Add SplitText() method for splitting utf-8 strings constrained by rendered width --- fpdf.go | 3 +++ splittext.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 splittext.go diff --git a/fpdf.go b/fpdf.go index 7bee6e5..d3366ce 100644 --- a/fpdf.go +++ b/fpdf.go @@ -2407,6 +2407,9 @@ func (f *Fpdf) Cellf(w, h float64, fmtStr string, args ...interface{}) { // used to determine the total height of wrapped text for vertical placement // purposes. // +// This method is useful for codepage-based fonts only. For UTF-8 encoded text, +// use SplitText(). +// // You can use MultiCell if you want to print a text on several lines in a // simple way. func (f *Fpdf) SplitLines(txt []byte, w float64) [][]byte { diff --git a/splittext.go b/splittext.go new file mode 100644 index 0000000..3902199 --- /dev/null +++ b/splittext.go @@ -0,0 +1,54 @@ +package gofpdf + +import ( + "math" + // "strings" + "unicode" +) + +// SplitText splits UTF-8 encoded 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. +func (f *Fpdf) SplitText(txt string, w float64) (lines []string) { + cw := f.currentFont.Cw + wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize)) + s := []rune(txt) // Return slice of UTF-8 runes + nb := len(s) + for nb > 0 && s[nb-1] == '\n' { + nb-- + } + s = s[0:nb] + sep := -1 + i := 0 + j := 0 + l := 0 + for i < nb { + c := s[i] + l += cw[c] + if unicode.IsSpace(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, string(s[j:sep])) + sep = -1 + j = i + l = 0 + } else { + i++ + } + } + if i != j { + lines = append(lines, string(s[j:i])) + } + return lines +} -- cgit v1.2.1-24-ge1ad