Font.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /* GG is a GUI for SDL and OpenGL.
00003    Copyright (C) 2003 T. Zachary Laine
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public License
00007    as published by the Free Software Foundation; either version 2.1
00008    of the License, or (at your option) any later version.
00009    
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014     
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA
00019 
00020    If you do not wish to comply with the terms of the LGPL please
00021    contact the author as other terms are available for a fee.
00022     
00023    Zach Laine
00024    whatwasthataddress@hotmail.com */
00025 
00031 #ifndef _GG_Font_h_
00032 #define _GG_Font_h_
00033 
00034 #include <GG/AlignmentFlags.h>
00035 #include <GG/Texture.h>
00036 
00037 #include <set>
00038 
00039 #include <boost/serialization/access.hpp>
00040 
00041 
00042 typedef unsigned long FT_ULong;
00043 struct FT_FaceRec_;
00044 typedef struct FT_FaceRec_*  FT_Face;
00045 
00046 namespace GG {
00047 
00049 GG_API std::string " from a Clr object with color channels...">RgbaTag(const Clr& c);
00050 
00052 GG_FLAG_TYPE(TextFormat);
00053 extern GG_API const TextFormat FORMAT_NONE;        
00054 extern GG_API const TextFormat FORMAT_VCENTER;     
00055 extern GG_API const TextFormat FORMAT_TOP;         
00056 extern GG_API const TextFormat FORMAT_BOTTOM;      
00057 extern GG_API const TextFormat FORMAT_CENTER;      
00058 extern GG_API const TextFormat FORMAT_LEFT;        
00059 extern GG_API const TextFormat FORMAT_RIGHT;       
00060 extern GG_API const TextFormat FORMAT_WORDBREAK;   
00061 extern GG_API const TextFormat FORMAT_LINEWRAP;    
00062 extern GG_API const TextFormat FORMAT_IGNORETAGS;  
00063 
00064 
00108 class GG_API Font
00109 {
00110 public:
00112     struct GG_API TextElement
00113     {
00115         enum TextElementType {
00116             OPEN_TAG,   
00117             CLOSE_TAG,  
00118             TEXT,       
00119             WHITESPACE, 
00120             NEWLINE     
00121         };
00122 
00123         TextElement(bool ws, bool nl); 
00124         virtual ~TextElement(); 
00125 
00126         int Width() const;                       
00127         virtual TextElementType Type() const;    
00128         virtual int OriginalStringChars() const; 
00129 
00130         std::string      text;       
00131         std::vector<int> widths;     
00132         const bool       whitespace; 
00133         const bool       newline;    
00134 
00135     protected:
00136         TextElement();
00137 
00138     private:
00139         friend class boost::serialization::access;
00140         template <class Archive>
00141         void serialize(Archive& ar, const unsigned int version);
00142     };
00143 
00145     struct GG_API FormattingTag : TextElement
00146     {
00147         FormattingTag(bool close); 
00148 
00149         virtual TextElementType Type() const;
00150         virtual int OriginalStringChars() const;
00151 
00152         std::vector<std::string> params;            
00153         std::string              original_tag_text; 
00154         const bool               close_tag;         
00155 
00156     private:
00157         FormattingTag();
00158         friend class boost::serialization::access;
00159         template <class Archive>
00160         void serialize(Archive& ar, const unsigned int version);
00161     };
00162 
00166     struct GG_API LineData
00167     {
00168         LineData(); 
00169 
00172         struct GG_API CharData
00173         {
00174             CharData(); 
00175             CharData(int extent_, int original_index, const std::vector<boost::shared_ptr<TextElement> >& tags_); 
00176 
00177             int extent;              
00178             int original_char_index; 
00179             std::vector<boost::shared_ptr<FormattingTag> >
00180                 tags;                
00181 
00182         private:
00183             friend class boost::serialization::access;
00184             template <class Archive>
00185             void serialize(Archive& ar, const unsigned int version);
00186         };
00187 
00188         int         Width() const; 
00189         bool        Empty() const; 
00190 
00191         std::vector<CharData> char_data;     
00192         Alignment             justification; 
00193 
00194     private:
00195         friend class boost::serialization::access;
00196         template <class Archive>
00197         void serialize(Archive& ar, const unsigned int version);
00198     };
00199 
00202     struct GG_API RenderState
00203     {
00204         RenderState(); 
00205 
00206         bool    ignore_tags;        
00207         bool    use_italics;        
00208         bool    draw_underline;     
00209         bool    color_set;          
00210         Clr     curr_color;         
00211     };
00212 
00214     enum GlyphRange {
00215         NUMBER =             1 << 0,    
00216         ALPHA_UPPER =        1 << 1,    
00217         ALPHA_LOWER =        1 << 2,    
00218         SYMBOL =             1 << 3,    
00219         ALL_DEFINED_RANGES = NUMBER | ALPHA_UPPER | ALPHA_LOWER | SYMBOL, 
00220         ALL_CHARS =          (1 << 5) - 1 
00221     };
00222  
00224 
00226     Font(const std::string& font_filename, int pts, unsigned int range = ALL_DEFINED_RANGES);
00227     virtual ~Font(); 
00228 
00229  
00231     const std::string&FontName() const;   
00232     int               PointSize() const;  
00233 
00235     int               GetGlyphRange() const;
00236 
00237     int               Ascent() const;     
00238     int               Descent() const;    
00239     int               Height() const;     
00240     int               Lineskip() const;   
00241     int               SpaceWidth() const; 
00242     int               RenderGlyph(const Pt& pt, char c) const; 
00243     int               RenderGlyph(int x, int y, char c) const; 
00244     int               RenderText(const Pt& pt, const std::string& text) const; 
00245     int               RenderText(int x, int y, const std::string& text) const; 
00246     void              RenderText(const Pt& pt1, const Pt& pt2, const std::string& text, Flags<TextFormat>& format, const std::vector<LineData>* line_data = 0, RenderState* render_state = 0) const; 
00247     void              RenderText(int x1, int y1, int x2, int y2, const std::string& text, Flags<TextFormat>& format, const std::vector<LineData>* line_data = 0, RenderState* render_state = 0) const; 
00248     void              RenderText(const Pt& pt1, const Pt& pt2, const std::string& text, Flags<TextFormat>& format, const std::vector<LineData>& line_data, RenderState& render_state, int begin_line, int begin_char, int end_line, int end_char) const; 
00249     void              RenderText(int x1, int y1, int x2, int y2, const std::string& text, Flags<TextFormat>& format, const std::vector<LineData>& line_data, RenderState& render_state, int begin_line, int begin_char, int end_line, int end_char) const; 
00250     Pt                DetermineLines(const std::string& text, Flags<TextFormat>& format, int box_width, std::vector<LineData>& lines) const; 
00251     Pt                TextExtent(const std::string& text, Flags<TextFormat> format = FORMAT_NONE, int box_width = 0) const; 
00252 
00253 
00254     static void       RegisterKnownTag(const std::string& tag);   
00255     static void       RemoveKnownTag(const std::string& tag);     
00256     static void       ClearKnownTags();                      
00257  
00259 
00260     GG_ABSTRACT_EXCEPTION(Exception);
00261 
00263     GG_CONCRETE_EXCEPTION(BadFile, GG::Font, Exception);
00264 
00266     GG_CONCRETE_EXCEPTION(InvalidPointSize, GG::Font, Exception);
00267 
00269     GG_CONCRETE_EXCEPTION(InvalidRangeFlags, GG::Font, Exception);
00270 
00272     GG_CONCRETE_EXCEPTION(UnscalableFont, GG::Font, Exception);
00273 
00275     GG_CONCRETE_EXCEPTION(BadFace, GG::Font, Exception);
00276 
00278     GG_CONCRETE_EXCEPTION(BadPointSize, GG::Font, Exception);
00279 
00281     GG_CONCRETE_EXCEPTION(BadGlyph, GG::Font, Exception);
00283 
00284 protected: 
00286     Font(); 
00287 
00288 
00289 private:
00292     struct Glyph
00293     {
00294         Glyph() : left_bearing(0), advance(0), width(0) {} 
00295         Glyph(const boost::shared_ptr<Texture>& texture, int x1, int y1, int x2, int y2, int lb, int adv) : 
00296             sub_texture(texture, x1, y1, x2, y2), left_bearing(lb), advance(adv), width(x2 - x1) {} 
00297 
00298         SubTexture  sub_texture;   
00299         int         left_bearing;  
00300         int         advance;       
00301         int         width;         
00302     };
00303     struct HandleTagFunctor;
00304 
00305     void              Init(const std::string& font_filename, int pts, unsigned int range);
00306     bool              GenerateGlyph(FT_Face font, FT_ULong ch);
00307     inline int        RenderGlyph(int x, int y, const Glyph& glyph, const RenderState* render_state) const;
00308     void              HandleTag(const boost::shared_ptr<FormattingTag>& tag, double* orig_color, RenderState& render_state) const;
00309 
00310     std::string          m_font_filename;
00311     int                  m_pt_sz;
00312     int                  m_glyph_range; 
00313     int                  m_ascent;      
00314     int                  m_descent;     
00315     int                  m_height;      
00316     int                  m_lineskip;    
00317     double               m_underline_offset; 
00318     double               m_underline_height; 
00319     double               m_italics_offset;   
00320     int                  m_space_width; 
00321     std::map<FT_ULong, Glyph>
00322                          m_glyphs;      
00323     std::vector<boost::shared_ptr<Texture> >
00324                          m_textures;    
00325 
00326     static std::set<std::string>   s_action_tags; 
00327     static std::set<std::string>   s_known_tags;  
00328 
00329     friend struct HandleTagFunctor;
00330 
00331     friend class boost::serialization::access;
00332     template <class Archive>
00333     void serialize(Archive& ar, const unsigned int version);
00334 };
00335 
00336 // define EnumMap and stream operators for Font::GlyphRange
00337 GG_ENUM_MAP_BEGIN(Font::GlyphRange)
00338     GG_ENUM_MAP_INSERT(Font::NUMBER)
00339     GG_ENUM_MAP_INSERT(Font::ALPHA_UPPER)
00340     GG_ENUM_MAP_INSERT(Font::ALPHA_LOWER)
00341     GG_ENUM_MAP_INSERT(Font::SYMBOL)
00342     GG_ENUM_MAP_INSERT(Font::ALL_DEFINED_RANGES)
00343     GG_ENUM_MAP_INSERT(Font::ALL_CHARS)
00344 GG_ENUM_MAP_END
00345 
00346 GG_ENUM_STREAM_IN(Font::GlyphRange)
00347 GG_ENUM_STREAM_OUT(Font::GlyphRange)
00348 
00349 
00359 class GG_API FontManager
00360 {
00361 private:
00363     struct FontKey
00364     {
00365         FontKey(const std::string& str, int pts); 
00366         bool operator<(const FontKey& rhs) const; 
00367 
00368         std::string filename;   
00369         int         points;     
00370     };
00371 
00372 public: 
00374     boost::shared_ptr<Font> GetFont(const std::string& font_filename, int pts, unsigned int range = Font::ALL_DEFINED_RANGES); 
00375     void                    FreeFont(const std::string& font_filename, int pts); 
00376 
00377 
00378 private:
00379     FontManager();
00380 
00381     std::map<FontKey, boost::shared_ptr<Font> > m_rendered_fonts;
00382 
00383     friend FontManager& GetFontManager();
00384 };
00385 
00387 FontManager& GetFontManager();
00388 
00390 GG_EXCEPTION(FailedFTLibraryInit);
00391 
00392 } // template GG
00393 
00394 // template implementations
00395 template <class Archive>
00396 void GG::Font::TextElement::serialize(Archive& ar, const unsigned int version)
00397 {
00398     ar  & BOOST_SERIALIZATION_NVP(text)
00399         & BOOST_SERIALIZATION_NVP(widths)
00400         & boost::serialization::make_nvp("whitespace", const_cast<bool&>(whitespace))
00401         & boost::serialization::make_nvp("newline", const_cast<bool&>(newline));
00402 }
00403 
00404 template <class Archive>
00405 void GG::Font::FormattingTag::serialize(Archive& ar, const unsigned int version)
00406 {
00407     ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(TextElement)
00408         & BOOST_SERIALIZATION_NVP(params)
00409         & BOOST_SERIALIZATION_NVP(original_tag_text)
00410         & boost::serialization::make_nvp("close_tag", const_cast<bool&>(close_tag));
00411 }
00412 
00413 template <class Archive>
00414 void GG::Font::LineData::CharData::serialize(Archive& ar, const unsigned int version)
00415 {
00416     ar  & BOOST_SERIALIZATION_NVP(extent)
00417         & BOOST_SERIALIZATION_NVP(original_char_index)
00418         & BOOST_SERIALIZATION_NVP(tags);
00419 }
00420 
00421 template <class Archive>
00422 void GG::Font::LineData::serialize(Archive& ar, const unsigned int version)
00423 {
00424     ar  & BOOST_SERIALIZATION_NVP(char_data)
00425         & BOOST_SERIALIZATION_NVP(justification);
00426 }
00427 
00428 template <class Archive>
00429 void GG::Font::serialize(Archive& ar, const unsigned int version)
00430 {
00431     ar  & BOOST_SERIALIZATION_NVP(m_font_filename)
00432         & BOOST_SERIALIZATION_NVP(m_pt_sz)
00433         & BOOST_SERIALIZATION_NVP(m_glyph_range);
00434 
00435     if (Archive::is_loading::value) {
00436         if (!m_font_filename.empty() && 0 < m_pt_sz) {
00437             try {
00438                 Init(m_font_filename, m_pt_sz, m_glyph_range);
00439             } catch (const Exception& e) {
00440                 // take no action; the Font must have been uninitialized when saved
00441             }
00442         }
00443     }
00444 }
00445 
00446 #endif // _GG_Font_h_

Generated on Wed Mar 26 14:35:41 2008 for GG by  doxygen 1.5.2