Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Add DDS support for {text,icon}-size (#8593)
Browse files Browse the repository at this point in the history
* Update gl-js and generate style code

* Factor out packUint8Pair() helper function

* Draft implementation of DDS for {text,icon}-size

Ports mapbox/mapbox-gl-js#4455

* Fix text-size/composite-function-line-placement test

* Refactor to PaintPropertyBinders-like strategy

* Dedupe gl::Program construction

* Use exponential function base for interpolation

* Dedupe coveringZoomStops method

* Fixup tests

* Fix CI errors (hidden within #if block)
  • Loading branch information
anandthakker authored Apr 6, 2017
1 parent f9cc044 commit 693c9f3
Show file tree
Hide file tree
Showing 37 changed files with 1,008 additions and 218 deletions.
4 changes: 2 additions & 2 deletions include/mbgl/style/conversion/make_property_setters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ auto makeLayoutPropertySetters() {
result["icon-ignore-placement"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconIgnorePlacement>;
result["icon-optional"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconOptional>;
result["icon-rotation-alignment"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconRotationAlignment>;
result["icon-size"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconSize>;
result["icon-size"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconSize>;
result["icon-text-fit"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<IconTextFitType>, &SymbolLayer::setIconTextFit>;
result["icon-text-fit-padding"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<std::array<float, 4>>, &SymbolLayer::setIconTextFitPadding>;
result["icon-image"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setIconImage>;
Expand All @@ -49,7 +49,7 @@ auto makeLayoutPropertySetters() {
result["text-rotation-alignment"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextRotationAlignment>;
result["text-field"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setTextField>;
result["text-font"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<std::vector<std::string>>, &SymbolLayer::setTextFont>;
result["text-size"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextSize>;
result["text-size"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextSize>;
result["text-max-width"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxWidth>;
result["text-line-height"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLineHeight>;
result["text-letter-spacing"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLetterSpacing>;
Expand Down
9 changes: 9 additions & 0 deletions include/mbgl/style/data_driven_property_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ class DataDrivenPropertyValue {
bool isDataDriven() const {
return value.template is<SourceFunction<T>>() || value.template is<CompositeFunction<T>>();
}

bool isZoomConstant() const {
return !value.template is<CameraFunction<T>>() && !value.template is<CompositeFunction<T>>();
}

template <class... Ts>
auto match(Ts&&... ts) const {
return value.match(std::forward<Ts>(ts)...);
}

template <typename Evaluator>
auto evaluate(const Evaluator& evaluator) const {
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/style/function/camera_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class CameraFunction {
return s.evaluate(Value(double(zoom))).value_or(T());
});
}

friend bool operator==(const CameraFunction& lhs,
const CameraFunction& rhs) {
return lhs.stops == rhs.stops;
Expand Down
12 changes: 6 additions & 6 deletions include/mbgl/style/layers/symbol_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ class SymbolLayer : public Layer {
PropertyValue<AlignmentType> getIconRotationAlignment() const;
void setIconRotationAlignment(PropertyValue<AlignmentType>);

static PropertyValue<float> getDefaultIconSize();
PropertyValue<float> getIconSize() const;
void setIconSize(PropertyValue<float>);
static DataDrivenPropertyValue<float> getDefaultIconSize();
DataDrivenPropertyValue<float> getIconSize() const;
void setIconSize(DataDrivenPropertyValue<float>);

static PropertyValue<IconTextFitType> getDefaultIconTextFit();
PropertyValue<IconTextFitType> getIconTextFit() const;
Expand Down Expand Up @@ -107,9 +107,9 @@ class SymbolLayer : public Layer {
PropertyValue<std::vector<std::string>> getTextFont() const;
void setTextFont(PropertyValue<std::vector<std::string>>);

static PropertyValue<float> getDefaultTextSize();
PropertyValue<float> getTextSize() const;
void setTextSize(PropertyValue<float>);
static DataDrivenPropertyValue<float> getDefaultTextSize();
DataDrivenPropertyValue<float> getTextSize() const;
void setTextSize(DataDrivenPropertyValue<float>);

static PropertyValue<float> getDefaultTextMaxWidth();
PropertyValue<float> getTextMaxWidth() const;
Expand Down
2 changes: 1 addition & 1 deletion mapbox-gl-js
Submodule mapbox-gl-js updated 65 files
+1 −0 .gitignore
+1 −0 circle.yml
+129 −0 debug/textsize.html
+1 −1 package.json
+2 −1 src/data/array_group.js
+2 −3 src/data/bucket/circle_bucket.js
+2 −3 src/data/bucket/fill_bucket.js
+2 −3 src/data/bucket/fill_extrusion_bucket.js
+2 −3 src/data/bucket/line_bucket.js
+240 −53 src/data/bucket/symbol_bucket.js
+10 −0 src/data/buffer.js
+3 −1 src/data/buffer_group.js
+31 −5 src/data/program_configuration.js
+67 −24 src/render/draw_symbol.js
+3 −3 src/render/vertex_array_object.js
+14 −5 src/shaders/_prelude.vertex.glsl
+18 −0 src/shaders/encode_attribute.js
+44 −7 src/shaders/symbol_icon.vertex.glsl
+7 −4 src/shaders/symbol_sdf.fragment.glsl
+60 −11 src/shaders/symbol_sdf.vertex.glsl
+15 −3 src/source/image_source.js
+7 −0 src/style-spec/README.md
+61 −14 src/style-spec/function/index.js
+2 −0 src/style-spec/reference/v8.json
+23 −3 src/style/style_declaration.js
+25 −0 src/style/style_layer.js
+ test/integration/render-tests/icon-size/camera-function-high-base-plain/expected.png
+50 −0 test/integration/render-tests/icon-size/camera-function-high-base-plain/style.json
+ test/integration/render-tests/icon-size/camera-function-high-base-sdf/expected.png
+50 −0 test/integration/render-tests/icon-size/camera-function-high-base-sdf/style.json
+ test/integration/render-tests/icon-size/camera-function-plain/expected.png
+49 −0 test/integration/render-tests/icon-size/camera-function-plain/style.json
+ test/integration/render-tests/icon-size/camera-function-sdf/expected.png
+49 −0 test/integration/render-tests/icon-size/camera-function-sdf/style.json
+ test/integration/render-tests/icon-size/composite-function-high-base-plain/expected.png
+54 −0 test/integration/render-tests/icon-size/composite-function-high-base-plain/style.json
+ test/integration/render-tests/icon-size/composite-function-high-base-sdf/expected.png
+54 −0 test/integration/render-tests/icon-size/composite-function-high-base-sdf/style.json
+ test/integration/render-tests/icon-size/composite-function-plain/expected.png
+50 −0 test/integration/render-tests/icon-size/composite-function-plain/style.json
+ test/integration/render-tests/icon-size/composite-function-sdf/expected.png
+50 −0 test/integration/render-tests/icon-size/composite-function-sdf/style.json
+ test/integration/render-tests/icon-size/property-function-plain/expected.png
+66 −0 test/integration/render-tests/icon-size/property-function-plain/style.json
+ test/integration/render-tests/icon-size/property-function-sdf/expected.png
+66 −0 test/integration/render-tests/icon-size/property-function-sdf/style.json
+ test/integration/render-tests/regressions/mapbox-gl-js#4550/expected.png
+34 −0 test/integration/render-tests/regressions/mapbox-gl-js#4550/style.json
+ test/integration/render-tests/text-size/camera-function-high-base/expected.png
+58 −0 test/integration/render-tests/text-size/camera-function-high-base/style.json
+ test/integration/render-tests/text-size/camera-function-interval/expected.png
+44 −0 test/integration/render-tests/text-size/camera-function-interval/style.json
+ test/integration/render-tests/text-size/composite-function-high-base/expected.png
+67 −0 test/integration/render-tests/text-size/composite-function-high-base/style.json
+ test/integration/render-tests/text-size/composite-function-line-placement/expected.png
+62 −0 test/integration/render-tests/text-size/composite-function-line-placement/style.json
+ test/integration/render-tests/text-size/composite-function/expected.png
+63 −0 test/integration/render-tests/text-size/composite-function/style.json
+ test/integration/render-tests/text-size/property-function/expected.png
+66 −0 test/integration/render-tests/text-size/property-function/style.json
+10 −0 test/node_modules/mapbox-gl-js-test.js
+2 −3 test/unit/data/bucket.test.js
+15 −0 test/unit/shaders/encode_attribute.test.js
+15 −15 test/unit/style-spec/function.test.js
+13 −0 test/unit/util/struct_array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1526,11 +1526,11 @@ public static PropertyValue<Float> iconSize(Float value) {
/**
* Scale factor for icon. 1 is original size, 3 triples the size.
*
* @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>> iconSize(CameraFunction<Z, Float> function) {
public static <T> PropertyValue<Function<T, Float>> iconSize(Function<T, Float> function) {
return new LayoutPropertyValue<>("icon-size", function);
}

Expand Down Expand Up @@ -1802,11 +1802,11 @@ public static PropertyValue<Float> textSize(Float value) {
/**
* Font size.
*
* @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>> textSize(CameraFunction<Z, Float> function) {
public static <T> PropertyValue<Function<T, Float>> textSize(Function<T, Float> function) {
return new LayoutPropertyValue<>("text-size", function);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,114 @@ public void testIconSizeAsCameraFunction() {
}


@Test
public void testIconSizeAsIdentitySourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("icon-size");
assertNotNull(layer);

// Set
layer.setProperties(
iconSize(property("FeaturePropertyA", Stops.<Float>identity()))
);

// Verify
assertNotNull(layer.getIconSize());
assertNotNull(layer.getIconSize().getFunction());
assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty());
assertEquals(IdentityStops.class, layer.getIconSize().getFunction().getStops().getClass());
}

@Test
public void testIconSizeAsExponentialSourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("icon-size");
assertNotNull(layer);

// Set
layer.setProperties(
iconSize(
property(
"FeaturePropertyA",
exponential(
stop(0.3f, iconSize(0.3f))
).withBase(0.5f)
)
)
);

// Verify
assertNotNull(layer.getIconSize());
assertNotNull(layer.getIconSize().getFunction());
assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty());
assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass());
}

@Test
public void testIconSizeAsCategoricalSourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("icon-size");
assertNotNull(layer);

// Set
layer.setProperties(
iconSize(
property(
"FeaturePropertyA",
categorical(
stop(1.0f, iconSize(0.3f))
)
).withDefaultValue(iconSize(0.3f))
)
);

// Verify
assertNotNull(layer.getIconSize());
assertNotNull(layer.getIconSize().getFunction());
assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty());
assertEquals(CategoricalStops.class, layer.getIconSize().getFunction().getStops().getClass());
assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue());
assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue());
assertEquals(0.3f, ((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue());
}

@Test
public void testIconSizeAsCompositeFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("icon-size");
assertNotNull(layer);

// Set
layer.setProperties(
iconSize(
composite(
"FeaturePropertyA",
exponential(
stop(0, 0.3f, iconSize(0.9f))
).withBase(0.5f)
).withDefaultValue(iconSize(0.3f))
)
);

// Verify
assertNotNull(layer.getIconSize());
assertNotNull(layer.getIconSize().getFunction());
assertEquals(CompositeFunction.class, layer.getIconSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconSize().getFunction()).getProperty());
assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass());
assertEquals(1, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).size());

ExponentialStops<Stop.CompositeValue<Float, Float>, Float> stops =
(ExponentialStops<Stop.CompositeValue<Float, Float>, Float>) layer.getIconSize().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 testIconTextFitAsConstant() {
checkViewIsDisplayed(R.id.mapView);
Expand Down Expand Up @@ -1074,6 +1182,114 @@ public void testTextSizeAsCameraFunction() {
}


@Test
public void testTextSizeAsIdentitySourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("text-size");
assertNotNull(layer);

// Set
layer.setProperties(
textSize(property("FeaturePropertyA", Stops.<Float>identity()))
);

// Verify
assertNotNull(layer.getTextSize());
assertNotNull(layer.getTextSize().getFunction());
assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty());
assertEquals(IdentityStops.class, layer.getTextSize().getFunction().getStops().getClass());
}

@Test
public void testTextSizeAsExponentialSourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("text-size");
assertNotNull(layer);

// Set
layer.setProperties(
textSize(
property(
"FeaturePropertyA",
exponential(
stop(0.3f, textSize(0.3f))
).withBase(0.5f)
)
)
);

// Verify
assertNotNull(layer.getTextSize());
assertNotNull(layer.getTextSize().getFunction());
assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty());
assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass());
}

@Test
public void testTextSizeAsCategoricalSourceFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("text-size");
assertNotNull(layer);

// Set
layer.setProperties(
textSize(
property(
"FeaturePropertyA",
categorical(
stop(1.0f, textSize(0.3f))
)
).withDefaultValue(textSize(0.3f))
)
);

// Verify
assertNotNull(layer.getTextSize());
assertNotNull(layer.getTextSize().getFunction());
assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty());
assertEquals(CategoricalStops.class, layer.getTextSize().getFunction().getStops().getClass());
assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue());
assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue());
assertEquals(0.3f, ((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue());
}

@Test
public void testTextSizeAsCompositeFunction() {
checkViewIsDisplayed(R.id.mapView);
Timber.i("text-size");
assertNotNull(layer);

// Set
layer.setProperties(
textSize(
composite(
"FeaturePropertyA",
exponential(
stop(0, 0.3f, textSize(0.9f))
).withBase(0.5f)
).withDefaultValue(textSize(0.3f))
)
);

// Verify
assertNotNull(layer.getTextSize());
assertNotNull(layer.getTextSize().getFunction());
assertEquals(CompositeFunction.class, layer.getTextSize().getFunction().getClass());
assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextSize().getFunction()).getProperty());
assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass());
assertEquals(1, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).size());

ExponentialStops<Stop.CompositeValue<Float, Float>, Float> stops =
(ExponentialStops<Stop.CompositeValue<Float, Float>, Float>) layer.getTextSize().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 testTextMaxWidthAsConstant() {
checkViewIsDisplayed(R.id.mapView);
Expand Down
18 changes: 18 additions & 0 deletions platform/darwin/src/MGLSymbolStyleLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,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 *> *iconScale;

Expand Down Expand Up @@ -919,6 +928,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 *> *textFontSize;

Expand Down
Loading

0 comments on commit 693c9f3

Please sign in to comment.