wrap.go 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package gg
  2. import (
  3. "strings"
  4. "unicode"
  5. )
  6. type measureStringer interface {
  7. MeasureString(s string) (w, h float64)
  8. }
  9. func splitOnSpace(x string) []string {
  10. var result []string
  11. pi := 0
  12. ps := false
  13. for i, c := range x {
  14. s := unicode.IsSpace(c)
  15. if s != ps && i > 0 {
  16. result = append(result, x[pi:i])
  17. pi = i
  18. }
  19. ps = s
  20. }
  21. result = append(result, x[pi:])
  22. return result
  23. }
  24. func wordWrap(m measureStringer, s string, width float64) []string {
  25. var result []string
  26. for _, line := range strings.Split(s, "\n") {
  27. fields := splitOnSpace(line)
  28. if len(fields)%2 == 1 {
  29. fields = append(fields, "")
  30. }
  31. x := ""
  32. for i := 0; i < len(fields); i += 2 {
  33. w, _ := m.MeasureString(x + fields[i])
  34. if w > width {
  35. if x == "" {
  36. result = append(result, fields[i])
  37. x = ""
  38. continue
  39. } else {
  40. result = append(result, x)
  41. x = ""
  42. }
  43. }
  44. x += fields[i] + fields[i+1]
  45. }
  46. if x != "" {
  47. result = append(result, x)
  48. }
  49. }
  50. for i, line := range result {
  51. result[i] = strings.TrimSpace(line)
  52. }
  53. return result
  54. }