Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Fix combination of icon-text-fit with text-variable-anchors an…
Browse files Browse the repository at this point in the history
…d text-writing-mode
  • Loading branch information
alexshalamov committed Aug 9, 2019
1 parent 799b883 commit 19a49a5
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 47 deletions.
10 changes: 9 additions & 1 deletion src/mbgl/layout/symbol_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ SymbolInstanceSharedData::SymbolInstanceSharedData(GeometryCoordinates line_,
bool allowVerticalPlacement) : line(std::move(line_)) {
// Create the quads used for rendering the icon and glyphs.
if (shapedIcon) {
iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal);
iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, getAnyShaping(shapedTextOrientations));
if (allowVerticalPlacement && shapedTextOrientations.vertical && layout.get<IconTextFit>() != IconTextFitType::None) {
verticalIconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.vertical);
}
}

bool singleLineInitialized = false;
Expand Down Expand Up @@ -153,6 +156,11 @@ const optional<SymbolQuad>& SymbolInstance::iconQuad() const {
return sharedData->iconQuad;
}

const optional<SymbolQuad>& SymbolInstance::verticalIconQuad() const {
assert(sharedData);
return sharedData->verticalIconQuad;
}

void SymbolInstance::releaseSharedData() {
sharedData.reset();
}
Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/layout/symbol_instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct SymbolInstanceSharedData {
SymbolQuads leftJustifiedGlyphQuads;
SymbolQuads verticalGlyphQuads;
optional<SymbolQuad> iconQuad;
optional<SymbolQuad> verticalIconQuad;
};

class SymbolInstance {
Expand Down Expand Up @@ -71,6 +72,7 @@ class SymbolInstance {
const SymbolQuads& centerJustifiedGlyphQuads() const;
const SymbolQuads& verticalGlyphQuads() const;
const optional<SymbolQuad>& iconQuad() const;
const optional<SymbolQuad>& verticalIconQuad() const;
void releaseSharedData();

private:
Expand Down Expand Up @@ -101,6 +103,7 @@ class SymbolInstance {
optional<size_t> placedLeftTextIndex;
optional<size_t> placedVerticalTextIndex;
optional<size_t> placedIconIndex;
optional<size_t> placedVerticalIconIndex;
float textBoxScale;
float radialTextOffset;
bool singleLine;
Expand Down
45 changes: 28 additions & 17 deletions src/mbgl/layout/symbol_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,32 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn

// Insert final placement into collision tree and add glyphs/icons to buffers

// Process icon first, so that text symbols would have reference to iconIndex which
// is used when dynamic vertices for icon-text-fit image has to be updated.
if (hasIcon) {
if (symbolInstance.hasIcon) {
const Range<float> sizeData = bucket->iconSizeBinder->getVertexSizeData(feature);
const auto placeIcon = [&] (const SymbolQuad& iconQuad, auto& index, const WritingModeType writingMode) {
bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
symbolInstance.iconOffset, writingMode, symbolInstance.line(), std::vector<float>());
index = bucket->icon.placedSymbols.size() - 1;
PlacedSymbol& iconSymbol = bucket->icon.placedSymbols.back();
iconSymbol.angle = (allowVerticalPlacement && writingMode == WritingModeType::Vertical) ? M_PI_2 : 0;
iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, iconQuad,
symbolInstance.anchor, iconSymbol, feature.sortKey);
};

placeIcon(*symbolInstance.iconQuad(), symbolInstance.placedIconIndex, WritingModeType::None);
if (symbolInstance.verticalIconQuad()) {
placeIcon(*symbolInstance.verticalIconQuad(), symbolInstance.placedVerticalIconIndex, WritingModeType::Vertical);
}

for (auto& pair : bucket->paintProperties) {
pair.second.iconBinders.populateVertexVectors(feature, bucket->icon.vertices.elements(), {}, {});
}
}
}

if (hasText && feature.formattedText) {
optional<std::size_t> lastAddedSection;
if (singleLine) {
Expand All @@ -643,21 +669,6 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
updatePaintPropertiesForSection(*bucket, feature, *lastAddedSection);
}

if (hasIcon) {
if (symbolInstance.hasIcon) {
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, WritingModeType::None, symbolInstance.line(), std::vector<float>());
symbolInstance.placedIconIndex = bucket->icon.placedSymbols.size() - 1;
PlacedSymbol& iconSymbol = bucket->icon.placedSymbols.back();
iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, *symbolInstance.iconQuad(),
symbolInstance.anchor, iconSymbol, feature.sortKey);

for (auto& pair : bucket->paintProperties) {
pair.second.iconBinders.populateVertexVectors(feature, bucket->icon.vertices.elements(), {}, {});
}
}
}
symbolInstance.releaseSharedData();
}

