diff --git a/include/llmr/geometry/glyph_atlas.hpp b/include/llmr/geometry/glyph_atlas.hpp index 5bcd573f5..0aada6a73 100644 --- a/include/llmr/geometry/glyph_atlas.hpp +++ b/include/llmr/geometry/glyph_atlas.hpp @@ -12,8 +12,6 @@ namespace llmr { -class VectorTileGlyph; - class GlyphAtlas { public: diff --git a/include/llmr/geometry/sprite_atlas.hpp b/include/llmr/geometry/sprite_atlas.hpp index 220edc701..13b85e548 100644 --- a/include/llmr/geometry/sprite_atlas.hpp +++ b/include/llmr/geometry/sprite_atlas.hpp @@ -62,7 +62,7 @@ private: BinPack bin; std::map> images; std::set uninitialized; - char *data = nullptr; + uint32_t *data = nullptr; std::atomic dirty; uint32_t texture = 0; uint32_t filter = 0; diff --git a/include/llmr/map/tile_parser.hpp b/include/llmr/map/tile_parser.hpp index 5785c29b3..84bb65e12 100644 --- a/include/llmr/map/tile_parser.hpp +++ b/include/llmr/map/tile_parser.hpp @@ -42,7 +42,6 @@ private: GlyphAtlas& glyphAtlas; GlyphStore &glyphStore; SpriteAtlas &spriteAtlas; - Faces faces; Placement placement; }; diff --git a/include/llmr/map/vector_tile.hpp b/include/llmr/map/vector_tile.hpp index f57c5d350..1e809556e 100644 --- a/include/llmr/map/vector_tile.hpp +++ b/include/llmr/map/vector_tile.hpp @@ -83,38 +83,9 @@ public: uint32_t extent = 4096; std::vector keys; std::vector values; - std::vector faces; std::map> shaping; }; -class VectorTileGlyph { -public: - VectorTileGlyph(); - VectorTileGlyph(pbf data); - - uint32_t id = 0; - - // A signed distance field of the glyph with a border of 3 pixels. - std::string bitmap; - - // Glyph metrics - GlyphMetrics metrics; -}; - -std::ostream& operator<<(std::ostream&, const VectorTileGlyph& glyph); - -class VectorTileFace { -public: - VectorTileFace(pbf data); - - std::string name; - std::string family; - std::string style; - std::vector glyphs; -}; - -std::ostream& operator<<(std::ostream&, const VectorTileFace& face); - class VectorTile { public: VectorTile(); @@ -122,7 +93,6 @@ public: VectorTile& operator=(VectorTile&& other); std::map layers; - std::map faces; }; diff --git a/include/llmr/renderer/text_bucket.hpp b/include/llmr/renderer/text_bucket.hpp index ad282bdd0..36c50ae7f 100644 --- a/include/llmr/renderer/text_bucket.hpp +++ b/include/llmr/renderer/text_bucket.hpp @@ -36,9 +36,9 @@ public: void addGlyphs(const PlacedGlyphs &glyphs, float placementZoom, PlacementRange placementRange, float zoom); - void addFeature(const VectorTileFeature &feature, + void addFeature(const pbf &geometry, const GlyphPositions &face, - const std::map &shapings); + const Shaping &shaping); void drawGlyphs(TextShader &shader); diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index b8ffcfad6..d0bc3b2d4 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -128,6 +128,7 @@ struct IconClass : public GenericClass { }; struct IconProperties : public GenericProperties { + inline IconProperties() : GenericProperties() {} float size = 0; Color color = {{ 1, 1, 1, 1 }}; std::string image; @@ -147,6 +148,7 @@ struct LineClass : public GenericClass { }; struct LineProperties : public GenericProperties { + inline LineProperties() : GenericProperties() {} float width = 0; float offset = 0; Color color = {{ 0, 0, 0, 1 }}; @@ -164,6 +166,7 @@ struct FillClass : public GenericClass { }; struct FillProperties : public GenericProperties { + inline FillProperties() : GenericProperties() {} Winding winding = Winding::NonZero; bool antialias = true; Color fill_color = {{ 0, 0, 0, 1 }}; @@ -187,6 +190,7 @@ struct TextClass : public GenericClass { }; struct TextProperties : public GenericProperties { + inline TextProperties() : GenericProperties() {} Color color = {{ 0, 0, 0, 1 }}; Color halo = {{ 1, 1, 1, 0.75 }}; float halo_radius = 0.25f; @@ -202,6 +206,7 @@ struct BackgroundClass : public GenericClass { }; struct BackgroundProperties : public GenericProperties { + inline BackgroundProperties() : GenericProperties() {} Color color = {{ 1, 1, 1, 1 }}; }; @@ -209,6 +214,7 @@ struct RasterClass : public GenericClass { }; struct RasterProperties : public GenericProperties { + inline RasterProperties() : GenericProperties() {} }; struct CompositeClass : public GenericClass { @@ -219,6 +225,12 @@ struct CompositeProperties : public GenericProperties { }; +const IconProperties defaultIconProperties; +const LineProperties defaultLineProperties; +const FillProperties defaultFillProperties; +const TextProperties defaultTextProperties; +const BackgroundProperties defaultBackgroundProperties; +const RasterProperties defaultRasterProperties; const CompositeProperties defaultCompositeProperties; } diff --git a/include/llmr/text/glyph.hpp b/include/llmr/text/glyph.hpp index c13088c41..a5775b87d 100644 --- a/include/llmr/text/glyph.hpp +++ b/include/llmr/text/glyph.hpp @@ -43,8 +43,6 @@ struct Glyph { }; typedef std::map GlyphPositions; -typedef std::map Faces; -typedef std::vector IndexedFaces; class GlyphPlacement { public: diff --git a/ios/Info.plist b/ios/Info.plist index d78b5428e..9c96d492a 100644 --- a/ios/Info.plist +++ b/ios/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.mapbox.llmr.native + com.mapbox.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/ios/MVKMapKit b/ios/MVKMapKit index 9c3aa2d91..7c7bb2310 160000 --- a/ios/MVKMapKit +++ b/ios/MVKMapKit @@ -1 +1 @@ -Subproject commit 9c3aa2d919f2a76d5fef2500a3ee624b57a11383 +Subproject commit 7c7bb2310216a8d18108db40b09db08732df1f88 diff --git a/proto/vector_tile.proto b/proto/vector_tile.proto index e982c1a01..ea482adb2 100644 --- a/proto/vector_tile.proto +++ b/proto/vector_tile.proto @@ -75,43 +75,6 @@ message feature { optional uint32 vertex_count = 6; } -// Stores a glyph with metrics and optional SDF bitmap information. -message glyph { - required uint32 id = 1; - - // A signed distance field of the glyph with a border of 3 pixels. - optional bytes bitmap = 2; - - // Glyph metrics. - required uint32 width = 3; - required uint32 height = 4; - required sint32 left = 5; - required sint32 top = 6; - required uint32 advance = 7; -} - -// Stores font face information and a list of glyphs. -message face { - required string family = 1; - required string style = 2; - repeated glyph glyphs = 5; -} - -// Stores the shaping information for the label with a given text -message label { - // The original value ID this shaping information is for. - required uint32 text = 1; - - // References the index of the font stack in the layer's fontstack array. - required uint32 stack = 2; - - // Parallel arrays of face ID, glyph ID and position. - repeated uint32 faces = 3 [packed = true]; - repeated uint32 glyphs = 4 [packed = true]; - repeated uint32 x = 5 [packed = true]; - repeated uint32 y = 6 [packed = true]; -} - message layer { // Any compliant implementation must first read the version // number encoded in this message and choose the correct @@ -136,18 +99,11 @@ message layer { // Total vertex count in this layer. optional uint32 vertex_count = 6; - // Shaping information for labels contained in this tile. - repeated string faces = 7; - repeated label labels = 8; - repeated string stacks = 9; - extensions 16 to max; } message tile { repeated layer layers = 3; - repeated face faces = 4; - extensions 16 to 8191; } diff --git a/src/geometry/glyph_atlas.cpp b/src/geometry/glyph_atlas.cpp index f4defac69..afb904407 100644 --- a/src/geometry/glyph_atlas.cpp +++ b/src/geometry/glyph_atlas.cpp @@ -137,6 +137,8 @@ void GlyphAtlas::bind() { glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); dirty = false; +#if defined(DEBUG) // platform::show_debug_image("Glyph Atlas", data, width, height); +#endif } }; diff --git a/src/geometry/sprite_atlas.cpp b/src/geometry/sprite_atlas.cpp index 35f6f4588..bb514502b 100644 --- a/src/geometry/sprite_atlas.cpp +++ b/src/geometry/sprite_atlas.cpp @@ -30,24 +30,36 @@ bool SpriteAtlas::resize(const float newRatio) { pixelRatio = newRatio; if (data) { - char *old_data = data; + uint32_t *old_data = data; data = nullptr; allocate(); - dimension w = static_cast(width * newRatio); - dimension h = static_cast(height * newRatio); - float s = std::pow(oldRatio / newRatio, 2); + const int old_w = width * oldRatio; + const int old_h = height * oldRatio; + const int new_w = width * newRatio; + const int new_h = height * newRatio; // Basic image scaling. TODO: Replace this with better image scaling. uint32_t *img_new = reinterpret_cast(data); - uint32_t *img_old = reinterpret_cast(old_data); - for (size_t i = 0, length = w * h; i < length; i++) { - img_new[i] = img_old[static_cast(s * i)]; + const uint32_t *img_old = reinterpret_cast(old_data); + + for (int y = 0; y < new_h; y++) { + const int old_yoffset = ((y * old_h) / new_h) * old_w; + const int new_yoffset = y * new_w; + for (int x = 0; x < new_w; x++) { + const int old_x = (x * old_w) / new_w; + img_new[new_yoffset + x] = img_old[old_yoffset + old_x]; + } } free(old_data); dirty = true; + + // Mark all sprite images as in need of update + for (const auto &pair : images) { + uninitialized.emplace(pair.first); + } } return dirty; @@ -185,7 +197,7 @@ void SpriteAtlas::allocate() { if (!data) { dimension w = static_cast(width * pixelRatio); dimension h = static_cast(height * pixelRatio); - data = (char *)calloc(w * h, sizeof(uint32_t)); + data = (uint32_t *)calloc(w * h, sizeof(uint32_t)); } } @@ -270,8 +282,9 @@ void SpriteAtlas::bind(bool linear) { data // const GLvoid * data ); +#if defined(DEBUG) // platform::show_color_debug_image("Sprite Atlas", data, width, height, width * pixelRatio, height * pixelRatio); - +#endif dirty = false; } }; diff --git a/src/map/map.cpp b/src/map/map.cpp index 7ac6dbe0e..71ce0e938 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -479,8 +479,9 @@ void Map::prepare() { } void Map::render() { +#if defined(DEBUG) std::vector debug; - +#endif painter.clear(); painter.resetFramebuffer(); @@ -493,6 +494,7 @@ void Map::render() { painter.drawClippingMasks(sources); +#if defined(DEBUG) // Generate debug information size_t source_id = 0; for (const auto &pair : sources) { @@ -501,7 +503,7 @@ void Map::render() { debug.emplace_back(util::sprintf<100>("source %d: %d\n", source_id, count)); source_id++; } - +#endif // Actually render the layers if (debug::renderTree) { std::cout << "{" << std::endl; indent++; } renderLayers(style.layers); @@ -520,7 +522,9 @@ void Map::render() { painter.renderMatte(); +#if defined(DEBUG) painter.renderDebugText(debug); +#endif // Schedule another rerender when we definitely need a next frame. if (transform.needsTransition()) { @@ -573,19 +577,25 @@ void Map::renderLayers(const std::vector& layers) { template typename Styles::const_iterator find_style(const Styles &styles, const LayerDescription &layer_desc) { auto it = styles.find(layer_desc.name); +#if defined(DEBUG) if (it == styles.end()) { if (debug::renderWarnings) { fprintf(stderr, "[WARNING] can't find class named '%s' in style\n", layer_desc.name.c_str()); } } +#endif return it; } template bool is_invisible(const Styles &styles, const LayerDescription &layer_desc) { auto it = find_style(styles, layer_desc); - if (it == styles.end()) { return true; } + if (it == styles.end()) { + // We don't have a style, so we fall back to the default style which is + // always visible. + return false; + } return !it->second.isVisible(); } diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 9ad752526..2c8a47deb 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -42,7 +42,9 @@ void TileData::request() { // Schedule tile parsing in another thread tile->reparse(); } else { +#if defined(DEBUG) fprintf(stderr, "[%s] tile loading failed: %d, %s\n", tile->url.c_str(), res->code, res->error_message.c_str()); +#endif } }, map.getLoop()); } diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp index 2d47542d9..38ec86484 100644 --- a/src/map/tile_parser.cpp +++ b/src/map/tile_parser.cpp @@ -15,8 +15,6 @@ #include #include -#include - using namespace llmr; TileParser::TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, GlyphStore &glyphStore, SpriteAtlas &spriteAtlas) @@ -201,11 +199,8 @@ std::unique_ptr TileParser::createTextBucket(const VectorTileLayer& laye // Create a copy! const FontStack &fontStack = glyphStore.getFontStack(bucket_desc.geometry.font); - std::map shaping; GlyphPositions face; - // std::cerr << bucket_desc; - // Shape and place all labels. { FilteredVectorTileLayer filtered_layer(layer, bucket_desc); @@ -222,23 +217,21 @@ std::unique_ptr TileParser::createTextBucket(const VectorTileLayer& laye continue; } - const std::u32string string = ucs4conv.convert(toString(it_prop->second)); + const std::string source_string = toString(it_prop->second); + const std::u32string string = ucs4conv.convert(source_string); // Shape labels. - const Shaping shaped = fontStack.getShaping(string, bucket_desc.geometry.max_width, + const Shaping shaping = fontStack.getShaping(string, bucket_desc.geometry.max_width, bucket_desc.geometry.line_height, bucket_desc.geometry.alignment, bucket_desc.geometry.vertical_alignment, bucket_desc.geometry.letter_spacing); - shaping.emplace(toString(it_prop->second), shaped); // Place labels. addGlyph(tile.id.to_uint64(), bucket_desc.geometry.font, string, fontStack, glyphAtlas, face); + + bucket->addFeature(feature.geometry, face, shaping); } } - // It looks like nearly the same interface through the rest - // of the stack. - addBucketFeatures(bucket, layer, bucket_desc, face, shaping); - return std::move(bucket); } diff --git a/src/map/vector_tile.cpp b/src/map/vector_tile.cpp index 248e94712..f0f5a85cd 100644 --- a/src/map/vector_tile.cpp +++ b/src/map/vector_tile.cpp @@ -70,9 +70,6 @@ VectorTile::VectorTile(pbf tile) { if (tile.tag == 3) { // layer VectorTileLayer layer(tile.message()); layers.emplace(layer.name, std::forward(layer)); - } else if (tile.tag == 4) { // face - VectorTileFace face(tile.message()); - faces.emplace(face.name, std::forward(face)); } else { tile.skip(); } @@ -86,100 +83,8 @@ VectorTile& VectorTile::operator=(VectorTile && other) { return *this; } -VectorTileFace::VectorTileFace(pbf face) { - while (face.next()) { - if (face.tag == 1) { // family - family = face.string(); - } else if (face.tag == 2) { // style - style = face.string(); - } else if (face.tag == 5) { // glyphs - glyphs.emplace_back(face.message()); - } else { - face.skip(); - } - } - name = family + " " + style; -} - - -std::ostream& llmr::operator<<(std::ostream& os, const VectorTileFace& face) { - os << "Face: " << face.name << std::endl; - for (const VectorTileGlyph& glyph : face.glyphs) { - os << " - " << glyph; - } - return os; -} - - -// -1 overflows to maximum value -VectorTileGlyph::VectorTileGlyph() {} - -VectorTileGlyph::VectorTileGlyph(pbf glyph) { - while (glyph.next()) { - if (glyph.tag == 1) { // id - id = glyph.varint(); - } else if (glyph.tag == 2) { // bitmap - bitmap = glyph.string(); - } else if (glyph.tag == 3) { // width - metrics.width = glyph.varint(); - } else if (glyph.tag == 4) { // height - metrics.height = glyph.varint(); - } else if (glyph.tag == 5) { // left - metrics.left = glyph.svarint(); - } else if (glyph.tag == 6) { // top - metrics.top = glyph.svarint(); - } else if (glyph.tag == 7) { // advance - metrics.advance = glyph.varint(); - } else { - glyph.skip(); - } - } -} - -std::ostream& llmr::operator<<(std::ostream& os, const VectorTileGlyph& glyph) { - os << "Glyph " << glyph.id << ": " << glyph.metrics.width << "x" << glyph.metrics.height << - " (" << glyph.metrics.left << "/" << glyph.metrics.top << ") +" << glyph.metrics.advance << std::endl; - return os; -} - -class VectorTileLabel { -public: - VectorTileLabel(pbf data); - - uint32_t text = 0; - uint32_t stack = 0; - std::vector placements; -}; - -VectorTileLabel::VectorTileLabel(pbf label) { - pbf faces, glyphs, x, y; - - while (label.next()) { - if (label.tag == 1) { // text - text = label.varint(); - } else if (label.tag == 2) { // stack - stack = label.varint(); - } else if (label.tag == 3) { // faces - faces = label.message(); - } else if (label.tag == 4) { // glyphs - glyphs = label.message(); - } else if (label.tag == 5) { // x - x = label.message(); - } else if (label.tag == 6) { // y - y = label.message(); - } else { - label.skip(); - } - } - - while (faces && glyphs && x && y) { - placements.emplace_back(faces.varint(), glyphs.varint(), x.varint(), y.varint()); - } -} - VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { std::vector stacks; - std::vector labels; while (layer.next()) { if (layer.tag == 1) { // name @@ -190,34 +95,10 @@ VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { values.emplace_back(std::move(parseValue(layer.message()))); } else if (layer.tag == 5) { // extent extent = layer.varint(); - } else if (layer.tag == 7) { // faces - faces.emplace_back(layer.string()); - } else if (layer.tag == 8) { // labels - labels.emplace_back(layer.message()); - } else if (layer.tag == 9) { // stacks - stacks.emplace_back(layer.string()); } else { layer.skip(); } } - - // Build index of [stack][text] => shaping information - for (VectorTileLabel& label : labels) { - if (values.size() <= label.text || stacks.size() <= label.stack) { - // The indices are out of range. Skip this label. - continue; - } - - const Value& text = values[label.text]; - const std::string& stack = stacks[label.stack]; - - shaping[stack][text].swap(label.placements); - } -} - -std::ostream& llmr::operator<<(std::ostream& os, const GlyphPlacement& placement) { - os << "Glyph " << placement.face << "/" << placement.glyph << ": " << placement.x << "/" << placement.y << std::endl; - return os; } FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer, const BucketDescription& bucket_desc) diff --git a/src/map/vector_tile_data.cpp b/src/map/vector_tile_data.cpp index 3c972aa31..4a1e91f41 100644 --- a/src/map/vector_tile_data.cpp +++ b/src/map/vector_tile_data.cpp @@ -24,7 +24,9 @@ void VectorTileData::parse() { // is going to be discarded afterwards. TileParser parser(data, *this, map.getStyle(), map.getGlyphAtlas(), map.getGlyphStore(), map.getSpriteAtlas()); } catch (const std::exception& ex) { +#if defined(DEBUG) fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); +#endif cancel(); return; } diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index 2a4e1c78a..702156659 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -182,18 +182,24 @@ void FillBucket::tessellate() { if (a != TESS_UNDEF && b != TESS_UNDEF && c != TESS_UNDEF) { triangleElementsBuffer.add(triangleIndex + a, triangleIndex + b, triangleIndex + c); } else { +#if defined(DEBUG) // TODO: We're missing a vertex that was not part of the line. fprintf(stderr, "undefined element buffer\n"); +#endif } } else { +#if defined(DEBUG) fprintf(stderr, "undefined element buffer\n"); +#endif } } triangleGroup.vertex_length += total_vertex_count; triangleGroup.elements_length += triangle_count; } else { +#if defined(DEBUG) fprintf(stderr, "tessellation failed\n"); +#endif } // We're adding the total vertex count *after* we added additional vertices diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 82808f4d1..b755301eb 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -1,13 +1,13 @@ #include - #include - #include #include -#include #include #include #include +#if defined(DEBUG) +#include +#endif #include #include @@ -29,8 +29,9 @@ bool Painter::needsAnimation() const { } void Painter::setup() { +#if defined(DEBUG) util::timer timer("painter setup"); - +#endif setupShaders(); assert(iconShader); diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index cd7b0780d..d0ba2a8de 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -146,9 +146,10 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons const std::unordered_map &fill_properties = map.getStyle().computed.fills; const std::unordered_map::const_iterator fill_properties_it = fill_properties.find(layer_name); - if (fill_properties_it == fill_properties.end()) return; - const FillProperties& properties = fill_properties_it->second; + const FillProperties &properties = fill_properties_it != fill_properties.end() + ? fill_properties_it->second + : defaultFillProperties; if (!properties.enabled) return; diff --git a/src/renderer/painter_icon.cpp b/src/renderer/painter_icon.cpp index 382312c12..51bb88fb2 100644 --- a/src/renderer/painter_icon.cpp +++ b/src/renderer/painter_icon.cpp @@ -13,9 +13,10 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons const std::unordered_map &icon_properties = map.getStyle().computed.icons; const std::unordered_map::const_iterator icon_properties_it = icon_properties.find(layer_name); - if (icon_properties_it == icon_properties.end()) return; - const IconProperties& properties = icon_properties_it->second; + const IconProperties &properties = icon_properties_it != icon_properties.end() + ? icon_properties_it->second + : defaultIconProperties; if (!properties.enabled) return; Color color = properties.color; diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 2788a8bb1..71692c74c 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -11,9 +11,10 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons const std::unordered_map &line_properties = map.getStyle().computed.lines; const std::unordered_map::const_iterator line_properties_it = line_properties.find(layer_name); - if (line_properties_it == line_properties.end()) return; - const LineProperties& properties = line_properties_it->second; + const LineProperties &properties = line_properties_it != line_properties.end() + ? line_properties_it->second + : defaultLineProperties; if (!properties.enabled) return; float width = properties.width; diff --git a/src/renderer/painter_raster.cpp b/src/renderer/painter_raster.cpp index de0d35261..f1943bb49 100644 --- a/src/renderer/painter_raster.cpp +++ b/src/renderer/painter_raster.cpp @@ -9,9 +9,10 @@ void Painter::renderRaster(RasterBucket& bucket, const std::string& layer_name, const std::unordered_map &raster_properties = map.getStyle().computed.rasters; const std::unordered_map::const_iterator raster_properties_it = raster_properties.find(layer_name); - if (raster_properties_it == raster_properties.end()) return; - const RasterProperties& properties = raster_properties_it->second; + const RasterProperties &properties = raster_properties_it != raster_properties.end() + ? raster_properties_it->second + : defaultRasterProperties; if (!properties.enabled) return; depthMask(false); diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp index 0c3c0a01b..148fe7d53 100644 --- a/src/renderer/painter_text.cpp +++ b/src/renderer/painter_text.cpp @@ -1,6 +1,7 @@ #include #include #include +#include using namespace llmr; @@ -11,9 +12,10 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons const std::unordered_map &text_properties = map.getStyle().computed.texts; const std::unordered_map::const_iterator text_properties_it = text_properties.find(layer_name); - if (text_properties_it == text_properties.end()) return; - const TextProperties& properties = text_properties_it->second; + const TextProperties &properties = text_properties_it != text_properties.end() + ? text_properties_it->second + : defaultTextProperties; if (!properties.enabled) return; mat4 exMatrix; @@ -66,8 +68,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons history[0].z = history[1].z; } - size_t frameLen = history.size(); - assert("there should never be less than three frames in the history" && frameLen >= 3); + assert("there should never be less than three frames in the history" && (history.size() >= 3)); // Find the range of zoom levels we want to fade between float startingZ = history.front().z; @@ -81,7 +82,9 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons timeDiff = lastFrame.timestamp - history[1].timestamp; float fadedist = zoomDiff / (timeDiff / duration); - if (isnan(fadedist)) fprintf(stderr, "fadedist should never be NaN\n"); +#if defined(DEBUG) + if (std::isnan(fadedist)) fprintf(stderr, "fadedist should never be NaN\n"); +#endif // At end of a zoom when the zoom stops changing continue pretending to zoom at that speed // bump is how much farther it would have been if it had continued zooming at the same rate diff --git a/src/renderer/text_bucket.cpp b/src/renderer/text_bucket.cpp index 5823607ac..da6de3817 100644 --- a/src/renderer/text_bucket.cpp +++ b/src/renderer/text_bucket.cpp @@ -99,37 +99,15 @@ void TextBucket::addGlyphs(const PlacedGlyphs &glyphs, float placementZoom, } }; -void TextBucket::addFeature(const VectorTileFeature &feature, +void TextBucket::addFeature(const pbf &geom_pbf, const GlyphPositions &face, - const std::map &shapings) { - auto it_prop = feature.properties.find(geom_desc.field); - if (it_prop == feature.properties.end()) { - // feature does not have the correct property - if (debug::labelTextMissingWarning) { - fprintf(stderr, "[WARNING] feature doesn't have property '%s' required for labelling\n", geom_desc.field.c_str()); - } - return; - } - const Value &value = it_prop->second; - - auto it_shaping = shapings.find(toString(value)); - if (it_shaping == shapings.end()) { - if (debug::shapingWarning) { - fprintf(stderr, "[WARNING] missing shaping for '%s'\n", toString(value).c_str()); - } - // we lack shaping information for this label - return; - } - const Shaping &shaping = it_shaping->second; - - // std::cerr << "we have shaping for " << value << std::endl; - + const Shaping &shaping) { // Decode all lines. std::vector line; Geometry::command cmd; Coordinate coord; - pbf geom = feature.geometry; + pbf geom(geom_pbf); Geometry geometry(geom); int32_t x, y; while ((cmd = geometry.next(x, y)) != Geometry::end) { diff --git a/src/shader/gaussian_shader.cpp b/src/shader/gaussian_shader.cpp index 450ce331a..03509de41 100644 --- a/src/shader/gaussian_shader.cpp +++ b/src/shader/gaussian_shader.cpp @@ -12,7 +12,9 @@ GaussianShader::GaussianShader() shaders[GAUSSIAN_SHADER].fragment ) { if (!valid) { +#if defined(DEBUG) fprintf(stderr, "invalid raster shader\n"); +#endif return; } diff --git a/src/shader/raster_shader.cpp b/src/shader/raster_shader.cpp index eaf45ea2b..f083d3e26 100644 --- a/src/shader/raster_shader.cpp +++ b/src/shader/raster_shader.cpp @@ -12,7 +12,9 @@ RasterShader::RasterShader() shaders[RASTER_SHADER].fragment ) { if (!valid) { +#if defined(DEBUG) fprintf(stderr, "invalid raster shader\n"); +#endif return; } diff --git a/src/shader/shader.cpp b/src/shader/shader.cpp index 97e494f65..70b59e7aa 100644 --- a/src/shader/shader.cpp +++ b/src/shader/shader.cpp @@ -1,7 +1,8 @@ #include #include +#if defined(DEBUG) #include - +#endif #include #include #include @@ -11,18 +12,23 @@ using namespace llmr; Shader::Shader(const GLchar *vertSource, const GLchar *fragSource) : valid(false), program(0) { +#if defined(DEBUG) util::timer timer("shader compilation"); - +#endif GLuint vertShader; if (!compileShader(&vertShader, GL_VERTEX_SHADER, vertSource)) { +#if defined(DEBUG) fprintf(stderr, "Vertex shader failed to compile: %s\n", vertSource); +#endif return; } GLuint fragShader; if (!compileShader(&fragShader, GL_FRAGMENT_SHADER, fragSource)) { +#if defined(DEBUG) fprintf(stderr, "Fragment shader failed to compile: %s\n", fragSource); +#endif return; } @@ -80,7 +86,9 @@ Shader::Shader(const GLchar *vertSource, const GLchar *fragSource) glGetProgramiv(program, GL_VALIDATE_STATUS, &status); if (status == 0) { +#if defined(DEBUG) fprintf(stderr, "Program failed to validate\n"); +#endif glDeleteShader(vertShader); vertShader = 0; glDeleteShader(fragShader); diff --git a/src/style/sprite.cpp b/src/style/sprite.cpp index bb24c5fec..a0070b288 100644 --- a/src/style/sprite.cpp +++ b/src/style/sprite.cpp @@ -54,7 +54,9 @@ void Sprite::complete(std::shared_ptr &sprite) { if (sprite->raster && sprite->pos.size()) { sprite->loaded = true; sprite->map.update(); +#if defined(DEBUG) fprintf(stderr, "sprite loaded\n"); +#endif } } diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp index 4d7ff57ec..4831d8130 100644 --- a/src/text/glyph_store.cpp +++ b/src/text/glyph_store.cpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace llmr { @@ -120,7 +119,9 @@ GlyphPBF::GlyphPBF(const std::string &fontStack, GlyphRange glyphRange) // TODO: Find more reliable URL normalization function std::replace(url.begin(), url.end(), ' ', '+'); +#if defined(DEBUG) fprintf(stderr, "%s\n", url.c_str()); +#endif platform::request_http(url, [&](platform::Response *res) { if (res->code != 200) { diff --git a/src/util/constants.cpp b/src/util/constants.cpp index f67464926..46852e5e7 100644 --- a/src/util/constants.cpp +++ b/src/util/constants.cpp @@ -2,6 +2,7 @@ const float llmr::util::tileSize = 512.0f; +#if defined(DEBUG) const bool llmr::debug::tileParseWarnings = false; const bool llmr::debug::styleParseWarnings = false; const bool llmr::debug::spriteWarnings = false; @@ -12,3 +13,15 @@ const bool llmr::debug::missingFontStackWarning = true; const bool llmr::debug::missingFontFaceWarning = true; const bool llmr::debug::glyphWarning = true; const bool llmr::debug::shapingWarning = true; +#else +const bool llmr::debug::tileParseWarnings = false; +const bool llmr::debug::styleParseWarnings = false; +const bool llmr::debug::spriteWarnings = false; +const bool llmr::debug::renderWarnings = false; +const bool llmr::debug::renderTree = false; +const bool llmr::debug::labelTextMissingWarning = false; +const bool llmr::debug::missingFontStackWarning = false; +const bool llmr::debug::missingFontFaceWarning = false; +const bool llmr::debug::glyphWarning = false; +const bool llmr::debug::shapingWarning = false; +#endif \ No newline at end of file