Add SetDashOffset. Close #64.

This commit is contained in:
Michael Fogleman 2019-02-20 16:47:39 -05:00
parent fa28a6e1e3
commit 3bcf9e0320
3 changed files with 35 additions and 4 deletions

View File

@ -121,6 +121,7 @@ SetLineWidth(lineWidth float64)
SetLineCap(lineCap LineCap) SetLineCap(lineCap LineCap)
SetLineJoin(lineJoin LineJoin) SetLineJoin(lineJoin LineJoin)
SetDash(dashes ...float64) SetDash(dashes ...float64)
SetDashOffset(offset float64)
SetFillRule(fillRule FillRule) SetFillRule(fillRule FillRule)
``` ```

View File

@ -67,6 +67,7 @@ type Context struct {
current Point current Point
hasCurrent bool hasCurrent bool
dashes []float64 dashes []float64
dashOffset float64
lineWidth float64 lineWidth float64
lineCap LineCap lineCap LineCap
lineJoin LineJoin lineJoin LineJoin
@ -151,6 +152,12 @@ func (dc *Context) SetDash(dashes ...float64) {
dc.dashes = dashes dc.dashes = dashes
} }
// SetDashOffset sets the initial offset into the dash pattern to use when
// stroking dashed paths.
func (dc *Context) SetDashOffset(offset float64) {
dc.dashOffset = offset
}
func (dc *Context) SetLineWidth(lineWidth float64) { func (dc *Context) SetLineWidth(lineWidth float64) {
dc.lineWidth = lineWidth dc.lineWidth = lineWidth
} }
@ -389,7 +396,7 @@ func (dc *Context) joiner() raster.Joiner {
func (dc *Context) stroke(painter raster.Painter) { func (dc *Context) stroke(painter raster.Painter) {
path := dc.strokePath path := dc.strokePath
if len(dc.dashes) > 0 { if len(dc.dashes) > 0 {
path = dashed(path, dc.dashes) path = dashed(path, dc.dashes, dc.dashOffset)
} else { } else {
// TODO: this is a temporary workaround to remove tiny segments // TODO: this is a temporary workaround to remove tiny segments
// that result in rendering issues // that result in rendering issues

29
path.go
View File

@ -1,6 +1,8 @@
package gg package gg
import ( import (
"math"
"github.com/golang/freetype/raster" "github.com/golang/freetype/raster"
"golang.org/x/image/math/fixed" "golang.org/x/image/math/fixed"
) )
@ -57,7 +59,7 @@ func flattenPath(p raster.Path) [][]Point {
return result return result
} }
func dashPath(paths [][]Point, dashes []float64) [][]Point { func dashPath(paths [][]Point, dashes []float64, offset float64) [][]Point {
var result [][]Point var result [][]Point
if len(dashes) == 0 { if len(dashes) == 0 {
return paths return paths
@ -73,6 +75,27 @@ func dashPath(paths [][]Point, dashes []float64) [][]Point {
pathIndex := 1 pathIndex := 1
dashIndex := 0 dashIndex := 0
segmentLength := 0.0 segmentLength := 0.0
// offset
if offset != 0 {
var totalLength float64
for _, dashLength := range dashes {
totalLength += dashLength
}
offset = math.Mod(offset, totalLength)
if offset < 0 {
offset += totalLength
}
for i, dashLength := range dashes {
offset -= dashLength
if offset < 0 {
dashIndex = i
segmentLength = dashLength + offset
break
}
}
}
var segment []Point var segment []Point
segment = append(segment, previous) segment = append(segment, previous)
for pathIndex < len(path) { for pathIndex < len(path) {
@ -135,6 +158,6 @@ func rasterPath(paths [][]Point) raster.Path {
return result return result
} }
func dashed(path raster.Path, dashes []float64) raster.Path { func dashed(path raster.Path, dashes []float64, offset float64) raster.Path {
return rasterPath(dashPath(flattenPath(path), dashes)) return rasterPath(dashPath(flattenPath(path), dashes, offset))
} }