Expand Down Expand Up @@ -693,9 +704,9 @@ std::size_t SymbolLayout::addSymbolGlyphQuads(SymbolBucket& bucket,
optional<std::size_t> lastAddedSection) {
const Range<float> sizeData = bucket.textSizeBinder->getVertexSizeData(feature);
const bool hasFormatSectionOverrides = bucket.hasFormatSectionOverrides();

const auto& placedIconIndex = writingMode == WritingModeType::Vertical ? symbolInstance.placedVerticalIconIndex : symbolInstance.placedIconIndex;
bucket.text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
symbolInstance.textOffset, writingMode, symbolInstance.line(), CalculateTileDistances(symbolInstance.line(), symbolInstance.anchor));
symbolInstance.textOffset, writingMode, symbolInstance.line(), CalculateTileDistances(symbolInstance.line(), symbolInstance.anchor), placedIconIndex);
placedIndex = bucket.text.placedSymbols.size() - 1;
PlacedSymbol& placedSymbol = bucket.text.placedSymbols.back();
placedSymbol.angle = (allowVerticalPlacement && writingMode == WritingModeType::Vertical) ? M_PI_2 : 0;
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/programs/symbol_program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Values makeValues(const bool isText,
const bool rotateInShader = rotateWithMap && !pitchWithMap && !alongLine;

mat4 labelPlaneMatrix;
if (alongLine || (isText && hasVariablePacement)) {
if (alongLine || hasVariablePacement) {
// For labels that follow lines the first part of the projection is handled on the cpu.
// Pass an identity matrix because no transformation needs to be done in the vertex shader.
matrix::identity(labelPlaneMatrix);
Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/renderer/buckets/symbol_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ void SymbolBucket::sortFeatures(const float angle) {
if (symbolInstance.placedIconIndex) {
addPlacedSymbol(icon.triangles, icon.placedSymbols[*symbolInstance.placedIconIndex]);
}

if (symbolInstance.placedVerticalIconIndex) {
addPlacedSymbol(icon.triangles, icon.placedSymbols[*symbolInstance.placedVerticalIconIndex]);
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/mbgl/renderer/buckets/symbol_bucket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class CrossTileSymbolLayerIndex;
class PlacedSymbol {
public:
PlacedSymbol(Point<float> anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_,
std::array<float, 2> lineOffset_, WritingModeType writingModes_, GeometryCoordinates line_, std::vector<float> tileDistances_) :
std::array<float, 2> lineOffset_, WritingModeType writingModes_, GeometryCoordinates line_, std::vector<float> tileDistances_, optional<size_t> placedIconIndex_ = nullopt) :
anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_),
lineOffset(lineOffset_), writingModes(writingModes_), line(std::move(line_)), tileDistances(std::move(tileDistances_)), hidden(false), vertexStartIndex(0)
lineOffset(lineOffset_), writingModes(writingModes_), line(std::move(line_)), tileDistances(std::move(tileDistances_)), hidden(false), vertexStartIndex(0), placedIconIndex(std::move(placedIconIndex_))
{
}
Point<float> anchorPoint;
Expand All @@ -43,6 +43,9 @@ class PlacedSymbol {
// placement for orientation variants.
optional<style::TextWritingModeType> placedOrientation;
float angle = 0;

// Reference to placed icon, only applicable for text symbols.
optional<size_t> placedIconIndex;
};

class SymbolBucket final : public Bucket {
Expand Down
7 changes: 4 additions & 3 deletions src/mbgl/renderer/layers/render_symbol_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,12 @@ void drawIcon(const DrawFn& draw,
: gfx::TextureFilterType::Nearest };

const Size& iconSize = tile.getIconAtlasTexture().size;
const bool variablePlacedIcon = bucket.hasVariablePlacement && layout.get<IconTextFit>() != IconTextFitType::None;

if (bucket.sdfIcons) {
if (values.hasHalo) {
draw(parameters.programs.getSymbolLayerPrograms().symbolIconSDF,
SymbolSDFIconProgram::layoutUniformValues(false, false, values, iconSize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo),
SymbolSDFIconProgram::layoutUniformValues(false, variablePlacedIcon, values, iconSize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo),
bucket.icon,
iconSegments,
bucket.iconSizeBinder,
Expand All @@ -149,7 +150,7 @@ void drawIcon(const DrawFn& draw,

if (values.hasFill) {
draw(parameters.programs.getSymbolLayerPrograms().symbolIconSDF,
SymbolSDFIconProgram::layoutUniformValues(false, false, values, iconSize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill),
SymbolSDFIconProgram::layoutUniformValues(false, variablePlacedIcon, values, iconSize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill),
bucket.icon,
iconSegments,
bucket.iconSizeBinder,
Expand All @@ -162,7 +163,7 @@ void drawIcon(const DrawFn& draw,
}
} else {
draw(parameters.programs.getSymbolLayerPrograms().symbolIcon,
SymbolIconProgram::layoutUniformValues(false, false, values, iconSize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange),
SymbolIconProgram::layoutUniformValues(false, variablePlacedIcon, values, iconSize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange),
bucket.icon,
iconSegments,
bucket.iconSizeBinder,
Expand Down
Loading

0 comments on commit 19a49a5

Please sign in to comment.