diff --git a/include/mbgl/style/style_properties.hpp b/include/mbgl/style/style_properties.hpp index 9ab528586fa..23354b1a24a 100644 --- a/include/mbgl/style/style_properties.hpp +++ b/include/mbgl/style/style_properties.hpp @@ -45,6 +45,20 @@ struct LineProperties { } }; +struct CircleProperties { + inline CircleProperties() {} + float radius = 5.0f; + Color color = {{ 0, 0, 0, 1 }}; + float opacity = 1.0f; + std::array translate = {{ 0, 0 }}; + TranslateAnchorType translateAnchor = TranslateAnchorType::Map; + float blur = 0; + + inline bool isVisible() const { + return radius > 0 && color[3] > 0 && opacity > 0; + } +}; + struct SymbolProperties { inline SymbolProperties() {} @@ -100,6 +114,7 @@ struct BackgroundProperties { typedef mapbox::util::variant< FillProperties, LineProperties, + CircleProperties, SymbolProperties, RasterProperties, BackgroundProperties, diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp index e46ece6f4a5..adc13b386c3 100644 --- a/include/mbgl/style/types.hpp +++ b/include/mbgl/style/types.hpp @@ -27,6 +27,7 @@ enum class StyleLayerType : uint8_t { Unknown, Fill, Line, + Circle, Symbol, Raster, Background @@ -36,6 +37,7 @@ MBGL_DEFINE_ENUM_CLASS(StyleLayerTypeClass, StyleLayerType, { { StyleLayerType::Unknown, "unknown" }, { StyleLayerType::Fill, "fill" }, { StyleLayerType::Line, "line" }, + { StyleLayerType::Circle, "circle" }, { StyleLayerType::Symbol, "symbol" }, { StyleLayerType::Raster, "raster" }, { StyleLayerType::Background, "background" }, diff --git a/src/mbgl/geometry/circle_buffer.cpp b/src/mbgl/geometry/circle_buffer.cpp new file mode 100644 index 00000000000..f4b0cddec30 --- /dev/null +++ b/src/mbgl/geometry/circle_buffer.cpp @@ -0,0 +1,13 @@ +#include + +#include + +#include + +using namespace mbgl; + +void CircleVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey) { + vertex_type *vertices = static_cast(addElement()); + vertices[0] = (x * 2) + ((ex + 1) / 2); + vertices[1] = (y * 2) + ((ey + 1) / 2); +} diff --git a/src/mbgl/geometry/circle_buffer.hpp b/src/mbgl/geometry/circle_buffer.hpp new file mode 100644 index 00000000000..cab9122e5b6 --- /dev/null +++ b/src/mbgl/geometry/circle_buffer.hpp @@ -0,0 +1,27 @@ +#ifndef MBGL_GEOMETRY_CIRCLE_BUFFER +#define MBGL_GEOMETRY_CIRCLE_BUFFER + +#include + +namespace mbgl { + +class CircleVertexBuffer : public Buffer< + 4 // 2 bytes per short * 4 of them. +> { +public: + typedef int16_t vertex_type; + + /* + * Add a vertex to this buffer + * + * @param {number} x vertex position + * @param {number} y vertex position + * @param {number} ex extrude normal + * @param {number} ey extrude normal + */ + void add(vertex_type x, vertex_type y, float ex, float ey); +}; + +} + +#endif // MBGL_GEOMETRY_CIRCLE_BUFFER diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp index 77dc5c22fa7..68b0e15dc4e 100644 --- a/src/mbgl/map/tile_worker.cpp +++ b/src/mbgl/map/tile_worker.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -139,15 +140,22 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr std::unique_ptr bucket; - if (styleBucket.type == StyleLayerType::Fill) { + switch (styleBucket.type) { + case StyleLayerType::Fill: bucket = createFillBucket(*geometryLayer, styleBucket); - } else if (styleBucket.type == StyleLayerType::Line) { + break; + case StyleLayerType::Line: bucket = createLineBucket(*geometryLayer, styleBucket); - } else if (styleBucket.type == StyleLayerType::Symbol) { + break; + case StyleLayerType::Circle: + bucket = createCircleBucket(*geometryLayer, styleBucket); + break; + case StyleLayerType::Symbol: bucket = createSymbolBucket(*geometryLayer, styleBucket); - } else if (styleBucket.type == StyleLayerType::Raster) { + break; + case StyleLayerType::Raster: return; - } else { + default: Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')", styleBucket.name.c_str(), styleBucket.source_layer.c_str()); } @@ -203,6 +211,17 @@ std::unique_ptr TileWorker::createLineBucket(const GeometryTileLayer& la return bucket->hasData() ? std::move(bucket) : nullptr; } +std::unique_ptr TileWorker::createCircleBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { + auto bucket = std::make_unique(circleVertexBuffer, + triangleElementsBuffer); + + // Circle does not have layout properties to apply. + + addBucketGeometries(bucket, layer, bucket_desc.filter); + return bucket->hasData() ? std::move(bucket) : nullptr; +} + std::unique_ptr TileWorker::createSymbolBucket(const GeometryTileLayer& layer, const StyleBucket& bucket_desc) { auto bucket = std::make_unique(*collision, id.overscaling); diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/map/tile_worker.hpp index da5c7665068..15a5487dc94 100644 --- a/src/mbgl/map/tile_worker.hpp +++ b/src/mbgl/map/tile_worker.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ class TileWorker : public util::noncopyable { std::unique_ptr createFillBucket(const GeometryTileLayer&, const StyleBucket&); std::unique_ptr createLineBucket(const GeometryTileLayer&, const StyleBucket&); + std::unique_ptr createCircleBucket(const GeometryTileLayer&, const StyleBucket&); std::unique_ptr createSymbolBucket(const GeometryTileLayer&, const StyleBucket&); template @@ -68,6 +70,7 @@ class TileWorker : public util::noncopyable { FillVertexBuffer fillVertexBuffer; LineVertexBuffer lineVertexBuffer; + CircleVertexBuffer circleVertexBuffer; TriangleElementsBuffer triangleElementsBuffer; LineElementsBuffer lineElementsBuffer; diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp new file mode 100644 index 00000000000..fde04df29a0 --- /dev/null +++ b/src/mbgl/renderer/circle_bucket.cpp @@ -0,0 +1,92 @@ +#include +#include + +#include + +using namespace mbgl; + +CircleBucket::CircleBucket(CircleVertexBuffer& vertexBuffer, + TriangleElementsBuffer& elementsBuffer) + : vertexBuffer_(vertexBuffer) + , elementsBuffer_(elementsBuffer) + , vertexStart_(vertexBuffer_.index()) + , elementsStart_(elementsBuffer_.index()) { +} + +CircleBucket::~CircleBucket() { + // Do not remove. header file only contains forward definitions to unique pointers. +} + +void CircleBucket::upload() { + vertexBuffer_.upload(); + elementsBuffer_.upload(); + uploaded = true; +} + +void CircleBucket::render(Painter& painter, + const StyleLayer& layer_desc, + const TileID& id, + const mat4& matrix) { + painter.renderCircle(*this, layer_desc, id, matrix); +} + +bool CircleBucket::hasData() const { + return !triangleGroups_.empty(); +} + +void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) { + for (auto& circle : geometryCollection) { + for(auto & geometry : circle) { + auto x = geometry.x; + auto y = geometry.y; + + // this geometry will be of the Point type, and we'll derive + // two triangles from it. + // + // ┌─────────┐ + // │ 4 3 │ + // │ │ + // │ 1 2 │ + // └─────────┘ + // + vertexBuffer_.add(x, y, -1, -1); // 1 + vertexBuffer_.add(x, y, 1, -1); // 2 + vertexBuffer_.add(x, y, 1, 1); // 3 + vertexBuffer_.add(x, y, -1, 1); // 4 + + if (!triangleGroups_.size() || (triangleGroups_.back()->vertex_length + 4 > 65535)) { + // Move to a new group because the old one can't hold the geometry. + triangleGroups_.emplace_back(std::make_unique()); + } + + TriangleGroup& group = *triangleGroups_.back(); + auto index = group.vertex_length; + + // 1, 2, 3 + // 1, 4, 3 + elementsBuffer_.add(index, index + 1, index + 2); + elementsBuffer_.add(index, index + 3, index + 2); + + group.vertex_length += 4; + group.elements_length += 2; + } + } +} + +void CircleBucket::drawCircles(CircleShader& shader) { + char* vertexIndex = BUFFER_OFFSET(vertexStart_ * vertexBuffer_.itemSize); + char* elementsIndex = BUFFER_OFFSET(elementsStart_ * elementsBuffer_.itemSize); + + for (auto& group : triangleGroups_) { + assert(group); + + if (!group->elements_length) continue; + + group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex); + + MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elementsIndex)); + + vertexIndex += group->vertex_length * vertexBuffer_.itemSize; + elementsIndex += group->elements_length * elementsBuffer_.itemSize; + } +} diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp new file mode 100644 index 00000000000..727b9fa3767 --- /dev/null +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -0,0 +1,46 @@ +#ifndef MBGL_RENDERER_CIRCLE_BUCKET +#define MBGL_RENDERER_CIRCLE_BUCKET + +#include + +#include + +#include +#include + +#include +#include + +namespace mbgl { + +class CircleVertexBuffer; +class CircleShader; + +class CircleBucket : public Bucket { + using TriangleGroup = ElementGroup<3>; + +public: + CircleBucket(CircleVertexBuffer &vertexBuffer, TriangleElementsBuffer &elementsBuffer); + ~CircleBucket() override; + + void upload() override; + void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; + + bool hasData() const; + void addGeometry(const GeometryCollection&); + + void drawCircles(CircleShader& shader); + +private: + CircleVertexBuffer& vertexBuffer_; + TriangleElementsBuffer& elementsBuffer_; + + const size_t vertexStart_; + const size_t elementsStart_; + + std::vector> triangleGroups_; +}; + +} // namespace mbgl + +#endif // MBGL_RENDERER_CIRCLE_BUCKET diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 1c6c69a7c9b..5ad3dbb4339 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,7 @@ void Painter::setup() { assert(sdfGlyphShader); assert(sdfIconShader); assert(dotShader); + assert(circleShader); // Blending @@ -100,6 +102,7 @@ void Painter::setupShaders() { if (!sdfIconShader) sdfIconShader = std::make_unique(); if (!dotShader) dotShader = std::make_unique(); if (!collisionBoxShader) collisionBoxShader = std::make_unique(); + if (!circleShader) circleShader = std::make_unique(); } void Painter::resize() { diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 34f48420b52..4e1113c232d 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -38,6 +38,7 @@ struct FrameData; class DebugBucket; class FillBucket; class LineBucket; +class CircleBucket; class SymbolBucket; class RasterBucket; @@ -50,6 +51,7 @@ class LineShader; class LinejoinShader; class LineSDFShader; class LinepatternShader; +class CircleShader; class PatternShader; class IconShader; class RasterShader; @@ -106,6 +108,7 @@ class Painter : private util::noncopyable { void renderDebugText(DebugBucket& bucket, const mat4 &matrix); void renderFill(FillBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix); void renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix); + void renderCircle(CircleBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix); void renderSymbol(SymbolBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix); void renderRaster(RasterBucket& bucket, const StyleLayer &layer_desc, const TileID& id, const mat4 &matrix); void renderBackground(const StyleLayer &layer_desc); @@ -227,6 +230,7 @@ class Painter : private util::noncopyable { std::unique_ptr sdfIconShader; std::unique_ptr dotShader; std::unique_ptr collisionBoxShader; + std::unique_ptr circleShader; StaticVertexBuffer backgroundBuffer = { { -1, -1 }, { 1, -1 }, diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp new file mode 100644 index 00000000000..0c0ac15069f --- /dev/null +++ b/src/mbgl/renderer/painter_circle.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +using namespace mbgl; + +void Painter::renderCircle(CircleBucket& bucket, + const StyleLayer& layer_desc, + const TileID& id, + const mat4& matrix) { + // Abort early. + if (pass == RenderPass::Opaque) return; + + config.stencilTest = false; + + const CircleProperties& properties = layer_desc.getProperties(); + mat4 vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor); + + Color color = properties.color; + color[0] *= properties.opacity; + color[1] *= properties.opacity; + color[2] *= properties.opacity; + color[3] *= properties.opacity; + + // Antialiasing factor: this is a minimum blur distance that serves as + // a faux-antialiasing for the circle. since blur is a ratio of the circle's + // size and the intent is to keep the blur at roughly 1px, the two + // are inversely related. + float antialiasing = 1 / data.pixelRatio / properties.radius; + + useProgram(circleShader->program); + + circleShader->u_matrix = vtxMatrix; + circleShader->u_exmatrix = projMatrix; + circleShader->u_color = color; + circleShader->u_blur = std::max(properties.blur, antialiasing); + circleShader->u_size = properties.radius; + + bucket.drawCircles(*circleShader); +} diff --git a/src/mbgl/shader/circle.fragment.glsl b/src/mbgl/shader/circle.fragment.glsl new file mode 100644 index 00000000000..7267bf81e3b --- /dev/null +++ b/src/mbgl/shader/circle.fragment.glsl @@ -0,0 +1,10 @@ +uniform vec4 u_color; +uniform float u_blur; +uniform float u_size; + +varying vec2 v_extrude; + +void main() { + float t = smoothstep(1.0 - u_blur, 1.0, length(v_extrude)); + gl_FragColor = u_color * (1.0 - t); +} diff --git a/src/mbgl/shader/circle.vertex.glsl b/src/mbgl/shader/circle.vertex.glsl new file mode 100644 index 00000000000..eeeb30abc5b --- /dev/null +++ b/src/mbgl/shader/circle.vertex.glsl @@ -0,0 +1,23 @@ +// set by gl_util +uniform float u_size; + +attribute vec2 a_pos; + +uniform mat4 u_matrix; +uniform mat4 u_exmatrix; + +varying vec2 v_extrude; + +void main(void) { + // unencode the extrusion vector that we snuck into the a_pos vector + v_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0); + + vec4 extrude = u_exmatrix * vec4(v_extrude * u_size, 0, 0); + // multiply a_pos by 0.5, since we had it * 2 in order to sneak + // in extrusion data + gl_Position = u_matrix * vec4(a_pos * 0.5, 0, 1); + + // gl_Position is divided by gl_Position.w after this shader runs. + // Multiply the extrude by it so that it isn't affected by it. + gl_Position += extrude * gl_Position.w; +} diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp new file mode 100644 index 00000000000..074f92d68b2 --- /dev/null +++ b/src/mbgl/shader/circle_shader.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +#include + +using namespace mbgl; + +CircleShader::CircleShader() + : Shader( + "circle", + shaders[CIRCLE_SHADER].vertex, + shaders[CIRCLE_SHADER].fragment + ) { + a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_pos")); +} + +void CircleShader::bind(char *offset) { + MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos)); + MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 4, offset)); +} diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp new file mode 100644 index 00000000000..545a0baad5c --- /dev/null +++ b/src/mbgl/shader/circle_shader.hpp @@ -0,0 +1,27 @@ +#ifndef MBGL_SHADER_CIRCLE_SHADER +#define MBGL_SHADER_CIRCLE_SHADER + +#include +#include + +namespace mbgl { + +class CircleShader : public Shader { +public: + CircleShader(); + + void bind(char *offset); + + UniformMatrix<4> u_matrix = {"u_matrix", *this}; + UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this}; + Uniform> u_color = {"u_color", *this}; + Uniform u_size = {"u_size", *this}; + Uniform u_blur = {"u_blur", *this}; + +private: + int32_t a_pos = -1; +}; + +} + +#endif // MBGL_SHADER_CIRCLE_SHADER diff --git a/src/mbgl/style/property_fallback.cpp b/src/mbgl/style/property_fallback.cpp index 091c12e5d85..74dd247b03a 100644 --- a/src/mbgl/style/property_fallback.cpp +++ b/src/mbgl/style/property_fallback.cpp @@ -21,6 +21,13 @@ const std::map PropertyFallbackValue::properties = { { PropertyKey::LineGapWidth, defaultStyleProperties().gap_width }, { PropertyKey::LineBlur, defaultStyleProperties().blur }, + { PropertyKey::CircleRadius, defaultStyleProperties().radius }, + { PropertyKey::CircleColor, defaultStyleProperties().color }, + { PropertyKey::CircleOpacity, defaultStyleProperties().opacity }, + { PropertyKey::CircleTranslate, defaultStyleProperties().translate }, + { PropertyKey::CircleTranslateAnchor, defaultStyleProperties().translateAnchor }, + { PropertyKey::CircleBlur, defaultStyleProperties().blur }, + { PropertyKey::IconOpacity, defaultStyleProperties().icon.opacity }, { PropertyKey::IconSize, defaultStyleProperties().icon.size }, { PropertyKey::IconColor, defaultStyleProperties().icon.color }, diff --git a/src/mbgl/style/property_key.hpp b/src/mbgl/style/property_key.hpp index 015ea1aa630..e7ddef51c35 100644 --- a/src/mbgl/style/property_key.hpp +++ b/src/mbgl/style/property_key.hpp @@ -27,6 +27,13 @@ enum class PropertyKey { LineMiterLimit, LineRoundLimit, + CircleRadius, + CircleColor, + CircleOpacity, + CircleTranslate, + CircleTranslateAnchor, + CircleBlur, + SymbolPlacement, SymbolSpacing, SymbolAvoidEdges, diff --git a/src/mbgl/style/style_layer.cpp b/src/mbgl/style/style_layer.cpp index 5fc6af793ce..33fe3285ab0 100644 --- a/src/mbgl/style/style_layer.cpp +++ b/src/mbgl/style/style_layer.cpp @@ -19,6 +19,8 @@ bool StyleLayer::isVisible() const { return getProperties().isVisible(); case StyleLayerType::Line: return getProperties().isVisible(); + case StyleLayerType::Circle: + return getProperties().isVisible(); case StyleLayerType::Symbol: return getProperties().isVisible(); case StyleLayerType::Raster: @@ -204,6 +206,18 @@ void StyleLayer::applyStyleProperties(const float z, const TimeP applyStyleProperty(PropertyKey::LineWidth, line.dash_line_width, std::floor(z), now, zoomHistory); } +template <> +void StyleLayer::applyStyleProperties(const float z, const TimePoint& now, const ZoomHistory &zoomHistory) { + properties.set(); + CircleProperties& circle = properties.get(); + applyTransitionedStyleProperty(PropertyKey::CircleRadius, circle.radius, z, now, zoomHistory); + applyTransitionedStyleProperty(PropertyKey::CircleColor, circle.color, z, now, zoomHistory); + applyTransitionedStyleProperty(PropertyKey::CircleOpacity, circle.opacity, z, now, zoomHistory); + applyTransitionedStyleProperty(PropertyKey::CircleTranslate, circle.translate, z, now, zoomHistory); + applyStyleProperty(PropertyKey::CircleTranslateAnchor, circle.translateAnchor, z, now, zoomHistory); + applyTransitionedStyleProperty(PropertyKey::CircleBlur, circle.blur, z, now, zoomHistory); +} + template <> void StyleLayer::applyStyleProperties(const float z, const TimePoint& now, const ZoomHistory &zoomHistory) { properties.set(); @@ -255,6 +269,7 @@ void StyleLayer::updateProperties(float z, const TimePoint& now, ZoomHistory &zo switch (type) { case StyleLayerType::Fill: applyStyleProperties(z, now, zoomHistory); break; case StyleLayerType::Line: applyStyleProperties(z, now, zoomHistory); break; + case StyleLayerType::Circle: applyStyleProperties(z, now, zoomHistory); break; case StyleLayerType::Symbol: applyStyleProperties(z, now, zoomHistory); break; case StyleLayerType::Raster: applyStyleProperties(z, now, zoomHistory); break; case StyleLayerType::Background: applyStyleProperties(z, now, zoomHistory); break; diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index b9ba61ee229..cd5211aaf62 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -834,6 +834,13 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty>>>("line-dasharray", Key::LineDashArray, klass, value, "line-dasharray-transition"); parseOptionalProperty>>("line-pattern", Key::LineImage, klass, value, "line-pattern-transition"); + parseOptionalProperty>("circle-radius", Key::CircleRadius, klass, value); + parseOptionalProperty>("circle-color", Key::CircleColor, klass, value); + parseOptionalProperty>("circle-opacity", Key::CircleOpacity, klass, value); + parseOptionalProperty>>("circle-translate", Key::CircleTranslate, klass, value); + parseOptionalProperty>("circle-translate-anchor", Key::CircleTranslateAnchor, klass, value); + parseOptionalProperty>("circle-blur", Key::CircleBlur, klass, value); + parseOptionalProperty>("icon-opacity", Key::IconOpacity, klass, value); parseOptionalProperty("icon-opacity-transition", Key::IconOpacity, klass, value); parseOptionalProperty>("icon-size", Key::IconSize, klass, value); diff --git a/src/mbgl/style/style_properties.cpp b/src/mbgl/style/style_properties.cpp index 3c5b525c1d4..aa4c7e29c7f 100644 --- a/src/mbgl/style/style_properties.cpp +++ b/src/mbgl/style/style_properties.cpp @@ -5,6 +5,7 @@ namespace mbgl { template<> const FillProperties &defaultStyleProperties() { static const FillProperties p; return p; } template<> const LineProperties &defaultStyleProperties() { static const LineProperties p; return p; } +template<> const CircleProperties &defaultStyleProperties() { static const CircleProperties p; return p; } template<> const SymbolProperties &defaultStyleProperties() { static const SymbolProperties p; return p; } template<> const RasterProperties &defaultStyleProperties() { static const RasterProperties p; return p; } template<> const BackgroundProperties &defaultStyleProperties() { static const BackgroundProperties p; return p; } diff --git a/test/fixtures/style_parser/circle-blur.info.json b/test/fixtures/style_parser/circle-blur.info.json new file mode 100644 index 00000000000..397e4cd4d18 --- /dev/null +++ b/test/fixtures/style_parser/circle-blur.info.json @@ -0,0 +1,7 @@ +{ + "default": { + "log": [ + [1, "WARNING", "ParseStyle", "value of 'circle-blur' must be a number, or a number function"] + ] + } +} diff --git a/test/fixtures/style_parser/circle-blur.style.json b/test/fixtures/style_parser/circle-blur.style.json new file mode 100644 index 00000000000..8140ad5e47c --- /dev/null +++ b/test/fixtures/style_parser/circle-blur.style.json @@ -0,0 +1,18 @@ +{ + "version": 8, + "sources": { + "mapbox": { + "type": "vector", + "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5", + "maxzoom": 14 + } + }, + "layers": [{ + "id": "circle_blur_example", + "type": "circle", + "source": "mapbox", + "paint": { + "circle-blur": null + } + }] +} diff --git a/test/fixtures/style_parser/circle-color.info.json b/test/fixtures/style_parser/circle-color.info.json new file mode 100644 index 00000000000..b1708c2f051 --- /dev/null +++ b/test/fixtures/style_parser/circle-color.info.json @@ -0,0 +1,7 @@ +{ + "default": { + "log": [ + [1, "WARNING", "ParseStyle", "color value must be a string"] + ] + } +} diff --git a/test/fixtures/style_parser/circle-color.style.json b/test/fixtures/style_parser/circle-color.style.json new file mode 100644 index 00000000000..44c32f99cea --- /dev/null +++ b/test/fixtures/style_parser/circle-color.style.json @@ -0,0 +1,18 @@ +{ + "version": 8, + "sources": { + "mapbox": { + "type": "vector", + "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5", + "maxzoom": 14 + } + }, + "layers": [{ + "id": "circle_color_example", + "type": "circle", + "source": "mapbox", + "paint": { + "circle-color": null + } + }] +} diff --git a/test/fixtures/style_parser/circle-opacity.info.json b/test/fixtures/style_parser/circle-opacity.info.json new file mode 100644 index 00000000000..3e8662bdbe2 --- /dev/null +++ b/test/fixtures/style_parser/circle-opacity.info.json @@ -0,0 +1,7 @@ +{ + "default": { + "log": [ + [1, "WARNING", "ParseStyle", "value of 'circle-opacity' must be a number, or a number function"] + ] + } +} diff --git a/test/fixtures/style_parser/circle-opacity.style.json b/test/fixtures/style_parser/circle-opacity.style.json new file mode 100644 index 00000000000..601e81a51b1 --- /dev/null +++ b/test/fixtures/style_parser/circle-opacity.style.json @@ -0,0 +1,18 @@ +{ + "version": 8, + "sources": { + "mapbox": { + "type": "vector", + "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5", + "maxzoom": 14 + } + }, + "layers": [{ + "id": "circle_opacity_example", + "type": "circle", + "source": "mapbox", + "paint": { + "circle-opacity": null + } + }] +} diff --git a/test/fixtures/style_parser/circle-radius.info.json b/test/fixtures/style_parser/circle-radius.info.json new file mode 100644 index 00000000000..7e87aa4fdbc --- /dev/null +++ b/test/fixtures/style_parser/circle-radius.info.json @@ -0,0 +1,7 @@ +{ + "default": { + "log": [ + [1, "WARNING", "ParseStyle", "value of 'circle-radius' must be a number, or a number function"] + ] + } +} diff --git a/test/fixtures/style_parser/circle-radius.style.json b/test/fixtures/style_parser/circle-radius.style.json new file mode 100644 index 00000000000..a7fb28b2d38 --- /dev/null +++ b/test/fixtures/style_parser/circle-radius.style.json @@ -0,0 +1,18 @@ +{ + "version": 8, + "sources": { + "mapbox": { + "type": "vector", + "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5", + "maxzoom": 14 + } + }, + "layers": [{ + "id": "circle_radius_example", + "type": "circle", + "source": "mapbox", + "paint": { + "circle-radius": null + } + }] +} diff --git a/test/suite b/test/suite index af7481f223a..303b18c915c 160000 --- a/test/suite +++ b/test/suite @@ -1 +1 @@ -Subproject commit af7481f223acec41421bcf9ec944651216c1358c +Subproject commit 303b18c915c708fd9f0eb1bd98a9262ff5f07645