summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorm-stephen <truestyle2005@163.com>2019-09-04 10:44:25 +0800
committerGitHub <noreply@github.com>2019-09-04 10:44:25 +0800
commit3029993eb11d7a8936f9efca7604779566b1f1b4 (patch)
tree9e6e5ef6e971ab9a85c7990b20b274d92b266ba8
parent76d2cd3374ca1ccea5c1247f77997c7cd4ec65a4 (diff)
parentc7be3d52a709c98e93384bdcabc5cebc7adb9dac (diff)
downloadqtlocation-mapboxgl-upstream/stephen-ios13-compass.tar.gz
Merge branch 'master' into stephen-ios13-compassupstream/stephen-ios13-compass
m---------mapbox-gl-js0
-rw-r--r--platform/android/CHANGELOG.md1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java12
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h13
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--src/mbgl/layout/symbol_instance.cpp4
-rw-r--r--src/mbgl/layout/symbol_instance.hpp4
-rw-r--r--src/mbgl/layout/symbol_layout.cpp101
-rw-r--r--src/mbgl/layout/symbol_layout.hpp14
-rw-r--r--src/mbgl/style/sources/custom_geometry_source.cpp2
-rw-r--r--src/mbgl/style/sources/raster_source.cpp1
-rw-r--r--src/mbgl/style/sources/vector_source.cpp1
-rw-r--r--src/mbgl/style/style_impl.cpp5
-rw-r--r--src/mbgl/text/placement.cpp26
-rw-r--r--src/mbgl/text/placement.hpp2
-rw-r--r--src/mbgl/text/shaping.cpp4
-rw-r--r--src/mbgl/text/shaping.hpp2
-rw-r--r--test/storage/sync_file_source.test.cpp50
-rw-r--r--test/test-files.json1
-rw-r--r--test/text/cross_tile_symbol_index.test.cpp3
-rw-r--r--test/text/shaping.test.cpp2
21 files changed, 183 insertions, 66 deletions
diff --git a/mapbox-gl-js b/mapbox-gl-js
-Subproject 11c5c828f1124a07ae87443f303d5e576ff3f9a
+Subproject 572bbb55757c93a9f11fa9b0d0ca099bc4ec361
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index 5d8266c931..376a0b97e5 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -7,6 +7,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
- Introduce `clusterProperties` option for aggregated cluster properties. [#15425](https://github.com/mapbox/mapbox-gl-native/pull/15425)
- Expose the `CameraPosition#padding` field and associated utility camera position builders. This gives a choice to set a persisting map padding immediately during a transition instead of setting it lazily `MapboxMap#setPadding`, which required scheduling additional transition to be applied. This also deprecates `MapboxMap#setPadding` as there should be no need for a lazy padding setter. [#15444](https://github.com/mapbox/mapbox-gl-native/pull/15444)
- Add number-format expression that allows to format a number to a string, with configurations as minimal/maximal fraction and locale/currency. [#15424](https://github.com/mapbox/mapbox-gl-native/pull/15424)
+ - Enable using of `text-offset` option together with `text-variable-anchor` (if `text-radial-offset` option is not provided). If used with `text-variable-anchor`, input values will be taken as absolute values. Offsets along the x- and y-axis will be applied automatically based on the anchor position. [#15542](https://github.com/mapbox/mapbox-gl-native/pull/15542)
### Performance improvements
- Mark used offline region resources in batches. [#15521](https://github.com/mapbox/mapbox-gl-native/pull/15521)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
index 82085b171c..66a6fe20b2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
@@ -2296,7 +2296,7 @@ public class PropertyFactory {
}
/**
- * Radial offset of text, in the direction of the symbol's anchor. Useful in combination with {@link PropertyFactory#textVariableAnchor}, which doesn't support the two-dimensional {@link PropertyFactory#textOffset}.
+ * Radial offset of text, in the direction of the symbol's anchor. Useful in combination with {@link PropertyFactory#textVariableAnchor}, which defaults to using the two-dimensional {@link PropertyFactory#textOffset} if present.
*
* @param value a Float value
* @return property wrapper around Float
@@ -2306,7 +2306,7 @@ public class PropertyFactory {
}
/**
- * Radial offset of text, in the direction of the symbol's anchor. Useful in combination with {@link PropertyFactory#textVariableAnchor}, which doesn't support the two-dimensional {@link PropertyFactory#textOffset}.
+ * Radial offset of text, in the direction of the symbol's anchor. Useful in combination with {@link PropertyFactory#textVariableAnchor}, which defaults to using the two-dimensional {@link PropertyFactory#textOffset} if present.
*
* @param value a Float value
* @return property wrapper around Float
@@ -2316,7 +2316,7 @@ public class PropertyFactory {
}
/**
- * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the {@link PropertyFactory#textRadialOffset} instead of the two-dimensional {@link PropertyFactory#textOffset}.
+ * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the {@link PropertyFactory#textRadialOffset} or the two-dimensional {@link PropertyFactory#textOffset}.
*
* @param value a String[] value
* @return property wrapper around String[]
@@ -2326,7 +2326,7 @@ public class PropertyFactory {
}
/**
- * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the {@link PropertyFactory#textRadialOffset} instead of the two-dimensional {@link PropertyFactory#textOffset}.
+ * To increase the chance of placing high-priority labels on the map, you can provide an array of {@link Property.TEXT_ANCHOR} locations: the render will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the {@link PropertyFactory#textRadialOffset} or the two-dimensional {@link PropertyFactory#textOffset}.
*
* @param value a String[] value
* @return property wrapper around String[]
@@ -2476,7 +2476,7 @@ public class PropertyFactory {
}
/**
- * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up.
+ * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. If used with text-variable-anchor, input values will be taken as absolute values. Offsets along the x- and y-axis will be applied automatically based on the anchor position.
*
* @param value a Float[] value
* @return property wrapper around Float[]
@@ -2486,7 +2486,7 @@ public class PropertyFactory {
}
/**
- * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up.
+ * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. If used with text-variable-anchor, input values will be taken as absolute values. Offsets along the x- and y-axis will be applied automatically based on the anchor position.
*
* @param value a Float[] value
* @return property wrapper around Float[]
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index fb00b0d165..53bc488a41 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -1404,8 +1404,7 @@ MGL_EXPORT
ems downward. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `text` is non-`nil`, and
- `textRadialOffset` is set to `nil`, and `textVariableAnchor` is set to `nil`.
- Otherwise, it is ignored.
+ `textRadialOffset` is set to `nil`. Otherwise, it is ignored.
You can set this property to an expression containing any of the following:
@@ -1428,8 +1427,7 @@ MGL_EXPORT
ems upward. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `text` is non-`nil`, and
- `textRadialOffset` is set to `nil`, and `textVariableAnchor` is set to `nil`.
- Otherwise, it is ignored.
+ `textRadialOffset` is set to `nil`. Otherwise, it is ignored.
You can set this property to an expression containing any of the following:
@@ -1521,8 +1519,8 @@ MGL_EXPORT
/**
Radial offset of text, in the direction of the symbol's anchor. Useful in
- combination with `textVariableAnchor`, which doesn't support the
- two-dimensional `textOffset`.
+ combination with `textVariableAnchor`, which defaults to using the
+ two-dimensional `textOffset` if present.
This property is measured in ems.
@@ -1634,8 +1632,7 @@ MGL_EXPORT
provide an array of `textAnchor` locations: the render will attempt to place
the label at each location, in order, before moving onto the next label. Use
`textJustify: auto` to choose justification based on anchor position. To apply
- an offset, use the `textRadialOffset` instead of the two-dimensional
- `textOffset`.
+ an offset, use the `textRadialOffset` or the two-dimensional `textOffset`.
This property is only applied to the style if `text` is non-`nil`, and
`symbolPlacement` is set to an expression that evaluates to or
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 2e3fa77208..b8c33716f9 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -8,6 +8,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Fixed a bug with annotation view positions after camera transitions. ([#15122](https://github.com/mapbox/mapbox-gl-native/pull/15122/))
* Fixed a rendering issue of `collisionBox` when `text-translate` or `icon-translate` is enabled. ([#15467](https://github.com/mapbox/mapbox-gl-native/pull/15467))
* Fixed an issue where the scale bar text would become illegible if iOS 13 dark mode was enabled. ([#15524](https://github.com/mapbox/mapbox-gl-native/pull/15524))
+* Enable using of `text-offset` option together with `text-variable-anchor` (if `text-radial-offset` option is not provided). If used with `text-variable-anchor`, input values will be taken as absolute values. Offsets along the x- and y-axis will be applied automatically based on the anchor position. ([#15542](https://github.com/mapbox/mapbox-gl-native/pull/15542))
* Fixed an issue with the appearance of the compass text in iOS 13. ([#15547](https://github.com/mapbox/mapbox-gl-native/pull/15547))
### Performance improvements
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index ad36e6c38c..41a00e0131 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -87,7 +87,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
const float overscaling,
const float iconRotation,
const float textRotation,
- float radialTextOffset_,
+ const std::array<float, 2>& variableTextOffset_,
bool allowVerticalPlacement,
const SymbolContent iconType) :
sharedData(std::move(sharedData_)),
@@ -104,7 +104,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
iconOffset(iconOffset_),
key(std::move(key_)),
textBoxScale(textBoxScale_),
- radialTextOffset(radialTextOffset_),
+ variableTextOffset(variableTextOffset_),
singleLine(shapedTextOrientations.singleLine) {
// 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap
if(!sharedData->empty()) symbolContent |= SymbolContent::Text;
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 7d002d2285..3e2ab5f8b3 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -83,7 +83,7 @@ public:
const float overscaling,
const float iconRotation,
const float textRotation,
- float radialTextOffset,
+ const std::array<float, 2>& variableTextOffset,
bool allowVerticalPlacement,
const SymbolContent iconType = SymbolContent::None);
@@ -130,7 +130,7 @@ public:
optional<size_t> placedIconIndex;
optional<size_t> placedVerticalIconIndex;
float textBoxScale;
- float radialTextOffset;
+ std::array<float, 2> variableTextOffset;
bool singleLine;
uint32_t crossTileID = 0;
};
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 0ee4143894..1dbb5d91dc 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -91,11 +91,13 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
pixelRatio(parameters.pixelRatio),
tileSize(util::tileSize * overscaling),
tilePixelRatio(float(util::EXTENT) / tileSize),
- textSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get<TextSize>()),
- iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get<IconSize>()),
layout(createLayout(toSymbolLayerProperties(layers.at(0)).layerImpl().layout, zoom)) {
const SymbolLayer::Impl& leader = toSymbolLayerProperties(layers.at(0)).layerImpl();
+ textSize = leader.layout.get<TextSize>();
+ iconSize = leader.layout.get<IconSize>();
+ textRadialOffset = leader.layout.get<TextRadialOffset>();
+
const bool hasText = has<TextField>(*layout) && has<TextFont>(*layout);
const bool hasIcon = has<IconImage>(*layout);
@@ -235,11 +237,9 @@ Shaping& shapingForTextJustifyType(ShapedTextOrientations& shapedTextOrientation
}
}
-} // namespace
-
-// static
-Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float radialOffset) {
- Point<float> result{};
+std::array<float, 2> evaluateRadialOffset(style::SymbolAnchorType anchor, float radialOffset) {
+ std::array<float, 2> result{{0.0f, 0.0f}};
+ if (radialOffset < 0.0f) radialOffset = 0.0f; // Ignore negative offset.
// solve for r where r^2 + r^2 = radialOffset^2
const float sqrt2 = 1.41421356237f;
const float hypotenuse = radialOffset / sqrt2;
@@ -247,17 +247,17 @@ Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r
switch (anchor) {
case SymbolAnchorType::TopRight:
case SymbolAnchorType::TopLeft:
- result.y = hypotenuse - baselineOffset;
+ result[1] = hypotenuse - baselineOffset;
break;
case SymbolAnchorType::BottomRight:
case SymbolAnchorType::BottomLeft:
- result.y = -hypotenuse + baselineOffset;
+ result[1] = -hypotenuse + baselineOffset;
break;
case SymbolAnchorType::Bottom:
- result.y = -radialOffset + baselineOffset;
+ result[1] = -radialOffset + baselineOffset;
break;
case SymbolAnchorType::Top:
- result.y = radialOffset - baselineOffset;
+ result[1] = radialOffset - baselineOffset;
break;
default:
break;
@@ -266,17 +266,17 @@ Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r
switch (anchor) {
case SymbolAnchorType::TopRight:
case SymbolAnchorType::BottomRight:
- result.x = -hypotenuse;
+ result[0] = -hypotenuse;
break;
case SymbolAnchorType::TopLeft:
case SymbolAnchorType::BottomLeft:
- result.x = hypotenuse;
+ result[0] = hypotenuse;
break;
case SymbolAnchorType::Left:
- result.x = radialOffset;
+ result[0] = radialOffset;
break;
case SymbolAnchorType::Right:
- result.x = -radialOffset;
+ result[0] = -radialOffset;
break;
default:
break;
@@ -285,6 +285,54 @@ Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r
return result;
}
+} // namespace
+
+// static
+std::array<float, 2> SymbolLayout::evaluateVariableOffset(style::SymbolAnchorType anchor, std::array<float, 2> offset) {
+ if (offset[1] == INVALID_OFFSET_VALUE) {
+ return evaluateRadialOffset(anchor, offset[0]);
+ }
+ std::array<float, 2> result{{0.0f, 0.0f}};
+ offset[0] = std::abs(offset[0]);
+ offset[1] = std::abs(offset[1]);
+
+ switch (anchor) {
+ case SymbolAnchorType::TopRight:
+ case SymbolAnchorType::TopLeft:
+ case SymbolAnchorType::Top:
+ result[1] = offset[1] - baselineOffset;
+ break;
+ case SymbolAnchorType::BottomRight:
+ case SymbolAnchorType::BottomLeft:
+ case SymbolAnchorType::Bottom:
+ result[1] = -offset[1] + baselineOffset;
+ break;
+ case SymbolAnchorType::Center:
+ case SymbolAnchorType::Left:
+ case SymbolAnchorType::Right:
+ break;
+ }
+
+ switch (anchor) {
+ case SymbolAnchorType::TopRight:
+ case SymbolAnchorType::BottomRight:
+ case SymbolAnchorType::Right:
+ result[0] = -offset[0];
+ break;
+ case SymbolAnchorType::TopLeft:
+ case SymbolAnchorType::BottomLeft:
+ case SymbolAnchorType::Left:
+ result[0] = offset[0];
+ break;
+ case SymbolAnchorType::Center:
+ case SymbolAnchorType::Top:
+ case SymbolAnchorType::Bottom:
+ break;
+ }
+
+ return result;
+}
+
void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions,
const ImageMap& imageMap, const ImagePositions& imagePositions) {
const bool isPointPlacement = layout->get<SymbolPlacement>() == SymbolPlacementType::Point;
@@ -296,7 +344,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
ShapedTextOrientations shapedTextOrientations;
optional<PositionedIcon> shapedIcon;
- Point<float> textOffset;
+ std::array<float, 2> textOffset{{0.0f, 0.0f}};
// if feature has text, shape the text
if (feature.formattedText) {
@@ -320,18 +368,18 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
return result;
};
const std::vector<style::TextVariableAnchorType> variableTextAnchor = layout->evaluate<TextVariableAnchor>(zoom, feature);
- const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature);
const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature);
if (variableTextAnchor.empty()) {
// Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector
// is calculated at placement time instead of layout time
+ const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature);
if (radialOffset > 0.0f) {
// The style spec says don't use `text-offset` and `text-radial-offset` together
// but doesn't actually specify what happens if you use both. We go with the radial offset.
textOffset = evaluateRadialOffset(textAnchor, radialOffset * util::ONE_EM);
} else {
- textOffset = { layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM,
- layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM};
+ textOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM,
+ layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}};
}
}
TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout->evaluate<TextJustify>(zoom, feature);
@@ -435,14 +483,13 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const ShapedTextOrientations& shapedTextOrientations,
optional<PositionedIcon> shapedIcon,
const GlyphPositions& glyphPositions,
- Point<float> offset,
+ std::array<float, 2> textOffset,
const SymbolContent iconType) {
const float minScale = 0.5f;
const float glyphSize = 24.0f;
const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature);
const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature);
- const std::array<float, 2> textOffset = {{ offset.x, offset.y }};
const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature);
@@ -462,7 +509,15 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const float textMaxAngle = layout->get<TextMaxAngle>() * util::DEG2RAD;
const float iconRotation = layout->evaluate<IconRotate>(zoom, feature);
const float textRotation = layout->evaluate<TextRotate>(zoom, feature);
- const float radialTextOffset = layout->evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM;
+ std::array<float, 2> variableTextOffset;
+ if (!textRadialOffset.isUndefined()) {
+ variableTextOffset = {{layout->evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM,
+ INVALID_OFFSET_VALUE}};
+ } else {
+ variableTextOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM,
+ layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}};
+ }
+
const SymbolPlacementType textPlacement = layout->get<TextRotationAlignment>() != AlignmentType::Map
? SymbolPlacementType::Point
: layout->get<SymbolPlacement>();
@@ -503,7 +558,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
iconBoxScale, iconPadding, iconOffset, indexedFeature,
layoutFeatureIndex, feature.index,
feature.formattedText ? feature.formattedText->rawText() : std::u16string(),
- overscaling, iconRotation, textRotation, radialTextOffset, allowVerticalPlacement, iconType);
+ overscaling, iconRotation, textRotation, variableTextOffset, allowVerticalPlacement, iconType);
}
};
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 8d4c51148a..1abcaaa5d6 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -45,7 +45,16 @@ public:
const std::string bucketLeaderID;
std::vector<SymbolInstance> symbolInstances;
- static Point<float> evaluateRadialOffset(style::SymbolAnchorType anchor, float radialOffset);
+ static constexpr float INVALID_OFFSET_VALUE = std::numeric_limits<float>::max();
+ /**
+ * @brief Calculates variable text offset.
+ *
+ * @param anchor text anchor
+ * @param textOffset Either `text-offset` or [ `text-radial-offset`, INVALID_OFFSET_VALUE ]
+ * @return std::array<float, 2> offset along x- and y- axis correspondingly.
+ */
+ static std::array<float, 2> evaluateVariableOffset(style::SymbolAnchorType anchor, std::array<float, 2> textOffset);
+
private:
void addFeature(const size_t,
@@ -53,7 +62,7 @@ private:
const ShapedTextOrientations& shapedTextOrientations,
optional<PositionedIcon> shapedIcon,
const GlyphPositions&,
- Point<float> textOffset,
+ std::array<float, 2> textOffset,
const SymbolContent iconType);
bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&);
@@ -101,6 +110,7 @@ private:
style::TextSize::UnevaluatedType textSize;
style::IconSize::UnevaluatedType iconSize;
+ style::TextRadialOffset::UnevaluatedType textRadialOffset;
Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> layout;
std::vector<SymbolFeature> features;
diff --git a/src/mbgl/style/sources/custom_geometry_source.cpp b/src/mbgl/style/sources/custom_geometry_source.cpp
index 6e9d8d65fb..73675c056f 100644
--- a/src/mbgl/style/sources/custom_geometry_source.cpp
+++ b/src/mbgl/style/sources/custom_geometry_source.cpp
@@ -1,6 +1,7 @@
#include <mbgl/style/sources/custom_geometry_source.hpp>
#include <mbgl/style/custom_tile_loader.hpp>
#include <mbgl/style/sources/custom_geometry_source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
#include <mbgl/actor/actor.hpp>
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/tile/tile_id.hpp>
@@ -25,6 +26,7 @@ const CustomGeometrySource::Impl& CustomGeometrySource::impl() const {
void CustomGeometrySource::loadDescription(FileSource&) {
baseImpl = makeMutable<CustomGeometrySource::Impl>(impl(), loader->self());
loaded = true;
+ observer->onSourceLoaded(*this);
}
void CustomGeometrySource::setTileData(const CanonicalTileID& tileID,
diff --git a/src/mbgl/style/sources/raster_source.cpp b/src/mbgl/style/sources/raster_source.cpp
index b4fbe22ae1..115887d004 100644
--- a/src/mbgl/style/sources/raster_source.cpp
+++ b/src/mbgl/style/sources/raster_source.cpp
@@ -41,6 +41,7 @@ void RasterSource::loadDescription(FileSource& fileSource) {
if (urlOrTileset.is<Tileset>()) {
baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>());
loaded = true;
+ observer->onSourceLoaded(*this);
return;
}
diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp
index 8fa694e4d0..f103a7768f 100644
--- a/src/mbgl/style/sources/vector_source.cpp
+++ b/src/mbgl/style/sources/vector_source.cpp
@@ -38,6 +38,7 @@ void VectorSource::loadDescription(FileSource& fileSource) {
if (urlOrTileset.is<Tileset>()) {
baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>());
loaded = true;
+ observer->onSourceLoaded(*this);
return;
}
diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp
index 10fee73cdd..d3298c5cac 100644
--- a/src/mbgl/style/style_impl.cpp
+++ b/src/mbgl/style/style_impl.cpp
@@ -140,9 +140,8 @@ void Style::Impl::addSource(std::unique_ptr<Source> source) {
}
source->setObserver(this);
- source->loadDescription(fileSource);
-
- sources.add(std::move(source));
+ auto item = sources.add(std::move(source));
+ item->loadDescription(fileSource);
}
std::unique_ptr<Source> Style::Impl::removeSource(const std::string& id) {
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 4cf69a11b6..a8c0a1bd44 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -86,15 +86,13 @@ void Placement::placeLayer(const RenderLayer& layer, const mat4& projMatrix, boo
}
namespace {
-Point<float> calculateVariableLayoutOffset(style::SymbolAnchorType anchor, float width, float height, float radialOffset, float textBoxScale) {
+Point<float> calculateVariableLayoutOffset(style::SymbolAnchorType anchor, float width, float height, std::array<float, 2> offset, float textBoxScale) {
AnchorAlignment alignment = AnchorAlignment::getAnchorAlignment(anchor);
float shiftX = -(alignment.horizontalAlign - 0.5f) * width;
float shiftY = -(alignment.verticalAlign - 0.5f) * height;
- Point<float> offset = SymbolLayout::evaluateRadialOffset(anchor, radialOffset);
- return Point<float>(
- shiftX + offset.x * textBoxScale,
- shiftY + offset.y * textBoxScale
- );
+ auto variableOffset = SymbolLayout::evaluateVariableOffset(anchor, offset);
+ return { shiftX + variableOffset[0] * textBoxScale,
+ shiftY + variableOffset[1] * textBoxScale };
}
} // namespace
@@ -283,7 +281,7 @@ void Placement::placeBucket(
for (size_t i = 0u; i < placementAttempts; ++i) {
auto anchor = variableTextAnchors[i % anchorsSize];
const bool allowOverlap = (i >= anchorsSize);
- shift = calculateVariableLayoutOffset(anchor, width, height, symbolInstance.radialTextOffset, textBoxScale);
+ shift = calculateVariableLayoutOffset(anchor, width, height, symbolInstance.variableTextOffset, textBoxScale);
if (rotateWithMap) {
float angle = pitchWithMap ? state.getBearing() : -state.getBearing();
shift = util::rotate(shift, angle);
@@ -314,7 +312,7 @@ void Placement::placeBucket(
}
variableOffsets.insert(std::make_pair(symbolInstance.crossTileID, VariableOffset{
- symbolInstance.radialTextOffset,
+ symbolInstance.variableTextOffset,
width,
height,
anchor,
@@ -524,13 +522,13 @@ void Placement::updateLayerBuckets(const RenderLayer& layer, const TransformStat
}
namespace {
-Point<float> calculateVariableRenderShift(style::SymbolAnchorType anchor, float width, float height, float radialOffset, float textBoxScale, float renderTextSize) {
+Point<float> calculateVariableRenderShift(style::SymbolAnchorType anchor, float width, float height, std::array<float, 2> textOffset, float textBoxScale, float renderTextSize) {
AnchorAlignment alignment = AnchorAlignment::getAnchorAlignment(anchor);
float shiftX = -(alignment.horizontalAlign - 0.5f) * width;
float shiftY = -(alignment.verticalAlign - 0.5f) * height;
- Point<float> offset = SymbolLayout::evaluateRadialOffset(anchor, radialOffset);
- return { (shiftX / textBoxScale + offset.x) * renderTextSize,
- (shiftY / textBoxScale + offset.y) * renderTextSize };
+ auto variablOffset = SymbolLayout::evaluateVariableOffset(anchor, textOffset);
+ return { (shiftX / textBoxScale + variablOffset[0]) * renderTextSize,
+ (shiftY / textBoxScale + variablOffset[1]) * renderTextSize };
}
} // namespace
@@ -610,7 +608,7 @@ bool Placement::updateBucketDynamicVertices(SymbolBucket& bucket, const Transfor
(*variableOffset).anchor,
(*variableOffset).width,
(*variableOffset).height,
- (*variableOffset).radialOffset,
+ (*variableOffset).offset,
(*variableOffset).textBoxScale,
renderTextSize);
@@ -815,7 +813,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
shift = calculateVariableLayoutOffset(variableOffset.anchor,
variableOffset.width,
variableOffset.height,
- variableOffset.radialOffset,
+ variableOffset.offset,
variableOffset.textBoxScale);
if (rotateWithMap) {
shift = util::rotate(shift, pitchWithMap ? state.getBearing() : -state.getBearing());
diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp
index 2349fd3785..c1fe69b852 100644
--- a/src/mbgl/text/placement.hpp
+++ b/src/mbgl/text/placement.hpp
@@ -34,7 +34,7 @@ public:
class VariableOffset {
public:
- float radialOffset;
+ std::array<float, 2> offset;
float width;
float height;
style::TextVariableAnchorType anchor;
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index 0cb9ea73a9..d6d9a3d34e 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -413,7 +413,7 @@ const Shaping getShaping(const TaggedString& formattedString,
const style::SymbolAnchorType textAnchor,
const style::TextJustifyType textJustify,
const float spacing,
- const Point<float>& translate,
+ const std::array<float, 2>& translate,
const WritingModeType writingMode,
BiDi& bidi,
const GlyphMap& glyphs,
@@ -432,7 +432,7 @@ const Shaping getShaping(const TaggedString& formattedString,
reorderedLines.emplace_back(line, formattedString.getSections());
}
}
- Shaping shaping(translate.x, translate.y, writingMode, reorderedLines.size());
+ Shaping shaping(translate[0], translate[1], writingMode, reorderedLines.size());
shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor,
textJustify, writingMode, glyphs, allowVerticalPlacement);
diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp
index 60a9c718ff..0e2f5515fe 100644
--- a/src/mbgl/text/shaping.hpp
+++ b/src/mbgl/text/shaping.hpp
@@ -73,7 +73,7 @@ const Shaping getShaping(const TaggedString& string,
style::SymbolAnchorType textAnchor,
style::TextJustifyType textJustify,
float spacing,
- const Point<float>& translate,
+ const std::array<float, 2>& translate,
const WritingModeType,
BiDi& bidi,
const GlyphMap& glyphs,
diff --git a/test/storage/sync_file_source.test.cpp b/test/storage/sync_file_source.test.cpp
new file mode 100644
index 0000000000..4bd964199d
--- /dev/null
+++ b/test/storage/sync_file_source.test.cpp
@@ -0,0 +1,50 @@
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/gfx/headless_frontend.hpp>
+#include <mbgl/map/map.hpp>
+#include <mbgl/map/map_impl.hpp>
+#include <mbgl/style/style.hpp>
+#include <mbgl/test/map_adapter.hpp>
+#include <unordered_map>
+
+#include <gtest/gtest.h>
+
+using namespace mbgl;
+
+class SyncFileSource : public FileSource {
+public:
+ std::unique_ptr<AsyncRequest> request(const Resource& resource, FileSource::Callback callback) {
+ Response response;
+ auto it = assets.find(resource.url);
+ if (it == assets.end()) {
+ response.error = std::make_unique<Response::Error>(
+ Response::Error::Reason::NotFound, std::string{ "Not Found: " } + resource.url);
+ } else {
+ response.data = it->second;
+ }
+ callback(response);
+ return nullptr;
+ }
+
+ void add(std::string const& key, std::string const& data) {
+ assets.emplace(key, std::make_shared<std::string>(data));
+ };
+
+private:
+ std::unordered_map<std::string, std::shared_ptr<std::string>> assets;
+};
+
+TEST(SyncFileSource, LoadSyncRender) {
+ util::RunLoop loop;
+ auto fs = std::make_shared<SyncFileSource>();
+ fs->add("mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7",
+ util::read_file("test/fixtures/resources/source_vector.json"));
+ fs->add("mapbox://sprites/mapbox/streets-v9.png",
+ util::read_file("test/fixtures/resources/sprite.png"));
+ fs->add("mapbox://sprites/mapbox/streets-v9.json",
+ util::read_file("test/fixtures/resources/sprite.json"));
+ HeadlessFrontend frontend{ { 512, 512 }, 1.0 };
+ MapAdapter map{ frontend, MapObserver::nullObserver(), fs, MapOptions() };
+ map.getStyle().loadJSON(util::read_file("test/fixtures/resources/style_vector.json"));
+}
diff --git a/test/test-files.json b/test/test-files.json
index e46f833269..f5e4013029 100644
--- a/test/test-files.json
+++ b/test/test-files.json
@@ -46,6 +46,7 @@
"test/storage/online_file_source.test.cpp",
"test/storage/resource.test.cpp",
"test/storage/sqlite.test.cpp",
+ "test/storage/sync_file_source.test.cpp",
"test/style/conversion/conversion_impl.test.cpp",
"test/style/conversion/function.test.cpp",
"test/style/conversion/geojson_options.test.cpp",
diff --git a/test/text/cross_tile_symbol_index.test.cpp b/test/text/cross_tile_symbol_index.test.cpp
index 11d6fc7de3..4ff84063f9 100644
--- a/test/text/cross_tile_symbol_index.test.cpp
+++ b/test/text/cross_tile_symbol_index.test.cpp
@@ -13,12 +13,13 @@ SymbolInstance makeSymbolInstance(float x, float y, std::u16string key) {
Anchor anchor(x, y, 0, 0);
std::array<float, 2> textOffset{{0.0f, 0.0f}};
std::array<float, 2> iconOffset{{0.0f, 0.0f}};
+ std::array<float, 2> variableTextOffset{{0.0f, 0.0f}};
style::SymbolPlacementType placementType = style::SymbolPlacementType::Point;
auto sharedData = std::make_shared<SymbolInstanceSharedData>(std::move(line),
shaping, nullopt, nullopt, layout_, placementType,
textOffset, positions, false);
- return SymbolInstance(anchor, std::move(sharedData), shaping, nullopt, nullopt, 0, 0, placementType, textOffset, 0, 0, iconOffset, subfeature, 0, 0, key, 0.0f, 0.0f, 0.0f, 0.0f, false);
+ return SymbolInstance(anchor, std::move(sharedData), shaping, nullopt, nullopt, 0, 0, placementType, textOffset, 0, 0, iconOffset, subfeature, 0, 0, key, 0.0f, 0.0f, 0.0f, variableTextOffset, false);
}
diff --git a/test/text/shaping.test.cpp b/test/text/shaping.test.cpp
index 17c2fc96af..b22cd7da36 100644
--- a/test/text/shaping.test.cpp
+++ b/test/text/shaping.test.cpp
@@ -33,7 +33,7 @@ TEST(Shaping, ZWSP) {
style::SymbolAnchorType::Center,
style::TextJustifyType::Center,
0, // spacing
- {0.0f, 0.0f}, // translate
+ {{0.0f, 0.0f}}, // translate
WritingModeType::Horizontal,
bidi,
glyphs,