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 }