splittext.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package gofpdf
  2. import (
  3. "math"
  4. )
  5. // SplitText splits UTF-8 encoded text into several lines using the current
  6. // font. Each line has its length limited to a maximum width given by w. This
  7. // function can be used to determine the total height of wrapped text for
  8. // vertical placement purposes.
  9. func (f *Fpdf) SplitText(txt string, w float64) (lines []string) {
  10. cw := f.currentFont.Cw // 字符宽度
  11. wmax := int(math.Ceil((w - 2*f.cMargin) * 1000 / f.fontSize)) // 框的宽度
  12. s := []rune(txt) // Return slice of UTF-8 runes
  13. nb := len(s) // 字符长度
  14. // 去掉结尾的换行符
  15. for nb > 0 && s[nb-1] == '\n' {
  16. nb--
  17. }
  18. s = s[0:nb] //去掉结尾的换行符
  19. //sep := -1
  20. i := 0 // 遍历时的下标
  21. j := 0 // 换行时保留的上一行结束的位置
  22. l := 0 // 现在的长度
  23. // 遍历字符串(去掉换行符之后的)
  24. for i < nb {
  25. // 这里是为了防止内存溢出,曾出现过前面是汉字后面是非汉字,lines为["汉字汉字汉字","","","".....]无限个""导致内存溢出
  26. if len(lines) > len(s) {
  27. break
  28. }
  29. c := s[i] // 当前字符
  30. l += cw[c] // 当前需要的长度
  31. //if unicode.IsSpace(c) || isChinese(c) { // 判断是不是空格类字符和中文
  32. // sep = i
  33. //}
  34. // 如果换行或者超长了
  35. if c == '\n' || l > wmax {
  36. ///////////////
  37. // 如果第一个字就超宽了,别循环了,会死循环
  38. if i == 0 {
  39. break
  40. }
  41. //if sep == -1 {
  42. // if i == j {
  43. // i++
  44. // }
  45. // sep = i
  46. //} else {
  47. // ///////////////
  48. // //i = sep + 1
  49. // //////////////
  50. // i = sep
  51. //}
  52. i++
  53. lines = append(lines, string(s[j:i]))
  54. //sep = -1
  55. j = i
  56. l = 0
  57. } else {
  58. i++
  59. }
  60. }
  61. // 把最后一行补上
  62. if i != j {
  63. lines = append(lines, string(s[j:i]))
  64. }
  65. return lines
  66. }