summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-06-16 11:49:11 +0200
committerKonstantin Käfer <mail@kkaefer.com>2014-06-16 11:49:11 +0200
commit71d2b230a123997b1793dec03b2dec1c6611faaf (patch)
tree362ba98babd195e43ad2f721e5fbfd812f4f5923 /src
parent610a9e4a63cf22eb22d5a1f19cdc784a7059befc (diff)
downloadqtlocation-mapboxgl-71d2b230a123997b1793dec03b2dec1c6611faaf.tar.gz
separate bucket render properties and change naming
Diffstat (limited to 'src')
-rw-r--r--src/map/tile_parser.cpp45
-rw-r--r--src/renderer/fill_bucket.cpp44
-rw-r--r--src/renderer/icon_bucket.cpp10
-rw-r--r--src/renderer/line_bucket.cpp19
-rw-r--r--src/renderer/painter_icon.cpp2
-rw-r--r--src/renderer/painter_text.cpp8
-rw-r--r--src/renderer/text_bucket.cpp8
-rw-r--r--src/style/bucket_description.cpp4
-rw-r--r--src/style/style_parser.cpp294
-rw-r--r--src/text/placement.cpp25
10 files changed, 283 insertions, 176 deletions
diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp
index 21d2bf1bfc..1c1268c809 100644
--- a/src/map/tile_parser.cpp
+++ b/src/map/tile_parser.cpp
@@ -166,24 +166,38 @@ void TileParser::addBucketFeatures(Bucket &bucket, const VectorTileLayer &layer,
std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
+ if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketFillDescription>()) {
+ return nullptr;
+ }
+
std::unique_ptr<FillBucket> bucket = std::make_unique<FillBucket>(
- tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer, bucket_desc);
+ tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer,
+ bucket_desc.render.get<BucketFillDescription>());
addBucketFeatures(bucket, layer, bucket_desc);
return obsolete() ? nullptr : std::move(bucket);
}
std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
+ if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketLineDescription>()) {
+ return nullptr;
+ }
+
std::unique_ptr<LineBucket> bucket = std::make_unique<LineBucket>(
- tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, bucket_desc);
+ tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer,
+ bucket_desc.render.get<BucketLineDescription>());
addBucketFeatures(bucket, layer, bucket_desc);
return obsolete() ? nullptr : std::move(bucket);
}
std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
- std::unique_ptr<IconBucket> bucket =
- std::make_unique<IconBucket>(tile.iconVertexBuffer, bucket_desc);
+ if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketIconDescription>()) {
+ return nullptr;
+ }
+
+ std::unique_ptr<IconBucket> bucket = std::make_unique<IconBucket>(
+ tile.iconVertexBuffer, bucket_desc.render.get<BucketIconDescription>());
addBucketFeatures(bucket, layer, bucket_desc, *spriteAtlas);
return obsolete() ? nullptr : std::move(bucket);
}
@@ -192,8 +206,15 @@ typedef std::pair<uint16_t, uint16_t> GlyphRange;
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
+
+ if (!bucket_desc.render.valid() || !bucket_desc.render.is<BucketTextDescription>()) {
+ return nullptr;
+ }
+
+ const BucketTextDescription &properties = bucket_desc.render.get<BucketTextDescription>();
+
std::unique_ptr<TextBucket> bucket = std::make_unique<TextBucket>(
- tile.textVertexBuffer, tile.triangleElementsBuffer, bucket_desc, placement);
+ tile.textVertexBuffer, tile.triangleElementsBuffer, properties, placement);
util::utf8_to_utf32 ucs4conv;
@@ -210,7 +231,7 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &laye
VectorTileFeature feature{feature_pbf, layer};
const std::u32string string = ucs4conv.convert(
- util::replaceTokens(bucket_desc.geometry.field, feature.properties));
+ util::replaceTokens(properties.field, feature.properties));
// Loop through all characters of this text and collect unique codepoints.
for (uint32_t chr : string) {
@@ -220,23 +241,23 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &laye
labels.emplace_back(string, feature.geometry);
}
- glyphStore->waitForGlyphRanges(bucket_desc.geometry.font, ranges);
+ glyphStore->waitForGlyphRanges(properties.font, ranges);
}
// Create a copy!
- const FontStack &fontStack = glyphStore->getFontStack(bucket_desc.geometry.font);
+ const FontStack &fontStack = glyphStore->getFontStack(properties.font);
GlyphPositions face;
// Shape and place all labels.
for (const std::pair<std::u32string, pbf> &label : labels) {
// Shape labels.
- const Shaping shaping = fontStack.getShaping(label.first, bucket_desc.geometry.max_width,
- bucket_desc.geometry.line_height, bucket_desc.geometry.alignment,
- bucket_desc.geometry.vertical_alignment, bucket_desc.geometry.letter_spacing);
+ const Shaping shaping = fontStack.getShaping(label.first, properties.max_width,
+ properties.line_height, properties.alignment,
+ properties.vertical_alignment, properties.letter_spacing);
// Place labels.
- addGlyph(tile.id.to_uint64(), bucket_desc.geometry.font, label.first, fontStack, *glyphAtlas,
+ addGlyph(tile.id.to_uint64(), properties.font, label.first, fontStack, *glyphAtlas,
face);
bucket->addFeature(label.second, face, shaping);
diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp
index 7021566592..d7ba048a5c 100644
--- a/src/renderer/fill_bucket.cpp
+++ b/src/renderer/fill_bucket.cpp
@@ -30,30 +30,26 @@ void FillBucket::free(void *, void *ptr) {
::free(ptr);
}
-FillBucket::FillBucket(FillVertexBuffer& vertexBuffer,
- TriangleElementsBuffer& triangleElementsBuffer,
- LineElementsBuffer& lineElementsBuffer,
- const BucketDescription& bucket_desc)
- : geom_desc(bucket_desc.geometry),
- allocator(new TESSalloc {
- &alloc,
- &realloc,
- &free,
- nullptr, // userData
- 64, // meshEdgeBucketSize
- 64, // meshVertexBucketSize
- 32, // meshFaceBucketSize
- 64, // dictNodeBucketSize
- 8, // regionBucketSize
- 128, // extraVertices allocated for the priority queue.
-}),
-tesselator(tessNewTess(allocator)),
-vertexBuffer(vertexBuffer),
-triangleElementsBuffer(triangleElementsBuffer),
-lineElementsBuffer(lineElementsBuffer),
-vertex_start(vertexBuffer.index()),
-triangle_elements_start(triangleElementsBuffer.index()),
-line_elements_start(lineElementsBuffer.index()) {
+FillBucket::FillBucket(FillVertexBuffer &vertexBuffer,
+ TriangleElementsBuffer &triangleElementsBuffer,
+ LineElementsBuffer &lineElementsBuffer,
+ const BucketFillDescription &properties)
+ : properties(properties),
+ allocator(new TESSalloc{&alloc, &realloc, &free, nullptr, // userData
+ 64, // meshEdgeBucketSize
+ 64, // meshVertexBucketSize
+ 32, // meshFaceBucketSize
+ 64, // dictNodeBucketSize
+ 8, // regionBucketSize
+ 128, // extraVertices allocated for the priority queue.
+ }),
+ tesselator(tessNewTess(allocator)),
+ vertexBuffer(vertexBuffer),
+ triangleElementsBuffer(triangleElementsBuffer),
+ lineElementsBuffer(lineElementsBuffer),
+ vertex_start(vertexBuffer.index()),
+ triangle_elements_start(triangleElementsBuffer.index()),
+ line_elements_start(lineElementsBuffer.index()) {
assert(tesselator);
}
diff --git a/src/renderer/icon_bucket.cpp b/src/renderer/icon_bucket.cpp
index fd43f69514..b6c324d2ad 100644
--- a/src/renderer/icon_bucket.cpp
+++ b/src/renderer/icon_bucket.cpp
@@ -19,8 +19,8 @@ struct geometry_too_long_exception : std::exception {};
using namespace llmr;
IconBucket::IconBucket(IconVertexBuffer& vertexBuffer,
- const BucketDescription& bucket_desc)
- : geometry(bucket_desc.geometry),
+ const BucketIconDescription& properties)
+ : properties(properties),
vertexBuffer(vertexBuffer),
vertex_start(vertexBuffer.index()) {
}
@@ -28,15 +28,15 @@ IconBucket::IconBucket(IconVertexBuffer& vertexBuffer,
void IconBucket::addFeature(const VectorTileFeature &feature, SpriteAtlas &sprite_atlas) {
std::string field;
- if (geometry.field.size()) {
- field = util::replaceTokens(geometry.field, feature.properties);
+ if (properties.icon.size()) {
+ field = util::replaceTokens(properties.icon, feature.properties);
}
if (!field.size()) {
field = "<circle>";
}
- const Rect<uint16_t> rect = sprite_atlas.getIcon(geometry.size, field);
+ const Rect<uint16_t> rect = sprite_atlas.getIcon(properties.size, field);
const uint16_t tx = rect.x + rect.w / 2;
const uint16_t ty = rect.y + rect.h / 2;
diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp
index 58dde3f50b..d6d3dcf77f 100644
--- a/src/renderer/line_bucket.cpp
+++ b/src/renderer/line_bucket.cpp
@@ -20,8 +20,8 @@ using namespace llmr;
LineBucket::LineBucket(LineVertexBuffer& vertexBuffer,
TriangleElementsBuffer& triangleElementsBuffer,
PointElementsBuffer& pointElementsBuffer,
- const BucketDescription& bucket_desc)
- : geometry(bucket_desc.geometry),
+ const BucketLineDescription& properties)
+ : properties(properties),
vertexBuffer(vertexBuffer),
triangleElementsBuffer(triangleElementsBuffer),
pointElementsBuffer(pointElementsBuffer),
@@ -60,9 +60,6 @@ struct TriangleElement {
typedef uint16_t PointElement;
void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
- const JoinType join = geometry.join;
- const CapType cap = geometry.cap;
- const float miterLimit = geometry.miter_limit;
// TODO: use roundLimit
// const float roundLimit = geometry.round_limit;
@@ -80,8 +77,8 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
return;
}
- CapType beginCap = cap;
- CapType endCap = closed ? CapType::Butt : cap;
+ CapType beginCap = properties.cap;
+ CapType endCap = closed ? CapType::Butt : properties.cap;
JoinType currentJoin = JoinType::None;
@@ -111,7 +108,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
if (currentVertex) prevVertex = currentVertex;
currentVertex = vertices[i];
- currentJoin = join;
+ currentJoin = properties.join;
if (prevVertex) distance += util::dist<double>(currentVertex, prevVertex);
@@ -164,7 +161,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
// Switch to miter joins if the angle is very low.
if (currentJoin != JoinType::Miter) {
- if (std::fabs(joinAngularity) < 0.5 && roundness < miterLimit) {
+ if (std::fabs(joinAngularity) < 0.5 && roundness < properties.miter_limit) {
currentJoin = JoinType::Miter;
}
}
@@ -213,14 +210,14 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
// The two normals are almost parallel.
joinNormal.x = -nextNormal.y;
joinNormal.y = nextNormal.x;
- } else if (roundness > miterLimit) {
+ } else if (roundness > properties.miter_limit) {
// If the miter grows too large, flip the direction to make a
// bevel join.
joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity;
joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity;
}
- if (roundness > miterLimit) {
+ if (roundness > properties.miter_limit) {
flip = -flip;
}
diff --git a/src/renderer/painter_icon.cpp b/src/renderer/painter_icon.cpp
index 8ddf493d0d..8c07349b2a 100644
--- a/src/renderer/painter_icon.cpp
+++ b/src/renderer/painter_icon.cpp
@@ -41,7 +41,7 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons
spriteAtlas.bind(map.getState().isChanging());
- const float iconSize = bucket.geometry.size * map.getState().getPixelRatio();
+ const float iconSize = bucket.properties.size * map.getState().getPixelRatio();
iconShader->setSize(iconSize);
#ifndef GL_ES_VERSION_2_0
glPointSize(iconSize);
diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp
index 5307a12acf..baebe26699 100644
--- a/src/renderer/painter_text.cpp
+++ b/src/renderer/painter_text.cpp
@@ -20,7 +20,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
mat4 exMatrix;
matrix::copy(exMatrix, projMatrix);
- if (bucket.geom_desc.path == TextPathType::Curve) {
+ if (bucket.properties.path == TextPathType::Curve) {
matrix::rotate_z(exMatrix, exMatrix, map.getState().getAngle());
}
@@ -30,7 +30,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
}
// If layerStyle.size > bucket.info.fontSize then labels may collide
- float fontSize = std::fmin(properties.size, bucket.geom_desc.size);
+ float fontSize = std::fmin(properties.size, bucket.properties.max_size);
matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f);
const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor);
@@ -48,10 +48,10 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
float angle = std::round((map.getState().getAngle() + rotate) / M_PI * 128);
// adjust min/max zooms for variable font sies
- float zoomAdjust = log(fontSize / bucket.geom_desc.size) / log(2);
+ float zoomAdjust = log(fontSize / bucket.properties.max_size) / log(2);
textShader->setAngle((int32_t)(angle + 256) % 256);
- textShader->setFlip(bucket.geom_desc.path == TextPathType::Curve ? 1 : 0);
+ textShader->setFlip(bucket.properties.path == TextPathType::Curve ? 1 : 0);
textShader->setZoom((map.getState().getNormalizedZoom() - zoomAdjust) * 10); // current zoom level
// Label fading
diff --git a/src/renderer/text_bucket.cpp b/src/renderer/text_bucket.cpp
index da6de38171..bd18f0576f 100644
--- a/src/renderer/text_bucket.cpp
+++ b/src/renderer/text_bucket.cpp
@@ -22,8 +22,8 @@ using namespace llmr;
TextBucket::TextBucket(
TextVertexBuffer &vertexBuffer,
TriangleElementsBuffer &triangleElementsBuffer,
- const BucketDescription &bucket_desc, Placement &placement)
- : geom_desc(bucket_desc.geometry),
+ const BucketTextDescription &properties, Placement &placement)
+ : properties(properties),
vertexBuffer(vertexBuffer),
triangleElementsBuffer(triangleElementsBuffer),
placement(placement),
@@ -113,14 +113,14 @@ void TextBucket::addFeature(const pbf &geom_pbf,
while ((cmd = geometry.next(x, y)) != Geometry::end) {
if (cmd == Geometry::move_to) {
if (!line.empty()) {
- placement.addFeature(*this, line, geom_desc, face, shaping);
+ placement.addFeature(*this, line, properties, face, shaping);
line.clear();
}
}
line.emplace_back(x, y);
}
if (line.size()) {
- placement.addFeature(*this, line, geom_desc, face, shaping);
+ placement.addFeature(*this, line, properties, face, shaping);
}
}
diff --git a/src/style/bucket_description.cpp b/src/style/bucket_description.cpp
index b154c3a176..24d086f64d 100644
--- a/src/style/bucket_description.cpp
+++ b/src/style/bucket_description.cpp
@@ -8,10 +8,6 @@ std::ostream& llmr::operator<<(std::ostream& os, const BucketDescription& bucket
os << " - type: " << (uint32_t)bucket.type << std::endl;
os << " - source_name: " << bucket.source_name << std::endl;
os << " - source_layer: " << bucket.source_layer << std::endl;
- os << " - cap: " << (uint32_t)bucket.geometry.cap << std::endl;
- os << " - join: " << (uint32_t)bucket.geometry.join << std::endl;
- os << " - font: " << bucket.geometry.font << std::endl;
- os << " - size: " << bucket.geometry.size << std::endl;
return os;
}
diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp
index b686c0ec55..edce8d2b65 100644
--- a/src/style/style_parser.cpp
+++ b/src/style/style_parser.cpp
@@ -73,145 +73,251 @@ PropertyFilterExpression StyleParser::parseFilterOrExpression(JSVal value) {
BucketDescription StyleParser::parseBucket(JSVal value) {
BucketDescription bucket;
- rapidjson::Value::ConstMemberIterator itr = value.MemberBegin();
- for (; itr != value.MemberEnd(); ++itr) {
- const std::string name(itr->name.GetString(), itr->name.GetStringLength());
- JSVal value = itr->value;
-
- if (name == "type") {
- if (value.IsString()) {
- bucket.type = bucketType({ value.GetString(), value.GetStringLength() });
- } else {
- throw Style::exception("bucket type must be a string");
- }
- } else if (name == "feature_type") {
- if (value.IsString()) {
- bucket.feature_type = bucketType({ value.GetString(), value.GetStringLength() });
+ if (value.HasMember("type")) {
+ JSVal type = value["type"];
+ if (type.IsString()) {
+ bucket.type = bucketType({ type.GetString(), type.GetStringLength() });
+ } else {
+ throw Style::exception("bucket type must be a string");
+ }
+ }
+
+ if (value.HasMember("feature_type")) {
+ JSVal feature_type = value["feature_type"];
+ if (feature_type.IsString()) {
+ bucket.feature_type = bucketType({ feature_type.GetString(), feature_type.GetStringLength() });
+ } else {
+ throw Style::exception("feature type must be a string");
+ }
+ }
+
+ if (value.HasMember("source")) {
+ JSVal source = value["source"];
+ if (source.IsString()) {
+ bucket.source_name = { source.GetString(), source.GetStringLength() };
+ } else {
+ throw Style::exception("source name must be a string");
+ }
+ }
+
+ if (value.HasMember("layer")) {
+ JSVal source_layer = value["layer"];
+ if (source_layer.IsString()) {
+ bucket.source_layer = { source_layer.GetString(), source_layer.GetStringLength() };
+ } else {
+ throw Style::exception("layer name must be a string");
+ }
+ }
+
+ if (value.HasMember("filter")) {
+ bucket.filter = std::move(parseFilterOrExpression(value["filter"]));
+ } else {
+ // Allow a filter triple to be specified at the bucket root as well.
+ bucket.filter = std::move(parseFilterOrExpression(value));
+ }
+
+ if (bucket.feature_type == BucketType::None) {
+ bucket.feature_type = bucket.type;
+ }
+
+ switch (bucket.type) {
+ case BucketType::Fill: {
+ bucket.render = BucketFillDescription{};
+ } break;
+
+ case BucketType::Line: {
+ bucket.render = BucketLineDescription{};
+ BucketLineDescription &render = bucket.render.get<BucketLineDescription>();
+
+ if (value.HasMember("cap")) {
+ JSVal property = value["cap"];
+ if (property.IsString()) {
+ render.cap = capType({property.GetString(), property.GetStringLength()});
} else {
- throw Style::exception("feature type must be a string");
+ throw Style::exception("cap type must be a string");
}
- } else if (name == "source") {
- if (value.IsString()) {
- bucket.source_name = { value.GetString(), value.GetStringLength() };
+ }
+ if (value.HasMember("join")) {
+ JSVal property = value["join"];
+ if (property.IsString()) {
+ render.join = joinType({property.GetString(), property.GetStringLength()});
} else {
- throw Style::exception("source name must be a string");
+ throw Style::exception("join type must be a string");
}
- } else if (name == "layer") {
- if (value.IsString()) {
- bucket.source_layer = { value.GetString(), value.GetStringLength() };
+ }
+ if (value.HasMember("miterLimit")) {
+ JSVal property = value["miterLimit"];
+ if (property.IsNumber()) {
+ render.miter_limit = property.GetDouble();
} else {
- throw Style::exception("layer name must be a string");
+ throw Style::exception("miter limit must be a number");
}
- } else if (name == "cap") {
- if (value.IsString()) {
- bucket.geometry.cap = capType({ value.GetString(), value.GetStringLength() });
+ }
+ if (value.HasMember("roundLimit")) {
+ JSVal property = value["roundLimit"];
+ if (property.IsNumber()) {
+ render.round_limit = property.GetDouble();
} else {
- throw Style::exception("cap type must be a string");
+ throw Style::exception("round limit must be a number");
}
- } else if (name == "join") {
- if (value.IsString()) {
- bucket.geometry.join = joinType({ value.GetString(), value.GetStringLength() });
+ }
+ } break;
+
+ case BucketType::Icon: {
+ bucket.render = BucketIconDescription{};
+ BucketIconDescription &render = bucket.render.get<BucketIconDescription>();
+
+ if (value.HasMember("size")) {
+ JSVal property = value["size"];
+ if (property.IsNumber()) {
+ render.size = property.GetDouble();
} else {
- throw Style::exception("join type must be a string");
+ throw Style::exception("font size must be a number");
}
- } else if (name == "font") {
- if (value.IsString()) {
- bucket.geometry.font = { value.GetString(), value.GetStringLength() };
+ }
+
+ if (value.HasMember("icon")) {
+ JSVal property = value["icon"];
+ if (property.IsString()) {
+ render.icon = {property.GetString(), property.GetStringLength()};
} else {
- throw Style::exception("font stack must be a string");
+ throw Style::exception("text field must be a string");
}
- } else if (name == "fontSize" || name == "size") {
- if (value.IsNumber()) {
- bucket.geometry.size = value.GetDouble();
+ }
+
+ if (value.HasMember("translate")) {
+ JSVal property = value["translate"];
+ if (property.IsArray()) {
+ render.translate.x = property[(rapidjson::SizeType)0].GetDouble() * 24;
+ render.translate.y = property[(rapidjson::SizeType)1].GetDouble() * -24;
} else {
- throw Style::exception("font size must be a number");
+ throw Style::exception("translate must be a string");
}
- } else if (name == "text_field" || name == "icon") {
- if (value.IsString()) {
- bucket.geometry.field = { value.GetString(), value.GetStringLength() };
+ }
+ } break;
+
+ case BucketType::Text: {
+ bucket.render = BucketTextDescription{};
+ BucketTextDescription &render = bucket.render.get<BucketTextDescription>();
+
+ if (value.HasMember("text_field")) {
+ JSVal property = value["text_field"];
+ if (property.IsString()) {
+ render.field = {property.GetString(), property.GetStringLength()};
} else {
throw Style::exception("text field must be a string");
}
- } else if (name == "path") {
- if (value.IsString()) {
- bucket.geometry.path = textPathType({ value.GetString(), value.GetStringLength() });
+ }
+
+ if (value.HasMember("path")) {
+ JSVal property = value["path"];
+ if (property.IsString()) {
+ render.path = textPathType({property.GetString(), property.GetStringLength()});
} else {
throw Style::exception("curve must be a string");
}
- } else if (name == "alignment") {
- if (value.IsString()) {
- bucket.geometry.alignment = alignmentType({ value.GetString(), value.GetStringLength() });
+ }
+
+ if (value.HasMember("font")) {
+ JSVal property = value["font"];
+ if (property.IsString()) {
+ render.font = {property.GetString(), property.GetStringLength()};
} else {
- throw Style::exception("alignment must be a string");
+ throw Style::exception("font stack must be a string");
}
- } else if (name == "translate") {
- if (value.IsArray()) {
- bucket.geometry.translate.x = value[(rapidjson::SizeType)0].GetDouble() * 24;
- bucket.geometry.translate.y = value[(rapidjson::SizeType)1].GetDouble() * -24;
+ }
+
+ if (value.HasMember("fontSize")) {
+ JSVal property = value["fontSize"];
+ if (property.IsNumber()) {
+ render.max_size = property.GetDouble();
} else {
- throw Style::exception("translate must be a string");
+ throw Style::exception("font size must be a number");
}
- } else if (name == "verticalAlignment") {
- if (value.IsString()) {
- bucket.geometry.vertical_alignment = verticalAlignmentType({ value.GetString(), value.GetStringLength() });
+ }
+
+ if (value.HasMember("maxWidth")) {
+ JSVal property = value["maxWidth"];
+ if (property.IsNumber()) {
+ render.max_width = property.GetDouble() * 24;
} else {
- throw Style::exception("verticalAlignment must be a string");
+ throw Style::exception("max width must be a number");
}
- } else if (name == "lineHeight") {
- if (value.IsNumber()) {
- bucket.geometry.line_height = value.GetDouble() * 24;
+ }
+
+ if (value.HasMember("lineHeight")) {
+ JSVal property = value["lineHeight"];
+ if (property.IsNumber()) {
+ render.line_height = property.GetDouble() * 24;
} else {
throw Style::exception("line height must be a number");
}
- } else if (name == "maxWidth") {
- if (value.IsNumber()) {
- bucket.geometry.max_width = value.GetDouble() * 24;
- } else {
- throw Style::exception("max width must be a number");
- }
- } else if (name == "letterSpacing") {
- if (value.IsNumber()) {
- bucket.geometry.letter_spacing = value.GetDouble() * 24;
+ }
+
+ if (value.HasMember("letterSpacing")) {
+ JSVal property = value["letterSpacing"];
+ if (property.IsNumber()) {
+ render.letter_spacing = property.GetDouble() * 24;
} else {
throw Style::exception("letter spacing must be a number");
}
- } else if (name == "miterLimit") {
- if (value.IsNumber()) {
- bucket.geometry.miter_limit = value.GetDouble();
+ }
+
+ if (value.HasMember("alignment")) {
+ JSVal property = value["alignment"];
+ if (property.IsString()) {
+ render.alignment =
+ alignmentType({property.GetString(), property.GetStringLength()});
} else {
- throw Style::exception("miter limit must be a number");
+ throw Style::exception("alignment must be a string");
}
- } else if (name == "roundLimit") {
- if (value.IsNumber()) {
- bucket.geometry.round_limit = value.GetDouble();
+ }
+
+ if (value.HasMember("verticalAlignment")) {
+ JSVal property = value["verticalAlignment"];
+ if (property.IsString()) {
+ render.vertical_alignment =
+ verticalAlignmentType({property.GetString(), property.GetStringLength()});
} else {
- throw Style::exception("round limit must be a number");
+ throw Style::exception("verticalAlignment must be a string");
}
- } else if (name == "textMinDistance") {
- if (value.IsNumber()) {
- bucket.geometry.textMinDistance = value.GetDouble();
+ }
+
+ if (value.HasMember("translate")) {
+ JSVal property = value["translate"];
+ if (property.IsArray()) {
+ render.translate.x = property[(rapidjson::SizeType)0].GetDouble() * 24;
+ render.translate.y = property[(rapidjson::SizeType)1].GetDouble() * -24;
} else {
- throw Style::exception("text min distance must be a number");
+ throw Style::exception("translate must be a string");
}
- } else if (name == "maxAngleDelta") {
- if (value.IsNumber()) {
- bucket.geometry.maxAngleDelta = value.GetDouble();
+ }
+
+ if (value.HasMember("maxAngleDelta")) {
+ JSVal property = value["maxAngleDelta"];
+ if (property.IsNumber()) {
+ render.max_angle_delta = property.GetDouble();
} else {
throw Style::exception("max angle delta must be a number");
}
}
- }
+ if (value.HasMember("textMinDistance")) {
+ JSVal property = value["textMinDistance"];
+ if (property.IsNumber()) {
+ render.min_distance = property.GetDouble();
+ } else {
+ throw Style::exception("text min distance must be a number");
+ }
+ }
+ } break;
- if (value.HasMember("filter")) {
- bucket.filter = std::move(parseFilterOrExpression(value["filter"]));
- } else {
- // Allow a filter triple to be specified at the bucket root as well.
- bucket.filter = std::move(parseFilterOrExpression(value));
- }
+ case BucketType::Raster: {
+ bucket.render = BucketRasterDescription{};
+ } break;
- if (bucket.feature_type == BucketType::None) {
- bucket.feature_type = bucket.type;
+ default:
+ break;
}
return bucket;
diff --git a/src/text/placement.cpp b/src/text/placement.cpp
index b15e324965..112f1d79cf 100644
--- a/src/text/placement.cpp
+++ b/src/text/placement.cpp
@@ -244,19 +244,11 @@ void getGlyphs(PlacedGlyphs &glyphs, GlyphBoxes &boxes,
}
}
-void Placement::addFeature(TextBucket& bucket,
- const std::vector<Coordinate> &line,
- const BucketGeometryDescription &info,
- const GlyphPositions &face,
+void Placement::addFeature(TextBucket &bucket, const std::vector<Coordinate> &line,
+ const BucketTextDescription &info, const GlyphPositions &face,
const Shaping &shaping) {
-
const bool horizontal = info.path == TextPathType::Horizontal;
- const float padding = info.padding;
- const float maxAngleDelta = info.maxAngleDelta;
- const float textMinDistance = info.textMinDistance;
- const float rotate = info.rotate;
- const float fontScale =
- (tileExtent / util::tileSize) / (glyphSize / info.size);
+ const float fontScale = (tileExtent / util::tileSize) / (glyphSize / info.max_size);
Anchors anchors;
@@ -268,7 +260,7 @@ void Placement::addFeature(TextBucket& bucket,
} else {
// Line labels
- anchors = interpolate(line, textMinDistance, minScale);
+ anchors = interpolate(line, info.min_distance, minScale);
// Sort anchors by segment so that we can start placement with
// the anchors that can be shown at the lowest zoom levels.
@@ -279,11 +271,10 @@ void Placement::addFeature(TextBucket& bucket,
PlacedGlyphs glyphs;
GlyphBoxes boxes;
- getGlyphs(glyphs, boxes, anchor, info.translate, shaping, face, fontScale, horizontal,
- line, maxAngleDelta, rotate);
- PlacementProperty place =
- collision.place(boxes, anchor, anchor.scale, maxPlacementScale,
- padding, horizontal, info.alwaysVisible);
+ getGlyphs(glyphs, boxes, anchor, info.translate, shaping, face, fontScale, horizontal, line,
+ info.max_angle_delta, info.rotate);
+ PlacementProperty place = collision.place(boxes, anchor, anchor.scale, maxPlacementScale,
+ info.padding, horizontal, info.always_visible);
if (place) {
bucket.addGlyphs(glyphs, place.zoom, place.rotationRange, zoom - zOffset);
}