diff options
author | Kurt <kurt.w.jung@gmail.com> | 2019-05-10 17:47:17 -0400 |
---|---|---|
committer | Kurt <kurt.w.jung@gmail.com> | 2019-05-10 17:47:17 -0400 |
commit | 8f080922446313698730071fd92ca15900e6a941 (patch) | |
tree | 32bc0736b68091bc1bbc2833a838057e6658ab60 | |
parent | 65c03ae855f64ff46c37f9d58ed572a302bd355d (diff) |
Add SplitText() method for splitting utf-8 strings constrained by rendered width
-rw-r--r-- | fpdf.go | 3 | ||||
-rw-r--r-- | splittext.go | 54 |
2 files changed, 57 insertions, 0 deletions
@@ -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 +} |