summaryrefslogtreecommitdiff
path: root/src/mbgl/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/text')
-rw-r--r--src/mbgl/text/glyph.hpp6
-rw-r--r--src/mbgl/text/glyph_manager.cpp11
-rw-r--r--src/mbgl/text/glyph_manager.hpp2
-rw-r--r--src/mbgl/text/placement_config.hpp6
-rw-r--r--src/mbgl/text/quads.cpp23
-rw-r--r--src/mbgl/text/shaping.cpp110
-rw-r--r--src/mbgl/text/shaping.hpp7
7 files changed, 95 insertions, 70 deletions
diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp
index 19ecdfd17c..6cccb72ebe 100644
--- a/src/mbgl/text/glyph.hpp
+++ b/src/mbgl/text/glyph.hpp
@@ -58,13 +58,13 @@ using GlyphMap = std::map<FontStack, Glyphs>;
class PositionedGlyph {
public:
- explicit PositionedGlyph(GlyphID glyph_, float x_, float y_, float angle_)
- : glyph(glyph_), x(x_), y(y_), angle(angle_) {}
+ explicit PositionedGlyph(GlyphID glyph_, float x_, float y_, bool vertical_)
+ : glyph(glyph_), x(x_), y(y_), vertical(vertical_) {}
GlyphID glyph = 0;
float x = 0;
float y = 0;
- float angle = 0;
+ bool vertical = false;
};
enum class WritingModeType : uint8_t;
diff --git a/src/mbgl/text/glyph_manager.cpp b/src/mbgl/text/glyph_manager.cpp
index 916d39ae62..c79a1938c1 100644
--- a/src/mbgl/text/glyph_manager.cpp
+++ b/src/mbgl/text/glyph_manager.cpp
@@ -36,8 +36,9 @@ void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphD
for (const auto& range : ranges) {
auto it = entry.ranges.find(range);
if (it == entry.ranges.end() || !it->second.parsed) {
- GlyphRequest& request = requestRange(entry, fontStack, range);
+ GlyphRequest& request = entry.ranges[range];
request.requestors[&requestor] = dependencies;
+ requestRange(request, fontStack, range);
}
}
}
@@ -49,18 +50,14 @@ void GlyphManager::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphD
}
}
-GlyphManager::GlyphRequest& GlyphManager::requestRange(Entry& entry, const FontStack& fontStack, const GlyphRange& range) {
- GlyphRequest& request = entry.ranges[range];
-
+void GlyphManager::requestRange(GlyphRequest& request, const FontStack& fontStack, const GlyphRange& range) {
if (request.req) {
- return request;
+ return;
}
request.req = fileSource.request(Resource::glyphs(glyphURL, fontStack, range), [this, fontStack, range](Response res) {
processResponse(res, fontStack, range);
});
-
- return request;
}
void GlyphManager::processResponse(const Response& res, const FontStack& fontStack, const GlyphRange& range) {
diff --git a/src/mbgl/text/glyph_manager.hpp b/src/mbgl/text/glyph_manager.hpp
index 00df079462..de2b9cde7b 100644
--- a/src/mbgl/text/glyph_manager.hpp
+++ b/src/mbgl/text/glyph_manager.hpp
@@ -58,7 +58,7 @@ private:
std::unordered_map<FontStack, Entry, FontStackHash> entries;
- GlyphRequest& requestRange(Entry&, const FontStack&, const GlyphRange&);
+ void requestRange(GlyphRequest&, const FontStack&, const GlyphRange&);
void processResponse(const Response&, const FontStack&, const GlyphRange&);
void notify(GlyphRequestor&, const GlyphDependencies&);
diff --git a/src/mbgl/text/placement_config.hpp b/src/mbgl/text/placement_config.hpp
index 1e1279341d..48b24b5f41 100644
--- a/src/mbgl/text/placement_config.hpp
+++ b/src/mbgl/text/placement_config.hpp
@@ -13,9 +13,9 @@ public:
bool operator==(const PlacementConfig& rhs) const {
return angle == rhs.angle &&
pitch == rhs.pitch &&
- cameraToCenterDistance == rhs.cameraToCenterDistance &&
- (pitch * util::RAD2DEG < 25 || cameraToTileDistance == rhs.cameraToTileDistance) &&
- debug == rhs.debug;
+ debug == rhs.debug &&
+ ((pitch * util::RAD2DEG < 25) ||
+ (cameraToCenterDistance == rhs.cameraToCenterDistance && cameraToTileDistance == rhs.cameraToTileDistance));
}
bool operator!=(const PlacementConfig& rhs) const {
diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp
index 7908ea4abc..0014ae8d01 100644
--- a/src/mbgl/text/quads.cpp
+++ b/src/mbgl/text/quads.cpp
@@ -133,18 +133,27 @@ SymbolQuads getGlyphQuads(const Shaping& shapedText,
const float x2 = x1 + rect.w;
const float y2 = y1 + rect.h;
- const Point<float> center{builtInOffset.x - halfAdvance, static_cast<float>(static_cast<float>(glyph.metrics.advance) / 2.0)};
-
Point<float> tl{x1, y1};
Point<float> tr{x2, y1};
Point<float> bl{x1, y2};
Point<float> br{x2, y2};
- if (positionedGlyph.angle != 0) {
- tl = util::rotate(tl - center, positionedGlyph.angle) + center;
- tr = util::rotate(tr - center, positionedGlyph.angle) + center;
- bl = util::rotate(bl - center, positionedGlyph.angle) + center;
- br = util::rotate(br - center, positionedGlyph.angle) + center;
+ if (alongLine && positionedGlyph.vertical) {
+ // Vertical-supporting glyphs are laid out in 24x24 point boxes (1 square em)
+ // In horizontal orientation, the y values for glyphs are below the midline
+ // and we use a "yOffset" of -17 to pull them up to the middle.
+ // By rotating counter-clockwise around the point at the center of the left
+ // edge of a 24x24 layout box centered below the midline, we align the center
+ // of the glyphs with the horizontal midline, so the yOffset is no longer
+ // necessary, but we also pull the glyph to the left along the x axis
+ const Point<float> center{-halfAdvance, halfAdvance};
+ const float verticalRotation = -M_PI_2;
+ const Point<float> xOffsetCorrection{5, 0};
+
+ tl = util::rotate(tl - center, verticalRotation) + center + xOffsetCorrection;
+ tr = util::rotate(tr - center, verticalRotation) + center + xOffsetCorrection;
+ bl = util::rotate(bl - center, verticalRotation) + center + xOffsetCorrection;
+ br = util::rotate(br - center, verticalRotation) + center + xOffsetCorrection;
}
if (textRotate) {
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index 4a206e9bae..5d688ea539 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -11,12 +11,63 @@
namespace mbgl {
-PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, const float iconRotation) {
+struct AnchorAlignment {
+ AnchorAlignment(float horizontal_, float vertical_)
+ : horizontalAlign(horizontal_), verticalAlign(vertical_) {
+ }
+
+ float horizontalAlign;
+ float verticalAlign;
+};
+
+AnchorAlignment getAnchorAlignment(style::SymbolAnchorType anchor) {
+ float horizontalAlign = 0.5;
+ float verticalAlign = 0.5;
+
+ switch (anchor) {
+ case style::SymbolAnchorType::Top:
+ case style::SymbolAnchorType::Bottom:
+ case style::SymbolAnchorType::Center:
+ break;
+ case style::SymbolAnchorType::Right:
+ case style::SymbolAnchorType::TopRight:
+ case style::SymbolAnchorType::BottomRight:
+ horizontalAlign = 1;
+ break;
+ case style::SymbolAnchorType::Left:
+ case style::SymbolAnchorType::TopLeft:
+ case style::SymbolAnchorType::BottomLeft:
+ horizontalAlign = 0;
+ break;
+ }
+
+ switch (anchor) {
+ case style::SymbolAnchorType::Left:
+ case style::SymbolAnchorType::Right:
+ case style::SymbolAnchorType::Center:
+ break;
+ case style::SymbolAnchorType::Bottom:
+ case style::SymbolAnchorType::BottomLeft:
+ case style::SymbolAnchorType::BottomRight:
+ verticalAlign = 1;
+ break;
+ case style::SymbolAnchorType::Top:
+ case style::SymbolAnchorType::TopLeft:
+ case style::SymbolAnchorType::TopRight:
+ verticalAlign = 0;
+ break;
+ }
+
+ return AnchorAlignment(horizontalAlign, verticalAlign);
+}
+
+PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, style::SymbolAnchorType iconAnchor, const float iconRotation) {
+ AnchorAlignment anchorAlign = getAnchorAlignment(iconAnchor);
float dx = iconOffset[0];
float dy = iconOffset[1];
- float x1 = dx - image.displaySize()[0] / 2.0f;
+ float x1 = dx - image.displaySize()[0] * anchorAlign.horizontalAlign;
float x2 = x1 + image.displaySize()[0];
- float y1 = dy - image.displaySize()[1] / 2.0f;
+ float y1 = dy - image.displaySize()[1] * anchorAlign.verticalAlign;
float y2 = y1 + image.displaySize()[1];
return PositionedIcon { image, y1, y2, x1, x2, iconRotation };
@@ -200,7 +251,7 @@ void shapeLines(Shaping& shaping,
const std::vector<std::u16string>& lines,
const float spacing,
const float lineHeight,
- const style::TextAnchorType textAnchor,
+ const style::SymbolAnchorType textAnchor,
const style::TextJustifyType textJustify,
const float verticalHeight,
const WritingModeType writingMode,
@@ -237,10 +288,10 @@ void shapeLines(Shaping& shaping,
const Glyph& glyph = **it->second;
if (writingMode == WritingModeType::Horizontal || !util::i18n::hasUprightVerticalOrientation(chr)) {
- shaping.positionedGlyphs.emplace_back(chr, x, y, 0);
+ shaping.positionedGlyphs.emplace_back(chr, x, y, false);
x += glyph.metrics.advance + spacing;
} else {
- shaping.positionedGlyphs.emplace_back(chr, x, 0, -M_PI_2);
+ shaping.positionedGlyphs.emplace_back(chr, x, 0, true);
x += verticalHeight + spacing;
}
}
@@ -258,58 +309,23 @@ void shapeLines(Shaping& shaping,
y += lineHeight;
}
- 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;
- }
+ auto anchorAlign = getAnchorAlignment(textAnchor);
- align(shaping, justify, horizontalAlign, verticalAlign,
- maxLineLength, lineHeight, lines.size());
+ align(shaping, justify, anchorAlign.horizontalAlign, anchorAlign.verticalAlign, maxLineLength,
+ lineHeight, lines.size());
const uint32_t height = lines.size() * lineHeight;
// Calculate the bounding box
- shaping.top += -verticalAlign * height;
+ shaping.top += -anchorAlign.verticalAlign * height;
shaping.bottom = shaping.top + height;
- shaping.left += -horizontalAlign * maxLineLength;
+ shaping.left += -anchorAlign.horizontalAlign * maxLineLength;
shaping.right = shaping.left + maxLineLength;
}
const Shaping getShaping(const std::u16string& logicalInput,
const float maxWidth,
const float lineHeight,
- const style::TextAnchorType textAnchor,
+ const style::SymbolAnchorType textAnchor,
const style::TextJustifyType textJustify,
const float spacing,
const Point<float>& translate,
diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp
index 00e4ec55f8..0a961849e5 100644
--- a/src/mbgl/text/shaping.hpp
+++ b/src/mbgl/text/shaping.hpp
@@ -32,7 +32,10 @@ private:
float _angle;
public:
- static PositionedIcon shapeIcon(const ImagePosition&, const std::array<float, 2>& iconOffset, const float iconRotation);
+ static PositionedIcon shapeIcon(const ImagePosition&,
+ const std::array<float, 2>& iconOffset,
+ style::SymbolAnchorType iconAnchor,
+ const float iconRotation);
const ImagePosition& image() const { return _image; }
float top() const { return _top; }
@@ -45,7 +48,7 @@ public:
const Shaping getShaping(const std::u16string& string,
float maxWidth,
float lineHeight,
- style::TextAnchorType textAnchor,
+ style::SymbolAnchorType textAnchor,
style::TextJustifyType textJustify,
float spacing,
const Point<float>& translate,