summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt <kurt.w.jung@gmail.com>2019-05-10 17:47:17 -0400
committerKurt <kurt.w.jung@gmail.com>2019-05-10 17:47:17 -0400
commit8f080922446313698730071fd92ca15900e6a941 (patch)
tree32bc0736b68091bc1bbc2833a838057e6658ab60
parent65c03ae855f64ff46c37f9d58ed572a302bd355d (diff)
Add SplitText() method for splitting utf-8 strings constrained by rendered width
-rw-r--r--fpdf.go3
-rw-r--r--splittext.go54
2 files changed, 57 insertions, 0 deletions
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
+}