5
5
import 'dart:async' show Future;
6
6
import 'dart:typed_data' show Uint8List;
7
7
8
- import 'package:flutter/foundation.dart' show kIsWeb;
8
+ import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting ;
9
9
import 'package:flutter/material.dart'
10
10
show
11
11
AssetBundleImageKey,
@@ -29,6 +29,14 @@ enum MapBitmapScaling {
29
29
none,
30
30
}
31
31
32
+ /// Convert a string from provided JSON to a MapBitmapScaling enum.
33
+ @visibleForTesting
34
+ MapBitmapScaling mapBitmapScalingFromString (String mode) => switch (mode) {
35
+ 'auto' => MapBitmapScaling .auto,
36
+ 'none' => MapBitmapScaling .none,
37
+ _ => throw ArgumentError ('Unrecognized MapBitmapScaling $mode ' , 'mode' ),
38
+ };
39
+
32
40
// The default pixel ratio for custom bitmaps.
33
41
const double _naturalPixelRatio = 1.0 ;
34
42
@@ -44,14 +52,14 @@ const double _naturalPixelRatio = 1.0;
44
52
/// a default marker icon.
45
53
/// Use the [BitmapDescriptor.defaultMarkerWithHue] to create a
46
54
/// [BitmapDescriptor] for a default marker icon with a hue value.
47
- class BitmapDescriptor {
48
- const BitmapDescriptor ._(this ._json );
55
+ abstract class BitmapDescriptor {
56
+ const BitmapDescriptor ._();
49
57
50
58
/// The inverse of .toJson.
51
59
// TODO(stuartmorgan): Remove this in the next breaking change.
52
60
@Deprecated ('No longer supported' )
53
- BitmapDescriptor . fromJson (Object json) : _json = json {
54
- assert (_json is List <dynamic >);
61
+ static BitmapDescriptor fromJson (Object json) {
62
+ assert (json is List <dynamic >);
55
63
final List <dynamic > jsonList = json as List <dynamic >;
56
64
assert (_validTypes.contains (jsonList[0 ]));
57
65
switch (jsonList[0 ]) {
@@ -61,19 +69,25 @@ class BitmapDescriptor {
61
69
assert (jsonList[1 ] is num );
62
70
final num secondElement = jsonList[1 ] as num ;
63
71
assert (0 <= secondElement && secondElement < 360 );
72
+ return DefaultMarker (hue: secondElement);
64
73
}
74
+ return const DefaultMarker ();
65
75
case _fromBytes:
66
76
assert (jsonList.length == 2 );
67
77
assert (jsonList[1 ] != null && jsonList[1 ] is List <int >);
68
78
assert ((jsonList[1 ] as List <int >).isNotEmpty);
79
+ return BytesBitmap (byteData: jsonList[1 ] as Uint8List );
69
80
case _fromAsset:
70
81
assert (jsonList.length <= 3 );
71
82
assert (jsonList[1 ] != null && jsonList[1 ] is String );
72
83
assert ((jsonList[1 ] as String ).isNotEmpty);
73
84
if (jsonList.length == 3 ) {
74
85
assert (jsonList[2 ] != null && jsonList[2 ] is String );
75
86
assert ((jsonList[2 ] as String ).isNotEmpty);
87
+ return AssetBitmap (
88
+ name: jsonList[1 ] as String , package: jsonList[2 ] as String );
76
89
}
90
+ return AssetBitmap (name: jsonList[1 ] as String );
77
91
case _fromAssetImage:
78
92
assert (jsonList.length <= 4 );
79
93
assert (jsonList[1 ] != null && jsonList[1 ] is String );
@@ -82,7 +96,15 @@ class BitmapDescriptor {
82
96
if (jsonList.length == 4 ) {
83
97
assert (jsonList[3 ] != null && jsonList[3 ] is List <dynamic >);
84
98
assert ((jsonList[3 ] as List <dynamic >).length == 2 );
99
+ final List <dynamic > sizeList = jsonList[3 ] as List <dynamic >;
100
+ return AssetImageBitmap (
101
+ name: jsonList[1 ] as String ,
102
+ scale: jsonList[2 ] as double ,
103
+ size: Size ((sizeList[0 ] as num ).toDouble (),
104
+ (sizeList[1 ] as num ).toDouble ()));
85
105
}
106
+ return AssetImageBitmap (
107
+ name: jsonList[1 ] as String , scale: jsonList[2 ] as double );
86
108
case AssetMapBitmap .type:
87
109
assert (jsonList.length == 2 );
88
110
assert (jsonList[1 ] != null && jsonList[1 ] is Map <String , dynamic >);
@@ -96,6 +118,16 @@ class BitmapDescriptor {
96
118
assert (jsonMap['imagePixelRatio' ] is double );
97
119
assert (! jsonMap.containsKey ('width' ) || jsonMap['width' ] is double );
98
120
assert (! jsonMap.containsKey ('height' ) || jsonMap['height' ] is double );
121
+ final double ? width =
122
+ jsonMap.containsKey ('width' ) ? jsonMap['width' ] as double : null ;
123
+ final double ? height =
124
+ jsonMap.containsKey ('height' ) ? jsonMap['height' ] as double : null ;
125
+ return AssetMapBitmap (jsonMap['assetName' ] as String ,
126
+ bitmapScaling:
127
+ mapBitmapScalingFromString (jsonMap['bitmapScaling' ] as String ),
128
+ imagePixelRatio: jsonMap['imagePixelRatio' ] as double ,
129
+ width: width,
130
+ height: height);
99
131
case BytesMapBitmap .type:
100
132
assert (jsonList.length == 2 );
101
133
assert (jsonList[1 ] != null && jsonList[1 ] is Map <String , dynamic >);
@@ -109,9 +141,20 @@ class BitmapDescriptor {
109
141
assert (jsonMap['imagePixelRatio' ] is double );
110
142
assert (! jsonMap.containsKey ('width' ) || jsonMap['width' ] is double );
111
143
assert (! jsonMap.containsKey ('height' ) || jsonMap['height' ] is double );
144
+ final double ? width =
145
+ jsonMap.containsKey ('width' ) ? jsonMap['width' ] as double : null ;
146
+ final double ? height =
147
+ jsonMap.containsKey ('height' ) ? jsonMap['height' ] as double : null ;
148
+ return BytesMapBitmap (jsonMap['byteData' ] as Uint8List ,
149
+ bitmapScaling:
150
+ mapBitmapScalingFromString (jsonMap['bitmapScaling' ] as String ),
151
+ width: width,
152
+ height: height,
153
+ imagePixelRatio: jsonMap['imagePixelRatio' ] as double );
112
154
default :
113
155
break ;
114
156
}
157
+ throw ArgumentError ('Unrecognized BitmapDescriptor type ${jsonList [0 ]}' );
115
158
}
116
159
117
160
static const String _defaultMarker = 'defaultMarker' ;
@@ -160,15 +203,14 @@ class BitmapDescriptor {
160
203
static const double hueRose = 330.0 ;
161
204
162
205
/// Creates a BitmapDescriptor that refers to the default marker image.
163
- static const BitmapDescriptor defaultMarker =
164
- BitmapDescriptor ._(< Object > [_defaultMarker]);
206
+ static const BitmapDescriptor defaultMarker = DefaultMarker ();
165
207
166
208
/// Creates a BitmapDescriptor that refers to a colorization of the default
167
209
/// marker image. For convenience, there is a predefined set of hue values.
168
210
/// See e.g. [hueYellow] .
169
211
static BitmapDescriptor defaultMarkerWithHue (double hue) {
170
212
assert (0.0 <= hue && hue < 360.0 );
171
- return BitmapDescriptor ._( < Object > [_defaultMarker, hue] );
213
+ return DefaultMarker (hue : hue);
172
214
}
173
215
174
216
/// Creates a [BitmapDescriptor] from an asset image.
@@ -189,27 +231,17 @@ class BitmapDescriptor {
189
231
}) async {
190
232
final double ? devicePixelRatio = configuration.devicePixelRatio;
191
233
if (! mipmaps && devicePixelRatio != null ) {
192
- return BitmapDescriptor ._(< Object > [
193
- _fromAssetImage,
194
- assetName,
195
- devicePixelRatio,
196
- ]);
234
+ return AssetImageBitmap (name: assetName, scale: devicePixelRatio);
197
235
}
198
236
final AssetImage assetImage =
199
237
AssetImage (assetName, package: package, bundle: bundle);
200
238
final AssetBundleImageKey assetBundleImageKey =
201
239
await assetImage.obtainKey (configuration);
202
- final Size ? size = configuration.size;
203
- return BitmapDescriptor ._(< Object > [
204
- _fromAssetImage,
205
- assetBundleImageKey.name,
206
- assetBundleImageKey.scale,
207
- if (kIsWeb && size != null )
208
- < Object > [
209
- size.width,
210
- size.height,
211
- ],
212
- ]);
240
+ final Size ? size = kIsWeb ? configuration.size : null ;
241
+ return AssetImageBitmap (
242
+ name: assetBundleImageKey.name,
243
+ scale: assetBundleImageKey.scale,
244
+ size: size);
213
245
}
214
246
215
247
/// Creates a BitmapDescriptor using an array of bytes that must be encoded
@@ -222,15 +254,7 @@ class BitmapDescriptor {
222
254
static BitmapDescriptor fromBytes (Uint8List byteData, {Size ? size}) {
223
255
assert (byteData.isNotEmpty,
224
256
'Cannot create BitmapDescriptor with empty byteData' );
225
- return BitmapDescriptor ._(< Object > [
226
- _fromBytes,
227
- byteData,
228
- if (kIsWeb && size != null )
229
- < Object > [
230
- size.width,
231
- size.height,
232
- ]
233
- ]);
257
+ return BytesBitmap (byteData: byteData, size: size);
234
258
}
235
259
236
260
/// Creates a [BitmapDescriptor] from an asset using [AssetMapBitmap] .
@@ -306,10 +330,100 @@ class BitmapDescriptor {
306
330
);
307
331
}
308
332
309
- final Object _json;
310
-
311
333
/// Convert the object to a Json format.
312
- Object toJson () => _json;
334
+ Object toJson ();
335
+ }
336
+
337
+ /// A BitmapDescriptor using the default marker.
338
+ class DefaultMarker extends BitmapDescriptor {
339
+ /// Provide an optional [hue] for the default marker.
340
+ const DefaultMarker ({this .hue}) : super ._();
341
+
342
+ /// Optional hue of the colorization of the default marker.
343
+ final num ? hue;
344
+
345
+ @override
346
+ Object toJson () => (hue == null )
347
+ ? const < Object > [BitmapDescriptor ._defaultMarker]
348
+ : < Object > [BitmapDescriptor ._defaultMarker, hue! ];
349
+ }
350
+
351
+ /// A BitmapDescriptor using an array of bytes that must be encoded
352
+ /// as PNG.
353
+ @Deprecated ('Use BytesMapBitmap instead' )
354
+ class BytesBitmap extends BitmapDescriptor {
355
+ /// On the web, the [size] parameter represents the *physical size* of the
356
+ /// bitmap, regardless of the actual resolution of the encoded PNG.
357
+ /// This helps the browser to render High-DPI images at the correct size.
358
+ /// `size` is not required (and ignored, if passed) in other platforms.
359
+ @Deprecated ('Use BytesMapBitmap instead' )
360
+ const BytesBitmap ({required Uint8List byteData, Size ? size})
361
+ : this ._(byteData, kIsWeb ? size : null );
362
+
363
+ @Deprecated ('Use BytesMapBitmap instead' )
364
+ const BytesBitmap ._(this .byteData, this .size) : super ._();
365
+
366
+ /// Array of bytes encoding a PNG.
367
+ final Uint8List byteData;
368
+
369
+ /// On web, the physical size of the bitmap. Null on all other platforms.
370
+ final Size ? size;
371
+
372
+ @override
373
+ Object toJson () => < Object > [
374
+ BitmapDescriptor ._fromBytes,
375
+ byteData,
376
+ if (size != null ) < Object > [size! .width, size! .height]
377
+ ];
378
+ }
379
+
380
+ /// A bitmap specified by a name and optional package.
381
+ class AssetBitmap extends BitmapDescriptor {
382
+ /// Provides an asset name with [name] and optionally a [package] .
383
+ const AssetBitmap ({required this .name, this .package}) : super ._();
384
+
385
+ /// Name of the asset backing the bitmap.
386
+ final String name;
387
+
388
+ /// Optional package of the asset.
389
+ final String ? package;
390
+
391
+ @override
392
+ Object toJson () => < Object > [
393
+ BitmapDescriptor ._fromAsset,
394
+ name,
395
+ if (package != null ) package!
396
+ ];
397
+ }
398
+
399
+ /// A [BitmapDescriptor] from an asset image.
400
+ @Deprecated ('Use AssetMapBitmap instead' )
401
+ class AssetImageBitmap extends BitmapDescriptor {
402
+ /// Creates a [BitmapDescriptor] from an asset image with specified [name] and [scale] , and an optional [size] .
403
+ /// Asset images in flutter are stored per:
404
+ /// https://flutter.dev/to/resolution-aware-images
405
+ /// This method takes into consideration various asset resolutions
406
+ /// and scales the images to the right resolution depending on the dpi.
407
+ @Deprecated ('Use AssetMapBitmap instead' )
408
+ const AssetImageBitmap ({required this .name, required this .scale, this .size})
409
+ : super ._();
410
+
411
+ /// Name of the image asset.
412
+ final String name;
413
+
414
+ /// Scaling factor for the asset image.
415
+ final double scale;
416
+
417
+ /// Size of the image if using mipmaps.
418
+ final Size ? size;
419
+
420
+ @override
421
+ Object toJson () => < Object > [
422
+ BitmapDescriptor ._fromAssetImage,
423
+ name,
424
+ scale,
425
+ if (size != null ) < Object > [size! .width, size! .height]
426
+ ];
313
427
}
314
428
315
429
/// Represents a [BitmapDescriptor] base class for map bitmaps.
@@ -344,7 +458,7 @@ abstract class MapBitmap extends BitmapDescriptor {
344
458
required this .imagePixelRatio,
345
459
this .width,
346
460
this .height,
347
- }) : super ._(const < Object > [] );
461
+ }) : super ._();
348
462
349
463
/// The scaling method of the bitmap.
350
464
final MapBitmapScaling bitmapScaling;
0 commit comments