diff options
Diffstat (limited to 'platform/darwin/src')
-rw-r--r-- | platform/darwin/src/MGLAttributedExpression.h | 44 | ||||
-rw-r--r-- | platform/darwin/src/MGLAttributedExpression.m | 59 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.h | 10 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.mm | 68 |
4 files changed, 180 insertions, 1 deletions
diff --git a/platform/darwin/src/MGLAttributedExpression.h b/platform/darwin/src/MGLAttributedExpression.h new file mode 100644 index 0000000000..aa5d51c66e --- /dev/null +++ b/platform/darwin/src/MGLAttributedExpression.h @@ -0,0 +1,44 @@ +#import "MGLFoundation.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NSString * MGLAttributedExpressionKey NS_EXTENSIBLE_STRING_ENUM; + +FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontNamesAttribute; +FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontSizeAttribute; + +/** + An `MGLAttributedExpression` object associates text formatting attibutes (such as font size or + font names) to an `NSExpression`. + */ +MGL_EXPORT +@interface MGLAttributedExpression : NSObject + +/** + The expression content of the receiver as `NSExpression`. + */ +@property (strong, nonatomic) NSExpression *expression; + +/** + The formatting attributes. + */ +@property (strong, nonatomic, readonly) NSDictionary<MGLAttributedExpressionKey, id> *attributes; + +/** + Returns an `MGLAttributedExpression` object initialized with an expression and no attribute information. + */ +- (instancetype)initWithExpression:(NSExpression *)expression; + +/** + Returns an `MGLAttributedExpression` object initialized with an expression and text format attributes. + */ +- (instancetype)initWithExpression:(NSExpression *)expression attributes:(nullable NSDictionary <MGLAttributedExpressionKey, id> *)attrs; + +/** + Creates an `MGLAttributedExpression` object initialized with an expression and the format attributes for font names and font size. + */ ++ (instancetype)attributedExpression:(NSExpression *)expression fontNames:(nullable NSArray<NSString*> *)fontNames fontSize:(nullable NSNumber *)fontSize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAttributedExpression.m b/platform/darwin/src/MGLAttributedExpression.m new file mode 100644 index 0000000000..715f74e42f --- /dev/null +++ b/platform/darwin/src/MGLAttributedExpression.m @@ -0,0 +1,59 @@ +#import "MGLAttributedExpression.h" +#import "MGLLoggingConfiguration_Private.h" + +const MGLAttributedExpressionKey MGLFontNamesAttribute = @"text-font"; +const MGLAttributedExpressionKey MGLFontSizeAttribute = @"font-scale"; + +@implementation MGLAttributedExpression + +- (instancetype)initWithExpression:(NSExpression *)expression { + self = [self initWithExpression:expression attributes:nil]; + return self; +} + ++ (instancetype)attributedExpression:(NSExpression *)expression fontNames:(nullable NSArray<NSString *> *)fontNames fontSize:(nullable NSNumber *)fontSize { + MGLAttributedExpression *attributedExpression; + + NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; + + if (fontNames && fontNames.count > 0) { + attrs[MGLFontNamesAttribute] = fontNames; + } + + if (fontSize) { + attrs[MGLFontSizeAttribute] = fontSize; + } + + attributedExpression = [[self alloc] initWithExpression:expression attributes:attrs]; + return attributedExpression; +} + +- (instancetype)initWithExpression:(NSExpression *)expression attributes:(NSDictionary<MGLAttributedExpressionKey,id> *)attrs { + if (self = [super init]) + { + MGLLogInfo(@"Starting %@ initialization.", NSStringFromClass([self class])); + _expression = expression; + _attributes = attrs; + + MGLLogInfo(@"Finalizing %@ initialization.", NSStringFromClass([self class])); + } + return self; +} + +- (BOOL)isEqual:(id)object { + BOOL result = NO; + + if ([object isKindOfClass:[self class]]) { + MGLAttributedExpression *otherObject = object; + result = [self.expression isEqual:otherObject.expression] && + [_attributes isEqual:otherObject.attributes]; + } + + return result; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"MGLAttributedExpression<Expression: %@ Attributes: %@>", self.expression, self.attributes]; +} + +@end diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h index 1e6fd6fc46..a19ec1af2e 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.h +++ b/platform/darwin/src/NSExpression+MGLAdditions.h @@ -7,6 +7,8 @@ #import "MGLTypes.h" +@class MGLAttributedExpression; + NS_ASSUME_NONNULL_BEGIN typedef NSString *MGLExpressionInterpolationMode NS_TYPED_ENUM; @@ -150,6 +152,14 @@ FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionI */ + (instancetype)mgl_expressionForMatchingExpression:(nonnull NSExpression *)inputExpression inDictionary:(nonnull NSDictionary<NSExpression *, NSExpression *> *)matchedExpressions defaultExpression:(nonnull NSExpression *)defaultExpression NS_SWIFT_NAME(init(forMGLMatchingKey:in:default:)); +/** + Returns an attributed function expression specifying an `MGLAttributedExpression` constant + expression array. + + @param attributedExpressions The `MGLAttributedExpression` constant expression array. + */ ++ (instancetype)mgl_expressionForAttributedExpressions:(nonnull NSArray<NSExpression *> *)attributedExpressions NS_SWIFT_NAME(init(forAttributedExpressions:)); + #pragma mark Concatenating String Expressions /** diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 6aaba4dd90..c4e2908888 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -11,6 +11,7 @@ #import "NSPredicate+MGLAdditions.h" #import "NSValue+MGLStyleAttributeAdditions.h" #import "MGLVectorTileSource_Private.h" +#import "MGLAttributedExpression.h" #import <objc/runtime.h> @@ -75,6 +76,7 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = INSTALL_METHOD(mgl_atan:); INSTALL_METHOD(mgl_tan:); INSTALL_METHOD(mgl_log2:); + INSTALL_METHOD(mgl_attributed:); // Install functions that resemble control structures, taking arbitrary // numbers of arguments. Vararg aftermarket functions need to be declared @@ -96,6 +98,12 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = return [components componentsJoinedByString:@""]; } +- (NSString *)mgl_attributed:(NSArray<MGLAttributedExpression *> *)attributedExpressions { + [NSException raise:NSInvalidArgumentException + format:@"Text format expressions lack underlying Objective-C implementations."]; + return nil; +} + /** Rounds the given number to the nearest integer. If the number is halfway between two integers, this method rounds it away from zero. @@ -229,7 +237,6 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = return nil; } - /** A placeholder for a catch-all method that evaluates an arbitrary number of arguments as an expression according to the Mapbox Style Specification’s @@ -591,6 +598,10 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = arguments:optionsArray]; } ++ (instancetype)mgl_expressionForAttributedExpressions:(nonnull NSArray<NSExpression *> *)attributedExpressions { + return [NSExpression expressionForFunction:@"mgl_attributed:" arguments:attributedExpressions]; +} + - (instancetype)mgl_expressionByAppendingExpression:(nonnull NSExpression *)expression { NSExpression *subexpression = [NSExpression expressionForAggregate:@[self, expression]]; return [NSExpression expressionForFunction:@"mgl_join:" arguments:@[subexpression]]; @@ -860,6 +871,22 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { return [NSExpression expressionForFunction:@"MGL_MATCH" arguments:optionsArray]; + } else if ([op isEqualToString:@"format"]) { + NSMutableArray *attributedExpressions = [NSMutableArray array]; + + for (NSUInteger index = 0; index < argumentObjects.count; index+=2) { + NSExpression *expression = [NSExpression expressionWithMGLJSONObject:argumentObjects[index]]; + NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; + if ((index + 1) < argumentObjects.count) { + attrs = argumentObjects[index + 1]; + } + + MGLAttributedExpression *attributedExpression = [[MGLAttributedExpression alloc] initWithExpression:expression attributes:attrs]; + + [attributedExpressions addObject:[NSExpression expressionForConstantValue:attributedExpression]]; + } + return [NSExpression expressionForFunction:@"mgl_attributed:" arguments:attributedExpressions]; + } else if ([op isEqualToString:@"coalesce"]) { NSMutableArray *expressions = [NSMutableArray array]; for (id operand in argumentObjects) { @@ -971,6 +998,23 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { return @[@"literal", @[@(mglValue[0]), @(mglValue[1]), @(mglValue[2]), @(mglValue[3])]]; } } + if ([constantValue isKindOfClass:[MGLAttributedExpression class]]) { + MGLAttributedExpression *attributedExpression = (MGLAttributedExpression *)constantValue; + id jsonObject = attributedExpression.expression.mgl_jsonExpressionObject; + NSMutableArray *attributes = [NSMutableArray array]; + if ([jsonObject isKindOfClass:[NSArray class]]) { + [attributes addObjectsFromArray:jsonObject]; + } else { + [attributes addObject:jsonObject]; + } + if (attributedExpression.attributes) { + [attributes addObject:attributedExpression.attributes]; + } else { + [attributes addObject:@{}]; + } + + return attributes; + } return self.constantValue; } @@ -1115,6 +1159,9 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { } [NSException raise:NSInvalidArgumentException format:@"Casting expression to %@ not yet implemented.", type]; + } else if ([function isEqualToString:@"mgl_attributed:"]) { + return [self mgl_jsonFormatExpressionObject]; + } else if ([function isEqualToString:@"MGL_FUNCTION"] || [function isEqualToString:@"MGL_FUNCTION:"]) { NSExpression *firstOp = self.arguments.firstObject; @@ -1363,6 +1410,25 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { return expressionObject; } +- (id)mgl_jsonFormatExpressionObject { + NSArray<NSExpression *> *attributedExpressions; + NSExpression *formatArray = self.arguments.firstObject; + + if ([formatArray respondsToSelector:@selector(constantValue)] && [formatArray.constantValue isKindOfClass:[NSArray class]]) { + attributedExpressions = (NSArray *)formatArray.constantValue; + } else { + attributedExpressions = self.arguments; + } + + NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"format", nil]; + + for (NSUInteger index = 0; index < attributedExpressions.count; index++) { + [expressionObject addObjectsFromArray:attributedExpressions[index].mgl_jsonExpressionObject]; + } + + return expressionObject; +} + #pragma mark Localization /** |