From 387fa1800f24a40f5cae2bd9457a5628fe55ba49 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 18 Dec 2018 17:26:31 -0800 Subject: [ios, macos] Add "includesIdeographicGlyphs" option to MGLOfflineRegion. --- platform/darwin/src/MGLOfflineRegion.h | 13 ++++ platform/darwin/src/MGLShapeOfflineRegion.mm | 23 ++++-- platform/darwin/src/MGLTilePyramidOfflineRegion.mm | 23 ++++-- platform/darwin/test/MGLOfflineRegionTests.m | 11 +-- platform/darwin/test/MGLOfflineStorageTests.mm | 2 +- .../ios/app/MBXOfflinePacksTableViewController.m | 2 + platform/macos/app/Base.lproj/MapDocument.xib | 84 ++++++++++++---------- platform/macos/app/MapDocument.m | 4 ++ 8 files changed, 109 insertions(+), 53 deletions(-) diff --git a/platform/darwin/src/MGLOfflineRegion.h b/platform/darwin/src/MGLOfflineRegion.h index 3e0f485e2c..6a9bdbc399 100644 --- a/platform/darwin/src/MGLOfflineRegion.h +++ b/platform/darwin/src/MGLOfflineRegion.h @@ -19,6 +19,19 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, readonly) NSURL *styleURL; +/** + Specifies whether to include ideographic glyphs in downloaded font data. + Ideographic glyphs make up the majority of downloaded font data, but + it is possible to configure the renderer to use locally installed fonts + instead of relying on fonts downloaded as part of the offline pack. + See `MGLIdeographicFontFamilyName` setting. Also, for regions outside of + China, Japan, and Korea, these glyphs will rarely appear for non-CJK users. + + By default, this property is set to `YES`, so that the offline pack will + include ideographic glyphs. + */ +@property (nonatomic) BOOL includesIdeographicGlyphs; + @end NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShapeOfflineRegion.mm b/platform/darwin/src/MGLShapeOfflineRegion.mm index 67b9941a49..25b6b8e166 100644 --- a/platform/darwin/src/MGLShapeOfflineRegion.mm +++ b/platform/darwin/src/MGLShapeOfflineRegion.mm @@ -26,6 +26,7 @@ } @synthesize styleURL = _styleURL; +@synthesize includesIdeographicGlyphs = _includesIdeographicGlyphs; -(NSDictionary *)offlineStartEventAttributes { return @{ @@ -71,6 +72,7 @@ _shape = shape; _minimumZoomLevel = minimumZoomLevel; _maximumZoomLevel = maximumZoomLevel; + _includesIdeographicGlyphs = YES; } return self; } @@ -78,7 +80,9 @@ - (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegionDefinition &)definition { NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())]; MGLShape *shape = MGLShapeFromGeoJSON(definition.geometry); - return [self initWithStyleURL:styleURL shape:shape fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom]; + MGLShapeOfflineRegion* result = [self initWithStyleURL:styleURL shape:shape fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom]; + result.includesIdeographicGlyphs = definition.includeIdeographs; + return result; } - (const mbgl::OfflineRegionDefinition)offlineRegionDefinition { @@ -90,7 +94,7 @@ return mbgl::OfflineGeometryRegionDefinition(_styleURL.absoluteString.UTF8String, _shape.geometryObject, _minimumZoomLevel, _maximumZoomLevel, - scaleFactor); + scaleFactor, _includesIdeographicGlyphs); } - (nullable instancetype)initWithCoder:(NSCoder *)coder { @@ -100,7 +104,9 @@ double minimumZoomLevel = [coder decodeDoubleForKey:@"minimumZoomLevel"]; double maximumZoomLevel = [coder decodeDoubleForKey:@"maximumZoomLevel"]; - return [self initWithStyleURL:styleURL shape:shape fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel]; + MGLShapeOfflineRegion* result = [self initWithStyleURL:styleURL shape:shape fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel]; + result.includesIdeographicGlyphs = [coder decodeBoolForKey:@"includesIdeographicGlyphs"]; + return result; } - (void)encodeWithCoder:(NSCoder *)coder @@ -109,10 +115,13 @@ [coder encodeObject:_shape forKey:@"shape"]; [coder encodeDouble:_maximumZoomLevel forKey:@"maximumZoomLevel"]; [coder encodeDouble:_minimumZoomLevel forKey:@"minimumZoomLevel"]; + [coder encodeBool:_includesIdeographicGlyphs forKey:@"includesIdeographicGlyphs"]; } - (id)copyWithZone:(nullable NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL shape:_shape fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel]; + MGLShapeOfflineRegion* result = [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL shape:_shape fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel]; + result.includesIdeographicGlyphs = _includesIdeographicGlyphs; + return result; } - (BOOL)isEqual:(id)other { @@ -127,13 +136,15 @@ return (_minimumZoomLevel == otherRegion->_minimumZoomLevel && _maximumZoomLevel == otherRegion->_maximumZoomLevel && _shape.geometryObject == otherRegion->_shape.geometryObject - && [_styleURL isEqual:otherRegion->_styleURL]); + && [_styleURL isEqual:otherRegion->_styleURL] + && _includesIdeographicGlyphs == otherRegion->_includesIdeographicGlyphs); } - (NSUInteger)hash { return (_styleURL.hash + _shape.hash - + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash); + + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash + + @(_includesIdeographicGlyphs).hash); } @end diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion.mm b/platform/darwin/src/MGLTilePyramidOfflineRegion.mm index 4b19b76508..a398d6baa4 100644 --- a/platform/darwin/src/MGLTilePyramidOfflineRegion.mm +++ b/platform/darwin/src/MGLTilePyramidOfflineRegion.mm @@ -23,6 +23,7 @@ } @synthesize styleURL = _styleURL; +@synthesize includesIdeographicGlyphs = _includesIdeographicGlyphs; -(NSDictionary *)offlineStartEventAttributes { return @{ @@ -67,6 +68,7 @@ _bounds = bounds; _minimumZoomLevel = minimumZoomLevel; _maximumZoomLevel = maximumZoomLevel; + _includesIdeographicGlyphs = YES; } return self; } @@ -74,7 +76,9 @@ - (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineTilePyramidRegionDefinition &)definition { NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())]; MGLCoordinateBounds bounds = MGLCoordinateBoundsFromLatLngBounds(definition.bounds); - return [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom]; + MGLTilePyramidOfflineRegion* result = [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom]; + result.includesIdeographicGlyphs = definition.includeIdeographs; + return result; } - (const mbgl::OfflineRegionDefinition)offlineRegionDefinition { @@ -86,7 +90,7 @@ return mbgl::OfflineTilePyramidRegionDefinition(_styleURL.absoluteString.UTF8String, MGLLatLngBoundsFromCoordinateBounds(_bounds), _minimumZoomLevel, _maximumZoomLevel, - scaleFactor); + scaleFactor, _includesIdeographicGlyphs); } - (nullable instancetype)initWithCoder:(NSCoder *)coder { @@ -100,7 +104,9 @@ double minimumZoomLevel = [coder decodeDoubleForKey:@"minimumZoomLevel"]; double maximumZoomLevel = [coder decodeDoubleForKey:@"maximumZoomLevel"]; - return [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel]; + MGLTilePyramidOfflineRegion* result = [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel]; + result.includesIdeographicGlyphs = [coder decodeBoolForKey:@"includesIdeographicGlyphs"]; + return result; } - (void)encodeWithCoder:(NSCoder *)coder @@ -112,10 +118,13 @@ [coder encodeDouble:_bounds.ne.longitude forKey:@"northEastLongitude"]; [coder encodeDouble:_maximumZoomLevel forKey:@"maximumZoomLevel"]; [coder encodeDouble:_minimumZoomLevel forKey:@"minimumZoomLevel"]; + [coder encodeBool:_includesIdeographicGlyphs forKey:@"includesIdeographicGlyphs"]; } - (id)copyWithZone:(nullable NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL bounds:_bounds fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel]; + MGLTilePyramidOfflineRegion* result = [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL bounds:_bounds fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel]; + result.includesIdeographicGlyphs = _includesIdeographicGlyphs; + return result; } - (BOOL)isEqual:(id)other { @@ -130,14 +139,16 @@ return (_minimumZoomLevel == otherRegion->_minimumZoomLevel && _maximumZoomLevel == otherRegion->_maximumZoomLevel && MGLCoordinateBoundsEqualToCoordinateBounds(_bounds, otherRegion->_bounds) - && [_styleURL isEqual:otherRegion->_styleURL]); + && [_styleURL isEqual:otherRegion->_styleURL] + && _includesIdeographicGlyphs == otherRegion->_includesIdeographicGlyphs); } - (NSUInteger)hash { return (_styleURL.hash + @(_bounds.sw.latitude).hash + @(_bounds.sw.longitude).hash + @(_bounds.ne.latitude).hash + @(_bounds.ne.longitude).hash - + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash); + + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash + + @(_includesIdeographicGlyphs).hash); } @end diff --git a/platform/darwin/test/MGLOfflineRegionTests.m b/platform/darwin/test/MGLOfflineRegionTests.m index eac6da9b54..4d5767a8d2 100644 --- a/platform/darwin/test/MGLOfflineRegionTests.m +++ b/platform/darwin/test/MGLOfflineRegionTests.m @@ -25,8 +25,9 @@ XCTAssertEqualObjects(original.styleURL, copy.styleURL, @"Style URL has changed."); XCTAssert(MGLCoordinateBoundsEqualToCoordinateBounds(original.bounds, copy.bounds), @"Bounds have changed."); - XCTAssertEqual(original.minimumZoomLevel, original.minimumZoomLevel, @"Minimum zoom level has changed."); - XCTAssertEqual(original.maximumZoomLevel, original.maximumZoomLevel, @"Maximum zoom level has changed."); + XCTAssertEqual(original.minimumZoomLevel, copy.minimumZoomLevel, @"Minimum zoom level has changed."); + XCTAssertEqual(original.maximumZoomLevel, copy.maximumZoomLevel, @"Maximum zoom level has changed."); + XCTAssertEqual(original.includesIdeographicGlyphs, copy.includesIdeographicGlyphs, @"Include ideographs has changed."); } - (void)testGeometryRegionEquality { @@ -36,13 +37,15 @@ XCTAssertNil(error); MGLShapeOfflineRegion *original = [[MGLShapeOfflineRegion alloc] initWithStyleURL:[MGLStyle lightStyleURLWithVersion:MGLStyleDefaultVersion] shape:shape fromZoomLevel:5 toZoomLevel:10]; + original.includesIdeographicGlyphs = NO; MGLShapeOfflineRegion *copy = [original copy]; XCTAssertEqualObjects(original, copy, @"Shape region should be equal to its copy."); XCTAssertEqualObjects(original.styleURL, copy.styleURL, @"Style URL has changed."); XCTAssertEqualObjects(original.shape, copy.shape, @"Geometry has changed."); - XCTAssertEqual(original.minimumZoomLevel, original.minimumZoomLevel, @"Minimum zoom level has changed."); - XCTAssertEqual(original.maximumZoomLevel, original.maximumZoomLevel, @"Maximum zoom level has changed."); + XCTAssertEqual(original.minimumZoomLevel, copy.minimumZoomLevel, @"Minimum zoom level has changed."); + XCTAssertEqual(original.maximumZoomLevel, copy.maximumZoomLevel, @"Maximum zoom level has changed."); + XCTAssertEqual(original.includesIdeographicGlyphs, copy.includesIdeographicGlyphs, @"Include ideographs has changed."); } @end diff --git a/platform/darwin/test/MGLOfflineStorageTests.mm b/platform/darwin/test/MGLOfflineStorageTests.mm index f5d7ed28e1..6fb787b556 100644 --- a/platform/darwin/test/MGLOfflineStorageTests.mm +++ b/platform/darwin/test/MGLOfflineStorageTests.mm @@ -140,7 +140,7 @@ MGLShape *shape = [MGLShape shapeWithData: [geojson dataUsingEncoding:NSUTF8StringEncoding] encoding: NSUTF8StringEncoding error:&error]; XCTAssertNil(error); MGLShapeOfflineRegion *region = [[MGLShapeOfflineRegion alloc] initWithStyleURL:styleURL shape:shape fromZoomLevel:zoomLevel toZoomLevel:zoomLevel]; - + region.includesIdeographicGlyphs = NO; NSString *nameKey = @"Name"; NSString *name = @"Utrecht centrum"; diff --git a/platform/ios/app/MBXOfflinePacksTableViewController.m b/platform/ios/app/MBXOfflinePacksTableViewController.m index 497784f36b..fe63f4a02e 100644 --- a/platform/ios/app/MBXOfflinePacksTableViewController.m +++ b/platform/ios/app/MBXOfflinePacksTableViewController.m @@ -102,7 +102,9 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac name = nameField.placeholder; } + NSString *fontFamilyName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLIdeographicFontFamilyName"]; MGLTilePyramidOfflineRegion *region = [[MGLTilePyramidOfflineRegion alloc] initWithStyleURL:mapView.styleURL bounds:mapView.visibleCoordinateBounds fromZoomLevel:mapView.zoomLevel toZoomLevel:mapView.maximumZoomLevel]; + region.includesIdeographicGlyphs = fontFamilyName; NSData *context = [NSKeyedArchiver archivedDataWithRootObject:@{ MBXOfflinePackContextNameKey: name, }]; diff --git a/platform/macos/app/Base.lproj/MapDocument.xib b/platform/macos/app/Base.lproj/MapDocument.xib index 72fa024fcc..dd8237dbb5 100644 --- a/platform/macos/app/Base.lproj/MapDocument.xib +++ b/platform/macos/app/Base.lproj/MapDocument.xib @@ -1,14 +1,15 @@ - + - + + @@ -55,10 +56,10 @@ - + - + @@ -130,11 +131,11 @@ - - - + + - - - - - - - - - - + + @@ -384,16 +377,16 @@ - - + + - - + + @@ -406,7 +399,7 @@ - + + + + + + + + + + @@ -471,7 +483,7 @@ Gw - + diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index d2bc7e9bfc..213aa33107 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -82,6 +82,7 @@ NSArray> *MBXFlattenedShapes(NSArray> *sha @property (weak) IBOutlet NSNumberFormatter *minimumOfflinePackZoomLevelFormatter; @property (weak) IBOutlet NSTextField *maximumOfflinePackZoomLevelField; @property (weak) IBOutlet NSNumberFormatter *maximumOfflinePackZoomLevelFormatter; +@property (weak) IBOutlet NSButton *includesIdeographicGlyphsBox; @end @@ -931,6 +932,8 @@ NSArray> *MBXFlattenedShapes(NSArray> *sha self.minimumOfflinePackZoomLevelFormatter.maximum = @(ceil(self.mapView.maximumZoomLevel)); self.maximumOfflinePackZoomLevelFormatter.maximum = @(ceil(self.mapView.maximumZoomLevel)); + NSString *fontFamilyName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLIdeographicFontFamilyName"]; + self.includesIdeographicGlyphsBox.state = fontFamilyName ? NSOffState : NSOnState; [self.addOfflinePackWindow makeFirstResponder:self.offlinePackNameField]; __weak __typeof__(self) weakSelf = self; @@ -945,6 +948,7 @@ NSArray> *MBXFlattenedShapes(NSArray> *sha bounds:strongSelf.mapView.visibleCoordinateBounds fromZoomLevel:strongSelf.minimumOfflinePackZoomLevelField.integerValue toZoomLevel:strongSelf.maximumOfflinePackZoomLevelField.integerValue]; + region.includesIdeographicGlyphs = strongSelf.includesIdeographicGlyphsBox.state == NSOnState; NSString *name = strongSelf.offlinePackNameField.stringValue; if (!name.length) { name = strongSelf.offlinePackNameField.placeholderString; -- cgit v1.2.1