From a37dcedc419a6eefc333b6219f2220feca5cae0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 11 Mar 2014 15:16:29 +0100 Subject: [PATCH] parse label shaping --- include/llmr/map/vector_tile.hpp | 15 +++++++ src/map/vector_tile.cpp | 71 ++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/include/llmr/map/vector_tile.hpp b/include/llmr/map/vector_tile.hpp index 805c5eb91..4f78d9d98 100644 --- a/include/llmr/map/vector_tile.hpp +++ b/include/llmr/map/vector_tile.hpp @@ -67,6 +67,19 @@ private: std::set values; }; +class VectorTilePlacement { +public: + VectorTilePlacement(uint32_t face, uint32_t glyph, uint32_t x, uint32_t y); + + uint32_t face = 0; + uint32_t glyph = 0; + uint32_t x = 0; + uint32_t y = 0; +}; + +std::ostream& operator<<(std::ostream&, const VectorTilePlacement& placement); + + class VectorTileLayer { public: VectorTileLayer(pbf data); @@ -76,6 +89,8 @@ public: uint32_t extent = 4096; std::vector keys; std::vector values; + std::vector faces; + std::map>> shaping; }; class VectorTileGlyph { diff --git a/src/map/vector_tile.cpp b/src/map/vector_tile.cpp index 0e703f669..fb6340532 100644 --- a/src/map/vector_tile.cpp +++ b/src/map/vector_tile.cpp @@ -79,11 +79,49 @@ VectorTileGlyph::VectorTileGlyph(pbf glyph) { std::ostream& llmr::operator<<(std::ostream& os, const VectorTileGlyph& glyph) { os << "Glyph " << glyph.id << ": " << glyph.width << "x" << glyph.height << - " (" << glyph.left << "/" << glyph.top << ") +" << glyph.advance << std::endl; + " (" << glyph.left << "/" << glyph.top << ") +" << glyph.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 name = layer.string(); @@ -94,15 +132,40 @@ VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { } else if (layer.tag == 5) { // extent extent = layer.varint(); } else if (layer.tag == 7) { // faces - std::string face = layer.string(); + faces.emplace_back(layer.string()); } else if (layer.tag == 8) { // labels - layer.skip(); + labels.emplace_back(layer.message()); } else if (layer.tag == 9) { // stacks - std::string stack = layer.string(); + 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); + } +} + +VectorTilePlacement::VectorTilePlacement(uint32_t face, uint32_t glyph, uint32_t x, uint32_t y) + : face(face), + glyph(glyph), + x(x), + y(y) { +} + +std::ostream& llmr::operator<<(std::ostream& os, const VectorTilePlacement& placement) { + os << "Glyph " << placement.face << "/" << placement.glyph << ": " << placement.x << "/" << placement.y << std::endl; + return os; } FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer, const BucketDescription& bucket_desc)