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
00020
00021
00022 #if defined(WIN32)
00023
00024 #if defined(__VISUALC__) || defined(_MSC_VER) || defined(__BORLANDC__) || defined(__GNUC__) || defined(__WATCOMC__) || defined(__CYGWIN__)
00025 #define LASIDLLEXPORT __declspec(dllexport)
00026 #define LASIDLLIMPORT __declspec(dllimport)
00027 #else
00028 #define LASIDLLEXPORT
00029 #define LASIDLLIMPORT
00030 #endif
00031 #else
00032 #define LASIDLLEXPORT
00033 #define LASIDLLIMPORT
00034 #endif
00035
00036 #if defined(LASi_EXPORTS)
00037 #define LASIDLLIMPEXP LASIDLLEXPORT
00038 #define LASIDLLIMPEXP_DATA(type) LASIDLLEXPORT type
00039 #elif defined(LASi_DLL)
00040 #define LASIDLLIMPEXP LASIDLLIMPORT
00041 #define LASIDLLIMPEXP_DATA(type) LASIDLLIMPORT type
00042 #else
00043 #define LASIDLLIMPEXP
00044 #define LASIDLLIMPEXP_DATA(type) type
00045 #endif
00046
00047 namespace LASi {
00048
00049 enum FontStyle{
00050 NORMAL_STYLE,
00051 OBLIQUE,
00052 ITALIC
00053 };
00054
00055 enum FontWeight{
00056 ULTRALIGHT,
00057 LIGHT,
00058 NORMAL_WEIGHT,
00059 BOLD,
00060 ULTRABOLD,
00061 HEAVY
00062 };
00063
00064 enum FontVariant{
00065 NORMAL_VARIANT,
00066 SMALLCAPS
00067 };
00068
00069 enum FontStretch{
00070 ULTRACONDENSED,
00071 EXTRACONDENSED,
00072 CONDENSED,
00073 SEMICONDENSED,
00074 NORMAL_STRETCH,
00075 SEMIEXPANDED,
00076 EXPANDED,
00077 EXTRAEXPANDED,
00078 ULTRAEXPANDED
00079 };
00080
00081 class PostscriptDocument;
00082 class write_glyph_routine_to_stream;
00083
00087 class LASIDLLIMPEXP oPostscriptStream : public std::ostringstream {
00088 public:
00089 friend class PostscriptDocument;
00090 friend class show;
00091 friend class setFont;
00092 friend class setFontSize;
00093
00094 oPostscriptStream(PostscriptDocument& psDoc) : _psDoc(psDoc) {}
00095
00096 protected:
00097 PostscriptDocument& doc() {return _psDoc;}
00098
00099 private:
00100 PostscriptDocument& _psDoc;
00101 };
00102
00103 template<class T>
00104 inline oPostscriptStream& operator<<(oPostscriptStream& os, T t) {
00105 static_cast<std::ostream&>(os) << t;
00106 return os;
00107 }
00108
00114 class LASIDLLIMPEXP PostscriptDocument {
00115 public:
00116 friend class write_glyph_routine_to_stream;
00117 friend class show;
00118
00119 PostscriptDocument();
00120 ~PostscriptDocument();
00121
00125 void setFont(
00126 const char* const family = "sans",
00127 LASi::FontStyle = LASi::NORMAL_STYLE,
00128 LASi::FontWeight = LASi::NORMAL_WEIGHT,
00129 LASi::FontVariant = LASi::NORMAL_VARIANT,
00130 LASi::FontStretch = LASi::NORMAL_STRETCH
00131 );
00132
00136 void setFontSize(const double size) {_fontSize = size;}
00137
00140 std::ostringstream& osHeader() {return _osHeader;}
00141
00144 oPostscriptStream& osBody() {return _osBody;}
00145
00148 oPostscriptStream& osFooter() {return _osFooter;}
00149
00159 void write(std::ostream& os, double llx=0, double lly=0, double urx=0, double ury=0);
00160
00167 void get_dimensions(const char* s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00168 void get_dimensions(std::string s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00169
00170 protected:
00175 class GlyphId {
00176 public:
00177 friend bool operator==(const GlyphId id1, const GlyphId id2) {
00178 return id1._str == id2._str;
00179 }
00180
00181 friend bool operator<(const GlyphId id1, const GlyphId id2) {
00182 return id1._str < id2._str;
00183 }
00184
00185 GlyphId() {}
00186 GlyphId(FT_Face, const FT_UInt);
00187
00189 std::string str() const {return _str;}
00190
00191 private:
00193 std::string _str;
00194 };
00195
00198 typedef std::map<GlyphId, FreetypeGlyphMgr> GlyphMap;
00199
00204 typedef void (PostscriptDocument::*GLYPH_FUNC)(
00205 const GlyphMap::value_type&, void* contextData);
00206
00207 void invoke_glyph_routine(const GlyphMap::value_type&, void* contextData);
00208
00209 void accrue_dimensions( const GlyphMap::value_type&, void* contextData1);
00210
00213 void for_each_glyph_do(const std::string&, const GLYPH_FUNC, void* contextData);
00214
00215 PangoContext* pangoContext() const;
00216
00219 std::string glyphProcName() const;
00220
00223 double getFontSize() {return _fontSize;}
00224
00227 class write_glyph_routine_to_stream {
00228 private:
00229 std::ostream& os;
00230 PangoContext* pangoCtx;
00231
00232 public:
00233 write_glyph_routine_to_stream(std::ostream& os, PangoContext* pangoCtx)
00234 : os(os), pangoCtx(pangoCtx) {}
00235 void operator()(PostscriptDocument::GlyphMap::value_type v);
00236 };
00237
00238 private:
00239 GlyphMap _glyphMap;
00240
00241 static const unsigned int DRAWING_SCALE;
00242
00243
00244
00245 ContextMgr* _pContextMgr;
00246 double _fontSize;
00247 std::ostringstream _osHeader;
00248 oPostscriptStream _osBody;
00249 oPostscriptStream _osFooter;
00250 };
00251
00254 class LASIDLLIMPEXP setFont {
00255 public:
00258 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFont& x) {
00259 x.apply(os);
00260 return os;
00261 }
00262
00266 setFont(
00267 const char* const family = "sans",
00268 const LASi::FontStyle style = LASi::NORMAL_STYLE,
00269 const LASi::FontWeight weight = LASi::NORMAL_WEIGHT,
00270 const LASi::FontVariant variant = LASi::NORMAL_VARIANT,
00271 const LASi::FontStretch stretch = LASi::NORMAL_STRETCH )
00272 : _family(family), _style(style), _weight(weight), _variant(variant), _stretch(stretch)
00273 {}
00274
00275 protected:
00276 void apply(oPostscriptStream& os) const {
00277 os.doc().setFont(_family, _style,_weight, _variant, _stretch);
00278 }
00279
00280 private:
00281 const char* const _family;
00282 const LASi::FontStyle _style;
00283 const LASi::FontWeight _weight;
00284 const LASi::FontVariant _variant;
00285 const LASi::FontStretch _stretch;
00286
00287 };
00288
00291 class LASIDLLIMPEXP setFontSize {
00292 public:
00295 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFontSize& x) {
00296 x.apply(os);
00297 return os;
00298 }
00299
00304 setFontSize(double size) : _size(size) {}
00305
00306 protected:
00307 void apply(oPostscriptStream& os) const {
00308 os.doc().setFontSize(_size);
00309 }
00310
00311 private:
00312 double _size;
00313 };
00314
00317 class LASIDLLIMPEXP show{
00318 public:
00321 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const show& x) {
00322 x.apply(os);
00323 return os;
00324 }
00325
00329 show(const char* c_str ) : _str(c_str ) {}
00330 show(std::string stl_str ) : _str(stl_str) {}
00331
00332 protected:
00333 void apply(oPostscriptStream& os) const;
00334
00335 private:
00336 std::string _str;
00337 };
00338 }
00339 #endif
00340