diff options
author | Young Hahn <young@mapbox.com> | 2016-06-15 17:13:31 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-15 17:13:31 -0400 |
commit | 199ea2a82a74cf2f7b63078e2dd4b8274c061851 (patch) | |
tree | 5d56478a020a911745d793b8ac5d7f236730c621 | |
parent | a020e535cac36d69a8939fb7956260d2217c65b4 (diff) | |
download | qtlocation-mapboxgl-199ea2a82a74cf2f7b63078e2dd4b8274c061851.tar.gz |
Support for icon-text-fit, icon-text-fit-padding (#5334)
* Add support for icon-text-fit
* Port unit tests for getIconQuads() from js => cpp
* Add support for padding in all 4 directions.
* Update all hashes post-merge
-rw-r--r-- | include/mbgl/style/layers/symbol_layer.hpp | 6 | ||||
-rw-r--r-- | include/mbgl/style/types.hpp | 7 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | platform/node/src/node_style.hpp | 8 | ||||
-rw-r--r-- | platform/node/src/node_style_properties.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer.cpp | 14 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer_properties.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer_properties.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/property_evaluator.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/style/property_parsing.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/types.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/text/quads.cpp | 44 | ||||
-rw-r--r-- | src/mbgl/text/quads.hpp | 2 | ||||
-rw-r--r-- | test/test.gypi | 2 | ||||
-rw-r--r-- | test/text/quads.cpp | 266 |
16 files changed, 384 insertions, 10 deletions
diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index 676d90d5b9..7d98a5ef6b 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -53,6 +53,12 @@ public: PropertyValue<float> getIconSize() const; void setIconSize(PropertyValue<float>); + PropertyValue<IconTextFitType> getIconTextFit() const; + void setIconTextFit(PropertyValue<IconTextFitType>); + + PropertyValue<std::array<float, 4>> getIconTextFitPadding() const; + void setIconTextFitPadding(PropertyValue<std::array<float, 4>>); + PropertyValue<std::string> getIconImage() const; void setIconImage(PropertyValue<std::string>); diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index 46c0cb3c39..28ebda9fb9 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -80,5 +80,12 @@ enum class TextTransformType : uint8_t { Lowercase, }; +enum class IconTextFitType : uint8_t { + None, + Both, + Width, + Height +}; + } // namespace style } // namespace mbgl diff --git a/package.json b/package.json index 1b0da8c4df..fcf5ee9bc4 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "ejs": "^2.4.1", "express": "^4.11.1", "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#59e998295d548f208ee3ec10cdd21ff2630e2079", - "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#2461efc3d883f2f2e56a6c6b2bfd7d54bbfe9f86", - "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#3d06b422b1aa81aec71b4c67128f3d947205d6af", + "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#194fc55b6a7dd54c1e2cf2dd9048fbb5e836716d", + "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#146a348f1768ce13e153fce3b32bbed469aa5fe4", "node-gyp": "^3.3.1", "request": "^2.72.0", "tape": "^4.5.1" diff --git a/platform/node/src/node_style.hpp b/platform/node/src/node_style.hpp index 34b8b96a99..a987c0d262 100644 --- a/platform/node/src/node_style.hpp +++ b/platform/node/src/node_style.hpp @@ -79,6 +79,14 @@ struct ValueConverter<std::array<float, 2>> { }; template <> +struct ValueConverter<std::array<float, 4>> { + mbgl::optional<mbgl::style::PropertyValue<std::array<float, 4>>> operator()(const v8::Local<v8::Value>& value) const { + (void)value; + return {}; + } +}; + +template <> struct ValueConverter<std::vector<float>> { mbgl::optional<mbgl::style::PropertyValue<std::vector<float>>> operator()(const v8::Local<v8::Value>& value) const { (void)value; diff --git a/platform/node/src/node_style_properties.hpp b/platform/node/src/node_style_properties.hpp index 4702918ae1..88142f8e1f 100644 --- a/platform/node/src/node_style_properties.hpp +++ b/platform/node/src/node_style_properties.hpp @@ -27,11 +27,14 @@ inline PropertySetters makeLayoutPropertySetters() { result["icon-optional"] = makePropertySetter(&SymbolLayer::setIconOptional); result["icon-rotation-alignment"] = makePropertySetter(&SymbolLayer::setIconRotationAlignment); result["icon-size"] = makePropertySetter(&SymbolLayer::setIconSize); + result["icon-text-fit"] = makePropertySetter(&SymbolLayer::setIconTextFit); + result["icon-text-fit-padding"] = makePropertySetter(&SymbolLayer::setIconTextFitPadding); result["icon-image"] = makePropertySetter(&SymbolLayer::setIconImage); result["icon-rotate"] = makePropertySetter(&SymbolLayer::setIconRotate); result["icon-padding"] = makePropertySetter(&SymbolLayer::setIconPadding); result["icon-keep-upright"] = makePropertySetter(&SymbolLayer::setIconKeepUpright); result["icon-offset"] = makePropertySetter(&SymbolLayer::setIconOffset); + result["text-pitch-alignment"] = makePropertySetter(&SymbolLayer::setTextPitchAlignment); result["text-rotation-alignment"] = makePropertySetter(&SymbolLayer::setTextRotationAlignment); result["text-field"] = makePropertySetter(&SymbolLayer::setTextField); result["text-font"] = makePropertySetter(&SymbolLayer::setTextFont); diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 60624fa59e..e34aedb47e 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -51,7 +51,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, // Create the quad used for rendering the icon. iconQuads(addToBuffers && shapedIcon ? - getIconQuads(anchor, shapedIcon, line, layout, iconAlongLine) : + getIconQuads(anchor, shapedIcon, line, layout, iconAlongLine, shapedText) : SymbolQuads()), // Create the collision features that will be used to check whether this symbol instance can be placed diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 282873b501..38a898deca 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -106,6 +106,20 @@ PropertyValue<float> SymbolLayer::getIconSize() const { void SymbolLayer::setIconSize(PropertyValue<float> value) { impl->layout.iconSize.set(value); } +PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const { + return impl->layout.iconTextFit.get(); +} + +void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) { + impl->layout.iconTextFit.set(value); +} +PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const { + return impl->layout.iconTextFitPadding.get(); +} + +void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) { + impl->layout.iconTextFitPadding.set(value); +} PropertyValue<std::string> SymbolLayer::getIconImage() const { return impl->layout.iconImage.get(); } diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp index 5c6f65112d..d77d10700c 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.cpp +++ b/src/mbgl/style/layers/symbol_layer_properties.cpp @@ -14,6 +14,8 @@ void SymbolLayoutProperties::parse(const JSValue& value) { iconOptional.parse("icon-optional", value); iconRotationAlignment.parse("icon-rotation-alignment", value); iconSize.parse("icon-size", value); + iconTextFit.parse("icon-text-fit", value); + iconTextFitPadding.parse("icon-text-fit-padding", value); iconImage.parse("icon-image", value); iconRotate.parse("icon-rotate", value); iconPadding.parse("icon-padding", value); @@ -49,6 +51,8 @@ void SymbolLayoutProperties::recalculate(const CalculationParameters& 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); diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index 772445f051..1882c03fef 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -25,6 +25,8 @@ public: LayoutProperty<bool> iconOptional { false }; LayoutProperty<AlignmentType> iconRotationAlignment { AlignmentType::Viewport }; 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 }; diff --git a/src/mbgl/style/property_evaluator.cpp b/src/mbgl/style/property_evaluator.cpp index 7b91b9e500..3394d69e41 100644 --- a/src/mbgl/style/property_evaluator.cpp +++ b/src/mbgl/style/property_evaluator.cpp @@ -19,6 +19,7 @@ template <> inline Color defaultStopsValue() { return { 0, 0, 0, 1 }; } template <> inline std::vector<float> defaultStopsValue() { return {{ 1, 0 }}; } template <> inline std::vector<std::string> defaultStopsValue() { return {{}}; } template <> inline std::array<float, 2> defaultStopsValue() { return {{ 0, 0 }}; } +template <> inline std::array<float, 4> defaultStopsValue() { return {{ 0, 0, 0, 0 }}; } template <> inline std::string defaultStopsValue() { return {}; } template <> inline TranslateAnchorType defaultStopsValue() { return {}; } @@ -30,6 +31,7 @@ template <> inline TextAnchorType defaultStopsValue() { return {}; } template <> inline TextJustifyType defaultStopsValue() { return {}; } template <> inline TextTransformType defaultStopsValue() { return {}; } template <> inline AlignmentType defaultStopsValue() { return {}; } +template <> inline IconTextFitType defaultStopsValue() { return {}; }; template <typename T> T PropertyEvaluator<T>::operator()(const Function<T>& fn) const { @@ -87,6 +89,7 @@ template class PropertyEvaluator<Color>; template class PropertyEvaluator<std::vector<float>>; template class PropertyEvaluator<std::vector<std::string>>; template class PropertyEvaluator<std::array<float, 2>>; +template class PropertyEvaluator<std::array<float, 4>>; template class PropertyEvaluator<std::string>; template class PropertyEvaluator<TranslateAnchorType>; @@ -98,6 +101,7 @@ template class PropertyEvaluator<TextAnchorType>; template class PropertyEvaluator<TextJustifyType>; template class PropertyEvaluator<TextTransformType>; template class PropertyEvaluator<AlignmentType>; +template class PropertyEvaluator<IconTextFitType>; template <typename T> Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Undefined&) const { diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp index f5e0cca993..2b08ba8788 100644 --- a/src/mbgl/style/property_parsing.cpp +++ b/src/mbgl/style/property_parsing.cpp @@ -71,6 +71,25 @@ optional<std::array<float, 2>> parseConstant(const char* name, const JSValue& va } template <> +optional<std::array<float, 4>> parseConstant(const char* name, const JSValue& value) { + if (value.IsArray() && value.Size() == 4 && + value[rapidjson::SizeType(0)].IsNumber() && + value[rapidjson::SizeType(1)].IsNumber() && + value[rapidjson::SizeType(2)].IsNumber() && + value[rapidjson::SizeType(3)].IsNumber()) { + + float first = value[rapidjson::SizeType(0)].GetDouble(); + float second = value[rapidjson::SizeType(1)].GetDouble(); + float third = value[rapidjson::SizeType(2)].GetDouble(); + float fourth = value[rapidjson::SizeType(3)].GetDouble(); + return { {{ first, second, third, fourth }} }; + } else { + Log::Warning(Event::ParseStyle, "value of '%s' must be an array of four numbers", name); + return {}; + } +} + +template <> optional<std::vector<float>> parseConstant(const char* name, const JSValue& value) { if (!value.IsArray()) { Log::Warning(Event::ParseStyle, "value of '%s' must be an array of numbers", name); diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp index d292d2d5b4..25a1753870 100644 --- a/src/mbgl/style/types.cpp +++ b/src/mbgl/style/types.cpp @@ -77,4 +77,11 @@ MBGL_DEFINE_ENUM(AlignmentType, { { AlignmentType::Undefined, "undefined" }, }); +MBGL_DEFINE_ENUM(IconTextFitType, { + { IconTextFitType::None, "none" }, + { IconTextFitType::Both, "both" }, + { IconTextFitType::Width, "width" }, + { IconTextFitType::Height, "height" }, +}); + } // namespace mbgl diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index a46b329d1a..727b86f610 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -15,7 +15,7 @@ const float globalMinScale = 0.5f; // underscale by 1 zoom level SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, const GeometryCoordinates& line, const SymbolLayoutProperties& layout, - const bool alongLine) { + const bool alongLine, const Shaping& shapedText) { auto image = *(shapedIcon.image); @@ -24,11 +24,43 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, auto right = left + image.pos.w / image.relativePixelRatio; auto top = shapedIcon.top - border; auto bottom = top + image.pos.h / image.relativePixelRatio; - Point<float> tl{left, top}; - Point<float> tr{right, top}; - Point<float> br{right, bottom}; - Point<float> bl{left, bottom}; - + Point<float> tl; + Point<float> tr; + Point<float> br; + Point<float> bl; + + if (layout.iconTextFit != IconTextFitType::None && shapedText) { + auto iconWidth = right - left; + auto iconHeight = bottom - top; + auto size = layout.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; + left = textLeft + offsetX - padL; + top = textTop + offsetY - padT; + right = textLeft + offsetX + padR + width; + bottom = textTop + offsetY + padB + height; + tl = {left, top}; + tr = {right, top}; + br = {right, bottom}; + bl = {left, bottom}; + } else { + tl = {left, top}; + tr = {right, top}; + br = {right, bottom}; + bl = {left, bottom}; + } float angle = layout.iconRotate * util::DEG2RAD; if (alongLine) { diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index 0ea5129238..dd64af682a 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -40,7 +40,7 @@ typedef std::vector<SymbolQuad> SymbolQuads; SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, const GeometryCoordinates& line, const style::SymbolLayoutProperties&, - const bool alongLine); + const bool alongLine, const Shaping& shapedText); SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, const float boxScale, const GeometryCoordinates& line, const style::SymbolLayoutProperties&, diff --git a/test/test.gypi b/test/test.gypi index da605b6fd8..e72718d865 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -56,6 +56,8 @@ 'math/minmax.cpp', 'math/clamp.cpp', + 'text/quads.cpp', + 'tile/geometry_tile_data.cpp', 'tile/tile_id.cpp', diff --git a/test/text/quads.cpp b/test/text/quads.cpp new file mode 100644 index 0000000000..6fdd769fc3 --- /dev/null +++ b/test/text/quads.cpp @@ -0,0 +1,266 @@ +#include <mbgl/geometry/anchor.hpp> +#include <mbgl/sprite/sprite_atlas.hpp> +#include <mbgl/test/util.hpp> +#include <mbgl/text/quads.hpp> +#include <mbgl/text/shaping.hpp> +#include <mbgl/text/glyph.hpp> +#include <mbgl/style/layers/symbol_layer.hpp> +#include <mbgl/style/layers/symbol_layer_impl.hpp> + +using namespace mbgl; +using namespace mbgl::style; + +TEST(getIconQuads, normal) { + auto layer = std::make_unique<SymbolLayer>("symbol"); + Anchor anchor(2.0, 3.0, 0.0, 0.5f, 0); + SpriteAtlasElement image = { + Rect<uint16_t>( 0, 0, 15, 11 ), + std::shared_ptr<const SpriteImage>(), + 1.0f + }; + PositionedIcon shapedIcon(image, -5.0, 6.0, -7.0, 8.0); + GeometryCoordinates line; + Shaping shapedText; + + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads.size(), 1u); + ASSERT_EQ(quads[0].anchorPoint.x, 2); + ASSERT_EQ(quads[0].anchorPoint.y, 3); + ASSERT_EQ(quads[0].tl.x, -8); + ASSERT_EQ(quads[0].tl.y, -6); + ASSERT_EQ(quads[0].tr.x, 7); + ASSERT_EQ(quads[0].tr.y, -6); + ASSERT_EQ(quads[0].bl.x, -8); + ASSERT_EQ(quads[0].bl.y, 5); + ASSERT_EQ(quads[0].br.x, 7); + ASSERT_EQ(quads[0].br.y, 5); + ASSERT_EQ(quads[0].anchorAngle, 0.0f); + ASSERT_EQ(quads[0].glyphAngle, 0.0f); + ASSERT_EQ(quads[0].minScale, 0.5f); +} + +TEST(getIconQuads, style) { + Anchor anchor(0.0, 0.0, 0.0, 0.5f, 0); + SpriteAtlasElement image = { + Rect<uint16_t>( 0, 0, 20, 20 ), + std::shared_ptr<const SpriteImage>(), + 1.0f + }; + PositionedIcon shapedIcon(image, -10.0, 10.0, -10.0, 10.0); + GeometryCoordinates line; + Shaping shapedText; + shapedText.top = -10.0f; + shapedText.bottom = 30.0f; + shapedText.left = -60.0f; + shapedText.right = 20.0f; + shapedText.positionedGlyphs.emplace_back(PositionedGlyph(32, 0.0f, 0.0f)); + + // none + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads.size(), 1u); + ASSERT_EQ(quads[0].anchorPoint.x, 0); + ASSERT_EQ(quads[0].anchorPoint.y, 0); + ASSERT_EQ(quads[0].tl.x, -11); + ASSERT_EQ(quads[0].tl.y, -11); + ASSERT_EQ(quads[0].tr.x, 9); + ASSERT_EQ(quads[0].tr.y, -11); + ASSERT_EQ(quads[0].bl.x, -11); + ASSERT_EQ(quads[0].bl.y, 9); + ASSERT_EQ(quads[0].br.x, 9); + ASSERT_EQ(quads[0].br.y, 9); + ASSERT_EQ(quads[0].anchorAngle, 0.0f); + ASSERT_EQ(quads[0].glyphAngle, 0.0f); + ASSERT_EQ(quads[0].minScale, 0.5f); + } + + // width + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(24.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -60); + ASSERT_EQ(quads[0].tl.y, 0); + ASSERT_EQ(quads[0].tr.x, 20); + ASSERT_EQ(quads[0].tr.y, 0); + ASSERT_EQ(quads[0].bl.x, -60); + ASSERT_EQ(quads[0].bl.y, 20); + ASSERT_EQ(quads[0].br.x, 20); + ASSERT_EQ(quads[0].br.y, 20); + } + + // width x textSize + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -30); + ASSERT_EQ(quads[0].tl.y, -5); + ASSERT_EQ(quads[0].tr.x, 10); + ASSERT_EQ(quads[0].tr.y, -5); + ASSERT_EQ(quads[0].bl.x, -30); + ASSERT_EQ(quads[0].bl.y, 15); + ASSERT_EQ(quads[0].br.x, 10); + ASSERT_EQ(quads[0].br.y, 15); + } + + // width x textSize + padding + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width); + layer->impl->layout.iconTextFitPadding.value[0] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[1] = 10.0f; + layer->impl->layout.iconTextFitPadding.value[2] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[3] = 10.0f; + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -40); + ASSERT_EQ(quads[0].tl.y, -10); + ASSERT_EQ(quads[0].tr.x, 20); + ASSERT_EQ(quads[0].tr.y, -10); + ASSERT_EQ(quads[0].bl.x, -40); + ASSERT_EQ(quads[0].bl.y, 20); + ASSERT_EQ(quads[0].br.x, 20); + ASSERT_EQ(quads[0].br.y, 20); + } + + // height + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(24.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -30); + ASSERT_EQ(quads[0].tl.y, -10); + ASSERT_EQ(quads[0].tr.x, -10); + ASSERT_EQ(quads[0].tr.y, -10); + ASSERT_EQ(quads[0].bl.x, -30); + ASSERT_EQ(quads[0].bl.y, 30); + ASSERT_EQ(quads[0].br.x, -10); + ASSERT_EQ(quads[0].br.y, 30); + } + + // height x textSize + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -20); + ASSERT_EQ(quads[0].tl.y, -5); + ASSERT_EQ(quads[0].tr.x, 0); + ASSERT_EQ(quads[0].tr.y, -5); + ASSERT_EQ(quads[0].bl.x, -20); + ASSERT_EQ(quads[0].bl.y, 15); + ASSERT_EQ(quads[0].br.x, 0); + ASSERT_EQ(quads[0].br.y, 15); + } + + // height x textSize + padding + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height); + layer->impl->layout.iconTextFitPadding.value[0] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[1] = 10.0f; + layer->impl->layout.iconTextFitPadding.value[2] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[3] = 10.0f; + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -30); + ASSERT_EQ(quads[0].tl.y, -10); + ASSERT_EQ(quads[0].tr.x, 10); + ASSERT_EQ(quads[0].tr.y, -10); + ASSERT_EQ(quads[0].bl.x, -30); + ASSERT_EQ(quads[0].bl.y, 20); + ASSERT_EQ(quads[0].br.x, 10); + ASSERT_EQ(quads[0].br.y, 20); + } + + // both + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(24.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -60); + ASSERT_EQ(quads[0].tl.y, -10); + ASSERT_EQ(quads[0].tr.x, 20); + ASSERT_EQ(quads[0].tr.y, -10); + ASSERT_EQ(quads[0].bl.x, -60); + ASSERT_EQ(quads[0].bl.y, 30); + ASSERT_EQ(quads[0].br.x, 20); + ASSERT_EQ(quads[0].br.y, 30); + } + + // both x textSize + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -30); + ASSERT_EQ(quads[0].tl.y, -5); + ASSERT_EQ(quads[0].tr.x, 10); + ASSERT_EQ(quads[0].tr.y, -5); + ASSERT_EQ(quads[0].bl.x, -30); + ASSERT_EQ(quads[0].bl.y, 15); + ASSERT_EQ(quads[0].br.x, 10); + ASSERT_EQ(quads[0].br.y, 15); + } + + // both x textSize + padding + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); + layer->impl->layout.iconTextFitPadding.value[0] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[1] = 10.0f; + layer->impl->layout.iconTextFitPadding.value[2] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[3] = 10.0f; + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -40); + ASSERT_EQ(quads[0].tl.y, -10); + ASSERT_EQ(quads[0].tr.x, 20); + ASSERT_EQ(quads[0].tr.y, -10); + ASSERT_EQ(quads[0].bl.x, -40); + ASSERT_EQ(quads[0].bl.y, 20); + ASSERT_EQ(quads[0].br.x, 20); + ASSERT_EQ(quads[0].br.y, 20); + } + + // both x textSize + padding t/r/b/l + { + auto layer = std::make_unique<SymbolLayer>("symbol"); + layer->impl->layout.textSize = LayoutProperty<float>(12.0f); + layer->impl->layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both); + layer->impl->layout.iconTextFitPadding.value[0] = 0.0f; + layer->impl->layout.iconTextFitPadding.value[1] = 5.0f; + layer->impl->layout.iconTextFitPadding.value[2] = 10.0f; + layer->impl->layout.iconTextFitPadding.value[3] = 15.0f; + SymbolQuads quads = getIconQuads(anchor, shapedIcon, line, layer->impl->layout, false, shapedText); + + ASSERT_EQ(quads[0].tl.x, -45); + ASSERT_EQ(quads[0].tl.y, -5); + ASSERT_EQ(quads[0].tr.x, 15); + ASSERT_EQ(quads[0].tr.y, -5); + ASSERT_EQ(quads[0].bl.x, -45); + ASSERT_EQ(quads[0].bl.y, 25); + ASSERT_EQ(quads[0].br.x, 15); + ASSERT_EQ(quads[0].br.y, 25); + } +} + |