[core] getGlyphQuad -> getGlyphQuads

This commit is contained in:
Konstantin Käfer
2019-12-09 14:37:09 +01:00
committed by Alexander Shalamov
parent d8d336160c
commit 4b171cccf1
8 changed files with 111 additions and 45 deletions

View File

@@ -31,10 +31,10 @@ SymbolInstanceSharedData::SymbolInstanceSharedData(GeometryCoordinates line_,
: line(std::move(line_)) {
// Create the quads used for rendering the icon and glyphs.
if (shapedIcon) {
iconQuad = getIconQuad(*shapedIcon, getAnyShaping(shapedTextOrientations).writingMode, iconType);
iconQuads = getIconQuads(*shapedIcon, getAnyShaping(shapedTextOrientations).writingMode, iconType);
if (verticallyShapedIcon) {
verticalIconQuad =
getIconQuad(*verticallyShapedIcon, shapedTextOrientations.vertical.writingMode, iconType);
verticalIconQuads =
getIconQuads(*verticallyShapedIcon, shapedTextOrientations.vertical.writingMode, iconType);
}
}
@@ -130,6 +130,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
centerJustifiedGlyphQuadsSize = sharedData->centerJustifiedGlyphQuads.size();
leftJustifiedGlyphQuadsSize = sharedData->leftJustifiedGlyphQuads.size();
verticalGlyphQuadsSize = sharedData->verticalGlyphQuads.size();
iconQuadsSize = sharedData->iconQuads ? sharedData->iconQuads->size() : 0;
if (rightJustifiedGlyphQuadsSize || centerJustifiedGlyphQuadsSize || leftJustifiedGlyphQuadsSize) {
writingModes |= WritingModeType::Horizontal;
@@ -165,11 +166,11 @@ const SymbolQuads& SymbolInstance::verticalGlyphQuads() const {
return sharedData->verticalGlyphQuads;
}
const optional<SymbolQuad>& SymbolInstance::iconQuad() const {
const optional<SymbolQuads>& SymbolInstance::iconQuads() const {
assert(sharedData);
return sharedData->iconQuad;
return sharedData->iconQuads;
}
bool SymbolInstance::hasText() const {
return static_cast<bool>(symbolContent & SymbolContent::Text);
}
@@ -182,9 +183,9 @@ bool SymbolInstance::hasSdfIcon() const {
return static_cast<bool>(symbolContent & SymbolContent::IconSDF);
}
const optional<SymbolQuad>& SymbolInstance::verticalIconQuad() const {
const optional<SymbolQuads>& SymbolInstance::verticalIconQuads() const {
assert(sharedData);
return sharedData->verticalIconQuad;
return sharedData->verticalIconQuads;
}
void SymbolInstance::releaseSharedData() {

View File

@@ -41,8 +41,8 @@ struct SymbolInstanceSharedData {
SymbolQuads centerJustifiedGlyphQuads;
SymbolQuads leftJustifiedGlyphQuads;
SymbolQuads verticalGlyphQuads;
optional<SymbolQuad> iconQuad;
optional<SymbolQuad> verticalIconQuad;
optional<SymbolQuads> iconQuads;
optional<SymbolQuads> verticalIconQuads;
};
class SymbolInstance {
@@ -79,8 +79,8 @@ public:
bool hasText() const;
bool hasIcon() const;
bool hasSdfIcon() const;
const optional<SymbolQuad>& iconQuad() const;
const optional<SymbolQuad>& verticalIconQuad() const;
const optional<SymbolQuads>& iconQuads() const;
const optional<SymbolQuads>& verticalIconQuads() const;
void releaseSharedData();
private:
@@ -94,6 +94,7 @@ public:
std::size_t centerJustifiedGlyphQuadsSize;
std::size_t leftJustifiedGlyphQuadsSize;
std::size_t verticalGlyphQuadsSize;
std::size_t iconQuadsSize;
CollisionFeature textCollisionFeature;
CollisionFeature iconCollisionFeature;

View File

@@ -745,7 +745,7 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
if (hasIcon) {
const Range<float> sizeData = bucket->iconSizeBinder->getVertexSizeData(feature);
auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket->sdfIcon : bucket->icon;
const auto placeIcon = [&](const SymbolQuad& iconQuad, auto& index, const WritingModeType writingMode) {
const auto placeIcon = [&](const SymbolQuads& iconQuads, auto& index, const WritingModeType writingMode) {
iconBuffer.placedSymbols.emplace_back(symbolInstance.anchor.point,
symbolInstance.anchor.segment.value_or(0u),
sizeData.min,
@@ -757,13 +757,15 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
index = iconBuffer.placedSymbols.size() - 1;
PlacedSymbol& iconSymbol = iconBuffer.placedSymbols.back();
iconSymbol.angle = (allowVerticalPlacement && writingMode == WritingModeType::Vertical) ? M_PI_2 : 0;
iconSymbol.vertexStartIndex = addSymbol(iconBuffer, sizeData, iconQuad,
symbolInstance.anchor, iconSymbol, feature.sortKey);
iconSymbol.vertexStartIndex =
addSymbols(iconBuffer, sizeData, iconQuads, symbolInstance.anchor, iconSymbol, feature.sortKey);
};
placeIcon(*symbolInstance.iconQuad(), symbolInstance.placedIconIndex, WritingModeType::None);
if (symbolInstance.verticalIconQuad()) {
placeIcon(*symbolInstance.verticalIconQuad(), symbolInstance.placedVerticalIconIndex, WritingModeType::Vertical);
placeIcon(*symbolInstance.iconQuads(), symbolInstance.placedIconIndex, WritingModeType::None);
if (symbolInstance.verticalIconQuads()) {
placeIcon(*symbolInstance.verticalIconQuads(),
symbolInstance.placedVerticalIconIndex,
WritingModeType::Vertical);
}
for (auto& pair : bucket->paintProperties) {
@@ -959,6 +961,24 @@ size_t SymbolLayout::addSymbol(SymbolBucket::Buffer& buffer,
return index;
}
size_t SymbolLayout::addSymbols(SymbolBucket::Buffer& buffer,
const Range<float> sizeData,
const SymbolQuads& symbols,
const Anchor& labelAnchor,
PlacedSymbol& placedSymbol,
float sortKey) {
bool firstSymbol = true;
size_t firstIndex = 0;
for (auto& symbol : symbols) {
const size_t index = addSymbol(buffer, sizeData, symbol, labelAnchor, placedSymbol, sortKey);
if (firstSymbol) {
firstIndex = index;
firstSymbol = false;
}
}
return firstIndex;
}
void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) {
if (!hasSymbolInstances()) {

View File

@@ -81,6 +81,12 @@ private:
const Anchor& labelAnchor,
PlacedSymbol& placedSymbol,
float sortKey);
size_t addSymbols(SymbolBucket::Buffer&,
const Range<float> sizeData,
const SymbolQuads&,
const Anchor& labelAnchor,
PlacedSymbol& placedSymbol,
float sortKey);
// Adds symbol quads to bucket and returns formatted section index of last
// added quad.

View File

@@ -945,19 +945,22 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket,
}
}
if (symbolInstance.hasIcon()) {
size_t iconOpacityVerticesSize = 0u;
const auto& opacityVertex =
SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity);
auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket.sdfIcon : bucket.icon;
if (symbolInstance.placedIconIndex) {
iconBuffer.opacityVertices.extend(4, opacityVertex);
iconOpacityVerticesSize += symbolInstance.iconQuadsSize * 4;
iconBuffer.placedSymbols[*symbolInstance.placedIconIndex].hidden = opacityState.isHidden();
}
if (symbolInstance.placedVerticalIconIndex) {
iconBuffer.opacityVertices.extend(4, opacityVertex);
iconOpacityVerticesSize += symbolInstance.iconQuadsSize * 4;
iconBuffer.placedSymbols[*symbolInstance.placedVerticalIconIndex].hidden = opacityState.isHidden();
}
iconBuffer.opacityVertices.extend(iconOpacityVerticesSize, opacityVertex);
}
auto updateIconCollisionBox = [&](const auto& feature, const bool placed, const Point<float>& shift) {

View File

@@ -14,7 +14,7 @@ namespace mbgl {
using namespace style;
SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, WritingModeType writingMode, SymbolContent iconType) {
SymbolQuads getIconQuads(const PositionedIcon& shapedIcon, WritingModeType writingMode, SymbolContent iconType) {
const ImagePosition& image = shapedIcon.image();
// If you have a 10px icon that isn't perfectly aligned to the pixel grid it will cover 11 actual
@@ -74,17 +74,17 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, WritingModeType writing
Point<float> pixelOffsetBR;
Point<float> minFontScale;
return SymbolQuad{tl,
tr,
bl,
br,
textureRect,
writingMode,
{0.0f, 0.0f},
iconType == SymbolContent::IconSDF,
pixelOffsetTL,
pixelOffsetBR,
minFontScale};
return {SymbolQuad{tl,
tr,
bl,
br,
textureRect,
writingMode,
{0.0f, 0.0f},
iconType == SymbolContent::IconSDF,
pixelOffsetTL,
pixelOffsetBR,
minFontScale}};
}
SymbolQuads getGlyphQuads(const Shaping& shapedText,

View File

@@ -57,7 +57,7 @@ public:
using SymbolQuads = std::vector<SymbolQuad>;
SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, WritingModeType writingMode, SymbolContent iconType);
SymbolQuads getIconQuads(const PositionedIcon& shapedIcon, WritingModeType writingMode, SymbolContent iconType);
SymbolQuads getGlyphQuads(const Shaping& shapedText,
const std::array<float, 2> textOffset,

View File

@@ -22,8 +22,10 @@ TEST(getIconQuads, normal) {
GeometryCoordinates line;
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_EQ(quad.tl.x, -14);
EXPECT_EQ(quad.tl.y, -10);
EXPECT_EQ(quad.tr.x, 1);
@@ -60,7 +62,10 @@ TEST(getIconQuads, style) {
EXPECT_FLOAT_EQ(-18.5f, shapedIcon.left());
SymbolLayoutProperties::Evaluated layout;
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -19.5);
EXPECT_FLOAT_EQ(quad.tl.y, -19.5);
@@ -76,7 +81,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Width, {{0, 0, 0, 0}}, {{0, 0}}, 24.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -64.4444427);
EXPECT_FLOAT_EQ(quad.tl.y, 0);
@@ -92,7 +100,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Width, {{0, 0, 0, 0}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -32.2222214);
EXPECT_FLOAT_EQ(quad.tl.y, -5);
@@ -108,7 +119,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Width, {{5, 10, 5, 10}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -43.3333321);
EXPECT_FLOAT_EQ(quad.tl.y, -5);
@@ -124,7 +138,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Height, {{0, 0, 0, 0}}, {{0, 0}}, 24.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -30);
EXPECT_FLOAT_EQ(quad.tl.y, -12.2222214);
@@ -141,7 +158,10 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Height, {{0, 0, 0, 0}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -20);
EXPECT_FLOAT_EQ(quad.tl.y, -6.11111069);
@@ -157,7 +177,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Height, {{5, 10, 5, 20}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -20);
EXPECT_FLOAT_EQ(quad.tl.y, -11.666666);
@@ -173,7 +196,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Both, {{0, 0, 0, 0}}, {{0, 0}}, 24.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -64.4444427);
EXPECT_FLOAT_EQ(quad.tl.y, -12.2222214);
@@ -189,7 +215,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Both, {{0, 0, 0, 0}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -32.2222214);
EXPECT_FLOAT_EQ(quad.tl.y, -6.11111069);
@@ -205,7 +234,10 @@ TEST(getIconQuads, style) {
{
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Both, {{5, 10, 5, 10}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -43.3333321);
EXPECT_FLOAT_EQ(quad.tl.y, -11.666666);
@@ -223,7 +255,10 @@ TEST(getIconQuads, style) {
layout.get<TextSize>() = 12.0f;
auto shapedIcon = PositionedIcon::shapeIcon(image, {{-9.5f, -9.5f}}, SymbolAnchorType::Center, 0);
shapedIcon.fitIconToText(shapedText, IconTextFitType::Both, {{0, 5, 10, 15}}, {{0, 0}}, 12.0f / 24.0f);
SymbolQuad quad = getIconQuad(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
SymbolQuads quads = getIconQuads(shapedIcon, WritingModeType::Horizontal, SymbolContent::IconRGBA);
ASSERT_EQ(quads.size(), 1);
const auto& quad = quads[0];
EXPECT_FLOAT_EQ(quad.tl.x, -48.3333321);
EXPECT_FLOAT_EQ(quad.tl.y, -6.66666603);