00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 class a2dFontMonkey
00030 : public a2dFont
00031 {
00032 public:
00033
00034
00035
00036
00037 a2dFontMonkey(const wxString& filename = wxT(""), double size = 0.0 );
00038
00039 a2dFontMonkey(const a2dFontMonkey& other);
00040
00041 a2dFontMonkey( const a2dFontMonkey& other, CloneOptions options );
00042
00043 virtual ~a2dFontMonkey();
00044
00045 // Documented in base class
00046 virtual wxRefObject* Clone( CloneOptions options ) const;
00047
00048
00049 a2dFontMonkey& operator = (const a2dFontMonkey& other);
00050
00051 // Documented in base class
00052 virtual bool operator == (const a2dFont& other) const;
00053
00054
00055
00056
00057
00058
00059 void SetFilename(const wxString& filename);
00060
00061
00062
00063
00064 wxString GetFilename( bool filenameonly = false ) const;
00065
00066 // Documented in base class
00067 virtual double GetWidth( wxChar c ) const;
00068
00069 // Documented in base class
00070 virtual double GetKerning( wxChar c1, wxChar c2 ) const;
00071
00072 // Documented in base class
00073 static void GetInfoList( a2dFontInfoList& list );
00074
00075 // Documented in base class
00076 static a2dFont* CreateFont( const a2dFontInfo& info, bool force = false );
00077
00078 protected:
00079
00080 wxString m_filename;
00081
00082 private:
00083 DECLARE_DYNAMIC_CLASS(a2dFontMonkey)
00084 };
00085
00086 \endcode
00087
00088 \section classimp Class implementation.
00089
00090 The class implementation is also straightforward.
00091
00092 The problem you have to deal with is parsing the font. Also for improved
00093 drawing speed, you might want to add some font caching here. (see also the
00094 implementation of a2dFontFreetype::GetGlyph )
00095
00096 The extra parameter of m_fontinfo is free to use for anything, but please keep in
00097 mind, that this should allways be in text format. In general it will be used for
00098 storing the filename of the font. (see also a2dFontInfo )
00099
00100
00101 \code
00102
00103 IMPLEMENT_DYNAMIC_CLASS( a2dFontMonkey, a2dFont )
00104
00105 a2dFontMonkey::a2dFontMonkey(const wxString& filename, double size, int alignment)
00106 : a2dFont(size, alignment)
00107 {
00108 m_fontinfo.SetType( wxT("Monkey font") );
00109 SetFilename( filename );
00110 }
00111
00112 a2dFontMonkey::a2dFontMonkey( const a2dFontMonkey& other )
00113 : a2dFont( other )
00114 {
00115 m_fontinfo.SetType( wxT("Monkey font") );
00116 m_width = NULL;
00117 m_characters = NULL;
00118 m_weight = -1;
00119 *this = other;
00120 }
00121
00122 a2dFontMonkey::a2dFontMonkey( const a2dFontMonkey& other, CloneOptions options )
00123 : a2dFont( other, options )
00124 {
00125 m_width = NULL;
00126 m_characters = NULL;
00127 m_weight = -1;
00128 SetFilename( other.m_filename );
00129 }
00130
00131 a2dFontMonkey::~a2dFontMonkey()
00132 {
00133 // delete font storage
00134 delete .......
00135 }
00136
00137 wxRefObject* a2dFontMonkey::Clone( CloneOptions options ) const
00138 {
00139 return new a2dFontMonkey( *this, options );
00140 }
00141
00142 a2dFontMonkey& a2dFontMonkey::operator = ( const a2dFontMonkey& other )
00143 {
00144 a2dFont::operator = ( other );
00145 SetFilename( m_filename );
00146 return *this;
00147 }
00148
00149 bool a2dFontMonkey::operator == ( const a2dFont& other ) const
00150 {
00151 a2dFontMonkey* mkyfont = wxDynamicCast( &other, a2dFontMonkey );
00152 return (mkyfont) && a2dFont::operator == ( other )
00153 && ( m_filename == mkyfont->m_filename );
00154 }
00155
00156 wxString a2dFontMonkey::GetFilename(bool filenameonly) const
00157 {
00158 if ( filenameonly )
00159 {
00160 wxFileName filename( m_filename );
00161 return filename.GetFullName();
00162 }
00163 else
00164 return m_filename;
00165 }
00166
00167 void a2dFontMonkey::SetFilename(const wxString& filename)
00168 {
00169 m_ok = false;
00170
00171 // delete previous font storage
00172 delete .......
00173
00174 m_filename = filename;
00175 if ( m_filename.IsEmpty() )
00176 return;
00177
00178 wxString fname = a2dCanvasGlobals->GetFontPathList().FindValidPath( m_filename );
00179
00180 // open file and proces font data.
00181
00182 ...........
00183 size = ...... // something loaded
00184
00185
00186 // Set getextextent params normalized to the font height.
00187 m_height = .... / size;
00188 m_desc = .... / size;
00189 m_lead = ..... / size; // or just 0.0;
00190
00191 // If succesfull:
00192 m_ok = true;
00193 }
00194
00195 double a2dFontMonkey::GetWidth( wxChar c ) const
00196 {
00197 if ( !m_ok )
00198 return 0.0;
00199
00200 return m_size * ..... // width of character c;
00201 }
00202
00203 double a2dFontMonkey::GetKerning( wxChar c1, wxChar c2 ) const
00204 {
00205 if ( !m_ok )
00206 return 0.0;
00207
00208 return m_size * ..... // kerning between c1 and c2;
00209 }
00210
00211 // create a list of fonts for the font selection dialog.
00212 void a2dFontMonkey::GetInfoList( a2dFontInfoList& list )
00213 {
00214 wxPathList& pathlist = a2dCanvasGlobals->GetFontPathList();
00215 for ( wxPathList::Node *node = pathlist.GetFirst(); node; node = node->GetNext() )
00216 {
00217 wxString path(node->GetData());
00218 if (!wxDir::Exists( path ) )
00219 continue;
00220
00221 wxArrayString files;
00222 wxDir::GetAllFiles( path, &files, wxT("*.mky"), wxDIR_FILES );
00223 for ( unsigned int i = 0; i < files.GetCount(); i++)
00224 {
00225 wxFileName filename( files.Item(i) );
00226
00227 // get font name and style parameters.
00228 wxString fontname = ....
00229 wxString stylename = ....
00230
00231 // set font style for selection dialog.
00232 list.Append( new a2dFontInfo(
00233 wxT("Monkey font"), fontname, stylename, filename.GetFullName() ));
00234 }
00235 }
00236 }
00237
00238 // try to make a font from the fontinfo.
00239 a2dFont* a2dFontMonkey::CreateFont( const a2dFontInfo& info, bool force )
00240 {
00241 // todo implement search for alternatives, see a2dFontFreetype::CreateFont()
00242 if ( info.GetType() == wxT("Monkey font") && !info.GetExtra().IsEmpty() )
00243 {
00244 a2dFontMonkey* font = new a2dFontMonkey( info.GetExtra(),
00245 info.GetSize(), info.GetAlignment() );
00246 return font;
00247 }
00248 else
00249 return NULL;
00250 }
00251
00252 \endcode
00253
00254
00255
00256 \section morethings More things to do.
00257
00258 Now that we have a font class, with some a Createfont class does not mean, that
00259 the font can now be created in a general way. The applications, do not know of
00260 the existance of specific font classes. Therefore they will call a2dFont::CreateFont.
00261 To enable the creation of your font, you should add this method to
00262 - (stylebase.cpp) a2dFont* a2dFont::CreateFont( const a2dFontInfo& info );
00263
00264 Also to be able to select the font using the font selection dialog, add your class to:
00265 - (stylebase.cpp) void a2dFont::GetInfoList( a2dFontInfoList& list );
00266
00267
00268 \section drawing Drawing of the font
00269
00270 Add a specific monkey font drawing routines to the wxDrawer2D header:
00271 - (drawer2d.h) virtual void wxDrawer2D::DrawTextMonkey( const wxString& text, double x, double y ) { DrawTextGeneric( text, x, y, &wxDcDrawer::DrawCharMonkeyCb ); }
00272 - (drawer2d.h) virtual void wxDrawer2D::DrawCharMonkey( wxChar c ) { DrawCharUnknown( c ); }
00273 - (drawer2d.h) void wxDrawer2D::DrawCharMonkeyCb( wxChar c ) { DrawCharMonkey( c ); }
00274
00275 The last line is a wrapper for the DrawChar function. It seems redundant, but Iso C++ does not
00276 allow anymore to call a virtual member directly.
00277
00278 The font drawing will be invokated through DrawText. To let this know of the
00279 existance of the monkey font class, you should add this newly created method to:
00280 - (drawer2d.cpp) void wxDrawer2D::DrawText( const wxString& text, double x, double y );
00281
00282 Now, at minimum, implement the font drawing in wxDcDrawer.
00283
00284 The drawing routines are seperated in two routines. The first parses the string and calls the
00285 second one to draw each character. The first is allready supplied, but might be overruled,
00286 to set text colours, etc.
00287
00288 \code
00289 void wxDrawer2D::DrawTextMonkey( const wxString& text, double x, double y )
00290 {
00291 // Set text colour.
00292 ...
00293
00294 // Call generic string parsing routine.
00295 DrawTextGeneric( text, x, y, (void (wxDrawer2D::*)( wxChar )) &wxDcDrawer::DrawCharMonkeyCb );
00296 }
00297 \endcode
00298
00299 The implementation of the character drawing routine can fully concentrate on drawing
00300 the character. The calling routine allready took care of performing all necessary affine
00301 transforms. The origin (0, 0) is set at the lower left bounding box of the character.
00302 Depending on the font, scaling to size should still be performed here.
00303
00304 \code
00305 void wxDcDrawer::DrawCharMonkey( wxChar c )
00306 {
00307 // Draw the character here.
00308 a2dFontStroke* mkyfont = wxDynamicCast( m_currentfont.Get(), a2dFontMonkey );
00309
00310 // save context
00311 a2dAffineMatrix oldaffine = GetTransform();
00312
00313 // scale character to size
00314 a2dAffineMatrix affine;
00315 affine.Scale( mkyfont->GetSize() );
00316 SetTransForm( oldaffine * affine );
00317
00318 // do actual drawing here.
00319
00320 // restore context
00321 SetTransForm( oldaffine );
00322 }
00323 \endcode
00324
00325 So now finally the font should work.
00326
00327 \par
00328
00329 */