word wrap in progress

This commit is contained in:
Michael Fogleman 2016-02-24 17:22:21 -05:00
parent c7b235b146
commit 315dff9066
3 changed files with 77 additions and 14 deletions

View File

@ -504,6 +504,14 @@ func (dc *Context) DrawStringAnchored(s string, x, y, ax, ay float64) {
d.DrawString(s)
}
func (dc *Context) DrawStringWrapped(s string, x, y, w float64) {
lines := wordWrap(dc, s, w)
for _, line := range lines {
dc.DrawStringAnchored(line, x, y, 0, 0)
y += dc.fontHeight * 1.5
}
}
// MeasureString returns the rendered width and height of the specified text
// given the current font face.
func (dc *Context) MeasureString(s string) (w, h float64) {

View File

@ -2,14 +2,12 @@ package main
import "github.com/fogleman/gg"
var lines = []string{
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod",
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,",
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo",
"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse",
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat",
"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
}
var line = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod" +
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam," +
"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo" +
"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse" +
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat" +
"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ")
func main() {
const W = 800
@ -18,11 +16,7 @@ func main() {
dc.SetRGB(1, 1, 1)
dc.Clear()
dc.SetRGB(0, 0, 0)
// dc.LoadFontFace("/Library/Fonts/Arial.ttf", 18)
const h = 24
for i, line := range lines {
y := H/2 - h*len(lines)/2 + i*h
dc.DrawStringAnchored(line, 400, float64(y), 0.5, 0.5)
}
dc.LoadFontFace("/Library/Fonts/Arial.ttf", 18)
dc.DrawStringWrapped(line, 20, 20, W-40)
dc.SavePNG("out.png")
}

61
wrap.go Normal file
View File

@ -0,0 +1,61 @@
package gg
import (
"strings"
"unicode"
)
type measureStringer interface {
MeasureString(s string) (w, h float64)
}
func splitOnSpace(x string) []string {
var result []string
pi := 0
ps := false
for i, c := range x {
s := unicode.IsSpace(c)
if s != ps && i > 0 {
result = append(result, x[pi:i])
pi = i
}
ps = s
}
result = append(result, x[pi:])
return result
}
func wordWrap(m measureStringer, s string, width float64) []string {
var result []string
for _, line := range strings.Split(s, "\n") {
fields := splitOnSpace(line)
widths := make([]float64, len(fields))
for i, field := range fields {
widths[i], _ = m.MeasureString(field)
}
start := 0
total := 0.0
for i := 0; i < len(fields); i += 2 {
if total+widths[i] > width {
if i == start {
end := i + 2
result = append(result, strings.Join(fields[start:end], ""))
start, total = end, 0
continue
} else {
end := i
result = append(result, strings.Join(fields[start:end], ""))
start, total = end, 0
}
}
total += widths[i] + widths[i+1]
}
if start < len(fields) {
result = append(result, strings.Join(fields[start:], ""))
}
}
for i, line := range result {
result[i] = strings.TrimSpace(line)
}
return result
}