Commit 7d253789 authored by fmatosqg's avatar fmatosqg Committed by Hans Muller

Make image resolution more strict, clean gallery pubspec.yaml (#17241) (#17322)

parent b6ceff55
......@@ -84,10 +84,6 @@ flutter:
assets:
- lib/gallery/example_code.dart
- packages/flutter_gallery_assets/white_logo/logo.png
- packages/flutter_gallery_assets/white_logo/1.5x/logo.png
- packages/flutter_gallery_assets/white_logo/2.5x/logo.png
- packages/flutter_gallery_assets/white_logo/3.0x/logo.png
- packages/flutter_gallery_assets/white_logo/4.0x/logo.png
- packages/flutter_gallery_assets/videos/butterfly.mp4
- packages/flutter_gallery_assets/animated_flutter_lgtm.gif
- packages/flutter_gallery_assets/animated_flutter_stickers.webp
......
......@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -56,6 +57,10 @@ const String _kAssetManifestFileName = 'AssetManifest.json';
/// icons/2.0x/heart.png
/// ```
///
/// assets/icons/3.0x/heart.png would be a valid variant of
/// assets/icons/heart.png.
///
///
/// ## Fetching assets
///
/// When fetching an image provided by the app itself, use the [assetName]
......@@ -166,6 +171,7 @@ class AssetImage extends AssetBundleImageProvider {
final AssetBundle chosenBundle = bundle ?? configuration.bundle ?? rootBundle;
Completer<AssetBundleImageKey> completer;
Future<AssetBundleImageKey> result;
chosenBundle.loadStructuredData<Map<String, List<String>>>(_kAssetManifestFileName, _manifestParser).then<void>(
(Map<String, List<String>> manifest) {
final String chosenName = _chooseVariant(
......@@ -252,10 +258,18 @@ class AssetImage extends AssetBundleImageProvider {
return candidates[lower];
}
static final RegExp _extractRatioRegExp = new RegExp(r'/?(\d+(\.\d*)?)x/');
static final RegExp _extractRatioRegExp = new RegExp(r'/?(\d+(\.\d*)?)x$');
double _parseScale(String key) {
final Match match = _extractRatioRegExp.firstMatch(key);
if ( key == assetName){
return _naturalResolution;
}
final File assetPath = new File(key);
final Directory assetDir = assetPath.parent;
final Match match = _extractRatioRegExp.firstMatch(assetDir.path);
if (match != null && match.groupCount > 0)
return double.parse(match.group(1));
return _naturalResolution; // i.e. default to 1.0x
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
class TestAssetBundle extends CachingAssetBundle {
Map<String, List<String>> _assetBundleMap;
TestAssetBundle(this._assetBundleMap);
Map<String, int> loadCallCount = <String, int>{};
String get _assetBundleContents {
return json.encode(_assetBundleMap);
}
@override
Future<ByteData> load(String key) async {
if (key == 'AssetManifest.json')
return new ByteData.view(new Uint8List.fromList(
const Utf8Encoder().convert(_assetBundleContents)).buffer);
loadCallCount[key] = loadCallCount[key] ?? 0 + 1;
if (key == 'one')
return new ByteData(1)
..setInt8(0, 49);
throw new FlutterError('key not found');
}
}
void main() {
group('1.0 scale device tests', () {
void _buildAndTestWithOneAsset(String mainAssetPath) {
final Map<String, List<String>> assetBundleMap = <String, List<String>>{};
assetBundleMap[mainAssetPath] = <String>[];
final AssetImage assetImage = new AssetImage(
mainAssetPath,
bundle: new TestAssetBundle(assetBundleMap));
const ImageConfiguration configuration = const ImageConfiguration();
assetImage.obtainKey(configuration)
.then(expectAsync1((AssetBundleImageKey bundleKey) {
expect(bundleKey.name, mainAssetPath);
expect(bundleKey.scale, 1.0);
}));
}
test('When asset is main variant check scale is 1.0', () {
_buildAndTestWithOneAsset('assets/normalFolder/normalFile.png');
});
test(
'When asset path and key are the same string even though it could be took as a 3.0x variant',
() async {
_buildAndTestWithOneAsset('assets/parentFolder/3.0x/normalFile.png');
});
test(
'When asset path contains variant identifier as part of parent folder name scale is 1.0',
() {
_buildAndTestWithOneAsset(
'assets/parentFolder/__3.0x__/leafFolder/normalFile.png');
});
test(
'When asset path contains variant identifier as part of leaf folder name scale is 1.0',
() {
_buildAndTestWithOneAsset(
'assets/parentFolder/__3.0x_leaf_folder_/normalFile.png');
});
test(
'When asset path contains variant identifier as part of parent folder name scale is 1.0',
() {
_buildAndTestWithOneAsset(
'assets/parentFolder/__3.0x__/leafFolder/normalFile.png');
});
test(
'When asset path contains variant identifier in parent folder scale is 1.0',
() {
_buildAndTestWithOneAsset(
'assets/parentFolder/3.0x/leafFolder/normalFile.png');
});
});
group('High-res device behavior tests', () {
test('When asset is not main variant check scale is not 1.0', () {
const String mainAssetPath = 'assets/normalFolder/normalFile.png';
const String variantPath = 'assets/normalFolder/3.0x/normalFile.png';
final Map<String, List<String>> assetBundleMap =
<String, List<String>>{};
assetBundleMap[mainAssetPath] = <String>[mainAssetPath, variantPath];
final TestAssetBundle testAssetBundle = new TestAssetBundle(
assetBundleMap);
final AssetImage assetImage = new AssetImage(
mainAssetPath,
bundle: testAssetBundle);
// we have the exact match for this scale, let's use it
assetImage.obtainKey(const ImageConfiguration())
.then(expectAsync1((AssetBundleImageKey bundleKey) {
expect(bundleKey.name, mainAssetPath);
expect(bundleKey.scale, 1.0);
}));
// we also have the exact match for this scale, let's use it
assetImage.obtainKey(new ImageConfiguration(
bundle: testAssetBundle,
devicePixelRatio: 3.0))
.then(expectAsync1((AssetBundleImageKey bundleKey) {
expect(bundleKey.name, variantPath);
expect(bundleKey.scale, 3.0);
}));
});
test(
'When high-res device and high-res asset not present in bundle then return main variant', () {
const String mainAssetPath = 'assets/normalFolder/normalFile.png';
final Map<String, List<String>> assetBundleMap =
<String, List<String>>{};
assetBundleMap[mainAssetPath] = <String>[mainAssetPath];
final TestAssetBundle testAssetBundle = new TestAssetBundle(
assetBundleMap);
final AssetImage assetImage = new AssetImage(
mainAssetPath,
bundle: new TestAssetBundle(assetBundleMap));
assetImage.obtainKey(const ImageConfiguration())
.then(expectAsync1((AssetBundleImageKey bundleKey) {
expect(bundleKey.name, mainAssetPath);
expect(bundleKey.scale, 1.0);
}));
assetImage.obtainKey(new ImageConfiguration(
bundle: testAssetBundle,
devicePixelRatio: 3.0))
.then(expectAsync1((AssetBundleImageKey bundleKey) {
expect(bundleKey.name, mainAssetPath);
expect(bundleKey.scale, 1.0);
}));
});
});
group(
'Regression - When assets available are 1.0 and 3.0 check devices with a range of scales', () {
const String mainAssetPath = 'assets/normalFolder/normalFile.png';
const String variantPath = 'assets/normalFolder/3.0x/normalFile.png';
void _buildBundleAndTestVariantLogic(double deviceRatio, double chosenAssetRatio,
String expectedAssetPath) {
final Map<String, List<String>> assetBundleMap =
<String, List<String>>{};
assetBundleMap[mainAssetPath] = <String>[mainAssetPath, variantPath];
final TestAssetBundle testAssetBundle = new TestAssetBundle(
assetBundleMap);
final AssetImage assetImage = new AssetImage(
mainAssetPath,
bundle: testAssetBundle);
// we have 1.0 and 3.0, asking for 1.5 should give
assetImage.obtainKey(new ImageConfiguration(
bundle: testAssetBundle,
devicePixelRatio: deviceRatio))
.then(expectAsync1((AssetBundleImageKey bundleKey) {
expect(bundleKey.name, expectedAssetPath);
expect(bundleKey.scale, chosenAssetRatio);
}));
}
test('Obvious case 1.0 - we have exact asset', () {
_buildBundleAndTestVariantLogic(1.0, 1.0, mainAssetPath);
});
test('Obvious case 3.0 - we have exact asset', () {
_buildBundleAndTestVariantLogic(3.0, 3.0, variantPath);
});
test('Typical case 2.0', () {
_buildBundleAndTestVariantLogic(2.0, 1.0, mainAssetPath);
});
test('Borderline case 2.01', () {
_buildBundleAndTestVariantLogic(2.01, 3.0, variantPath);
});
test('Borderline case 2.9', () {
_buildBundleAndTestVariantLogic(2.9, 3.0, variantPath);
});
test('Typical case 4.0', () {
_buildBundleAndTestVariantLogic(4.0, 3.0, variantPath);
});
});
}
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