summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2018-03-06 02:14:20 -0800
committerMinh Nguyễn <mxn@1ec5.org>2018-03-30 03:29:44 -0700
commit0595b4f1fdf9d2c65e8d9407b45a2a1c262c4d71 (patch)
treecd2709f9932a26ffd0c4635f19247813910c9c43
parent07726c8e9b763248696ecacd5eae363debf8581b (diff)
downloadqtlocation-mapboxgl-0595b4f1fdf9d2c65e8d9407b45a2a1c262c4d71.tar.gz
[ios, macos] More robust color conversion
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm13
-rw-r--r--platform/ios/src/UIColor+MGLAdditions.mm39
-rw-r--r--platform/macos/src/NSColor+MGLAdditions.mm47
3 files changed, 85 insertions, 14 deletions
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 8108ddb7b9..2bdebc89bb 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -901,16 +901,9 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
format:@"Casting expression to %@ not yet implemented.", type];
} else if ([function isEqualToString:@"MGL_FUNCTION"]) {
return self.arguments.mgl_jsonExpressionObject;
- } else if (op == [MGLColor class]) {
- if ([function isEqualToString:@"colorWithRed:green:blue:"]
- || [function isEqualToString:@"colorWithCalibratedRed:green:blue:"]) {
- NSArray *arguments = self.arguments.mgl_jsonExpressionObject;
- return [@[@"rgb"] arrayByAddingObjectsFromArray:arguments];
- } else if ([function isEqualToString:@"colorWithRed:green:blue:alpha:"]
- || [function isEqualToString:@"colorWithCalibratedRed:green:blue:alpha:"]) {
- NSArray *arguments = self.arguments.mgl_jsonExpressionObject;
- return [@[@"rgba"] arrayByAddingObjectsFromArray:arguments];
- }
+ } else if (op == [MGLColor class] && [function isEqualToString:@"colorWithRed:green:blue:alpha:"]) {
+ NSArray *arguments = self.arguments.mgl_jsonExpressionObject;
+ return [@[@"rgba"] arrayByAddingObjectsFromArray:arguments];
} else if ([function isEqualToString:@"median:"] ||
[function isEqualToString:@"mode:"] ||
[function isEqualToString:@"stddev:"] ||
diff --git a/platform/ios/src/UIColor+MGLAdditions.mm b/platform/ios/src/UIColor+MGLAdditions.mm
index 2b8dfb0446..9ca39acda4 100644
--- a/platform/ios/src/UIColor+MGLAdditions.mm
+++ b/platform/ios/src/UIColor+MGLAdditions.mm
@@ -25,13 +25,48 @@
@implementation NSExpression (MGLColorAdditions)
+ (NSExpression *)mgl_expressionForRGBComponents:(NSArray<NSExpression *> *)components {
+ if (UIColor *color = [self mgl_colorWithRGBComponents:components]) {
+ return [NSExpression expressionForConstantValue:color];
+ }
+
NSExpression *color = [NSExpression expressionForConstantValue:[UIColor class]];
- return [NSExpression expressionForFunction:color selectorName:@"colorWithRed:green:blue:" arguments:components];
+ NSExpression *alpha = [NSExpression expressionForConstantValue:@1.0];
+ return [NSExpression expressionForFunction:color
+ selectorName:@"colorWithRed:green:blue:alpha:"
+ arguments:[components arrayByAddingObject:alpha]];
}
+ (NSExpression *)mgl_expressionForRGBAComponents:(NSArray<NSExpression *> *)components {
+ if (UIColor *color = [self mgl_colorWithRGBComponents:components]) {
+ return [NSExpression expressionForConstantValue:color];
+ }
+
NSExpression *color = [NSExpression expressionForConstantValue:[UIColor class]];
- return [NSExpression expressionForFunction:color selectorName:@"colorWithRed:green:blue:alpha:" arguments:components];
+ return [NSExpression expressionForFunction:color
+ selectorName:@"colorWithRed:green:blue:alpha:"
+ arguments:components];
+}
+
++ (UIColor *)mgl_colorWithRGBComponents:(NSArray<NSExpression *> *)components {
+ if (components.count < 3 || components.count > 4) {
+ return nil;
+ }
+
+ for (NSExpression *component in components) {
+ if (component.expressionType != NSConstantValueExpressionType) {
+ return nil;
+ }
+
+ NSNumber *number = (NSNumber *)component.constantValue;
+ if (![number isKindOfClass:[NSNumber class]]) {
+ return nil;
+ }
+ }
+
+ return [UIColor colorWithRed:[components[0].constantValue doubleValue] / 255.0
+ green:[components[1].constantValue doubleValue] / 255.0
+ blue:[components[2].constantValue doubleValue] / 255.0
+ alpha:components.count == 3 ? [components[3].constantValue doubleValue] : 1.0];
}
@end
diff --git a/platform/macos/src/NSColor+MGLAdditions.mm b/platform/macos/src/NSColor+MGLAdditions.mm
index e80a2910f8..4ffc1ef0b2 100644
--- a/platform/macos/src/NSColor+MGLAdditions.mm
+++ b/platform/macos/src/NSColor+MGLAdditions.mm
@@ -37,13 +37,56 @@
@implementation NSExpression (MGLColorAdditions)
+ (NSExpression *)mgl_expressionForRGBComponents:(NSArray<NSExpression *> *)components {
+ if (NSColor *color = [self mgl_colorWithComponentExpressions:components]) {
+ return [NSExpression expressionForConstantValue:color];
+ }
+
NSExpression *color = [NSExpression expressionForConstantValue:[NSColor class]];
- return [NSExpression expressionForFunction:color selectorName:@"colorWithCalibratedRed:green:blue:" arguments:components];
+ NSExpression *alpha = [NSExpression expressionForConstantValue:@1.0];
+ return [NSExpression expressionForFunction:color
+ selectorName:@"colorWithRed:green:blue:alpha:"
+ arguments:[components arrayByAddingObject:alpha]];
}
+ (NSExpression *)mgl_expressionForRGBAComponents:(NSArray<NSExpression *> *)components {
+ if (NSColor *color = [self mgl_colorWithComponentExpressions:components]) {
+ return [NSExpression expressionForConstantValue:color];
+ }
+
NSExpression *color = [NSExpression expressionForConstantValue:[NSColor class]];
- return [NSExpression expressionForFunction:color selectorName:@"colorWithCalibratedRed:green:blue:alpha:" arguments:components];
+ return [NSExpression expressionForFunction:color
+ selectorName:@"colorWithRed:green:blue:alpha:"
+ arguments:components];
+}
+
+/**
+ Returns a color object corresponding to the given component expressions.
+ */
++ (NSColor *)mgl_colorWithComponentExpressions:(NSArray<NSExpression *> *)componentExpressions {
+ // Map the component expressions to constant components. If any component is
+ // a non-constant expression, the components cannot be converted into a
+ // constant color value.
+ std::vector<CGFloat> components;
+ for (NSExpression *componentExpression in componentExpressions) {
+ if (componentExpression.expressionType != NSConstantValueExpressionType) {
+ return nil;
+ }
+
+ NSNumber *component = (NSNumber *)componentExpression.constantValue;
+ if (![component isKindOfClass:[NSNumber class]]) {
+ return nil;
+ }
+
+ components.push_back(component.doubleValue / 255.0);
+ }
+ // Alpha
+ components.back() *= 255.0;
+
+ // The Mapbox Style Specification does not specify a color space, but it is
+ // assumed to be sRGB for consistency with CSS.
+ return [NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace]
+ components:&components[0]
+ count:components.size()];
}
@end