From 1b3894b02865976c26441d149c1b8e8f17358b54 Mon Sep 17 00:00:00 2001 From: Michael Fogleman Date: Sun, 11 Feb 2018 23:15:32 -0500 Subject: [PATCH] Add SetMask and AsMask and an example using them --- context.go | 21 ++++++++++++++++++++ examples/gradient-text.go | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 examples/gradient-text.go diff --git a/context.go b/context.go index edcf63e..0ac2c4f 100644 --- a/context.go +++ b/context.go @@ -2,6 +2,7 @@ package gg import ( + "errors" "image" "image/color" "image/png" @@ -445,6 +446,26 @@ func (dc *Context) ClipPreserve() { } } +// SetMask allows you to directly set the *image.Alpha to be used as a clipping +// mask. It must be the same size as the context, else an error is returned +// and the mask is unchanged. +func (dc *Context) SetMask(mask *image.Alpha) error { + if mask.Bounds().Size() != dc.im.Bounds().Size() { + return errors.New("mask size must match context size") + } + dc.mask = mask + return nil +} + +// AsMask returns an *image.Alpha representing the alpha channel of this +// context. This can be useful for advanced clipping operations where you first +// render the mask geometry and then use it as a mask. +func (dc *Context) AsMask() *image.Alpha { + mask := image.NewAlpha(dc.im.Bounds()) + draw.Draw(mask, dc.im.Bounds(), dc.im, image.ZP, draw.Src) + return mask +} + // Clip updates the clipping region by intersecting the current // clipping region with the current path as it would be filled by dc.Fill(). // The path is cleared after this operation. diff --git a/examples/gradient-text.go b/examples/gradient-text.go new file mode 100644 index 0000000..5a3b983 --- /dev/null +++ b/examples/gradient-text.go @@ -0,0 +1,41 @@ +package main + +import ( + "image/color" + + "github.com/fogleman/gg" +) + +const ( + W = 1024 + H = 512 +) + +func main() { + dc := gg.NewContext(W, H) + + // draw text + dc.SetRGB(0, 0, 0) + dc.LoadFontFace("/Library/Fonts/Impact.ttf", 128) + dc.DrawStringAnchored("Gradient Text", W/2, H/2, 0.5, 0.5) + + // get the context as an alpha mask + mask := dc.AsMask() + + // clear the context + dc.SetRGB(1, 1, 1) + dc.Clear() + + // set a gradient + g := gg.NewLinearGradient(0, 0, W, H) + g.AddColorStop(0, color.RGBA{255, 0, 0, 255}) + g.AddColorStop(1, color.RGBA{0, 0, 255, 255}) + dc.SetFillStyle(g) + + // using the mask, fill the context with the gradient + dc.SetMask(mask) + dc.DrawRectangle(0, 0, W, H) + dc.Fill() + + dc.SavePNG("out.png") +}