Skip to content

Commit

Permalink
Don't second guess the visible portion of a FillOriginal
Browse files Browse the repository at this point in the history
Just skip frame 1 the flicker goes :)

Fixes fyne-io#1432
  • Loading branch information
andydotxyz committed Oct 22, 2020
1 parent d1b64d2 commit ba120aa
Showing 1 changed file with 17 additions and 35 deletions.
52 changes: 17 additions & 35 deletions internal/painter/image.go
Expand Up @@ -55,26 +55,23 @@ func PaintImage(img *canvas.Image, c fyne.Canvas, width, height int) image.Image
aspect := float32(origW) / float32(origH)
viewAspect := float32(width) / float32(height)

firstPassOriginal := false
texW, texH := width, height
if viewAspect > aspect {
texW = int(float32(height) * aspect)
} else if viewAspect < aspect {
texH = int(float32(width) / aspect)
}

icon.SetTarget(0, 0, float64(texW), float64(texH))
// this is used by our render code, so let's set it to the file aspect
aspects[img.Resource] = aspect
// if the image specifies it should be original size we need at least that many pixels on screen
if img.FillMode == canvas.ImageFillOriginal {
if !checkImageMinSize(img, c, origW, origH) {
firstPassOriginal = true
return nil
}
}

texW, texH := width, height
if firstPassOriginal { // we draw pixel 1:1 so we can subimage it below to fit in the current bounds
texW, texH = origW, origH
} else {
if viewAspect > aspect {
texW = int(float32(height) * aspect)
} else if viewAspect < aspect {
texH = int(float32(width) / aspect)
}
}

icon.SetTarget(0, 0, float64(texW), float64(texH))
tex = image.NewNRGBA(image.Rect(0, 0, texW, texH))
scanner := rasterx.NewScannerGV(origW, origH, tex, tex.Bounds())
raster := rasterx.NewDasher(width, height, scanner)
Expand All @@ -85,12 +82,6 @@ func PaintImage(img *canvas.Image, c fyne.Canvas, width, height int) image.Image
return nil
}

if firstPassOriginal { // crop out the currently visible portion to avoid flicker when it sizes later
return imageSubset(tex, width, height, img.ScaleMode)
}

// this is used by our render code, so let's set it to the file aspect
aspects[img.Resource] = aspect
svgCachePut(img.Resource, tex, width, height)
}

Expand All @@ -105,42 +96,33 @@ func PaintImage(img *canvas.Image, c fyne.Canvas, width, height int) image.Image
return nil
}
origSize := pixels.Bounds().Size()
// this is used by our render code, so let's set it to the file aspect
aspects[img] = float32(origSize.X) / float32(origSize.Y)
// if the image specifies it should be original size we need at least that many pixels on screen
if img.FillMode == canvas.ImageFillOriginal {
if !checkImageMinSize(img, c, origSize.X, origSize.Y) {
return imageSubset(pixels, width, height, img.ScaleMode)
return nil
}
}
// this is used by our render code, so let's set it to the file aspect
aspects[img] = float32(origSize.X) / float32(origSize.Y)

return scaleImage(pixels, width, height, img.ScaleMode)
case img.Image != nil:
origSize := img.Image.Bounds().Size()
// this is used by our render code, so let's set it to the file aspect
aspects[img] = float32(origSize.X) / float32(origSize.Y)
// if the image specifies it should be original size we need at least that many pixels on screen
if img.FillMode == canvas.ImageFillOriginal {
if !checkImageMinSize(img, c, origSize.X, origSize.Y) {
return imageSubset(img.Image, width, height, img.ScaleMode)
return nil
}
}

// this is used by our render code, so let's set it to the file aspect
aspects[img] = float32(origSize.X) / float32(origSize.Y)
return scaleImage(img.Image, width, height, img.ScaleMode)
default:
return image.NewNRGBA(image.Rect(0, 0, 1, 1))
}
}

// imageSubset returns a portion of an image based on pixel dimensions.
// This is needed when we initially display an image with original dimensions that are still being calculated.
func imageSubset(img image.Image, width, height int, scale canvas.ImageScale) image.Image {
sub := img.(interface {
SubImage(r image.Rectangle) image.Image
}).SubImage(image.Rect(0, 0, width, height))
return scaleImage(sub, width, height, scale)
}

func scaleImage(pixels image.Image, scaledW, scaledH int, scale canvas.ImageScale) image.Image {
pixW := fyne.Min(scaledW, pixels.Bounds().Dx()) // don't push more pixels than we have to
pixH := fyne.Min(scaledH, pixels.Bounds().Dy()) // the GL calls will scale this up on GPU.
Expand Down

0 comments on commit ba120aa

Please sign in to comment.