diff options
author | Lauren Budorick <lauren@mapbox.com> | 2017-07-21 14:09:18 -0700 |
---|---|---|
committer | Lauren Budorick <lauren@mapbox.com> | 2017-07-26 12:16:56 -0700 |
commit | 226883e68f1982fa0221407fd8f7dc4605716c71 (patch) | |
tree | 84e6f4ad4dcde62a62c4e5e392b8646af7b3f63f | |
parent | f6b8a4df99fddfae919bd884d4fbf635de6f23d6 (diff) | |
download | qtlocation-mapboxgl-226883e68f1982fa0221407fd8f7dc4605716c71.tar.gz |
[core] Implement property functions for text-anchor and text-justify
-rw-r--r-- | include/mbgl/style/conversion/make_property_setters.hpp | 4 | ||||
-rw-r--r-- | include/mbgl/style/layers/symbol_layer.hpp | 12 | ||||
m--------- | mapbox-gl-js | 0 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 46 | ||||
-rw-r--r-- | src/mbgl/style/function/categorical_stops.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/function/identity_stops.cpp | 20 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer_properties.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/text/shaping.cpp | 82 | ||||
-rw-r--r-- | src/mbgl/text/shaping.hpp | 6 |
10 files changed, 110 insertions, 78 deletions
diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp index f5d7f1874b..9252297d75 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp +++ b/include/mbgl/style/conversion/make_property_setters.hpp @@ -54,8 +54,8 @@ auto makeLayoutPropertySetters() { result["text-max-width"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxWidth>; result["text-line-height"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLineHeight>; result["text-letter-spacing"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLetterSpacing>; - result["text-justify"] = &setProperty<V, SymbolLayer, PropertyValue<TextJustifyType>, &SymbolLayer::setTextJustify>; - result["text-anchor"] = &setProperty<V, SymbolLayer, PropertyValue<TextAnchorType>, &SymbolLayer::setTextAnchor>; + result["text-justify"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<TextJustifyType>, &SymbolLayer::setTextJustify>; + result["text-anchor"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<TextAnchorType>, &SymbolLayer::setTextAnchor>; result["text-max-angle"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxAngle>; result["text-rotate"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextRotate>; result["text-padding"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextPadding>; diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp index f4d0322dc7..6e355c0057 100644 --- a/include/mbgl/style/layers/symbol_layer.hpp +++ b/include/mbgl/style/layers/symbol_layer.hpp @@ -134,13 +134,13 @@ public: PropertyValue<float> getTextLetterSpacing() const; void setTextLetterSpacing(PropertyValue<float>); - static PropertyValue<TextJustifyType> getDefaultTextJustify(); - PropertyValue<TextJustifyType> getTextJustify() const; - void setTextJustify(PropertyValue<TextJustifyType>); + static DataDrivenPropertyValue<TextJustifyType> getDefaultTextJustify(); + DataDrivenPropertyValue<TextJustifyType> getTextJustify() const; + void setTextJustify(DataDrivenPropertyValue<TextJustifyType>); - static PropertyValue<TextAnchorType> getDefaultTextAnchor(); - PropertyValue<TextAnchorType> getTextAnchor() const; - void setTextAnchor(PropertyValue<TextAnchorType>); + static DataDrivenPropertyValue<TextAnchorType> getDefaultTextAnchor(); + DataDrivenPropertyValue<TextAnchorType> getTextAnchor() const; + void setTextAnchor(DataDrivenPropertyValue<TextAnchorType>); static PropertyValue<float> getDefaultTextMaxAngle(); PropertyValue<float> getTextMaxAngle() const; diff --git a/mapbox-gl-js b/mapbox-gl-js -Subproject 9d72cc2c461673525f1a6321314d2460c0f3324 +Subproject a397d33ae3de497f67ea7fed6edeb72b730ba08 diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 956ba770dd..229b8f2ee2 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -180,47 +180,6 @@ bool SymbolLayout::hasSymbolInstances() const { void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, const ImageMap& imageMap, const ImagePositions& imagePositions) { - float horizontalAlign = 0.5; - float verticalAlign = 0.5; - - switch (layout.get<TextAnchor>()) { - case TextAnchorType::Top: - case TextAnchorType::Bottom: - case TextAnchorType::Center: - break; - case TextAnchorType::Right: - case TextAnchorType::TopRight: - case TextAnchorType::BottomRight: - horizontalAlign = 1; - break; - case TextAnchorType::Left: - case TextAnchorType::TopLeft: - case TextAnchorType::BottomLeft: - horizontalAlign = 0; - break; - } - - switch (layout.get<TextAnchor>()) { - case TextAnchorType::Left: - case TextAnchorType::Right: - case TextAnchorType::Center: - break; - case TextAnchorType::Bottom: - case TextAnchorType::BottomLeft: - case TextAnchorType::BottomRight: - verticalAlign = 1; - break; - case TextAnchorType::Top: - case TextAnchorType::TopLeft: - case TextAnchorType::TopRight: - verticalAlign = 0; - break; - } - - const float justify = layout.get<TextJustify>() == TextJustifyType::Right ? 1 : - layout.get<TextJustify>() == TextJustifyType::Left ? 0 : - 0.5; - const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && layout.get<SymbolPlacement>() == SymbolPlacementType::Line; @@ -248,9 +207,8 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ? layout.get<TextMaxWidth>() * oneEm : 0, /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm, - /* horizontalAlign */ horizontalAlign, - /* verticalAlign */ verticalAlign, - /* justify */ justify, + /* anchor */ layout.evaluate<TextAnchor>(zoom, feature), + /* justify */ layout.evaluate<TextJustify>(zoom, feature), /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get<TextLetterSpacing>() * oneEm : 0.0f, /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm), /* verticalHeight */ oneEm, diff --git a/src/mbgl/style/function/categorical_stops.cpp b/src/mbgl/style/function/categorical_stops.cpp index 8b5dc65fe9..1a30a1f1c7 100644 --- a/src/mbgl/style/function/categorical_stops.cpp +++ b/src/mbgl/style/function/categorical_stops.cpp @@ -33,6 +33,8 @@ template class CategoricalStops<Color>; template class CategoricalStops<std::array<float, 2>>; template class CategoricalStops<std::string>; template class CategoricalStops<TextTransformType>; +template class CategoricalStops<TextJustifyType>; +template class CategoricalStops<TextAnchorType>; template class CategoricalStops<LineJoinType>; } // namespace style diff --git a/src/mbgl/style/function/identity_stops.cpp b/src/mbgl/style/function/identity_stops.cpp index 1bb14f077f..7815f4aca0 100644 --- a/src/mbgl/style/function/identity_stops.cpp +++ b/src/mbgl/style/function/identity_stops.cpp @@ -36,11 +36,29 @@ optional<TextTransformType> IdentityStops<TextTransformType>::evaluate(const Val if (!value.is<std::string>()) { return {}; } - + return Enum<TextTransformType>::toEnum(value.get<std::string>()); } template <> +optional<TextJustifyType> IdentityStops<TextJustifyType>::evaluate(const Value& value) const { + if (!value.is<std::string>()) { + return {}; + } + + return Enum<TextJustifyType>::toEnum(value.get<std::string>()); +} + +template <> +optional<TextAnchorType> IdentityStops<TextAnchorType>::evaluate(const Value& value) const { + if (!value.is<std::string>()) { + return {}; + } + + return Enum<TextAnchorType>::toEnum(value.get<std::string>()); +} + +template <> optional<LineJoinType> IdentityStops<LineJoinType>::evaluate(const Value& value) const { if (!value.is<std::string>()) { return {}; diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index c102c64a94..803ae7397e 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -476,15 +476,15 @@ void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() { +DataDrivenPropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() { return TextJustify::defaultValue(); } -PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const { +DataDrivenPropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const { return impl().layout.get<TextJustify>(); } -void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { +void SymbolLayer::setTextJustify(DataDrivenPropertyValue<TextJustifyType> value) { if (value == getTextJustify()) return; auto impl_ = mutableImpl(); @@ -492,15 +492,15 @@ void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } -PropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() { +DataDrivenPropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() { return TextAnchor::defaultValue(); } -PropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const { +DataDrivenPropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const { return impl().layout.get<TextAnchor>(); } -void SymbolLayer::setTextAnchor(PropertyValue<TextAnchorType> value) { +void SymbolLayer::setTextAnchor(DataDrivenPropertyValue<TextAnchorType> value) { if (value == getTextAnchor()) return; auto impl_ = mutableImpl(); diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index 4b2bff01b8..fe6ab38e92 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -132,12 +132,12 @@ struct TextLetterSpacing : LayoutProperty<float> { static float defaultValue() { return 0; } }; -struct TextJustify : LayoutProperty<TextJustifyType> { +struct TextJustify : DataDrivenLayoutProperty<TextJustifyType> { static constexpr const char * key = "text-justify"; static TextJustifyType defaultValue() { return TextJustifyType::Center; } }; -struct TextAnchor : LayoutProperty<TextAnchorType> { +struct TextAnchor : DataDrivenLayoutProperty<TextAnchorType> { static constexpr const char * key = "text-anchor"; static TextAnchorType defaultValue() { return TextAnchorType::Center; } }; diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 6c7ecff42a..6e50f31a49 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -196,13 +196,62 @@ std::set<std::size_t> determineLineBreaks(const std::u16string& logicalInput, return leastBadBreaks(evaluateBreak(logicalInput.size(), currentX, targetWidth, potentialBreaks, 0, true)); } +struct AnchorAlignment { + AnchorAlignment(float horizontal_, float vertical_) + : horizontalAlign(horizontal_), verticalAlign(vertical_) { + } + + const float horizontalAlign; + const float verticalAlign; +}; + +AnchorAlignment getAnchorAlignment(const style::TextAnchorType textAnchor) { + float horizontalAlign = 0.5; + float verticalAlign = 0.5; + + switch (textAnchor) { + case style::TextAnchorType::Top: + case style::TextAnchorType::Bottom: + case style::TextAnchorType::Center: + break; + case style::TextAnchorType::Right: + case style::TextAnchorType::TopRight: + case style::TextAnchorType::BottomRight: + horizontalAlign = 1; + break; + case style::TextAnchorType::Left: + case style::TextAnchorType::TopLeft: + case style::TextAnchorType::BottomLeft: + horizontalAlign = 0; + break; + } + + switch (textAnchor) { + case style::TextAnchorType::Left: + case style::TextAnchorType::Right: + case style::TextAnchorType::Center: + break; + case style::TextAnchorType::Bottom: + case style::TextAnchorType::BottomLeft: + case style::TextAnchorType::BottomRight: + verticalAlign = 1; + break; + case style::TextAnchorType::Top: + case style::TextAnchorType::TopLeft: + case style::TextAnchorType::TopRight: + verticalAlign = 0; + break; + } + + return { horizontalAlign, verticalAlign }; +} + void shapeLines(Shaping& shaping, const std::vector<std::u16string>& lines, const float spacing, const float lineHeight, - const float horizontalAlign, - const float verticalAlign, - const float justify, + const style::TextAnchorType textAnchor, + const style::TextJustifyType textJustify, const float verticalHeight, const WritingModeType writingMode, const Glyphs& glyphs) { @@ -214,6 +263,10 @@ void shapeLines(Shaping& shaping, float y = yOffset; float maxLineLength = 0; + + const float justify = textJustify == style::TextJustifyType::Right ? 1 : + textJustify == style::TextJustifyType::Left ? 0 : + 0.5; for (std::u16string line : lines) { // Collapse whitespace so it doesn't throw off justification @@ -254,24 +307,25 @@ void shapeLines(Shaping& shaping, x = 0; y += lineHeight; } - - align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, - lines.size()); + + const AnchorAlignment anchorPosition = getAnchorAlignment(textAnchor); + + align(shaping, justify, anchorPosition.horizontalAlign, anchorPosition.verticalAlign, + maxLineLength, lineHeight, lines.size()); const uint32_t height = lines.size() * lineHeight; - + // Calculate the bounding box - shaping.top += -verticalAlign * height; + shaping.top += -anchorPosition.verticalAlign * height; shaping.bottom = shaping.top + height; - shaping.left += -horizontalAlign * maxLineLength; + shaping.left += -anchorPosition.horizontalAlign * maxLineLength; shaping.right = shaping.left + maxLineLength; } const Shaping getShaping(const std::u16string& logicalInput, const float maxWidth, const float lineHeight, - const float horizontalAlign, - const float verticalAlign, - const float justify, + const style::TextAnchorType textAnchor, + const style::TextJustifyType textJustify, const float spacing, const Point<float>& translate, const float verticalHeight, @@ -284,8 +338,8 @@ const Shaping getShaping(const std::u16string& logicalInput, bidi.processText(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, writingMode, glyphs)); - shapeLines(shaping, reorderedLines, spacing, lineHeight, horizontalAlign, verticalAlign, - justify, verticalHeight, writingMode, glyphs); + shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor, + textJustify, verticalHeight, writingMode, glyphs); return shaping; } diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index ca475e2a6c..00e4ec55f8 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -2,6 +2,7 @@ #include <mbgl/text/glyph.hpp> #include <mbgl/renderer/image_atlas.hpp> +#include <mbgl/style/types.hpp> namespace mbgl { @@ -44,9 +45,8 @@ public: const Shaping getShaping(const std::u16string& string, float maxWidth, float lineHeight, - float horizontalAlign, - float verticalAlign, - float justify, + style::TextAnchorType textAnchor, + style::TextJustifyType textJustify, float spacing, const Point<float>& translate, float verticalHeight, |