initial commit
This commit is contained in:
commit
5af2d1264c
157
context.go
Normal file
157
context.go
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
package dd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
|
||||||
|
"github.com/golang/freetype/raster"
|
||||||
|
"golang.org/x/image/math/fixed"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LineCap int
|
||||||
|
|
||||||
|
const (
|
||||||
|
LineCapRound LineCap = iota
|
||||||
|
LineCapButt
|
||||||
|
LineCapSquare
|
||||||
|
)
|
||||||
|
|
||||||
|
type LineJoin int
|
||||||
|
|
||||||
|
const (
|
||||||
|
LineJoinRound LineJoin = iota
|
||||||
|
LineJoinBevel
|
||||||
|
)
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
im *image.RGBA
|
||||||
|
color color.Color
|
||||||
|
path raster.Path
|
||||||
|
start fixed.Point26_6
|
||||||
|
lineWidth float64
|
||||||
|
capper raster.Capper
|
||||||
|
joiner raster.Joiner
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContext(width, height int) *Context {
|
||||||
|
im := image.NewRGBA(image.Rect(0, 0, width, height))
|
||||||
|
return &Context{
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
im: im,
|
||||||
|
color: color.Transparent,
|
||||||
|
lineWidth: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Image() image.Image {
|
||||||
|
return c.im
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Width() int {
|
||||||
|
return c.width
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Height() int {
|
||||||
|
return c.height
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) WriteToPNG(path string) error {
|
||||||
|
return writeToPNG(path, c.im)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Paint() {
|
||||||
|
draw.Draw(c.im, c.im.Bounds(), image.NewUniform(c.color), image.ZP, draw.Src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetSourceRGBA(r, g, b, a float64) {
|
||||||
|
c.color = color.RGBA{
|
||||||
|
uint8(r * 255),
|
||||||
|
uint8(g * 255),
|
||||||
|
uint8(b * 255),
|
||||||
|
uint8(a * 255),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetSourceRGB(r, g, b float64) {
|
||||||
|
c.SetSourceRGBA(r, g, b, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetLineWidth(lineWidth float64) {
|
||||||
|
c.lineWidth = lineWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetLineCap(lineCap LineCap) {
|
||||||
|
switch lineCap {
|
||||||
|
case LineCapButt:
|
||||||
|
c.capper = raster.ButtCapper
|
||||||
|
case LineCapRound:
|
||||||
|
c.capper = raster.RoundCapper
|
||||||
|
case LineCapSquare:
|
||||||
|
c.capper = raster.SquareCapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetLineJoin(lineJoin LineJoin) {
|
||||||
|
switch lineJoin {
|
||||||
|
case LineJoinBevel:
|
||||||
|
c.joiner = raster.BevelJoiner
|
||||||
|
case LineJoinRound:
|
||||||
|
c.joiner = raster.RoundJoiner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) MoveTo(x, y float64) {
|
||||||
|
c.start = fp(x, y)
|
||||||
|
c.path.Start(c.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) LineTo(x, y float64) {
|
||||||
|
c.path.Add1(fp(x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) QuadraticTo(x1, y1, x2, y2 float64) {
|
||||||
|
c.path.Add2(fp(x1, y1), fp(x2, y2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) ClosePath() {
|
||||||
|
c.path.Add1(c.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) NewPath() {
|
||||||
|
c.path.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) StrokePreserve() {
|
||||||
|
painter := raster.NewRGBAPainter(c.im)
|
||||||
|
painter.SetColor(c.color)
|
||||||
|
r := raster.NewRasterizer(c.width, c.height)
|
||||||
|
r.UseNonZeroWinding = true
|
||||||
|
r.AddStroke(c.path, fi(c.lineWidth), c.capper, c.joiner)
|
||||||
|
r.Rasterize(painter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Stroke() {
|
||||||
|
c.StrokePreserve()
|
||||||
|
c.NewPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) FillPreserve() {
|
||||||
|
// make sure the path is closed
|
||||||
|
path := make(raster.Path, len(c.path))
|
||||||
|
copy(path, c.path)
|
||||||
|
path.Add1(c.start)
|
||||||
|
painter := raster.NewRGBAPainter(c.im)
|
||||||
|
painter.SetColor(c.color)
|
||||||
|
r := raster.NewRasterizer(c.width, c.height)
|
||||||
|
r.AddPath(path)
|
||||||
|
r.Rasterize(painter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Fill() {
|
||||||
|
c.FillPreserve()
|
||||||
|
c.NewPath()
|
||||||
|
}
|
22
examples/example0.go
Normal file
22
examples/example0.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/fogleman/dd"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
dc := dd.NewContext(256, 256)
|
||||||
|
dc.SetSourceRGBA(1, 0, 0, 0.3)
|
||||||
|
dc.Paint()
|
||||||
|
dc.MoveTo(20, 20)
|
||||||
|
dc.LineTo(236, 236)
|
||||||
|
dc.LineTo(236, 128)
|
||||||
|
dc.LineTo(20, 128)
|
||||||
|
dc.QuadraticTo(0, 64, 120, 20)
|
||||||
|
dc.SetSourceRGBA(1, 0, 0, 0.8)
|
||||||
|
dc.FillPreserve()
|
||||||
|
dc.SetSourceRGB(0, 0, 0)
|
||||||
|
dc.SetLineWidth(8)
|
||||||
|
// dc.SetLineCap(dd.LineCapButt)
|
||||||
|
// dc.SetLineJoin(dd.LineJoinBevel)
|
||||||
|
dc.Stroke()
|
||||||
|
dc.WriteToPNG("out.png")
|
||||||
|
}
|
26
util.go
Normal file
26
util.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package dd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/image/math/fixed"
|
||||||
|
)
|
||||||
|
|
||||||
|
func writeToPNG(path string, im image.Image) error {
|
||||||
|
file, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
return png.Encode(file, im)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fp(x, y float64) fixed.Point26_6 {
|
||||||
|
return fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fi(x float64) fixed.Int26_6 {
|
||||||
|
return fixed.Int26_6(x * 64)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user