diff options
69 files changed, 1212 insertions, 1058 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index bbfec6a4c2..adbaed8333 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -236,7 +236,6 @@ set(MBGL_CORE_FILES include/mbgl/style/types.hpp src/mbgl/style/bucket_parameters.cpp src/mbgl/style/bucket_parameters.hpp - src/mbgl/style/calculation_parameters.hpp src/mbgl/style/cascade_parameters.hpp src/mbgl/style/class_dictionary.cpp src/mbgl/style/class_dictionary.hpp @@ -249,6 +248,7 @@ set(MBGL_CORE_FILES src/mbgl/style/paint_property.hpp src/mbgl/style/parser.cpp src/mbgl/style/parser.hpp + src/mbgl/style/property_evaluation_parameters.hpp src/mbgl/style/property_evaluator.cpp src/mbgl/style/property_evaluator.hpp src/mbgl/style/property_parsing.cpp @@ -442,8 +442,10 @@ set(MBGL_CORE_FILES src/mbgl/util/http_header.hpp src/mbgl/util/http_timeout.cpp src/mbgl/util/http_timeout.hpp + src/mbgl/util/ignore.hpp src/mbgl/util/i18n.cpp src/mbgl/util/i18n.hpp + src/mbgl/util/indexed_tuple.hpp src/mbgl/util/interpolate.hpp src/mbgl/util/intersection_tests.cpp src/mbgl/util/intersection_tests.hpp diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp index d7e160fdca..859b683d5e 100644 --- a/include/mbgl/style/property_value.hpp +++ b/include/mbgl/style/property_value.hpp @@ -33,9 +33,9 @@ public: explicit operator bool() const { return !isUndefined(); }; - template <typename Visitor> - static auto visit(const PropertyValue<T>& value, Visitor&& visitor) { - return Value::visit(value.value, visitor); + template <typename Evaluator> + auto evaluate(const Evaluator& evaluator) const { + return Value::visit(value, evaluator); } }; diff --git a/include/mbgl/style/transition_options.hpp b/include/mbgl/style/transition_options.hpp index d7a6633f0c..e2a156e665 100644 --- a/include/mbgl/style/transition_options.hpp +++ b/include/mbgl/style/transition_options.hpp @@ -6,9 +6,21 @@ namespace mbgl { namespace style { -struct TransitionOptions { +class TransitionOptions { +public: optional<Duration> duration = {}; optional<Duration> delay = {}; + + TransitionOptions reverseMerge(const TransitionOptions& defaults) const { + return { + duration ? duration : defaults.duration, + delay ? delay : defaults.delay + }; + } + + explicit operator bool() const { + return duration || delay; + } }; } // namespace style diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 64b913200e..fafcc7c15d 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -7,7 +7,7 @@ using namespace style; SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, const Shaping& shapedText, const PositionedIcon& shapedIcon, - const SymbolLayoutProperties& layout, const bool addToBuffers, const uint32_t index_, + const SymbolLayoutProperties::Evaluated& layout, const bool addToBuffers, const uint32_t index_, const float textBoxScale, const float textPadding, const SymbolPlacementType textPlacement, const float iconBoxScale, const float iconPadding, const SymbolPlacementType iconPlacement, const GlyphPositions& face, const IndexedSubfeature& indexedFeature) : diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 3087bf09f9..508c11a394 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -2,21 +2,18 @@ #include <mbgl/text/quads.hpp> #include <mbgl/text/collision_feature.hpp> +#include <mbgl/style/layers/symbol_layer_properties.hpp> namespace mbgl { struct Anchor; class IndexedSubfeature; -namespace style { -class SymbolLayoutProperties; -} // namespace style - class SymbolInstance { public: explicit SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, const Shaping& shapedText, const PositionedIcon& shapedIcon, - const style::SymbolLayoutProperties&, const bool inside, const uint32_t index, + const style::SymbolLayoutProperties::Evaluated&, const bool inside, const uint32_t index, const float textBoxScale, const float textPadding, style::SymbolPlacementType textPlacement, const float iconBoxScale, const float iconPadding, style::SymbolPlacementType iconPlacement, const GlyphPositions& face, const IndexedSubfeature& indexedfeature); diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 6556d65d3d..9ea779d47b 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -33,7 +33,7 @@ SymbolLayout::SymbolLayout(std::string bucketName_, const MapMode mode_, const GeometryTileLayer& layer, const style::Filter& filter, - style::SymbolLayoutProperties layout_, + style::SymbolLayoutProperties::Evaluated layout_, float textMaxSize_, SpriteAtlas& spriteAtlas_) : bucketName(std::move(bucketName_)), @@ -47,8 +47,8 @@ SymbolLayout::SymbolLayout(std::string bucketName_, tileSize(util::tileSize * overscaling_), tilePixelRatio(float(util::EXTENT) / tileSize) { - const bool hasText = !layout.textField.value.empty() && !layout.textFont.value.empty(); - const bool hasIcon = !layout.iconImage.value.empty(); + const bool hasText = !layout.get<TextField>().empty() && !layout.get<TextFont>().empty(); + const bool hasIcon = !layout.get<IconImage>().empty(); if (!hasText && !hasIcon) { return; @@ -84,11 +84,11 @@ SymbolLayout::SymbolLayout(std::string bucketName_, }; if (hasText) { - std::string u8string = util::replaceTokens(layout.textField, getValue); + std::string u8string = util::replaceTokens(layout.get<TextField>(), getValue); - if (layout.textTransform == TextTransformType::Uppercase) { + if (layout.get<TextTransform>() == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); - } else if (layout.textTransform == TextTransformType::Lowercase) { + } else if (layout.get<TextTransform>() == TextTransformType::Lowercase) { u8string = platform::lowercase(u8string); } @@ -103,7 +103,7 @@ SymbolLayout::SymbolLayout(std::string bucketName_, } if (hasIcon) { - ft.icon = util::replaceTokens(layout.iconImage, getValue); + ft.icon = util::replaceTokens(layout.get<IconImage>(), getValue); } if (ft.text || ft.icon) { @@ -121,7 +121,7 @@ SymbolLayout::SymbolLayout(std::string bucketName_, } } - if (layout.symbolPlacement == SymbolPlacementType::Line) { + if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) { util::mergeLines(features); } } @@ -131,11 +131,11 @@ bool SymbolLayout::hasSymbolInstances() const { } bool SymbolLayout::canPrepare(GlyphAtlas& glyphAtlas) { - if (!layout.textField.value.empty() && !layout.textFont.value.empty() && !glyphAtlas.hasGlyphRanges(layout.textFont, ranges)) { + if (!layout.get<TextField>().empty() && !layout.get<TextFont>().empty() && !glyphAtlas.hasGlyphRanges(layout.get<TextFont>(), ranges)) { return false; } - if (!layout.iconImage.value.empty() && !spriteAtlas.isLoaded()) { + if (!layout.get<IconImage>().empty() && !spriteAtlas.isLoaded()) { return false; } @@ -147,7 +147,7 @@ void SymbolLayout::prepare(uintptr_t tileUID, float horizontalAlign = 0.5; float verticalAlign = 0.5; - switch (layout.textAnchor) { + switch (layout.get<TextAnchor>()) { case TextAnchorType::Top: case TextAnchorType::Bottom: case TextAnchorType::Center: @@ -164,7 +164,7 @@ void SymbolLayout::prepare(uintptr_t tileUID, break; } - switch (layout.textAnchor) { + switch (layout.get<TextAnchor>()) { case TextAnchorType::Left: case TextAnchorType::Right: case TextAnchorType::Center: @@ -181,11 +181,11 @@ void SymbolLayout::prepare(uintptr_t tileUID, break; } - const float justify = layout.textJustify == TextJustifyType::Right ? 1 : - layout.textJustify == TextJustifyType::Left ? 0 : + const float justify = layout.get<TextJustify>() == TextJustifyType::Right ? 1 : + layout.get<TextJustify>() == TextJustifyType::Left ? 0 : 0.5; - auto glyphSet = glyphAtlas.getGlyphSet(layout.textFont); + auto glyphSet = glyphAtlas.getGlyphSet(layout.get<TextFont>()); for (const auto& feature : features) { if (feature.geometry.empty()) continue; @@ -199,18 +199,18 @@ void SymbolLayout::prepare(uintptr_t tileUID, shapedText = glyphSet->getShaping( /* string */ *feature.text, /* base direction of text */ *feature.writingDirection, - /* maxWidth: ems */ layout.symbolPlacement != SymbolPlacementType::Line ? - layout.textMaxWidth * 24 : 0, - /* lineHeight: ems */ layout.textLineHeight * 24, + /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ? + layout.get<TextMaxWidth>() * 24 : 0, + /* lineHeight: ems */ layout.get<TextLineHeight>() * 24, /* horizontalAlign */ horizontalAlign, /* verticalAlign */ verticalAlign, /* justify */ justify, - /* spacing: ems */ layout.textLetterSpacing * 24, - /* translate */ Point<float>(layout.textOffset.value[0], layout.textOffset.value[1])); + /* spacing: ems */ layout.get<TextLetterSpacing>() * 24, + /* translate */ Point<float>(layout.get<TextOffset>()[0], layout.get<TextOffset>()[1])); // Add the glyphs we need for this label to the glyph atlas. if (shapedText) { - glyphAtlas.addGlyphs(tileUID, *feature.text, layout.textFont, **glyphSet, face); + glyphAtlas.addGlyphs(tileUID, *feature.text, layout.get<TextFont>(), **glyphSet, face); } } @@ -225,7 +225,7 @@ void SymbolLayout::prepare(uintptr_t tileUID, } if ((*image).relativePixelRatio != 1.0f) { iconsNeedLinear = true; - } else if (layout.iconRotate != 0) { + } else if (layout.get<IconRotate>() != 0) { iconsNeedLinear = true; } } @@ -247,24 +247,24 @@ void SymbolLayout::addFeature(const GeometryCollection &lines, const float minScale = 0.5f; const float glyphSize = 24.0f; - const float fontScale = layout.textSize / glyphSize; + const float fontScale = layout.get<TextSize>() / glyphSize; const float textBoxScale = tilePixelRatio * fontScale; const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize; - const float iconBoxScale = tilePixelRatio * layout.iconSize; - const float symbolSpacing = tilePixelRatio * layout.symbolSpacing; - const bool avoidEdges = layout.symbolAvoidEdges && layout.symbolPlacement != SymbolPlacementType::Line; - const float textPadding = layout.textPadding * tilePixelRatio; - const float iconPadding = layout.iconPadding * tilePixelRatio; - const float textMaxAngle = layout.textMaxAngle * util::DEG2RAD; - const SymbolPlacementType textPlacement = layout.textRotationAlignment != AlignmentType::Map + const float iconBoxScale = tilePixelRatio * layout.get<IconSize>(); + const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>(); + const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line; + const float textPadding = layout.get<TextPadding>() * tilePixelRatio; + const float iconPadding = layout.get<IconPadding>() * tilePixelRatio; + const float textMaxAngle = layout.get<TextMaxAngle>() * util::DEG2RAD; + const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point - : layout.symbolPlacement; - const SymbolPlacementType iconPlacement = layout.iconRotationAlignment != AlignmentType::Map + : layout.get<SymbolPlacement>(); + const SymbolPlacementType iconPlacement = layout.get<IconRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point - : layout.symbolPlacement; - const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap || - layout.textIgnorePlacement || layout.iconIgnorePlacement; - const bool isLine = layout.symbolPlacement == SymbolPlacementType::Line; + : layout.get<SymbolPlacement>(); + const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() || + layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>(); + const bool isLine = layout.get<SymbolPlacement>() == SymbolPlacementType::Line; const float textRepeatDistance = symbolSpacing / 2; auto& clippedLines = isLine ? @@ -335,15 +335,15 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) // Calculate which labels can be shown and when they can be shown and // create the bufers used for rendering. - const SymbolPlacementType textPlacement = layout.textRotationAlignment != AlignmentType::Map + const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point - : layout.symbolPlacement; - const SymbolPlacementType iconPlacement = layout.iconRotationAlignment != AlignmentType::Map + : layout.get<SymbolPlacement>(); + const SymbolPlacementType iconPlacement = layout.get<IconRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point - : layout.symbolPlacement; + : layout.get<SymbolPlacement>(); - const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap || - layout.textIgnorePlacement || layout.iconIgnorePlacement; + const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() || + layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>(); // Sort symbols by their y position on the canvas so that they lower symbols // are drawn on top of higher symbols. @@ -367,18 +367,18 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) const bool hasText = symbolInstance.hasText; const bool hasIcon = symbolInstance.hasIcon; - const bool iconWithoutText = layout.textOptional || !hasText; - const bool textWithoutIcon = layout.iconOptional || !hasIcon; + const bool iconWithoutText = layout.get<TextOptional>() || !hasText; + const bool textWithoutIcon = layout.get<IconOptional>() || !hasIcon; // Calculate the scales at which the text and icon can be placed without collision. float glyphScale = hasText ? collisionTile.placeFeature(symbolInstance.textCollisionFeature, - layout.textAllowOverlap, layout.symbolAvoidEdges) : + layout.get<TextAllowOverlap>(), layout.get<SymbolAvoidEdges>()) : collisionTile.minScale; float iconScale = hasIcon ? collisionTile.placeFeature(symbolInstance.iconCollisionFeature, - layout.iconAllowOverlap, layout.symbolAvoidEdges) : + layout.get<IconAllowOverlap>(), layout.get<SymbolAvoidEdges>()) : collisionTile.minScale; @@ -396,20 +396,20 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) // Insert final placement into collision tree and add glyphs/icons to buffers if (hasText) { - collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.textIgnorePlacement); + collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.get<TextIgnorePlacement>()); if (glyphScale < collisionTile.maxScale) { addSymbols( bucket->text, symbolInstance.glyphQuads, glyphScale, - layout.textKeepUpright, textPlacement, collisionTile.config.angle); + layout.get<TextKeepUpright>(), textPlacement, collisionTile.config.angle); } } if (hasIcon) { - collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.iconIgnorePlacement); + collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get<IconIgnorePlacement>()); if (iconScale < collisionTile.maxScale) { addSymbols( bucket->icon, symbolInstance.iconQuads, iconScale, - layout.iconKeepUpright, iconPlacement, collisionTile.config.angle); + layout.get<IconKeepUpright>(), iconPlacement, collisionTile.config.angle); } } } diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index c21398fabf..a9a2578950 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -34,7 +34,7 @@ public: const MapMode, const GeometryTileLayer&, const style::Filter&, - style::SymbolLayoutProperties, + style::SymbolLayoutProperties::Evaluated, float textMaxSize, SpriteAtlas&); @@ -78,7 +78,7 @@ private: const float overscaling; const float zoom; const MapMode mode; - const style::SymbolLayoutProperties layout; + const style::SymbolLayoutProperties::Evaluated layout; const float textMaxSize; SpriteAtlas& spriteAtlas; diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index 8c35df1b6e..2cadaa6c11 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -8,10 +8,12 @@ namespace mbgl { +using namespace style; + static_assert(sizeof(LineAttributes::Vertex) == 8, "expected LineVertex size"); template <class Values, class...Args> -Values makeValues(const style::LinePaintProperties& properties, +Values makeValues(const LinePaintProperties::Evaluated& properties, const RenderTile& tile, const TransformState& state, Args&&... args) { @@ -27,14 +29,16 @@ Values makeValues(const style::LinePaintProperties& properties, float x = state.getSize().height / 2.0f * std::tan(state.getPitch()); return Values { - uniforms::u_matrix::Value{ tile.translatedMatrix(properties.lineTranslate.value, - properties.lineTranslateAnchor.value, - state) }, - uniforms::u_opacity::Value{ properties.lineOpacity.value }, - uniforms::u_width::Value{ properties.lineWidth.value }, - uniforms::u_gapwidth::Value{ properties.lineGapWidth.value }, - uniforms::u_blur::Value{ properties.lineBlur.value }, - uniforms::u_offset::Value{ properties.lineOffset.value }, + uniforms::u_matrix::Value{ + tile.translatedMatrix(properties.get<LineTranslate>(), + properties.get<LineTranslateAnchor>(), + state) + }, + uniforms::u_opacity::Value{ properties.get<LineOpacity>() }, + uniforms::u_width::Value{ properties.get<LineWidth>() }, + uniforms::u_gapwidth::Value{ properties.get<LineGapWidth>() }, + uniforms::u_blur::Value{ properties.get<LineBlur>() }, + uniforms::u_offset::Value{ properties.get<LineOffset>() }, uniforms::u_antialiasingmatrix::Value{ antialiasingMatrix }, uniforms::u_ratio::Value{ 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) }, uniforms::u_extra::Value{ (topedgelength + x) / topedgelength - 1.0f }, @@ -43,19 +47,19 @@ Values makeValues(const style::LinePaintProperties& properties, } LineProgram::UniformValues -LineProgram::uniformValues(const style::LinePaintProperties& properties, +LineProgram::uniformValues(const LinePaintProperties::Evaluated& properties, const RenderTile& tile, const TransformState& state) { return makeValues<LineProgram::UniformValues>( properties, tile, state, - uniforms::u_color::Value{ properties.lineColor.value } + uniforms::u_color::Value{ properties.get<LineColor>() } ); } LineSDFProgram::UniformValues -LineSDFProgram::uniformValues(const style::LinePaintProperties& properties, +LineSDFProgram::uniformValues(const LinePaintProperties::Evaluated& properties, float pixelRatio, const RenderTile& tile, const TransformState& state, @@ -63,8 +67,8 @@ LineSDFProgram::uniformValues(const style::LinePaintProperties& properties, const LinePatternPos& posB, float dashLineWidth, float atlasWidth) { - const float widthA = posA.width * properties.lineDasharray.value.fromScale * dashLineWidth; - const float widthB = posB.width * properties.lineDasharray.value.toScale * dashLineWidth; + const float widthA = posA.width * properties.get<LineDasharray>().fromScale * dashLineWidth; + const float widthB = posB.width * properties.get<LineDasharray>().toScale * dashLineWidth; std::array<float, 2> scaleA {{ 1.0f / tile.id.pixelsToTileUnits(widthA, state.getIntegerZoom()), @@ -80,30 +84,30 @@ LineSDFProgram::uniformValues(const style::LinePaintProperties& properties, properties, tile, state, - uniforms::u_color::Value{ properties.lineColor.value }, + uniforms::u_color::Value{ properties.get<LineColor>() }, uniforms::u_patternscale_a::Value{ scaleA }, uniforms::u_patternscale_b::Value{ scaleB }, uniforms::u_tex_y_a::Value{ posA.y }, uniforms::u_tex_y_b::Value{ posB.y }, - uniforms::u_mix::Value{ properties.lineDasharray.value.t }, + uniforms::u_mix::Value{ properties.get<LineDasharray>().t }, uniforms::u_sdfgamma::Value{ atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f }, uniforms::u_image::Value{ 0 } ); } LinePatternProgram::UniformValues -LinePatternProgram::uniformValues(const style::LinePaintProperties& properties, +LinePatternProgram::uniformValues(const LinePaintProperties::Evaluated& properties, const RenderTile& tile, const TransformState& state, const SpriteAtlasPosition& posA, const SpriteAtlasPosition& posB) { std::array<float, 2> sizeA {{ - tile.id.pixelsToTileUnits(posA.size[0] * properties.linePattern.value.fromScale, state.getIntegerZoom()), + tile.id.pixelsToTileUnits(posA.size[0] * properties.get<LinePattern>().fromScale, state.getIntegerZoom()), posA.size[1] }}; std::array<float, 2> sizeB {{ - tile.id.pixelsToTileUnits(posB.size[0] * properties.linePattern.value.toScale, state.getIntegerZoom()), + tile.id.pixelsToTileUnits(posB.size[0] * properties.get<LinePattern>().toScale, state.getIntegerZoom()), posB.size[1] }}; @@ -117,7 +121,7 @@ LinePatternProgram::uniformValues(const style::LinePaintProperties& properties, uniforms::u_pattern_br_b::Value{ posB.br }, uniforms::u_pattern_size_a::Value{ sizeA }, uniforms::u_pattern_size_b::Value{ sizeB }, - uniforms::u_fade::Value{ properties.linePattern.value.t }, + uniforms::u_fade::Value{ properties.get<LinePattern>().t }, uniforms::u_image::Value{ 0 } ); } diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index de3297de96..059806ffb2 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -6,16 +6,13 @@ #include <mbgl/shader/line.hpp> #include <mbgl/shader/line_pattern.hpp> #include <mbgl/shader/line_sdf.hpp> +#include <mbgl/style/layers/line_layer_properties.hpp> #include <mbgl/util/geometry.hpp> #include <cmath> namespace mbgl { -namespace style { -class LinePaintProperties; -} // namespace style - class RenderTile; class TransformState; class LinePatternPos; @@ -104,7 +101,7 @@ class LineProgram : public Program< public: using Program::Program; - static UniformValues uniformValues(const style::LinePaintProperties&, + static UniformValues uniformValues(const style::LinePaintProperties::Evaluated&, const RenderTile&, const TransformState&); }; @@ -135,7 +132,7 @@ class LinePatternProgram : public Program< public: using Program::Program; - static UniformValues uniformValues(const style::LinePaintProperties&, + static UniformValues uniformValues(const style::LinePaintProperties::Evaluated&, const RenderTile&, const TransformState&, const SpriteAtlasPosition& posA, @@ -168,7 +165,7 @@ class LineSDFProgram : public Program< public: using Program::Program; - static UniformValues uniformValues(const style::LinePaintProperties&, + static UniformValues uniformValues(const style::LinePaintProperties::Evaluated&, float pixelRatio, const RenderTile&, const TransformState&, diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 554fef5ca7..007060bd1b 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -64,7 +64,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) { return; } - const float miterLimit = layout.lineJoin == LineJoinType::Bevel ? 1.05f : float(layout.lineMiterLimit); + const float miterLimit = layout.get<LineJoin>() == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>()); const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); @@ -77,8 +77,8 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) { return; } - const LineCapType beginCap = layout.lineCap; - const LineCapType endCap = closed ? LineCapType::Butt : LineCapType(layout.lineCap); + const LineCapType beginCap = layout.get<LineCap>(); + const LineCapType endCap = closed ? LineCapType::Butt : LineCapType(layout.get<LineCap>()); double distance = 0; bool startOfLine = true; @@ -171,12 +171,12 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) { // The join if a middle vertex, otherwise the cap const bool middleVertex = prevCoordinate && nextCoordinate; - LineJoinType currentJoin = layout.lineJoin; + LineJoinType currentJoin = layout.get<LineJoin>(); const LineCapType currentCap = nextCoordinate ? beginCap : endCap; if (middleVertex) { if (currentJoin == LineJoinType::Round) { - if (miterLength < layout.lineRoundLimit) { + if (miterLength < layout.get<LineRoundLimit>()) { currentJoin = LineJoinType::Miter; } else if (miterLength <= 2) { currentJoin = LineJoinType::FakeRound; diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index ae9d7d7f0e..d11d78ff69 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -24,7 +24,7 @@ public: void addGeometry(const GeometryCollection&); void addGeometry(const GeometryCoordinates& line); - style::LineLayoutProperties layout; + style::LineLayoutProperties::Evaluated layout; gl::VertexVector<LineVertex> vertices; gl::IndexVector<gl::Triangles> triangles; diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index 4e87829914..acf327a5d4 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -14,13 +14,13 @@ using namespace style; void Painter::renderBackground(PaintParameters& parameters, const BackgroundLayer& layer) { // Note that for bottommost layers without a pattern, the background color is drawn with // glClear rather than this method. - const BackgroundPaintProperties& properties = layer.impl->paint; + const BackgroundPaintProperties::Evaluated& properties = layer.impl->paint.evaluated; - if (!properties.backgroundPattern.value.to.empty()) { + if (!properties.get<BackgroundPattern>().to.empty()) { optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition( - properties.backgroundPattern.value.from, SpritePatternMode::Repeating); + properties.get<BackgroundPattern>().from, SpritePatternMode::Repeating); optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition( - properties.backgroundPattern.value.to, SpritePatternMode::Repeating); + properties.get<BackgroundPattern>().to, SpritePatternMode::Repeating); if (!imagePosA || !imagePosB) return; @@ -36,11 +36,11 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye colorModeForRenderPass(), FillPatternUniforms::values( matrixForTile(tileID), - properties.backgroundOpacity.value, + properties.get<BackgroundOpacity>(), context.viewport.getCurrentValue().size, *imagePosA, *imagePosB, - properties.backgroundPattern.value, + properties.get<BackgroundPattern>(), tileID, state ), @@ -58,9 +58,9 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye colorModeForRenderPass(), FillProgram::UniformValues { uniforms::u_matrix::Value{ matrixForTile(tileID) }, - uniforms::u_opacity::Value{ properties.backgroundOpacity.value }, - uniforms::u_color::Value{ properties.backgroundColor.value }, - uniforms::u_outline_color::Value{ properties.backgroundColor.value }, + uniforms::u_opacity::Value{ properties.get<BackgroundOpacity>() }, + uniforms::u_color::Value{ properties.get<BackgroundColor>() }, + uniforms::u_outline_color::Value{ properties.get<BackgroundColor>() }, uniforms::u_world::Value{ context.viewport.getCurrentValue().size }, }, tileTriangleVertexBuffer, diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index 763181605f..0767a50943 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -20,8 +20,8 @@ void Painter::renderCircle(PaintParameters& parameters, return; } - const CirclePaintProperties& properties = layer.impl->paint; - const bool scaleWithMap = properties.circlePitchScale.value == CirclePitchScaleType::Map; + const CirclePaintProperties::Evaluated& properties = layer.impl->paint.evaluated; + const bool scaleWithMap = properties.get<CirclePitchScale>() == CirclePitchScaleType::Map; parameters.programs.circle.draw( context, @@ -32,13 +32,15 @@ void Painter::renderCircle(PaintParameters& parameters, : gl::StencilMode::disabled(), colorModeForRenderPass(), CircleProgram::UniformValues { - uniforms::u_matrix::Value{ tile.translatedMatrix(properties.circleTranslate.value, - properties.circleTranslateAnchor.value, - state) }, - uniforms::u_opacity::Value{ properties.circleOpacity.value }, - uniforms::u_color::Value{ properties.circleColor.value }, - uniforms::u_radius::Value{ properties.circleRadius.value }, - uniforms::u_blur::Value{ properties.circleBlur.value }, + uniforms::u_matrix::Value{ + tile.translatedMatrix(properties.get<CircleTranslate>(), + properties.get<CircleTranslateAnchor>(), + state) + }, + uniforms::u_opacity::Value{ properties.get<CircleOpacity>() }, + uniforms::u_color::Value{ properties.get<CircleColor>() }, + uniforms::u_radius::Value{ properties.get<CircleRadius>() }, + uniforms::u_blur::Value{ properties.get<CircleBlur>() }, uniforms::u_scale_with_map::Value{ scaleWithMap }, uniforms::u_extrude_scale::Value{ scaleWithMap ? std::array<float, 2> {{ diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index e5a536fde3..356ccfc0b2 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -17,17 +17,17 @@ void Painter::renderFill(PaintParameters& parameters, FillBucket& bucket, const FillLayer& layer, const RenderTile& tile) { - const FillPaintProperties& properties = layer.impl->paint; + const FillPaintProperties::Evaluated& properties = layer.impl->paint.evaluated; - if (!properties.fillPattern.value.from.empty()) { + if (!properties.get<FillPattern>().from.empty()) { if (pass != RenderPass::Translucent) { return; } optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition( - properties.fillPattern.value.from, SpritePatternMode::Repeating); + properties.get<FillPattern>().from, SpritePatternMode::Repeating); optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition( - properties.fillPattern.value.to, SpritePatternMode::Repeating); + properties.get<FillPattern>().to, SpritePatternMode::Repeating); if (!imagePosA || !imagePosB) { return; @@ -48,14 +48,14 @@ void Painter::renderFill(PaintParameters& parameters, stencilModeForClipping(tile.clip), colorModeForRenderPass(), FillPatternUniforms::values( - tile.translatedMatrix(properties.fillTranslate.value, - properties.fillTranslateAnchor.value, + tile.translatedMatrix(properties.get<FillTranslate>(), + properties.get<FillTranslateAnchor>(), state), - properties.fillOpacity.value, + properties.get<FillOpacity>(), context.viewport.getCurrentValue().size, *imagePosA, *imagePosB, - properties.fillPattern.value, + properties.get<FillPattern>(), tile.id, state ), @@ -72,7 +72,7 @@ void Painter::renderFill(PaintParameters& parameters, *bucket.triangleIndexBuffer, bucket.triangleSegments); - if (!properties.fillAntialias.value || !properties.fillOutlineColor.isUndefined()) { + if (!properties.get<FillAntialias>() || !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined()) { return; } @@ -97,11 +97,11 @@ void Painter::renderFill(PaintParameters& parameters, stencilModeForClipping(tile.clip), colorModeForRenderPass(), FillProgram::UniformValues { - uniforms::u_matrix::Value{ tile.translatedMatrix(properties.fillTranslate.value, - properties.fillTranslateAnchor.value, + uniforms::u_matrix::Value{ tile.translatedMatrix(properties.get<FillTranslate>(), + properties.get<FillTranslateAnchor>(), state) }, - uniforms::u_opacity::Value{ properties.fillOpacity.value }, - uniforms::u_color::Value{ properties.fillColor.value }, + uniforms::u_opacity::Value{ properties.get<FillOpacity>() }, + uniforms::u_color::Value{ properties.get<FillColor>() }, uniforms::u_outline_color::Value{ outlineColor }, uniforms::u_world::Value{ context.viewport.getCurrentValue().size }, }, @@ -111,10 +111,10 @@ void Painter::renderFill(PaintParameters& parameters, ); }; - if (properties.fillAntialias.value && !properties.fillOutlineColor.isUndefined() && pass == RenderPass::Translucent) { + if (properties.get<FillAntialias>() && !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) { draw(2, parameters.programs.fillOutline, - properties.fillOutlineColor.value, + properties.get<FillOutlineColor>(), gl::Lines { 2.0f }, *bucket.vertexBuffer, *bucket.lineIndexBuffer, @@ -123,20 +123,20 @@ void Painter::renderFill(PaintParameters& parameters, // Only draw the fill when it's opaque and we're drawing opaque fragments, // or when it's translucent and we're drawing translucent fragments. - if ((properties.fillColor.value.a >= 1.0f && properties.fillOpacity.value >= 1.0f) == (pass == RenderPass::Opaque)) { + if ((properties.get<FillColor>().a >= 1.0f && properties.get<FillOpacity>() >= 1.0f) == (pass == RenderPass::Opaque)) { draw(1, parameters.programs.fill, - properties.fillOutlineColor.value, + properties.get<FillOutlineColor>(), gl::Triangles(), *bucket.vertexBuffer, *bucket.triangleIndexBuffer, bucket.triangleSegments); } - if (properties.fillAntialias.value && properties.fillOutlineColor.isUndefined() && pass == RenderPass::Translucent) { + if (properties.get<FillAntialias>() && layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) { draw(2, parameters.programs.fillOutline, - properties.fillColor.value, + properties.get<FillColor>(), gl::Lines { 2.0f }, *bucket.vertexBuffer, *bucket.lineIndexBuffer, diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 151228ee95..a66f53a856 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -21,7 +21,7 @@ void Painter::renderLine(PaintParameters& parameters, return; } - const auto& properties = layer.impl->paint; + const LinePaintProperties::Evaluated& properties = layer.impl->paint.evaluated; auto draw = [&] (auto& program, auto&& uniformValues) { program.draw( @@ -37,11 +37,11 @@ void Painter::renderLine(PaintParameters& parameters, ); }; - if (!properties.lineDasharray.value.from.empty()) { - const LinePatternCap cap = bucket.layout.lineCap == LineCapType::Round + if (!properties.get<LineDasharray>().from.empty()) { + const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round : LinePatternCap::Square; - LinePatternPos posA = lineAtlas->getDashPosition(properties.lineDasharray.value.from, cap); - LinePatternPos posB = lineAtlas->getDashPosition(properties.lineDasharray.value.to, cap); + LinePatternPos posA = lineAtlas->getDashPosition(properties.get<LineDasharray>().from, cap); + LinePatternPos posB = lineAtlas->getDashPosition(properties.get<LineDasharray>().to, cap); lineAtlas->bind(context, 0); @@ -56,11 +56,11 @@ void Painter::renderLine(PaintParameters& parameters, layer.impl->dashLineWidth, lineAtlas->getSize().width)); - } else if (!properties.linePattern.value.from.empty()) { + } else if (!properties.get<LinePattern>().from.empty()) { optional<SpriteAtlasPosition> posA = spriteAtlas->getPosition( - properties.linePattern.value.from, SpritePatternMode::Repeating); + properties.get<LinePattern>().from, SpritePatternMode::Repeating); optional<SpriteAtlasPosition> posB = spriteAtlas->getPosition( - properties.linePattern.value.to, SpritePatternMode::Repeating); + properties.get<LinePattern>().to, SpritePatternMode::Repeating); if (!posA || !posB) return; diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index fe25878016..950d37abf2 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -48,7 +48,7 @@ void Painter::renderRaster(PaintParameters& parameters, if (!bucket.hasData()) return; - const RasterPaintProperties& properties = layer.impl->paint; + const RasterPaintProperties::Evaluated& properties = layer.impl->paint.evaluated; assert(bucket.texture); context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear); @@ -64,13 +64,13 @@ void Painter::renderRaster(PaintParameters& parameters, uniforms::u_matrix::Value{ tile.matrix }, uniforms::u_image0::Value{ 0 }, uniforms::u_image1::Value{ 1 }, - uniforms::u_opacity0::Value{ properties.rasterOpacity.value }, + uniforms::u_opacity0::Value{ properties.get<RasterOpacity>() }, uniforms::u_opacity1::Value{ 0 }, - uniforms::u_brightness_low::Value{ properties.rasterBrightnessMin.value }, - uniforms::u_brightness_high::Value{ properties.rasterBrightnessMax.value }, - uniforms::u_saturation_factor::Value{ saturationFactor(properties.rasterSaturation.value) }, - uniforms::u_contrast_factor::Value{ contrastFactor(properties.rasterContrast.value) }, - uniforms::u_spin_weights::Value{ spinWeights(properties.rasterHueRotate.value) }, + uniforms::u_brightness_low::Value{ properties.get<RasterBrightnessMin>() }, + uniforms::u_brightness_high::Value{ properties.get<RasterBrightnessMax>() }, + uniforms::u_saturation_factor::Value{ saturationFactor(properties.get<RasterSaturation>()) }, + uniforms::u_contrast_factor::Value{ contrastFactor(properties.get<RasterContrast>()) }, + uniforms::u_spin_weights::Value{ spinWeights(properties.get<RasterHueRotate>()) }, uniforms::u_buffer_scale::Value{ 1.0f }, uniforms::u_scale_parent::Value{ 1.0f }, uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} }, diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 8c1948e458..d4effe3f9d 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -43,8 +43,8 @@ void Painter::renderSymbol(PaintParameters& parameters, // tile edges the icons are included in both tiles and clipped when drawing. // // TODO remove the `true ||` when #1673 is implemented - const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.textAllowOverlap || layout.iconAllowOverlap || - layout.textIgnorePlacement || layout.iconIgnorePlacement)); + const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() || + layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>())); program.draw( context, diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 81170646bc..0f2c89339f 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -7,7 +7,7 @@ namespace mbgl { using namespace style; SymbolBucket::SymbolBucket(const MapMode mode_, - style::SymbolLayoutProperties layout_, + style::SymbolLayoutProperties::Evaluated layout_, bool sdfIcons_, bool iconsNeedLinear_) : mode(mode_), diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index e5c44d8a3c..d62a61aab7 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -17,7 +17,7 @@ namespace mbgl { class SymbolBucket : public Bucket { public: SymbolBucket(const MapMode, - style::SymbolLayoutProperties, + style::SymbolLayoutProperties::Evaluated, bool sdfIcons, bool iconsNeedLinear); @@ -29,7 +29,7 @@ public: bool hasCollisionBoxData() const; const MapMode mode; - const style::SymbolLayoutProperties layout; + const style::SymbolLayoutProperties::Evaluated layout; const bool sdfIcons; const bool iconsNeedLinear; diff --git a/src/mbgl/style/class_dictionary.hpp b/src/mbgl/style/class_dictionary.hpp index e609fb5303..37eb488240 100644 --- a/src/mbgl/style/class_dictionary.hpp +++ b/src/mbgl/style/class_dictionary.hpp @@ -9,7 +9,6 @@ namespace mbgl { namespace style { enum class ClassID : uint32_t { - Fallback = 0, // These values are from the fallback properties Default = 1, // These values are from the default style for a layer Named = 2 // These values (and all subsequent IDs) are from a named style from the layer }; diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp index 4bf2956a6d..38ac32e1de 100644 --- a/src/mbgl/style/layer_impl.hpp +++ b/src/mbgl/style/layer_impl.hpp @@ -19,7 +19,7 @@ class Bucket; namespace style { class CascadeParameters; -class CalculationParameters; +class PropertyEvaluationParameters; class BucketParameters; /** @@ -57,7 +57,7 @@ public: // Fully evaluate cascaded paint properties based on a zoom level. // Returns true if any paint properties have active transitions. - virtual bool recalculate(const CalculationParameters&) = 0; + virtual bool evaluate(const PropertyEvaluationParameters&) = 0; virtual std::unique_ptr<Bucket> createBucket(BucketParameters&) const = 0; diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index 5e5faf37e6..a54115d1a7 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -42,13 +42,13 @@ PropertyValue<Color> BackgroundLayer::getDefaultBackgroundColor() { } PropertyValue<Color> BackgroundLayer::getBackgroundColor(const optional<std::string>& klass) const { - return impl->paint.backgroundColor.get(klass); + return impl->paint.get<BackgroundColor>(klass); } void BackgroundLayer::setBackgroundColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getBackgroundColor(klass)) return; - impl->paint.backgroundColor.set(value, klass); + impl->paint.set<BackgroundColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -57,13 +57,13 @@ PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() { } PropertyValue<std::string> BackgroundLayer::getBackgroundPattern(const optional<std::string>& klass) const { - return impl->paint.backgroundPattern.get(klass); + return impl->paint.get<BackgroundPattern>(klass); } void BackgroundLayer::setBackgroundPattern(PropertyValue<std::string> value, const optional<std::string>& klass) { if (value == getBackgroundPattern(klass)) return; - impl->paint.backgroundPattern.set(value, klass); + impl->paint.set<BackgroundPattern>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -72,13 +72,13 @@ PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() { } PropertyValue<float> BackgroundLayer::getBackgroundOpacity(const optional<std::string>& klass) const { - return impl->paint.backgroundOpacity.get(klass); + return impl->paint.get<BackgroundOpacity>(klass); } void BackgroundLayer::setBackgroundOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getBackgroundOpacity(klass)) return; - impl->paint.backgroundOpacity.set(value, klass); + impl->paint.set<BackgroundOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp index ea389b828e..9a7db9416e 100644 --- a/src/mbgl/style/layers/background_layer_impl.cpp +++ b/src/mbgl/style/layers/background_layer_impl.cpp @@ -8,12 +8,12 @@ void BackgroundLayer::Impl::cascade(const CascadeParameters& parameters) { paint.cascade(parameters); } -bool BackgroundLayer::Impl::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = paint.recalculate(parameters); +bool BackgroundLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) { + paint.evaluate(parameters); - passes = paint.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None; + passes = paint.evaluated.get<BackgroundOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None; - return hasTransitions; + return paint.hasTransition(); } std::unique_ptr<Bucket> BackgroundLayer::Impl::createBucket(BucketParameters&) const { diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp index abbb740f42..6ede1b7d97 100644 --- a/src/mbgl/style/layers/background_layer_impl.hpp +++ b/src/mbgl/style/layers/background_layer_impl.hpp @@ -13,7 +13,7 @@ public: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) override; - bool recalculate(const CalculationParameters&) override; + bool evaluate(const PropertyEvaluationParameters&) override; std::unique_ptr<Bucket> createBucket(BucketParameters&) const override; diff --git a/src/mbgl/style/layers/background_layer_properties.cpp b/src/mbgl/style/layers/background_layer_properties.cpp index 558093a255..ba3e638977 100644 --- a/src/mbgl/style/layers/background_layer_properties.cpp +++ b/src/mbgl/style/layers/background_layer_properties.cpp @@ -5,21 +5,5 @@ namespace mbgl { namespace style { -void BackgroundPaintProperties::cascade(const CascadeParameters& parameters) { - backgroundColor.cascade(parameters); - backgroundPattern.cascade(parameters); - backgroundOpacity.cascade(parameters); -} - -bool BackgroundPaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - - hasTransitions |= backgroundColor.calculate(parameters); - hasTransitions |= backgroundPattern.calculate(parameters); - hasTransitions |= backgroundOpacity.calculate(parameters); - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp index 78a35a4f0c..792bf3de94 100644 --- a/src/mbgl/style/layers/background_layer_properties.hpp +++ b/src/mbgl/style/layers/background_layer_properties.hpp @@ -9,18 +9,23 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; +struct BackgroundColor : PaintProperty<Color> { + static Color defaultValue() { return Color::black(); } +}; -class BackgroundPaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); +struct BackgroundPattern : CrossFadedPaintProperty<std::string> { + static std::string defaultValue() { return ""; } +}; - PaintProperty<Color> backgroundColor { Color::black() }; - PaintProperty<std::string, CrossFadedPropertyEvaluator> backgroundPattern { "" }; - PaintProperty<float> backgroundOpacity { 1 }; +struct BackgroundOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } }; +class BackgroundPaintProperties : public PaintProperties< + BackgroundColor, + BackgroundPattern, + BackgroundOpacity +> {}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index a2b8d316d6..ce01a12ff2 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -67,13 +67,13 @@ PropertyValue<float> CircleLayer::getDefaultCircleRadius() { } PropertyValue<float> CircleLayer::getCircleRadius(const optional<std::string>& klass) const { - return impl->paint.circleRadius.get(klass); + return impl->paint.get<CircleRadius>(klass); } void CircleLayer::setCircleRadius(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getCircleRadius(klass)) return; - impl->paint.circleRadius.set(value, klass); + impl->paint.set<CircleRadius>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -82,13 +82,13 @@ PropertyValue<Color> CircleLayer::getDefaultCircleColor() { } PropertyValue<Color> CircleLayer::getCircleColor(const optional<std::string>& klass) const { - return impl->paint.circleColor.get(klass); + return impl->paint.get<CircleColor>(klass); } void CircleLayer::setCircleColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getCircleColor(klass)) return; - impl->paint.circleColor.set(value, klass); + impl->paint.set<CircleColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -97,13 +97,13 @@ PropertyValue<float> CircleLayer::getDefaultCircleBlur() { } PropertyValue<float> CircleLayer::getCircleBlur(const optional<std::string>& klass) const { - return impl->paint.circleBlur.get(klass); + return impl->paint.get<CircleBlur>(klass); } void CircleLayer::setCircleBlur(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getCircleBlur(klass)) return; - impl->paint.circleBlur.set(value, klass); + impl->paint.set<CircleBlur>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -112,13 +112,13 @@ PropertyValue<float> CircleLayer::getDefaultCircleOpacity() { } PropertyValue<float> CircleLayer::getCircleOpacity(const optional<std::string>& klass) const { - return impl->paint.circleOpacity.get(klass); + return impl->paint.get<CircleOpacity>(klass); } void CircleLayer::setCircleOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getCircleOpacity(klass)) return; - impl->paint.circleOpacity.set(value, klass); + impl->paint.set<CircleOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -127,13 +127,13 @@ PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() { } PropertyValue<std::array<float, 2>> CircleLayer::getCircleTranslate(const optional<std::string>& klass) const { - return impl->paint.circleTranslate.get(klass); + return impl->paint.get<CircleTranslate>(klass); } void CircleLayer::setCircleTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) { if (value == getCircleTranslate(klass)) return; - impl->paint.circleTranslate.set(value, klass); + impl->paint.set<CircleTranslate>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -142,13 +142,13 @@ PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor( } PropertyValue<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor(const optional<std::string>& klass) const { - return impl->paint.circleTranslateAnchor.get(klass); + return impl->paint.get<CircleTranslateAnchor>(klass); } void CircleLayer::setCircleTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) { if (value == getCircleTranslateAnchor(klass)) return; - impl->paint.circleTranslateAnchor.set(value, klass); + impl->paint.set<CircleTranslateAnchor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -157,13 +157,13 @@ PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() { } PropertyValue<CirclePitchScaleType> CircleLayer::getCirclePitchScale(const optional<std::string>& klass) const { - return impl->paint.circlePitchScale.get(klass); + return impl->paint.get<CirclePitchScale>(klass); } void CircleLayer::setCirclePitchScale(PropertyValue<CirclePitchScaleType> value, const optional<std::string>& klass) { if (value == getCirclePitchScale(klass)) return; - impl->paint.circlePitchScale.set(value, klass); + impl->paint.set<CirclePitchScale>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp index 33699b6665..6599126702 100644 --- a/src/mbgl/style/layers/circle_layer_impl.cpp +++ b/src/mbgl/style/layers/circle_layer_impl.cpp @@ -12,13 +12,13 @@ void CircleLayer::Impl::cascade(const CascadeParameters& parameters) { paint.cascade(parameters); } -bool CircleLayer::Impl::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = paint.recalculate(parameters); +bool CircleLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) { + paint.evaluate(parameters); - passes = (paint.circleRadius > 0 && paint.circleColor.value.a > 0 && paint.circleOpacity > 0) + passes = (paint.evaluated.get<CircleRadius>() > 0 && paint.evaluated.get<CircleColor>().a > 0 && paint.evaluated.get<CircleOpacity>() > 0) ? RenderPass::Translucent : RenderPass::None; - return hasTransitions; + return paint.hasTransition(); } std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(BucketParameters& parameters) const { @@ -35,8 +35,8 @@ std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(BucketParameters& parame } float CircleLayer::Impl::getQueryRadius() const { - const std::array<float, 2>& translate = paint.circleTranslate; - return paint.circleRadius + util::length(translate[0], translate[1]); + const std::array<float, 2>& translate = paint.evaluated.get<CircleTranslate>(); + return paint.evaluated.get<CircleRadius>() + util::length(translate[0], translate[1]); } bool CircleLayer::Impl::queryIntersectsGeometry( @@ -46,9 +46,9 @@ bool CircleLayer::Impl::queryIntersectsGeometry( const float pixelsToTileUnits) const { auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( - queryGeometry, paint.circleTranslate, paint.circleTranslateAnchor, bearing, pixelsToTileUnits); + queryGeometry, paint.evaluated.get<CircleTranslate>(), paint.evaluated.get<CircleTranslateAnchor>(), bearing, pixelsToTileUnits); - auto circleRadius = paint.circleRadius * pixelsToTileUnits; + auto circleRadius = paint.evaluated.get<CircleRadius>() * pixelsToTileUnits; return util::polygonIntersectsBufferedMultiPoint( translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius); diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp index 14baaf84e4..df3b34cc1a 100644 --- a/src/mbgl/style/layers/circle_layer_impl.hpp +++ b/src/mbgl/style/layers/circle_layer_impl.hpp @@ -13,7 +13,7 @@ public: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) override; - bool recalculate(const CalculationParameters&) override; + bool evaluate(const PropertyEvaluationParameters&) override; std::unique_ptr<Bucket> createBucket(BucketParameters&) const override; diff --git a/src/mbgl/style/layers/circle_layer_properties.cpp b/src/mbgl/style/layers/circle_layer_properties.cpp index 7243cf87f4..af727fa36f 100644 --- a/src/mbgl/style/layers/circle_layer_properties.cpp +++ b/src/mbgl/style/layers/circle_layer_properties.cpp @@ -5,29 +5,5 @@ namespace mbgl { namespace style { -void CirclePaintProperties::cascade(const CascadeParameters& parameters) { - circleRadius.cascade(parameters); - circleColor.cascade(parameters); - circleBlur.cascade(parameters); - circleOpacity.cascade(parameters); - circleTranslate.cascade(parameters); - circleTranslateAnchor.cascade(parameters); - circlePitchScale.cascade(parameters); -} - -bool CirclePaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - - hasTransitions |= circleRadius.calculate(parameters); - hasTransitions |= circleColor.calculate(parameters); - hasTransitions |= circleBlur.calculate(parameters); - hasTransitions |= circleOpacity.calculate(parameters); - hasTransitions |= circleTranslate.calculate(parameters); - hasTransitions |= circleTranslateAnchor.calculate(parameters); - hasTransitions |= circlePitchScale.calculate(parameters); - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index 0166bc8be4..b7f279de4b 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -9,22 +9,43 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; - -class CirclePaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); - - PaintProperty<float> circleRadius { 5 }; - PaintProperty<Color> circleColor { Color::black() }; - PaintProperty<float> circleBlur { 0 }; - PaintProperty<float> circleOpacity { 1 }; - PaintProperty<std::array<float, 2>> circleTranslate { {{ 0, 0 }} }; - PaintProperty<TranslateAnchorType> circleTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty<CirclePitchScaleType> circlePitchScale { CirclePitchScaleType::Map }; +struct CircleRadius : PaintProperty<float> { + static float defaultValue() { return 5; } }; +struct CircleColor : PaintProperty<Color> { + static Color defaultValue() { return Color::black(); } +}; + +struct CircleBlur : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct CircleOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct CircleTranslate : PaintProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct CircleTranslateAnchor : PaintProperty<TranslateAnchorType> { + static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } +}; + +struct CirclePitchScale : PaintProperty<CirclePitchScaleType> { + static CirclePitchScaleType defaultValue() { return CirclePitchScaleType::Map; } +}; + +class CirclePaintProperties : public PaintProperties< + CircleRadius, + CircleColor, + CircleBlur, + CircleOpacity, + CircleTranslate, + CircleTranslateAnchor, + CirclePitchScale +> {}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp index 1126d57552..50dcc0dda9 100644 --- a/src/mbgl/style/layers/custom_layer_impl.cpp +++ b/src/mbgl/style/layers/custom_layer_impl.cpp @@ -62,7 +62,7 @@ void CustomLayer::Impl::render(const TransformState& state) const { renderFn(context, parameters); } -bool CustomLayer::Impl::recalculate(const CalculationParameters&) { +bool CustomLayer::Impl::evaluate(const PropertyEvaluationParameters&) { passes = RenderPass::Translucent; return false; } diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp index b5b626ca5e..56e3f3146c 100644 --- a/src/mbgl/style/layers/custom_layer_impl.hpp +++ b/src/mbgl/style/layers/custom_layer_impl.hpp @@ -29,7 +29,7 @@ private: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) final {} - bool recalculate(const CalculationParameters&) final; + bool evaluate(const PropertyEvaluationParameters&) final; std::unique_ptr<Bucket> createBucket(BucketParameters&) const final; diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index c61de81d1a..3bea9b56b0 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -67,13 +67,13 @@ PropertyValue<bool> FillLayer::getDefaultFillAntialias() { } PropertyValue<bool> FillLayer::getFillAntialias(const optional<std::string>& klass) const { - return impl->paint.fillAntialias.get(klass); + return impl->paint.get<FillAntialias>(klass); } void FillLayer::setFillAntialias(PropertyValue<bool> value, const optional<std::string>& klass) { if (value == getFillAntialias(klass)) return; - impl->paint.fillAntialias.set(value, klass); + impl->paint.set<FillAntialias>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -82,13 +82,13 @@ PropertyValue<float> FillLayer::getDefaultFillOpacity() { } PropertyValue<float> FillLayer::getFillOpacity(const optional<std::string>& klass) const { - return impl->paint.fillOpacity.get(klass); + return impl->paint.get<FillOpacity>(klass); } void FillLayer::setFillOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getFillOpacity(klass)) return; - impl->paint.fillOpacity.set(value, klass); + impl->paint.set<FillOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -97,13 +97,13 @@ PropertyValue<Color> FillLayer::getDefaultFillColor() { } PropertyValue<Color> FillLayer::getFillColor(const optional<std::string>& klass) const { - return impl->paint.fillColor.get(klass); + return impl->paint.get<FillColor>(klass); } void FillLayer::setFillColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getFillColor(klass)) return; - impl->paint.fillColor.set(value, klass); + impl->paint.set<FillColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -112,13 +112,13 @@ PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() { } PropertyValue<Color> FillLayer::getFillOutlineColor(const optional<std::string>& klass) const { - return impl->paint.fillOutlineColor.get(klass); + return impl->paint.get<FillOutlineColor>(klass); } void FillLayer::setFillOutlineColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getFillOutlineColor(klass)) return; - impl->paint.fillOutlineColor.set(value, klass); + impl->paint.set<FillOutlineColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -127,13 +127,13 @@ PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() { } PropertyValue<std::array<float, 2>> FillLayer::getFillTranslate(const optional<std::string>& klass) const { - return impl->paint.fillTranslate.get(klass); + return impl->paint.get<FillTranslate>(klass); } void FillLayer::setFillTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) { if (value == getFillTranslate(klass)) return; - impl->paint.fillTranslate.set(value, klass); + impl->paint.set<FillTranslate>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -142,13 +142,13 @@ PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() { } PropertyValue<TranslateAnchorType> FillLayer::getFillTranslateAnchor(const optional<std::string>& klass) const { - return impl->paint.fillTranslateAnchor.get(klass); + return impl->paint.get<FillTranslateAnchor>(klass); } void FillLayer::setFillTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) { if (value == getFillTranslateAnchor(klass)) return; - impl->paint.fillTranslateAnchor.set(value, klass); + impl->paint.set<FillTranslateAnchor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -157,13 +157,13 @@ PropertyValue<std::string> FillLayer::getDefaultFillPattern() { } PropertyValue<std::string> FillLayer::getFillPattern(const optional<std::string>& klass) const { - return impl->paint.fillPattern.get(klass); + return impl->paint.get<FillPattern>(klass); } void FillLayer::setFillPattern(PropertyValue<std::string> value, const optional<std::string>& klass) { if (value == getFillPattern(klass)) return; - impl->paint.fillPattern.set(value, klass); + impl->paint.set<FillPattern>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp index fc439f1cd1..6a690ba447 100644 --- a/src/mbgl/style/layers/fill_layer_impl.cpp +++ b/src/mbgl/style/layers/fill_layer_impl.cpp @@ -12,22 +12,22 @@ void FillLayer::Impl::cascade(const CascadeParameters& parameters) { paint.cascade(parameters); } -bool FillLayer::Impl::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = paint.recalculate(parameters); +bool FillLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) { + paint.evaluate(parameters); passes = RenderPass::None; - if (paint.fillAntialias) { + if (paint.evaluated.get<FillAntialias>()) { passes |= RenderPass::Translucent; } - if (!paint.fillPattern.value.from.empty() || (paint.fillColor.value.a * paint.fillOpacity) < 1.0f) { + if (!paint.evaluated.get<FillPattern>().from.empty() || (paint.evaluated.get<FillColor>().a * paint.evaluated.get<FillOpacity>()) < 1.0f) { passes |= RenderPass::Translucent; } else { passes |= RenderPass::Opaque; } - return hasTransitions; + return paint.hasTransition(); } std::unique_ptr<Bucket> FillLayer::Impl::createBucket(BucketParameters& parameters) const { @@ -44,7 +44,7 @@ std::unique_ptr<Bucket> FillLayer::Impl::createBucket(BucketParameters& paramete } float FillLayer::Impl::getQueryRadius() const { - const std::array<float, 2>& translate = paint.fillTranslate; + const std::array<float, 2>& translate = paint.evaluated.get<FillTranslate>(); return util::length(translate[0], translate[1]); } @@ -55,7 +55,7 @@ bool FillLayer::Impl::queryIntersectsGeometry( const float pixelsToTileUnits) const { auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( - queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits); + queryGeometry, paint.evaluated.get<FillTranslate>(), paint.evaluated.get<FillTranslateAnchor>(), bearing, pixelsToTileUnits); return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry); } diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp index 54cfb80c86..53276d744a 100644 --- a/src/mbgl/style/layers/fill_layer_impl.hpp +++ b/src/mbgl/style/layers/fill_layer_impl.hpp @@ -13,7 +13,7 @@ public: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) override; - bool recalculate(const CalculationParameters&) override; + bool evaluate(const PropertyEvaluationParameters&) override; std::unique_ptr<Bucket> createBucket(BucketParameters&) const override; diff --git a/src/mbgl/style/layers/fill_layer_properties.cpp b/src/mbgl/style/layers/fill_layer_properties.cpp index 9a55cbc145..b07a083950 100644 --- a/src/mbgl/style/layers/fill_layer_properties.cpp +++ b/src/mbgl/style/layers/fill_layer_properties.cpp @@ -5,29 +5,5 @@ namespace mbgl { namespace style { -void FillPaintProperties::cascade(const CascadeParameters& parameters) { - fillAntialias.cascade(parameters); - fillOpacity.cascade(parameters); - fillColor.cascade(parameters); - fillOutlineColor.cascade(parameters); - fillTranslate.cascade(parameters); - fillTranslateAnchor.cascade(parameters); - fillPattern.cascade(parameters); -} - -bool FillPaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - - hasTransitions |= fillAntialias.calculate(parameters); - hasTransitions |= fillOpacity.calculate(parameters); - hasTransitions |= fillColor.calculate(parameters); - hasTransitions |= fillOutlineColor.calculate(parameters); - hasTransitions |= fillTranslate.calculate(parameters); - hasTransitions |= fillTranslateAnchor.calculate(parameters); - hasTransitions |= fillPattern.calculate(parameters); - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index d12eb8d6f4..b2d926c31e 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -9,22 +9,43 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; - -class FillPaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); - - PaintProperty<bool> fillAntialias { true }; - PaintProperty<float> fillOpacity { 1 }; - PaintProperty<Color> fillColor { Color::black() }; - PaintProperty<Color> fillOutlineColor { {} }; - PaintProperty<std::array<float, 2>> fillTranslate { {{ 0, 0 }} }; - PaintProperty<TranslateAnchorType> fillTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty<std::string, CrossFadedPropertyEvaluator> fillPattern { "" }; +struct FillAntialias : PaintProperty<bool> { + static bool defaultValue() { return true; } }; +struct FillOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct FillColor : PaintProperty<Color> { + static Color defaultValue() { return Color::black(); } +}; + +struct FillOutlineColor : PaintProperty<Color> { + static Color defaultValue() { return {}; } +}; + +struct FillTranslate : PaintProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct FillTranslateAnchor : PaintProperty<TranslateAnchorType> { + static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } +}; + +struct FillPattern : CrossFadedPaintProperty<std::string> { + static std::string defaultValue() { return ""; } +}; + +class FillPaintProperties : public PaintProperties< + FillAntialias, + FillOpacity, + FillColor, + FillOutlineColor, + FillTranslate, + FillTranslateAnchor, + FillPattern +> {}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index c2cbc56a09..dcc78bafe5 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -78,17 +78,17 @@ const Filter& <%- camelize(type) %>Layer::getFilter() const { <% for (const property of layoutProperties) { -%> PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() { - return { <%- defaultValue(property) %> }; + return <%- camelize(property.name) %>::defaultValue(); } PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { - return impl->layout.<%- camelizeWithLeadingLowercase(property.name) %>.get(); + return impl->layout.unevaluated.get<<%- camelize(property.name) %>>(); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue<<%- propertyType(property) %>> value) { if (value == get<%- camelize(property.name) %>()) return; - impl->layout.<%- camelizeWithLeadingLowercase(property.name) %>.set(value); + impl->layout.unevaluated.get<<%- camelize(property.name) %>>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "<%- property.name %>"); } <% } -%> @@ -100,13 +100,13 @@ PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::getDefa } PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(const optional<std::string>& klass) const { - return impl->paint.<%- camelizeWithLeadingLowercase(property.name) %>.get(klass); + return impl->paint.get<<%- camelize(property.name) %>>(klass); } void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue<<%- propertyType(property) %>> value, const optional<std::string>& klass) { if (value == get<%- camelize(property.name) %>(klass)) return; - impl->paint.<%- camelizeWithLeadingLowercase(property.name) %>.set(value, klass); + impl->paint.set<<%- camelize(property.name) %>>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } <% } -%> diff --git a/src/mbgl/style/layers/layer_properties.cpp.ejs b/src/mbgl/style/layers/layer_properties.cpp.ejs index b781a4a9d9..3b287decc0 100644 --- a/src/mbgl/style/layers/layer_properties.cpp.ejs +++ b/src/mbgl/style/layers/layer_properties.cpp.ejs @@ -10,29 +10,5 @@ namespace mbgl { namespace style { -<% if (layoutProperties.length) { -%> -void <%- camelize(type) %>LayoutProperties::recalculate(const CalculationParameters& parameters) { -<% for (const property of layoutProperties) { -%> - <%- camelizeWithLeadingLowercase(property.name) %>.calculate(parameters); -<% } -%> -} - -<% } -%> -void <%- camelize(type) %>PaintProperties::cascade(const CascadeParameters& parameters) { -<% for (const property of paintProperties) { -%> - <%- camelizeWithLeadingLowercase(property.name) %>.cascade(parameters); -<% } -%> -} - -bool <%- camelize(type) %>PaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - -<% for (const property of paintProperties) { -%> - hasTransitions |= <%- camelizeWithLeadingLowercase(property.name) %>.calculate(parameters); -<% } -%> - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 0c91ecba8c..f490a636f9 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -14,33 +14,35 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; - -<% if (layoutProperties.length) { -%> -class <%- camelize(type) %>LayoutProperties { -public: - void recalculate(const CalculationParameters&); - <% for (const property of layoutProperties) { -%> - LayoutProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> }; +struct <%- camelize(property.name) %> : LayoutProperty<<%- propertyType(property) %>> { + static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; } +}; + <% } -%> +<% for (const property of paintProperties) { -%> +struct <%- camelize(property.name) %> : <% +if (/-pattern$/.test(property.name) || property.name === 'line-dasharray') { +%>CrossFaded<% } -%>PaintProperty<<%- propertyType(property) %>> { + static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; } }; <% } -%> -class <%- camelize(type) %>PaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); +<% if (layoutProperties.length) { -%> +class <%- camelize(type) %>LayoutProperties : public LayoutProperties< +<% for (const property of layoutProperties.slice(0, -1)) { -%> + <%- camelize(property.name) %>, +<% } -%> + <%- camelize(layoutProperties.slice(-1)[0].name) %> +> {}; -<% for (const property of paintProperties) { -%> -<% if (/-pattern$/.test(property.name) || property.name === 'line-dasharray') { -%> - PaintProperty<<%- propertyType(property) %>, CrossFadedPropertyEvaluator> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> }; -<% } else { -%> - PaintProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> }; <% } -%> +class <%- camelize(type) %>PaintProperties : public PaintProperties< +<% for (const property of paintProperties.slice(0, -1)) { -%> + <%- camelize(property.name) %>, <% } -%> -}; + <%- camelize(paintProperties.slice(-1)[0].name) %> +> {}; } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 49ecf63c18..8c38ef5694 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -60,59 +60,59 @@ const Filter& LineLayer::getFilter() const { // Layout properties PropertyValue<LineCapType> LineLayer::getDefaultLineCap() { - return { LineCapType::Butt }; + return LineCap::defaultValue(); } PropertyValue<LineCapType> LineLayer::getLineCap() const { - return impl->layout.lineCap.get(); + return impl->layout.unevaluated.get<LineCap>(); } void LineLayer::setLineCap(PropertyValue<LineCapType> value) { if (value == getLineCap()) return; - impl->layout.lineCap.set(value); + impl->layout.unevaluated.get<LineCap>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "line-cap"); } PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() { - return { LineJoinType::Miter }; + return LineJoin::defaultValue(); } PropertyValue<LineJoinType> LineLayer::getLineJoin() const { - return impl->layout.lineJoin.get(); + return impl->layout.unevaluated.get<LineJoin>(); } void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) { if (value == getLineJoin()) return; - impl->layout.lineJoin.set(value); + impl->layout.unevaluated.get<LineJoin>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "line-join"); } PropertyValue<float> LineLayer::getDefaultLineMiterLimit() { - return { 2 }; + return LineMiterLimit::defaultValue(); } PropertyValue<float> LineLayer::getLineMiterLimit() const { - return impl->layout.lineMiterLimit.get(); + return impl->layout.unevaluated.get<LineMiterLimit>(); } void LineLayer::setLineMiterLimit(PropertyValue<float> value) { if (value == getLineMiterLimit()) return; - impl->layout.lineMiterLimit.set(value); + impl->layout.unevaluated.get<LineMiterLimit>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "line-miter-limit"); } PropertyValue<float> LineLayer::getDefaultLineRoundLimit() { - return { 1 }; + return LineRoundLimit::defaultValue(); } PropertyValue<float> LineLayer::getLineRoundLimit() const { - return impl->layout.lineRoundLimit.get(); + return impl->layout.unevaluated.get<LineRoundLimit>(); } void LineLayer::setLineRoundLimit(PropertyValue<float> value) { if (value == getLineRoundLimit()) return; - impl->layout.lineRoundLimit.set(value); + impl->layout.unevaluated.get<LineRoundLimit>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "line-round-limit"); } @@ -123,13 +123,13 @@ PropertyValue<float> LineLayer::getDefaultLineOpacity() { } PropertyValue<float> LineLayer::getLineOpacity(const optional<std::string>& klass) const { - return impl->paint.lineOpacity.get(klass); + return impl->paint.get<LineOpacity>(klass); } void LineLayer::setLineOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getLineOpacity(klass)) return; - impl->paint.lineOpacity.set(value, klass); + impl->paint.set<LineOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -138,13 +138,13 @@ PropertyValue<Color> LineLayer::getDefaultLineColor() { } PropertyValue<Color> LineLayer::getLineColor(const optional<std::string>& klass) const { - return impl->paint.lineColor.get(klass); + return impl->paint.get<LineColor>(klass); } void LineLayer::setLineColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getLineColor(klass)) return; - impl->paint.lineColor.set(value, klass); + impl->paint.set<LineColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -153,13 +153,13 @@ PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() { } PropertyValue<std::array<float, 2>> LineLayer::getLineTranslate(const optional<std::string>& klass) const { - return impl->paint.lineTranslate.get(klass); + return impl->paint.get<LineTranslate>(klass); } void LineLayer::setLineTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) { if (value == getLineTranslate(klass)) return; - impl->paint.lineTranslate.set(value, klass); + impl->paint.set<LineTranslate>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -168,13 +168,13 @@ PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() { } PropertyValue<TranslateAnchorType> LineLayer::getLineTranslateAnchor(const optional<std::string>& klass) const { - return impl->paint.lineTranslateAnchor.get(klass); + return impl->paint.get<LineTranslateAnchor>(klass); } void LineLayer::setLineTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) { if (value == getLineTranslateAnchor(klass)) return; - impl->paint.lineTranslateAnchor.set(value, klass); + impl->paint.set<LineTranslateAnchor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -183,13 +183,13 @@ PropertyValue<float> LineLayer::getDefaultLineWidth() { } PropertyValue<float> LineLayer::getLineWidth(const optional<std::string>& klass) const { - return impl->paint.lineWidth.get(klass); + return impl->paint.get<LineWidth>(klass); } void LineLayer::setLineWidth(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getLineWidth(klass)) return; - impl->paint.lineWidth.set(value, klass); + impl->paint.set<LineWidth>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -198,13 +198,13 @@ PropertyValue<float> LineLayer::getDefaultLineGapWidth() { } PropertyValue<float> LineLayer::getLineGapWidth(const optional<std::string>& klass) const { - return impl->paint.lineGapWidth.get(klass); + return impl->paint.get<LineGapWidth>(klass); } void LineLayer::setLineGapWidth(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getLineGapWidth(klass)) return; - impl->paint.lineGapWidth.set(value, klass); + impl->paint.set<LineGapWidth>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -213,13 +213,13 @@ PropertyValue<float> LineLayer::getDefaultLineOffset() { } PropertyValue<float> LineLayer::getLineOffset(const optional<std::string>& klass) const { - return impl->paint.lineOffset.get(klass); + return impl->paint.get<LineOffset>(klass); } void LineLayer::setLineOffset(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getLineOffset(klass)) return; - impl->paint.lineOffset.set(value, klass); + impl->paint.set<LineOffset>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -228,13 +228,13 @@ PropertyValue<float> LineLayer::getDefaultLineBlur() { } PropertyValue<float> LineLayer::getLineBlur(const optional<std::string>& klass) const { - return impl->paint.lineBlur.get(klass); + return impl->paint.get<LineBlur>(klass); } void LineLayer::setLineBlur(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getLineBlur(klass)) return; - impl->paint.lineBlur.set(value, klass); + impl->paint.set<LineBlur>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -243,13 +243,13 @@ PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() { } PropertyValue<std::vector<float>> LineLayer::getLineDasharray(const optional<std::string>& klass) const { - return impl->paint.lineDasharray.get(klass); + return impl->paint.get<LineDasharray>(klass); } void LineLayer::setLineDasharray(PropertyValue<std::vector<float>> value, const optional<std::string>& klass) { if (value == getLineDasharray(klass)) return; - impl->paint.lineDasharray.set(value, klass); + impl->paint.set<LineDasharray>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -258,13 +258,13 @@ PropertyValue<std::string> LineLayer::getDefaultLinePattern() { } PropertyValue<std::string> LineLayer::getLinePattern(const optional<std::string>& klass) const { - return impl->paint.linePattern.get(klass); + return impl->paint.get<LinePattern>(klass); } void LineLayer::setLinePattern(PropertyValue<std::string> value, const optional<std::string>& klass) { if (value == getLinePattern(klass)) return; - impl->paint.linePattern.set(value, klass); + impl->paint.set<LinePattern>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp index c116af5fc2..e6ec21a659 100644 --- a/src/mbgl/style/layers/line_layer_impl.cpp +++ b/src/mbgl/style/layers/line_layer_impl.cpp @@ -12,26 +12,24 @@ void LineLayer::Impl::cascade(const CascadeParameters& parameters) { paint.cascade(parameters); } -bool LineLayer::Impl::recalculate(const CalculationParameters& parameters) { +bool LineLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) { // for scaling dasharrays - CalculationParameters dashArrayParams = parameters; + PropertyEvaluationParameters dashArrayParams = parameters; dashArrayParams.z = std::floor(dashArrayParams.z); - paint.lineWidth.calculate(dashArrayParams); - dashLineWidth = paint.lineWidth; + dashLineWidth = paint.evaluate<LineWidth>(dashArrayParams); - bool hasTransitions = paint.recalculate(parameters); + paint.evaluate(parameters); - passes = (paint.lineOpacity > 0 && paint.lineColor.value.a > 0 && paint.lineWidth > 0) + passes = (paint.evaluated.get<LineOpacity>() > 0 && paint.evaluated.get<LineColor>().a > 0 && paint.evaluated.get<LineWidth>() > 0) ? RenderPass::Translucent : RenderPass::None; - return hasTransitions; + return paint.hasTransition(); } std::unique_ptr<Bucket> LineLayer::Impl::createBucket(BucketParameters& parameters) const { auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaleFactor()); - bucket->layout = layout; - bucket->layout.recalculate(CalculationParameters(parameters.tileID.overscaledZ)); + bucket->layout = layout.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ)); auto& name = bucketName(); parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) { @@ -44,10 +42,10 @@ std::unique_ptr<Bucket> LineLayer::Impl::createBucket(BucketParameters& paramete } float LineLayer::Impl::getLineWidth() const { - if (paint.lineGapWidth > 0) { - return paint.lineGapWidth + 2 * paint.lineWidth; + if (paint.evaluated.get<LineGapWidth>() > 0) { + return paint.evaluated.get<LineGapWidth>() + 2 * paint.evaluated.get<LineWidth>(); } else { - return paint.lineWidth; + return paint.evaluated.get<LineWidth>(); } } @@ -82,8 +80,8 @@ optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const d } float LineLayer::Impl::getQueryRadius() const { - const std::array<float, 2>& translate = paint.lineTranslate; - return getLineWidth() / 2.0 + std::abs(paint.lineOffset) + util::length(translate[0], translate[1]); + const std::array<float, 2>& translate = paint.evaluated.get<LineTranslate>(); + return getLineWidth() / 2.0 + std::abs(paint.evaluated.get<LineOffset>()) + util::length(translate[0], translate[1]); } bool LineLayer::Impl::queryIntersectsGeometry( @@ -95,8 +93,8 @@ bool LineLayer::Impl::queryIntersectsGeometry( const float halfWidth = getLineWidth() / 2.0 * pixelsToTileUnits; auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( - queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits); - auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits); + queryGeometry, paint.evaluated.get<LineTranslate>(), paint.evaluated.get<LineTranslateAnchor>(), bearing, pixelsToTileUnits); + auto offsetGeometry = offsetLine(geometry, paint.evaluated.get<LineOffset>() * pixelsToTileUnits); return util::polygonIntersectsBufferedMultiLine( translatedQueryGeometry.value_or(queryGeometry), diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp index c6b4be3bec..3387db07f0 100644 --- a/src/mbgl/style/layers/line_layer_impl.hpp +++ b/src/mbgl/style/layers/line_layer_impl.hpp @@ -13,7 +13,7 @@ public: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) override; - bool recalculate(const CalculationParameters&) override; + bool evaluate(const PropertyEvaluationParameters&) override; std::unique_ptr<Bucket> createBucket(BucketParameters&) const override; diff --git a/src/mbgl/style/layers/line_layer_properties.cpp b/src/mbgl/style/layers/line_layer_properties.cpp index 2d6092745e..174239bcc8 100644 --- a/src/mbgl/style/layers/line_layer_properties.cpp +++ b/src/mbgl/style/layers/line_layer_properties.cpp @@ -5,42 +5,5 @@ namespace mbgl { namespace style { -void LineLayoutProperties::recalculate(const CalculationParameters& parameters) { - lineCap.calculate(parameters); - lineJoin.calculate(parameters); - lineMiterLimit.calculate(parameters); - lineRoundLimit.calculate(parameters); -} - -void LinePaintProperties::cascade(const CascadeParameters& parameters) { - lineOpacity.cascade(parameters); - lineColor.cascade(parameters); - lineTranslate.cascade(parameters); - lineTranslateAnchor.cascade(parameters); - lineWidth.cascade(parameters); - lineGapWidth.cascade(parameters); - lineOffset.cascade(parameters); - lineBlur.cascade(parameters); - lineDasharray.cascade(parameters); - linePattern.cascade(parameters); -} - -bool LinePaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - - hasTransitions |= lineOpacity.calculate(parameters); - hasTransitions |= lineColor.calculate(parameters); - hasTransitions |= lineTranslate.calculate(parameters); - hasTransitions |= lineTranslateAnchor.calculate(parameters); - hasTransitions |= lineWidth.calculate(parameters); - hasTransitions |= lineGapWidth.calculate(parameters); - hasTransitions |= lineOffset.calculate(parameters); - hasTransitions |= lineBlur.calculate(parameters); - hasTransitions |= lineDasharray.calculate(parameters); - hasTransitions |= linePattern.calculate(parameters); - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index b73e3f2ef2..07458cd634 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -9,35 +9,81 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; - -class LineLayoutProperties { -public: - void recalculate(const CalculationParameters&); - - LayoutProperty<LineCapType> lineCap { LineCapType::Butt }; - LayoutProperty<LineJoinType> lineJoin { LineJoinType::Miter }; - LayoutProperty<float> lineMiterLimit { 2 }; - LayoutProperty<float> lineRoundLimit { 1 }; -}; - -class LinePaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); - - PaintProperty<float> lineOpacity { 1 }; - PaintProperty<Color> lineColor { Color::black() }; - PaintProperty<std::array<float, 2>> lineTranslate { {{ 0, 0 }} }; - PaintProperty<TranslateAnchorType> lineTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty<float> lineWidth { 1 }; - PaintProperty<float> lineGapWidth { 0 }; - PaintProperty<float> lineOffset { 0 }; - PaintProperty<float> lineBlur { 0 }; - PaintProperty<std::vector<float>, CrossFadedPropertyEvaluator> lineDasharray { { } }; - PaintProperty<std::string, CrossFadedPropertyEvaluator> linePattern { "" }; +struct LineCap : LayoutProperty<LineCapType> { + static LineCapType defaultValue() { return LineCapType::Butt; } }; +struct LineJoin : LayoutProperty<LineJoinType> { + static LineJoinType defaultValue() { return LineJoinType::Miter; } +}; + +struct LineMiterLimit : LayoutProperty<float> { + static float defaultValue() { return 2; } +}; + +struct LineRoundLimit : LayoutProperty<float> { + static float defaultValue() { return 1; } +}; + +struct LineOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct LineColor : PaintProperty<Color> { + static Color defaultValue() { return Color::black(); } +}; + +struct LineTranslate : PaintProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct LineTranslateAnchor : PaintProperty<TranslateAnchorType> { + static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } +}; + +struct LineWidth : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct LineGapWidth : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct LineOffset : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct LineBlur : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct LineDasharray : CrossFadedPaintProperty<std::vector<float>> { + static std::vector<float> defaultValue() { return { }; } +}; + +struct LinePattern : CrossFadedPaintProperty<std::string> { + static std::string defaultValue() { return ""; } +}; + +class LineLayoutProperties : public LayoutProperties< + LineCap, + LineJoin, + LineMiterLimit, + LineRoundLimit +> {}; + +class LinePaintProperties : public PaintProperties< + LineOpacity, + LineColor, + LineTranslate, + LineTranslateAnchor, + LineWidth, + LineGapWidth, + LineOffset, + LineBlur, + LineDasharray, + LinePattern +> {}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index 238bfef6e4..21d72a0fdc 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -49,13 +49,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterOpacity() { } PropertyValue<float> RasterLayer::getRasterOpacity(const optional<std::string>& klass) const { - return impl->paint.rasterOpacity.get(klass); + return impl->paint.get<RasterOpacity>(klass); } void RasterLayer::setRasterOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterOpacity(klass)) return; - impl->paint.rasterOpacity.set(value, klass); + impl->paint.set<RasterOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -64,13 +64,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() { } PropertyValue<float> RasterLayer::getRasterHueRotate(const optional<std::string>& klass) const { - return impl->paint.rasterHueRotate.get(klass); + return impl->paint.get<RasterHueRotate>(klass); } void RasterLayer::setRasterHueRotate(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterHueRotate(klass)) return; - impl->paint.rasterHueRotate.set(value, klass); + impl->paint.set<RasterHueRotate>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -79,13 +79,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() { } PropertyValue<float> RasterLayer::getRasterBrightnessMin(const optional<std::string>& klass) const { - return impl->paint.rasterBrightnessMin.get(klass); + return impl->paint.get<RasterBrightnessMin>(klass); } void RasterLayer::setRasterBrightnessMin(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterBrightnessMin(klass)) return; - impl->paint.rasterBrightnessMin.set(value, klass); + impl->paint.set<RasterBrightnessMin>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -94,13 +94,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() { } PropertyValue<float> RasterLayer::getRasterBrightnessMax(const optional<std::string>& klass) const { - return impl->paint.rasterBrightnessMax.get(klass); + return impl->paint.get<RasterBrightnessMax>(klass); } void RasterLayer::setRasterBrightnessMax(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterBrightnessMax(klass)) return; - impl->paint.rasterBrightnessMax.set(value, klass); + impl->paint.set<RasterBrightnessMax>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -109,13 +109,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterSaturation() { } PropertyValue<float> RasterLayer::getRasterSaturation(const optional<std::string>& klass) const { - return impl->paint.rasterSaturation.get(klass); + return impl->paint.get<RasterSaturation>(klass); } void RasterLayer::setRasterSaturation(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterSaturation(klass)) return; - impl->paint.rasterSaturation.set(value, klass); + impl->paint.set<RasterSaturation>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -124,13 +124,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterContrast() { } PropertyValue<float> RasterLayer::getRasterContrast(const optional<std::string>& klass) const { - return impl->paint.rasterContrast.get(klass); + return impl->paint.get<RasterContrast>(klass); } void RasterLayer::setRasterContrast(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterContrast(klass)) return; - impl->paint.rasterContrast.set(value, klass); + impl->paint.set<RasterContrast>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -139,13 +139,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() { } PropertyValue<float> RasterLayer::getRasterFadeDuration(const optional<std::string>& klass) const { - return impl->paint.rasterFadeDuration.get(klass); + return impl->paint.get<RasterFadeDuration>(klass); } void RasterLayer::setRasterFadeDuration(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getRasterFadeDuration(klass)) return; - impl->paint.rasterFadeDuration.set(value, klass); + impl->paint.set<RasterFadeDuration>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } diff --git a/src/mbgl/style/layers/raster_layer_impl.cpp b/src/mbgl/style/layers/raster_layer_impl.cpp index 879bfa4559..3be4bb4fbd 100644 --- a/src/mbgl/style/layers/raster_layer_impl.cpp +++ b/src/mbgl/style/layers/raster_layer_impl.cpp @@ -8,12 +8,12 @@ void RasterLayer::Impl::cascade(const CascadeParameters& parameters) { paint.cascade(parameters); } -bool RasterLayer::Impl::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = paint.recalculate(parameters); +bool RasterLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) { + paint.evaluate(parameters); - passes = paint.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None; + passes = paint.evaluated.get<RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None; - return hasTransitions; + return paint.hasTransition(); } std::unique_ptr<Bucket> RasterLayer::Impl::createBucket(BucketParameters&) const { diff --git a/src/mbgl/style/layers/raster_layer_impl.hpp b/src/mbgl/style/layers/raster_layer_impl.hpp index a5b396e2ed..df5d388bdf 100644 --- a/src/mbgl/style/layers/raster_layer_impl.hpp +++ b/src/mbgl/style/layers/raster_layer_impl.hpp @@ -13,7 +13,7 @@ public: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) override; - bool recalculate(const CalculationParameters&) override; + bool evaluate(const PropertyEvaluationParameters&) override; std::unique_ptr<Bucket> createBucket(BucketParameters&) const override; diff --git a/src/mbgl/style/layers/raster_layer_properties.cpp b/src/mbgl/style/layers/raster_layer_properties.cpp index 68d9d1d35d..303719af40 100644 --- a/src/mbgl/style/layers/raster_layer_properties.cpp +++ b/src/mbgl/style/layers/raster_layer_properties.cpp @@ -5,29 +5,5 @@ namespace mbgl { namespace style { -void RasterPaintProperties::cascade(const CascadeParameters& parameters) { - rasterOpacity.cascade(parameters); - rasterHueRotate.cascade(parameters); - rasterBrightnessMin.cascade(parameters); - rasterBrightnessMax.cascade(parameters); - rasterSaturation.cascade(parameters); - rasterContrast.cascade(parameters); - rasterFadeDuration.cascade(parameters); -} - -bool RasterPaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - - hasTransitions |= rasterOpacity.calculate(parameters); - hasTransitions |= rasterHueRotate.calculate(parameters); - hasTransitions |= rasterBrightnessMin.calculate(parameters); - hasTransitions |= rasterBrightnessMax.calculate(parameters); - hasTransitions |= rasterSaturation.calculate(parameters); - hasTransitions |= rasterContrast.calculate(parameters); - hasTransitions |= rasterFadeDuration.calculate(parameters); - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp index ddfb833e12..caa6d0c58d 100644 --- a/src/mbgl/style/layers/raster_layer_properties.hpp +++ b/src/mbgl/style/layers/raster_layer_properties.hpp @@ -9,22 +9,43 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; - -class RasterPaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); - - PaintProperty<float> rasterOpacity { 1 }; - PaintProperty<float> rasterHueRotate { 0 }; - PaintProperty<float> rasterBrightnessMin { 0 }; - PaintProperty<float> rasterBrightnessMax { 1 }; - PaintProperty<float> rasterSaturation { 0 }; - PaintProperty<float> rasterContrast { 0 }; - PaintProperty<float> rasterFadeDuration { 300 }; +struct RasterOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } }; +struct RasterHueRotate : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct RasterBrightnessMin : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct RasterBrightnessMax : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct RasterSaturation : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct RasterContrast : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct RasterFadeDuration : PaintProperty<float> { + static float defaultValue() { return 300; } +}; + +class RasterPaintProperties : public PaintProperties< + RasterOpacity, + RasterHueRotate, + RasterBrightnessMin, + RasterBrightnessMax, + RasterSaturation, + RasterContrast, + RasterFadeDuration +> {}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index d49e8d7fe3..61f360ff64 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -60,479 +60,479 @@ const Filter& SymbolLayer::getFilter() const { // Layout properties PropertyValue<SymbolPlacementType> SymbolLayer::getDefaultSymbolPlacement() { - return { SymbolPlacementType::Point }; + return SymbolPlacement::defaultValue(); } PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const { - return impl->layout.symbolPlacement.get(); + return impl->layout.unevaluated.get<SymbolPlacement>(); } void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) { if (value == getSymbolPlacement()) return; - impl->layout.symbolPlacement.set(value); + impl->layout.unevaluated.get<SymbolPlacement>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-placement"); } PropertyValue<float> SymbolLayer::getDefaultSymbolSpacing() { - return { 250 }; + return SymbolSpacing::defaultValue(); } PropertyValue<float> SymbolLayer::getSymbolSpacing() const { - return impl->layout.symbolSpacing.get(); + return impl->layout.unevaluated.get<SymbolSpacing>(); } void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) { if (value == getSymbolSpacing()) return; - impl->layout.symbolSpacing.set(value); + impl->layout.unevaluated.get<SymbolSpacing>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-spacing"); } PropertyValue<bool> SymbolLayer::getDefaultSymbolAvoidEdges() { - return { false }; + return SymbolAvoidEdges::defaultValue(); } PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const { - return impl->layout.symbolAvoidEdges.get(); + return impl->layout.unevaluated.get<SymbolAvoidEdges>(); } void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) { if (value == getSymbolAvoidEdges()) return; - impl->layout.symbolAvoidEdges.set(value); + impl->layout.unevaluated.get<SymbolAvoidEdges>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-avoid-edges"); } PropertyValue<bool> SymbolLayer::getDefaultIconAllowOverlap() { - return { false }; + return IconAllowOverlap::defaultValue(); } PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const { - return impl->layout.iconAllowOverlap.get(); + return impl->layout.unevaluated.get<IconAllowOverlap>(); } void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) { if (value == getIconAllowOverlap()) return; - impl->layout.iconAllowOverlap.set(value); + impl->layout.unevaluated.get<IconAllowOverlap>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-allow-overlap"); } PropertyValue<bool> SymbolLayer::getDefaultIconIgnorePlacement() { - return { false }; + return IconIgnorePlacement::defaultValue(); } PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const { - return impl->layout.iconIgnorePlacement.get(); + return impl->layout.unevaluated.get<IconIgnorePlacement>(); } void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) { if (value == getIconIgnorePlacement()) return; - impl->layout.iconIgnorePlacement.set(value); + impl->layout.unevaluated.get<IconIgnorePlacement>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-ignore-placement"); } PropertyValue<bool> SymbolLayer::getDefaultIconOptional() { - return { false }; + return IconOptional::defaultValue(); } PropertyValue<bool> SymbolLayer::getIconOptional() const { - return impl->layout.iconOptional.get(); + return impl->layout.unevaluated.get<IconOptional>(); } void SymbolLayer::setIconOptional(PropertyValue<bool> value) { if (value == getIconOptional()) return; - impl->layout.iconOptional.set(value); + impl->layout.unevaluated.get<IconOptional>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-optional"); } PropertyValue<AlignmentType> SymbolLayer::getDefaultIconRotationAlignment() { - return { AlignmentType::Auto }; + return IconRotationAlignment::defaultValue(); } PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const { - return impl->layout.iconRotationAlignment.get(); + return impl->layout.unevaluated.get<IconRotationAlignment>(); } void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getIconRotationAlignment()) return; - impl->layout.iconRotationAlignment.set(value); + impl->layout.unevaluated.get<IconRotationAlignment>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-rotation-alignment"); } PropertyValue<float> SymbolLayer::getDefaultIconSize() { - return { 1 }; + return IconSize::defaultValue(); } PropertyValue<float> SymbolLayer::getIconSize() const { - return impl->layout.iconSize.get(); + return impl->layout.unevaluated.get<IconSize>(); } void SymbolLayer::setIconSize(PropertyValue<float> value) { if (value == getIconSize()) return; - impl->layout.iconSize.set(value); + impl->layout.unevaluated.get<IconSize>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-size"); } PropertyValue<IconTextFitType> SymbolLayer::getDefaultIconTextFit() { - return { IconTextFitType::None }; + return IconTextFit::defaultValue(); } PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const { - return impl->layout.iconTextFit.get(); + return impl->layout.unevaluated.get<IconTextFit>(); } void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) { if (value == getIconTextFit()) return; - impl->layout.iconTextFit.set(value); + impl->layout.unevaluated.get<IconTextFit>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit"); } PropertyValue<std::array<float, 4>> SymbolLayer::getDefaultIconTextFitPadding() { - return { {{ 0, 0, 0, 0 }} }; + return IconTextFitPadding::defaultValue(); } PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const { - return impl->layout.iconTextFitPadding.get(); + return impl->layout.unevaluated.get<IconTextFitPadding>(); } void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) { if (value == getIconTextFitPadding()) return; - impl->layout.iconTextFitPadding.set(value); + impl->layout.unevaluated.get<IconTextFitPadding>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit-padding"); } PropertyValue<std::string> SymbolLayer::getDefaultIconImage() { - return { "" }; + return IconImage::defaultValue(); } PropertyValue<std::string> SymbolLayer::getIconImage() const { - return impl->layout.iconImage.get(); + return impl->layout.unevaluated.get<IconImage>(); } void SymbolLayer::setIconImage(PropertyValue<std::string> value) { if (value == getIconImage()) return; - impl->layout.iconImage.set(value); + impl->layout.unevaluated.get<IconImage>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-image"); } PropertyValue<float> SymbolLayer::getDefaultIconRotate() { - return { 0 }; + return IconRotate::defaultValue(); } PropertyValue<float> SymbolLayer::getIconRotate() const { - return impl->layout.iconRotate.get(); + return impl->layout.unevaluated.get<IconRotate>(); } void SymbolLayer::setIconRotate(PropertyValue<float> value) { if (value == getIconRotate()) return; - impl->layout.iconRotate.set(value); + impl->layout.unevaluated.get<IconRotate>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-rotate"); } PropertyValue<float> SymbolLayer::getDefaultIconPadding() { - return { 2 }; + return IconPadding::defaultValue(); } PropertyValue<float> SymbolLayer::getIconPadding() const { - return impl->layout.iconPadding.get(); + return impl->layout.unevaluated.get<IconPadding>(); } void SymbolLayer::setIconPadding(PropertyValue<float> value) { if (value == getIconPadding()) return; - impl->layout.iconPadding.set(value); + impl->layout.unevaluated.get<IconPadding>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-padding"); } PropertyValue<bool> SymbolLayer::getDefaultIconKeepUpright() { - return { false }; + return IconKeepUpright::defaultValue(); } PropertyValue<bool> SymbolLayer::getIconKeepUpright() const { - return impl->layout.iconKeepUpright.get(); + return impl->layout.unevaluated.get<IconKeepUpright>(); } void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) { if (value == getIconKeepUpright()) return; - impl->layout.iconKeepUpright.set(value); + impl->layout.unevaluated.get<IconKeepUpright>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-keep-upright"); } PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() { - return { {{ 0, 0 }} }; + return IconOffset::defaultValue(); } PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const { - return impl->layout.iconOffset.get(); + return impl->layout.unevaluated.get<IconOffset>(); } void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) { if (value == getIconOffset()) return; - impl->layout.iconOffset.set(value); + impl->layout.unevaluated.get<IconOffset>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "icon-offset"); } PropertyValue<AlignmentType> SymbolLayer::getDefaultTextPitchAlignment() { - return { AlignmentType::Auto }; + return TextPitchAlignment::defaultValue(); } PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const { - return impl->layout.textPitchAlignment.get(); + return impl->layout.unevaluated.get<TextPitchAlignment>(); } void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) { if (value == getTextPitchAlignment()) return; - impl->layout.textPitchAlignment.set(value); + impl->layout.unevaluated.get<TextPitchAlignment>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-pitch-alignment"); } PropertyValue<AlignmentType> SymbolLayer::getDefaultTextRotationAlignment() { - return { AlignmentType::Auto }; + return TextRotationAlignment::defaultValue(); } PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const { - return impl->layout.textRotationAlignment.get(); + return impl->layout.unevaluated.get<TextRotationAlignment>(); } void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) { if (value == getTextRotationAlignment()) return; - impl->layout.textRotationAlignment.set(value); + impl->layout.unevaluated.get<TextRotationAlignment>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-rotation-alignment"); } PropertyValue<std::string> SymbolLayer::getDefaultTextField() { - return { "" }; + return TextField::defaultValue(); } PropertyValue<std::string> SymbolLayer::getTextField() const { - return impl->layout.textField.get(); + return impl->layout.unevaluated.get<TextField>(); } void SymbolLayer::setTextField(PropertyValue<std::string> value) { if (value == getTextField()) return; - impl->layout.textField.set(value); + impl->layout.unevaluated.get<TextField>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-field"); } PropertyValue<std::vector<std::string>> SymbolLayer::getDefaultTextFont() { - return { { "Open Sans Regular", "Arial Unicode MS Regular" } }; + return TextFont::defaultValue(); } PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const { - return impl->layout.textFont.get(); + return impl->layout.unevaluated.get<TextFont>(); } void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) { if (value == getTextFont()) return; - impl->layout.textFont.set(value); + impl->layout.unevaluated.get<TextFont>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-font"); } PropertyValue<float> SymbolLayer::getDefaultTextSize() { - return { 16 }; + return TextSize::defaultValue(); } PropertyValue<float> SymbolLayer::getTextSize() const { - return impl->layout.textSize.get(); + return impl->layout.unevaluated.get<TextSize>(); } void SymbolLayer::setTextSize(PropertyValue<float> value) { if (value == getTextSize()) return; - impl->layout.textSize.set(value); + impl->layout.unevaluated.get<TextSize>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-size"); } PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() { - return { 10 }; + return TextMaxWidth::defaultValue(); } PropertyValue<float> SymbolLayer::getTextMaxWidth() const { - return impl->layout.textMaxWidth.get(); + return impl->layout.unevaluated.get<TextMaxWidth>(); } void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) { if (value == getTextMaxWidth()) return; - impl->layout.textMaxWidth.set(value); + impl->layout.unevaluated.get<TextMaxWidth>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-max-width"); } PropertyValue<float> SymbolLayer::getDefaultTextLineHeight() { - return { 1.2 }; + return TextLineHeight::defaultValue(); } PropertyValue<float> SymbolLayer::getTextLineHeight() const { - return impl->layout.textLineHeight.get(); + return impl->layout.unevaluated.get<TextLineHeight>(); } void SymbolLayer::setTextLineHeight(PropertyValue<float> value) { if (value == getTextLineHeight()) return; - impl->layout.textLineHeight.set(value); + impl->layout.unevaluated.get<TextLineHeight>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-line-height"); } PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() { - return { 0 }; + return TextLetterSpacing::defaultValue(); } PropertyValue<float> SymbolLayer::getTextLetterSpacing() const { - return impl->layout.textLetterSpacing.get(); + return impl->layout.unevaluated.get<TextLetterSpacing>(); } void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) { if (value == getTextLetterSpacing()) return; - impl->layout.textLetterSpacing.set(value); + impl->layout.unevaluated.get<TextLetterSpacing>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-letter-spacing"); } PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() { - return { TextJustifyType::Center }; + return TextJustify::defaultValue(); } PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const { - return impl->layout.textJustify.get(); + return impl->layout.unevaluated.get<TextJustify>(); } void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { if (value == getTextJustify()) return; - impl->layout.textJustify.set(value); + impl->layout.unevaluated.get<TextJustify>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-justify"); } PropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() { - return { TextAnchorType::Center }; + return TextAnchor::defaultValue(); } PropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const { - return impl->layout.textAnchor.get(); + return impl->layout.unevaluated.get<TextAnchor>(); } void SymbolLayer::setTextAnchor(PropertyValue<TextAnchorType> value) { if (value == getTextAnchor()) return; - impl->layout.textAnchor.set(value); + impl->layout.unevaluated.get<TextAnchor>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-anchor"); } PropertyValue<float> SymbolLayer::getDefaultTextMaxAngle() { - return { 45 }; + return TextMaxAngle::defaultValue(); } PropertyValue<float> SymbolLayer::getTextMaxAngle() const { - return impl->layout.textMaxAngle.get(); + return impl->layout.unevaluated.get<TextMaxAngle>(); } void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) { if (value == getTextMaxAngle()) return; - impl->layout.textMaxAngle.set(value); + impl->layout.unevaluated.get<TextMaxAngle>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-max-angle"); } PropertyValue<float> SymbolLayer::getDefaultTextRotate() { - return { 0 }; + return TextRotate::defaultValue(); } PropertyValue<float> SymbolLayer::getTextRotate() const { - return impl->layout.textRotate.get(); + return impl->layout.unevaluated.get<TextRotate>(); } void SymbolLayer::setTextRotate(PropertyValue<float> value) { if (value == getTextRotate()) return; - impl->layout.textRotate.set(value); + impl->layout.unevaluated.get<TextRotate>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-rotate"); } PropertyValue<float> SymbolLayer::getDefaultTextPadding() { - return { 2 }; + return TextPadding::defaultValue(); } PropertyValue<float> SymbolLayer::getTextPadding() const { - return impl->layout.textPadding.get(); + return impl->layout.unevaluated.get<TextPadding>(); } void SymbolLayer::setTextPadding(PropertyValue<float> value) { if (value == getTextPadding()) return; - impl->layout.textPadding.set(value); + impl->layout.unevaluated.get<TextPadding>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-padding"); } PropertyValue<bool> SymbolLayer::getDefaultTextKeepUpright() { - return { true }; + return TextKeepUpright::defaultValue(); } PropertyValue<bool> SymbolLayer::getTextKeepUpright() const { - return impl->layout.textKeepUpright.get(); + return impl->layout.unevaluated.get<TextKeepUpright>(); } void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) { if (value == getTextKeepUpright()) return; - impl->layout.textKeepUpright.set(value); + impl->layout.unevaluated.get<TextKeepUpright>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-keep-upright"); } PropertyValue<TextTransformType> SymbolLayer::getDefaultTextTransform() { - return { TextTransformType::None }; + return TextTransform::defaultValue(); } PropertyValue<TextTransformType> SymbolLayer::getTextTransform() const { - return impl->layout.textTransform.get(); + return impl->layout.unevaluated.get<TextTransform>(); } void SymbolLayer::setTextTransform(PropertyValue<TextTransformType> value) { if (value == getTextTransform()) return; - impl->layout.textTransform.set(value); + impl->layout.unevaluated.get<TextTransform>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-transform"); } PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextOffset() { - return { {{ 0, 0 }} }; + return TextOffset::defaultValue(); } PropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const { - return impl->layout.textOffset.get(); + return impl->layout.unevaluated.get<TextOffset>(); } void SymbolLayer::setTextOffset(PropertyValue<std::array<float, 2>> value) { if (value == getTextOffset()) return; - impl->layout.textOffset.set(value); + impl->layout.unevaluated.get<TextOffset>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-offset"); } PropertyValue<bool> SymbolLayer::getDefaultTextAllowOverlap() { - return { false }; + return TextAllowOverlap::defaultValue(); } PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const { - return impl->layout.textAllowOverlap.get(); + return impl->layout.unevaluated.get<TextAllowOverlap>(); } void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) { if (value == getTextAllowOverlap()) return; - impl->layout.textAllowOverlap.set(value); + impl->layout.unevaluated.get<TextAllowOverlap>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-allow-overlap"); } PropertyValue<bool> SymbolLayer::getDefaultTextIgnorePlacement() { - return { false }; + return TextIgnorePlacement::defaultValue(); } PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const { - return impl->layout.textIgnorePlacement.get(); + return impl->layout.unevaluated.get<TextIgnorePlacement>(); } void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) { if (value == getTextIgnorePlacement()) return; - impl->layout.textIgnorePlacement.set(value); + impl->layout.unevaluated.get<TextIgnorePlacement>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-ignore-placement"); } PropertyValue<bool> SymbolLayer::getDefaultTextOptional() { - return { false }; + return TextOptional::defaultValue(); } PropertyValue<bool> SymbolLayer::getTextOptional() const { - return impl->layout.textOptional.get(); + return impl->layout.unevaluated.get<TextOptional>(); } void SymbolLayer::setTextOptional(PropertyValue<bool> value) { if (value == getTextOptional()) return; - impl->layout.textOptional.set(value); + impl->layout.unevaluated.get<TextOptional>() = value; impl->observer->onLayerLayoutPropertyChanged(*this, "text-optional"); } @@ -543,13 +543,13 @@ PropertyValue<float> SymbolLayer::getDefaultIconOpacity() { } PropertyValue<float> SymbolLayer::getIconOpacity(const optional<std::string>& klass) const { - return impl->paint.iconOpacity.get(klass); + return impl->paint.get<IconOpacity>(klass); } void SymbolLayer::setIconOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getIconOpacity(klass)) return; - impl->paint.iconOpacity.set(value, klass); + impl->paint.set<IconOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -558,13 +558,13 @@ PropertyValue<Color> SymbolLayer::getDefaultIconColor() { } PropertyValue<Color> SymbolLayer::getIconColor(const optional<std::string>& klass) const { - return impl->paint.iconColor.get(klass); + return impl->paint.get<IconColor>(klass); } void SymbolLayer::setIconColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getIconColor(klass)) return; - impl->paint.iconColor.set(value, klass); + impl->paint.set<IconColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -573,13 +573,13 @@ PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() { } PropertyValue<Color> SymbolLayer::getIconHaloColor(const optional<std::string>& klass) const { - return impl->paint.iconHaloColor.get(klass); + return impl->paint.get<IconHaloColor>(klass); } void SymbolLayer::setIconHaloColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getIconHaloColor(klass)) return; - impl->paint.iconHaloColor.set(value, klass); + impl->paint.set<IconHaloColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -588,13 +588,13 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() { } PropertyValue<float> SymbolLayer::getIconHaloWidth(const optional<std::string>& klass) const { - return impl->paint.iconHaloWidth.get(klass); + return impl->paint.get<IconHaloWidth>(klass); } void SymbolLayer::setIconHaloWidth(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getIconHaloWidth(klass)) return; - impl->paint.iconHaloWidth.set(value, klass); + impl->paint.set<IconHaloWidth>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -603,13 +603,13 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() { } PropertyValue<float> SymbolLayer::getIconHaloBlur(const optional<std::string>& klass) const { - return impl->paint.iconHaloBlur.get(klass); + return impl->paint.get<IconHaloBlur>(klass); } void SymbolLayer::setIconHaloBlur(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getIconHaloBlur(klass)) return; - impl->paint.iconHaloBlur.set(value, klass); + impl->paint.set<IconHaloBlur>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -618,13 +618,13 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() { } PropertyValue<std::array<float, 2>> SymbolLayer::getIconTranslate(const optional<std::string>& klass) const { - return impl->paint.iconTranslate.get(klass); + return impl->paint.get<IconTranslate>(klass); } void SymbolLayer::setIconTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) { if (value == getIconTranslate(klass)) return; - impl->paint.iconTranslate.set(value, klass); + impl->paint.set<IconTranslate>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -633,13 +633,13 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() } PropertyValue<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor(const optional<std::string>& klass) const { - return impl->paint.iconTranslateAnchor.get(klass); + return impl->paint.get<IconTranslateAnchor>(klass); } void SymbolLayer::setIconTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) { if (value == getIconTranslateAnchor(klass)) return; - impl->paint.iconTranslateAnchor.set(value, klass); + impl->paint.set<IconTranslateAnchor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -648,13 +648,13 @@ PropertyValue<float> SymbolLayer::getDefaultTextOpacity() { } PropertyValue<float> SymbolLayer::getTextOpacity(const optional<std::string>& klass) const { - return impl->paint.textOpacity.get(klass); + return impl->paint.get<TextOpacity>(klass); } void SymbolLayer::setTextOpacity(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getTextOpacity(klass)) return; - impl->paint.textOpacity.set(value, klass); + impl->paint.set<TextOpacity>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -663,13 +663,13 @@ PropertyValue<Color> SymbolLayer::getDefaultTextColor() { } PropertyValue<Color> SymbolLayer::getTextColor(const optional<std::string>& klass) const { - return impl->paint.textColor.get(klass); + return impl->paint.get<TextColor>(klass); } void SymbolLayer::setTextColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getTextColor(klass)) return; - impl->paint.textColor.set(value, klass); + impl->paint.set<TextColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -678,13 +678,13 @@ PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() { } PropertyValue<Color> SymbolLayer::getTextHaloColor(const optional<std::string>& klass) const { - return impl->paint.textHaloColor.get(klass); + return impl->paint.get<TextHaloColor>(klass); } void SymbolLayer::setTextHaloColor(PropertyValue<Color> value, const optional<std::string>& klass) { if (value == getTextHaloColor(klass)) return; - impl->paint.textHaloColor.set(value, klass); + impl->paint.set<TextHaloColor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -693,13 +693,13 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() { } PropertyValue<float> SymbolLayer::getTextHaloWidth(const optional<std::string>& klass) const { - return impl->paint.textHaloWidth.get(klass); + return impl->paint.get<TextHaloWidth>(klass); } void SymbolLayer::setTextHaloWidth(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getTextHaloWidth(klass)) return; - impl->paint.textHaloWidth.set(value, klass); + impl->paint.set<TextHaloWidth>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -708,13 +708,13 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() { } PropertyValue<float> SymbolLayer::getTextHaloBlur(const optional<std::string>& klass) const { - return impl->paint.textHaloBlur.get(klass); + return impl->paint.get<TextHaloBlur>(klass); } void SymbolLayer::setTextHaloBlur(PropertyValue<float> value, const optional<std::string>& klass) { if (value == getTextHaloBlur(klass)) return; - impl->paint.textHaloBlur.set(value, klass); + impl->paint.set<TextHaloBlur>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -723,13 +723,13 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() { } PropertyValue<std::array<float, 2>> SymbolLayer::getTextTranslate(const optional<std::string>& klass) const { - return impl->paint.textTranslate.get(klass); + return impl->paint.get<TextTranslate>(klass); } void SymbolLayer::setTextTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) { if (value == getTextTranslate(klass)) return; - impl->paint.textTranslate.set(value, klass); + impl->paint.set<TextTranslate>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } @@ -738,13 +738,13 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() } PropertyValue<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor(const optional<std::string>& klass) const { - return impl->paint.textTranslateAnchor.get(klass); + return impl->paint.get<TextTranslateAnchor>(klass); } void SymbolLayer::setTextTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) { if (value == getTextTranslateAnchor(klass)) return; - impl->paint.textTranslateAnchor.set(value, klass); + impl->paint.set<TextTranslateAnchor>(value, klass); impl->observer->onLayerPaintPropertyChanged(*this); } diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp index 0ac9ff832d..957bc1993e 100644 --- a/src/mbgl/style/layers/symbol_layer_impl.cpp +++ b/src/mbgl/style/layers/symbol_layer_impl.cpp @@ -10,20 +10,18 @@ void SymbolLayer::Impl::cascade(const CascadeParameters& parameters) { paint.cascade(parameters); } -bool SymbolLayer::Impl::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = paint.recalculate(parameters); +bool SymbolLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) { + paint.evaluate(parameters); // text-size and icon-size are layout properties but they also need to be evaluated as paint properties: - layout.iconSize.calculate(parameters); - layout.textSize.calculate(parameters); - iconSize = layout.iconSize; - textSize = layout.textSize; + iconSize = layout.evaluate<IconSize>(parameters); + textSize = layout.evaluate<TextSize>(parameters); - passes = ((paint.iconOpacity > 0 && (paint.iconColor.value.a > 0 || paint.iconHaloColor.value.a > 0) && iconSize > 0) - || (paint.textOpacity > 0 && (paint.textColor.value.a > 0 || paint.textHaloColor.value.a > 0) && textSize > 0)) + passes = ((paint.evaluated.get<IconOpacity>() > 0 && (paint.evaluated.get<IconColor>().a > 0 || paint.evaluated.get<IconHaloColor>().a > 0) && iconSize > 0) + || (paint.evaluated.get<TextOpacity>() > 0 && (paint.evaluated.get<TextColor>().a > 0 || paint.evaluated.get<TextHaloColor>().a > 0) && textSize > 0)) ? RenderPass::Translucent : RenderPass::None; - return hasTransitions; + return paint.hasTransition(); } std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&) const { @@ -32,37 +30,34 @@ std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&) const } std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters) const { - SymbolLayoutProperties layoutProperties = layout; + PropertyEvaluationParameters p(parameters.tileID.overscaledZ); + SymbolLayoutProperties::Evaluated evaluated = layout.evaluate(p); - CalculationParameters p(parameters.tileID.overscaledZ); - layoutProperties.recalculate(p); - - if (layoutProperties.iconRotationAlignment.value == AlignmentType::Auto) { - if (layoutProperties.symbolPlacement.value == SymbolPlacementType::Line) { - layoutProperties.iconRotationAlignment.value = AlignmentType::Map; + if (evaluated.get<IconRotationAlignment>() == AlignmentType::Auto) { + if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) { + evaluated.get<IconRotationAlignment>() = AlignmentType::Map; } else { - layoutProperties.iconRotationAlignment.value = AlignmentType::Viewport; + evaluated.get<IconRotationAlignment>() = AlignmentType::Viewport; } } - if (layoutProperties.textRotationAlignment.value == AlignmentType::Auto) { - if (layoutProperties.symbolPlacement.value == SymbolPlacementType::Line) { - layoutProperties.textRotationAlignment.value = AlignmentType::Map; + if (evaluated.get<TextRotationAlignment>() == AlignmentType::Auto) { + if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) { + evaluated.get<TextRotationAlignment>() = AlignmentType::Map; } else { - layoutProperties.textRotationAlignment.value = AlignmentType::Viewport; + evaluated.get<TextRotationAlignment>() = AlignmentType::Viewport; } } // If unspecified `text-pitch-alignment` inherits `text-rotation-alignment` - if (layoutProperties.textPitchAlignment.value == AlignmentType::Auto) { - layoutProperties.textPitchAlignment.value = layoutProperties.textRotationAlignment.value; + if (evaluated.get<TextPitchAlignment>() == AlignmentType::Auto) { + evaluated.get<TextPitchAlignment>() = evaluated.get<TextRotationAlignment>(); } - layoutProperties.textSize.calculate(CalculationParameters(18)); - float textMaxSize = layoutProperties.textSize; + float textMaxSize = layout.evaluate<TextSize>(PropertyEvaluationParameters(18)); - layoutProperties.iconSize.calculate(CalculationParameters(p.z + 1)); - layoutProperties.textSize.calculate(CalculationParameters(p.z + 1)); + evaluated.get<IconSize>() = layout.evaluate<IconSize>(PropertyEvaluationParameters(p.z + 1)); + evaluated.get<TextSize>() = layout.evaluate<TextSize>(PropertyEvaluationParameters(p.z + 1)); return std::make_unique<SymbolLayout>(id, parameters.layer.getName(), @@ -71,40 +66,40 @@ std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters.mode, parameters.layer, filter, - layoutProperties, + evaluated, textMaxSize, *spriteAtlas); } -SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties& layout_) const { +SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const { return SymbolPropertyValues { - layout_.iconRotationAlignment.value, // icon-pitch-alignment is not yet implemented; inherit the rotation alignment - layout_.iconRotationAlignment.value, - layout_.iconSize.value, - paint.iconOpacity.value, - paint.iconColor.value, - paint.iconHaloColor.value, - paint.iconHaloWidth.value, - paint.iconHaloBlur.value, - paint.iconTranslate.value, - paint.iconTranslateAnchor.value, + layout_.get<IconRotationAlignment>(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment + layout_.get<IconRotationAlignment>(), + layout_.get<IconSize>(), + paint.evaluated.get<IconOpacity>(), + paint.evaluated.get<IconColor>(), + paint.evaluated.get<IconHaloColor>(), + paint.evaluated.get<IconHaloWidth>(), + paint.evaluated.get<IconHaloBlur>(), + paint.evaluated.get<IconTranslate>(), + paint.evaluated.get<IconTranslateAnchor>(), iconSize, 1.0f }; } -SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties& layout_) const { +SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const { return SymbolPropertyValues { - layout_.textPitchAlignment.value, - layout_.textRotationAlignment.value, - layout_.textSize.value, - paint.textOpacity.value, - paint.textColor.value, - paint.textHaloColor.value, - paint.textHaloWidth.value, - paint.textHaloBlur.value, - paint.textTranslate.value, - paint.textTranslateAnchor.value, + layout_.get<TextPitchAlignment>(), + layout_.get<TextRotationAlignment>(), + layout_.get<TextSize>(), + paint.evaluated.get<TextOpacity>(), + paint.evaluated.get<TextColor>(), + paint.evaluated.get<TextHaloColor>(), + paint.evaluated.get<TextHaloWidth>(), + paint.evaluated.get<TextHaloBlur>(), + paint.evaluated.get<TextTranslate>(), + paint.evaluated.get<TextTranslateAnchor>(), textSize, 24.0f }; diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp index b760538f86..46ed75b231 100644 --- a/src/mbgl/style/layers/symbol_layer_impl.hpp +++ b/src/mbgl/style/layers/symbol_layer_impl.hpp @@ -47,13 +47,13 @@ public: std::unique_ptr<Layer> cloneRef(const std::string& id) const override; void cascade(const CascadeParameters&) override; - bool recalculate(const CalculationParameters&) override; + bool evaluate(const PropertyEvaluationParameters&) override; std::unique_ptr<Bucket> createBucket(BucketParameters&) const override; std::unique_ptr<SymbolLayout> createLayout(BucketParameters&) const; - SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties&) const; - SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties&) const; + SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties::Evaluated&) const; + SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties::Evaluated&) const; SymbolLayoutProperties layout; SymbolPaintProperties paint; diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp index 59a73d3d59..5a1ce713ba 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.cpp +++ b/src/mbgl/style/layers/symbol_layer_properties.cpp @@ -5,80 +5,5 @@ namespace mbgl { namespace style { -void SymbolLayoutProperties::recalculate(const CalculationParameters& parameters) { - symbolPlacement.calculate(parameters); - symbolSpacing.calculate(parameters); - symbolAvoidEdges.calculate(parameters); - iconAllowOverlap.calculate(parameters); - iconIgnorePlacement.calculate(parameters); - iconOptional.calculate(parameters); - iconRotationAlignment.calculate(parameters); - iconSize.calculate(parameters); - iconTextFit.calculate(parameters); - iconTextFitPadding.calculate(parameters); - iconImage.calculate(parameters); - iconRotate.calculate(parameters); - iconPadding.calculate(parameters); - iconKeepUpright.calculate(parameters); - iconOffset.calculate(parameters); - textPitchAlignment.calculate(parameters); - textRotationAlignment.calculate(parameters); - textField.calculate(parameters); - textFont.calculate(parameters); - textSize.calculate(parameters); - textMaxWidth.calculate(parameters); - textLineHeight.calculate(parameters); - textLetterSpacing.calculate(parameters); - textJustify.calculate(parameters); - textAnchor.calculate(parameters); - textMaxAngle.calculate(parameters); - textRotate.calculate(parameters); - textPadding.calculate(parameters); - textKeepUpright.calculate(parameters); - textTransform.calculate(parameters); - textOffset.calculate(parameters); - textAllowOverlap.calculate(parameters); - textIgnorePlacement.calculate(parameters); - textOptional.calculate(parameters); -} - -void SymbolPaintProperties::cascade(const CascadeParameters& parameters) { - iconOpacity.cascade(parameters); - iconColor.cascade(parameters); - iconHaloColor.cascade(parameters); - iconHaloWidth.cascade(parameters); - iconHaloBlur.cascade(parameters); - iconTranslate.cascade(parameters); - iconTranslateAnchor.cascade(parameters); - textOpacity.cascade(parameters); - textColor.cascade(parameters); - textHaloColor.cascade(parameters); - textHaloWidth.cascade(parameters); - textHaloBlur.cascade(parameters); - textTranslate.cascade(parameters); - textTranslateAnchor.cascade(parameters); -} - -bool SymbolPaintProperties::recalculate(const CalculationParameters& parameters) { - bool hasTransitions = false; - - hasTransitions |= iconOpacity.calculate(parameters); - hasTransitions |= iconColor.calculate(parameters); - hasTransitions |= iconHaloColor.calculate(parameters); - hasTransitions |= iconHaloWidth.calculate(parameters); - hasTransitions |= iconHaloBlur.calculate(parameters); - hasTransitions |= iconTranslate.calculate(parameters); - hasTransitions |= iconTranslateAnchor.calculate(parameters); - hasTransitions |= textOpacity.calculate(parameters); - hasTransitions |= textColor.calculate(parameters); - hasTransitions |= textHaloColor.calculate(parameters); - hasTransitions |= textHaloWidth.calculate(parameters); - hasTransitions |= textHaloBlur.calculate(parameters); - hasTransitions |= textTranslate.calculate(parameters); - hasTransitions |= textTranslateAnchor.calculate(parameters); - - return hasTransitions; -} - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index fefa0ae05e..8b72c4347a 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -9,69 +9,251 @@ namespace mbgl { namespace style { -class CascadeParameters; -class CalculationParameters; - -class SymbolLayoutProperties { -public: - void recalculate(const CalculationParameters&); - - LayoutProperty<SymbolPlacementType> symbolPlacement { SymbolPlacementType::Point }; - LayoutProperty<float> symbolSpacing { 250 }; - LayoutProperty<bool> symbolAvoidEdges { false }; - LayoutProperty<bool> iconAllowOverlap { false }; - LayoutProperty<bool> iconIgnorePlacement { false }; - LayoutProperty<bool> iconOptional { false }; - LayoutProperty<AlignmentType> iconRotationAlignment { AlignmentType::Auto }; - LayoutProperty<float> iconSize { 1 }; - LayoutProperty<IconTextFitType> iconTextFit { IconTextFitType::None }; - LayoutProperty<std::array<float, 4>> iconTextFitPadding { {{ 0, 0, 0, 0 }} }; - LayoutProperty<std::string> iconImage { "" }; - LayoutProperty<float> iconRotate { 0 }; - LayoutProperty<float> iconPadding { 2 }; - LayoutProperty<bool> iconKeepUpright { false }; - LayoutProperty<std::array<float, 2>> iconOffset { {{ 0, 0 }} }; - LayoutProperty<AlignmentType> textPitchAlignment { AlignmentType::Auto }; - LayoutProperty<AlignmentType> textRotationAlignment { AlignmentType::Auto }; - LayoutProperty<std::string> textField { "" }; - LayoutProperty<std::vector<std::string>> textFont { { "Open Sans Regular", "Arial Unicode MS Regular" } }; - LayoutProperty<float> textSize { 16 }; - LayoutProperty<float> textMaxWidth { 10 }; - LayoutProperty<float> textLineHeight { 1.2 }; - LayoutProperty<float> textLetterSpacing { 0 }; - LayoutProperty<TextJustifyType> textJustify { TextJustifyType::Center }; - LayoutProperty<TextAnchorType> textAnchor { TextAnchorType::Center }; - LayoutProperty<float> textMaxAngle { 45 }; - LayoutProperty<float> textRotate { 0 }; - LayoutProperty<float> textPadding { 2 }; - LayoutProperty<bool> textKeepUpright { true }; - LayoutProperty<TextTransformType> textTransform { TextTransformType::None }; - LayoutProperty<std::array<float, 2>> textOffset { {{ 0, 0 }} }; - LayoutProperty<bool> textAllowOverlap { false }; - LayoutProperty<bool> textIgnorePlacement { false }; - LayoutProperty<bool> textOptional { false }; -}; - -class SymbolPaintProperties { -public: - void cascade(const CascadeParameters&); - bool recalculate(const CalculationParameters&); - - PaintProperty<float> iconOpacity { 1 }; - PaintProperty<Color> iconColor { Color::black() }; - PaintProperty<Color> iconHaloColor { {} }; - PaintProperty<float> iconHaloWidth { 0 }; - PaintProperty<float> iconHaloBlur { 0 }; - PaintProperty<std::array<float, 2>> iconTranslate { {{ 0, 0 }} }; - PaintProperty<TranslateAnchorType> iconTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty<float> textOpacity { 1 }; - PaintProperty<Color> textColor { Color::black() }; - PaintProperty<Color> textHaloColor { {} }; - PaintProperty<float> textHaloWidth { 0 }; - PaintProperty<float> textHaloBlur { 0 }; - PaintProperty<std::array<float, 2>> textTranslate { {{ 0, 0 }} }; - PaintProperty<TranslateAnchorType> textTranslateAnchor { TranslateAnchorType::Map }; +struct SymbolPlacement : LayoutProperty<SymbolPlacementType> { + static SymbolPlacementType defaultValue() { return SymbolPlacementType::Point; } }; +struct SymbolSpacing : LayoutProperty<float> { + static float defaultValue() { return 250; } +}; + +struct SymbolAvoidEdges : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct IconAllowOverlap : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct IconIgnorePlacement : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct IconOptional : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct IconRotationAlignment : LayoutProperty<AlignmentType> { + static AlignmentType defaultValue() { return AlignmentType::Auto; } +}; + +struct IconSize : LayoutProperty<float> { + static float defaultValue() { return 1; } +}; + +struct IconTextFit : LayoutProperty<IconTextFitType> { + static IconTextFitType defaultValue() { return IconTextFitType::None; } +}; + +struct IconTextFitPadding : LayoutProperty<std::array<float, 4>> { + static std::array<float, 4> defaultValue() { return {{ 0, 0, 0, 0 }}; } +}; + +struct IconImage : LayoutProperty<std::string> { + static std::string defaultValue() { return ""; } +}; + +struct IconRotate : LayoutProperty<float> { + static float defaultValue() { return 0; } +}; + +struct IconPadding : LayoutProperty<float> { + static float defaultValue() { return 2; } +}; + +struct IconKeepUpright : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct IconOffset : LayoutProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct TextPitchAlignment : LayoutProperty<AlignmentType> { + static AlignmentType defaultValue() { return AlignmentType::Auto; } +}; + +struct TextRotationAlignment : LayoutProperty<AlignmentType> { + static AlignmentType defaultValue() { return AlignmentType::Auto; } +}; + +struct TextField : LayoutProperty<std::string> { + static std::string defaultValue() { return ""; } +}; + +struct TextFont : LayoutProperty<std::vector<std::string>> { + static std::vector<std::string> defaultValue() { return { "Open Sans Regular", "Arial Unicode MS Regular" }; } +}; + +struct TextSize : LayoutProperty<float> { + static float defaultValue() { return 16; } +}; + +struct TextMaxWidth : LayoutProperty<float> { + static float defaultValue() { return 10; } +}; + +struct TextLineHeight : LayoutProperty<float> { + static float defaultValue() { return 1.2; } +}; + +struct TextLetterSpacing : LayoutProperty<float> { + static float defaultValue() { return 0; } +}; + +struct TextJustify : LayoutProperty<TextJustifyType> { + static TextJustifyType defaultValue() { return TextJustifyType::Center; } +}; + +struct TextAnchor : LayoutProperty<TextAnchorType> { + static TextAnchorType defaultValue() { return TextAnchorType::Center; } +}; + +struct TextMaxAngle : LayoutProperty<float> { + static float defaultValue() { return 45; } +}; + +struct TextRotate : LayoutProperty<float> { + static float defaultValue() { return 0; } +}; + +struct TextPadding : LayoutProperty<float> { + static float defaultValue() { return 2; } +}; + +struct TextKeepUpright : LayoutProperty<bool> { + static bool defaultValue() { return true; } +}; + +struct TextTransform : LayoutProperty<TextTransformType> { + static TextTransformType defaultValue() { return TextTransformType::None; } +}; + +struct TextOffset : LayoutProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct TextAllowOverlap : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct TextIgnorePlacement : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct TextOptional : LayoutProperty<bool> { + static bool defaultValue() { return false; } +}; + +struct IconOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct IconColor : PaintProperty<Color> { + static Color defaultValue() { return Color::black(); } +}; + +struct IconHaloColor : PaintProperty<Color> { + static Color defaultValue() { return {}; } +}; + +struct IconHaloWidth : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct IconHaloBlur : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct IconTranslate : PaintProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct IconTranslateAnchor : PaintProperty<TranslateAnchorType> { + static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } +}; + +struct TextOpacity : PaintProperty<float> { + static float defaultValue() { return 1; } +}; + +struct TextColor : PaintProperty<Color> { + static Color defaultValue() { return Color::black(); } +}; + +struct TextHaloColor : PaintProperty<Color> { + static Color defaultValue() { return {}; } +}; + +struct TextHaloWidth : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct TextHaloBlur : PaintProperty<float> { + static float defaultValue() { return 0; } +}; + +struct TextTranslate : PaintProperty<std::array<float, 2>> { + static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; } +}; + +struct TextTranslateAnchor : PaintProperty<TranslateAnchorType> { + static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } +}; + +class SymbolLayoutProperties : public LayoutProperties< + SymbolPlacement, + SymbolSpacing, + SymbolAvoidEdges, + IconAllowOverlap, + IconIgnorePlacement, + IconOptional, + IconRotationAlignment, + IconSize, + IconTextFit, + IconTextFitPadding, + IconImage, + IconRotate, + IconPadding, + IconKeepUpright, + IconOffset, + TextPitchAlignment, + TextRotationAlignment, + TextField, + TextFont, + TextSize, + TextMaxWidth, + TextLineHeight, + TextLetterSpacing, + TextJustify, + TextAnchor, + TextMaxAngle, + TextRotate, + TextPadding, + TextKeepUpright, + TextTransform, + TextOffset, + TextAllowOverlap, + TextIgnorePlacement, + TextOptional +> {}; + +class SymbolPaintProperties : public PaintProperties< + IconOpacity, + IconColor, + IconHaloColor, + IconHaloWidth, + IconHaloBlur, + IconTranslate, + IconTranslateAnchor, + TextOpacity, + TextColor, + TextHaloColor, + TextHaloWidth, + TextHaloBlur, + TextTranslate, + TextTranslateAnchor +> {}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp index db1a1ebf28..6ea06ce556 100644 --- a/src/mbgl/style/layout_property.hpp +++ b/src/mbgl/style/layout_property.hpp @@ -1,43 +1,55 @@ #pragma once -#include <mbgl/style/property_value.hpp> -#include <mbgl/style/property_parsing.hpp> #include <mbgl/style/property_evaluator.hpp> - -#include <utility> +#include <mbgl/util/indexed_tuple.hpp> namespace mbgl { namespace style { -template <typename T> +class PropertyEvaluationParameters; + +template <class T> class LayoutProperty { public: - explicit LayoutProperty(T v) - : value(std::move(v)), - defaultValue(value) {} - - const PropertyValue<T>& get() const { - return currentValue; - } + using EvaluatorType = PropertyEvaluator<T>; + using UnevaluatedType = PropertyValue<T>; + using EvaluatedType = T; +}; - void set(const PropertyValue<T>& value_) { - currentValue = value_; +template <class... Ps> +class LayoutProperties { +public: + using Properties = TypeList<Ps...>; + using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>; + using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>; + + template <class TypeList> + using Tuple = IndexedTuple<Properties, TypeList>; + + class Evaluated : public Tuple<EvaluatedTypes> { + public: + using Tuple<EvaluatedTypes>::Tuple; + }; + + class Unevaluated : public Tuple<UnevaluatedTypes> { + public: + using Tuple<UnevaluatedTypes>::Tuple; + }; + + template <class P> + auto evaluate(const PropertyEvaluationParameters& parameters) const { + using Evaluator = typename P::EvaluatorType; + return unevaluated.template get<P>() + .evaluate(Evaluator(parameters, P::defaultValue())); } - void calculate(const CalculationParameters& parameters) { - if (currentValue) { - PropertyEvaluator<T> evaluator(parameters, defaultValue); - value = PropertyValue<T>::visit(currentValue, evaluator); - } + Evaluated evaluate(const PropertyEvaluationParameters& parameters) const { + return Evaluated { + evaluate<Ps>(parameters)... + }; } - // TODO: remove / privatize - operator T() const { return value; } - T value; - -private: - T defaultValue; - PropertyValue<T> currentValue; + Unevaluated unevaluated; }; } // namespace style diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 4a620706ec..bd25877d11 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -1,14 +1,14 @@ #pragma once #include <mbgl/style/class_dictionary.hpp> -#include <mbgl/style/property_parsing.hpp> #include <mbgl/style/property_evaluator.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/style/cascade_parameters.hpp> -#include <mbgl/style/calculation_parameters.hpp> +#include <mbgl/style/property_evaluation_parameters.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/util/interpolate.hpp> -#include <mbgl/util/rapidjson.hpp> +#include <mbgl/util/indexed_tuple.hpp> +#include <mbgl/util/ignore.hpp> #include <unordered_map> #include <utility> @@ -16,29 +16,59 @@ namespace mbgl { namespace style { -template <class T, template <class S> class Evaluator = PropertyEvaluator> -class PaintProperty { +template <class T, class Evaluator> +class UnevaluatedPaintProperty { public: - using Result = typename Evaluator<T>::ResultType; + using Result = typename Evaluator::ResultType; + + UnevaluatedPaintProperty() = default; + + UnevaluatedPaintProperty(PropertyValue<T> value_, + UnevaluatedPaintProperty<T, Evaluator> prior_, + TransitionOptions transition, + TimePoint now) + : begin(now + transition.delay.value_or(Duration::zero())), + end(begin + transition.duration.value_or(Duration::zero())), + value(std::move(value_)) { + if (transition) { + prior = { std::move(prior_) }; + } + } - explicit PaintProperty(T defaultValue_) - : defaultValue(defaultValue_) { - values.emplace(ClassID::Fallback, defaultValue_); + Result evaluate(const PropertyEvaluationParameters& parameters, T defaultValue) { + Result finalValue = value.evaluate(Evaluator(parameters, defaultValue)); + if (!prior) { + // No prior value. + return finalValue; + } else if (parameters.now >= end) { + // Transition from prior value is now complete. + prior = {}; + return finalValue; + } else { + // Interpolate between recursively-calculated prior value and final. + float t = std::chrono::duration<float>(parameters.now - begin) / (end - begin); + return util::interpolate(prior->get().evaluate(parameters, defaultValue), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001)); + } } - PaintProperty(const PaintProperty& other) - : defaultValue(other.defaultValue), - values(other.values), - transitions(other.transitions) { + bool hasTransition() const { + return bool(prior); } - PaintProperty& operator=(const PaintProperty& other) { - defaultValue = other.defaultValue; - values = other.values; - transitions = other.transitions; - return *this; + bool isUndefined() const { + return value.isUndefined(); } +private: + optional<mapbox::util::recursive_wrapper<UnevaluatedPaintProperty<T, Evaluator>>> prior; + TimePoint begin; + TimePoint end; + PropertyValue<T> value; +}; + +template <class T> +class CascadingPaintProperty { +public: bool isUndefined() const { return values.find(ClassID::Default) == values.end(); } @@ -57,82 +87,119 @@ public: transitions[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = transition; } - void cascade(const CascadeParameters& params) { - const bool overrideTransition = !params.transition.delay && !params.transition.duration; - Duration delay = params.transition.delay.value_or(Duration::zero()); - Duration duration = params.transition.duration.value_or(Duration::zero()); + template <class UnevaluatedPaintProperty> + UnevaluatedPaintProperty cascade(const CascadeParameters& params, UnevaluatedPaintProperty prior) const { + TransitionOptions transition; + PropertyValue<T> value; for (const auto classID : params.classes) { - if (values.find(classID) == values.end()) - continue; - - if (overrideTransition && transitions.find(classID) != transitions.end()) { - const TransitionOptions& transition = transitions[classID]; - if (transition.delay) delay = *transition.delay; - if (transition.duration) duration = *transition.duration; + if (values.find(classID) != values.end()) { + value = values.at(classID); + break; } - - cascaded = std::make_unique<CascadedValue>(std::move(cascaded), - params.now + delay, - params.now + delay + duration, - values.at(classID)); - - break; } - assert(cascaded); - } + for (const auto classID : params.classes) { + if (transitions.find(classID) != transitions.end()) { + transition = transitions.at(classID).reverseMerge(transition); + break; + } + } - bool calculate(const CalculationParameters& parameters) { - assert(cascaded); - Evaluator<T> evaluator(parameters, defaultValue); - value = cascaded->calculate(evaluator, parameters.now); - return cascaded->prior.operator bool(); + return UnevaluatedPaintProperty(std::move(value), + std::move(prior), + transition.reverseMerge(params.transition), + params.now); } - // TODO: remove / privatize - operator T() const { return value; } - Result value; - private: - T defaultValue; std::unordered_map<ClassID, PropertyValue<T>> values; std::unordered_map<ClassID, TransitionOptions> transitions; +}; - struct CascadedValue { - CascadedValue(std::unique_ptr<CascadedValue> prior_, - TimePoint begin_, - TimePoint end_, - PropertyValue<T> value_) - : prior(std::move(prior_)), - begin(std::move(begin_)), - end(std::move(end_)), - value(std::move(value_)) { - } +template <class T> +class PaintProperty { +public: + using ValueType = PropertyValue<T>; + using CascadingType = CascadingPaintProperty<T>; + using EvaluatorType = PropertyEvaluator<T>; + using UnevaluatedType = UnevaluatedPaintProperty<T, EvaluatorType>; + using EvaluatedType = T; +}; - Result calculate(const Evaluator<T>& evaluator, const TimePoint& now) { - Result finalValue = PropertyValue<T>::visit(value, evaluator); - if (!prior) { - // No prior value. - return finalValue; - } else if (now >= end) { - // Transition from prior value is now complete. - prior.reset(); - return finalValue; - } else { - // Interpolate between recursively-calculated prior value and final. - float t = std::chrono::duration<float>(now - begin) / (end - begin); - return util::interpolate(prior->calculate(evaluator, now), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001)); - } - } +template <class T> +class CrossFadedPaintProperty { +public: + using ValueType = PropertyValue<T>; + using CascadingType = CascadingPaintProperty<T>; + using EvaluatorType = CrossFadedPropertyEvaluator<T>; + using UnevaluatedType = UnevaluatedPaintProperty<T, EvaluatorType>; + using EvaluatedType = Faded<T>; +}; - std::unique_ptr<CascadedValue> prior; - TimePoint begin; - TimePoint end; - PropertyValue<T> value; +template <class... Ps> +class PaintProperties { +public: + using Properties = TypeList<Ps...>; + using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>; + using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>; + using CascadingTypes = TypeList<typename Ps::CascadingType...>; + + template <class TypeList> + using Tuple = IndexedTuple<Properties, TypeList>; + + class Evaluated : public Tuple<EvaluatedTypes> { + public: + using Tuple<EvaluatedTypes>::Tuple; + }; + + class Unevaluated : public Tuple<UnevaluatedTypes> { + public: + using Tuple<UnevaluatedTypes>::Tuple; }; - std::unique_ptr<CascadedValue> cascaded; + class Cascading : public Tuple<CascadingTypes> { + public: + using Tuple<CascadingTypes>::Tuple; + }; + + template <class P> + auto get(const optional<std::string>& klass) const { + return cascading.template get<P>().get(klass); + } + + template <class P> + void set(const typename P::ValueType& value, const optional<std::string>& klass) { + cascading.template get<P>().set(value, klass); + } + + void cascade(const CascadeParameters& parameters) { + unevaluated = Unevaluated { + cascading.template get<Ps>().cascade(parameters, + std::move(unevaluated.template get<Ps>()))... + }; + } + + template <class P> + auto evaluate(const PropertyEvaluationParameters& parameters) { + return unevaluated.template get<P>().evaluate(parameters, P::defaultValue()); + } + + void evaluate(const PropertyEvaluationParameters& parameters) { + evaluated = Evaluated { + evaluate<Ps>(parameters)... + }; + } + + bool hasTransition() const { + bool result = false; + util::ignore({ result |= unevaluated.template get<Ps>().hasTransition()... }); + return result; + } + + Cascading cascading; + Unevaluated unevaluated; + Evaluated evaluated; }; } // namespace style diff --git a/src/mbgl/style/calculation_parameters.hpp b/src/mbgl/style/property_evaluation_parameters.hpp index e1f059c524..2591fc07a1 100644 --- a/src/mbgl/style/calculation_parameters.hpp +++ b/src/mbgl/style/property_evaluation_parameters.hpp @@ -6,12 +6,12 @@ namespace mbgl { namespace style { -class CalculationParameters { +class PropertyEvaluationParameters { public: - explicit CalculationParameters(float z_) + explicit PropertyEvaluationParameters(float z_) : z(z_) {} - CalculationParameters(float z_, + PropertyEvaluationParameters(float z_, TimePoint now_, ZoomHistory zoomHistory_, Duration defaultFadeDuration_) diff --git a/src/mbgl/style/property_evaluator.cpp b/src/mbgl/style/property_evaluator.cpp index abb3681efa..c19f722100 100644 --- a/src/mbgl/style/property_evaluator.cpp +++ b/src/mbgl/style/property_evaluator.cpp @@ -1,5 +1,5 @@ #include <mbgl/style/property_evaluator.hpp> -#include <mbgl/style/calculation_parameters.hpp> +#include <mbgl/style/property_evaluation_parameters.hpp> #include <mbgl/style/types.hpp> #include <mbgl/util/interpolate.hpp> #include <mbgl/util/chrono.hpp> diff --git a/src/mbgl/style/property_evaluator.hpp b/src/mbgl/style/property_evaluator.hpp index 3f657fe3f4..c93a11a4e1 100644 --- a/src/mbgl/style/property_evaluator.hpp +++ b/src/mbgl/style/property_evaluator.hpp @@ -6,14 +6,14 @@ namespace mbgl { namespace style { -class CalculationParameters; +class PropertyEvaluationParameters; template <typename T> class PropertyEvaluator { public: using ResultType = T; - PropertyEvaluator(const CalculationParameters& parameters_, T defaultValue_) + PropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_) : parameters(parameters_), defaultValue(std::move(defaultValue_)) {} @@ -22,7 +22,7 @@ public: T operator()(const Function<T>&) const; private: - const CalculationParameters& parameters; + const PropertyEvaluationParameters& parameters; T defaultValue; }; @@ -41,7 +41,7 @@ class CrossFadedPropertyEvaluator { public: using ResultType = Faded<T>; - CrossFadedPropertyEvaluator(const CalculationParameters& parameters_, T defaultValue_) + CrossFadedPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_) : parameters(parameters_), defaultValue(std::move(defaultValue_)) {} @@ -52,7 +52,7 @@ public: private: Faded<T> calculate(const T& min, const T& mid, const T& max) const; - const CalculationParameters& parameters; + const PropertyEvaluationParameters& parameters; T defaultValue; }; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 0b3d782d06..d2c8798614 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -18,7 +18,7 @@ #include <mbgl/style/class_dictionary.hpp> #include <mbgl/style/update_parameters.hpp> #include <mbgl/style/cascade_parameters.hpp> -#include <mbgl/style/calculation_parameters.hpp> +#include <mbgl/style/property_evaluation_parameters.hpp> #include <mbgl/sprite/sprite_atlas.hpp> #include <mbgl/text/glyph_atlas.hpp> #include <mbgl/geometry/line_atlas.hpp> @@ -266,7 +266,6 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) { classIDs.push_back(ClassDictionary::Get().lookup(className)); } classIDs.push_back(ClassID::Default); - classIDs.push_back(ClassID::Fallback); const CascadeParameters parameters { classIDs, @@ -288,7 +287,7 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) { zoomHistory.update(z, timePoint); - const CalculationParameters parameters { + const PropertyEvaluationParameters parameters { z, mode == MapMode::Continuous ? timePoint : Clock::time_point::max(), zoomHistory, @@ -297,7 +296,7 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) { hasPendingTransitions = false; for (const auto& layer : layers) { - const bool hasTransitions = layer->baseImpl->recalculate(parameters); + const bool hasTransitions = layer->baseImpl->evaluate(parameters); // Disable this layer if it doesn't need to be rendered. const bool needsRendering = layer->baseImpl->needsRendering(zoomHistory.lastZoom); @@ -374,10 +373,10 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const { result.order.emplace_back(*layer); continue; } - const BackgroundPaintProperties& paint = background->impl->paint; - if (layer.get() == layers[0].get() && paint.backgroundPattern.value.from.empty()) { + const BackgroundPaintProperties::Evaluated& paint = background->impl->paint.evaluated; + if (layer.get() == layers[0].get() && paint.get<BackgroundPattern>().from.empty()) { // This is a solid background. We can use glClear(). - result.backgroundColor = paint.backgroundColor * paint.backgroundOpacity; + result.backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>(); } else { // This is a textured background, or not the bottommost layer. We need to render it with a quad. result.order.emplace_back(*layer); diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 3f142cd908..1a05e6f94f 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -14,7 +14,7 @@ using namespace style; const float globalMinScale = 0.5f; // underscale by 1 zoom level SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, const SymbolLayoutProperties& layout, + const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout, const style::SymbolPlacementType placement, const Shaping& shapedText) { auto image = *(shapedIcon.image); @@ -29,24 +29,24 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, Point<float> br; Point<float> bl; - if (layout.iconTextFit != IconTextFitType::None && shapedText) { + if (layout.get<IconTextFit>() != IconTextFitType::None && shapedText) { auto iconWidth = right - left; auto iconHeight = bottom - top; - auto size = layout.textSize / 24.0f; + auto size = layout.get<TextSize>() / 24.0f; auto textLeft = shapedText.left * size; auto textRight = shapedText.right * size; auto textTop = shapedText.top * size; auto textBottom = shapedText.bottom * size; auto textWidth = textRight - textLeft; auto textHeight = textBottom - textTop;; - auto padT = layout.iconTextFitPadding.value[0]; - auto padR = layout.iconTextFitPadding.value[1]; - auto padB = layout.iconTextFitPadding.value[2]; - auto padL = layout.iconTextFitPadding.value[3]; - auto offsetY = layout.iconTextFit == IconTextFitType::Width ? (textHeight - iconHeight) * 0.5 : 0; - auto offsetX = layout.iconTextFit == IconTextFitType::Height ? (textWidth - iconWidth) * 0.5 : 0; - auto width = layout.iconTextFit == IconTextFitType::Width || layout.iconTextFit == IconTextFitType::Both ? textWidth : iconWidth; - auto height = layout.iconTextFit == IconTextFitType::Height || layout.iconTextFit == IconTextFitType::Both ? textHeight : iconHeight; + auto padT = layout.get<IconTextFitPadding>()[0]; + auto padR = layout.get<IconTextFitPadding>()[1]; + auto padB = layout.get<IconTextFitPadding>()[2]; + auto padL = layout.get<IconTextFitPadding>()[3]; + auto offsetY = layout.get<IconTextFit>() == IconTextFitType::Width ? (textHeight - iconHeight) * 0.5 : 0; + auto offsetX = layout.get<IconTextFit>() == IconTextFitType::Height ? (textWidth - iconWidth) * 0.5 : 0; + auto width = layout.get<IconTextFit>() == IconTextFitType::Width || layout.get<IconTextFit>() == IconTextFitType::Both ? textWidth : iconWidth; + auto height = layout.get<IconTextFit>() == IconTextFitType::Height || layout.get<IconTextFit>() == IconTextFitType::Both ? textHeight : iconHeight; left = textLeft + offsetX - padL; top = textTop + offsetY - padT; right = textLeft + offsetX + padR + width; @@ -62,7 +62,7 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, bl = {left, bottom}; } - float angle = layout.iconRotate * util::DEG2RAD; + float angle = layout.get<IconRotate>() * util::DEG2RAD; if (placement == style::SymbolPlacementType::Line) { assert(static_cast<unsigned int>(anchor.segment) < line.size()); const GeometryCoordinate &prev= line[anchor.segment]; @@ -165,11 +165,11 @@ void getSegmentGlyphs(std::back_insert_iterator<GlyphInstances> glyphs, Anchor & } SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, - const float boxScale, const GeometryCoordinates& line, const SymbolLayoutProperties& layout, + const float boxScale, const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout, const style::SymbolPlacementType placement, const GlyphPositions& face) { - const float textRotate = layout.textRotate * util::DEG2RAD; - const bool keepUpright = layout.textKeepUpright; + const float textRotate = layout.get<TextRotate>() * util::DEG2RAD; + const bool keepUpright = layout.get<TextKeepUpright>(); SymbolQuads quads; diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index d4edbf9493..75fb53aade 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -2,6 +2,7 @@ #include <mbgl/text/glyph.hpp> #include <mbgl/style/types.hpp> +#include <mbgl/style/layers/symbol_layer_properties.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <vector> @@ -11,10 +12,6 @@ namespace mbgl { struct Anchor; class PositionedIcon; -namespace style { -class SymbolLayoutProperties; -} // namespace style - struct SymbolQuad { explicit SymbolQuad(Point<float> tl_, Point<float> tr_, Point<float> bl_, Point<float> br_, Rect<uint16_t> tex_, float anchorAngle_, float glyphAngle_, Point<float> anchorPoint_, @@ -40,11 +37,11 @@ struct SymbolQuad { typedef std::vector<SymbolQuad> SymbolQuads; SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, const style::SymbolLayoutProperties&, + const GeometryCoordinates& line, const style::SymbolLayoutProperties::Evaluated&, style::SymbolPlacementType placement, const Shaping& shapedText); SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, - const float boxScale, const GeometryCoordinates& line, const style::SymbolLayoutProperties&, + const float boxScale, const GeometryCoordinates& line, const style::SymbolLayoutProperties::Evaluated&, style::SymbolPlacementType placement, const GlyphPositions& face); } // namespace mbgl diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 1091cd6e94..062066aaf4 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -3,9 +3,11 @@ namespace mbgl { -PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties& layout) { - float dx = layout.iconOffset.value[0]; - float dy = layout.iconOffset.value[1]; +using namespace style; + +PositionedIcon shapeIcon(const SpriteAtlasElement& image, const SymbolLayoutProperties::Evaluated& layout) { + float dx = layout.get<IconOffset>()[0]; + float dy = layout.get<IconOffset>()[1]; float x1 = dx - image.spriteImage->getWidth() / 2.0f; float x2 = x1 + image.spriteImage->getWidth(); float y1 = dy - image.spriteImage->getHeight() / 2.0f; diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index d7c64e88b4..30375179b6 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -3,16 +3,13 @@ #include <mbgl/text/glyph.hpp> #include <mbgl/sprite/sprite_atlas.hpp> #include <mbgl/sprite/sprite_image.hpp> +#include <mbgl/style/layers/symbol_layer_properties.hpp> #include <mbgl/util/optional.hpp> namespace mbgl { class SpriteAtlasElement; -namespace style { -class SymbolLayoutProperties; -} // namespace style - class PositionedIcon { public: explicit PositionedIcon() {} @@ -29,6 +26,6 @@ class PositionedIcon { explicit operator bool() const { return image && (*image).pos.hasArea(); } }; -PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties&); +PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties::Evaluated&); } // namespace mbgl diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 419aee183f..03cdc63a91 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -30,7 +30,7 @@ TEST(Buckets, LineBucket) { TEST(Buckets, SymbolBucket) { mbgl::MapMode mapMode = mbgl::MapMode::Still; - mbgl::style::SymbolLayoutProperties properties; + mbgl::style::SymbolLayoutProperties::Evaluated properties; bool sdfIcons = false; bool iconsNeedLinear = false; diff --git a/test/style/functions.test.cpp b/test/style/functions.test.cpp index 9577bcc633..8ca2f951e7 100644 --- a/test/style/functions.test.cpp +++ b/test/style/functions.test.cpp @@ -2,16 +2,16 @@ #include <mbgl/test/util.hpp> #include <mbgl/style/property_evaluator.hpp> -#include <mbgl/style/calculation_parameters.hpp> +#include <mbgl/style/property_evaluation_parameters.hpp> using namespace mbgl; using namespace mbgl::style; float evaluate(PropertyValue<float> value, float zoom) { - return PropertyValue<float>::visit(value, PropertyEvaluator<float>(CalculationParameters(zoom), 0)); + return value.evaluate(PropertyEvaluator<float>(PropertyEvaluationParameters(zoom), 0)); } std::string evaluate(PropertyValue<std::string> value, float zoom) { - return PropertyValue<std::string>::visit(value, PropertyEvaluator<std::string>(CalculationParameters(zoom), "")); + return value.evaluate(PropertyEvaluator<std::string>(PropertyEvaluationParameters(zoom), "")); } TEST(Function, Constant) { diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp index 421d2f362d..c20218a82f 100644 --- a/test/text/quads.test.cpp +++ b/test/text/quads.test.cpp @@ -10,7 +10,7 @@ using namespace mbgl; using namespace mbgl::style; TEST(getIconQuads, normal) { - SymbolLayoutProperties layout; + SymbolLayoutProperties::Evaluated layout; Anchor anchor(2.0, 3.0, 0.0, 0.5f, 0); SpriteAtlasElement image = { Rect<uint16_t>( 0, 0, 15, 11 ), @@ -58,7 +58,7 @@ TEST(getIconQuads, style) { // none { - SymbolLayoutProperties layout; + SymbolLayoutProperties::Evaluated layout; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -80,9 +80,9 @@ TEST(getIconQuads, style) { // width { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(24.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width); + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 24.0f; + layout.get<IconTextFit>() = IconTextFitType::Width; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -98,9 +98,9 @@ TEST(getIconQuads, style) { // width x textSize { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width); + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Width; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -116,13 +116,13 @@ TEST(getIconQuads, style) { // width x textSize + padding { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width); - layout.iconTextFitPadding.value[0] = 5.0f; - layout.iconTextFitPadding.value[1] = 10.0f; - layout.iconTextFitPadding.value[2] = 5.0f; - layout.iconTextFitPadding.value[3] = 10.0f; + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Width; + layout.get<IconTextFitPadding>()[0] = 5.0f; + layout.get<IconTextFitPadding>()[1] = 10.0f; + layout.get<IconTextFitPadding>()[2] = 5.0f; + layout.get<IconTextFitPadding>()[3] = 10.0f; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -138,9 +138,9 @@ TEST(getIconQuads, style) { // height { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(24.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height); + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 24.0f; + layout.get<IconTextFit>() = IconTextFitType::Height; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -156,9 +156,9 @@ TEST(getIconQuads, style) { // height x textSize { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height); + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Height; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -174,13 +174,13 @@ TEST(getIconQuads, style) { // height x textSize + padding { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height); - layout.iconTextFitPadding.value[0] = 5.0f; - layout.iconTextFitPadding.value[1] = 10.0f; - layout.iconTextFitPadding.value[2] = 5.0f; - layout.iconTextFitPadding.value[3] = 10.0f; + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Height; + layout.get<IconTextFitPadding>()[0] = 5.0f; + layout.get<IconTextFitPadding>()[1] = 10.0f; + layout.get<IconTextFitPadding>()[2] = 5.0f; + layout.get<IconTextFitPadding>()[3] = 10.0f; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -196,9 +196,9 @@ TEST(getIconQuads, style) { // both { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(24.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 24.0f; + layout.get<IconTextFit>() = IconTextFitType::Both; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -214,9 +214,9 @@ TEST(getIconQuads, style) { // both x textSize { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Both; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -232,13 +232,13 @@ TEST(getIconQuads, style) { // both x textSize + padding { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); - layout.iconTextFitPadding.value[0] = 5.0f; - layout.iconTextFitPadding.value[1] = 10.0f; - layout.iconTextFitPadding.value[2] = 5.0f; - layout.iconTextFitPadding.value[3] = 10.0f; + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Both; + layout.get<IconTextFitPadding>()[0] = 5.0f; + layout.get<IconTextFitPadding>()[1] = 10.0f; + layout.get<IconTextFitPadding>()[2] = 5.0f; + layout.get<IconTextFitPadding>()[3] = 10.0f; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); @@ -254,13 +254,13 @@ TEST(getIconQuads, style) { // both x textSize + padding t/r/b/l { - SymbolLayoutProperties layout; - layout.textSize = LayoutProperty<float>(12.0f); - layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); - layout.iconTextFitPadding.value[0] = 0.0f; - layout.iconTextFitPadding.value[1] = 5.0f; - layout.iconTextFitPadding.value[2] = 10.0f; - layout.iconTextFitPadding.value[3] = 15.0f; + SymbolLayoutProperties::Evaluated layout; + layout.get<TextSize>() = 12.0f; + layout.get<IconTextFit>() = IconTextFitType::Both; + layout.get<IconTextFitPadding>()[0] = 0.0f; + layout.get<IconTextFitPadding>()[1] = 5.0f; + layout.get<IconTextFitPadding>()[2] = 10.0f; + layout.get<IconTextFitPadding>()[3] = 15.0f; SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText); |