github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/widget/material/icon.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package material
     4  
     5  import (
     6  	"image"
     7  	"image/color"
     8  	"image/draw"
     9  
    10  	"github.com/gop9/olt/gio/f32"
    11  	"github.com/gop9/olt/gio/layout"
    12  	"github.com/gop9/olt/gio/op/paint"
    13  	"github.com/gop9/olt/gio/unit"
    14  	"golang.org/x/exp/shiny/iconvg"
    15  )
    16  
    17  type Icon struct {
    18  	Color color.RGBA
    19  	src   []byte
    20  	size  unit.Value
    21  	// Cached values.
    22  	op       paint.ImageOp
    23  	imgSize  int
    24  	imgColor color.RGBA
    25  }
    26  
    27  // NewIcon returns a new Icon from IconVG data.
    28  func NewIcon(data []byte) (*Icon, error) {
    29  	_, err := iconvg.DecodeMetadata(data)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	return &Icon{src: data, Color: rgb(0x000000)}, nil
    34  }
    35  
    36  func (ic *Icon) Layout(gtx *layout.Context, sz unit.Value) {
    37  	ico := ic.image(gtx.Px(sz))
    38  	ico.Add(gtx.Ops)
    39  	paint.PaintOp{
    40  		Rect: f32.Rectangle{
    41  			Max: toPointF(ico.Size()),
    42  		},
    43  	}.Add(gtx.Ops)
    44  }
    45  
    46  func (ic *Icon) image(sz int) paint.ImageOp {
    47  	if sz == ic.imgSize && ic.Color == ic.imgColor {
    48  		return ic.op
    49  	}
    50  	m, _ := iconvg.DecodeMetadata(ic.src)
    51  	dx, dy := m.ViewBox.AspectRatio()
    52  	img := image.NewRGBA(image.Rectangle{Max: image.Point{X: sz, Y: int(float32(sz) * dy / dx)}})
    53  	var ico iconvg.Rasterizer
    54  	ico.SetDstImage(img, img.Bounds(), draw.Src)
    55  	m.Palette[0] = ic.Color
    56  	iconvg.Decode(&ico, ic.src, &iconvg.DecodeOptions{
    57  		Palette: &m.Palette,
    58  	})
    59  	ic.op = paint.NewImageOp(img)
    60  	ic.imgSize = sz
    61  	ic.imgColor = ic.Color
    62  	return ic.op
    63  }