gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/widget/image.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  // Package widget implements common widgets.
     4  package widget
     5  
     6  import (
     7  	"image"
     8  
     9  	"gioui.org/ui"
    10  	"gioui.org/ui/f32"
    11  	"gioui.org/ui/layout"
    12  	"gioui.org/ui/paint"
    13  )
    14  
    15  // Image is a widget that displays an image.
    16  type Image struct {
    17  	// Src is the image to display.
    18  	Src image.Image
    19  	// Rect is the source rectangle.
    20  	Rect image.Rectangle
    21  	// Scale is the ratio of image pixels to
    22  	// device pixels. If zero, a scale that
    23  	// makes the image appear at approximately
    24  	// 72 DPI is used.
    25  	Scale float32
    26  }
    27  
    28  func (im Image) Layout(gtx *layout.Context) {
    29  	size := im.Src.Bounds()
    30  	wf, hf := float32(size.Dx()), float32(size.Dy())
    31  	var w, h int
    32  	if im.Scale == 0 {
    33  		const dpPrPx = 160 / 72
    34  		w, h = gtx.Px(ui.Dp(wf*dpPrPx)), gtx.Px(ui.Dp(hf*dpPrPx))
    35  	} else {
    36  		w, h = int(wf*im.Scale+.5), int(hf*im.Scale+.5)
    37  	}
    38  	cs := gtx.Constraints
    39  	d := image.Point{X: cs.Width.Constrain(w), Y: cs.Height.Constrain(h)}
    40  	aspect := float32(w) / float32(h)
    41  	dw, dh := float32(d.X), float32(d.Y)
    42  	dAspect := dw / dh
    43  	if aspect < dAspect {
    44  		d.X = int(dh*aspect + 0.5)
    45  	} else {
    46  		d.Y = int(dw/aspect + 0.5)
    47  	}
    48  	dr := f32.Rectangle{
    49  		Max: f32.Point{X: float32(d.X), Y: float32(d.Y)},
    50  	}
    51  	paint.ImageOp{Src: im.Src, Rect: im.Rect}.Add(gtx.Ops)
    52  	paint.PaintOp{Rect: dr}.Add(gtx.Ops)
    53  	gtx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y}
    54  }