From 1045934d5e62eaf85bc280ce2d75e7558f5a5104 Mon Sep 17 00:00:00 2001 From: Roman Blum Date: Tue, 6 Dec 2016 02:16:13 +0100 Subject: [PATCH] [core, ios, macos] Add image accessor to MGLStyle (#7096) * [core] Add interface to get image from sprite atlas * [tests] Add tests for Map::getImage * [ios, macos] WIP: get MGLImage for name from style * [ios, macos] Fixed -imageForName: Convert from sprite images to platform images using the existing encodePNG() function, which is also used for printing. Allow -imageForName: to return nil without an assertion failure. Added a basic test. --- include/mbgl/map/map.hpp | 1 + platform/darwin/src/MGLStyle.h | 17 ++++++++++++ platform/darwin/src/MGLStyle.mm | 26 ++++++++++++++++-- platform/darwin/test/MGLStyleTests.mm | 24 ++++++++++++++++ .../darwin/test/Media.xcassets/Contents.json | 6 ++++ .../Contents.json | 26 ++++++++++++++++++ .../TrackingLocationMask.png | Bin 0 -> 407 bytes .../TrackingLocationMask@2x.png | Bin 0 -> 680 bytes .../TrackingLocationMask@3x.png | Bin 0 -> 903 bytes .../AppIcon.appiconset/Contents.json | 20 ++++++++++++++ platform/ios/ios.xcodeproj/project.pbxproj | 4 +++ platform/ios/src/UIImage+MGLAdditions.h | 6 ++++ platform/ios/src/UIImage+MGLAdditions.mm | 7 +++++ .../macos/macos.xcodeproj/project.pbxproj | 4 +++ platform/macos/src/NSImage+MGLAdditions.h | 6 ++++ platform/macos/src/NSImage+MGLAdditions.mm | 13 +++++++-- src/mbgl/map/map.cpp | 7 +++++ test/fixtures/map/get_icon/expected.png | Bin 0 -> 1010 bytes test/map/map.test.cpp | 12 ++++++++ 19 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 platform/darwin/test/Media.xcassets/Contents.json create mode 100644 platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/Contents.json create mode 100644 platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/TrackingLocationMask.png create mode 100644 platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/TrackingLocationMask@2x.png create mode 100644 platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/TrackingLocationMask@3x.png create mode 100644 test/fixtures/map/get_icon/expected.png diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 10153c54e..092cfbe29 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -171,6 +171,7 @@ public: // Add image, bound to the style void addImage(const std::string&, std::unique_ptr); void removeImage(const std::string&); + const SpriteImage* getImage(const std::string&); // Defaults std::string getStyleName() const; diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index 54ca267ba..3fe8fb949 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -371,6 +371,23 @@ static const NSInteger MGLStyleDefaultVersion = 9; #pragma mark Managing a Style’s Images +/** + Returns the image associated with the given name in the style. + + @note Names and their associated images are not guaranteed to exist across + styles or different versions of the same style. Applications that use this + API must first set the style URL to an explicitly versioned style using a + convenience method like `+[MGLStyle outdoorsStyleURLWithVersion:]`, + `MGLMapView`'s “Style URL” inspectable in Interface Builder, or a manually + constructed `NSURL`. This approach also avoids image name changes that will + occur in the default style over time. + + @param name The name associated with the image you want to obtain. + @return The image associated with the given name, or `nil` if no image is + associated with that name. + */ +- (nullable MGLImage *)imageForName:(NSString *)name; + /** Adds or overrides an image used by the style’s layers. diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 56dc4ad8f..99d6ca89b 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -482,19 +482,39 @@ static NSURL *MGLStyleURL_emerald; - (void)setImage:(MGLImage *)image forName:(NSString *)name { - NSAssert(image, @"image is null"); - NSAssert(name, @"name is null"); + if (!image) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot assign nil image to “%@”.", name]; + } + if (!name) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot assign image %@ to a nil name.", image]; + } self.mapView.mbglMap->addImage([name UTF8String], image.mgl_spriteImage); } - (void)removeImageForName:(NSString *)name { - NSAssert(name, @"name is null"); + if (!name) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot remove image with nil name."]; + } self.mapView.mbglMap->removeImage([name UTF8String]); } +- (MGLImage *)imageForName:(NSString *)name +{ + if (!name) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot get image with nil name."]; + } + + auto spriteImage = self.mapView.mbglMap->getImage([name UTF8String]); + return spriteImage ? [[MGLImage alloc] initWithMGLSpriteImage:spriteImage] : nil; +} + - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p; name = %@, URL = %@>", diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index 4c0c163b3..8f0d2502f 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -17,6 +17,11 @@ #import #import +#if TARGET_OS_IPHONE + #import +#else + #import +#endif #import @interface MGLStyleTests : XCTestCase @@ -175,4 +180,23 @@ return styleHeader; } +- (void)testImages { + NSString *imageName = @"TrackingLocationMask"; +#if TARGET_OS_IPHONE + MGLImage *image = [MGLImage imageNamed:imageName + inBundle:[NSBundle bundleForClass:[self class]] + compatibleWithTraitCollection:nil]; +#else + MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:imageName]; +#endif + XCTAssertNotNil(image); + + [self.mapView.style setImage:image forName:imageName]; + MGLImage *styleImage = [self.mapView.style imageForName:imageName]; + + XCTAssertNotNil(styleImage); + XCTAssertEqual(image.size.width, styleImage.size.width); + XCTAssertEqual(image.size.height, styleImage.size.height); +} + @end diff --git a/platform/darwin/test/Media.xcassets/Contents.json b/platform/darwin/test/Media.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/platform/darwin/test/Media.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/Contents.json b/platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/Contents.json new file mode 100644 index 000000000..08cd551fc --- /dev/null +++ b/platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "TrackingLocationMask.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "TrackingLocationMask@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "TrackingLocationMask@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/TrackingLocationMask.png b/platform/darwin/test/Media.xcassets/TrackingLocationMask.imageset/TrackingLocationMask.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7348c482f3cbbc9dfe456cdfc57af20e8b0ac4 GIT binary patch literal 407 zcmeAS@N?(olHy`uVBq!ia0vp^;vmey1|%P7U0DF67>k44ofy`glX(f`$Yi?shX83N zAO-;*Al87=+(7!{SMU3$f%INa7sn6}-lT*Db_uLflAK5OUNMPc$%qgYuxEVq-$91q zhzN7+0?y5iKdc3sc~~DtJDg!TlEOH_EneXs_Yni;i7!ive4esqonn7vZNbAD`GKp$ zvT;Vn0-g{{#twT%!%f^9H@@yPy~??wKw03w>Y;!MuJ;=xL^fJ5vInTKcIY!2noWNw zJiG05Nag|;ZGru2hXW?GD%@YmV8~^_{%IQHM}383&$XP2vIBjVHZ-4A^5#0@e6cI< zN1#Zg20PIG|Nq}+I}ih8B!E1UoS?w}hds;r7~>Pk=2-Df2e&tP&Dfx=>@RZj1J9?P z18cd{erPWc^1E~D#NtZga%%c>Qqx~9iQ^!16$ iZgcdsA5FO!Aj;4rTvNV%!AVdcGI+ZBxvX#yWBdysu8aTIX&kQ9iMv?LO0?O`Y-+>|gqM$ra0o zEwB!}d?Q8t*m9jJ{&>DanbXTl77n#WwZ7?_O-kmjEkDbLPmQ;V85^7!?xU8c2 zS=O$V+`nV=Pfg0ZY%w>_Zqdu?=3~{9^7K8Hi*x<7jo9P8i}%2kJjJ8=5vNyAD*3(4 z+ruzezw>)?c=qiQzVio`C2Z(A=u{IB{{99N|FaKOIg^?rd7gZ5 zjNhBg?J(gmd+pc0vkw=%iWQxGBtbmd{Dy4D>00MSRmY$H2rOi13HPx#32;bRa{vG#H~;`4H~~eLF<<}y032yVPgDQ^00IC20000003!eZ04M+e03!eZ z03rYY0v#855;6b)0qIFZK~#7F?3ghuMKKhHUxdWM!oFpv=8Kf_6yrY`NdZBOsjP}8MCu~VmMO42_s5r`{wN+8&4=SzXYsq?hP zN5qCf<02yc01mneRi#dsxzIV)k=`eDh61qHsg3l$sna$l8Fx{UY8t1`Yn(`8O0rf> zr03N6m=Okp%pU1Eb-pWrK~S_@TJRb=5 zy~nW+m+Sv+qdwzgkv=sX9|-2X(Ib6o5axcSQJ=mj(tiU00RR8zNKe@S009q4L_t*T zmcb3eKnw&Ue*7tcCg_4H2vtB8&;?WhO{4@0;D^BXh=kB8XKO#_ERpi@*|K+hCvDfY z{k?6x=s#G^qHS5+bWtEBf5)|Kzd8!#VUm{Z%i<=CLOF2la#Tm4JWbLnhb(T&2$U1o zDo?c+%F86J^T^^R^+LIDZE{t6p=@%=;->XLxp6J>RePXp^U2~Su0ff-rAPQ`PCvJQ6e&yZg(79?Jy7l_NiFvKeB>-W zTKG2TWwX-kh5U!X`^dIUw@(jzEW6jYDNTYB{i d@YkP?zz0UnU}&3;hF|~y002ovPDHLkV1f=4ihlqA literal 0 HcmV?d00001 diff --git a/platform/ios/app/Assets.xcassets/AppIcon.appiconset/Contents.json b/platform/ios/app/Assets.xcassets/AppIcon.appiconset/Contents.json index c1b88669e..e1bc22272 100644 --- a/platform/ios/app/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/platform/ios/app/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", @@ -36,6 +46,16 @@ "filename" : "Icon-60@3x.png", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index a5c042a08..488872ad3 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -188,6 +188,7 @@ DA25D5C01CCD9F8400607828 /* Root.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA25D5BF1CCD9F8400607828 /* Root.plist */; }; DA25D5C61CCDA06800607828 /* Root.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA25D5C41CCDA06800607828 /* Root.strings */; }; DA25D5CD1CCDA11500607828 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DA25D5B91CCD9EDE00607828 /* Settings.bundle */; }; + DA2784FC1DF02FF4001D5B8D /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA2784FB1DF02FF4001D5B8D /* Media.xcassets */; }; DA27C24E1CBB3811000B0ECD /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA27C24D1CBB3811000B0ECD /* GLKit.framework */; }; DA27C24F1CBB4C11000B0ECD /* MGLAccountManager_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8847FF1CBAFA6200AB86E3 /* MGLAccountManager_Private.h */; }; DA2DBBCE1D51E80400D38FF9 /* MGLStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2DBBCD1D51E80400D38FF9 /* MGLStyleLayerTests.m */; }; @@ -618,6 +619,7 @@ DA25D5B91CCD9EDE00607828 /* Settings.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Settings.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; DA25D5BF1CCD9F8400607828 /* Root.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Root.plist; sourceTree = ""; }; DA25D5C51CCDA06800607828 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Root.strings; sourceTree = ""; }; + DA2784FB1DF02FF4001D5B8D /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Media.xcassets; path = ../../darwin/test/Media.xcassets; sourceTree = ""; }; DA27C24D1CBB3811000B0ECD /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; }; DA2DBBCC1D51E80400D38FF9 /* MGLStyleLayerTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLStyleLayerTests.h; path = ../../darwin/test/MGLStyleLayerTests.h; sourceTree = ""; }; DA2DBBCD1D51E80400D38FF9 /* MGLStyleLayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLStyleLayerTests.m; path = ../../darwin/test/MGLStyleLayerTests.m; sourceTree = ""; }; @@ -1065,6 +1067,7 @@ DA2E88601CC0382C00F24E7B /* MGLStyleTests.mm */, DD58A4C51D822BD000E1F038 /* MGLExpressionTests.mm */, DA2E88551CC036F400F24E7B /* Info.plist */, + DA2784FB1DF02FF4001D5B8D /* Media.xcassets */, ); name = "SDK Tests"; path = test; @@ -1805,6 +1808,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + DA2784FC1DF02FF4001D5B8D /* Media.xcassets in Resources */, 353BAEF71D646370009A8DA9 /* amsterdam.geojson in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/platform/ios/src/UIImage+MGLAdditions.h b/platform/ios/src/UIImage+MGLAdditions.h index 411220c50..f291a302c 100644 --- a/platform/ios/src/UIImage+MGLAdditions.h +++ b/platform/ios/src/UIImage+MGLAdditions.h @@ -2,8 +2,14 @@ #include +NS_ASSUME_NONNULL_BEGIN + @interface UIImage (MGLAdditions) +- (nullable instancetype)initWithMGLSpriteImage:(const mbgl::SpriteImage *)spriteImage; + - (std::unique_ptr)mgl_spriteImage; @end + +NS_ASSUME_NONNULL_END diff --git a/platform/ios/src/UIImage+MGLAdditions.mm b/platform/ios/src/UIImage+MGLAdditions.mm index 8ec8f9e15..4507fb6c4 100644 --- a/platform/ios/src/UIImage+MGLAdditions.mm +++ b/platform/ios/src/UIImage+MGLAdditions.mm @@ -2,6 +2,13 @@ @implementation UIImage (MGLAdditions) +- (nullable instancetype)initWithMGLSpriteImage:(const mbgl::SpriteImage *)spriteImage +{ + std::string png = encodePNG(spriteImage->image); + NSData *data = [[NSData alloc] initWithBytes:png.data() length:png.size()]; + return [self initWithData:data scale:spriteImage->pixelRatio]; +} + - (std::unique_ptr)mgl_spriteImage { CGImageRef cgImage = self.CGImage; diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index fdfc1b9f0..07a912386 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ 55D9B4B11D005D3900C1CCE2 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D9B4B01D005D3900C1CCE2 /* libz.tbd */; }; DA0CD58E1CF56F5800A5F5A5 /* MGLFeatureTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */; }; DA2207BC1DC076940002F84D /* MGLStyleValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2207BB1DC076940002F84D /* MGLStyleValueTests.swift */; }; + DA2784FE1DF03060001D5B8D /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA2784FD1DF03060001D5B8D /* Media.xcassets */; }; DA2DBBCB1D51E30A00D38FF9 /* MGLStyleLayerTests.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA2DBBCA1D51E30A00D38FF9 /* MGLStyleLayerTests.xib */; }; DA35A2A41CC9EB1A00E826B2 /* MGLCoordinateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */; }; @@ -296,6 +297,7 @@ DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLFeatureTests.mm; path = ../../darwin/test/MGLFeatureTests.mm; sourceTree = ""; }; DA2207BA1DC076930002F84D /* test-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "test-Bridging-Header.h"; sourceTree = ""; }; DA2207BB1DC076940002F84D /* MGLStyleValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MGLStyleValueTests.swift; sourceTree = ""; }; + DA2784FD1DF03060001D5B8D /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Media.xcassets; path = ../../darwin/test/Media.xcassets; sourceTree = ""; }; DA2DBBCA1D51E30A00D38FF9 /* MGLStyleLayerTests.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MGLStyleLayerTests.xib; sourceTree = ""; }; DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCoordinateFormatter.h; sourceTree = ""; }; DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLCoordinateFormatter.m; sourceTree = ""; }; @@ -842,6 +844,7 @@ DAE6C3CC1CC34BD800DB3429 /* MGLStyleTests.mm */, DD58A4C71D822C6200E1F038 /* MGLExpressionTests.mm */, DAE6C33A1CC30DB200DB3429 /* Info.plist */, + DA2784FD1DF03060001D5B8D /* Media.xcassets */, ); name = "SDK Tests"; path = test; @@ -1150,6 +1153,7 @@ buildActionMask = 2147483647; files = ( 35724FC41D630502002A4AB4 /* amsterdam.geojson in Resources */, + DA2784FE1DF03060001D5B8D /* Media.xcassets in Resources */, DA2DBBCB1D51E30A00D38FF9 /* MGLStyleLayerTests.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/platform/macos/src/NSImage+MGLAdditions.h b/platform/macos/src/NSImage+MGLAdditions.h index a2144e96a..ee01a763a 100644 --- a/platform/macos/src/NSImage+MGLAdditions.h +++ b/platform/macos/src/NSImage+MGLAdditions.h @@ -2,8 +2,14 @@ #include +NS_ASSUME_NONNULL_BEGIN + @interface NSImage (MGLAdditions) +- (nullable instancetype)initWithMGLSpriteImage:(const mbgl::SpriteImage *)spriteImage; + - (std::unique_ptr)mgl_spriteImage; @end + +NS_ASSUME_NONNULL_END diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm index 7d02271bb..dd132d0e8 100644 --- a/platform/macos/src/NSImage+MGLAdditions.mm +++ b/platform/macos/src/NSImage+MGLAdditions.mm @@ -2,6 +2,16 @@ @implementation NSImage (MGLAdditions) +- (nullable instancetype)initWithMGLSpriteImage:(const mbgl::SpriteImage *)spriteImage { + std::string png = encodePNG(spriteImage->image); + NSData *data = [[NSData alloc] initWithBytes:png.data() length:png.size()]; + NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:data]; + if ([self initWithSize:NSMakeSize(spriteImage->getWidth(), spriteImage->getHeight())]) { + [self addRepresentation:rep]; + } + return self; +} + - (std::unique_ptr)mgl_spriteImage { // Create a bitmap image representation from the image, respecting backing // scale factor and any resizing done on the image at runtime. @@ -10,9 +20,6 @@ NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, self.size }]; [self unlockFocus]; - // Get the image’s raw pixel data as an RGBA buffer. - std::string pixelString((const char *)rep.bitmapData, rep.pixelsWide * rep.pixelsHigh * 4 /* RGBA */); - mbgl::PremultipliedImage cPremultipliedImage(rep.pixelsWide, rep.pixelsHigh); std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.size(), cPremultipliedImage.data.get()); return std::make_unique(std::move(cPremultipliedImage), diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 68c20a313..f6ee6a565 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -896,6 +896,13 @@ void Map::removeImage(const std::string& name) { impl->onUpdate(Update::Repaint); } +const SpriteImage* Map::getImage(const std::string& name) { + if (impl->style) { + return impl->style->spriteAtlas->getSprite(name).get(); + } + return nullptr; +} + #pragma mark - Defaults std::string Map::getStyleName() const { diff --git a/test/fixtures/map/get_icon/expected.png b/test/fixtures/map/get_icon/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..b112096c180eecca2d6afde217a9fe54eae6f327 GIT binary patch literal 1010 zcmVm{G8B)KoXJFa>pBy66(wY{N1{V$IeF+19SHcT z6u!wx>Kh-Ywd`huNn7=Ohk*=HT|M7$glc?V+76YwcTrt+HGNN~8&5eL(u>;+Am2oF`sBU=Mo2*bi}Ud?l#qhEy>oiS&DPrAXu9LANYbpjS$iC z=2g_qjQ8{N)H5?fi~IJ`oYP6~Mn>poE=RRmlXReI@Ly?%6|^ zBN6h~*Kc*13179f5wY$#>x=+L|K#LFq}&)Vy%DK>Tv(vf?d^FoH4N>kHsZ`C`lHvnlCvw70rk7d}-2OGCW*D&88mdA?;f;6Xy?E;tH z<$FW1S<9of9pD3BaOhnoX71%{sJB>@r2rrJf+J6;q4oXrG?_=J6krP<_!{Ssv?x)_ z&c2C>9TRG{otiJ1BLr^7mzJWRcaS=4U<)7fNg+d&_z1OrnEqBWb?9INTg``xMM$?R zE8i+Vvkyz9-ZMH%uz{^vmmjQfIP9pZsyfKaP(lz!gPF_;!Db7XZ=!)%j7Am~#-6*~ zw-mcwVjqzuttd(^Psn6W+>tEqtrKovcjt1Say1`+ObS+3SR9mZD$x`##@|9n5*! zI5shs>|fmc@Qvnci0*J56TGa@y7niKS;nWPrZz4AzO)gNH1U>54<|%nqID{xj55k7 gql_~COZ*aG0OGQs<%kp{B>(^b07*qoM6N<$f?LhmRsaA1 literal 0 HcmV?d00001 diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 97a09e94a..ac82bbaca 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -394,3 +394,15 @@ TEST(Map, RemoveImage) { map.removeImage("test-icon"); test::checkImage("test/fixtures/map/remove_icon", test::render(map, test.view)); } + +TEST(Map, GetImage) { + MapTest test; + + Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still); + auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")); + auto image = std::make_unique(std::move(decoded), 1.0); + + map.setStyleJSON(util::read_file("test/fixtures/api/icon_style.json")); + map.addImage("test-icon", std::move(image)); + test::checkImage("test/fixtures/map/get_icon", map.getImage("test-icon")->image); +}