From c49e1ac733f70d869eae91c5f825828c14168a31 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 1 Apr 2015 20:31:25 -0700 Subject: [PATCH] port getAnchors from -js --- src/mbgl/geometry/resample.cpp | 63 ----------------------- src/mbgl/geometry/resample.hpp | 13 ----- src/mbgl/renderer/symbol_bucket.cpp | 8 +-- src/mbgl/text/get_anchors.cpp | 79 +++++++++++++++++++++++++++++ src/mbgl/text/get_anchors.hpp | 14 +++++ src/mbgl/text/glyph.hpp | 2 +- src/mbgl/text/glyph_store.cpp | 2 +- 7 files changed, 99 insertions(+), 82 deletions(-) delete mode 100644 src/mbgl/geometry/resample.cpp delete mode 100644 src/mbgl/geometry/resample.hpp create mode 100644 src/mbgl/text/get_anchors.cpp create mode 100644 src/mbgl/text/get_anchors.hpp diff --git a/src/mbgl/geometry/resample.cpp b/src/mbgl/geometry/resample.cpp deleted file mode 100644 index ed086fefd..000000000 --- a/src/mbgl/geometry/resample.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include - -#include - -#include - -namespace mbgl { - -const float minScale = 0.5f; -const std::array, 4> minScaleArrays = {{ - /*1:*/ { minScale }, - /*2:*/ { minScale, 2 }, - /*4:*/ { minScale, 4, 2, 4 }, - /*8:*/ { minScale, 8, 4, 8, 2, 8, 4, 8 } -}}; - - -Anchors resample(const std::vector &vertices, float spacing, - const float /*minScale*/, float maxScale, const float tilePixelRatio, - float offset) { - - maxScale = std::round(std::fmax(std::fmin(8.0f, maxScale / 2.0f), 1.0f)); - spacing *= tilePixelRatio / maxScale; - offset *= tilePixelRatio; - const size_t index = util::clamp(std::floor(std::log(maxScale) / std::log(2)), 0, minScaleArrays.size() - 1); - const std::vector &minScales = minScaleArrays[index]; - const size_t len = minScales.size(); - - float distance = 0.0f; - float markedDistance = offset != 0.0f ? offset - spacing : offset; - int added = 0; - - Anchors points; - - auto end = vertices.end() - 1; - int i = 0; - for (auto it = vertices.begin(); it != end; it++, i++) { - const Coordinate &a = *(it), b = *(it + 1); - - float segmentDist = util::dist(a, b); - float angle = util::angle_to(b, a); - - while (markedDistance + spacing < distance + segmentDist) { - markedDistance += spacing; - - float t = (markedDistance - distance) / segmentDist, - x = util::interpolate(a.x, b.x, t), - y = util::interpolate(a.y, b.y, t), - s = minScales[added % len]; - - if (x >= 0 && x < 4096 && y >= 0 && y < 4096) { - points.emplace_back(x, y, angle, s, i); - } - - added++; - } - - distance += segmentDist; - } - - return points; -} -} diff --git a/src/mbgl/geometry/resample.hpp b/src/mbgl/geometry/resample.hpp deleted file mode 100644 index ce7eba2f1..000000000 --- a/src/mbgl/geometry/resample.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MBGL_GEOMETRY_INTERPOLATE -#define MBGL_GEOMETRY_INTERPOLATE - -#include -#include - -namespace mbgl { - -Anchors resample(const std::vector &vertices, float spacing, - float minScale, float maxScale, float tilePixelRatio, float offset); -} - -#endif diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index bfce2475b..eed9dbcd3 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -257,11 +257,11 @@ void SymbolBucket::addFeature(const std::vector> &lines, const float fontScale = layout.text.max_size / glyphSize; const float textBoxScale = collision.tilePixelRatio * fontScale; const float iconBoxScale = collision.tilePixelRatio * layout.icon.max_size; - //const float symbolSpacing = collision.tilePixelRatio * layout.min_distance; + const float symbolSpacing = collision.tilePixelRatio * layout.min_distance; const bool avoidEdges = layout.avoid_edges && layout.placement != PlacementType::Line; const float textPadding = layout.text.padding * collision.tilePixelRatio; const float iconPadding = layout.icon.padding * collision.tilePixelRatio; - //const float textMaxAngle = layout.text.max_angle * M_PI / 180; + const float textMaxAngle = layout.text.max_angle * M_PI / 180; const bool textAlongLine = layout.text.rotation_alignment == RotationAlignmentType::Map && layout.placement == PlacementType::Line; @@ -276,7 +276,7 @@ void SymbolBucket::addFeature(const std::vector> &lines, // Calculate the anchor points around which you want to place labels Anchors anchors = layout.placement == PlacementType::Line ? - resample(line, layout.min_distance, minScale, 2.0f, collision.tilePixelRatio, 0.0f) : + getAnchors(line, symbolSpacing, textMaxAngle, shapedText.left, shapedText.right, glyphSize, textBoxScale, 1.0f) : Anchors({ Anchor(float(line[0].x), float(line[0].y), 0, minScale) }); diff --git a/src/mbgl/text/get_anchors.cpp b/src/mbgl/text/get_anchors.cpp new file mode 100644 index 000000000..fa5f81ba4 --- /dev/null +++ b/src/mbgl/text/get_anchors.cpp @@ -0,0 +1,79 @@ +#include + +#include + +#include + +namespace mbgl { + +Anchors resample(const std::vector &line, const float offset, const float spacing, + const float angleWindowSize, const float maxAngle, const float labelLength, const bool placeAtMiddle) { + + float distance = 0; + float markedDistance = offset != 0.0f ? offset - spacing : 0; + + Anchors anchors; + + auto end = line.end() - 1; + int i = 0; + for (auto it = line.begin(); it != end; it++, i++) { + const Coordinate &a = *(it); + const Coordinate &b = *(it + 1); + + const float segmentDist = util::dist(a, b); + const float angle = util::angle_to(b, a); + + while (markedDistance + spacing < distance + segmentDist) { + markedDistance += spacing; + + float t = (markedDistance - distance) / segmentDist, + x = util::interpolate(a.x, b.x, t), + y = util::interpolate(a.y, b.y, t); + + if (x >= 0 && x < 4096 && y >= 0 && y < 4096) { + Anchor anchor(x, y, angle, 0.5f, i); + + if (!angleWindowSize || true) { + anchors.push_back(anchor); + } + //if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) { + } + } + + distance += segmentDist; + } + + if (!placeAtMiddle && !anchors.size()) { + // The first attempt at finding anchors at which labels can be placed failed. + // Try again, but this time just try placing one anchor at the middle of the line. + // This has the most effect for short lines in overscaled tiles, since the + // initial offset used in overscaled tiles is calculated to align labels with positions in + // parent tiles instead of placing the label as close to the beginning as possible. + anchors = std::move(resample(line, distance / 2, spacing, angleWindowSize, maxAngle, labelLength, true)); + } + + return anchors; +} + +Anchors getAnchors(const std::vector &line, float spacing, + const bool maxAngle, const float left, const float right, + const float glyphSize, const float boxScale, const float overscaling) { + + // Resample a line to get anchor points for labels and check that each + // potential label passes text-max-angle check and has enough froom to fit + // on the line. + + const float angleWindowSize = left - right != 0.0f ? + 3 / 5 * glyphSize * boxScale : + 0; + + // Offset the first anchor by half the label length (or half the spacing distance for icons). + // Add a bit of extra offset to avoid collisions at T intersections. + const float labelLength = right - left ? right - left : spacing; + const float extraOffset = glyphSize * 2; + const float offset = std::fmod((labelLength / 2 + extraOffset) * boxScale * overscaling, spacing); + + return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength * boxScale, false); +} + +} diff --git a/src/mbgl/text/get_anchors.hpp b/src/mbgl/text/get_anchors.hpp new file mode 100644 index 000000000..ca879d224 --- /dev/null +++ b/src/mbgl/text/get_anchors.hpp @@ -0,0 +1,14 @@ +#ifndef MBGL_TEXT_GETANCHORS +#define MBGL_TEXT_GETANCHORS + +#include +#include + +namespace mbgl { + +Anchors getAnchors(const std::vector &line, float spacing, + const bool maxAngle, const float left, const float right, + const float glyphSize, const float boxScale, const float overscaling); +} + +#endif diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp index 254cc212e..bc46042d2 100644 --- a/src/mbgl/text/glyph.hpp +++ b/src/mbgl/text/glyph.hpp @@ -58,7 +58,7 @@ class Shaping { public: inline explicit Shaping() : top(0), bottom(0), left(0), right(0) {} inline explicit Shaping(float x, float y) - : top(-y), bottom(y), left(-x), right(x) {} + : top(y), bottom(y), left(x), right(x) {} std::vector positionedGlyphs; int32_t top; int32_t bottom; diff --git a/src/mbgl/text/glyph_store.cpp b/src/mbgl/text/glyph_store.cpp index 06a211351..9e8f7d439 100644 --- a/src/mbgl/text/glyph_store.cpp +++ b/src/mbgl/text/glyph_store.cpp @@ -40,7 +40,7 @@ const Shaping FontStack::getShaping(const std::u32string &string, const float ma const float spacing, const vec2 &translate) const { std::lock_guard lock(mtx); - Shaping shaping(translate.x, translate.y); + Shaping shaping(translate.x * 24, translate.y * 24); // the y offset *should* be part of the font metadata const int32_t yOffset = -17;