added function to create an image pattern
This commit is contained in:
parent
5acbe5452b
commit
0e16a8261b
7 changed files with 91 additions and 13 deletions
|
@ -13,6 +13,7 @@ type Backend interface {
|
||||||
Size() (int, int)
|
Size() (int, int)
|
||||||
|
|
||||||
LoadImage(img image.Image) (Image, error)
|
LoadImage(img image.Image) (Image, error)
|
||||||
|
LoadImagePattern(data ImagePatternData) ImagePattern
|
||||||
LoadLinearGradient(data Gradient) LinearGradient
|
LoadLinearGradient(data Gradient) LinearGradient
|
||||||
LoadRadialGradient(data Gradient) RadialGradient
|
LoadRadialGradient(data Gradient) RadialGradient
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ type FillStyle struct {
|
||||||
RadFrom float64
|
RadFrom float64
|
||||||
RadTo float64
|
RadTo float64
|
||||||
}
|
}
|
||||||
Image Image
|
ImagePattern ImagePattern
|
||||||
}
|
}
|
||||||
|
|
||||||
type Gradient []GradientStop
|
type Gradient []GradientStop
|
||||||
|
@ -104,3 +105,12 @@ type Image interface {
|
||||||
Delete()
|
Delete()
|
||||||
Replace(src image.Image) error
|
Replace(src image.Image) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImagePatternData struct {
|
||||||
|
Image Image
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagePattern interface {
|
||||||
|
Delete()
|
||||||
|
Replace(data ImagePatternData)
|
||||||
|
}
|
||||||
|
|
|
@ -441,8 +441,8 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
|
||||||
gl.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
|
gl.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
|
||||||
return b.rgr.Vertex
|
return b.rgr.Vertex
|
||||||
}
|
}
|
||||||
if img := style.Image; img != nil {
|
if ip := style.ImagePattern; ip != nil {
|
||||||
img := img.(*Image)
|
img := ip.(*ImagePattern).data.Image.(*Image)
|
||||||
gl.UseProgram(b.ipr.ID)
|
gl.UseProgram(b.ipr.ID)
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||||
|
@ -498,8 +498,8 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
|
||||||
gl.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
|
gl.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
|
||||||
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
||||||
}
|
}
|
||||||
if img := style.Image; img != nil {
|
if ip := style.ImagePattern; ip != nil {
|
||||||
img := img.(*Image)
|
img := ip.(*ImagePattern).data.Image.(*Image)
|
||||||
gl.UseProgram(b.ipar.ID)
|
gl.UseProgram(b.ipar.ID)
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
gl.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||||
|
|
|
@ -239,3 +239,18 @@ func (b *GoGLBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64,
|
||||||
|
|
||||||
gl.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
gl.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImagePattern struct {
|
||||||
|
b *GoGLBackend
|
||||||
|
data backendbase.ImagePatternData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *GoGLBackend) LoadImagePattern(data backendbase.ImagePatternData) backendbase.ImagePattern {
|
||||||
|
return &ImagePattern{
|
||||||
|
b: b,
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *ImagePattern) Delete() {}
|
||||||
|
func (ip *ImagePattern) Replace(data backendbase.ImagePatternData) { ip.data = data }
|
||||||
|
|
|
@ -241,3 +241,18 @@ func (b *XMobileBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float6
|
||||||
|
|
||||||
b.glctx.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
b.glctx.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImagePattern struct {
|
||||||
|
b *XMobileBackend
|
||||||
|
data backendbase.ImagePatternData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *XMobileBackend) LoadImagePattern(data backendbase.ImagePatternData) backendbase.ImagePattern {
|
||||||
|
return &ImagePattern{
|
||||||
|
b: b,
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *ImagePattern) Delete() {}
|
||||||
|
func (ip *ImagePattern) Replace(data backendbase.ImagePatternData) { ip.data = data }
|
||||||
|
|
|
@ -434,8 +434,8 @@ func (b *XMobileBackend) useShader(style *backendbase.FillStyle) (vertexLoc gl.A
|
||||||
b.glctx.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
|
b.glctx.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
|
||||||
return b.rgr.Vertex
|
return b.rgr.Vertex
|
||||||
}
|
}
|
||||||
if img := style.Image; img != nil {
|
if ip := style.ImagePattern; ip != nil {
|
||||||
img := img.(*Image)
|
img := ip.(*ImagePattern).data.Image.(*Image)
|
||||||
b.glctx.UseProgram(b.ipr.ID)
|
b.glctx.UseProgram(b.ipr.ID)
|
||||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||||
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||||
|
@ -491,8 +491,8 @@ func (b *XMobileBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSl
|
||||||
b.glctx.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
|
b.glctx.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
|
||||||
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
||||||
}
|
}
|
||||||
if img := style.Image; img != nil {
|
if ip := style.ImagePattern; ip != nil {
|
||||||
img := img.(*Image)
|
img := ip.(*ImagePattern).data.Image.(*Image)
|
||||||
b.glctx.UseProgram(b.ipar.ID)
|
b.glctx.UseProgram(b.ipar.ID)
|
||||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||||
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||||
|
|
19
canvas.go
19
canvas.go
|
@ -74,7 +74,7 @@ type drawStyle struct {
|
||||||
color color.RGBA
|
color color.RGBA
|
||||||
radialGradient *RadialGradient
|
radialGradient *RadialGradient
|
||||||
linearGradient *LinearGradient
|
linearGradient *LinearGradient
|
||||||
image *Image
|
imagePattern *ImagePattern
|
||||||
}
|
}
|
||||||
|
|
||||||
type lineJoin uint8
|
type lineJoin uint8
|
||||||
|
@ -202,6 +202,8 @@ func (cv *Canvas) SetStrokeStyle(value ...interface{}) {
|
||||||
cv.state.stroke = cv.parseStyle(value...)
|
cv.state.stroke = cv.parseStyle(value...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var imagePatterns = make(map[interface{}]*ImagePattern)
|
||||||
|
|
||||||
func (cv *Canvas) parseStyle(value ...interface{}) drawStyle {
|
func (cv *Canvas) parseStyle(value ...interface{}) drawStyle {
|
||||||
var style drawStyle
|
var style drawStyle
|
||||||
if len(value) == 1 {
|
if len(value) == 1 {
|
||||||
|
@ -220,7 +222,12 @@ func (cv *Canvas) parseStyle(value ...interface{}) drawStyle {
|
||||||
} else if len(value) == 1 {
|
} else if len(value) == 1 {
|
||||||
switch v := value[0].(type) {
|
switch v := value[0].(type) {
|
||||||
case *Image, string:
|
case *Image, string:
|
||||||
style.image = cv.getImage(v)
|
if _, ok := imagePatterns[v]; !ok {
|
||||||
|
imagePatterns[v] = cv.CreatePattern(v, "")
|
||||||
|
}
|
||||||
|
style.imagePattern = imagePatterns[v]
|
||||||
|
case *ImagePattern:
|
||||||
|
style.imagePattern = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return style
|
return style
|
||||||
|
@ -249,8 +256,12 @@ func (cv *Canvas) backendFillStyle(s *drawStyle, alpha float64) backendbase.Fill
|
||||||
stl.Gradient.RadFrom = rg.radFrom
|
stl.Gradient.RadFrom = rg.radFrom
|
||||||
stl.Gradient.RadTo = rg.radTo
|
stl.Gradient.RadTo = rg.radTo
|
||||||
stl.RadialGradient = rg.grad
|
stl.RadialGradient = rg.grad
|
||||||
} else if img := s.image; img != nil {
|
} else if ip := s.imagePattern; ip != nil {
|
||||||
stl.Image = img.img
|
if ip.ip == nil {
|
||||||
|
stl.Color = color.RGBA{}
|
||||||
|
} else {
|
||||||
|
stl.ImagePattern = ip.ip
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
alpha *= float64(s.color.A) / 255
|
alpha *= float64(s.color.A) / 255
|
||||||
}
|
}
|
||||||
|
|
27
images.go
27
images.go
|
@ -183,3 +183,30 @@ func (cv *Canvas) GetImageData(x, y, w, h int) *image.RGBA {
|
||||||
func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
func (cv *Canvas) PutImageData(img *image.RGBA, x, y int) {
|
||||||
cv.b.PutImageData(img, x, y)
|
cv.b.PutImageData(img, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImagePattern is an image pattern that can be used for any
|
||||||
|
// fill call
|
||||||
|
type ImagePattern struct {
|
||||||
|
cv *Canvas
|
||||||
|
img *Image
|
||||||
|
ip backendbase.ImagePattern
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *ImagePattern) data() backendbase.ImagePatternData {
|
||||||
|
return backendbase.ImagePatternData{
|
||||||
|
Image: ip.img.img,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePattern creates a new image pattern with the specified
|
||||||
|
// image and repetition
|
||||||
|
func (cv *Canvas) CreatePattern(src interface{}, repetition string) *ImagePattern {
|
||||||
|
ip := &ImagePattern{
|
||||||
|
cv: cv,
|
||||||
|
img: cv.getImage(src),
|
||||||
|
}
|
||||||
|
if ip.img != nil {
|
||||||
|
ip.ip = cv.b.LoadImagePattern(ip.data())
|
||||||
|
}
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue