~eliasnaur/gio-patches

gio: Fix widget.Image Scaling v1 PROPOSED

~whereswaldon
As folks brought up in slack, the widget.Image's Scale field is
currently broken:
https://gophers.slack.com/archives/CM87SNCGM/p1614264964041100

I
believe this is the correct fix.

I also implemented tests to attempt
to catch scaling errors moving forward, though they only check the
dimensions rather than the contents of the image.

I also moved the
default scaling ratio into a package unexported constant so that I could
reference it from the tests.

As always, feedback welcome!

Cheers,
Chris

Chris Waldon (1):
  widget: fix image scaling

 widget/image.go      |  7 ++++-
 widget/image_test.go | 66 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 widget/image_test.go

-- 
2.30.1
#443021 apple.yml success
#443022 freebsd.yml success
#443023 linux.yml success
#443024 openbsd.yml success
builds.sr.ht
gio/patches: SUCCESS in 21m16s

[Fix widget.Image Scaling][0] from [~whereswaldon][1]

[0]: https://lists.sr.ht/~eliasnaur/gio-patches/patches/20672
[1]: mailto:christopher.waldon.dev@gmail.com

✓ #443023 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/443023
✓ #443024 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/443024
✓ #443022 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/443022
✓ #443021 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/443021
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/20672/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH gio 1/1] widget: fix image scaling Export this patch

~whereswaldon
From: Chris Waldon <christopher.waldon.dev@gmail.com>

Commit 94d242d broke the widget.Image's Scale field so
that it no longer had any effect on the actual size of
the displayed image. This commit fixes that, as well as
adding tests to confirm that the widget.Image type
scales appropriately with DPI changes and its own Scale
field.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
---
 widget/image.go      |  7 ++++-
 widget/image_test.go | 66 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 widget/image_test.go

diff --git a/widget/image.go b/widget/image.go
index 7706265..54ab62f 100644
--- a/widget/image.go
+++ b/widget/image.go
@@ -5,6 +5,7 @@ package widget
import (
	"image"

	"gioui.org/f32"
	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/op/clip"
@@ -22,10 +23,12 @@ type Image struct {
	Scale float32
}

const defaultScale = float32(160.0 / 72.0)

func (im Image) Layout(gtx layout.Context) layout.Dimensions {
	scale := im.Scale
	if scale == 0 {
		scale = 160.0 / 72.0
		scale = defaultScale
	}
	size := im.Src.Size()
	wf, hf := float32(size.X), float32(size.Y)
@@ -33,6 +36,8 @@ func (im Image) Layout(gtx layout.Context) layout.Dimensions {
	cs := gtx.Constraints
	d := cs.Constrain(image.Pt(w, h))
	stack := op.Save(gtx.Ops)
	pixelScale := scale * gtx.Metric.PxPerDp
	op.Affine(f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(pixelScale, pixelScale))).Add(gtx.Ops)
	clip.Rect(image.Rectangle{Max: d}).Add(gtx.Ops)
	im.Src.Add(gtx.Ops)
	paint.PaintOp{}.Add(gtx.Ops)
diff --git a/widget/image_test.go b/widget/image_test.go
new file mode 100644
index 0000000..edc183c
--- /dev/null
+++ b/widget/image_test.go
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: Unlicense OR MIT

package widget

import (
	"image"
	"testing"

	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/op/paint"
)

func TestImageScale(t *testing.T) {
	var ops op.Ops
	gtx := layout.Context{
		Ops: &ops,
		Constraints: layout.Constraints{
			Max: image.Pt(50, 50),
		},
	}
	imgSize := image.Pt(10, 10)
	img := image.NewNRGBA(image.Rectangle{Max: imgSize})
	imgOp := paint.NewImageOp(img)

	// Ensure the default scales correctly.
	dims := Image{Src: imgOp}.Layout(gtx)
	expectedSize := imgSize
	expectedSize.X = int(float32(expectedSize.X) * defaultScale)
	expectedSize.Y = int(float32(expectedSize.Y) * defaultScale)
	if dims.Size != expectedSize {
		t.Fatalf("non-scaled image is wrong size, expected %v, got %v", expectedSize, dims.Size)
	}

	// Ensure scaling the image via the Scale field works.
	currentScale := float32(0.5)
	dims = Image{Src: imgOp, Scale: float32(currentScale)}.Layout(gtx)
	expectedSize = imgSize
	expectedSize.X = int(float32(expectedSize.X) * currentScale)
	expectedSize.Y = int(float32(expectedSize.Y) * currentScale)
	if dims.Size != expectedSize {
		t.Fatalf(".5 scale image is wrong size, expected %v, got %v", expectedSize, dims.Size)
	}

	// Ensure the image responds to changes in DPI.
	currentScale = float32(1)
	gtx.Metric.PxPerDp = 2
	dims = Image{Src: imgOp, Scale: float32(currentScale)}.Layout(gtx)
	expectedSize = imgSize
	expectedSize.X = int(float32(expectedSize.X) * currentScale * gtx.Metric.PxPerDp)
	expectedSize.Y = int(float32(expectedSize.Y) * currentScale * gtx.Metric.PxPerDp)
	if dims.Size != expectedSize {
		t.Fatalf("HiDPI non-scaled image is wrong size, expected %v, got %v", expectedSize, dims.Size)
	}

	// Ensure scaling the image responds to changes in DPI.
	currentScale = float32(.5)
	gtx.Metric.PxPerDp = 2
	dims = Image{Src: imgOp, Scale: float32(currentScale)}.Layout(gtx)
	expectedSize = imgSize
	expectedSize.X = int(float32(expectedSize.X) * currentScale * gtx.Metric.PxPerDp)
	expectedSize.Y = int(float32(expectedSize.Y) * currentScale * gtx.Metric.PxPerDp)
	if dims.Size != expectedSize {
		t.Fatalf("HiDPI .5 scale image is wrong size, expected %v, got %v", expectedSize, dims.Size)
	}
}
-- 
2.30.1
builds.sr.ht
gio/patches: SUCCESS in 21m16s

[Fix widget.Image Scaling][0] from [~whereswaldon][1]

[0]: https://lists.sr.ht/~eliasnaur/gio-patches/patches/20672
[1]: mailto:christopher.waldon.dev@gmail.com

✓ #443023 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/443023
✓ #443024 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/443024
✓ #443022 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/443022
✓ #443021 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/443021