Merge branch 'master' into linebreak

Conflicts:
	src/map/tile_parser.cpp
	src/text/glyph_store.cpp
This commit is contained in:
Young Hahn
2014-05-30 09:00:29 -04:00
31 changed files with 128 additions and 272 deletions

View File

@@ -479,8 +479,9 @@ void Map::prepare() {
}
void Map::render() {
#if defined(DEBUG)
std::vector<std::string> 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<LayerDescription>& layers) {
template <typename Styles>
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 <typename Styles>
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();
}

View File

@@ -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());
}

View File

@@ -15,8 +15,6 @@
#include <llmr/util/std.hpp>
#include <llmr/util/utf.hpp>
#include <iostream>
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<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
// Create a copy!
const FontStack &fontStack = glyphStore.getFontStack(bucket_desc.geometry.font);
std::map<Value, Shaping> 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<Bucket> 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);
}

View File

@@ -70,9 +70,6 @@ VectorTile::VectorTile(pbf tile) {
if (tile.tag == 3) { // layer
VectorTileLayer layer(tile.message());
layers.emplace(layer.name, std::forward<VectorTileLayer>(layer));
} else if (tile.tag == 4) { // face
VectorTileFace face(tile.message());
faces.emplace(face.name, std::forward<VectorTileFace>(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<GlyphPlacement> 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<std::string> stacks;
std::vector<VectorTileLabel> 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)

View File

@@ -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;
}