codeberg.org/go-pdf/fpdf@v0.11.1/splittext.go (about)

     1  // Copyright ©2023 The go-pdf Authors. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fpdf
     6  
     7  import (
     8  	"math"
     9  	"unicode"
    10  )
    11  
    12  // SplitText splits UTF-8 encoded text into several lines using the current
    13  // font. Each line has its length limited to a maximum width given by w. This
    14  // function can be used to determine the total height of wrapped text for
    15  // vertical placement purposes.
    16  func (f *Fpdf) SplitText(txt string, w float64) (lines []string) {
    17  	cw := f.currentFont.Cw
    18  	wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize))
    19  	s := []rune(txt) // Return slice of UTF-8 runes
    20  	nb := len(s)
    21  	for nb > 0 && s[nb-1] == '\n' {
    22  		nb--
    23  	}
    24  	s = s[0:nb]
    25  	sep := -1
    26  	i := 0
    27  	j := 0
    28  	l := 0
    29  
    30  	for i < nb {
    31  		c := s[i]
    32  
    33  		if int(c) >= len(cw) {
    34  			// Decimal representation of c is greater than the font width's array size so it can't be used as index.
    35  			l += cw[f.currentFont.Desc.MissingWidth]
    36  		} else {
    37  			l += cw[c]
    38  		}
    39  
    40  		if unicode.IsSpace(c) || isChinese(c) {
    41  			sep = i
    42  		}
    43  		if c == '\n' || l > wmax {
    44  			if sep == -1 {
    45  				if i == j {
    46  					i++
    47  				}
    48  				sep = i
    49  			} else {
    50  				i = sep + 1
    51  			}
    52  			lines = append(lines, string(s[j:sep]))
    53  			sep = -1
    54  			j = i
    55  			l = 0
    56  		} else {
    57  			i++
    58  		}
    59  	}
    60  	if i != j {
    61  		lines = append(lines, string(s[j:i]))
    62  	}
    63  	return lines
    64  }