summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLauren Budorick <lauren@mapbox.com>2017-07-26 13:18:47 -0700
committerGitHub <noreply@github.com>2017-07-26 13:18:47 -0700
commita8ef2af353de195648578bf0d753703cb6f34905 (patch)
treeb6afc3efd568b0310c9e6287d4c0c9c78bee5baf /src
parentc5a5b4083795107b7df7bab39b461568a3861dba (diff)
downloadqtlocation-mapboxgl-a8ef2af353de195648578bf0d753703cb6f34905.tar.gz
[core][android][macos][ios] Implement property functions for line-join, text-justify, text-anchor (#9583)
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/layout/symbol_layout.cpp46
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.cpp14
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.hpp3
-rw-r--r--src/mbgl/shaders/preludes.cpp23
-rw-r--r--src/mbgl/style/function/categorical_stops.cpp3
-rw-r--r--src/mbgl/style/function/identity_stops.cpp29
-rw-r--r--src/mbgl/style/layers/line_layer.cpp6
-rw-r--r--src/mbgl/style/layers/line_layer_properties.hpp2
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp12
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.hpp4
-rw-r--r--src/mbgl/text/shaping.cpp63
-rw-r--r--src/mbgl/text/shaping.hpp6
12 files changed, 112 insertions, 99 deletions
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/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp
index d1771d484a..194b012eee 100644
--- a/src/mbgl/renderer/buckets/line_bucket.cpp
+++ b/src/mbgl/renderer/buckets/line_bucket.cpp
@@ -15,7 +15,8 @@ LineBucket::LineBucket(const BucketParameters& parameters,
const std::vector<const RenderLayer*>& layers,
const style::LineLayoutProperties::Unevaluated& layout_)
: layout(layout_.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ))),
- overscaling(parameters.tileID.overscaleFactor()) {
+ overscaling(parameters.tileID.overscaleFactor()),
+ zoom(parameters.tileID.overscaledZ) {
for (const auto& layer : layers) {
paintPropertyBinders.emplace(
std::piecewise_construct,
@@ -29,7 +30,7 @@ LineBucket::LineBucket(const BucketParameters& parameters,
void LineBucket::addFeature(const GeometryTileFeature& feature,
const GeometryCollection& geometryCollection) {
for (auto& line : geometryCollection) {
- addGeometry(line, feature.getType());
+ addGeometry(line, feature);
}
for (auto& pair : paintPropertyBinders) {
@@ -62,7 +63,8 @@ const float LINE_DISTANCE_SCALE = 1.0 / 2.0;
// The maximum line distance, in tile units, that fits in the buffer.
const float MAX_LINE_DISTANCE = std::pow(2, LINE_DISTANCE_BUFFER_BITS) / LINE_DISTANCE_SCALE;
-void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType type) {
+void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const GeometryTileFeature& feature) {
+ const FeatureType type = feature.getType();
const std::size_t len = [&coordinates] {
std::size_t l = coordinates.size();
// If the line has duplicate vertices at the end, adjust length to remove them.
@@ -86,7 +88,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType
return;
}
- const float miterLimit = layout.get<LineJoin>() == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>());
+ const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature);
+
+ const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>());
const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling));
@@ -193,7 +197,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType
// The join if a middle vertex, otherwise the cap
const bool middleVertex = prevCoordinate && nextCoordinate;
- LineJoinType currentJoin = layout.get<LineJoin>();
+ LineJoinType currentJoin = joinType;
const LineCapType currentCap = nextCoordinate ? beginCap : endCap;
if (middleVertex) {
diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp
index 8ef25b02ec..4fb77c377e 100644
--- a/src/mbgl/renderer/buckets/line_bucket.hpp
+++ b/src/mbgl/renderer/buckets/line_bucket.hpp
@@ -41,7 +41,7 @@ public:
std::map<std::string, LineProgram::PaintPropertyBinders> paintPropertyBinders;
private:
- void addGeometry(const GeometryCoordinates&, FeatureType);
+ void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&);
struct TriangleElement {
TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {}
@@ -59,6 +59,7 @@ private:
std::ptrdiff_t e3;
const uint32_t overscaling;
+ const float zoom;
float getLineWidth(const RenderLineLayer& layer) const;
};
diff --git a/src/mbgl/shaders/preludes.cpp b/src/mbgl/shaders/preludes.cpp
index 95fa624e8d..feb185a684 100644
--- a/src/mbgl/shaders/preludes.cpp
+++ b/src/mbgl/shaders/preludes.cpp
@@ -24,25 +24,6 @@ precision highp float;
#endif
-float evaluate_zoom_function_1(const vec4 values, const float t) {
- if (t < 1.0) {
- return mix(values[0], values[1], t);
- } else if (t < 2.0) {
- return mix(values[1], values[2], t - 1.0);
- } else {
- return mix(values[2], values[3], t - 2.0);
- }
-}
-vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) {
- if (t < 1.0) {
- return mix(value0, value1, t);
- } else if (t < 2.0) {
- return mix(value1, value2, t - 1.0);
- } else {
- return mix(value2, value3, t - 2.0);
- }
-}
-
// Unpack a pair of values that have been packed into a single float.
// The packed values are assumed to be 8-bit unsigned integers, and are
// packed like so:
@@ -54,8 +35,8 @@ vec2 unpack_float(const float packedValue) {
}
-// To minimize the number of attributes needed in the mapbox-gl-native shaders,
-// we encode a 4-component color into a pair of floats (i.e. a vec2) as follows:
+// To minimize the number of attributes needed, we encode a 4-component
+// color into a pair of floats (i.e. a vec2) as follows:
// [ floor(color.r * 255) * 256 + color.g * 255,
// floor(color.b * 255) * 256 + color.g * 255 ]
vec4 decode_color(const vec2 encodedColor) {
diff --git a/src/mbgl/style/function/categorical_stops.cpp b/src/mbgl/style/function/categorical_stops.cpp
index 2984c3832f..1a30a1f1c7 100644
--- a/src/mbgl/style/function/categorical_stops.cpp
+++ b/src/mbgl/style/function/categorical_stops.cpp
@@ -33,6 +33,9 @@ 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
} // namespace mbgl
diff --git a/src/mbgl/style/function/identity_stops.cpp b/src/mbgl/style/function/identity_stops.cpp
index 0c6891eac5..7815f4aca0 100644
--- a/src/mbgl/style/function/identity_stops.cpp
+++ b/src/mbgl/style/function/identity_stops.cpp
@@ -36,11 +36,38 @@ 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 {};
+ }
+
+ return Enum<LineJoinType>::toEnum(value.get<std::string>());
+}
+
+template <>
optional<std::array<float, 2>> IdentityStops<std::array<float, 2>>::evaluate(const Value& value) const {
if (!value.is<std::vector<Value>>()) {
return {};
diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp
index 6fbdf19568..1c7f0d28ee 100644
--- a/src/mbgl/style/layers/line_layer.cpp
+++ b/src/mbgl/style/layers/line_layer.cpp
@@ -108,15 +108,15 @@ void LineLayer::setLineCap(PropertyValue<LineCapType> value) {
baseImpl = std::move(impl_);
observer->onLayerChanged(*this);
}
-PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() {
+DataDrivenPropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() {
return LineJoin::defaultValue();
}
-PropertyValue<LineJoinType> LineLayer::getLineJoin() const {
+DataDrivenPropertyValue<LineJoinType> LineLayer::getLineJoin() const {
return impl().layout.get<LineJoin>();
}
-void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) {
+void LineLayer::setLineJoin(DataDrivenPropertyValue<LineJoinType> value) {
if (value == getLineJoin())
return;
auto impl_ = mutableImpl();
diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp
index b2c7f3199c..aeaf51698a 100644
--- a/src/mbgl/style/layers/line_layer_properties.hpp
+++ b/src/mbgl/style/layers/line_layer_properties.hpp
@@ -17,7 +17,7 @@ struct LineCap : LayoutProperty<LineCapType> {
static LineCapType defaultValue() { return LineCapType::Butt; }
};
-struct LineJoin : LayoutProperty<LineJoinType> {
+struct LineJoin : DataDrivenLayoutProperty<LineJoinType> {
static constexpr const char * key = "line-join";
static LineJoinType defaultValue() { return LineJoinType::Miter; }
};
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
index 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..4a206e9bae 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -200,9 +200,8 @@ 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 +213,10 @@ void shapeLines(Shaping& shaping,
float y = yOffset;
float maxLineLength = 0;
+
+ const float justify = textJustify == style::TextJustifyType::Right ? 1 :
+ textJustify == style::TextJustifyType::Left ? 0 :
+ 0.5;
for (std::u16string line : lines) {
// Collapse whitespace so it doesn't throw off justification
@@ -254,11 +257,48 @@ void shapeLines(Shaping& shaping,
x = 0;
y += lineHeight;
}
-
- align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight,
- lines.size());
+
+ float horizontalAlign = 0.5;
+ float verticalAlign = 0.5;
+
+ switch (textAnchor) {
+ case style::TextAnchorType::Top:
+ case style::TextAnchorType::Bottom:
+ case style::TextAnchorType::Center:
+ break;
+ case style::TextAnchorType::Right:
+ case style::TextAnchorType::TopRight:
+ case style::TextAnchorType::BottomRight:
+ horizontalAlign = 1;
+ break;
+ case style::TextAnchorType::Left:
+ case style::TextAnchorType::TopLeft:
+ case style::TextAnchorType::BottomLeft:
+ horizontalAlign = 0;
+ break;
+ }
+
+ switch (textAnchor) {
+ case style::TextAnchorType::Left:
+ case style::TextAnchorType::Right:
+ case style::TextAnchorType::Center:
+ break;
+ case style::TextAnchorType::Bottom:
+ case style::TextAnchorType::BottomLeft:
+ case style::TextAnchorType::BottomRight:
+ verticalAlign = 1;
+ break;
+ case style::TextAnchorType::Top:
+ case style::TextAnchorType::TopLeft:
+ case style::TextAnchorType::TopRight:
+ verticalAlign = 0;
+ break;
+ }
+
+ align(shaping, justify, horizontalAlign, verticalAlign,
+ maxLineLength, lineHeight, lines.size());
const uint32_t height = lines.size() * lineHeight;
-
+
// Calculate the bounding box
shaping.top += -verticalAlign * height;
shaping.bottom = shaping.top + height;
@@ -269,9 +309,8 @@ void shapeLines(Shaping& shaping,
const Shaping getShaping(const std::u16string& logicalInput,
const float maxWidth,
const float lineHeight,
- const float horizontalAlign,
- const float verticalAlign,
- const float justify,
+ const style::TextAnchorType textAnchor,
+ const style::TextJustifyType textJustify,
const float spacing,
const Point<float>& translate,
const float verticalHeight,
@@ -284,8 +323,8 @@ const Shaping getShaping(const std::u16string& logicalInput,
bidi.processText(logicalInput,
determineLineBreaks(logicalInput, spacing, maxWidth, writingMode, glyphs));
- shapeLines(shaping, reorderedLines, spacing, lineHeight, horizontalAlign, verticalAlign,
- justify, verticalHeight, writingMode, glyphs);
+ shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor,
+ textJustify, verticalHeight, writingMode, glyphs);
return shaping;
}
diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp
index 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,