diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2018-03-06 02:14:20 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2018-03-30 03:29:44 -0700 |
commit | 0595b4f1fdf9d2c65e8d9407b45a2a1c262c4d71 (patch) | |
tree | cd2709f9932a26ffd0c4635f19247813910c9c43 | |
parent | 07726c8e9b763248696ecacd5eae363debf8581b (diff) | |
download | qtlocation-mapboxgl-0595b4f1fdf9d2c65e8d9407b45a2a1c262c4d71.tar.gz |
[ios, macos] More robust color conversion
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.mm | 13 | ||||
-rw-r--r-- | platform/ios/src/UIColor+MGLAdditions.mm | 39 | ||||
-rw-r--r-- | platform/macos/src/NSColor+MGLAdditions.mm | 47 |
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 |