summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/MGLAttributedExpression.h44
-rw-r--r--platform/darwin/src/MGLAttributedExpression.m59
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.h10
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm68
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
/**