int main(int argc, char** argv) { std::vector<std::string> args; for (int i=1;i<argc;++i) { args.push_back(argv[i]); } bool quiet = std::find(args.begin(), args.end(), "-q")!=args.end(); try { BOOST_TEST(set_working_dir(args)); // create a renderable map with a fontset and a text symbolizer // and do not register any fonts, to ensure the error thrown is reasonable mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>(); ctx->push("name"); mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1)); mapnik::transcoder tr("utf-8"); UnicodeString ustr = tr.transcode("hello world!"); feature->put("name",ustr); mapnik::geometry_type * pt = new mapnik::geometry_type(mapnik::Point); pt->move_to(128,128); feature->add_geometry(pt); mapnik::datasource_ptr memory_ds = boost::make_shared<mapnik::memory_datasource>(); mapnik::memory_datasource *cache = dynamic_cast<mapnik::memory_datasource *>(memory_ds.get()); cache->push(feature); mapnik::Map m(256,256); mapnik::font_set fontset("fontset"); // NOTE: this is a valid font, but will fail because none are registered fontset.add_face_name("DejaVu Sans Book"); m.insert_fontset("fontset", fontset); mapnik::layer lyr("myLayerName"); lyr.set_datasource(memory_ds); lyr.add_style("style"); m.addLayer(lyr); mapnik::feature_type_style the_style; mapnik::rule the_rule; mapnik::text_symbolizer text_sym(mapnik::parse_expression("[name]"),10,mapnik::color(0,0,0)); text_sym.set_fontset(fontset); the_rule.append(text_sym); the_style.add_rule(the_rule); m.insert_style("style",the_style ); m.zoom_to_box(mapnik::box2d<double>(-256,-256, 256,256)); mapnik::image_32 buf(m.width(),m.height()); mapnik::agg_renderer<mapnik::image_32> ren(m,buf); ren.apply(); } catch (std::exception const& ex) { BOOST_TEST_EQ(std::string(ex.what()),std::string("myLayerName: No valid font face could be loaded for font set: 'fontset'")); } if (!::boost::detail::test_errors()) { if (quiet) std::clog << "\x1b[1;32m.\x1b[0m"; else std::clog << "C++ fontset runtime: \x1b[1;32m✓ \x1b[0m\n"; #if BOOST_VERSION >= 104600 ::boost::detail::report_errors_remind().called_report_errors_function = true; #endif } else { return ::boost::report_errors(); } }
void LyricsParser_KFN::parse(QIODevice * file, LyricsLoader::Container& output, LyricsLoader::Properties &properties) { // Parse the song.ini and fill up the sync and text arrays QByteArrayList texts; QList< int > syncs; // Analyze each line int idx_text = 0, idx_sync = 0; QByteArrayList lines = load( file ).split( '\n' ); bool inGeneral = false; for ( int i = 0; i < lines.size(); i++ ) { QByteArray line = lines[i]; // Section detector if ( line.startsWith( '[' ) && line.endsWith( ']') ) { inGeneral = (line == "[General]"); continue; } if ( inGeneral ) { if ( line.startsWith( "Title=" ) ) { QString v = QString::fromUtf8( line.mid(6) ).trimmed(); if ( !v.isEmpty() ) properties[ LyricsLoader::PROP_TITLE ] = v; } if ( line.startsWith( "Artist=" ) ) { QString v = QString::fromUtf8( line.mid(7) ).trimmed(); if ( !v.isEmpty() ) properties[ LyricsLoader::PROP_ARTIST ] = v; } } // Try to match the sync first char matchbuf[128]; sprintf( matchbuf, "Sync%d=", idx_sync ); if ( line.startsWith( matchbuf ) ) { idx_sync++; // Syncs are split by comma QByteArrayList values = line.mid( strlen(matchbuf) ).split( ',' ); for ( int v = 0; v < values.size(); v++ ) syncs.push_back( values[v].toInt() ); } // Now the text sprintf( matchbuf, "Text%d=", idx_text ); if ( line.startsWith( matchbuf ) ) { idx_text++; QByteArray textvalue = line.mid( strlen(matchbuf) ); if ( !textvalue.isEmpty() ) { // Text is split by word and optionally by the slash QByteArrayList values = textvalue.split(' '); for ( int v = 0; v < values.size(); v++ ) { QByteArrayList morevalues = values[v].split( '/' ); for ( int vv = 0; vv < morevalues.size(); vv++ ) texts.push_back( morevalues[vv] ); // We split by space, so add it at the end of each word texts.last() = texts.last() + " "; } } // Line matched, so make it a line if ( texts.size() > 2 && texts[ texts.size() - 2 ] != "\n" ) texts.push_back( "\n" ); } } int curr_sync = 0; bool has_linefeed = false; int lines_no_block = 0; int lastsync = -1; // The original timing marks are not necessarily sorted, so we add them into a map // and then output them from that map QMap< int, QByteArray > sortedLyrics; for ( int i = 0; i < texts.size(); i++ ) { if ( texts[i] == "\n" ) { if ( lastsync == -1 ) continue; if ( has_linefeed ) lines_no_block = 0; else if ( ++lines_no_block > 6 ) { lines_no_block = 0; sortedLyrics[ lastsync ] += "\n"; } has_linefeed = true; sortedLyrics[ lastsync ] += "\n"; continue; } else has_linefeed = false; // Get the time if we have it if ( curr_sync >= syncs.size() ) continue; lastsync = syncs[ curr_sync++ ]; sortedLyrics.insert( lastsync, texts[i] ); } // Generate the content for encoding detection QByteArray lyricsForEncoding; for ( QMap< int, QByteArray >::const_iterator it = sortedLyrics.begin(); it != sortedLyrics.end(); ++it ) lyricsForEncoding.append( it.value() ); // Detect the encoding QTextCodec * codec = detectEncoding( lyricsForEncoding, properties ); for ( QMap< int, QByteArray >::const_iterator it = sortedLyrics.begin(); it != sortedLyrics.end(); ++it ) { qint64 timing = it.key() * 10; Lyric lyr( timing, codec->toUnicode( it.value() ) ); // Last line? if ( lyr.text.endsWith( '\n') ) { // Remove the \n lyr.text.chop( 1 ); output.push_back( lyr ); // and add an empty lyric output.push_back( Lyric( timing ) ); } else { output.push_back( lyr ); } } }
int main(int argc, char** argv) { std::vector<std::string> args; for (int i=1;i<argc;++i) { args.push_back(argv[i]); } bool quiet = std::find(args.begin(), args.end(), "-q")!=args.end(); try { BOOST_TEST(set_working_dir(args)); // create a renderable map with a fontset and a text symbolizer // and do not register any fonts, to ensure the error thrown is reasonable mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>(); ctx->push("name"); mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1)); mapnik::transcoder tr("utf-8"); mapnik::value_unicode_string ustr = tr.transcode("hello world!"); feature->put("name",ustr); auto pt = std::make_unique<mapnik::geometry_type>(mapnik::geometry_type::types::Point); pt->move_to(128,128); feature->add_geometry(pt.release()); mapnik::parameters params; params["type"]="memory"; auto ds = std::make_shared<mapnik::memory_datasource>(params); ds->push(feature); mapnik::Map m(256,256); mapnik::font_set fontset("fontset"); // NOTE: this is a valid font, but will fail because none are registered fontset.add_face_name("DejaVu Sans Book"); m.insert_fontset("fontset", fontset); mapnik::layer lyr("layer"); lyr.set_datasource(ds); lyr.add_style("style"); m.add_layer(lyr); mapnik::feature_type_style the_style; mapnik::rule r; mapnik::text_symbolizer text_sym; mapnik::text_placements_ptr placement_finder = std::make_shared<mapnik::text_placements_dummy>(); placement_finder->defaults.format_defaults.face_name = "DejaVu Sans Book"; placement_finder->defaults.format_defaults.text_size = 10.0; placement_finder->defaults.format_defaults.fill = mapnik::color(0,0,0); placement_finder->defaults.format_defaults.fontset = fontset; placement_finder->defaults.set_format_tree(std::make_shared<mapnik::formatting::text_node>(mapnik::parse_expression("[name]"))); mapnik::put<mapnik::text_placements_ptr>(text_sym, mapnik::keys::text_placements_, placement_finder); r.append(std::move(text_sym)); the_style.add_rule(std::move(r)); m.insert_style("style", std::move(the_style) ); m.zoom_to_box(mapnik::box2d<double>(-256,-256, 256,256)); mapnik::image_rgba8 buf(m.width(),m.height()); mapnik::agg_renderer<mapnik::image_rgba8> ren(m,buf); ren.apply(); } catch (std::exception const& ex) { BOOST_TEST_EQ(std::string(ex.what()),std::string("Unable to find specified font face 'DejaVu Sans Book' in font set: 'fontset'")); } u_cleanup(); if (!::boost::detail::test_errors()) { if (quiet) std::clog << "\x1b[1;32m.\x1b[0m"; else std::clog << "C++ fontset runtime: \x1b[1;32m✓ \x1b[0m\n"; ::boost::detail::report_errors_remind().called_report_errors_function = true; } else { return ::boost::report_errors(); } }
void MapSource::addSRTMLayers(Map& m,double w,double s,double e,double n) { // Get the layers from the map vector<Layer> layers=m.layers(); cerr<<"***addSRTMLayers():w s e n="<<w<<" "<<s<<" "<<e<<" "<<n<<endl; int i=0; // Find the index of the SRTM layer while(i<layers.size() && layers[i].name()!="srtm") i++; // Return if we can't find an SRTM layer if(i==layers.size()) return; // Set the specific latlon shapefile for the first SRTM layer parameters p; p["type"] = "shape"; std::stringstream str; int lon=floor(w),lat=floor(s); str<<(lat<0 ? "S":"N")<<setw(2)<<setfill('0')<< (lat<0 ? -lat:lat)<< (lon>=0 ? "E":"W") << setw(3)<<setfill('0') <<(lon>=0 ? lon:-lon)<<"c10"; p["file"] = str.str(); cerr<<"ADDING SRTM LAYER: " << p["file"] << endl; m.getLayer(i).set_datasource(datasource_cache::instance()->create(p)); // do we have more than one srtm layer? if(floor(w) != floor(e) || floor(s) != floor(n)) { // remove all layers after the SRTM layer. This is because there // are multiple SRTM layers (if the current tile spans a lat/lon square // boundary) for(int j=i+1; j<layers.size(); j++) m.removeLayer(j); for(int lon=floor(w); lon<=floor(e); lon++) { for(int lat=floor(s); lat<=floor(n); lat++) { // if this isn't the bottom left lat/lon square, add another // SRTM layer for it if(lon!=floor(w) || lat!=floor(s)) { parameters p; p["type"] = "shape"; std::stringstream str; str<<(lat<0 ? "S":"N")<<setw(2)<<setfill('0')<< (lat<0 ? -lat:lat)<< (lon>=0 ? "E":"W") << setw(3)<<setfill('0') <<(lon>=0 ? lon:-lon)<<"c10"; p["file"] = str.str(); cerr<<"ADDING SRTM LAYER: " << p["file"] << endl; layer lyr("srtm_" + str.str()); lyr.add_style("contours"); lyr.add_style("contours-text"); lyr.set_datasource (datasource_cache::instance()->create(p)); m.addLayer(lyr); } } } // Add the other layers back for(int j=i+1; j<layers.size(); j++) m.addLayer(layers[j]); } }