diff options
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<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setTextField>; result["text-font"] = &setProperty<V, SymbolLayer, PropertyValue<std::vector<std::string>>, &SymbolLayer::setTextFont>; result["text-size"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextSize>; - result["text-max-width"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxWidth>; + result["text-max-width"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextMaxWidth>; result["text-line-height"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLineHeight>; - result["text-letter-spacing"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLetterSpacing>; + result["text-letter-spacing"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextLetterSpacing>; result["text-justify"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<TextJustifyType>, &SymbolLayer::setTextJustify>; result["text-anchor"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<SymbolAnchorType>, &SymbolLayer::setTextAnchor>; result["text-max-angle"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &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<float> getTextSize() const; void setTextSize(DataDrivenPropertyValue<float>); - static PropertyValue<float> getDefaultTextMaxWidth(); - PropertyValue<float> getTextMaxWidth() const; - void setTextMaxWidth(PropertyValue<float>); + static DataDrivenPropertyValue<float> getDefaultTextMaxWidth(); + DataDrivenPropertyValue<float> getTextMaxWidth() const; + void setTextMaxWidth(DataDrivenPropertyValue<float>); static PropertyValue<float> getDefaultTextLineHeight(); PropertyValue<float> getTextLineHeight() const; void setTextLineHeight(PropertyValue<float>); - static PropertyValue<float> getDefaultTextLetterSpacing(); - PropertyValue<float> getTextLetterSpacing() const; - void setTextLetterSpacing(PropertyValue<float>); + static DataDrivenPropertyValue<float> getDefaultTextLetterSpacing(); + DataDrivenPropertyValue<float> getTextLetterSpacing() const; + void setTextLetterSpacing(DataDrivenPropertyValue<float>); static DataDrivenPropertyValue<TextJustifyType> getDefaultTextJustify(); DataDrivenPropertyValue<TextJustifyType> 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 <Z> the zoom parameter type - * @param function a wrapper {@link CameraFunction} for Float + * @param <T> the function input type + * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textMaxWidth(CameraFunction<Z, Float> function) { + public static <T> PropertyValue<Function<T, Float>> textMaxWidth(Function<T, Float> function) { return new LayoutPropertyValue<>("text-max-width", function); } @@ -2103,11 +2103,11 @@ public class PropertyFactory { /** * Text tracking amount. * - * @param <Z> the zoom parameter type - * @param function a wrapper {@link CameraFunction} for Float + * @param <T> the function input type + * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textLetterSpacing(CameraFunction<Z, Float> function) { + public static <T> PropertyValue<Function<T, Float>> textLetterSpacing(Function<T, Float> 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 @@ -1847,6 +1847,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.<Float>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<Stop.CompositeValue<Float, Float>, Float> stops = + (ExponentialStops<Stop.CompositeValue<Float, Float>, Float>) layer.getTextMaxWidth().getFunction().getStops(); + Stop<Stop.CompositeValue<Float, Float>, 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(); setupLayer(); @@ -1945,6 +2078,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.<Float>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<Stop.CompositeValue<Float, Float>, Float> stops = + (ExponentialStops<Stop.CompositeValue<Float, Float>, Float>) layer.getTextLetterSpacing().getFunction().getStops(); + Stop<Stop.CompositeValue<Float, Float>, 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(); setupLayer(); 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<NSNumber *> *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<NSNumber *> *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<NSNumber *> *)maximumTextWidth { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(maximumTextWidth); + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(maximumTextWidth); self.rawLayer->setTextMaxWidth(mbglValue); } @@ -494,9 +494,9 @@ namespace mbgl { auto propertyValue = self.rawLayer->getTextMaxWidth(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultTextMaxWidth()); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultTextMaxWidth()); } - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue); } - (void)setTextMaxWidth:(MGLStyleValue<NSNumber *> *)textMaxWidth { @@ -728,7 +728,7 @@ namespace mbgl { - (void)setTextLetterSpacing:(MGLStyleValue<NSNumber *> *)textLetterSpacing { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(textLetterSpacing); + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(textLetterSpacing); self.rawLayer->setTextLetterSpacing(mbglValue); } @@ -737,9 +737,9 @@ namespace mbgl { auto propertyValue = self.rawLayer->getTextLetterSpacing(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultTextLetterSpacing()); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultTextLetterSpacing()); } - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue); } - (void)setTextLineHeight:(MGLStyleValue<NSNumber *> *)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<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.maximumTextWidth = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> 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<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.maximumTextWidth = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "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<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.maximumTextWidth = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "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<NSNumber *> 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<NSNumber *> 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<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.textLetterSpacing = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> 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<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.textLetterSpacing = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "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<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.textLetterSpacing = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "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<NSNumber *> 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<NSNumber *> 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<SymbolPlacement>() != SymbolPlacementType::Line ? - layout.get<TextMaxWidth>() * oneEm : 0, + layout.evaluate<TextMaxWidth>(zoom, feature) * oneEm : 0, /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm, /* anchor */ layout.evaluate<TextAnchor>(zoom, feature), /* justify */ layout.evaluate<TextJustify>(zoom, feature), - /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get<TextLetterSpacing>() * oneEm : 0.0f, + /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * oneEm : 0.0f, /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(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<float> value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() { +DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() { return TextMaxWidth::defaultValue(); } -PropertyValue<float> SymbolLayer::getTextMaxWidth() const { +DataDrivenPropertyValue<float> SymbolLayer::getTextMaxWidth() const { return impl().layout.get<TextMaxWidth>(); } -void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) { +void SymbolLayer::setTextMaxWidth(DataDrivenPropertyValue<float> value) { if (value == getTextMaxWidth()) return; auto impl_ = mutableImpl(); @@ -476,15 +476,15 @@ void SymbolLayer::setTextLineHeight(PropertyValue<float> value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() { +DataDrivenPropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() { return TextLetterSpacing::defaultValue(); } -PropertyValue<float> SymbolLayer::getTextLetterSpacing() const { +DataDrivenPropertyValue<float> SymbolLayer::getTextLetterSpacing() const { return impl().layout.get<TextLetterSpacing>(); } -void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) { +void SymbolLayer::setTextLetterSpacing(DataDrivenPropertyValue<float> 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<float> { static float defaultValue() { return 16; } }; -struct TextMaxWidth : LayoutProperty<float> { +struct TextMaxWidth : DataDrivenLayoutProperty<float> { static constexpr const char * key = "text-max-width"; static float defaultValue() { return 10; } }; @@ -132,7 +132,7 @@ struct TextLineHeight : LayoutProperty<float> { static float defaultValue() { return 1.2; } }; -struct TextLetterSpacing : LayoutProperty<float> { +struct TextLetterSpacing : DataDrivenLayoutProperty<float> { static constexpr const char * key = "text-letter-spacing"; static float defaultValue() { return 0; } }; |