summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-10-27 13:55:24 -0700
committerChris Loer <chris.loer@gmail.com>2017-10-31 10:25:57 -0700
commit2d78e611cbe366d0e176abfb60194c4de234e2b1 (patch)
tree1990ae78396f0e6cd0d78a3838c913924a1db979
parent7d41c0255625c316a833a0f4b3e97896bd101775 (diff)
downloadqtlocation-mapboxgl-2d78e611cbe366d0e176abfb60194c4de234e2b1.tar.gz
Re-enable vertical glyph support.
-rw-r--r--src/mbgl/layout/symbol_instance.cpp8
-rw-r--r--src/mbgl/layout/symbol_instance.hpp3
-rw-r--r--src/mbgl/layout/symbol_layout.cpp42
-rw-r--r--src/mbgl/layout/symbol_layout.hpp2
-rw-r--r--src/mbgl/layout/symbol_projection.cpp27
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp10
-rw-r--r--src/mbgl/text/placement.cpp5
7 files changed, 42 insertions, 55 deletions
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index 3bc13331f8..b396c05f4e 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -32,7 +32,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
hasIcon(shapedIcon),
// Create the collision features that will be used to check whether this symbol instance can be placed
- textCollisionFeature(line_, anchor, shapedTextOrientations.second ?: shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature),
+ textCollisionFeature(line_, anchor, shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature),
iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, SymbolPlacementType::Point, indexedFeature),
featureIndex(featureIndex_),
textOffset(textOffset_),
@@ -45,12 +45,10 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.first);
}
if (shapedTextOrientations.first) {
- auto quads = getGlyphQuads(shapedTextOrientations.first, layout, textPlacement, positions);
- glyphQuads.insert(glyphQuads.end(), quads.begin(), quads.end());
+ horizontalGlyphQuads = getGlyphQuads(shapedTextOrientations.first, layout, textPlacement, positions);
}
if (shapedTextOrientations.second) {
- auto quads = getGlyphQuads(shapedTextOrientations.second, layout, textPlacement, positions);
- glyphQuads.insert(glyphQuads.end(), quads.begin(), quads.end());
+ verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.second, layout, textPlacement, positions);
}
}
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index f40f38368a..231d1ca079 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -39,7 +39,8 @@ public:
uint32_t index;
bool hasText;
bool hasIcon;
- SymbolQuads glyphQuads;
+ SymbolQuads horizontalGlyphQuads;
+ SymbolQuads verticalGlyphQuads;
optional<SymbolQuad> iconQuad;
CollisionFeature textCollisionFeature;
CollisionFeature iconCollisionFeature;
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 206ee05027..26059dcaf9 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -416,18 +416,6 @@ std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const
std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes) {
auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, symbolInstances);
- // Calculate which labels can be shown and when they can be shown and
- // create the bufers used for rendering.
-
- const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map
- ? SymbolPlacementType::Point
- : layout.get<SymbolPlacement>();
- const SymbolPlacementType iconPlacement = layout.get<IconRotationAlignment>() != AlignmentType::Map
- ? SymbolPlacementType::Point
- : layout.get<SymbolPlacement>();
-
- const bool keepUpright = layout.get<TextKeepUpright>();
-
// this iterates over the *bucket's* symbol instances so that it can set the placedsymbol index. TODO cleanup
for (SymbolInstance &symbolInstance : bucket->symbolInstances) {
@@ -439,16 +427,27 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes)
// Insert final placement into collision tree and add glyphs/icons to buffers
if (hasText) {
- const bool useVerticalMode = false; // TODO: Add both versions of glyphs to buckets
const Range<float> sizeData = bucket->textSizeBinder->getVertexSizeData(feature);
bucket->text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.textOffset, useVerticalMode, symbolInstance.line, CalculateTileDistances(symbolInstance.line, symbolInstance.anchor));
+ symbolInstance.textOffset, symbolInstance.writingModes, symbolInstance.line, CalculateTileDistances(symbolInstance.line, symbolInstance.anchor));
symbolInstance.placedTextIndices.push_back(bucket->text.placedSymbols.size() - 1);
- for (const auto& symbol : symbolInstance.glyphQuads) {
+ for (const auto& symbol : symbolInstance.horizontalGlyphQuads) {
addSymbol(
bucket->text, sizeData, symbol,
- keepUpright, textPlacement, symbolInstance.anchor, bucket->text.placedSymbols.back());
+ symbolInstance.anchor, bucket->text.placedSymbols.back());
+ }
+
+ if (symbolInstance.writingModes & WritingModeType::Vertical) {
+ bucket->text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
+ symbolInstance.textOffset, WritingModeType::Vertical, symbolInstance.line, CalculateTileDistances(symbolInstance.line, symbolInstance.anchor));
+ symbolInstance.placedTextIndices.push_back(bucket->text.placedSymbols.size() - 1);
+
+ for (const auto& symbol : symbolInstance.verticalGlyphQuads) {
+ addSymbol(
+ bucket->text, sizeData, symbol,
+ symbolInstance.anchor, bucket->text.placedSymbols.back());
+ }
}
}
@@ -456,11 +455,11 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes)
if (symbolInstance.iconQuad) {
const Range<float> sizeData = bucket->iconSizeBinder->getVertexSizeData(feature);
bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.iconOffset, false, symbolInstance.line, std::vector<float>());
+ symbolInstance.iconOffset, WritingModeType::None, symbolInstance.line, std::vector<float>());
symbolInstance.placedIconIndices.push_back(bucket->icon.placedSymbols.size() - 1);
addSymbol(
bucket->icon, sizeData, *symbolInstance.iconQuad,
- keepUpright, iconPlacement, symbolInstance.anchor, bucket->icon.placedSymbols.back());
+ symbolInstance.anchor, bucket->icon.placedSymbols.back());
}
}
@@ -481,8 +480,6 @@ template <typename Buffer>
void SymbolLayout::addSymbol(Buffer& buffer,
const Range<float> sizeData,
const SymbolQuad& symbol,
- const bool keepUpright,
- const style::SymbolPlacementType placement,
const Anchor& labelAnchor,
PlacedSymbol& placedSymbol) {
constexpr const uint16_t vertexLength = 4;
@@ -493,11 +490,6 @@ void SymbolLayout::addSymbol(Buffer& buffer,
const auto &br = symbol.br;
const auto &tex = symbol.tex;
- if (placement == style::SymbolPlacementType::Line && keepUpright) {
- // drop incorrectly oriented glyphs
- if ((symbol.writingMode == WritingModeType::Vertical) != placedSymbol.useVerticalMode) return;
- }
-
if (buffer.segments.empty() || buffer.segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
buffer.segments.emplace_back(buffer.vertices.vertexSize(), buffer.triangles.indexSize());
}
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 99b2fd561c..620a317add 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -63,8 +63,6 @@ private:
void addSymbol(Buffer&,
const Range<float> sizeData,
const SymbolQuad&,
- const bool keepUpright,
- const style::SymbolPlacementType,
const Anchor& labelAnchor,
PlacedSymbol& placedSymbol);
diff --git a/src/mbgl/layout/symbol_projection.cpp b/src/mbgl/layout/symbol_projection.cpp
index 6b1dbf8fac..d99b7e7620 100644
--- a/src/mbgl/layout/symbol_projection.cpp
+++ b/src/mbgl/layout/symbol_projection.cpp
@@ -261,7 +261,8 @@ namespace mbgl {
const mat4& labelPlaneMatrix,
const mat4& glCoordMatrix,
gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex>& dynamicVertexArray,
- const Point<float>& projectedAnchorPoint) {
+ const Point<float>& projectedAnchorPoint,
+ const float aspectRatio) {
const float fontScale = fontSize / 24.0;
const float lineOffsetX = symbol.lineOffset[0] * fontSize;
const float lineOffsetY = symbol.lineOffset[1] * fontSize;
@@ -278,30 +279,28 @@ namespace mbgl {
const Point<float> firstPoint = project(firstAndLastGlyph->first.point, glCoordMatrix).first;
const Point<float> lastPoint = project(firstAndLastGlyph->second.point, glCoordMatrix).first;
- if (keepUpright && !flip &&
- (symbol.useVerticalMode ? firstPoint.y < lastPoint.y : firstPoint.x > lastPoint.x)) {
- return PlacementResult::NeedsFlipping;
- }
-
if (keepUpright && !flip) {
- if (symbol.writingMode == WritingModeType::Horizontal) {
+ if (symbol.writingModes == (WritingModeType::Horizontal | WritingModeType::Vertical)) {
// On top of choosing whether to flip, choose whether to render this version of the glyphs or the alternate
// vertical glyphs. We can't just filter out vertical glyphs in the horizontal range because the horizontal
// and vertical versions can have slightly different projections which could lead to angles where both or
// neither showed.
- if (std::abs(lastPoint.y - firstPoint.y) > std::abs(lastPoint.x - firstPoint.x)) {
+ auto rise = std::abs(lastPoint.y - firstPoint.y);
+ auto run = std::abs(lastPoint.x - firstPoint.x) * aspectRatio;
+ if (rise > run) {
return PlacementResult::UseVertical;
}
}
- if (symbol.writingMode == WritingModeType::Vertical ? firstPoint.y < lastPoint.y : firstPoint.x > lastPoint.x) {
+ if ((symbol.writingModes == WritingModeType::Vertical) ?
+ (firstPoint.y < lastPoint.y) :
+ (firstPoint.x > lastPoint.x)) {
// Includes "horizontalOnly" case for labels without vertical glyphs
return PlacementResult::NeedsFlipping;
}
}
-
placedGlyphs.push_back(firstAndLastGlyph->first);
for (size_t glyphIndex = 1; glyphIndex < symbol.glyphOffsets.size() - 1; glyphIndex++) {
const float glyphOffsetX = symbol.glyphOffsets[glyphIndex];
@@ -324,7 +323,7 @@ namespace mbgl {
projectedVertex.first :
projectTruncatedLineSegment(symbol.anchorPoint,tileSegmentEnd, a, 1, posMatrix);
- if (symbol.useVerticalMode ? b.y > a.y : b.x < a.x) {
+ if (symbol.writingModes == WritingModeType::Vertical ? b.y > a.y : b.x < a.x) {
return PlacementResult::NeedsFlipping;
}
}
@@ -371,7 +370,7 @@ namespace mbgl {
// Don't do calculations for vertical glyphs unless the previous symbol was horizontal
// and we determined that vertical glyphs were necessary.
// Also don't do calculations for symbols that are collided and fully faded out
- if (placedSymbol.hidden || (placedSymbol.writingMode == WritingModeType::Vertical && !useVertical)) {
+ if (placedSymbol.hidden || (placedSymbol.writingModes == WritingModeType::Vertical && !useVertical)) {
hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray);
continue;
}
@@ -397,13 +396,13 @@ namespace mbgl {
const Point<float> anchorPoint = project(placedSymbol.anchorPoint, labelPlaneMatrix).first;
- PlacementResult placeUnflipped = placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, false /*unflipped*/, values.keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray, anchorPoint);
+ PlacementResult placeUnflipped = placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, false /*unflipped*/, values.keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray, anchorPoint, state.getSize().aspectRatio());
useVertical = placeUnflipped == PlacementResult::UseVertical;
if (placeUnflipped == PlacementResult::NotEnoughRoom || useVertical ||
(placeUnflipped == PlacementResult::NeedsFlipping &&
- placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, true /*flipped*/, values.keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray, anchorPoint) == PlacementResult::NotEnoughRoom)) {
+ placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, true /*flipped*/, values.keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray, anchorPoint, state.getSize().aspectRatio()) == PlacementResult::NotEnoughRoom)) {
hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray);
}
}
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index c18f89078d..131ee72c43 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -19,24 +19,20 @@ namespace mbgl {
class PlacedSymbol {
public:
PlacedSymbol(Point<float> anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_,
- std::array<float, 2> lineOffset_, bool useVerticalMode_, const GeometryCoordinates& line_, const std::vector<float>& tileDistances_) :
+ std::array<float, 2> lineOffset_, WritingModeType writingModes_, const GeometryCoordinates& line_, const std::vector<float>& tileDistances_) :
anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_),
- lineOffset(lineOffset_), useVerticalMode(useVerticalMode_), line(line_), tileDistances(tileDistances_)
+ lineOffset(lineOffset_), writingModes(writingModes_), line(line_), tileDistances(tileDistances_), hidden(false)
{
- // TODO WIP hook these up
- writingMode = WritingModeType::None;
- hidden = false;
}
Point<float> anchorPoint;
uint16_t segment;
float lowerSize;
float upperSize;
std::array<float, 2> lineOffset;
- bool useVerticalMode;
+ WritingModeType writingModes;
GeometryCoordinates line;
std::vector<float> tileDistances;
std::vector<float> glyphOffsets;
- WritingModeType writingMode;
bool hidden;
};
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index fa277b2b8b..bfdb6136a1 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -218,7 +218,10 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket) {
// TODO check if hasText is the right thing here, or if there are cases where hasText is true but it's not added to the buffers
if (symbolInstance.hasText) {
auto opacityVertex = SymbolOpacityAttributes::vertex(opacityState.text.placed, opacityState.text.opacity);
- for (size_t i = 0; i < symbolInstance.glyphQuads.size() * 4; i++) {
+ for (size_t i = 0; i < symbolInstance.horizontalGlyphQuads.size() * 4; i++) {
+ bucket.text.opacityVertices.emplace_back(opacityVertex);
+ }
+ for (size_t i = 0; i < symbolInstance.verticalGlyphQuads.size() * 4; i++) {
bucket.text.opacityVertices.emplace_back(opacityVertex);
}
// TODO On JS we avoid setting this if it hasn't chnaged, but it may be cheap enough here we don't care