Fixing issue where UIColor with alpha < 1 was being rendered incorrectly (#266)

* Expose new method to get color for pre-multiplied alpha

* Call new method to get pre-multiplied color values

* Fix tests

* Apply fix for macOS

* Update changelogs

* Rever submodule changes

* Add test

* Review comment

* Update platform/ios/CHANGELOG.md

Co-Authored-By: Minh Nguyễn <mxn@1ec5.org>

* Update platform/macos/CHANGELOG.md

Co-Authored-By: Minh Nguyễn <mxn@1ec5.org>

Co-authored-by: Minh Nguyễn <mxn@1ec5.org>
This commit is contained in:
Nishant Karajgikar
2020-04-21 10:04:13 -04:00
committed by GitHub
parent 23b5b46cd4
commit 6c764cbe31
8 changed files with 52 additions and 4 deletions

View File

@@ -308,7 +308,7 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier =
return { (int64_t)number.longLongValue };
}
} else if ([value isKindOfClass:[MGLColor class]]) {
auto hexString = [(MGLColor *)value mgl_color].stringify();
auto hexString = [(MGLColor *)value mgl_colorForPremultipliedValue].stringify();
return { hexString };
} else if (value && value != [NSNull null]) {
[NSException raise:NSInvalidArgumentException
@@ -481,7 +481,7 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier =
@implementation MGLColor (MGLExpressionAdditions)
- (id)mgl_jsonExpressionObject {
auto color = [self mgl_color];
auto color = [self mgl_colorForPremultipliedValue];
if (color.a == 1) {
return @[@"rgb", @(color.r * 255), @(color.g * 255), @(color.b * 255)];
}
@@ -1019,7 +1019,7 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
return @[@"literal", collection];
}
if ([constantValue isKindOfClass:[MGLColor class]]) {
auto color = [constantValue mgl_color];
auto color = [constantValue mgl_colorForPremultipliedValue];
if (color.a == 1) {
return @[@"rgb", @(color.r * 255), @(color.g * 255), @(color.b * 255)];
}

View File

@@ -296,10 +296,23 @@ using namespace std::string_literals;
float blue = (213.0 * alpha) / 255;
MGLColor *color = [MGLColor mgl_colorWithColor:{ red, green, blue, alpha }]; // papayawhip
NSExpression *expression = [NSExpression expressionForConstantValue:color];
NSArray *jsonExpression = @[@"rgba", @127.5, @119.5, @106.5, @0.5];
NSArray *jsonExpression = @[@"rgba", @255.0, @239.0, @213.0, @0.5];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], color);
}
{
// Transform color components to non-premultiplied values
NSArray *jsonExpression = @[@"rgba", @255.0, @239.0, @213.0, @0.5];
NSExpression *papayawhipExpression = [NSExpression expressionWithMGLJSONObject:jsonExpression];
MGLColor *papayaWhipColor = [papayawhipExpression expressionValueWithObject:nil context:nil];
CGFloat convertedRed = 0.0, convertedGreen = 0.0, convertedBlue = 0.0, convertedAlpha = 0.0;
[papayaWhipColor getRed:&convertedRed green:&convertedGreen blue:&convertedBlue alpha:&convertedAlpha];
XCTAssertEqualWithAccuracy(convertedRed, 255.0/255.0, 0.0000001);
XCTAssertEqualWithAccuracy(convertedGreen, 239.0/255.0, 0.0000001);
XCTAssertEqualWithAccuracy(convertedBlue, 213.0/255.0, 0.0000001);
XCTAssertEqual(convertedAlpha, 0.5);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"noindex(513)"];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @513);

View File

@@ -2,6 +2,12 @@
Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started.
## 5.9.0
### Styles and rendering
* Fixed an issue where properties such as `MGLFillStyleLayer.fillColor` and `MGLLineStyleLayer.lineColor` misinterpreted non-opaque `UIColor`s. ([#266](https://github.com/mapbox/mapbox-gl-native-ios/pull/266))
## 5.8.0
### Styles and rendering

View File

@@ -9,6 +9,8 @@
- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue;
- (mbgl::Color)mgl_colorForPremultipliedValue;
+ (UIColor *)mgl_colorWithColor:(mbgl::Color)color;
@end

View File

@@ -12,6 +12,14 @@
return { static_cast<float>(r*a), static_cast<float>(g*a), static_cast<float>(b*a), static_cast<float>(a) };
}
// Intended to be used when providing colors on the basis of an NSExpression
- (mbgl::Color)mgl_colorForPremultipliedValue
{
CGFloat r, g, b, a;
[self getRed:&r green:&g blue:&b alpha:&a];
return { static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a) };
}
- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue
{
mbgl::Color color = self.mgl_color;

View File

@@ -23,6 +23,7 @@
* Fixed an issue where style layers backed by a shape source could flicker when transitioning between styles. ([#15907](https://github.com/mapbox/mapbox-gl-native/pull/15907), [#15941](https://github.com/mapbox/mapbox-gl-native/pull/15941))
* Improved the performance of loading a style that has many style images. ([#16187](https://github.com/mapbox/mapbox-gl-native/pull/16187))
* Updated “map ID” to the more accurate term “tileset ID” in documentation; updated “style's Map ID” to the more accurate term “style URL”. ([#15116](https://github.com/mapbox/mapbox-gl-native/pull/15116))
* Fixed an issue where properties such as `MGLFillStyleLayer.fillColor` and `MGLLineStyleLayer.lineColor` misinterpreted non-opaque `NSColor`s. ([#266](https://github.com/mapbox/mapbox-gl-native-ios/pull/266))
### Camera

View File

@@ -10,6 +10,8 @@
*/
- (mbgl::Color)mgl_color;
- (mbgl::Color)mgl_colorForPremultipliedValue;
/**
Instantiates `NSColor` from an `mbgl::Color`
*/

View File

@@ -21,6 +21,22 @@
return { static_cast<float>(r*a), static_cast<float>(g*a), static_cast<float>(b*a), static_cast<float>(a) };
}
- (mbgl::Color)mgl_colorForPremultipliedValue {
CGFloat r, g, b, a;
// The Mapbox Style Specification does not specify a color space, but it is
// assumed to be sRGB for consistency with CSS.
NSColor *srgbColor = self;
if ([NSColor redColor].colorSpaceName == NSCalibratedRGBColorSpace) {
srgbColor = [srgbColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
} else {
srgbColor = [srgbColor colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
}
[srgbColor getRed:&r green:&g blue:&b alpha:&a];
return { static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a) };
}
+ (NSColor *)mgl_colorWithColor:(mbgl::Color)color {
// If there is no alpha value, return original color values.
if (color.a == 0.0f) {