Changeset 704 for trunk/src/load_map.cpp

Show
Ignore:
Timestamp:
06/29/08 06:58:48 (6 months ago)
Author:
artem
Message:

applied font fallback patch from Beau Gunderson

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/load_map.cpp

    r703 r704  
    3030#include <mapnik/datasource_cache.hpp> 
    3131#include <mapnik/font_engine_freetype.hpp> 
     32#include <mapnik/font_set.hpp> 
    3233 
    3334#include <mapnik/ptree_helpers.hpp> 
     
    6768         void parse_style( Map & map, ptree const & sty); 
    6869         void parse_layer( Map & map, ptree const & lay); 
    69           
     70         
     71         void parse_fontset(Map & map, ptree const & fset); 
     72         void parse_font(FontSet & fset, ptree const & f); 
     73      
    7074         void parse_rule( feature_type_style & style, ptree const & r); 
    7175          
     
    8084         void parse_markers_symbolizer( rule_type & rule, ptree const & sym ); 
    8185          
    82          void ensure_font_face( const text_symbolizer & text_symbol ); 
     86         void ensure_font_face( const std::string & face_name ); 
    8387          
    8488         bool strict_; 
     
    8791         face_manager<freetype_engine> font_manager_; 
    8892         std::map<std::string,std::string> file_sources_; 
     93         std::map<std::string,FontSet> fontsets_; 
    8994    }; 
    9095 
     
    143148                else if (v.first == "Layer") 
    144149                { 
    145  
    146150                    parse_layer(map, v.second ); 
     151                } 
     152                else if (v.first == "FontSet") 
     153                { 
     154                    parse_fontset(map, v.second); 
    147155                } 
    148156                else if (v.first == "FileSource") 
     
    227235        } 
    228236    } 
     237 
     238    void map_parser::parse_fontset( Map & map, ptree const & fset ) 
     239    { 
     240        string name("<missing name>"); 
     241        try 
     242        { 
     243            name = get_attr<string>(fset, "name"); 
     244            FontSet fontset(name); 
     245 
     246            ptree::const_iterator itr = fset.begin(); 
     247            ptree::const_iterator end = fset.end(); 
     248 
     249            for (; itr != end; ++itr)     
     250            { 
     251                ptree::value_type const& font_tag = *itr; 
     252 
     253                if (font_tag.first == "Font") 
     254                { 
     255                    parse_font(fontset, font_tag.second); 
     256                } 
     257                else if (font_tag.first != "<xmlcomment>" && 
     258                    font_tag.first != "<xmlattr>" ) 
     259                { 
     260                    throw config_error(std::string("Unknown child node in 'FontSet'.") + 
     261                        "Expected 'Font' but got '" + font_tag.first + "'"); 
     262                } 
     263            } 
     264 
     265            map.insert_fontset(name, fontset); 
     266                                 
     267            // XXX Hack because map object isn't accessible by text_symbolizer  
     268            // when it's parsed 
     269            fontsets_.insert(pair<std::string, FontSet>(name, fontset)); 
     270        } catch (const config_error & ex) { 
     271            if ( ! name.empty() ) { 
     272                ex.append_context(string("in FontSet '") + name + "'"); 
     273            } 
     274            throw; 
     275        } 
     276    } 
     277 
     278    void map_parser::parse_font(FontSet & fset, ptree const & f) 
     279        { 
     280        std::string face_name; 
     281 
     282        try 
     283        { 
     284            face_name = get_attr(f, "face_name", string()); 
     285         
     286            if ( strict_ ) 
     287            { 
     288                ensure_font_face( face_name ); 
     289            } 
     290        } 
     291        catch (const config_error & ex) 
     292        { 
     293            if (!face_name.empty()) 
     294            { 
     295                ex.append_context(string("in Font '") + face_name + "'"); 
     296            } 
     297            throw; 
     298        } 
     299 
     300        fset.add_face_name(face_name); 
     301         } 
    229302 
    230303    void map_parser::parse_layer( Map & map, ptree const & lay ) 
     
    604677        { 
    605678            std::string name = get_attr<string>(sym, "name");  
    606             std::string face_name =  get_attr<string>(sym, "face_name"); 
    607             unsigned size = get_attr(sym, "size", 10U ); 
     679 
     680            optional<std::string> face_name = 
     681                 get_opt_attr<std::string>(sym, "face_name"); 
     682             
     683            optional<std::string> fontset_name = 
     684                 get_opt_attr<std::string>(sym, "fontset_name"); 
     685 
     686            unsigned size = get_attr(sym, "size", 10U); 
    608687 
    609688            Color c = get_attr(sym, "fill", Color(0,0,0)); 
    610  
    611             text_symbolizer text_symbol(name, face_name, size, c); 
     689             
     690            text_symbolizer text_symbol = text_symbolizer(name, size, c);                 
     691             
     692            if (fontset_name && face_name) 
     693            { 
     694                throw config_error(std::string("Can't have both face_name and fontset_name")); 
     695            } 
     696            else if (fontset_name) 
     697            { 
     698                std::map<std::string,FontSet>::const_iterator itr = fontsets_.find(*fontset_name); 
     699                if (itr != fontsets_.end()) 
     700                { 
     701                    text_symbol.set_fontset(itr->second);                 
     702                } 
     703            } 
     704            else if (face_name) 
     705            { 
     706                text_symbol.set_face_name(*face_name);                 
     707            } 
     708            else 
     709            { 
     710                throw config_error(std::string("Must have face_name or fontset_name")); 
     711            } 
    612712 
    613713            int dx = get_attr(sym, "dx", 0); 
     
    684784            if ( strict_ ) 
    685785            { 
    686                 ensure_font_face( text_symbol ); 
     786                ensure_font_face( text_symbol.get_face_name() ); 
    687787            } 
    688788 
     
    9141014    }  
    9151015 
    916     void map_parser::ensure_font_face( const text_symbolizer & text_symbol ) 
    917     { 
    918         if ( ! font_manager_.get_face( text_symbol.get_face_name() ) ) 
     1016    void map_parser::ensure_font_face( const std::string & face_name ) 
     1017    { 
     1018        if ( ! font_manager_.get_face( face_name ) ) 
    9191019        { 
    9201020            throw config_error("Failed to find font face '" + 
    921                     text_symbol.get_face_name() + "'"); 
     1021                    face_name + "'"); 
    9221022        } 
    9231023    }