wxArt2D
canvasfont.doxy
1 /*! \page howtoadda2dfont How to add a new a2dFont derivative
2 
3 This page describes briefly how to add a new font type to wxArt2D.
4 The majority of this page is some fundamental code.
5 It is mainly documented here, because, the font class is used in some other places,
6 where it should be added by hand.
7 
8 This document might become outdated. Although it is assumed the general trend will
9 be the same, details might changed, so please also check the source code of eg. the Stroke fonts.
10 
11 Unfortunately, at present a new font cannot be created separately from the library,
12 since adding a new font type, involves changing some routines in the library itself.
13 
14 It is assumed, that you want to add a font format named monkey.
15 
16 \section classdef Class definition.
17 
18 The class definition itself is pretty straightforward. The next example shows a typical
19 font class definition.
20 
21 \code
22 
23 //! Monkey font class.
24 /*!
25  Clas for monkey fonts (*.MKY). This is just a demo class.
26  \ingroup property style
27  \ingroup textrelated
28 */
29 class a2dFontMonkey
30  : public a2dFont
31 {
32 public:
33  //! Constructor.
34  /*! \param filename Filename of the vector font.
35  \param size Size in world coordinates.
36  */
37  a2dFontMonkey(const wxString& filename = wxT(""), double size = 0.0 );
38  //! Copy constructor.
39  a2dFontMonkey(const a2dFontMonkey& other);
40  //! Copy constructor.
41  a2dFontMonkey( const a2dFontMonkey& other, CloneOptions options );
42  //! Destructor.
43  virtual ~a2dFontMonkey();
44 
45  // Documented in base class
46  virtual wxRefObject* Clone( CloneOptions options ) const;
47 
48  //! Assignment operator.
49  a2dFontMonkey& operator = (const a2dFontMonkey& other);
50 
51  // Documented in base class
52  virtual bool operator == (const a2dFont& other) const;
53 
54  //! Set the font filename and load the font.
55  /*! \param filename The filename of the font. This may either be a full path, or just the
56  fontname. In the latter case, the fontpath of a2dCanvasGlobals will be used to search the font.
57  \sa a2dCanvasGlobal
58  */
59  void SetFilename(const wxString& filename);
60  //! Get the font filename.
61  /*! \param filenameonly The returned filename will be stripped of drive-letters and directories.
62  \return The filename of the font.
63  */
64  wxString GetFilename( bool filenameonly = false ) const;
65 
66  // Documented in base class
67  virtual double GetWidth( wxChar c ) const;
68 
69  // Documented in base class
70  virtual double GetKerning( wxChar c1, wxChar c2 ) const;
71 
72  // Documented in base class
73  static void GetInfoList( a2dFontInfoList& list );
74 
75  // Documented in base class
76  static a2dFont* CreateFont( const a2dFontInfo& info, bool force = false );
77 
78 protected:
79  //! Filename of the font.
80  wxString m_filename;
81 
82 private:
83  DECLARE_DYNAMIC_CLASS(a2dFontMonkey)
84 };
85 
86 \endcode
87 
88 \section classimp Class implementation.
89 
90 The class implementation is also straightforward.
91 
92 The problem you have to deal with is parsing the font. Also for improved
93 drawing speed, you might want to add some font caching here. (see also the
94 implementation of a2dFontFreetype::GetGlyph )
95 
96 The extra parameter of m_fontinfo is free to use for anything, but please keep in
97 mind, that this should allways be in text format. In general it will be used for
98 storing the filename of the font. (see also a2dFontInfo )
99 
100 
101 \code
102 
103 IMPLEMENT_DYNAMIC_CLASS( a2dFontMonkey, a2dFont )
104 
105 a2dFontMonkey::a2dFontMonkey(const wxString& filename, double size, int alignment)
106  : a2dFont(size, alignment)
107 {
108  m_fontinfo.SetType( wxT("Monkey font") );
109  SetFilename( filename );
110 }
111 
112 a2dFontMonkey::a2dFontMonkey( const a2dFontMonkey& other )
113  : a2dFont( other )
114 {
115  m_fontinfo.SetType( wxT("Monkey font") );
116  m_width = NULL;
117  m_characters = NULL;
118  m_weight = -1;
119  *this = other;
120 }
121 
122 a2dFontMonkey::a2dFontMonkey( const a2dFontMonkey& other, CloneOptions options )
123  : a2dFont( other, options )
124 {
125  m_width = NULL;
126  m_characters = NULL;
127  m_weight = -1;
128  SetFilename( other.m_filename );
129 }
130 
131 a2dFontMonkey::~a2dFontMonkey()
132 {
133  // delete font storage
134  delete .......
135 }
136 
137 wxRefObject* a2dFontMonkey::Clone( CloneOptions options ) const
138 {
139  return new a2dFontMonkey( *this, options );
140 }
141 
142 a2dFontMonkey& a2dFontMonkey::operator = ( const a2dFontMonkey& other )
143 {
144  a2dFont::operator = ( other );
145  SetFilename( m_filename );
146  return *this;
147 }
148 
149 bool a2dFontMonkey::operator == ( const a2dFont& other ) const
150 {
151  a2dFontMonkey* mkyfont = wxDynamicCast( &other, a2dFontMonkey );
152  return (mkyfont) && a2dFont::operator == ( other )
153  && ( m_filename == mkyfont->m_filename );
154 }
155 
156 wxString a2dFontMonkey::GetFilename(bool filenameonly) const
157 {
158  if ( filenameonly )
159  {
160  wxFileName filename( m_filename );
161  return filename.GetFullName();
162  }
163  else
164  return m_filename;
165 }
166 
167 void a2dFontMonkey::SetFilename(const wxString& filename)
168 {
169  m_ok = false;
170 
171  // delete previous font storage
172  delete .......
173 
174  m_filename = filename;
175  if ( m_filename.IsEmpty() )
176  return;
177 
178  wxString fname = a2dCanvasGlobals->GetFontPathList().FindValidPath( m_filename );
179 
180  // open file and proces font data.
181 
182  ...........
183  size = ...... // something loaded
184 
185 
186  // Set getextextent params normalized to the font height.
187  m_height = .... / size;
188  m_desc = .... / size;
189  m_lead = ..... / size; // or just 0.0;
190 
191  // If succesfull:
192  m_ok = true;
193 }
194 
195 double a2dFontMonkey::GetWidth( wxChar c ) const
196 {
197  if ( !m_ok )
198  return 0.0;
199 
200  return m_size * ..... // width of character c;
201 }
202 
203 double a2dFontMonkey::GetKerning( wxChar c1, wxChar c2 ) const
204 {
205  if ( !m_ok )
206  return 0.0;
207 
208  return m_size * ..... // kerning between c1 and c2;
209 }
210 
211 // create a list of fonts for the font selection dialog.
212 void a2dFontMonkey::GetInfoList( a2dFontInfoList& list )
213 {
214  wxPathList& pathlist = a2dCanvasGlobals->GetFontPathList();
215  for ( wxPathList::Node *node = pathlist.GetFirst(); node; node = node->GetNext() )
216  {
217  wxString path(node->GetData());
218  if (!wxDir::Exists( path ) )
219  continue;
220 
221  wxArrayString files;
222  wxDir::GetAllFiles( path, &files, wxT("*.mky"), wxDIR_FILES );
223  for ( unsigned int i = 0; i < files.GetCount(); i++)
224  {
225  wxFileName filename( files.Item(i) );
226 
227  // get font name and style parameters.
228  wxString fontname = ....
229  wxString stylename = ....
230 
231  // set font style for selection dialog.
232  list.Append( new a2dFontInfo(
233  wxT("Monkey font"), fontname, stylename, filename.GetFullName() ));
234  }
235  }
236 }
237 
238 // try to make a font from the fontinfo.
239 a2dFont* a2dFontMonkey::CreateFont( const a2dFontInfo& info, bool force )
240 {
241  // todo implement search for alternatives, see a2dFontFreetype::CreateFont()
242  if ( info.GetType() == wxT("Monkey font") && !info.GetExtra().IsEmpty() )
243  {
244  a2dFontMonkey* font = new a2dFontMonkey( info.GetExtra(),
245  info.GetSize(), info.GetAlignment() );
246  return font;
247  }
248  else
249  return NULL;
250 }
251 
252 \endcode
253 
254 
255 
256 \section morethings More things to do.
257 
258 Now that we have a font class, with some a Createfont class does not mean, that
259 the font can now be created in a general way. The applications, do not know of
260 the existance of specific font classes. Therefore they will call a2dFont::CreateFont.
261 To enable the creation of your font, you should add this method to
262 - (stylebase.cpp) a2dFont* a2dFont::CreateFont( const a2dFontInfo& info );
263 
264 Also to be able to select the font using the font selection dialog, add your class to:
265 - (stylebase.cpp) void a2dFont::GetInfoList( a2dFontInfoList& list );
266 
267 
268 \section drawing Drawing of the font
269 
270 Add a specific monkey font drawing routines to the wxDrawer2D header:
271 - (drawer2d.h) virtual void wxDrawer2D::DrawTextMonkey( const wxString& text, double x, double y ) { DrawTextGeneric( text, x, y, &wxDcDrawer::DrawCharMonkeyCb ); }
272 - (drawer2d.h) virtual void wxDrawer2D::DrawCharMonkey( wxChar c ) { DrawCharUnknown( c ); }
273 - (drawer2d.h) void wxDrawer2D::DrawCharMonkeyCb( wxChar c ) { DrawCharMonkey( c ); }
274 
275 The last line is a wrapper for the DrawChar function. It seems redundant, but Iso C++ does not
276 allow anymore to call a virtual member directly.
277 
278 The font drawing will be invokated through DrawText. To let this know of the
279 existance of the monkey font class, you should add this newly created method to:
280 - (drawer2d.cpp) void wxDrawer2D::DrawText( const wxString& text, double x, double y );
281 
282 Now, at minimum, implement the font drawing in wxDcDrawer.
283 
284 The drawing routines are seperated in two routines. The first parses the string and calls the
285 second one to draw each character. The first is allready supplied, but might be overruled,
286 to set text colours, etc.
287 
288 \code
289 void wxDrawer2D::DrawTextMonkey( const wxString& text, double x, double y )
290 {
291  // Set text colour.
292  ...
293 
294  // Call generic string parsing routine.
295  DrawTextGeneric( text, x, y, (void (wxDrawer2D::*)( wxChar )) &wxDcDrawer::DrawCharMonkeyCb );
296 }
297 \endcode
298 
299 The implementation of the character drawing routine can fully concentrate on drawing
300 the character. The calling routine allready took care of performing all necessary affine
301 transforms. The origin (0, 0) is set at the lower left bounding box of the character.
302 Depending on the font, scaling to size should still be performed here.
303 
304 \code
305 void wxDcDrawer::DrawCharMonkey( wxChar c )
306 {
307  // Draw the character here.
308  a2dFontStroke* mkyfont = wxDynamicCast( m_currentfont.Get(), a2dFontMonkey );
309 
310  // save context
311  a2dAffineMatrix oldaffine = GetTransform();
312 
313  // scale character to size
314  a2dAffineMatrix affine;
315  affine.Scale( mkyfont->GetSize() );
316  SetTransForm( oldaffine * affine );
317 
318  // do actual drawing here.
319 
320  // restore context
321  SetTransForm( oldaffine );
322 }
323 \endcode
324 
325 So now finally the font should work.
326 
327 \par
328 
329 */
canvasfont.doxy Source File -- Sun Oct 12 2014 17:04:14 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation