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 namespace LASi {
00020
00021 enum FontStyle{
00022 NORMAL_STYLE,
00023 OBLIQUE,
00024 ITALIC
00025 };
00026
00027 enum FontWeight{
00028 ULTRALIGHT,
00029 LIGHT,
00030 NORMAL_WEIGHT,
00031 BOLD,
00032 ULTRABOLD,
00033 HEAVY
00034 };
00035
00036 enum FontVariant{
00037 NORMAL_VARIANT,
00038 SMALLCAPS
00039 };
00040
00041 enum FontStretch{
00042 ULTRACONDENSED,
00043 EXTRACONDENSED,
00044 CONDENSED,
00045 SEMICONDENSED,
00046 NORMAL_STRETCH,
00047 SEMIEXPANDED,
00048 EXPANDED,
00049 EXTRAEXPANDED,
00050 ULTRAEXPANDED
00051 };
00052
00053 class PostscriptDocument;
00054 class write_glyph_routine_to_stream;
00055
00059 class oPostscriptStream : public std::ostringstream {
00060 public:
00061 friend class PostscriptDocument;
00062 friend class show;
00063 friend class setFont;
00064 friend class setFontSize;
00065
00066 oPostscriptStream(PostscriptDocument& psDoc) : _psDoc(psDoc) {}
00067
00068 protected:
00069 PostscriptDocument& doc() {return _psDoc;}
00070
00071 private:
00072 PostscriptDocument& _psDoc;
00073 };
00074
00075 template<class T>
00076 inline oPostscriptStream& operator<<(oPostscriptStream& os, T t) {
00077 static_cast<std::ostream&>(os) << t;
00078 return os;
00079 }
00080
00086 class PostscriptDocument {
00087 public:
00088 friend class write_glyph_routine_to_stream;
00089 friend class show;
00090
00091 PostscriptDocument();
00092 ~PostscriptDocument();
00093
00097 void setFont(
00098 const char* const family = "sans",
00099 LASi::FontStyle = LASi::NORMAL_STYLE,
00100 LASi::FontWeight = LASi::NORMAL_WEIGHT,
00101 LASi::FontVariant = LASi::NORMAL_VARIANT,
00102 LASi::FontStretch = LASi::NORMAL_STRETCH
00103 );
00104
00108 void setFontSize(const double size) {_fontSize = size;}
00109
00112 std::ostringstream& osHeader() {return _osHeader;}
00113
00116 oPostscriptStream& osBody() {return _osBody;}
00117
00120 oPostscriptStream& osFooter() {return _osFooter;}
00121
00131 void write(std::ostream& os, double llx=0, double lly=0, double urx=0, double ury=0);
00132
00139 void get_dimensions(const char* s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00140 void get_dimensions(std::string s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00141
00142 protected:
00147 class GlyphId {
00148 public:
00149 friend bool operator==(const GlyphId id1, const GlyphId id2) {
00150 return id1._str == id2._str;
00151 }
00152
00153 friend bool operator<(const GlyphId id1, const GlyphId id2) {
00154 return id1._str < id2._str;
00155 }
00156
00157 GlyphId() {}
00158 GlyphId(FT_Face, const FT_UInt);
00159
00161 std::string str() const {return _str;}
00162
00163 private:
00165 std::string _str;
00166 };
00167
00170 typedef std::map<GlyphId, FreetypeGlyphMgr> GlyphMap;
00171
00176 typedef void (PostscriptDocument::*GLYPH_FUNC)(
00177 const GlyphMap::value_type&, void* contextData);
00178
00179 void invoke_glyph_routine(const GlyphMap::value_type&, void* contextData);
00180
00181 void accrue_dimensions( const GlyphMap::value_type&, void* contextData1);
00182
00185 void for_each_glyph_do(const std::string&, const GLYPH_FUNC, void* contextData);
00186
00187 PangoContext* pangoContext() const;
00188
00191 std::string glyphProcName() const;
00192
00195 double getFontSize() {return _fontSize;}
00196
00199 class write_glyph_routine_to_stream {
00200 private:
00201 std::ostream& os;
00202 PangoContext* pangoCtx;
00203
00204 public:
00205 write_glyph_routine_to_stream(std::ostream& os, PangoContext* pangoCtx)
00206 : os(os), pangoCtx(pangoCtx) {}
00207 void operator()(PostscriptDocument::GlyphMap::value_type v);
00208 };
00209
00210 private:
00211 GlyphMap _glyphMap;
00212
00213 static const unsigned int DRAWING_SCALE;
00214
00215
00216
00217 ContextMgr* _pContextMgr;
00218 double _fontSize;
00219 std::ostringstream _osHeader;
00220 oPostscriptStream _osBody;
00221 oPostscriptStream _osFooter;
00222 };
00223
00226 class setFont {
00227 public:
00230 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFont& x) {
00231 x.apply(os);
00232 return os;
00233 }
00234
00238 setFont(
00239 const char* const family = "sans",
00240 const LASi::FontStyle style = LASi::NORMAL_STYLE,
00241 const LASi::FontWeight weight = LASi::NORMAL_WEIGHT,
00242 const LASi::FontVariant variant = LASi::NORMAL_VARIANT,
00243 const LASi::FontStretch stretch = LASi::NORMAL_STRETCH )
00244 : _family(family), _style(style), _weight(weight), _variant(variant), _stretch(stretch)
00245 {}
00246
00247 protected:
00248 void apply(oPostscriptStream& os) const {
00249 os.doc().setFont(_family, _style,_weight, _variant, _stretch);
00250 }
00251
00252 private:
00253 const char* const _family;
00254 const LASi::FontStyle _style;
00255 const LASi::FontWeight _weight;
00256 const LASi::FontVariant _variant;
00257 const LASi::FontStretch _stretch;
00258
00259 };
00260
00263 class setFontSize {
00264 public:
00267 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFontSize& x) {
00268 x.apply(os);
00269 return os;
00270 }
00271
00276 setFontSize(double size) : _size(size) {}
00277
00278 protected:
00279 void apply(oPostscriptStream& os) const {
00280 os.doc().setFontSize(_size);
00281 }
00282
00283 private:
00284 double _size;
00285 };
00286
00289 class show{
00290 public:
00293 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const show& x) {
00294 x.apply(os);
00295 return os;
00296 }
00297
00301 show(const char* c_str ) : _str(c_str ) {}
00302 show(std::string stl_str ) : _str(stl_str) {}
00303
00304 protected:
00305 void apply(oPostscriptStream& os) const;
00306
00307 private:
00308 std::string _str;
00309 };
00310 }
00311 #endif
00312