diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp index f29d5f5b6fb..9252297d754 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp +++ b/include/mbgl/style/conversion/make_property_setters.hpp @@ -26,7 +26,7 @@ auto makeLayoutPropertySetters() { result["line-cap"] = &setProperty, &LineLayer::setLineCap>; - result["line-join"] = &setProperty, &LineLayer::setLineJoin>; + result["line-join"] = &setProperty, &LineLayer::setLineJoin>; result["line-miter-limit"] = &setProperty, &LineLayer::setLineMiterLimit>; result["line-round-limit"] = &setProperty, &LineLayer::setLineRoundLimit>; @@ -54,8 +54,8 @@ auto makeLayoutPropertySetters() { result["text-max-width"] = &setProperty, &SymbolLayer::setTextMaxWidth>; result["text-line-height"] = &setProperty, &SymbolLayer::setTextLineHeight>; result["text-letter-spacing"] = &setProperty, &SymbolLayer::setTextLetterSpacing>; - result["text-justify"] = &setProperty, &SymbolLayer::setTextJustify>; - result["text-anchor"] = &setProperty, &SymbolLayer::setTextAnchor>; + result["text-justify"] = &setProperty, &SymbolLayer::setTextJustify>; + result["text-anchor"] = &setProperty, &SymbolLayer::setTextAnchor>; result["text-max-angle"] = &setProperty, &SymbolLayer::setTextMaxAngle>; result["text-rotate"] = &setProperty, &SymbolLayer::setTextRotate>; result["text-padding"] = &setProperty, &SymbolLayer::setTextPadding>; diff --git a/include/mbgl/style/layers/line_layer.hpp b/include/mbgl/style/layers/line_layer.hpp index 0b49690fd88..45192963236 100644 --- a/include/mbgl/style/layers/line_layer.hpp +++ b/include/mbgl/style/layers/line_layer.hpp @@ -42,9 +42,9 @@ class LineLayer : public Layer { PropertyValue getLineCap() const; void setLineCap(PropertyValue); - static PropertyValue getDefaultLineJoin(); - PropertyValue getLineJoin() const; - void setLineJoin(PropertyValue); + static DataDrivenPropertyValue getDefaultLineJoin(); + DataDrivenPropertyValue getLineJoin() const; + void setLineJoin(DataDrivenPropertyValue); static PropertyValue getDefaultLineMiterLimit(); PropertyValue getLineMiterLimit() const; diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index f4d0322dc71..6e355c0057d 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -134,13 +134,13 @@ class SymbolLayer : public Layer { PropertyValue getTextLetterSpacing() const; void setTextLetterSpacing(PropertyValue); - static PropertyValue getDefaultTextJustify(); - PropertyValue getTextJustify() const; - void setTextJustify(PropertyValue); + static DataDrivenPropertyValue getDefaultTextJustify(); + DataDrivenPropertyValue getTextJustify() const; + void setTextJustify(DataDrivenPropertyValue); - static PropertyValue getDefaultTextAnchor(); - PropertyValue getTextAnchor() const; - void setTextAnchor(PropertyValue); + static DataDrivenPropertyValue getDefaultTextAnchor(); + DataDrivenPropertyValue getTextAnchor() const; + void setTextAnchor(DataDrivenPropertyValue); static PropertyValue getDefaultTextMaxAngle(); PropertyValue getTextMaxAngle() 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 1c68878772b..ef89c6809ef 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 @@ -1482,11 +1482,11 @@ public static PropertyValue lineJoin(@Property.LINE_JOIN String value) { /** * The display of lines when joining. * - * @param the zoom parameter type - * @param function a wrapper {@link CameraFunction} for String + * @param the function input type + * @param function a wrapper function for String * @return property wrapper around a String function */ - public static PropertyValue> lineJoin(CameraFunction function) { + public static PropertyValue> lineJoin(Function function) { return new LayoutPropertyValue<>("line-join", function); } @@ -2103,11 +2103,11 @@ public static PropertyValue textJustify(@Property.TEXT_JUSTIFY String va /** * Text justification options. * - * @param the zoom parameter type - * @param function a wrapper {@link CameraFunction} for String + * @param the function input type + * @param function a wrapper function for String * @return property wrapper around a String function */ - public static PropertyValue> textJustify(CameraFunction function) { + public static PropertyValue> textJustify(Function function) { return new LayoutPropertyValue<>("text-justify", function); } @@ -2126,11 +2126,11 @@ public static PropertyValue textAnchor(@Property.TEXT_ANCHOR String valu /** * Part of the text placed closest to the anchor. * - * @param the zoom parameter type - * @param function a wrapper {@link CameraFunction} for String + * @param the function input type + * @param function a wrapper function for String * @return property wrapper around a String function */ - public static PropertyValue> textAnchor(CameraFunction function) { + public static PropertyValue> textAnchor(Function function) { return new LayoutPropertyValue<>("text-anchor", function); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java index 7bdf47aff43..8123d24be81 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java @@ -203,6 +203,63 @@ public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { }); } + @Test + public void testLineJoinAsIdentitySourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("line-join"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineJoin(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getLineJoin()); + assertNotNull(layer.getLineJoin().getFunction()); + assertEquals(SourceFunction.class, layer.getLineJoin().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineJoin().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getLineJoin().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testLineJoinAsIntervalSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("line-join"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + lineJoin( + property( + "FeaturePropertyA", + interval( + stop(1, lineJoin(LINE_JOIN_BEVEL)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getLineJoin()); + assertNotNull(layer.getLineJoin().getFunction()); + assertEquals(SourceFunction.class, layer.getLineJoin().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineJoin().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getLineJoin().getFunction().getStops().getClass()); + } + }); + } + @Test public void testLineMiterLimitAsConstant() { validateTestSetup(); 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 fc8c4320a51..e2694af3485 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 @@ -1887,6 +1887,63 @@ public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { }); } + @Test + public void testTextJustifyAsIdentitySourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-justify"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textJustify(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getTextJustify()); + assertNotNull(layer.getTextJustify().getFunction()); + assertEquals(SourceFunction.class, layer.getTextJustify().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextJustify().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextJustify().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testTextJustifyAsIntervalSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-justify"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textJustify( + property( + "FeaturePropertyA", + interval( + stop(1, textJustify(TEXT_JUSTIFY_LEFT)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getTextJustify()); + assertNotNull(layer.getTextJustify().getFunction()); + assertEquals(SourceFunction.class, layer.getTextJustify().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextJustify().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getTextJustify().getFunction().getStops().getClass()); + } + }); + } + @Test public void testTextAnchorAsConstant() { validateTestSetup(); @@ -1935,6 +1992,63 @@ public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { }); } + @Test + public void testTextAnchorAsIdentitySourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-anchor"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textAnchor(property("FeaturePropertyA", Stops.identity())) + ); + + // Verify + assertNotNull(layer.getTextAnchor()); + assertNotNull(layer.getTextAnchor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextAnchor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextAnchor().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextAnchor().getFunction().getStops().getClass()); + } + }); + } + + @Test + public void testTextAnchorAsIntervalSourceFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("text-anchor"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + textAnchor( + property( + "FeaturePropertyA", + interval( + stop(1, textAnchor(TEXT_ANCHOR_CENTER)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getTextAnchor()); + assertNotNull(layer.getTextAnchor().getFunction()); + assertEquals(SourceFunction.class, layer.getTextAnchor().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextAnchor().getFunction()).getProperty()); + assertEquals(IntervalStops.class, layer.getTextAnchor().getFunction().getStops().getClass()); + } + }); + } + @Test public void testTextMaxAngleAsConstant() { validateTestSetup(); diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h index 4a96b11abf7..46025ddbf00 100644 --- a/platform/darwin/src/MGLLineStyleLayer.h +++ b/platform/darwin/src/MGLLineStyleLayer.h @@ -149,8 +149,18 @@ MGL_EXPORT You can set this property to an instance of: * `MGLConstantStyleValue` - * `MGLCameraStyleFunction` with an interpolation mode of - `MGLInterpolationModeInterval` + * `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 *lineJoin; diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm index 9be1667722d..5b2652cdeb0 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -109,7 +109,7 @@ - (void)setLineCap:(MGLStyleValue *)lineCap { - (void)setLineJoin:(MGLStyleValue *)lineJoin { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer().toEnumPropertyValue(lineJoin); + auto mbglValue = MGLStyleValueTransformer().toDataDrivenPropertyValue(lineJoin); self.rawLayer->setLineJoin(mbglValue); } @@ -118,9 +118,9 @@ - (void)setLineJoin:(MGLStyleValue *)lineJoin { auto propertyValue = self.rawLayer->getLineJoin(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer().toEnumStyleValue(self.rawLayer->getDefaultLineJoin()); + return MGLStyleValueTransformer().toDataDrivenStyleValue(self.rawLayer->getDefaultLineJoin()); } - return MGLStyleValueTransformer().toEnumStyleValue(propertyValue); + return MGLStyleValueTransformer().toDataDrivenStyleValue(propertyValue); } - (void)setLineMiterLimit:(MGLStyleValue *)lineMiterLimit { diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h index f8df073efe6..d8dded7dbd2 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ b/platform/darwin/src/MGLSymbolStyleLayer.h @@ -924,8 +924,18 @@ MGL_EXPORT You can set this property to an instance of: * `MGLConstantStyleValue` - * `MGLCameraStyleFunction` with an interpolation mode of - `MGLInterpolationModeInterval` + * `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 *textAnchor; @@ -1043,8 +1053,18 @@ MGL_EXPORT You can set this property to an instance of: * `MGLConstantStyleValue` - * `MGLCameraStyleFunction` with an interpolation mode of - `MGLInterpolationModeInterval` + * `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 *textJustification; diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index dd43ebd73c5..2541e6b0a4f 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -586,7 +586,7 @@ - (void)setTextAllowOverlap:(MGLStyleValue *)textAllowOverlap { - (void)setTextAnchor:(MGLStyleValue *)textAnchor { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer().toEnumPropertyValue(textAnchor); + auto mbglValue = MGLStyleValueTransformer().toDataDrivenPropertyValue(textAnchor); self.rawLayer->setTextAnchor(mbglValue); } @@ -595,9 +595,9 @@ - (void)setTextAnchor:(MGLStyleValue *)textAnchor { auto propertyValue = self.rawLayer->getTextAnchor(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer().toEnumStyleValue(self.rawLayer->getDefaultTextAnchor()); + return MGLStyleValueTransformer().toDataDrivenStyleValue(self.rawLayer->getDefaultTextAnchor()); } - return MGLStyleValueTransformer().toEnumStyleValue(propertyValue); + return MGLStyleValueTransformer().toDataDrivenStyleValue(propertyValue); } - (void)setTextFontNames:(MGLStyleValue *> *)textFontNames { @@ -675,7 +675,7 @@ - (void)setTextIgnorePlacement:(MGLStyleValue *)textIgnorePlacement - (void)setTextJustification:(MGLStyleValue *)textJustification { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer().toEnumPropertyValue(textJustification); + auto mbglValue = MGLStyleValueTransformer().toDataDrivenPropertyValue(textJustification); self.rawLayer->setTextJustify(mbglValue); } @@ -684,9 +684,9 @@ - (void)setTextJustification:(MGLStyleValue *)textJustification { auto propertyValue = self.rawLayer->getTextJustify(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer().toEnumStyleValue(self.rawLayer->getDefaultTextJustify()); + return MGLStyleValueTransformer().toDataDrivenStyleValue(self.rawLayer->getDefaultTextJustify()); } - return MGLStyleValueTransformer().toEnumStyleValue(propertyValue); + return MGLStyleValueTransformer().toDataDrivenStyleValue(propertyValue); } - (void)setTextJustify:(MGLStyleValue *)textJustify { diff --git a/platform/darwin/test/MGLLineStyleLayerTests.mm b/platform/darwin/test/MGLLineStyleLayerTests.mm index be7d9a6754e..7e7926e22e2 100644 --- a/platform/darwin/test/MGLLineStyleLayerTests.mm +++ b/platform/darwin/test/MGLLineStyleLayerTests.mm @@ -95,7 +95,7 @@ - (void)testProperties { MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLLineJoin:MGLLineJoinMiter]]; layer.lineJoin = constantStyleValue; - mbgl::style::PropertyValue propertyValue = { mbgl::style::LineJoinType::Miter }; + mbgl::style::DataDrivenPropertyValue propertyValue = { mbgl::style::LineJoinType::Miter }; XCTAssertEqual(rawLayer->getLineJoin(), propertyValue, @"Setting lineJoin to a constant value should update line-join."); XCTAssertEqualObjects(layer.lineJoin, constantStyleValue, @@ -119,11 +119,6 @@ - (void)testProperties { @"Unsetting lineJoin should return line-join to the default value."); XCTAssertEqualObjects(layer.lineJoin, defaultStyleValue, @"lineJoin should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.lineJoin = 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.lineJoin = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // line-miter-limit diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index 5e969e27ca0..6b0b20354b9 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -931,7 +931,7 @@ - (void)testProperties { MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLTextAnchor:MGLTextAnchorBottomRight]]; layer.textAnchor = constantStyleValue; - mbgl::style::PropertyValue propertyValue = { mbgl::style::TextAnchorType::BottomRight }; + mbgl::style::DataDrivenPropertyValue propertyValue = { mbgl::style::TextAnchorType::BottomRight }; XCTAssertEqual(rawLayer->getTextAnchor(), propertyValue, @"Setting textAnchor to a constant value should update text-anchor."); XCTAssertEqualObjects(layer.textAnchor, constantStyleValue, @@ -955,11 +955,6 @@ - (void)testProperties { @"Unsetting textAnchor should return text-anchor to the default value."); XCTAssertEqualObjects(layer.textAnchor, defaultStyleValue, @"textAnchor should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textAnchor = 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.textAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-font @@ -1105,7 +1100,7 @@ - (void)testProperties { MGLStyleValue *constantStyleValue = [MGLStyleValue valueWithRawValue:[NSValue valueWithMGLTextJustification:MGLTextJustificationRight]]; layer.textJustification = constantStyleValue; - mbgl::style::PropertyValue propertyValue = { mbgl::style::TextJustifyType::Right }; + mbgl::style::DataDrivenPropertyValue propertyValue = { mbgl::style::TextJustifyType::Right }; XCTAssertEqual(rawLayer->getTextJustify(), propertyValue, @"Setting textJustification to a constant value should update text-justify."); XCTAssertEqualObjects(layer.textJustification, constantStyleValue, @@ -1129,11 +1124,6 @@ - (void)testProperties { @"Unsetting textJustification should return text-justify to the default value."); XCTAssertEqualObjects(layer.textJustification, defaultStyleValue, @"textJustification should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textJustification = 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.textJustification = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-letter-spacing diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index 3a3358d8c2b..470e84bedbc 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -42,9 +42,6 @@ "render-tests/icon-text-fit/height": "https://github.com/mapbox/mapbox-gl-native/issues/5602", "render-tests/icon-text-fit/width-padding": "https://github.com/mapbox/mapbox-gl-native/issues/5602", "render-tests/icon-text-fit/width": "https://github.com/mapbox/mapbox-gl-native/issues/5602", - "render-tests/line-join/property-function": "https://github.com/mapbox/mapbox-gl-native/pull/9583", - "render-tests/line-join/property-function-dasharray": "https://github.com/mapbox/mapbox-gl-native/pull/9583", - "render-tests/line-width/property-function": "https://github.com/mapbox/mapbox-gl-js/issues/3682#issuecomment-264348200", "render-tests/regressions/mapbox-gl-js#2305": "https://github.com/mapbox/mapbox-gl-native/issues/6927", "render-tests/regressions/mapbox-gl-js#3010": "skip - needs issue", "render-tests/regressions/mapbox-gl-js#3548": "skip - needs issue", @@ -57,8 +54,6 @@ "render-tests/runtime-styling/set-style-paint-property-fill-flat-to-extrude": "skip - needs issue", "render-tests/runtime-styling/source-add-geojson-inline": "skip - needs issue", "render-tests/symbol-placement/line": "needs issue", - "render-tests/text-anchor/property-function": "https://github.com/mapbox/mapbox-gl-native/issues/9555", - "render-tests/text-justify/property-function": "https://github.com/mapbox/mapbox-gl-native/issues/9559", "render-tests/text-keep-upright/line-placement-true-offset": "https://github.com/mapbox/mapbox-gl-native/issues/9271", "render-tests/text-size/composite-function-high-base": "https://github.com/mapbox/mapbox-gl-native/issues/8654", "render-tests/video/default": "skip - needs issue" diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 956ba770dd1..229b8f2ee23 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -180,47 +180,6 @@ bool SymbolLayout::hasSymbolInstances() const { void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, const ImageMap& imageMap, const ImagePositions& imagePositions) { - float horizontalAlign = 0.5; - float verticalAlign = 0.5; - - switch (layout.get()) { - case TextAnchorType::Top: - case TextAnchorType::Bottom: - case TextAnchorType::Center: - break; - case TextAnchorType::Right: - case TextAnchorType::TopRight: - case TextAnchorType::BottomRight: - horizontalAlign = 1; - break; - case TextAnchorType::Left: - case TextAnchorType::TopLeft: - case TextAnchorType::BottomLeft: - horizontalAlign = 0; - break; - } - - switch (layout.get()) { - case TextAnchorType::Left: - case TextAnchorType::Right: - case TextAnchorType::Center: - break; - case TextAnchorType::Bottom: - case TextAnchorType::BottomLeft: - case TextAnchorType::BottomRight: - verticalAlign = 1; - break; - case TextAnchorType::Top: - case TextAnchorType::TopLeft: - case TextAnchorType::TopRight: - verticalAlign = 0; - break; - } - - const float justify = layout.get() == TextJustifyType::Right ? 1 : - layout.get() == TextJustifyType::Left ? 0 : - 0.5; - const bool textAlongLine = layout.get() == AlignmentType::Map && layout.get() == SymbolPlacementType::Line; @@ -248,9 +207,8 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph /* maxWidth: ems */ layout.get() != SymbolPlacementType::Line ? layout.get() * oneEm : 0, /* lineHeight: ems */ layout.get() * oneEm, - /* horizontalAlign */ horizontalAlign, - /* verticalAlign */ verticalAlign, - /* justify */ justify, + /* anchor */ layout.evaluate(zoom, feature), + /* justify */ layout.evaluate(zoom, feature), /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get() * oneEm : 0.0f, /* translate */ Point(layout.evaluate(zoom, feature)[0] * oneEm, layout.evaluate(zoom, feature)[1] * oneEm), /* verticalHeight */ oneEm, diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index d1771d484a7..194b012eee2 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -15,7 +15,8 @@ LineBucket::LineBucket(const BucketParameters& parameters, const std::vector& layers, const style::LineLayoutProperties::Unevaluated& layout_) : layout(layout_.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ))), - overscaling(parameters.tileID.overscaleFactor()) { + overscaling(parameters.tileID.overscaleFactor()), + zoom(parameters.tileID.overscaledZ) { for (const auto& layer : layers) { paintPropertyBinders.emplace( std::piecewise_construct, @@ -29,7 +30,7 @@ LineBucket::LineBucket(const BucketParameters& parameters, void LineBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometryCollection) { for (auto& line : geometryCollection) { - addGeometry(line, feature.getType()); + addGeometry(line, feature); } for (auto& pair : paintPropertyBinders) { @@ -62,7 +63,8 @@ const float LINE_DISTANCE_SCALE = 1.0 / 2.0; // The maximum line distance, in tile units, that fits in the buffer. const float MAX_LINE_DISTANCE = std::pow(2, LINE_DISTANCE_BUFFER_BITS) / LINE_DISTANCE_SCALE; -void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType type) { +void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const GeometryTileFeature& feature) { + const FeatureType type = feature.getType(); const std::size_t len = [&coordinates] { std::size_t l = coordinates.size(); // If the line has duplicate vertices at the end, adjust length to remove them. @@ -86,7 +88,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType return; } - const float miterLimit = layout.get() == LineJoinType::Bevel ? 1.05f : float(layout.get()); + const LineJoinType joinType = layout.evaluate(zoom, feature); + + const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get()); const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); @@ -193,7 +197,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType // The join if a middle vertex, otherwise the cap const bool middleVertex = prevCoordinate && nextCoordinate; - LineJoinType currentJoin = layout.get(); + LineJoinType currentJoin = joinType; const LineCapType currentCap = nextCoordinate ? beginCap : endCap; if (middleVertex) { diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 8ef25b02ec0..4fb77c377e2 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -41,7 +41,7 @@ class LineBucket : public Bucket { std::map paintPropertyBinders; private: - void addGeometry(const GeometryCoordinates&, FeatureType); + void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&); struct TriangleElement { TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {} @@ -59,6 +59,7 @@ class LineBucket : public Bucket { std::ptrdiff_t e3; const uint32_t overscaling; + const float zoom; float getLineWidth(const RenderLineLayer& layer) const; }; diff --git a/src/mbgl/shaders/preludes.cpp b/src/mbgl/shaders/preludes.cpp index 95fa624e8de..feb185a684f 100644 --- a/src/mbgl/shaders/preludes.cpp +++ b/src/mbgl/shaders/preludes.cpp @@ -24,25 +24,6 @@ precision highp float; #endif -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - // Unpack a pair of values that have been packed into a single float. // The packed values are assumed to be 8-bit unsigned integers, and are // packed like so: @@ -54,8 +35,8 @@ vec2 unpack_float(const float packedValue) { } -// To minimize the number of attributes needed in the mapbox-gl-native shaders, -// we encode a 4-component color into a pair of floats (i.e. a vec2) as follows: +// To minimize the number of attributes needed, we encode a 4-component +// color into a pair of floats (i.e. a vec2) as follows: // [ floor(color.r * 255) * 256 + color.g * 255, // floor(color.b * 255) * 256 + color.g * 255 ] vec4 decode_color(const vec2 encodedColor) { diff --git a/src/mbgl/style/function/categorical_stops.cpp b/src/mbgl/style/function/categorical_stops.cpp index 2984c3832f6..1a30a1f1c78 100644 --- a/src/mbgl/style/function/categorical_stops.cpp +++ b/src/mbgl/style/function/categorical_stops.cpp @@ -33,6 +33,9 @@ template class CategoricalStops; template class CategoricalStops>; template class CategoricalStops; template class CategoricalStops; +template class CategoricalStops; +template class CategoricalStops; +template class CategoricalStops; } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/function/identity_stops.cpp b/src/mbgl/style/function/identity_stops.cpp index 0c6891eac56..7815f4aca07 100644 --- a/src/mbgl/style/function/identity_stops.cpp +++ b/src/mbgl/style/function/identity_stops.cpp @@ -36,10 +36,37 @@ optional IdentityStops::evaluate(const Val if (!value.is()) { return {}; } - + return Enum::toEnum(value.get()); } +template <> +optional IdentityStops::evaluate(const Value& value) const { + if (!value.is()) { + return {}; + } + + return Enum::toEnum(value.get()); +} + +template <> +optional IdentityStops::evaluate(const Value& value) const { + if (!value.is()) { + return {}; + } + + return Enum::toEnum(value.get()); +} + +template <> +optional IdentityStops::evaluate(const Value& value) const { + if (!value.is()) { + return {}; + } + + return Enum::toEnum(value.get()); +} + template <> optional> IdentityStops>::evaluate(const Value& value) const { if (!value.is>()) { diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 6fbdf195687..1c7f0d28ee1 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -108,15 +108,15 @@ void LineLayer::setLineCap(PropertyValue value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue LineLayer::getDefaultLineJoin() { +DataDrivenPropertyValue LineLayer::getDefaultLineJoin() { return LineJoin::defaultValue(); } -PropertyValue LineLayer::getLineJoin() const { +DataDrivenPropertyValue LineLayer::getLineJoin() const { return impl().layout.get(); } -void LineLayer::setLineJoin(PropertyValue value) { +void LineLayer::setLineJoin(DataDrivenPropertyValue value) { if (value == getLineJoin()) return; auto impl_ = mutableImpl(); diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index b2c7f3199c9..aeaf51698a6 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -17,7 +17,7 @@ struct LineCap : LayoutProperty { static LineCapType defaultValue() { return LineCapType::Butt; } }; -struct LineJoin : LayoutProperty { +struct LineJoin : DataDrivenLayoutProperty { static constexpr const char * key = "line-join"; static LineJoinType defaultValue() { return LineJoinType::Miter; } }; diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index c102c64a949..803ae7397e3 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -476,15 +476,15 @@ void SymbolLayer::setTextLetterSpacing(PropertyValue value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue SymbolLayer::getDefaultTextJustify() { +DataDrivenPropertyValue SymbolLayer::getDefaultTextJustify() { return TextJustify::defaultValue(); } -PropertyValue SymbolLayer::getTextJustify() const { +DataDrivenPropertyValue SymbolLayer::getTextJustify() const { return impl().layout.get(); } -void SymbolLayer::setTextJustify(PropertyValue value) { +void SymbolLayer::setTextJustify(DataDrivenPropertyValue value) { if (value == getTextJustify()) return; auto impl_ = mutableImpl(); @@ -492,15 +492,15 @@ void SymbolLayer::setTextJustify(PropertyValue value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue SymbolLayer::getDefaultTextAnchor() { +DataDrivenPropertyValue SymbolLayer::getDefaultTextAnchor() { return TextAnchor::defaultValue(); } -PropertyValue SymbolLayer::getTextAnchor() const { +DataDrivenPropertyValue SymbolLayer::getTextAnchor() const { return impl().layout.get(); } -void SymbolLayer::setTextAnchor(PropertyValue value) { +void SymbolLayer::setTextAnchor(DataDrivenPropertyValue value) { if (value == getTextAnchor()) 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 4b2bff01b85..fe6ab38e92d 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -132,12 +132,12 @@ struct TextLetterSpacing : LayoutProperty { static float defaultValue() { return 0; } }; -struct TextJustify : LayoutProperty { +struct TextJustify : DataDrivenLayoutProperty { static constexpr const char * key = "text-justify"; static TextJustifyType defaultValue() { return TextJustifyType::Center; } }; -struct TextAnchor : LayoutProperty { +struct TextAnchor : DataDrivenLayoutProperty { static constexpr const char * key = "text-anchor"; static TextAnchorType defaultValue() { return TextAnchorType::Center; } }; diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 6c7ecff42ac..4a206e9baea 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -200,9 +200,8 @@ void shapeLines(Shaping& shaping, const std::vector& lines, const float spacing, const float lineHeight, - const float horizontalAlign, - const float verticalAlign, - const float justify, + const style::TextAnchorType textAnchor, + const style::TextJustifyType textJustify, const float verticalHeight, const WritingModeType writingMode, const Glyphs& glyphs) { @@ -214,6 +213,10 @@ void shapeLines(Shaping& shaping, float y = yOffset; float maxLineLength = 0; + + const float justify = textJustify == style::TextJustifyType::Right ? 1 : + textJustify == style::TextJustifyType::Left ? 0 : + 0.5; for (std::u16string line : lines) { // Collapse whitespace so it doesn't throw off justification @@ -254,11 +257,48 @@ void shapeLines(Shaping& shaping, x = 0; y += lineHeight; } - - align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, - lines.size()); + + float horizontalAlign = 0.5; + float verticalAlign = 0.5; + + switch (textAnchor) { + case style::TextAnchorType::Top: + case style::TextAnchorType::Bottom: + case style::TextAnchorType::Center: + break; + case style::TextAnchorType::Right: + case style::TextAnchorType::TopRight: + case style::TextAnchorType::BottomRight: + horizontalAlign = 1; + break; + case style::TextAnchorType::Left: + case style::TextAnchorType::TopLeft: + case style::TextAnchorType::BottomLeft: + horizontalAlign = 0; + break; + } + + switch (textAnchor) { + case style::TextAnchorType::Left: + case style::TextAnchorType::Right: + case style::TextAnchorType::Center: + break; + case style::TextAnchorType::Bottom: + case style::TextAnchorType::BottomLeft: + case style::TextAnchorType::BottomRight: + verticalAlign = 1; + break; + case style::TextAnchorType::Top: + case style::TextAnchorType::TopLeft: + case style::TextAnchorType::TopRight: + verticalAlign = 0; + break; + } + + align(shaping, justify, horizontalAlign, verticalAlign, + maxLineLength, lineHeight, lines.size()); const uint32_t height = lines.size() * lineHeight; - + // Calculate the bounding box shaping.top += -verticalAlign * height; shaping.bottom = shaping.top + height; @@ -269,9 +309,8 @@ void shapeLines(Shaping& shaping, const Shaping getShaping(const std::u16string& logicalInput, const float maxWidth, const float lineHeight, - const float horizontalAlign, - const float verticalAlign, - const float justify, + const style::TextAnchorType textAnchor, + const style::TextJustifyType textJustify, const float spacing, const Point& translate, const float verticalHeight, @@ -284,8 +323,8 @@ const Shaping getShaping(const std::u16string& logicalInput, bidi.processText(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, writingMode, glyphs)); - shapeLines(shaping, reorderedLines, spacing, lineHeight, horizontalAlign, verticalAlign, - justify, verticalHeight, writingMode, glyphs); + shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor, + textJustify, verticalHeight, writingMode, glyphs); return shaping; } diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index ca475e2a6c1..00e4ec55f86 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace mbgl { @@ -44,9 +45,8 @@ class PositionedIcon { const Shaping getShaping(const std::u16string& string, float maxWidth, float lineHeight, - float horizontalAlign, - float verticalAlign, - float justify, + style::TextAnchorType textAnchor, + style::TextJustifyType textJustify, float spacing, const Point& translate, float verticalHeight,