Compare commits

..

17 Commits
v1.3.0 ... main

Author SHA1 Message Date
d9a531518d migrated module to git.milar.in 2023-01-22 12:06:29 +01:00
Timon Ringwald
cc30f39e11 fixed drawclipping when drawing text on subimages 2022-04-22 11:57:30 +02:00
Timon Ringwald
69923d9438 fixed draw clipping on subimages 2022-04-22 11:49:17 +02:00
Timon Ringwald
2755d666d6 moduling 2022-04-22 11:48:47 +02:00
Michael Fogleman
8febc0f526 Fix rounding when converting to fixed precision 2021-09-28 10:35:35 -04:00
Michael Fogleman
af4cd58078
Merge pull request #124 from mazznoer/conic-gradient
Add conic gradient
2021-01-31 12:28:31 -05:00
Nor Khasyatillah
c26555283c Add conic gradient 2021-01-29 19:00:22 +07:00
Michael Fogleman
ad4d1eafac
Update README.md 2020-05-14 21:10:29 -04:00
Michael Fogleman
8d127f461d
Merge pull request #100 from ajnirp/patch-1
Update documentation link
2020-05-14 21:09:58 -04:00
Rohan Prinja
b89ba07b94
Update documentation link
When visiting the godoc link, a banner at the top informs me that "pkg.go.dev is a new destination for Go discovery and docs". While it doesn't look like godoc is going away, I figured it would be nice to link to both sites.
2020-05-14 17:15:05 -07:00
Michael Fogleman
4dc34561c6
Merge pull request #83 from Xeoncross/master
Add support for JPEG encoding
2019-08-26 15:13:58 -04:00
xeoncross
068da56c91 Added support for JPEG encoding 2019-08-26 14:04:06 -05:00
Michael Fogleman
f194ddec6f
Merge pull request #77 from leexingliang/master
modify comment
2019-06-12 10:10:55 -04:00
lixingliang
6897f9a1a0 modify comment 2019-06-12 11:43:36 +08:00
Michael Fogleman
72436a171b fix test for 1.12+ 2019-04-16 21:30:52 -04:00
Michael Fogleman
5899172fb0
Merge pull request #70 from bevand10/master
Add SaveJPG method
2019-04-16 21:28:22 -04:00
Dave Bevan
1236b6346f Add SaveJPG method 2019-04-12 18:25:28 +01:00
8 changed files with 125 additions and 7 deletions

View File

@ -14,7 +14,8 @@ Alternatively, you may use gopkg.in to grab a specific major-version:
## Documentation
https://godoc.org/github.com/fogleman/gg
- godoc: https://godoc.org/github.com/fogleman/gg
- pkg.go.dev: https://pkg.go.dev/github.com/fogleman/gg?tab=doc
## Hello, Circle!
@ -127,7 +128,7 @@ SetFillRule(fillRule FillRule)
## Gradients & Patterns
`gg` supports linear and radial gradients and surface patterns. You can also implement your own patterns.
`gg` supports linear, radial and conic gradients and surface patterns. You can also implement your own patterns.
```go
SetFillStyle(pattern Pattern)
@ -135,6 +136,7 @@ SetStrokeStyle(pattern Pattern)
NewSolidPattern(color color.Color)
NewLinearGradient(x0, y0, x1, y1 float64)
NewRadialGradient(x0, y0, r0, x1, y1, r1 float64)
NewConicGradient(cx, cy, deg float64)
NewSurfacePattern(im image.Image, op RepeatOp)
```

View File

