gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/widget/image.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package widget
     4  
     5  import (
     6  	"image"
     7  
     8  	"gioui.org/f32"
     9  	"gioui.org/layout"
    10  	"gioui.org/op"
    11  	"gioui.org/op/clip"
    12  	"gioui.org/op/paint"
    13  	"gioui.org/unit"
    14  )
    15  
    16  // Image is a widget that displays an image.
    17  type Image struct {
    18  	// Src is the image to display.
    19  	Src paint.ImageOp
    20  	// Fit specifies how to scale the image to the constraints.
    21  	// By default it does not do any scaling.
    22  	Fit Fit
    23  	// Position specifies where to position the image within
    24  	// the constraints.
    25  	Position layout.Direction
    26  	// Scale is the factor used for converting image pixels to dp.
    27  	// If Scale is zero it defaults to 1.
    28  	//
    29  	// To map one image pixel to one output pixel, set Scale to 1.0 / gtx.Metric.PxPerDp.
    30  	Scale float32
    31  }
    32  
    33  func (im Image) Layout(gtx layout.Context) layout.Dimensions {
    34  	scale := im.Scale
    35  	if scale == 0 {
    36  		scale = 1
    37  	}
    38  
    39  	size := im.Src.Size()
    40  	wf, hf := float32(size.X), float32(size.Y)
    41  	w, h := gtx.Dp(unit.Dp(wf*scale)), gtx.Dp(unit.Dp(hf*scale))
    42  
    43  	dims, trans := im.Fit.scale(gtx.Constraints, im.Position, layout.Dimensions{Size: image.Pt(w, h)})
    44  	defer clip.Rect{Max: dims.Size}.Push(gtx.Ops).Pop()
    45  
    46  	pixelScale := scale * gtx.Metric.PxPerDp
    47  	trans = trans.Mul(f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(pixelScale, pixelScale)))
    48  	defer op.Affine(trans).Push(gtx.Ops).Pop()
    49  
    50  	im.Src.Add(gtx.Ops)
    51  	paint.PaintOp{}.Add(gtx.Ops)
    52  
    53  	return dims
    54  }