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::PostscriptDocument();
00092 PostscriptDocument::~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
00125 void write(std::ostream& os);
00126
00133 void get_dimensions(const char* s, double *lineSpacing, double *xAdvance=NULL, double *yMin=NULL, double *yMax=NULL);
00134
00135 protected:
00140 class GlyphId {
00141 public:
00142 friend bool operator==(const GlyphId id1, const GlyphId id2) {
00143 return id1._str == id2._str;
00144 }
00145
00146 friend bool operator<(const GlyphId id1, const GlyphId id2) {
00147 return id1._str < id2._str;
00148 }
00149
00150 GlyphId() {}
00151 GlyphId(FT_Face, const FT_UInt);
00152
00154 std::string str() const {return _str;}
00155
00156 private:
00158 std::string _str;
00159 };
00160
00163 typedef std::map<GlyphId, FreetypeGlyphMgr> GlyphMap;
00164
00169 typedef void (PostscriptDocument::*GLYPH_FUNC)(
00170 const GlyphMap::value_type&, void* contextData);
00171
00172 void invoke_glyph_routine(const GlyphMap::value_type&, void* contextData);
00173
00174 void accrue_dimensions( const GlyphMap::value_type&, void* contextData1);
00175
00178 void for_each_glyph_do(const std::string&, const GLYPH_FUNC, void* contextData);
00179
00180 PangoContext* PostscriptDocument::pangoContext() const;
00181
00184 std::string glyphProcName() const;
00185
00188 double getFontSize() {return _fontSize;}
00189
00192 class write_glyph_routine_to_stream {
00193 private:
00194 std::ostream& os;
00195 PangoContext* pangoCtx;
00196
00197 public:
00198 write_glyph_routine_to_stream(std::ostream& os, PangoContext* pangoCtx)
00199 : os(os), pangoCtx(pangoCtx) {}
00200 void operator()(PostscriptDocument::GlyphMap::value_type v);
00201 };
00202
00203 private:
00204 GlyphMap _glyphMap;
00205
00206 static const unsigned int DRAWING_SCALE;
00207
00208
00209
00210 ContextMgr* _pContextMgr;
00211 double _fontSize;
00212 std::ostringstream _osHeader;
00213 oPostscriptStream _osBody;
00214 oPostscriptStream _osFooter;
00215 };
00216
00219 class setFont {
00220 public:
00223 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFont& x) {
00224 x.apply(os);
00225 return os;
00226 }
00227
00231 setFont(
00232 const char* const family = "sans",
00233 const LASi::FontStyle style = LASi::NORMAL_STYLE,
00234 const LASi::FontWeight weight = LASi::NORMAL_WEIGHT,
00235 const LASi::FontVariant variant = LASi::NORMAL_VARIANT,
00236 const LASi::FontStretch stretch = LASi::NORMAL_STRETCH )
00237 : _family(family), _style(style), _weight(weight), _variant(variant), _stretch(stretch)
00238 {}
00239
00240 protected:
00241 void apply(oPostscriptStream& os) const {
00242 os.doc().setFont(_family, _style,_weight, _variant, _stretch);
00243 }
00244
00245 private:
00246 const char* const _family;
00247 const LASi::FontStyle _style;
00248 const LASi::FontWeight _weight;
00249 const LASi::FontVariant _variant;
00250 const LASi::FontStretch _stretch;
00251
00252 };
00253
00256 class setFontSize {
00257 public:
00260 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const setFontSize& x) {
00261 x.apply(os);
00262 return os;
00263 }
00264
00269 setFontSize(double size) : _size(size) {}
00270
00271 protected:
00272 void apply(oPostscriptStream& os) const {
00273 os.doc().setFontSize(_size);
00274 }
00275
00276 private:
00277 double _size;
00278 };
00279
00282 class show{
00283 public:
00286 friend inline oPostscriptStream& operator<<(oPostscriptStream& os, const show& x) {
00287 x.apply(os);
00288 return os;
00289 }
00290
00294 show(const char* str) : _str(str) {}
00295
00296 protected:
00297 void apply(oPostscriptStream& os) const;
00298
00299 private:
00300 std::string _str;
00301 };
00302 }
00303 #endif
00304