LASi.h

Go to the documentation of this file.
00001 #ifndef LASI_H
00002 #define LASI_H
00003 
00009 #include <string>
00010 #include <ostream>
00011 #include <sstream>
00012 #include <map>
00013 #include <pango/pango.h>
00014 #include <freetype/ftglyph.h>
00015 
00016 class FreetypeGlyphMgr;
00017 class ContextMgr;
00018 
00019 // These macros are needed for Visual C++ and other Windows compilers as well
00020 // as gcc 4.x or higher with -fvisibility=hidden option.
00021 // All functions/classes marked with LASIDLLIMPEXP can be imported
00022 // from/exported to the Windows dll/gcc shared library.
00023 // Has no impact on other platforms.
00024 // Details handled identically to PLplot include/pldll.h(.in)
00025 #if defined ( WIN32 )
00026 /* Visual C/C++, Borland, MinGW and Watcom */
00027   #if defined ( __VISUALC__ ) || defined ( _MSC_VER ) || defined ( __BORLANDC__ ) || defined ( __GNUC__ ) || defined ( __WATCOMC__ )
00028     #define LASIDLLEXPORT    __declspec( dllexport )
00029     #define LASIDLLIMPORT    __declspec( dllimport )
00030   #else
00031     #define LASIDLLEXPORT
00032     #define LASIDLLIMPORT
00033   #endif
00034 #elif defined ( __CYGWIN__ )
00035   #define LASIDLLEXPORT    __declspec( dllexport )
00036   #define LASIDLLIMPORT    __declspec( dllimport )
00037 #elif defined ( __GNUC__ ) && __GNUC__ > 3
00038   // Follow ideas in http://gcc.gnu.org/wiki/Visibility for GCC version 4.x
00039   // The following forces exported symbols specifically designated with
00040   // LASIDLLEXPORT to be visible.
00041   #define LASIDLLEXPORT    __attribute__ ( ( visibility( "default" ) ) )
00042   #define LASIDLLIMPORT
00043 #endif
00044 
00045 // For an unknown compiler or static built we clear the macros.
00046 #ifndef LASIDLLEXPORT
00047   #define LASIDLLEXPORT
00048   #define LASIDLLIMPORT
00049 #endif
00050 
00051 #if defined(LASi_EXPORTS)
00052   #define LASIDLLIMPEXP LASIDLLEXPORT
00053   #define LASIDLLIMPEXP_DATA(type) LASIDLLEXPORT type
00054 #elif defined(LASi_DLL)
00055   #define LASIDLLIMPEXP LASIDLLIMPORT
00056   #define LASIDLLIMPEXP_DATA(type) LASIDLLIMPORT type
00057 #else
00058   #define LASIDLLIMPEXP
00059   #define LASIDLLIMPEXP_DATA(type) type
00060 #endif
00061 
00062 namespace LASi {
00063 
00064   enum FontStyle{
00065     NORMAL_STYLE,
00066     OBLIQUE,
00067     ITALIC
00068   };
00069 
00070   enum FontWeight{
00071     ULTRALIGHT,
00072     LIGHT,
00073     NORMAL_WEIGHT,
00074     BOLD,
00075     ULTRABOLD,
00076     HEAVY
00077   };
00078 
00079   enum FontVariant{
00080     NORMAL_VARIANT,
00081     SMALLCAPS
00082   };
00083 
00084   enum FontStretch{
00085     ULTRACONDENSED,
00086     EXTRACONDENSED,
00087     CONDENSED,
00088     SEMICONDENSED,
00089     NORMAL_STRETCH,
00090     SEMIEXPANDED,
00091     EXPANDED,
00092     EXTRAEXPANDED,
00093     ULTRAEXPANDED
00094   };
00095   
00096   class PostscriptDocument;
00097   class write_glyph_routine_to_stream;
00098 
00102   class LASIDLLIMPEXP oPostscriptStream : public std::ostringstream {
00103     public:
00104       friend class PostscriptDocument;
00105       friend class show;
00106       friend class setFont;
00107       friend class setFontSize;
00108 
00109       oPostscriptStream(PostscriptDocument& psDoc) : _psDoc(psDoc) {}
00110 
00111     protected:
00112       PostscriptDocument& doc() {return _psDoc;}
00113 
00114     private:
00115       PostscriptDocument& _psDoc;
00116   };
00117 
00118   template<class T>
00119     inline oPostscriptStream& operator<<(oPostscriptStream& os, T t) {
00120       static_cast<std::ostream&>(os) << t;
00121       return os;
00122     }
00123 
00129   class LASIDLLIMPEXP PostscriptDocument {
00130     public:
00131       friend class write_glyph_routine_to_stream; // helper class
00132       friend class show;
00133 
00134       PostscriptDocument();
00135       ~PostscriptDocument();
00136 
00140       void setFont(
00141           const char* const family = "sans",
00142           LASi::FontStyle   = LASi::NORMAL_STYLE,
00143           LASi::FontWeight  = LASi::NORMAL_WEIGHT,
00144           LASi::FontVariant = LASi::NORMAL_VARIANT,
00145           LASi::FontStretch = LASi::NORMAL_STRETCH
00146       );
00147 
00151       void setFontSize(const double size) {_fontSize = size;}
00152 
00155       std::ostringstream& osHeader() {return _osHeader;}
00156 
00159       oPostscriptStream& osBody() {return _osBody;}
00160 
00163       oPostscriptStream& osFooter() {return _osFooter;}
00164 
00174       void write(std::ostream& os, double llx=0, double lly=0, double urx=0, double ury=0);
00175 
00182       void get_dimensions(const char* s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00183       void get_dimensions(std::string s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00184 
00185     protected:
00190       class GlyphId {
00191         public:
00192           friend bool operator==(const GlyphId id1, const GlyphId id2) {
00193             return id1._str == id2._str;
00194           }
00195 
00196           friend bool operator<(const GlyphId id1, const GlyphId id2) {
00197             return id1._str < id2._str;
00198           }
00199 
00200           GlyphId() {}
00201           GlyphId(FT_Face, const FT_UInt);
00202 
00204           std::string str() const {return _str;}
00205 
00206         private:
00208           std::string _str;
00209       };
00210 
00213       typedef std::map<GlyphId, FreetypeGlyphMgr> GlyphMap;
00214 
00219       typedef void (PostscriptDocument::*GLYPH_FUNC)(
00220           const GlyphMap::value_type&, void* contextData);
00221 
00222       void invoke_glyph_routine(const GlyphMap::value_type&, void* contextData);
00223 
00224       void accrue_dimensions( const GlyphMap::value_type&, void* contextData1);
00225 
00228       void for_each_glyph_do(const std::string&, const GLYPH_FUNC, void* contextData,
00229                              bool applyOffset = false);
00230 
00231       PangoContext* pangoContext() const;
00232 
00235       std::string glyphProcName() const;
00236 
00239       double getFontSize() {return _fontSize;}
00240 
00243       class write_glyph_routine_to_stream {
00244         private:
00245           std::ostream& os;
00246           PangoContext* pangoCtx;
00247 
00248         public:
00249           write_glyph_routine_to_stream(std::ostream& os, PangoContext* pangoCtx) 
00250             : os(os), pangoCtx(pangoCtx) {}
00251           void operator()(PostscriptDocument::GlyphMap::value_type v);
00252       };
00253 
00254     private:
00255       GlyphMap _glyphMap;
00256 
00257       static const unsigned int DRAWING_SCALE;
00258 
00259       // Use pointers instead of objects in order to minimize namespace pollution of .h file user
00260       // Requires fwd declarations above.
00261       ContextMgr* _pContextMgr;     // manage PangoContext*
00262       double _fontSize;             // font size to be used when rendering next show()
00263       std::ostringstream _osHeader; // Postscript header
00264       oPostscriptStream _osBody;    // Postscript body
00265       oPostscriptStream _osFooter;  // Postscript footer
00266   };
00267 
00270   class LASIDLLIMPEXP setFont {
00271     public:
00274       friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFont& x) {
00275         x.apply(os);
00276         return os;
00277       }
00278 
00282       setFont(
00283           const char* const family = "sans",
00284           const LASi::FontStyle   style   = LASi::NORMAL_STYLE,
00285           const LASi::FontWeight  weight  = LASi::NORMAL_WEIGHT,
00286           const LASi::FontVariant variant = LASi::NORMAL_VARIANT,
00287           const LASi::FontStretch stretch = LASi::NORMAL_STRETCH )
00288           : _family(family), _style(style), _weight(weight), _variant(variant), _stretch(stretch)
00289       {}
00290       
00291     protected:
00292       void apply(oPostscriptStream& os) const {
00293         os.doc().setFont(_family, _style,_weight, _variant,  _stretch);
00294       }
00295 
00296     private:
00297       const char* const  _family;
00298       const LASi::FontStyle   _style;
00299       const LASi::FontWeight  _weight;
00300       const LASi::FontVariant _variant;
00301       const LASi::FontStretch _stretch;
00302       
00303   };
00304 
00307   class LASIDLLIMPEXP setFontSize {
00308     public:
00311       friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFontSize& x) {
00312         x.apply(os);
00313         return os;
00314       }
00315 
00320       setFontSize(double size) : _size(size) {}
00321 
00322     protected:
00323       void apply(oPostscriptStream& os) const {
00324         os.doc().setFontSize(_size);
00325       }
00326 
00327     private:
00328       double _size;
00329   };
00330 
00333   class LASIDLLIMPEXP show{
00334     public:
00337       friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const show& x) {
00338         x.apply(os);
00339         return os;
00340       }
00341 
00345       show(const char* c_str   ) : _str(c_str  ) {}
00346       show(std::string stl_str ) : _str(stl_str) {}
00347 
00348     protected:
00349       void apply(oPostscriptStream& os) const;
00350 
00351     private:
00352       std::string _str;
00353   };
00354 }
00355 #endif
00356