Skip to content

Commit 00d29b1

Browse files
authored
[google_maps_flutter] Fix ios tile overlay not loading when dealing with wide gamut images (flutter#6377)
Fixes flutter#135252 Google maps does not currently support the use of wide gamut images. Since engine uses 16 bit floats when dealing with wide gamut images ([here](https://github.com/flutter/engine/blob/8a51e124fbf168295a1b05f8d66459bfb29ae8a9/shell/platform/darwin/ios/framework/Source/FlutterView.mm#L125)), when we detect that an image is using that format, we downsample it. https://github.com/flutter/packages/assets/36148254/2d67418d-53a9-472b-b03e-86fb24f9610c ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [relevant style guides] and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use `dart format`.) - [x] I signed the [CLA]. - [x] The title of the PR starts with the name of the package surrounded by square brackets, e.g. `[shared_preferences]` - [x] I [linked to at least one issue that this PR fixes] in the description above. - [x] I updated `pubspec.yaml` with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes]. - [x] I updated `CHANGELOG.md` to add a description of the change, [following repository CHANGELOG style]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [relevant style guides]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md#style [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat [linked to at least one issue that this PR fixes]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [pub versioning philosophy]: https://dart.dev/tools/pub/versioning [exempt from version changes]: https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#version-and-changelog-updates [following repository CHANGELOG style]: https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changelog-style [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
1 parent 01d16a4 commit 00d29b1

File tree

7 files changed

+59
-4
lines changed

7 files changed

+59
-4
lines changed

packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.5.2
2+
3+
* Fixes the tile overlay not correctly displaying on physical ios devices.
4+
15
## 2.5.1
26

37
* Makes the tile overlay callback invoke the platform channel on the platform thread.

packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1430"
3+
LastUpgradeVersion = "1510"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
1818
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
1919
982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */; };
20+
F269303B2BB389BF00BF17C4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = F269303A2BB389BF00BF17C4 /* assets */; };
2021
F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */; };
2122
FC8F35FC8CD533B128950487 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */; };
2223
/* End PBXBuildFile section */
@@ -68,6 +69,7 @@
6869
E52C6A6210A56F027C582EF9 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
6970
EA0E91726245EDC22B97E8B9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
7071
F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
72+
F269303A2BB389BF00BF17C4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = "<group>"; };
7173
F7151F10265D7ED70028CB91 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7274
F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsTests.m; sourceTree = "<group>"; };
7375
F7151F14265D7ED70028CB91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -174,6 +176,7 @@
174176
F7151F11265D7ED70028CB91 /* RunnerTests */ = {
175177
isa = PBXGroup;
176178
children = (
179+
F269303A2BB389BF00BF17C4 /* assets */,
177180
F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */,
178181
982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */,
179182
982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */,
@@ -232,6 +235,7 @@
232235
97C146E61CF9000F007C117D /* Project object */ = {
233236
isa = PBXProject;
234237
attributes = {
238+
LastSwiftUpdateCheck = 1530;
235239
LastUpgradeCheck = 1510;
236240
ORGANIZATIONNAME = "The Flutter Authors";
237241
TargetAttributes = {
@@ -280,6 +284,7 @@
280284
isa = PBXResourcesBuildPhase;
281285
buildActionMask = 2147483647;
282286
files = (
287+
F269303B2BB389BF00BF17C4 /* assets in Resources */,
283288
);
284289
runOnlyForDeploymentPostprocessing = 0;
285290
};
@@ -596,6 +601,7 @@
596601
BUNDLE_LOADER = "$(TEST_HOST)";
597602
CLANG_ENABLE_MODULES = YES;
598603
CODE_SIGN_STYLE = Automatic;
604+
DEVELOPMENT_TEAM = "";
599605
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64";
600606
INFOPLIST_FILE = RunnerTests/Info.plist;
601607
LD_RUNPATH_SEARCH_PATHS = (

packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ @interface FLTGoogleMapFactory (Test)
1717
@interface GoogleMapsTests : XCTestCase
1818
@end
1919

20+
@interface FLTTileProviderController (Testing)
21+
- (UIImage *)handleResultTile:(nullable UIImage *)tileImage;
22+
@end
23+
2024
@implementation GoogleMapsTests
2125

2226
- (void)testPlugin {
@@ -62,4 +66,23 @@ - (void)testMapsServiceSync {
6266
XCTAssertEqual(factory1.sharedMapServices, factory2.sharedMapServices);
6367
}
6468

69+
- (void)testHandleResultTileDownsamplesWideGamutImages {
70+
FLTTileProviderController *controller = [[FLTTileProviderController alloc] init];
71+
72+
NSString *imagePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"widegamut"
73+
ofType:@"png"
74+
inDirectory:@"assets"];
75+
UIImage *wideGamutImage = [UIImage imageWithContentsOfFile:imagePath];
76+
77+
XCTAssertNotNil(wideGamutImage, @"The image should be loaded.");
78+
79+
UIImage *downsampledImage = [controller handleResultTile:wideGamutImage];
80+
81+
CGImageRef imageRef = downsampledImage.CGImage;
82+
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
83+
84+
// non wide gamut images use 8 bit format
85+
XCTAssert(bitsPerComponent == 8);
86+
}
87+
6588
@end

packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,29 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel
118118

119119
#pragma mark - GMSTileLayer method
120120

121+
- (UIImage *)handleResultTile:(nullable UIImage *)tile {
122+
CGImageRef imageRef = tile.CGImage;
123+
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
124+
BOOL isFloat = bitmapInfo && kCGBitmapFloatComponents;
125+
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
126+
127+
// Engine use f16 pixel format for wide gamut images
128+
// If it is wide gamut, we want to downsample it
129+
if (isFloat & (bitsPerComponent == 16)) {
130+
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
131+
CGContextRef context = CGBitmapContextCreate(nil, tile.size.width, tile.size.height, 8, 0,
132+
colorSpace, kCGImageAlphaPremultipliedLast);
133+
CGContextDrawImage(context, CGRectMake(0, 0, tile.size.width, tile.size.height), tile.CGImage);
134+
CGImageRef image = CGBitmapContextCreateImage(context);
135+
tile = [UIImage imageWithCGImage:image];
136+
137+
CGImageRelease(image);
138+
CGContextRelease(context);
139+
CGColorSpaceRelease(colorSpace);
140+
}
141+
return tile;
142+
}
143+
121144
- (void)requestTileForX:(NSUInteger)x
122145
y:(NSUInteger)y
123146
zoom:(NSUInteger)zoom
@@ -137,7 +160,7 @@ - (void)requestTileForX:(NSUInteger)x
137160
if (typedData == nil) {
138161
tileImage = kGMSTileLayerNoTile;
139162
} else {
140-
tileImage = [UIImage imageWithData:typedData.data];
163+
tileImage = [self handleResultTile:[UIImage imageWithData:typedData.data]];
141164
}
142165
} else {
143166
if ([result isKindOfClass:[FlutterError class]]) {
@@ -150,7 +173,6 @@ - (void)requestTileForX:(NSUInteger)x
150173
}
151174
tileImage = kGMSTileLayerNoTile;
152175
}
153-
154176
[receiver receiveTileWithX:x y:y zoom:zoom image:tileImage];
155177
}];
156178
});

packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: google_maps_flutter_ios
22
description: iOS implementation of the google_maps_flutter plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
5-
version: 2.5.1
5+
version: 2.5.2
66

77
environment:
88
sdk: ^3.2.3

0 commit comments

Comments
 (0)