[darwin] Bindings for new 'text-writing-mode' layout property

This commit is contained in:
Alexander Shalamov
2019-06-18 14:41:46 +03:00
parent dad43ba8fc
commit f944600413
6 changed files with 189 additions and 5 deletions

View File

@@ -79,6 +79,28 @@ global.camelizeWithLeadingLowercase = function (str) {
});
};
// Returns true only if property is an enum or if it is an array
// property with uniquely defined enum.
global.definesEnum = function(property, allProperties) {
if (property.type === "enum") {
return true;
}
if (property.type === 'array' && property.value === 'enum') {
const uniqueArrayEnum = (prop, enums) => {
if (prop.value !== 'enum') return false;
const enumsEqual = (val1, val2) => val1.length === val1.length && val1.every((val, i) => val === val2[i]);
return enums.filter(e => enumsEqual(Object.keys(prop.values).sort(), Object.keys(e.values).sort())).length == 0;
};
const allEnumProperties = _(allProperties).filter({'type': 'enum'}).value();
const uniqueArrayEnumProperties = _(allProperties).filter({'type': 'array'}).filter(prop => uniqueArrayEnum(prop, allEnumProperties)).value();
return _(uniqueArrayEnumProperties).filter({'name': property.name}).value().length != 0;
}
return false;
}
global.objCName = function (property) {
return camelizeWithLeadingLowercase(property.name);
};
@@ -144,6 +166,8 @@ global.objCTestValue = function (property, layerType, arraysAsStructs, indent) {
}
case 'anchor':
return `@"{'top','bottom'}"`;
case 'mode':
return `@"{'horizontal','vertical'}"`;
default:
throw new Error(`unknown array type for ${property.name}`);
}
@@ -194,6 +218,8 @@ global.mbglTestValue = function (property, layerType) {
return '{ 1, 1 }';
case 'anchor':
return '{ mbgl::style::SymbolAnchorType::Top, mbgl::style::SymbolAnchorType::Bottom }';
case 'mode':
return '{ mbgl::style::TextWritingModeType::Horizontal, mbgl::style::TextWritingModeType::Vertical }';
default:
throw new Error(`unknown array type for ${property.name}`);
}
@@ -213,6 +239,8 @@ global.mbglExpressionTestValue = function (property, layerType) {
switch (arrayType(property)) {
case 'anchor':
return `{"top", "bottom"}`;
case 'mode':
return `{"horizontal", "vertical"}`;
default:
break;
}
@@ -439,6 +467,8 @@ global.describeType = function (property) {
return '`MGLSphericalPosition`';
case 'anchor':
return '`MGLTextAnchor` array';
case 'mode':
return '`MGLTextWritingMode` array';
default:
return 'array';
}
@@ -568,6 +598,7 @@ global.propertyType = function (property) {
case 'translate':
return 'NSValue *';
case 'anchor':
case 'mode':
return 'NSArray<NSValue *> *';
default:
throw new Error(`unknown array type for ${property.name}`);
@@ -615,6 +646,8 @@ global.valueTransformerArguments = function (property) {
return ['std::array<float, 2>', objCType];
case 'anchor':
return ['std::vector<mbgl::style::SymbolAnchorType>', objCType, 'mbgl::style::SymbolAnchorType', 'MGLTextAnchor'];
case 'mode':
return ['std::vector<mbgl::style::TextWritingModeType>', objCType, 'mbgl::style::TextWritingModeType', 'MGLTextWritingMode'];
default:
throw new Error(`unknown array type for ${property.name}`);
}
@@ -666,6 +699,8 @@ global.mbglType = function(property) {
return 'mbgl::style::Position';
case 'anchor':
return 'std::vector<mbgl::style::SymbolAnchorType>';
case 'mode':
return 'std::vector<mbgl::style::TextWritingModeType>';
default:
throw new Error(`unknown array type for ${property.name}`);
}
@@ -773,7 +808,7 @@ var renamedPropertiesByLayerType = {};
for (var layer of layers) {
layer.properties = _.concat(layer.layoutProperties, layer.paintProperties);
let enumProperties = _.filter(layer.properties, prop => prop.type === 'enum');
let enumProperties = _.filter(layer.properties, prop => definesEnum(prop, layer.properties));
if (enumProperties.length) {
layer.enumProperties = enumProperties;
}

View File

@@ -19,7 +19,7 @@
NS_ASSUME_NONNULL_BEGIN
<% for (const property of layoutProperties) { -%>
<% if (property.type == "enum") { -%>
<% if (definesEnum(property, layoutProperties)) { -%>
/**
<%- propertyDoc(property.name, property, type, 'enum').wrap(80, 1) %>
@@ -38,7 +38,7 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(property.name) %>) {
<% } -%>
<% } -%>
<% for (const property of paintProperties) { -%>
<% if (property.type == "enum") { -%>
<% if (definesEnum(property, paintProperties)) { -%>
/**
<%- propertyDoc(property.name, property, type, 'enum').wrap(80, 1) %>

View File

@@ -25,7 +25,7 @@ namespace mbgl {
<% if (layoutProperties.length) { -%>
<% for (const property of layoutProperties) { -%>
<% if (property.type == "enum") { -%>
<% if (definesEnum(property, layoutProperties)) { -%>
MBGL_DEFINE_ENUM(MGL<%- camelize(property.name) %>, {
<% for (const value in property.values) { -%>
{ MGL<%- camelize(property.name) %><%- camelize(value) %>, "<%-value%>" },
@@ -37,7 +37,7 @@ namespace mbgl {
<% } -%>
<% if (paintProperties.length) { -%>
<% for (const property of paintProperties) { -%>
<% if (property.type == "enum") { -%>
<% if (definesEnum(property, paintProperties)) { -%>
MBGL_DEFINE_ENUM(MGL<%- camelize(property.name) %>, {
<% for (const value in property.values) { -%>
{ MGL<%- camelize(property.name) %><%- camelize(value) %>, "<%-value%>" },

View File

@@ -316,6 +316,30 @@ typedef NS_ENUM(NSUInteger, MGLTextTransform) {
MGLTextTransformLowercase,
};
/**
The property allows to control an orientation of a symbol. Note, that the
property values act as a hint, so that Symbols whose language doesn't support
provided orientation, will be laid out in their natural orientation. Example:
English point symbol will be rendered horizontally even if `"textWritingMode":
["vertical"]` is set. The order of elements in an array define priority order
for the placement of an orientation variant.
Values of this type are used in the `MGLSymbolStyleLayer.textWritingMode`
property.
*/
typedef NS_ENUM(NSUInteger, MGLTextWritingMode) {
/**
If a text's language supports horizontal writing mode, symbols with point
placement would be laid out horizontally.
*/
MGLTextWritingModeHorizontal,
/**
If a text's language supports vertical writing mode, symbols with point
placement would be laid out vertically.
*/
MGLTextWritingModeVertical,
};
/**
Controls the frame of reference for `MGLSymbolStyleLayer.iconTranslation`.
@@ -1646,6 +1670,38 @@ MGL_EXPORT
*/
@property (nonatomic, null_resettable) NSExpression *textVariableAnchor;
/**
The property allows to control an orientation of a symbol. Note, that the
property values act as a hint, so that Symbols whose language doesn't support
provided orientation, will be laid out in their natural orientation. Example:
English point symbol will be rendered horizontally even if `"textWritingMode":
["vertical"]` is set. The order of elements in an array define priority order
for the placement of an orientation variant.
This property is only applied to the style if `text` is non-`nil`, and
`symbolPlacement` is set to an expression that evaluates to or
`MGLSymbolPlacementPoint`. Otherwise, it is ignored.
You can set this property to an expression containing any of the following:
* Constant `MGLTextWritingMode` array values
* Constant array, whose each element is any of the following constant string
values:
* `horizontal`: If a text's language supports horizontal writing mode,
symbols with point placement would be laid out horizontally.
* `vertical`: If a text's language supports vertical writing mode, symbols
with point placement would be laid out vertically.
* Predefined functions, including mathematical and string operators
* Conditional expressions
* Variable assignments and references to assigned variables
* Step functions applied to the `$zoomLevel` variable
This property does not support applying interpolation functions to the
`$zoomLevel` variable or applying interpolation or step functions to feature
attributes.
*/
@property (nonatomic, null_resettable) NSExpression *textWritingMode;
#pragma mark - Accessing the Paint Attributes
#if TARGET_OS_IPHONE
@@ -2382,6 +2438,19 @@ MGL_EXPORT
*/
@property (readonly) MGLTextTransform MGLTextTransformValue;
/**
Creates a new value object containing the given `MGLTextWritingMode` enumeration.
@param textWritingMode The value for the new object.
@return A new value object that contains the enumeration value.
*/
+ (instancetype)valueWithMGLTextWritingMode:(MGLTextWritingMode)textWritingMode;
/**
The `MGLTextWritingMode` enumeration representation of the value.
*/
@property (readonly) MGLTextWritingMode MGLTextWritingModeValue;
/**
Creates a new value object containing the given `MGLIconTranslationAnchor` enumeration.

View File

@@ -96,6 +96,11 @@ namespace mbgl {
{ MGLTextTransformLowercase, "lowercase" },
});
MBGL_DEFINE_ENUM(MGLTextWritingMode, {
{ MGLTextWritingModeHorizontal, "horizontal" },
{ MGLTextWritingModeVertical, "vertical" },
});
MBGL_DEFINE_ENUM(MGLIconTranslationAnchor, {
{ MGLIconTranslationAnchorMap, "map" },
{ MGLIconTranslationAnchorViewport, "viewport" },
@@ -1023,6 +1028,24 @@ namespace mbgl {
return MGLStyleValueTransformer<std::vector<mbgl::style::SymbolAnchorType>, NSArray<NSValue *> *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toExpression(propertyValue);
}
- (void)setTextWritingMode:(NSExpression *)textWritingMode {
MGLAssertStyleLayerIsValid();
MGLLogDebug(@"Setting textWritingMode: %@", textWritingMode);
auto mbglValue = MGLStyleValueTransformer<std::vector<mbgl::style::TextWritingModeType>, NSArray<NSValue *> *, mbgl::style::TextWritingModeType, MGLTextWritingMode>().toPropertyValue<mbgl::style::PropertyValue<std::vector<mbgl::style::TextWritingModeType>>>(textWritingMode, false);
self.rawLayer->setTextWritingMode(mbglValue);
}
- (NSExpression *)textWritingMode {
MGLAssertStyleLayerIsValid();
auto propertyValue = self.rawLayer->getTextWritingMode();
if (propertyValue.isUndefined()) {
propertyValue = self.rawLayer->getDefaultTextWritingMode();
}
return MGLStyleValueTransformer<std::vector<mbgl::style::TextWritingModeType>, NSArray<NSValue *> *, mbgl::style::TextWritingModeType, MGLTextWritingMode>().toExpression(propertyValue);
}
#pragma mark - Accessing the Paint Attributes
- (void)setIconColor:(NSExpression *)iconColor {
@@ -1599,6 +1622,16 @@ namespace mbgl {
return textTransform;
}
+ (NSValue *)valueWithMGLTextWritingMode:(MGLTextWritingMode)textWritingMode {
return [NSValue value:&textWritingMode withObjCType:@encode(MGLTextWritingMode)];
}
- (MGLTextWritingMode)MGLTextWritingModeValue {
MGLTextWritingMode textWritingMode;
[self getValue:&textWritingMode];
return textWritingMode;
}
+ (NSValue *)valueWithMGLIconTranslationAnchor:(MGLIconTranslationAnchor)iconTranslationAnchor {
return [NSValue value:&iconTranslationAnchor withObjCType:@encode(MGLIconTranslationAnchor)];
}

View File

@@ -2074,6 +2074,50 @@
XCTAssertThrowsSpecificNamed(layer.textVariableAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes.");
}
// text-writing-mode
{
XCTAssertTrue(rawLayer->getTextWritingMode().isUndefined(),
@"text-writing-mode should be unset initially.");
NSExpression *defaultExpression = layer.textWritingMode;
NSExpression *constantExpression = [NSExpression expressionWithFormat:@"{'horizontal','vertical'}"];
layer.textWritingMode = constantExpression;
mbgl::style::PropertyValue<std::vector<mbgl::style::TextWritingModeType>> propertyValue = { { mbgl::style::TextWritingModeType::Horizontal, mbgl::style::TextWritingModeType::Vertical } };
XCTAssertEqual(rawLayer->getTextWritingMode(), propertyValue,
@"Setting textWritingMode to a constant value expression should update text-writing-mode.");
XCTAssertEqualObjects(layer.textWritingMode, constantExpression,
@"textWritingMode should round-trip constant value expressions.");
constantExpression = [NSExpression expressionWithFormat:@"{'horizontal','vertical'}"];
NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}];
layer.textWritingMode = functionExpression;
{
using namespace mbgl::style::expression::dsl;
propertyValue = mbgl::style::PropertyExpression<std::vector<mbgl::style::TextWritingModeType>>(
step(zoom(), literal({"horizontal", "vertical"}), 18.0, literal({"horizontal", "vertical"}))
);
}
XCTAssertEqual(rawLayer->getTextWritingMode(), propertyValue,
@"Setting textWritingMode to a camera expression should update text-writing-mode.");
XCTAssertEqualObjects(layer.textWritingMode, functionExpression,
@"textWritingMode should round-trip camera expressions.");
layer.textWritingMode = nil;
XCTAssertTrue(rawLayer->getTextWritingMode().isUndefined(),
@"Unsetting textWritingMode should return text-writing-mode to the default value.");
XCTAssertEqualObjects(layer.textWritingMode, defaultExpression,
@"textWritingMode should return the default value after being unset.");
functionExpression = [NSExpression expressionForKeyPath:@"bogus"];
XCTAssertThrowsSpecificNamed(layer.textWritingMode = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes.");
functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}];
functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}];
XCTAssertThrowsSpecificNamed(layer.textWritingMode = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes.");
}
// icon-color
{
XCTAssertTrue(rawLayer->getIconColor().isUndefined(),
@@ -3084,6 +3128,7 @@
[self testPropertyName:@"text-rotation-alignment" isBoolean:NO];
[self testPropertyName:@"text-transform" isBoolean:NO];
[self testPropertyName:@"text-variable-anchor" isBoolean:NO];
[self testPropertyName:@"text-writing-mode" isBoolean:NO];
[self testPropertyName:@"icon-color" isBoolean:NO];
[self testPropertyName:@"icon-halo-blur" isBoolean:NO];
[self testPropertyName:@"icon-halo-color" isBoolean:NO];
@@ -3148,6 +3193,8 @@
XCTAssertEqual([NSValue valueWithMGLTextTransform:MGLTextTransformNone].MGLTextTransformValue, MGLTextTransformNone);
XCTAssertEqual([NSValue valueWithMGLTextTransform:MGLTextTransformUppercase].MGLTextTransformValue, MGLTextTransformUppercase);
XCTAssertEqual([NSValue valueWithMGLTextTransform:MGLTextTransformLowercase].MGLTextTransformValue, MGLTextTransformLowercase);
XCTAssertEqual([NSValue valueWithMGLTextWritingMode:MGLTextWritingModeHorizontal].MGLTextWritingModeValue, MGLTextWritingModeHorizontal);
XCTAssertEqual([NSValue valueWithMGLTextWritingMode:MGLTextWritingModeVertical].MGLTextWritingModeValue, MGLTextWritingModeVertical);
XCTAssertEqual([NSValue valueWithMGLIconTranslationAnchor:MGLIconTranslationAnchorMap].MGLIconTranslationAnchorValue, MGLIconTranslationAnchorMap);
XCTAssertEqual([NSValue valueWithMGLIconTranslationAnchor:MGLIconTranslationAnchorViewport].MGLIconTranslationAnchorValue, MGLIconTranslationAnchorViewport);
XCTAssertEqual([NSValue valueWithMGLTextTranslationAnchor:MGLTextTranslationAnchorMap].MGLTextTranslationAnchorValue, MGLTextTranslationAnchorMap);