This repository has been archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'release-ios-v3.4.0' into erw-note-map-load
* release-ios-v3.4.0: [ios] Fixed crash on launch in iosapp [ios] Fix iosapp runtime styling examples (#7395) [ios, macos] handle duplicate layer error [core] guard against duplicate layer ids [core] use raii to guard backend deactivation [ios, macos] Override references to property names in property requirements lists (#7391) [ios, macos] Load features into shape source if possible (#7339) [ios, macos] Expanded source documentation [ios, macos] Rename MGLGeoJSONSource to MGLShapeSource (#7334) [ios, macos] Silence -Wc++11-narrowing warning in open gl layer (#7355) [ios, macos] Source-driven attribution (#5999) [ios, macos] renamed raster-hue-rotate
- Loading branch information
Showing
72 changed files
with
1,367 additions
and
537 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#import <Foundation/Foundation.h> | ||
#import <CoreGraphics/CoreGraphics.h> | ||
#import <CoreLocation/CoreLocation.h> | ||
|
||
#import "MGLTypes.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
/** | ||
Information about an attribution statement, usually a copyright or trademark | ||
statement, associated with a map content source. | ||
*/ | ||
@interface MGLAttributionInfo : NSObject | ||
|
||
/** | ||
Parses and returns the attribution infos contained in the given HTML source | ||
code string. | ||
@param htmlString The HTML source code to parse. | ||
@param fontSize The default text size in points. | ||
@param linkColor The default link color. | ||
*/ | ||
+ (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosFromHTMLString:(NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; | ||
|
||
- (instancetype)initWithTitle:(NSAttributedString *)title URL:(nullable NSURL *)URL; | ||
|
||
@property (nonatomic) NSAttributedString *title; | ||
@property (nonatomic, nullable) NSURL *URL; | ||
@property (nonatomic, getter=isFeedbackLink) BOOL feedbackLink; | ||
|
||
- (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel; | ||
|
||
@end | ||
|
||
@interface NSMutableArray (MGLAttributionInfoAdditions) | ||
|
||
/** | ||
Adds the given attribution info object to the receiver as long as it isn’t | ||
redundant to any object already in the receiver. Any existing object that is | ||
redundant to the given object is replaced by the given object. | ||
@param info The info object to add to the receiver. | ||
@return True if the given info object was added to the receiver. | ||
*/ | ||
- (void)growArrayByAddingAttributionInfo:(MGLAttributionInfo *)info; | ||
|
||
/** | ||
Adds each of the given attribution info objects to the receiver as long as it | ||
isn’t redundant to any object already in the receiver. Any existing object that | ||
is redundant to the given object is replaced by the given object. | ||
@param infos An array of info objects to add to the receiver. | ||
*/ | ||
- (void)growArrayByAddingAttributionInfosFromArray:(NS_ARRAY_OF(MGLAttributionInfo *) *)infos; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
#import "MGLAttributionInfo.h" | ||
|
||
#if TARGET_OS_IPHONE | ||
#import <UIKit/UIKit.h> | ||
#else | ||
#import <Cocoa/Cocoa.h> | ||
#endif | ||
|
||
#import "MGLMapCamera.h" | ||
#import "NSString+MGLAdditions.h" | ||
|
||
#include <string> | ||
|
||
@implementation MGLAttributionInfo | ||
|
||
+ (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosFromHTMLString:(NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { | ||
NSDictionary *options = @{ | ||
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, | ||
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding), | ||
}; | ||
// Apply a bogus, easily detectable style rule to any feedback link, since | ||
// NSAttributedString doesn’t preserve the class attribute. | ||
NSMutableString *css = [NSMutableString stringWithString: | ||
@".mapbox-improve-map { -webkit-text-stroke-width: 1000px; }"]; | ||
if (fontSize) { | ||
[css appendFormat:@"html { font-size: %.1fpx; }", fontSize]; | ||
} | ||
if (linkColor) { | ||
CGFloat red; | ||
CGFloat green; | ||
CGFloat blue; | ||
CGFloat alpha; | ||
#if !TARGET_OS_IPHONE | ||
linkColor = [linkColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; | ||
#endif | ||
[linkColor getRed:&red green:&green blue:&blue alpha:&alpha]; | ||
[css appendFormat: | ||
@"a:link { color: rgba(%f%%, %f%%, %f%%, %f); }", | ||
red * 100, green * 100, blue * 100, alpha]; | ||
} | ||
NSString *styledHTML = [NSString stringWithFormat:@"<style type='text/css'>%@</style>%@", css, htmlString]; | ||
NSData *htmlData = [styledHTML dataUsingEncoding:NSUTF8StringEncoding]; | ||
|
||
#if TARGET_OS_IPHONE | ||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithData:htmlData | ||
options:options | ||
documentAttributes:nil | ||
error:NULL]; | ||
#else | ||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithHTML:htmlData | ||
options:options | ||
documentAttributes:nil]; | ||
#endif | ||
|
||
NSMutableArray *infos = [NSMutableArray array]; | ||
[attributedString enumerateAttribute:NSLinkAttributeName | ||
inRange:attributedString.mgl_wholeRange | ||
options:0 | ||
usingBlock: | ||
^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) { | ||
NSCAssert(!value || [value isKindOfClass:[NSURL class]], @"If present, URL attribute must be an NSURL."); | ||
|
||
// Detect feedback links by the bogus style rule applied above. | ||
NSNumber *strokeWidth = [attributedString attribute:NSStrokeWidthAttributeName | ||
atIndex:range.location | ||
effectiveRange:NULL]; | ||
BOOL isFeedbackLink = NO; | ||
if ([strokeWidth floatValue] > 100) { | ||
isFeedbackLink = YES; | ||
[attributedString removeAttribute:NSStrokeWidthAttributeName range:range]; | ||
} | ||
|
||
// Omit whitespace-only strings. | ||
NSAttributedString *title = [[attributedString attributedSubstringFromRange:range] | ||
mgl_attributedStringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; | ||
if (!title.length) { | ||
return; | ||
} | ||
|
||
MGLAttributionInfo *info = [[MGLAttributionInfo alloc] initWithTitle:title URL:value]; | ||
info.feedbackLink = isFeedbackLink; | ||
[infos addObject:info]; | ||
}]; | ||
return infos; | ||
} | ||
|
||
- (instancetype)initWithTitle:(NSAttributedString *)title URL:(NSURL *)URL { | ||
if (self = [super init]) { | ||
_title = title; | ||
_URL = URL; | ||
} | ||
return self; | ||
} | ||
|
||
- (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel { | ||
if (!self.feedbackLink) { | ||
return nil; | ||
} | ||
|
||
NSURLComponents *components = [NSURLComponents componentsWithURL:self.URL resolvingAgainstBaseURL:NO]; | ||
components.fragment = [NSString stringWithFormat:@"/%.5f/%.5f/%i", | ||
centerCoordinate.longitude, centerCoordinate.latitude, (int)round(zoomLevel + 1)]; | ||
return components.URL; | ||
} | ||
|
||
- (BOOL)isEqual:(id)object { | ||
return [object isKindOfClass:[self class]] && [[object title] isEqual:self.title] && [[object URL] isEqual:self.URL]; | ||
} | ||
|
||
- (NSUInteger)hash { | ||
return self.title.hash + self.URL.hash; | ||
} | ||
|
||
/** | ||
Returns whether the given attribution info object overlaps with the receiver by | ||
its plain text title. | ||
@return `NSOrderedAscending` if the given object is a superset of the receiver, | ||
`NSOrderedDescending` if it is a subset of the receiver, or `NSOrderedSame` | ||
if there is no overlap. | ||
*/ | ||
- (NSComparisonResult)subsetCompare:(MGLAttributionInfo *)otherInfo { | ||
NSString *title = self.title.string; | ||
NSString *otherTitle = otherInfo.title.string; | ||
if ([title containsString:otherTitle]) { | ||
return NSOrderedDescending; | ||
} | ||
if ([otherTitle containsString:title]) { | ||
return NSOrderedAscending; | ||
} | ||
return NSOrderedSame; | ||
} | ||
|
||
@end | ||
|
||
@implementation NSMutableArray (MGLAttributionInfoAdditions) | ||
|
||
- (void)growArrayByAddingAttributionInfo:(MGLAttributionInfo *)info { | ||
__block BOOL didInsertInfo = NO; | ||
__block BOOL shouldAddInfo = YES; | ||
[self enumerateObjectsUsingBlock:^(MGLAttributionInfo * _Nonnull existingInfo, NSUInteger idx, BOOL * _Nonnull stop) { | ||
switch ([info subsetCompare:existingInfo]) { | ||
case NSOrderedDescending: | ||
// The existing info object is a subset of the one we’re adding. | ||
// Replace the existing object the first time we find a subset; | ||
// remove the existing object every time after that. | ||
if (didInsertInfo) { | ||
[self removeObjectAtIndex:idx]; | ||
} else { | ||
[self replaceObjectAtIndex:idx withObject:info]; | ||
didInsertInfo = YES; | ||
} | ||
break; | ||
|
||
case NSOrderedAscending: | ||
// The info object we’re adding is a subset of the existing one. | ||
// Don’t add the object and stop looking. | ||
shouldAddInfo = NO; | ||
*stop = YES; | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
}]; | ||
if (shouldAddInfo && !didInsertInfo) { | ||
// No overlapping infos were found, so append the info object. | ||
[self addObject:info]; | ||
} | ||
} | ||
|
||
- (void)growArrayByAddingAttributionInfosFromArray:(NS_ARRAY_OF(MGLAttributionInfo *) *)infos { | ||
for (MGLAttributionInfo *info in infos) { | ||
[self growArrayByAddingAttributionInfo:info]; | ||
} | ||
} | ||
|
||
@end |
Oops, something went wrong.