Changeset 713 for trunk

Show
Ignore:
Timestamp:
07/24/08 20:23:33 (6 months ago)
Author:
tom
Message:

Refactor some of the font set stuff so that the cairo renderer can be
made to work again.

Location:
trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/include/mapnik/font_engine_freetype.hpp

    r704 r713  
    6060namespace mapnik 
    6161{ 
     62    class MAPNIK_DECL font_glyph : private boost::noncopyable 
     63    { 
     64    public: 
     65        font_glyph(FT_Face face, unsigned index) 
     66            : face_(face), index_(index) {} 
     67 
     68        FT_Face get_face() const 
     69        { 
     70            return face_; 
     71        } 
     72 
     73        unsigned get_index() const 
     74        { 
     75            return index_; 
     76        } 
     77    private: 
     78        FT_Face face_; 
     79        unsigned index_; 
     80    }; 
     81 
     82    typedef boost::shared_ptr<font_glyph> glyph_ptr; 
     83 
    6284    class font_face : boost::noncopyable 
    6385    { 
     
    7698        } 
    7799         
    78         unsigned num_glyphs() const 
    79         { 
    80             return face_->num_glyphs; 
    81         } 
    82  
    83100        FT_GlyphSlot glyph() const 
    84101        { 
     
    118135     
    119136    typedef boost::shared_ptr<font_face> face_ptr; 
    120     
    121     class MAPNIK_DECL freetype_engine  // : public mapnik::singleton<freetype_engine,mapnik::CreateStatic>, 
    122          // private boost::noncopyable 
     137 
     138    class MAPNIK_DECL font_face_set : private boost::noncopyable 
    123139    { 
    124        // friend class mapnik::CreateStatic<freetype_engine>; 
    125       public: 
    126         static bool register_font(std::string const& file_name); 
    127         static std::vector<std::string> face_names (); 
    128         face_ptr create_face(std::string const& family_name); 
    129         virtual ~freetype_engine(); 
    130         freetype_engine(); 
    131       private: 
    132         FT_Library library_; 
    133         static boost::mutex mutex_; 
    134         static std::map<std::string,std::string> name2file_; 
    135     };  
    136      
    137     template <typename T> 
    138     class MAPNIK_DECL face_manager : private boost::noncopyable 
    139     { 
    140         typedef T font_engine_type; 
    141         typedef std::map<std::string,face_ptr> faces; 
    142          
    143140    public: 
    144         face_manager(T & engine) 
    145            : engine_(engine) {} 
    146          
    147         face_ptr get_face(std::string const& name) 
    148         { 
    149             typename faces::iterator itr; 
    150             itr = faces_.find(name); 
    151             if (itr != faces_.end()) 
    152             { 
    153                 return itr->second; 
    154             } 
    155             else 
    156             { 
    157                 face_ptr face = engine_.create_face(name); 
    158                 if (face) 
    159                 { 
    160                     faces_.insert(make_pair(name,face)); 
    161                 } 
    162                 return face;     
    163             } 
    164         } 
    165     private: 
    166         faces faces_; 
    167         font_engine_type & engine_; 
    168     }; 
    169          
    170     template <typename T> 
    171     struct text_renderer : private boost::noncopyable 
    172     { 
    173141        typedef std::pair<unsigned,unsigned> dimension_t; 
    174          
    175         struct glyph_t : boost::noncopyable 
    176         { 
    177             FT_Glyph image; 
    178             glyph_t(FT_Glyph image_) : image(image_) {} 
    179             ~glyph_t () { FT_Done_Glyph(image);} 
    180         }; 
    181          
    182         typedef boost::ptr_vector<glyph_t> glyphs_t; 
    183         typedef T pixmap_type; 
    184          
    185         text_renderer (pixmap_type & pixmap, std::vector<face_ptr> faces) 
    186             : pixmap_(pixmap), 
    187               faces_(faces), 
    188               fill_(0,0,0),  
    189               halo_fill_(255,255,255), 
    190               halo_radius_(0) {} 
     142 
     143        font_face_set(void) 
     144           : faces_() {} 
     145 
     146        void add(face_ptr face) 
     147        { 
     148            faces_.push_back(face); 
     149        } 
     150 
     151        unsigned size() const 
     152        { 
     153            return faces_.size(); 
     154        } 
     155 
     156        glyph_ptr get_glyph(unsigned c) const 
     157        { 
     158            for (std::vector<face_ptr>::const_iterator face = faces_.begin(); face != faces_.end(); ++face) 
     159            { 
     160               FT_Face f = (*face)->get_face(); 
     161               FT_UInt g = (*face)->get_char(c); 
     162 
     163               if (g) return glyph_ptr(new font_glyph(f, g)); 
     164            } 
     165 
     166            return glyph_ptr(); 
     167        } 
    191168 
    192169        dimension_t character_dimensions(const unsigned c) 
     
    201178            FT_BBox glyph_bbox;  
    202179            FT_Glyph image; 
    203                      
    204             FT_Face face = (*faces_.begin())->get_face(); 
    205              
    206             FT_UInt glyph_index = FT_Get_Char_Index(face, c); 
    207                   
    208             // If there's no glyph_index we loop through the remaining fonts 
    209             // in the fontset looking for one. 
    210             if (!glyph_index) { 
    211                 std::vector<face_ptr>::iterator itr = faces_.begin(); 
    212                 std::vector<face_ptr>::iterator end = faces_.end(); 
    213                  
    214                 ++itr; // Skip the first one, we already tried it. 
    215                  
    216                 for (; itr != end; ++itr) 
    217                 { 
    218                     FT_Face f = (*itr)->get_face(); 
    219                      
    220                     glyph_index = FT_Get_Char_Index(f, c); 
    221  
    222                     if (glyph_index) { 
    223                         face = f; 
    224                         break; 
    225                     } 
    226                 } 
    227             } 
     180 
     181            glyph_ptr glyph = get_glyph(c); 
     182            FT_Face face = glyph->get_face(); 
    228183 
    229184            matrix.xx = (FT_Fixed)( 1 * 0x10000L );  
     
    234189            FT_Set_Transform(face, &matrix, &pen); 
    235190 
    236             error = FT_Load_Glyph (face, glyph_index, FT_LOAD_NO_HINTING);  
     191            error = FT_Load_Glyph (face, glyph->get_index(), FT_LOAD_NO_HINTING);  
    237192            if ( error ) 
    238193                return dimension_t(0, 0); 
     
    328283        } 
    329284 
     285        void set_pixel_sizes(unsigned size) 
     286        { 
     287            for (std::vector<face_ptr>::iterator face = faces_.begin(); face != faces_.end(); ++face) 
     288            { 
     289                (*face)->set_pixel_sizes(size); 
     290            } 
     291        } 
     292    private: 
     293        std::vector<face_ptr> faces_; 
     294    }; 
     295     
     296    typedef boost::shared_ptr<font_face_set> face_set_ptr; 
     297 
     298    class MAPNIK_DECL freetype_engine  // : public mapnik::singleton<freetype_engine,mapnik::CreateStatic>, 
     299         // private boost::noncopyable 
     300    { 
     301       // friend class mapnik::CreateStatic<freetype_engine>; 
     302      public: 
     303        static bool register_font(std::string const& file_name); 
     304        static std::vector<std::string> face_names (); 
     305        face_ptr create_face(std::string const& family_name); 
     306        virtual ~freetype_engine(); 
     307        freetype_engine(); 
     308      private: 
     309        FT_Library library_; 
     310        static boost::mutex mutex_; 
     311        static std::map<std::string,std::string> name2file_; 
     312    };  
     313     
     314    template <typename T> 
     315    class MAPNIK_DECL face_manager : private boost::noncopyable 
     316    { 
     317        typedef T font_engine_type; 
     318        typedef std::map<std::string,face_ptr> faces; 
     319         
     320    public: 
     321        face_manager(T & engine) 
     322           : engine_(engine) {} 
     323         
     324        face_ptr get_face(std::string const& name) 
     325        { 
     326            typename faces::iterator itr; 
     327            itr = faces_.find(name); 
     328            if (itr != faces_.end()) 
     329            { 
     330                return itr->second; 
     331            } 
     332            else 
     333            { 
     334                face_ptr face = engine_.create_face(name); 
     335                if (face) 
     336                { 
     337                    faces_.insert(make_pair(name,face)); 
     338                } 
     339                return face;     
     340            } 
     341        } 
     342 
     343        face_set_ptr get_face_set(std::string const& name) 
     344        { 
     345            face_set_ptr face_set(new font_face_set); 
     346            if (face_ptr face = get_face(name)) 
     347            { 
     348                face_set->add(face); 
     349            } 
     350            return face_set; 
     351        } 
     352 
     353        face_set_ptr get_face_set(FontSet const& fontset) 
     354        { 
     355            std::vector<std::string> const& names = fontset.get_face_names(); 
     356            face_set_ptr face_set(new font_face_set); 
     357            for (std::vector<std::string>::const_iterator name = names.begin(); name != names.end(); ++name) 
     358            { 
     359                if (face_ptr face = get_face(*name)) 
     360                { 
     361                    face_set->add(face); 
     362                } 
     363            } 
     364            return face_set; 
     365        } 
     366    private: 
     367        faces faces_; 
     368        font_engine_type & engine_; 
     369    }; 
     370 
     371    template <typename T> 
     372    struct text_renderer : private boost::noncopyable 
     373    { 
     374        struct glyph_t : boost::noncopyable 
     375        { 
     376            FT_Glyph image; 
     377            glyph_t(FT_Glyph image_) : image(image_) {} 
     378            ~glyph_t () { FT_Done_Glyph(image);} 
     379        }; 
     380         
     381        typedef boost::ptr_vector<glyph_t> glyphs_t; 
     382        typedef T pixmap_type; 
     383         
     384        text_renderer (pixmap_type & pixmap, face_set_ptr faces) 
     385            : pixmap_(pixmap), 
     386              faces_(faces), 
     387              fill_(0,0,0),  
     388              halo_fill_(255,255,255), 
     389              halo_radius_(0) {} 
     390 
    330391        void set_pixel_size(unsigned size) 
    331392        { 
    332             std::vector<face_ptr>::iterator itr = faces_.begin(); 
    333             std::vector<face_ptr>::iterator end = faces_.end(); 
    334             for (; itr != end; ++itr) 
    335             { 
    336                 (*itr)->set_pixel_sizes(size); 
    337             } 
     393            faces_->set_pixel_sizes(size); 
    338394        } 
    339395     
     
    366422            bbox.xMax = bbox.yMax = -32000; // properly grew the bbox later 
    367423             
    368             std::vector<face_ptr>::iterator end = faces_.end(); 
    369              
    370424            for (int i = 0; i < path->num_nodes(); i++)  
    371425            { 
     
    386440                pen.x = int(x * 64); 
    387441                pen.y = int(y * 64); 
    388                          
    389                 FT_Face face = (*faces_.begin())->get_face(); 
    390  
    391                 FT_UInt glyph_index = FT_Get_Char_Index(face, unsigned(c)); 
    392                       
    393                 // If there's no glyph_index we loop through the remaining fonts 
    394                 // in the fontset looking for one. 
    395                 if (!glyph_index) { 
    396                     std::vector<face_ptr>::iterator itr = faces_.begin(); 
    397                     ++itr; // Skip the first one, we already tried it. 
    398                      
    399                     for (; itr != end; ++itr) 
    400                     { 
    401 #ifdef MAPNIK_DEBUG 
    402                         // TODO Enable when we have support for setting verbosity 
    403                         //std::clog << "prepare_glyphs: Falling back to font named \"" 
    404                         //    << (*itr)->family_name() << " " << (*itr)->style_name() 
    405                         //    << "\"" << std::endl; 
    406 #endif 
    407  
    408                         FT_Face f = (*itr)->get_face(); 
    409                          
    410                         glyph_index = FT_Get_Char_Index(f, unsigned(c)); 
    411  
    412                         if (glyph_index) { 
    413                             face = f; 
    414                             break; 
    415                         } 
    416                     } 
    417  
    418 #ifdef MAPNIK_DEBUG 
    419                     // TODO Enable when we have support for setting verbosity 
    420                     //if (!glyph_index) { 
    421                     //    std::clog << "prepare_glyphs: Failed to fall back, glyph " 
    422                     //        << c << " not found in any font." << std::endl; 
    423                     //} 
    424 #endif 
    425                 } 
     442                 
     443                glyph_ptr glyph = faces_->get_glyph(unsigned(c)); 
     444                FT_Face face = glyph->get_face(); 
    426445 
    427446                matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );  
     
    432451                FT_Set_Transform(face, &matrix, &pen); 
    433452 
    434                 error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_HINTING);  
     453                error = FT_Load_Glyph(face, glyph->get_index(), FT_LOAD_NO_HINTING);  
    435454                if ( error ) 
    436455                    continue; 
     
    559578     
    560579        pixmap_type & pixmap_; 
    561         std::vector<face_ptr> faces_; 
     580        face_set_ptr faces_; 
    562581        mapnik::Color fill_; 
    563582        mapnik::Color halo_fill_; 
  • trunk/include/mapnik/font_set.hpp

    r709 r713  
    4242            FontSet(FontSet const& rhs); 
    4343            FontSet& operator=(FontSet const& rhs); 
     44            unsigned size() const; 
    4445            std::string const& get_name() const; 
    4546            void add_face_name(std::string); 
  • trunk/src/agg_renderer.cpp

    r708 r713  
    460460      if (text.length() > 0 && data) 
    461461      { 
    462          std::vector<face_ptr> faces; 
    463                          
    464          faces.push_back(font_manager_.get_face(sym.get_face_name())); 
    465           
    466          if (faces.size() > 0) 
     462         face_set_ptr faces; 
     463 
     464         if (sym.get_fontset().size() > 0) 
     465         { 
     466            faces = font_manager_.get_face_set(sym.get_fontset()); 
     467         } 
     468         else  
     469         { 
     470            faces = font_manager_.get_face_set(sym.get_face_name()); 
     471         } 
     472 
     473         if (faces->size() > 0) 
    467474         { 
    468475            text_renderer<mapnik::Image32> ren(pixmap_, faces); 
     
    473480            string_info info(text); 
    474481 
    475             ren.get_string_info(info); 
     482            faces->get_string_info(info); 
    476483             
    477484            placement_finder<label_collision_detector4> finder(detector_); 
     
    676683         Color const& fill = sym.get_fill(); 
    677684 
    678          std::vector<face_ptr> faces; 
    679      
    680          FontSet fontset = sym.get_fontset(); 
    681          std::vector<std::string> face_names = fontset.get_face_names(); 
    682      
    683          if (face_names.size() > 0) 
    684          { 
    685             std::vector<std::string>::iterator itr = face_names.begin(); 
    686             std::vector<std::string>::iterator end = face_names.end(); 
    687  
    688             for (; itr != end; ++itr) 
    689             { 
    690                faces.push_back(font_manager_.get_face(*itr)); 
    691             } 
     685         face_set_ptr faces; 
     686 
     687         if (sym.get_fontset().size() > 0) 
     688         { 
     689            faces = font_manager_.get_face_set(sym.get_fontset()); 
    692690         } 
    693691         else  
    694692         { 
    695             faces.push_back(font_manager_.get_face(sym.get_face_name())); 
    696          } 
    697       
    698          if (faces.size() > 0) 
     693            faces = font_manager_.get_face_set(sym.get_face_name()); 
     694         } 
     695 
     696         if (faces->size() > 0) 
    699697         { 
    700698            text_renderer<mapnik::Image32> ren(pixmap_, faces); 
     
    708706            string_info info(text); 
    709707             
    710             ren.get_string_info(info); 
     708            faces->get_string_info(info); 
    711709            unsigned num_geom = feature.num_geometries(); 
    712710            for (unsigned i=0;i<num_geom;++i) 
  • trunk/src/font_set.cpp

    r710 r713  
    5353    FontSet::~FontSet() {} 
    5454     
     55    unsigned FontSet::size() const 
     56    { 
     57        return face_names_.size(); 
     58    } 
     59 
    5560    void FontSet::add_face_name(std::string face_name) 
    5661    {