@ -5,6 +5,7 @@ import (
"errors"
"image"
"image/color"
"image/jpeg"
"image/png"
"io"
"math"
@ -140,11 +141,23 @@ func (dc *Context) SavePNG(path string) error {
return SavePNG(path, dc.im)
}
// SaveJPG encodes the image as a JPG and writes it to disk.
func (dc *Context) SaveJPG(path string, quality int) error {
return SaveJPG(path, dc.im, quality)
}
// EncodePNG encodes the image as a PNG and writes it to the provided io.Writer.
func (dc *Context) EncodePNG(w io.Writer) error {
return png.Encode(w, dc.im)
}
// EncodeJPG encodes the image as a JPG and writes it to the provided io.Writer
// in JPEG 4:2:0 baseline format with the given options.
// Default parameters are used if a nil *jpeg.Options is passed.
func (dc *Context) EncodeJPG(w io.Writer, o *jpeg.Options) error {
return jpeg.Encode(w, dc.im, o)
}
// SetDash sets the current dash pattern to use. Call with zero arguments to
// disable dashes. The values specify the lengths of each dash, with
// alternating on and off lengths.
@ -405,6 +418,7 @@ func (dc *Context) stroke(painter raster.Painter) {
r := dc.rasterizer
r.UseNonZeroWinding = true
r.Clear()
r.Dx, r.Dy = dc.im.Bounds().Min.X, dc.im.Bounds().Min.Y
r.AddStroke(path, fix(dc.lineWidth), dc.capper(), dc.joiner())
r.Rasterize(painter)
}
@ -419,6 +433,7 @@ func (dc *Context) fill(painter raster.Painter) {
r := dc.rasterizer
r.UseNonZeroWinding = dc.fillRule == FillRuleWinding
r.Clear()
r.Dx, r.Dy = dc.im.Bounds().Min.X, dc.im.Bounds().Min.Y
r.AddPath(path)
r.Rasterize(painter)
}
@ -741,7 +756,7 @@ func (dc *Context) DrawStringAnchored(s string, x, y, ax, ay float64) {
x -= ax * w
y += ay * h
if dc.mask == nil {
dc.drawString(dc.im, s, x, y)
dc.drawString(dc.im, s, x+float64(dc.im.Bounds().Min.X), y+float64(dc.im.Bounds().Min.Y))
} else {
im := image.NewRGBA(image.Rect(0, 0, dc.width, dc.height))
dc.drawString(im, s, x, y)
@ -844,13 +859,13 @@ func (dc *Context) ScaleAbout(sx, sy, x, y float64) {
dc.Translate(-x, -y)
}
// Rotate updates the current matrix with a clockwise rotation.
// Rotate updates the current matrix with a anticlockwise rotation.
// Rotation occurs about the origin. Angle is specified in radians.
func (dc *Context) Rotate(angle float64) {
dc.matrix = dc.matrix.Rotate(angle)
}
// RotateAbout updates the current matrix with a clockwise rotation.
// RotateAbout updates the current matrix with a anticlockwise rotation.
// Rotation occurs about the specified point. Angle is specified in radians.
func (dc *Context) RotateAbout(angle, x, y float64) {
dc.Translate(x, y)

View File

@ -191,7 +191,7 @@ func TestPushPop(t *testing.T) {
dc.Pop()
}
saveImage(dc, "TestPushPop")
checkHash(t, dc, "e0d6724eb72033577811a55f7a642f6a")
checkHash(t, dc, "31e908ee1c2ea180da98fd5681a89d05")
}
func TestDrawStringWrapped(t *testing.T) {

View File

@ -0,0 +1,38 @@
// +build ignore
package main
import (
"image/color"
"github.com/fogleman/gg"
)
func main() {
dc := gg.NewContext(400, 400)
grad1 := gg.NewConicGradient(200, 200, 0)
grad1.AddColorStop(0.0, color.Black)
grad1.AddColorStop(0.5, color.RGBA{255, 215, 0, 255})
grad1.AddColorStop(1.0, color.RGBA{255, 0, 0, 255})
grad2 := gg.NewConicGradient(200, 200, 90)
grad2.AddColorStop(0.00, color.RGBA{255, 0, 0, 255})
grad2.AddColorStop(0.16, color.RGBA{255, 255, 0, 255})
grad2.AddColorStop(0.33, color.RGBA{0, 255, 0, 255})
grad2.AddColorStop(0.50, color.RGBA{0, 255, 255, 255})
grad2.AddColorStop(0.66, color.RGBA{0, 0, 255, 255})
grad2.AddColorStop(0.83, color.RGBA{255, 0, 255, 255})
grad2.AddColorStop(1.00, color.RGBA{255, 0, 0, 255})
dc.SetStrokeStyle(grad1)
dc.SetLineWidth(20)
dc.DrawCircle(200, 200, 180)
dc.Stroke()
dc.SetFillStyle(grad2)
dc.DrawCircle(200, 200, 150)
dc.Fill()
dc.SavePNG("gradient-conic.png")
}

9
go.mod Normal file
View File

@ -0,0 +1,9 @@
module git.milar.in/milarin/gg
go 1.18
require (
github.com/fogleman/gg v1.3.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
)

8
go.sum Normal file
View File

@ -0,0 +1,8 @@
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -164,6 +164,52 @@ func NewRadialGradient(x0, y0, r0, x1, y1, r1 float64) Gradient {
return g
}
// Conic Gradient
type conicGradient struct {
cx, cy float64
rotation float64
stops stops
}
func (g *conicGradient) ColorAt(x, y int) color.Color {
if len(g.stops) == 0 {
return color.Transparent
}
a := math.Atan2(float64(y)-g.cy, float64(x)-g.cx)
t := norm(a, -math.Pi, math.Pi) - g.rotation
if t < 0 {
t += 1
}
return getColor(t, g.stops)
}
func (g *conicGradient) AddColorStop(offset float64, color color.Color) {
g.stops = append(g.stops, stop{pos: offset, color: color})
sort.Sort(g.stops)
}
func NewConicGradient(cx, cy, deg float64) Gradient {
g := &conicGradient{
cx: cx,
cy: cy,
rotation: normalizeAngle(deg) / 360,
}
return g
}
func normalizeAngle(t float64) float64 {
t = math.Mod(t, 360)
if t < 0 {
t += 360
}
return t
}
// Map value which is in range [a..b] to range [0..1]
func norm(value, a, b float64) float64 {
return (value - a) * (1.0 / (b - a))
}
func getColor(pos float64, stops stops) color.Color {
if pos <= 0.0 || len(stops) == 1 {
return stops[0].color

View File

@ -109,7 +109,7 @@ func fixp(x, y float64) fixed.Point26_6 {
}
func fix(x float64) fixed.Int26_6 {
return fixed.Int26_6(x * 64)
return fixed.Int26_6(math.Round(x * 64))
}
func unfix(x fixed.Int26_6) float64 {