From 69b52367d35616850b73b03f807ab5c0747c5187 Mon Sep 17 00:00:00 2001 From: Asheem Mamoowala Date: Fri, 25 Aug 2017 16:11:24 -0700 Subject: [core][ios][macos][android]DDS-ify `text-letter-spacing` and `text-max-width` --- .../style/conversion/make_property_setters.hpp | 4 +- include/mbgl/style/layers/symbol_layer.hpp | 12 +- .../mapboxsdk/style/layers/PropertyFactory.java | 12 +- .../mapboxsdk/testapp/style/SymbolLayerTest.java | 266 +++++++++++++++++++++ platform/darwin/src/MGLSymbolStyleLayer.h | 18 ++ platform/darwin/src/MGLSymbolStyleLayer.mm | 12 +- platform/darwin/test/MGLSymbolStyleLayerTests.mm | 60 ++++- platform/node/test/ignores.json | 4 - src/mbgl/layout/symbol_layout.cpp | 4 +- src/mbgl/style/layers/symbol_layer.cpp | 12 +- src/mbgl/style/layers/symbol_layer_properties.hpp | 4 +- 11 files changed, 362 insertions(+), 46 deletions(-) diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp index ef96f534a9..59b0e7be32 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp +++ b/include/mbgl/style/conversion/make_property_setters.hpp @@ -52,9 +52,9 @@ auto makeLayoutPropertySetters() { result["text-field"] = &setProperty, &SymbolLayer::setTextField>; result["text-font"] = &setProperty>, &SymbolLayer::setTextFont>; result["text-size"] = &setProperty, &SymbolLayer::setTextSize>; - result["text-max-width"] = &setProperty, &SymbolLayer::setTextMaxWidth>; + result["text-max-width"] = &setProperty, &SymbolLayer::setTextMaxWidth>; result["text-line-height"] = &setProperty, &SymbolLayer::setTextLineHeight>; - result["text-letter-spacing"] = &setProperty, &SymbolLayer::setTextLetterSpacing>; + result["text-letter-spacing"] = &setProperty, &SymbolLayer::setTextLetterSpacing>; result["text-justify"] = &setProperty, &SymbolLayer::setTextJustify>; result["text-anchor"] = &setProperty, &SymbolLayer::setTextAnchor>; result["text-max-angle"] = &setProperty, &SymbolLayer::setTextMaxAngle>; diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index 2d5123573f..a72baa0b4e 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -126,17 +126,17 @@ public: DataDrivenPropertyValue getTextSize() const; void setTextSize(DataDrivenPropertyValue); - static PropertyValue getDefaultTextMaxWidth(); - PropertyValue getTextMaxWidth() const; - void setTextMaxWidth(PropertyValue); + static DataDrivenPropertyValue getDefaultTextMaxWidth(); + DataDrivenPropertyValue getTextMaxWidth() const; + void setTextMaxWidth(DataDrivenPropertyValue); static PropertyValue getDefaultTextLineHeight(); PropertyValue getTextLineHeight() const; void setTextLineHeight(PropertyValue); - static PropertyValue getDefaultTextLetterSpacing(); - PropertyValue getTextLetterSpacing() const; - void setTextLetterSpacing(PropertyValue); + static DataDrivenPropertyValue getDefaultTextLetterSpacing(); + DataDrivenPropertyValue getTextLetterSpacing() const; + void setTextLetterSpacing(DataDrivenPropertyValue); static DataDrivenPropertyValue getDefaultTextJustify(); DataDrivenPropertyValue getTextJustify() const; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java index 3e90605a92..d4ddbe48ef 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java @@ -2057,11 +2057,11 @@ public class PropertyFactory { /** * The maximum line width for text wrapping. * - * @param the zoom parameter type - * @param function a wrapper {@link CameraFunction} for Float + * @param the function input type + * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static PropertyValue> textMaxWidth(CameraFunction function) { + public static PropertyValue> textMaxWidth(Function function) { return new LayoutPropertyValue<>("text-max-width", function); } @@ -2103,11 +2103,11 @@ public class PropertyFactory { /** * Text tracking amount. * - * @param the zoom parameter type - * @param function a wrapper {@link CameraFunction} for Float + * @param the function input type + * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static PropertyValue> textLetterSpacing(CameraFunction function) { + public static PropertyValue> textLetterSpacing(Function function) { return new LayoutPropertyValue<>("text-letter-spacing", function); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java index 1c9faeb9ea..f8248ae4a7 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java @@ -1846,6 +1846,139 @@ public class SymbolLayerTest extends BaseActivityTest { }); } + @Test + public void testTextMaxWidthAsIdentitySourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-max-width"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textMaxWidth(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getTextMaxWidth()); + assertNotNull(layer.getTextMaxWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getTextMaxWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextMaxWidth().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextMaxWidth().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testTextMaxWidthAsExponentialSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-max-width"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textMaxWidth( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textMaxWidth(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getTextMaxWidth()); + assertNotNull(layer.getTextMaxWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getTextMaxWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextMaxWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextMaxWidth().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testTextMaxWidthAsCategoricalSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-max-width"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textMaxWidth( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textMaxWidth(0.3f)) + ) + ).withDefaultValue(textMaxWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextMaxWidth()); + assertNotNull(layer.getTextMaxWidth().getFunction()); + assertEquals(SourceFunction.class, layer.getTextMaxWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextMaxWidth().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextMaxWidth().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextMaxWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextMaxWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextMaxWidth().getFunction()).getDefaultValue().getValue()); + } + }); + + } + + @Test + public void testTextMaxWidthAsCompositeFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-max-width"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textMaxWidth( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textMaxWidth(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textMaxWidth(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextMaxWidth()); + assertNotNull(layer.getTextMaxWidth().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextMaxWidth().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextMaxWidth().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextMaxWidth().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextMaxWidth().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextMaxWidth().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); + } + @Test public void testTextLineHeightAsConstant() { validateTestSetup(); @@ -1944,6 +2077,139 @@ public class SymbolLayerTest extends BaseActivityTest { }); } + @Test + public void testTextLetterSpacingAsIdentitySourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-letter-spacing"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textLetterSpacing(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getTextLetterSpacing()); + assertNotNull(layer.getTextLetterSpacing().getFunction()); + assertEquals(SourceFunction.class, layer.getTextLetterSpacing().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextLetterSpacing().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextLetterSpacing().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testTextLetterSpacingAsExponentialSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-letter-spacing"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textLetterSpacing( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textLetterSpacing(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getTextLetterSpacing()); + assertNotNull(layer.getTextLetterSpacing().getFunction()); + assertEquals(SourceFunction.class, layer.getTextLetterSpacing().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextLetterSpacing().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextLetterSpacing().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testTextLetterSpacingAsCategoricalSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-letter-spacing"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textLetterSpacing( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textLetterSpacing(0.3f)) + ) + ).withDefaultValue(textLetterSpacing(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextLetterSpacing()); + assertNotNull(layer.getTextLetterSpacing().getFunction()); + assertEquals(SourceFunction.class, layer.getTextLetterSpacing().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextLetterSpacing().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextLetterSpacing().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextLetterSpacing().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextLetterSpacing().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextLetterSpacing().getFunction()).getDefaultValue().getValue()); + } + }); + + } + + @Test + public void testTextLetterSpacingAsCompositeFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-letter-spacing"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textLetterSpacing( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textLetterSpacing(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textLetterSpacing(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextLetterSpacing()); + assertNotNull(layer.getTextLetterSpacing().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextLetterSpacing().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextLetterSpacing().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextLetterSpacing().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextLetterSpacing().getFunction().getStops()).size()); + + ExponentialStops, Float> stops = + (ExponentialStops, Float>) layer.getTextLetterSpacing().getFunction().getStops(); + Stop, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + }); + } + @Test public void testTextJustifyAsConstant() { validateTestSetup(); diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h index bc39df5b16..ffb95dfc73 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ b/platform/darwin/src/MGLSymbolStyleLayer.h @@ -857,6 +857,15 @@ MGL_EXPORT * `MGLCameraStyleFunction` with an interpolation mode of: * `MGLInterpolationModeExponential` * `MGLInterpolationModeInterval` + * `MGLSourceStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` + * `MGLInterpolationModeIdentity` + * `MGLCompositeStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` */ @property (nonatomic, null_resettable) MGLStyleValue *maximumTextWidth; @@ -1162,6 +1171,15 @@ MGL_EXPORT * `MGLCameraStyleFunction` with an interpolation mode of: * `MGLInterpolationModeExponential` * `MGLInterpolationModeInterval` + * `MGLSourceStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` + * `MGLInterpolationModeIdentity` + * `MGLCompositeStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` */ @property (nonatomic, null_resettable) MGLStyleValue *textLetterSpacing; diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index 7e8b0b247b..1990c82669 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -485,7 +485,7 @@ namespace mbgl { - (void)setMaximumTextWidth:(MGLStyleValue *)maximumTextWidth { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer().toInterpolatablePropertyValue(maximumTextWidth); + auto mbglValue = MGLStyleValueTransformer().toDataDrivenPropertyValue(maximumTextWidth); self.rawLayer->setTextMaxWidth(mbglValue); } @@ -494,9 +494,9 @@ namespace mbgl { auto propertyValue = self.rawLayer->getTextMaxWidth(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer().toStyleValue(self.rawLayer->getDefaultTextMaxWidth()); + return MGLStyleValueTransformer().toDataDrivenStyleValue(self.rawLayer->getDefaultTextMaxWidth()); } - return MGLStyleValueTransformer().toStyleValue(propertyValue); + return MGLStyleValueTransformer().toDataDrivenStyleValue(propertyValue); } - (void)setTextMaxWidth:(MGLStyleValue *)textMaxWidth { @@ -728,7 +728,7 @@ namespace mbgl { - (void)setTextLetterSpacing:(MGLStyleValue *)textLetterSpacing { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer().toInterpolatablePropertyValue(textLetterSpacing); + auto mbglValue = MGLStyleValueTransformer().toDataDrivenPropertyValue(textLetterSpacing); self.rawLayer->setTextLetterSpacing(mbglValue); } @@ -737,9 +737,9 @@ namespace mbgl { auto propertyValue = self.rawLayer->getTextLetterSpacing(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer().toStyleValue(self.rawLayer->getDefaultTextLetterSpacing()); + return MGLStyleValueTransformer().toDataDrivenStyleValue(self.rawLayer->getDefaultTextLetterSpacing()); } - return MGLStyleValueTransformer().toStyleValue(propertyValue); + return MGLStyleValueTransformer().toDataDrivenStyleValue(propertyValue); } - (void)setTextLineHeight:(MGLStyleValue *)textLineHeight { diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index abbaef9159..1ac86dd402 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -736,7 +736,7 @@ MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:@0xff]; layer.maximumTextWidth = constantStyleValue; - mbgl::style::PropertyValue propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getTextMaxWidth(), propertyValue, @"Setting maximumTextWidth to a constant value should update text-max-width."); XCTAssertEqualObjects(layer.maximumTextWidth, constantStyleValue, @@ -753,6 +753,29 @@ XCTAssertEqualObjects(layer.maximumTextWidth, functionStyleValue, @"maximumTextWidth should round-trip camera functions."); + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.maximumTextWidth = functionStyleValue; + + mbgl::style::ExponentialStops exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getTextMaxWidth(), propertyValue, + @"Setting maximumTextWidth to a source function should update text-max-width."); + XCTAssertEqualObjects(layer.maximumTextWidth, functionStyleValue, + @"maximumTextWidth should round-trip source functions."); + + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.maximumTextWidth = functionStyleValue; + + std::map innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getTextMaxWidth(), propertyValue, + @"Setting maximumTextWidth to a composite function should update text-max-width."); + XCTAssertEqualObjects(layer.maximumTextWidth, functionStyleValue, + @"maximumTextWidth should round-trip composite functions."); layer.maximumTextWidth = nil; @@ -760,11 +783,6 @@ @"Unsetting maximumTextWidth should return text-max-width to the default value."); XCTAssertEqualObjects(layer.maximumTextWidth, defaultStyleValue, @"maximumTextWidth should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.maximumTextWidth = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.maximumTextWidth = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // symbol-avoid-edges @@ -1168,7 +1186,7 @@ MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:@0xff]; layer.textLetterSpacing = constantStyleValue; - mbgl::style::PropertyValue propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getTextLetterSpacing(), propertyValue, @"Setting textLetterSpacing to a constant value should update text-letter-spacing."); XCTAssertEqualObjects(layer.textLetterSpacing, constantStyleValue, @@ -1185,6 +1203,29 @@ XCTAssertEqualObjects(layer.textLetterSpacing, functionStyleValue, @"textLetterSpacing should round-trip camera functions."); + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.textLetterSpacing = functionStyleValue; + + mbgl::style::ExponentialStops exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getTextLetterSpacing(), propertyValue, + @"Setting textLetterSpacing to a source function should update text-letter-spacing."); + XCTAssertEqualObjects(layer.textLetterSpacing, functionStyleValue, + @"textLetterSpacing should round-trip source functions."); + + functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.textLetterSpacing = functionStyleValue; + + std::map innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getTextLetterSpacing(), propertyValue, + @"Setting textLetterSpacing to a composite function should update text-letter-spacing."); + XCTAssertEqualObjects(layer.textLetterSpacing, functionStyleValue, + @"textLetterSpacing should round-trip composite functions."); layer.textLetterSpacing = nil; @@ -1192,11 +1233,6 @@ @"Unsetting textLetterSpacing should return text-letter-spacing to the default value."); XCTAssertEqualObjects(layer.textLetterSpacing, defaultStyleValue, @"textLetterSpacing should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textLetterSpacing = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textLetterSpacing = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-line-height diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index a19d0e9cca..f2f5eff194 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -49,10 +49,6 @@ "render-tests/runtime-styling/source-add-geojson-inline": "skip - needs issue", "render-tests/symbol-placement/line": "needs issue", "render-tests/text-keep-upright/line-placement-true-offset": "https://github.com/mapbox/mapbox-gl-native/issues/9271", - "render-tests/text-letter-spacing/property-function": "https://github.com/mapbox/mapbox-gl-native/issues/9668", - "render-tests/text-letter-spacing/zoom-and-property-function": "https://github.com/mapbox/mapbox-gl-native/issues/9668", - "render-tests/text-max-width/property-function": "https://github.com/mapbox/mapbox-gl-native/issues/9654", - "render-tests/text-max-width/zoom-and-property-function": "https://github.com/mapbox/mapbox-gl-native/issues/9654", "render-tests/text-pitch-alignment/auto-text-rotation-alignment-map": "https://github.com/mapbox/mapbox-gl-native/issues/9732", "render-tests/text-pitch-alignment/auto-text-rotation-alignment-viewport": "https://github.com/mapbox/mapbox-gl-native/issues/9732", "render-tests/text-pitch-alignment/map-text-rotation-alignment-map": "https://github.com/mapbox/mapbox-gl-native/issues/9732", diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index adb8ce5927..2c90b69b08 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -205,11 +205,11 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph const Shaping result = getShaping( /* string */ text, /* maxWidth: ems */ layout.get() != SymbolPlacementType::Line ? - layout.get() * oneEm : 0, + layout.evaluate(zoom, feature) * oneEm : 0, /* lineHeight: ems */ layout.get() * oneEm, /* anchor */ layout.evaluate(zoom, feature), /* justify */ layout.evaluate(zoom, feature), - /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get() * oneEm : 0.0f, + /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.evaluate(zoom, feature) * oneEm : 0.0f, /* translate */ Point(layout.evaluate(zoom, feature)[0] * oneEm, layout.evaluate(zoom, feature)[1] * oneEm), /* verticalHeight */ oneEm, /* writingMode */ writingMode, diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 2b86b26025..9a944657ca 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -444,15 +444,15 @@ void SymbolLayer::setTextSize(DataDrivenPropertyValue value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue SymbolLayer::getDefaultTextMaxWidth() { +DataDrivenPropertyValue SymbolLayer::getDefaultTextMaxWidth() { return TextMaxWidth::defaultValue(); } -PropertyValue SymbolLayer::getTextMaxWidth() const { +DataDrivenPropertyValue SymbolLayer::getTextMaxWidth() const { return impl().layout.get(); } -void SymbolLayer::setTextMaxWidth(PropertyValue value) { +void SymbolLayer::setTextMaxWidth(DataDrivenPropertyValue value) { if (value == getTextMaxWidth()) return; auto impl_ = mutableImpl(); @@ -476,15 +476,15 @@ void SymbolLayer::setTextLineHeight(PropertyValue value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue SymbolLayer::getDefaultTextLetterSpacing() { +DataDrivenPropertyValue SymbolLayer::getDefaultTextLetterSpacing() { return TextLetterSpacing::defaultValue(); } -PropertyValue SymbolLayer::getTextLetterSpacing() const { +DataDrivenPropertyValue SymbolLayer::getTextLetterSpacing() const { return impl().layout.get(); } -void SymbolLayer::setTextLetterSpacing(PropertyValue value) { +void SymbolLayer::setTextLetterSpacing(DataDrivenPropertyValue value) { if (value == getTextLetterSpacing()) return; auto impl_ = mutableImpl(); diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index 0d163b9fb9..436b5cbd4f 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -122,7 +122,7 @@ struct TextSize : DataDrivenLayoutProperty { static float defaultValue() { return 16; } }; -struct TextMaxWidth : LayoutProperty { +struct TextMaxWidth : DataDrivenLayoutProperty { static constexpr const char * key = "text-max-width"; static float defaultValue() { return 10; } }; @@ -132,7 +132,7 @@ struct TextLineHeight : LayoutProperty { static float defaultValue() { return 1.2; } }; -struct TextLetterSpacing : LayoutProperty { +struct TextLetterSpacing : DataDrivenLayoutProperty { static constexpr const char * key = "text-letter-spacing"; static float defaultValue() { return 0; } }; -- cgit v1.2.1