Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[ios, macos] More robust color conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
1ec5 committed Mar 6, 2018
1 parent 69c3618 commit b9575c1
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 14 deletions.
13 changes: 3 additions & 10 deletions platform/darwin/src/NSExpression+MGLAdditions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -672,16 +672,9 @@ - (id)mgl_jsonExpressionObject {
}];
[expressionObject addObject:self.operand.mgl_jsonExpressionObject];
return expressionObject;
} 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:"] ||
Expand Down
39 changes: 37 additions & 2 deletions platform/ios/src/UIColor+MGLAdditions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,48 @@ + (UIColor *)mgl_colorWithColor:(mbgl::Color)color
@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
47 changes: 45 additions & 2 deletions platform/macos/src/NSColor+MGLAdditions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,56 @@ + (NSColor *)mgl_colorWithColor:(mbgl::Color)color
@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

0 comments on commit b9575c1

Please sign in to comment.