Commit f52a1e0a authored by Kris Giesing's avatar Kris Giesing

Associate scale with image more strongly in image resources

parent b81f3f8b
......@@ -668,10 +668,10 @@ class BackgroundImage {
_imageResource.removeListener(_handleImageChanged);
}
void _handleImageChanged(ui.Image resolvedImage) {
void _handleImageChanged(ImageInfo resolvedImage) {
if (resolvedImage == null)
return;
_image = resolvedImage;
_image = resolvedImage.image;
final List<VoidCallback> localListeners =
new List<VoidCallback>.from(_listeners);
for (VoidCallback listener in localListeners)
......
......@@ -22,7 +22,7 @@ class RenderImage extends RenderBox {
ui.Image image,
double width,
double height,
double scale,
double scale: 1.0,
Color color,
ImageFit fit,
FractionalOffset alignment,
......@@ -84,6 +84,7 @@ class RenderImage extends RenderBox {
double get scale => _scale;
double _scale;
void set scale (double value) {
assert(value != null);
if (value == _scale)
return;
_scale = value;
......@@ -175,9 +176,8 @@ class RenderImage extends RenderBox {
if (constraints.isTight || _image == null)
return constraints.smallest;
double scale = _scale ?? 1.0;
double width = _image.width.toDouble() / scale;
double height = _image.height.toDouble() / scale;
double width = _image.width.toDouble() / _scale;
double height = _image.height.toDouble() / _scale;
assert(width > 0.0);
assert(height > 0.0);
double aspectRatio = width / height;
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:ui' as ui;
import 'dart:ui_internals' as internals;
import 'dart:typed_data';
......@@ -48,8 +47,8 @@ abstract class CachingAssetBundle extends AssetBundle {
final Map<String, Future<String>> _stringCache =
new Map<String, Future<String>>();
Future<ui.Image> fetchImage(String key) async {
return await decodeImageFromDataPipe(await load(key));
Future<ImageInfo> fetchImage(String key) async {
return new ImageInfo(image: await decodeImageFromDataPipe(await load(key)));
}
ImageResource loadImage(String key) {
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:ui' as ui;
import 'package:mojo/mojo/url_response.mojom.dart';
import 'package:quiver/collection.dart';
......@@ -15,7 +14,7 @@ import 'image_resource.dart';
/// Implements a way to retrieve an image, for example by fetching it from the network.
/// Also used as a key in the image cache.
abstract class ImageProvider {
Future<ui.Image> loadImage();
Future<ImageInfo> loadImage();
}
class _UrlFetcher implements ImageProvider {
......@@ -23,13 +22,13 @@ class _UrlFetcher implements ImageProvider {
_UrlFetcher(this._url);
Future<ui.Image> loadImage() async {
Future<ImageInfo> loadImage() async {
UrlResponse response = await fetchUrl(_url);
if (response.statusCode >= 400) {
print("Failed (${response.statusCode}) to load image $_url");
return null;
}
return await decodeImageFromDataPipe(response.body);
return new ImageInfo(image: await decodeImageFromDataPipe(response.body));
}
bool operator ==(other) => other is _UrlFetcher && _url == other._url;
......
......@@ -7,8 +7,14 @@ import 'dart:ui' as ui;
import 'print.dart';
class ImageInfo {
ImageInfo({ this.image, this.scale: 1.0 });
final ui.Image image;
final double scale;
}
/// A callback for when the image is available.
typedef void ImageListener(ui.Image image);
typedef void ImageListener(ImageInfo image);
/// A handle to an image resource
///
......@@ -16,21 +22,20 @@ typedef void ImageListener(ui.Image image);
/// image object might change over time, either because the image is animating
/// or because the underlying image resource was mutated.
class ImageResource {
ImageResource(this._futureImage, { this.scale : 1.0 }) {
ImageResource(this._futureImage) {
_futureImage.then(_handleImageLoaded, onError: (exception, stack) => _handleImageError('Failed to load image:', exception, stack));
}
bool _resolved = false;
Future<ui.Image> _futureImage;
ui.Image _image;
double scale;
Future<ImageInfo> _futureImage;
ImageInfo _image;
final List<ImageListener> _listeners = new List<ImageListener>();
/// The first concrete [ui.Image] object represented by this handle.
///
/// Instead of receivingly only the first image, most clients will want to
/// [addListener] to be notified whenever a a concrete image is available.
Future<ui.Image> get first => _futureImage;
Future<ImageInfo> get first => _futureImage;
/// Adds a listener callback that is called whenever a concrete [ui.Image]
/// object is available. Note: If a concrete image is available currently,
......@@ -51,7 +56,7 @@ class ImageResource {
_listeners.remove(listener);
}
void _handleImageLoaded(ui.Image image) {
void _handleImageLoaded(ImageInfo image) {
_image = image;
_resolved = true;
_notifyListeners();
......
......@@ -5,7 +5,6 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:mojo/core.dart' as core;
......@@ -51,13 +50,15 @@ class _ResolutionAwareAssetBundle extends _ResolvingAssetBundle {
_ResolutionAwareAssetResolver get resolver => super.resolver;
Future<ui.Image> fetchImage(String key) async {
Future<ImageInfo> fetchImage(String key) async {
core.MojoDataPipeConsumer pipe = await load(key);
// At this point the key should be in our key cache, and the image
// resource should be in our image cache
double scale = resolver.getScale(keyCache[key]);
imageResourceCache[key].scale = scale;
return await decodeImageFromDataPipe(pipe);
return new ImageInfo(
image: await decodeImageFromDataPipe(pipe),
scale: scale
);
}
}
......
......@@ -1508,7 +1508,7 @@ class RawImage extends LeafRenderObjectWidget {
this.image,
this.width,
this.height,
this.scale,
this.scale: 1.0,
this.color,
this.fit,
this.alignment,
......@@ -1658,16 +1658,11 @@ class _ImageListenerState extends State<RawImageResource> {
config.image.addListener(_handleImageChanged);
}
// Note, we remember the resolved image and the scale together. If the
// source image resource is updated, we shouldn't grab its scale until
// it provides the associated resolved image.
ui.Image _resolvedImage;
double _scale;
ImageInfo _resolvedImage;
void _handleImageChanged(ui.Image resolvedImage) {
void _handleImageChanged(ImageInfo resolvedImage) {
setState(() {
_resolvedImage = resolvedImage;
_scale = config.image.scale;
});
}
......@@ -1685,10 +1680,10 @@ class _ImageListenerState extends State<RawImageResource> {
Widget build(BuildContext context) {
return new RawImage(
image: _resolvedImage,
image: _resolvedImage?.image,
width: config.width,
height: config.height,
scale: _scale,
scale: _resolvedImage == null ? 1.0 : _resolvedImage.scale,
color: config.color,
fit: config.fit,
alignment: config.alignment,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment