add glyph store and load glyph pbfs

This commit is contained in:
Konstantin Käfer
2014-05-28 20:51:13 +02:00
parent 1749aa3de2
commit ed7b86a134
10 changed files with 334 additions and 44 deletions

View File

@@ -9,17 +9,21 @@
#include <llmr/util/raster.hpp>
#include <llmr/util/constants.hpp>
#include <llmr/geometry/glyph_atlas.hpp>
#include <llmr/text/glyph_store.hpp>
#include <llmr/util/std.hpp>
#include <codecvt>
using namespace llmr;
TileParser::TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, SpriteAtlas &spriteAtlas)
TileParser::TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, GlyphStore &glyphStore, SpriteAtlas &spriteAtlas)
: vector_data(pbf((const uint8_t *)data.data(), data.size())),
tile(tile),
style(style),
glyphAtlas(glyphAtlas),
glyphStore(glyphStore),
spriteAtlas(spriteAtlas),
placement(tile.id.z) {
parseGlyphs();
@@ -162,35 +166,42 @@ std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer& laye
return obsolete() ? nullptr : std::move(bucket);
}
typedef std::pair<uint16_t, uint16_t> GlyphRange;
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
// Determine the correct text stack.
if (!layer.shaping.size()) {
if (debug::missingFontStackWarning) {
fprintf(stderr, "[WARNING] missing font stack '%s'\n", bucket_desc.geometry.font.c_str());
}
return nullptr;
}
// TODO: currently hardcoded to use the first font stack.
const std::map<Value, Shaping>& shaping = layer.shaping.begin()->second;
const Faces& const_faces = faces;
IndexedFaces faces;
for (const std::string& face : layer.faces) {
auto it = const_faces.find(face);
if (it == const_faces.end()) {
// This layer references an unknown face.
if (debug::missingFontFaceWarning) {
fprintf(stderr, "[WARNING] missing font face '%s'\n", face.c_str());
}
return nullptr;
}
faces.push_back(&it->second);
}
std::unique_ptr<TextBucket> bucket = std::make_unique<TextBucket>(
tile.textVertexBuffer, tile.triangleElementsBuffer, bucket_desc, placement);
addBucketFeatures(bucket, layer, bucket_desc, faces, shaping);
std::set<GlyphRange> ranges;
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> ucs4conv;
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (const pbf& feature_pbf : filtered_layer) {
if (obsolete()) return nullptr;
VectorTileFeature feature { feature_pbf, layer };
auto it_prop = feature.properties.find(bucket_desc.geometry.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", bucket_desc.geometry.field.c_str());
}
continue;
}
const std::u32string string = ucs4conv.from_bytes(toString(it_prop->second));
// Loop through all characters of this text and collect unique codepoints.
for (uint32_t chr : string) {
ranges.insert(getGlyphRange(chr));
}
}
glyphStore.waitForGlyphRanges(bucket_desc.geometry.font, ranges);
// TODO: Now that we have all the glyph ranges, actually perform the shaping and add features to
// the bucket, and add the required glyphs from the glyphStore to the glyphAtlas.
return std::move(bucket);
}