* Add "less" target to view make output through less.
[matthijs/ABM2.git] / ABM2 / Amaltheia / myFont.cpp
1 #include <amaltheia/Graphics.h> 
2
3 #include <GL/gl.h>
4 #include <GL/glu.h>
5
6
7 #include <cassert>
8 #include <string> // For memset
9 #include <ft2build.h>
10 #include <freetype/freetype.h>
11 #include <freetype/ftglyph.h>
12 #include <freetype/ftoutln.h>
13 #include <freetype/fttrigon.h>
14
15
16 Graphics *g;
17
18 //#include "FTGLTextureFont.h"
19 //#include "FTTextureGlyph.h"
20 typedef double   FTGL_DOUBLE;
21 typedef float    FTGL_FLOAT;
22
23 // Fixes for deprecated identifiers in 2.1.5
24 #ifndef FT_OPEN_MEMORY
25 #define FT_OPEN_MEMORY (FT_Open_Flags)1
26 #endif
27
28 #ifndef FT_RENDER_MODE_MONO
29 #define FT_RENDER_MODE_MONO ft_render_mode_mono
30 #endif
31
32 #ifndef FT_RENDER_MODE_NORMAL
33 #define FT_RENDER_MODE_NORMAL ft_render_mode_normal
34 #endif
35
36
37
38
39
40 inline unsigned int NextPowerOf2( unsigned int in)
41 {
42         in -= 1;
43
44         in |= in >> 16;
45         in |= in >> 8;
46         in |= in >> 4;
47         in |= in >> 2;
48         in |= in >> 1;
49
50         return in + 1;
51 }
52
53
54 class FTPoint
55 {
56         public:
57                 FTPoint()
58                 {
59                         values[0] = 0;
60                         values[1] = 0;
61                         values[2] = 0;
62                 }
63                 FTPoint( const double x, const double y, const double z)
64                 {
65                         values[0] = x;
66                         values[1] = y;
67                         values[2] = z;
68                 }
69         
70                 FTPoint( const FT_Vector& ft_vector)
71                 {
72                         values[0] = ft_vector.x;
73                         values[1] = ft_vector.y;
74                         values[2] = 0;
75                 }
76         
77                 FTPoint& operator += ( const FTPoint& point)
78                 {
79                         values[0] += point.values[0];
80                         values[1] += point.values[1];
81                         values[2] += point.values[2];
82
83                         return *this;
84                 }
85
86                 FTPoint operator + ( const FTPoint& point)
87                 {
88                         FTPoint temp;
89                         temp.values[0] = values[0] + point.values[0];
90                         temp.values[1] = values[1] + point.values[1];
91                         temp.values[2] = values[2] + point.values[2];
92
93                         return temp;
94                 }
95         
96                 FTPoint operator * ( double multiplier)
97                 {
98                         FTPoint temp;
99                         temp.values[0] = values[0] * multiplier;
100                         temp.values[1] = values[1] * multiplier;
101                         temp.values[2] = values[2] * multiplier;
102
103                         return temp;
104                 }
105         
106         
107                 friend FTPoint operator*( double multiplier, FTPoint& point);
108                 friend bool operator == ( const FTPoint &a, const FTPoint &b);
109                 friend bool operator != ( const FTPoint &a, const FTPoint &b);
110                 operator const double*() const
111                 {
112                         return values;
113                 }
114                 void X( double x) { values[0] = x;};
115                 void Y( double y) { values[1] = y;};
116                 void Z( double z) { values[2] = z;};
117                 double X() const { return values[0];};
118                 double Y() const { return values[1];};
119                 double Z() const { return values[2];};
120         
121         private:
122                 double values[3];
123 };
124
125 bool operator == ( const FTPoint &a, const FTPoint &b) 
126 {
127         return((a.values[0] == b.values[0]) && (a.values[1] == b.values[1]) && (a.values[2] == b.values[2]));
128 }
129
130 bool operator != ( const FTPoint &a, const FTPoint &b) 
131 {
132         return((a.values[0] != b.values[0]) || (a.values[1] != b.values[1]) || (a.values[2] != b.values[2]));
133 }
134
135 FTPoint operator*( double multiplier, FTPoint& point)
136 {
137         return point * multiplier;
138 }
139
140
141 class FTBBox
142 {
143         public:
144                 
145                 FTBBox()
146         :   lowerX(0.0f),
147                 lowerY(0.0f),
148                 lowerZ(0.0f),
149                 upperX(0.0f),
150                 upperY(0.0f),
151                 upperZ(0.0f)
152                 {}
153         
154         FTBBox( float lx, float ly, float lz, float ux, float uy, float uz)
155         :   lowerX(lx),
156                 lowerY(ly),
157                 lowerZ(lz),
158                 upperX(ux),
159                 upperY(uy),
160                 upperZ(uz)
161                 {}
162         
163         
164                 FTBBox( FT_GlyphSlot glyph)
165         :   lowerX(0.0f),
166                 lowerY(0.0f),
167                 lowerZ(0.0f),
168                 upperX(0.0f),
169                 upperY(0.0f),
170                 upperZ(0.0f)
171                 {
172                         FT_BBox bbox;
173                         FT_Outline_Get_CBox( &(glyph->outline), &bbox);
174
175                         lowerX = static_cast<float>( bbox.xMin) / 64.0f;
176                         lowerY = static_cast<float>( bbox.yMin) / 64.0f;
177                         lowerZ = 0.0f;
178                         upperX = static_cast<float>( bbox.xMax) / 64.0f;
179                         upperY = static_cast<float>( bbox.yMax) / 64.0f;
180                         upperZ = 0.0f;
181             
182                 }       
183
184                 ~FTBBox()
185                 {}
186         
187                 FTBBox& Move( FTPoint distance)
188                 {
189                         lowerX += distance.X();
190                         lowerY += distance.Y();
191                         lowerZ += distance.Z();
192                         upperX += distance.X();
193                         upperY += distance.Y();
194                         upperZ += distance.Z();
195                         return *this;
196                 }
197
198                 FTBBox& operator += ( const FTBBox& bbox) 
199                 {
200                         lowerX = bbox.lowerX < lowerX? bbox.lowerX: lowerX; 
201                         lowerY = bbox.lowerY < lowerY? bbox.lowerY: lowerY;
202                         lowerZ = bbox.lowerZ < lowerZ? bbox.lowerZ: lowerZ; 
203                         upperX = bbox.upperX > upperX? bbox.upperX: upperX; 
204                         upperY = bbox.upperY > upperY? bbox.upperY: upperY; 
205                         upperZ = bbox.upperZ > upperZ? bbox.upperZ: upperZ; 
206             
207                         return *this;
208                 }
209         
210                 void SetDepth( float depth)
211                 {
212                         upperZ = lowerZ + depth;
213                 }
214         
215                 float lowerX, lowerY, lowerZ, upperX, upperY, upperZ;
216         protected:
217     
218         private:
219 };
220
221
222
223
224
225 class FTGlyph
226 {
227         public:
228                 FTGlyph( FT_GlyphSlot glyph, bool useList = true)
229                 {
230                         useDisplayList = useList;
231                         err = 0;
232                         if( glyph)
233                         {
234                                 bBox = FTBBox( glyph);
235                                 advance = FTPoint( glyph->advance.x / 64.0f, glyph->advance.y / 64.0f, 0.0f);
236                         }
237                 }
238
239                 virtual FTGlyph::~FTGlyph()
240                 {}
241                 
242                 virtual const FTPoint& Render( const FTPoint& pen) = 0;
243       const FTPoint& Advance() const { return advance;}
244                 const FTBBox& BBox() const { return bBox;}
245                 FT_Error Error() const { return err;}
246         
247         protected:
248                 FTPoint advance;
249                 FTBBox bBox;
250                 bool useDisplayList;
251                 FT_Error err;
252         
253         private:
254 };
255
256
257
258
259
260
261 class FTLibrary
262 {
263         public:
264                 static const FTLibrary& Instance();
265                 const FT_Library* const GetLibrary() const { return library;}
266                 FT_Error Error() const { return err;}
267                 ~FTLibrary();
268         
269         private:
270                 FTLibrary();
271                 FTLibrary( const FT_Library&){}
272                 FTLibrary& operator=( const FT_Library&) { return *this; }
273         
274                 bool Initialise();
275                 FT_Library* library;
276                 FT_Error err;
277         
278 };
279
280
281
282
283 const FTLibrary&  FTLibrary::Instance()
284 {
285         static FTLibrary ftlib;
286         return ftlib;
287 }
288
289
290 FTLibrary::~FTLibrary()
291 {
292         if( library != 0)
293         {
294                 FT_Done_FreeType( *library);
295
296                 delete library;
297                 library= 0;
298         }
299
300 //  if( manager != 0)
301 //  {
302 //      FTC_Manager_Done( manager );
303         //
304 //      delete manager;
305 //      manager= 0;
306 //  }
307 }
308
309
310 FTLibrary::FTLibrary()
311         :   library(0),
312     err(0)
313 {
314         Initialise();
315 }
316
317
318 bool FTLibrary::Initialise()
319 {
320         if( library != 0)
321                 return true;
322
323         library = new FT_Library;
324     
325         err = FT_Init_FreeType( library);
326         if( err)
327         {
328                 delete library;
329                 library = 0;
330                 return false;
331         }
332     
333 //  FTC_Manager* manager;
334         //  
335 //  if( FTC_Manager_New( lib, 0, 0, 0, my_face_requester, 0, manager )
336 //  {
337 //      delete manager;
338 //      manager= 0;
339 //      return false;
340 //  }
341
342         return true;
343 }
344
345
346
347
348 class FTSize
349 {
350         public:
351                 FTSize();
352                 virtual ~FTSize();
353                 bool CharSize( FT_Face* face, unsigned int point_size, unsigned int x_resolution, unsigned int y_resolution);
354                 unsigned int CharSize() const;
355                 float Ascender() const;
356                 float Descender() const;
357                 float Height() const;
358                 float Width() const;
359                 float Underline() const;
360                 FT_Error Error() const { return err; }
361         
362         private:
363                 FT_Face* ftFace;
364                 FT_Size ftSize;
365                 unsigned int size;
366                 unsigned int xResolution;
367                 unsigned int yResolution;
368                 FT_Error err;
369         
370 };
371
372
373
374 FTSize::FTSize()
375         :   ftFace(0),
376     ftSize(0),
377          size(0),
378          xResolution(0),
379          yResolution(0),
380          err(0)
381 {}
382
383
384          FTSize::~FTSize()
385          {}
386
387
388          bool FTSize::CharSize( FT_Face* face, unsigned int pointSize, unsigned int xRes, unsigned int yRes )
389          {
390                  if( size != pointSize || xResolution != xRes || yResolution != yRes)
391                  {
392                          err = FT_Set_Char_Size( *face, 0L, pointSize * 64, xResolution, yResolution);
393
394                          if( !err)
395                          {
396                                  ftFace = face;
397                                  size = pointSize;
398                                  xResolution = xRes;
399                                  yResolution = yRes;
400                                  ftSize = (*ftFace)->size;
401                          }
402                          else
403                          {
404                                  ftFace = 0;
405                                  size = 0;
406                                  xResolution = 0;
407                                  yResolution = 0;
408                                  ftSize = 0;
409                          }
410                  }
411     
412                  return !err;
413          }
414
415
416          unsigned int FTSize::CharSize() const
417          {
418                  return size;
419          }
420
421
422          float FTSize::Ascender() const
423          {
424                  return ftSize == 0 ? 0.0f : static_cast<float>( ftSize->metrics.ascender) / 64.0f;
425          }
426
427
428          float FTSize::Descender() const
429          {
430                  return ftSize == 0 ? 0.0f : static_cast<float>( ftSize->metrics.descender) / 64.0f;
431          }
432
433
434          float FTSize::Height() const
435          {
436                  if( 0 == ftSize)
437                  {
438                          return 0.0f;
439                  }
440     
441                  if( FT_IS_SCALABLE((*ftFace)))
442                  {
443                          return ( (*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) * ( (float)ftSize->metrics.y_ppem / (float)(*ftFace)->units_per_EM);
444                  }
445                  else
446                  {
447                          return static_cast<float>( ftSize->metrics.height) / 64.0f;
448                  }
449          }
450
451
452          float FTSize::Width() const
453          {
454                  if( 0 == ftSize)
455                  {
456                          return 0.0f;
457                  }
458     
459                  if( FT_IS_SCALABLE((*ftFace)))
460                  {
461                          return ( (*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) * ( static_cast<float>(ftSize->metrics.x_ppem) / static_cast<float>((*ftFace)->units_per_EM));
462                  }
463                  else
464                  {
465                          return static_cast<float>( ftSize->metrics.max_advance) / 64.0f;
466                  }
467          }
468
469
470          float FTSize::Underline() const
471          {
472                  return 0.0f;
473          }
474
475
476
477
478 class FTFace
479 {
480         public:
481         
482                 FTFace( const char* fontFilePath);
483                 FTFace( const unsigned char *pBufferBytes, size_t bufferSizeInBytes );
484                 virtual ~FTFace();
485
486                 bool Attach( const char* fontFilePath);
487                 bool Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes);
488                 FT_Face* Face() const { return ftFace;}
489                 const FTSize& Size( const unsigned int size, const unsigned int res);
490                 unsigned int CharMapCount();
491                 FT_Encoding* CharMapList();
492                 FTPoint KernAdvance( unsigned int index1, unsigned int index2);
493                 FT_GlyphSlot Glyph( unsigned int index, FT_Int load_flags);
494                 unsigned int GlyphCount() const { return numGlyphs;}
495                 FT_Error Error() const { return err; }
496         
497         private:
498                 FT_Face* ftFace;
499                 FTSize  charSize;
500                 int numGlyphs;
501                 FT_Encoding* fontEncodingList;
502                 bool hasKerningTable;
503                 FT_Error err;
504 };
505
506 FTFace::FTFace( const char* fontFilePath)
507         :   numGlyphs(0),
508     fontEncodingList(0),
509          err(0)
510 {
511         const FT_Long DEFAULT_FACE_INDEX = 0;
512         ftFace = new FT_Face;
513
514         err = FT_New_Face( *FTLibrary::Instance().GetLibrary(), fontFilePath, DEFAULT_FACE_INDEX, ftFace);
515
516         if( err)
517         {
518                 delete ftFace;
519                 ftFace = 0;
520         }
521         else
522         {
523                 numGlyphs = (*ftFace)->num_glyphs;
524                 hasKerningTable = FT_HAS_KERNING((*ftFace));
525         }
526 }
527
528
529 FTFace::FTFace( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
530         :   numGlyphs(0),
531     err(0)
532 {
533         const FT_Long DEFAULT_FACE_INDEX = 0;
534         ftFace = new FT_Face;
535
536         err = FT_New_Memory_Face( *FTLibrary::Instance().GetLibrary(), (FT_Byte *)pBufferBytes, bufferSizeInBytes, DEFAULT_FACE_INDEX, ftFace);
537
538         if( err)
539         {
540                 delete ftFace;
541                 ftFace = 0;
542         }
543         else
544         {
545                 numGlyphs = (*ftFace)->num_glyphs;
546         }
547 }
548
549
550 FTFace::~FTFace()
551 {
552         if( ftFace)
553         {
554                 FT_Done_Face( *ftFace);
555                 delete ftFace;
556                 ftFace = 0;
557         }
558 }
559
560
561 bool FTFace::Attach( const char* fontFilePath)
562 {
563         err = FT_Attach_File( *ftFace, fontFilePath);
564         return !err;
565 }
566
567
568 bool FTFace::Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
569 {
570         FT_Open_Args open;
571
572         open.flags = FT_OPEN_MEMORY;
573         open.memory_base = (FT_Byte *)pBufferBytes;
574         open.memory_size = bufferSizeInBytes;
575
576         err = FT_Attach_Stream( *ftFace, &open);
577         return !err;
578 }
579
580
581 const FTSize& FTFace::Size( const unsigned int size, const unsigned int res)
582 {
583         charSize.CharSize( ftFace, size, res, res);
584         err = charSize.Error();
585
586         return charSize;
587 }
588
589
590 unsigned int FTFace::CharMapCount()
591 {
592         return (*ftFace)->num_charmaps;
593 }
594
595
596 FT_Encoding* FTFace::CharMapList()
597 {
598         if( 0 == fontEncodingList)
599         {
600                 fontEncodingList = new FT_Encoding[CharMapCount()];
601                 for( size_t encodingIndex = 0; encodingIndex < CharMapCount(); ++encodingIndex)
602                 {
603                         fontEncodingList[encodingIndex] = (*ftFace)->charmaps[encodingIndex]->encoding;
604                 }
605         }
606     
607         return fontEncodingList;
608 }
609
610
611 FTPoint FTFace::KernAdvance( unsigned int index1, unsigned int index2)
612 {
613         float x, y;
614         x = y = 0.0f;
615
616         if( hasKerningTable && index1 && index2)
617         {
618                 FT_Vector kernAdvance;
619                 kernAdvance.x = kernAdvance.y = 0;
620
621                 err = FT_Get_Kerning( *ftFace, index1, index2, ft_kerning_unfitted, &kernAdvance);
622                 if( !err)
623                 {   
624                         x = static_cast<float>( kernAdvance.x) / 64.0f;
625                         y = static_cast<float>( kernAdvance.y) / 64.0f;
626                 }
627         }
628     
629         return FTPoint( x, y, 0.0);
630 }
631
632
633 FT_GlyphSlot FTFace::Glyph( unsigned int index, FT_Int load_flags)
634 {
635         err = FT_Load_Glyph( *ftFace, index, load_flags);
636         if( err)
637         {
638                 return NULL;
639         }
640
641         return (*ftFace)->glyph;
642 }
643
644
645
646
647
648
649
650
651
652  template <typename FT_VECTOR_ITEM_TYPE>  class FTVector
653 {
654         public:
655                 typedef FT_VECTOR_ITEM_TYPE value_type;
656                 typedef value_type& reference;
657                 typedef const value_type& const_reference;
658                 typedef value_type* iterator;
659                 typedef const value_type* const_iterator;
660                 typedef size_t size_type;
661         
662                 FTVector()
663                 {
664                         Capacity = Size = 0;
665                         Items = 0;
666                 }
667
668         
669                 virtual ~FTVector()
670                 {
671                         clear();
672                 }
673         
674                 FTVector& operator =(const FTVector& v)
675                 {
676                         reserve(v.capacity());
677             
678                         iterator ptr = begin();
679                         const_iterator vbegin = v.begin();
680                         const_iterator vend = v.end();
681             
682                         while( vbegin != vend)
683                         {
684                                 *ptr++ = *vbegin++;
685                         }
686             
687                         Size = v.size();
688                         return *this;
689                 }
690         
691                 size_type size() const
692                 {
693                         return Size;
694                 }
695         
696                 size_type capacity() const
697                 {
698                         return Capacity;
699                 }
700         
701                 iterator begin()
702                 {
703                         return Items;
704                 }
705         
706                 const_iterator begin() const
707                 {
708                         return Items;
709                 }
710         
711                 iterator end()
712                 {
713                         return begin() + size(); 
714                 }
715         
716                 const_iterator end() const
717                 {
718                         return begin() + size(); 
719                 }
720         
721                 bool empty() const 
722                 { 
723                         return size() == 0; 
724                 }
725
726                 reference operator [](size_type pos) 
727                 { 
728                         return( *(begin() + pos)); 
729                 }
730
731                 const_reference operator []( size_type pos) const 
732                 { 
733                         return( *(begin() + pos)); 
734                 }
735         
736                 void clear()
737                 {
738                         if( Capacity)
739                         {
740                                 delete [] Items;
741                                 Capacity = Size = 0;
742                                 Items = 0;
743                         }
744                 }
745
746                 void reserve( size_type n)
747                 {
748                         if( capacity() < n)
749                         {
750                                 expand(n);
751                         }
752                 }
753
754                 void push_back(const value_type& x)
755                 {
756                         if( size() == capacity())
757                         {
758                                 expand();
759                         }
760            
761                         ( *this)[size()] = x;
762                         ++Size;
763                 }
764
765                 void resize(size_type n, value_type x)
766                 {
767                         if( n == size())
768                         {
769                                 return;
770                         }
771             
772                         reserve(n);
773                         iterator begin, end;
774             
775                         if( n >= Size)
776                         {
777                                 begin = this->end();
778                                 end = this->begin() + n;
779                         }
780                         else
781                         {
782                                 begin = this->begin() + n;
783                                 end = this->end();
784                         }
785         
786                         while( begin != end)
787                         {
788                                 *begin++ = x;
789                         }
790         
791                         Size = n;
792                 }
793
794         
795         private:
796                 void expand(size_type capacity_hint = 0)
797                 {
798                         size_type new_capacity =( capacity() == 0) ? 256 : capacity()* 2;
799                         if( capacity_hint)
800                         {
801                                 while( new_capacity < capacity_hint)
802                                 {
803                                         new_capacity *= 2;
804                                 }
805                         }
806             
807                         value_type *new_items = new value_type[new_capacity];
808             
809                         iterator begin = this->begin();
810                         iterator end = this->end();
811                         value_type *ptr = new_items;
812             
813                         while( begin != end)
814                         {
815                                 *ptr++ = *begin++;
816                         }
817             
818                         if( Capacity)
819                         {
820                                 delete [] Items;
821                         }
822         
823                         Items = new_items;
824                         Capacity = new_capacity;
825                 }
826
827                 size_type Capacity;
828                 size_type Size;
829                 value_type* Items;
830 };
831
832
833
834
835
836
837
838
839
840
841
842
843
844 class FTCharToGlyphIndexMap
845 {
846         public:
847   
848                 typedef unsigned long CharacterCode;
849                 typedef signed long GlyphIndex;
850         
851                 enum 
852                 {
853                         NumberOfBuckets = 256,
854                         BucketSize = 256,
855                         IndexNotFound = -1
856                 };
857
858                 FTCharToGlyphIndexMap()
859                 {
860                         this->Indices = 0;
861                 }
862
863                 virtual ~FTCharToGlyphIndexMap()
864                 {
865                         if( this->Indices)
866                         {
867                 // Free all buckets
868                                 this->clear();
869         
870                 // Free main structure
871                                 delete [] this->Indices;
872                                 this->Indices = 0;
873                         }
874                 }
875   
876                 void clear()
877                 {
878                         if(this->Indices)
879                         {
880                                 for( int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++)
881                                 {
882                                         if( this->Indices[i])
883                                         {
884                                                 delete [] this->Indices[i];
885                                                 this->Indices[i] = 0;
886                                         }
887                                 }
888                         }
889                 }
890
891                 const GlyphIndex find( CharacterCode c)
892                 {
893                         if( !this->Indices)
894                         {
895                                 return 0;
896                         }
897         
898             // Find position of char code in buckets
899                         div_t pos = div( c, FTCharToGlyphIndexMap::BucketSize);
900         
901                         if( !this->Indices[pos.quot])
902                         {
903                                 return 0;
904                         }
905         
906                         const FTCharToGlyphIndexMap::GlyphIndex *ptr = &this->Indices[pos.quot][pos.rem];
907                         if( *ptr == FTCharToGlyphIndexMap::IndexNotFound)
908                         {
909                                 return 0;
910                         }
911         
912                         return *ptr;
913                 }
914
915                 void insert( CharacterCode c, GlyphIndex g)
916                 {
917                         if( !this->Indices)
918                         {
919                                 this->Indices = new GlyphIndex* [FTCharToGlyphIndexMap::NumberOfBuckets];
920                                 for( int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++)
921                                 {
922                                         this->Indices[i] = 0;
923                                 }
924                         }
925         
926             // Find position of char code in buckets
927                         div_t pos = div(c, FTCharToGlyphIndexMap::BucketSize);
928         
929             // Allocate bucket if does not exist yet
930                         if( !this->Indices[pos.quot])
931                         {
932                                 this->Indices[pos.quot] = new GlyphIndex [FTCharToGlyphIndexMap::BucketSize];
933                                 for( int i = 0; i < FTCharToGlyphIndexMap::BucketSize; i++)
934                                 {
935                                         this->Indices[pos.quot][i] = FTCharToGlyphIndexMap::IndexNotFound;
936                                 }
937                         }
938           
939                         this->Indices[pos.quot][pos.rem] = g;
940                 }
941   
942         private:
943                 GlyphIndex** Indices;
944 };
945
946
947
948
949
950 class FTCharmap
951 {
952         public:
953                 FTCharmap( FTFace* face);
954                 virtual ~FTCharmap();
955
956                 FT_Encoding Encoding() const { return ftEncoding;}
957                 bool CharMap( FT_Encoding encoding);
958                 unsigned int GlyphListIndex( const unsigned int characterCode);
959                 unsigned int FontIndex( const unsigned int characterCode);
960                 void InsertIndex( const unsigned int characterCode, const unsigned int containerIndex);
961                 FT_Error Error() const { return err;}
962         
963         private:
964                 FT_Encoding ftEncoding;
965                 const FT_Face ftFace;
966                 typedef FTCharToGlyphIndexMap CharacterMap;
967                 CharacterMap charMap;
968         
969                 FT_Error err;
970         
971 };
972
973
974
975
976
977 FTCharmap::FTCharmap( FTFace* face)
978         :   ftFace( *(face->Face())),
979     err(0)
980 {
981         if( !ftFace->charmap)
982         {
983                 err = FT_Set_Charmap( ftFace, ftFace->charmaps[0]);
984         }
985     
986         ftEncoding = ftFace->charmap->encoding;
987 }
988
989
990 FTCharmap::~FTCharmap()
991 {
992         charMap.clear();
993 }
994
995
996 bool FTCharmap::CharMap( FT_Encoding encoding)
997 {
998         if( ftEncoding == encoding)
999         {
1000                 return true;
1001         }
1002     
1003         err = FT_Select_Charmap( ftFace, encoding );
1004     
1005         if( !err)
1006         {
1007                 ftEncoding = encoding;
1008         }
1009         else
1010         {
1011                 ftEncoding = ft_encoding_none;
1012         }
1013         
1014         charMap.clear();
1015         return !err;
1016 }
1017
1018
1019 unsigned int FTCharmap::GlyphListIndex( unsigned int characterCode )
1020 {
1021         return charMap.find( characterCode);
1022 }
1023
1024
1025 unsigned int FTCharmap::FontIndex( unsigned int characterCode )
1026 {
1027         return FT_Get_Char_Index( ftFace, characterCode);
1028 }
1029
1030
1031 void FTCharmap::InsertIndex( const unsigned int characterCode, const unsigned int containerIndex)
1032 {
1033         charMap.insert( characterCode, containerIndex);
1034 }
1035
1036
1037
1038
1039 class FTGlyphContainer
1040 {
1041         typedef FTVector<FTGlyph*> GlyphVector;
1042         public:
1043                 FTGlyphContainer( FTFace* face);
1044                 ~FTGlyphContainer();
1045                 bool CharMap( FT_Encoding encoding);
1046                 unsigned int FontIndex( const unsigned int characterCode ) const;
1047                 void Add( FTGlyph* glyph, const unsigned int characterCode);
1048                 const FTGlyph* const Glyph( const unsigned int characterCode) const;
1049                 FTBBox BBox( const unsigned int characterCode) const;
1050                 float Advance( const unsigned int characterCode, const unsigned int nextCharacterCode);
1051         
1052                 FTPoint Render( const unsigned int characterCode, const unsigned int nextCharacterCode, FTPoint penPosition);
1053         
1054                 FT_Error Error() const { return err;}
1055
1056         private:
1057                 FTFace* face;
1058                 FTCharmap* charMap;
1059
1060                 GlyphVector glyphs;
1061
1062                 FT_Error err;
1063 };
1064
1065
1066 FTGlyphContainer::FTGlyphContainer( FTFace* f)
1067         :   face(f),
1068     err(0)
1069 {
1070         glyphs.push_back( NULL);
1071         charMap = new FTCharmap( face);
1072 }
1073
1074
1075 FTGlyphContainer::~FTGlyphContainer()
1076 {
1077         GlyphVector::iterator glyphIterator;
1078         for( glyphIterator = glyphs.begin(); glyphIterator != glyphs.end(); ++glyphIterator)
1079         {
1080                 delete *glyphIterator;
1081         }
1082     
1083         glyphs.clear();
1084         delete charMap;
1085 }
1086
1087
1088 bool FTGlyphContainer::CharMap( FT_Encoding encoding)
1089 {
1090         bool result = charMap->CharMap( encoding);
1091         err = charMap->Error();
1092         return result;
1093 }
1094
1095
1096 unsigned int FTGlyphContainer::FontIndex( const unsigned int characterCode) const
1097 {
1098         return charMap->FontIndex( characterCode);
1099 }
1100
1101
1102 void FTGlyphContainer::Add( FTGlyph* tempGlyph, const unsigned int characterCode)
1103 {
1104         charMap->InsertIndex( characterCode, glyphs.size());
1105         glyphs.push_back( tempGlyph);
1106 }
1107
1108
1109 const FTGlyph* const FTGlyphContainer::Glyph( const unsigned int characterCode) const
1110 {
1111         signed int index = charMap->GlyphListIndex( characterCode);
1112         return glyphs[index];
1113 }
1114
1115
1116 FTBBox FTGlyphContainer::BBox( const unsigned int characterCode) const
1117 {
1118         return glyphs[charMap->GlyphListIndex( characterCode)]->BBox();
1119 }
1120
1121
1122 float FTGlyphContainer::Advance( const unsigned int characterCode, const unsigned int nextCharacterCode)
1123 {
1124         unsigned int left = charMap->FontIndex( characterCode);
1125         unsigned int right = charMap->FontIndex( nextCharacterCode);
1126
1127         float width = face->KernAdvance( left, right).X();
1128         width += glyphs[charMap->GlyphListIndex( characterCode)]->Advance().X();
1129     
1130         return width;
1131 }
1132
1133
1134 FTPoint FTGlyphContainer::Render( const unsigned int characterCode, const unsigned int nextCharacterCode, FTPoint penPosition)
1135 {
1136         FTPoint kernAdvance, advance;
1137     
1138         unsigned int left = charMap->FontIndex( characterCode);
1139         unsigned int right = charMap->FontIndex( nextCharacterCode);
1140
1141         kernAdvance = face->KernAdvance( left, right);
1142         
1143         if( !face->Error())
1144         {
1145                 advance = glyphs[charMap->GlyphListIndex( characterCode)]->Render( penPosition);
1146         }
1147     
1148         kernAdvance += advance;
1149         return kernAdvance;
1150 }
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160 class FTFont
1161 {
1162         public:
1163                 
1164                 FTFont( const char* fontFilePath);
1165       FTFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes);
1166                 virtual ~FTFont();
1167         
1168                 bool Attach( const char* fontFilePath);
1169                 bool Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes);
1170                 bool CharMap( FT_Encoding encoding );
1171                 unsigned int CharMapCount();
1172                 FT_Encoding* CharMapList();
1173         virtual bool FaceSize( const unsigned int size, const unsigned int res = 72);
1174         unsigned int FaceSize() const;
1175         virtual void Depth( float depth){}
1176                 void UseDisplayList( bool useList);
1177         float Ascender() const;
1178         float Descender() const;
1179         float LineHeight() const;
1180         void BBox( const char* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz);
1181                 void BBox( const wchar_t* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz);
1182                 float Advance( const wchar_t* string);
1183                 float Advance( const char* string);
1184                 virtual void Render( const char* string );
1185                 virtual void Render( const wchar_t* string );
1186                 FT_Error Error() const { return err;}
1187
1188         protected:
1189                 virtual FTGlyph* MakeGlyph( unsigned int g) = 0;
1190                 FTFace face;
1191                 FTSize charSize;
1192                 bool useDisplayLists;
1193                 FT_Error err;
1194         
1195         private:        
1196                 inline bool CheckGlyph( const unsigned int chr);
1197                 FTGlyphContainer* glyphList;
1198                 FTPoint pen;
1199 };
1200
1201
1202
1203 FTFont::FTFont( const char* fontFilePath) : face(fontFilePath), useDisplayLists(true), glyphList(0)
1204 {
1205         err = face.Error();
1206         if( err == 0)
1207         {
1208                 glyphList = new FTGlyphContainer( &face);
1209         }
1210 }
1211
1212
1213
1214
1215 FTFont::FTFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
1216         :   face( pBufferBytes, bufferSizeInBytes),
1217     glyphList(0)
1218 {
1219         err = face.Error();
1220         if( err == 0)
1221         {
1222                 glyphList = new FTGlyphContainer( &face);
1223         }
1224 }
1225
1226
1227 FTFont::~FTFont()
1228 {
1229         delete glyphList;
1230 }
1231
1232
1233 bool FTFont::Attach( const char* fontFilePath)
1234 {
1235         if( face.Attach( fontFilePath))
1236         {
1237                 err = 0;
1238                 return true;
1239         }
1240         else
1241         {
1242                 err = face.Error();
1243                 return false;
1244         }
1245 }
1246
1247
1248 bool FTFont::Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
1249 {
1250         if( face.Attach( pBufferBytes, bufferSizeInBytes))
1251         {
1252                 err = 0;
1253                 return true;
1254         }
1255         else
1256         {
1257                 err = face.Error();
1258                 return false;
1259         }
1260 }
1261
1262
1263 bool FTFont::FaceSize( const unsigned int size, const unsigned int res )
1264 {
1265         charSize = face.Size( size, res);
1266         err = face.Error();
1267     
1268         if( err != 0)
1269         {
1270                 return false;
1271         }
1272     
1273         if( glyphList != NULL)
1274         {
1275                 delete glyphList;
1276         }
1277     
1278         glyphList = new FTGlyphContainer( &face);
1279         return true;
1280 }
1281
1282
1283 unsigned int FTFont::FaceSize() const
1284 {
1285         return charSize.CharSize();
1286 }
1287
1288
1289 bool FTFont::CharMap( FT_Encoding encoding)
1290 {
1291         bool result = glyphList->CharMap( encoding);
1292         err = glyphList->Error();
1293         return result;
1294 }
1295
1296
1297 unsigned int FTFont::CharMapCount()
1298 {
1299         return face.CharMapCount();
1300 }
1301
1302
1303 FT_Encoding* FTFont::CharMapList()
1304 {
1305         return face.CharMapList();
1306 }
1307
1308
1309 void FTFont::UseDisplayList( bool useList)
1310 {
1311         useDisplayLists = useList;
1312 }
1313
1314 float FTFont::Ascender() const
1315 {
1316         return charSize.Ascender();
1317 }
1318
1319
1320 float FTFont::Descender() const
1321 {
1322         return charSize.Descender();
1323 }
1324
1325 float FTFont::LineHeight() const
1326 {
1327         return charSize.Height();
1328 }
1329
1330 void FTFont::BBox( const char* string,
1331                                                  float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
1332 {
1333         FTBBox totalBBox;
1334
1335         if((NULL != string) && ('\0' != *string))
1336         {
1337                 const unsigned char* c = (unsigned char*)string;
1338                 float advance = 0;
1339
1340                 if(CheckGlyph( *c))
1341                 {
1342                         totalBBox = glyphList->BBox( *c);
1343                         advance = glyphList->Advance( *c, *(c + 1));
1344                 }
1345                 
1346                 while( *++c)
1347                 {
1348                         if(CheckGlyph( *c))
1349                         {
1350                                 FTBBox tempBBox = glyphList->BBox( *c);
1351                                 tempBBox.Move( FTPoint( advance, 0.0f, 0.0f));
1352                                 totalBBox += tempBBox;
1353                                 advance += glyphList->Advance( *c, *(c + 1));
1354                         }
1355                 }
1356         }
1357
1358         llx = totalBBox.lowerX;
1359         lly = totalBBox.lowerY;
1360         llz = totalBBox.lowerZ;
1361         urx = totalBBox.upperX;
1362         ury = totalBBox.upperY;
1363         urz = totalBBox.upperZ;
1364 }
1365
1366
1367 void FTFont::BBox( const wchar_t* string,
1368                                                  float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
1369 {
1370         FTBBox totalBBox;
1371
1372         if((NULL != string) && ('\0' != *string))
1373         {
1374                 const wchar_t* c = string;
1375                 float advance = 0;
1376
1377                 if(CheckGlyph( *c))
1378                 {
1379                         totalBBox = glyphList->BBox( *c);
1380                         advance = glyphList->Advance( *c, *(c + 1));
1381                 }
1382         
1383                 while( *++c)
1384                 {
1385                         if(CheckGlyph( *c))
1386                         {
1387                                 FTBBox tempBBox = glyphList->BBox( *c);
1388                                 tempBBox.Move( FTPoint( advance, 0.0f, 0.0f));
1389                                 totalBBox += tempBBox;
1390                                 advance += glyphList->Advance( *c, *(c + 1));
1391                         }
1392                 }
1393         }
1394
1395         llx = totalBBox.lowerX;
1396         lly = totalBBox.lowerY;
1397         llz = totalBBox.lowerZ;
1398         urx = totalBBox.upperX;
1399         ury = totalBBox.upperY;
1400         urz = totalBBox.upperZ;
1401 }
1402
1403
1404 float FTFont::Advance( const wchar_t* string)
1405 {
1406         const wchar_t* c = string;
1407         float width = 0.0f;
1408
1409         while( *c)
1410         {
1411                 if(CheckGlyph( *c))
1412                 {
1413                         width += glyphList->Advance( *c, *(c + 1));
1414                 }
1415                 ++c;
1416         }
1417     
1418         return width;
1419 }
1420
1421
1422 float FTFont::Advance( const char* string)
1423 {
1424         const unsigned char* c = (unsigned char*)string;
1425         float width = 0.0f;
1426
1427         while( *c)
1428         {
1429                 if(CheckGlyph( *c))
1430                 {
1431                         width += glyphList->Advance( *c, *(c + 1));
1432                 }
1433                 ++c;
1434         }
1435     
1436         return width;
1437 }
1438
1439
1440 void FTFont::Render( const char* string )
1441 {
1442         const unsigned char* c = (unsigned char*)string;
1443         pen.X(0); pen.Y(0);
1444
1445         while( *c)
1446         {
1447                 if(CheckGlyph( *c))
1448                 {
1449                         pen = glyphList->Render( *c, *(c + 1), pen);
1450                 }
1451                 ++c;
1452         }
1453 }
1454
1455
1456 void FTFont::Render( const wchar_t* string )
1457 {
1458         const wchar_t* c = string;
1459         pen.X(0); pen.Y(0);
1460
1461         while( *c)
1462         {
1463                 if(CheckGlyph( *c))
1464                 {
1465                         pen = glyphList->Render( *c, *(c + 1), pen);
1466                 }
1467                 ++c;
1468         }
1469 }
1470
1471
1472 bool FTFont::CheckGlyph( const unsigned int characterCode)
1473 {
1474         if( NULL == glyphList->Glyph( characterCode))
1475         {
1476                 unsigned int glyphIndex = glyphList->FontIndex( characterCode);
1477                 FTGlyph* tempGlyph = MakeGlyph( glyphIndex);
1478                 if( NULL == tempGlyph)
1479                 {
1480                         if( 0 == err)
1481                         {
1482                                 err = 0x13;
1483                         }
1484             
1485                         return false;
1486                 }
1487                 glyphList->Add( tempGlyph, characterCode);
1488         }
1489     
1490         return true;
1491 }
1492
1493
1494
1495
1496
1497
1498 class FTTextureGlyph : public FTGlyph
1499 {
1500         public:
1501                 FTTextureGlyph( FT_GlyphSlot glyph, Texture * tid, int xOffset, int yOffset, int width, int height);
1502                 virtual ~FTTextureGlyph();
1503                 virtual const FTPoint& Render( const FTPoint& pen);
1504                 static void FTTextureGlyph::ResetActiveTexture()
1505                 {
1506                         activeTextureID = 0;
1507                         activeTexture = 0;
1508                 }
1509         
1510         private:
1511                 int destWidth;
1512                 int destHeight;
1513                 FTPoint pos;
1514                 FTPoint uv[2];
1515                 int glTextureID;
1516                 Texture* textureID;
1517                 static int activeTextureID;
1518                 static Texture* activeTexture;
1519         
1520 };
1521
1522
1523 int FTTextureGlyph::activeTextureID = 0;
1524 Texture* FTTextureGlyph::activeTexture = 0;
1525  
1526 FTTextureGlyph::FTTextureGlyph( FT_GlyphSlot glyph, Texture *tid, int xOffset, int yOffset, int width, int height)
1527         :   FTGlyph(glyph)
1528 {
1529         destWidth = 0;
1530         destHeight = 0;
1531
1532         textureID = tid;
1533         glTextureID = tid->gl_Tex;
1534                 
1535         err = FT_Render_Glyph( glyph, FT_RENDER_MODE_NORMAL);
1536         if( err || glyph->format != ft_glyph_format_bitmap)
1537         {
1538                 return;
1539         }
1540
1541         FT_Bitmap      bitmap = glyph->bitmap;
1542
1543         destWidth  = bitmap.width;
1544         destHeight = bitmap.rows;
1545     
1546         int tW=0, tH=0;
1547         if( destWidth && destHeight)
1548         {
1549                 glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
1550                 glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
1551                 glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
1552                 glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
1553                 
1554                 
1555                 g->setTexture(tid);
1556 //              glBindTexture( GL_TEXTURE_2D, glTextureID);
1557                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,GL_TEXTURE_WIDTH, &tW);
1558                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,GL_TEXTURE_HEIGHT, &tH);
1559                 tid->texSubImage2D(xOffset, yOffset, destWidth, destHeight, AM_ALPHA, AM_UBYTE, bitmap.buffer);
1560
1561         //      glTexSubImage2D( GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer);
1562                 
1563                 printf("TW=%d tH=%d   txoff=%d  yoff=%d w=%d h=%d\n", tW, tH, xOffset, yOffset, destWidth, destHeight);
1564                 glPopClientAttrib();
1565         }
1566
1567     
1568         uv[0].X( static_cast<float>(xOffset) / static_cast<float>(width));
1569         uv[0].Y( static_cast<float>(yOffset) / static_cast<float>(height));
1570         uv[1].X( static_cast<float>( xOffset + destWidth) / static_cast<float>(width));
1571         uv[1].Y( static_cast<float>( yOffset + destHeight) / static_cast<float>(height));
1572     
1573         pos.X( glyph->bitmap_left);
1574         pos.Y( glyph->bitmap_top);
1575 }
1576
1577
1578 FTTextureGlyph::~FTTextureGlyph()
1579 { }
1580
1581
1582 const FTPoint& FTTextureGlyph::Render( const FTPoint& pen)
1583 {
1584         if( activeTextureID != glTextureID)
1585         {
1586                 g->setTexture(textureID);
1587                 printf("setT = %d\n", textureID->gl_Tex);
1588                 activeTexture = textureID;
1589                 //activeTextureID = glTextureID;
1590 //              glBindTexture( GL_TEXTURE_2D, glTextureID);
1591                 
1592         }
1593
1594         vertex array[4];
1595  
1596
1597         
1598         //g->setWorld(pen.X(),  pen.Y(), 0.0f, 0,0,0, 1,1,1);
1599         glTranslatef( pen.X(),  pen.Y(), 0.0f);
1600         
1601         array[0].u = uv[0].X();
1602         array[0].v = 1 - uv[0].Y();
1603         array[0].x = pos.X();
1604         array[0].y = pos.Y();
1605         array[0].z = 0;
1606         array[0].col = COLOUR_RGBA(255,255,255,255);
1607         array[0].nx = array[0].ny = array[0].nz = 0;
1608
1609         array[1].u = uv[0].X();
1610         array[1].v = 1 - uv[1].Y();
1611         array[1].x = pos.X();
1612         array[1].y = pos.Y() - destHeight;
1613         array[1].z = 0;
1614         array[1].col = COLOUR_RGBA(255,255,255,255);
1615         array[1].nx = array[1].ny = array[1].nz = 0;
1616
1617         array[2].u = uv[1].X();
1618         array[2].v = 1 - uv[1].Y();
1619         array[2].x = pos.X() + destWidth;
1620         array[2].y = pos.Y() - destHeight;
1621         array[2].z = 0;
1622         array[2].col = COLOUR_RGBA(255,255,255,255);
1623         array[2].nx = array[2].ny = array[2].nz = 0;
1624
1625         array[3].u = uv[1].X();
1626         array[3].v = 1 - uv[0].Y();
1627         array[3].x = pos.X() + destWidth;
1628         array[3].y = pos.Y();
1629         array[3].z = 0;
1630         array[3].col = COLOUR_RGBA(255,255,255,255);
1631         array[3].nx = array[3].ny = array[3].nz = 0;
1632         
1633         //g->renderVertexArray(array, 4, AM_TRIANGLE_STRIP);
1634         g->addTriangle(array[0], array[1], array[2]);
1635         g->addTriangle(array[2], array[3], array[0]);
1636         
1637 /*      glBegin( GL_QUADS);
1638         glTexCoord2f( uv[0].X(), uv[0].Y());
1639         glVertex2f( pos.X(), pos.Y());
1640         
1641         glTexCoord2f( uv[0].X(), uv[1].Y());
1642         glVertex2f( pos.X(), pos.Y() - destHeight);
1643
1644         glTexCoord2f( uv[1].X(), uv[1].Y());
1645         glVertex2f( destWidth + pos.X(), pos.Y() - destHeight);
1646         
1647         glTexCoord2f( uv[1].X(), uv[0].Y());
1648         glVertex2f( destWidth + pos.X(), pos.Y());
1649         glEnd();
1650         */
1651         return advance;
1652 }
1653
1654
1655
1656
1657
1658 class myFont : public FTFont
1659 {
1660
1661         private:
1662                 inline virtual FTGlyph* MakeGlyph( unsigned int glyphIndex)
1663                 {
1664                         FT_GlyphSlot ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING);
1665     
1666                         if( ftGlyph)
1667                         {
1668                                 glyphHeight = static_cast<int>( charSize.Height());
1669                                 glyphWidth = static_cast<int>( charSize.Width());
1670         
1671                                 if( textureIDList.empty())
1672                                 {
1673                                         textureIDList.push_back( CreateTexture());
1674                                         xOffset = yOffset = padding;
1675                                 }
1676         
1677                                 if( xOffset > ( textureWidth - glyphWidth))
1678                                 {
1679                                         xOffset = padding;
1680                                         yOffset += glyphHeight;
1681             
1682                                         if( yOffset > ( textureHeight - glyphHeight))
1683                                         {
1684                                                 textureIDList.push_back( CreateTexture());
1685                                                 yOffset = padding;
1686                                         }
1687                                 }
1688         
1689                                 FTTextureGlyph* tempGlyph = new FTTextureGlyph( ftGlyph, textureIDList[textureIDList.size() - 1],
1690                                                 xOffset, yOffset, textureWidth, textureHeight);
1691                                 xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);
1692         
1693                                 --remGlyphs;
1694                                 return tempGlyph;
1695                         }
1696     
1697                         err = face.Error();
1698                         return NULL;
1699                 }
1700                 
1701                 inline void CalculateTextureSize()
1702                 {
1703                         
1704                         if( !maximumGLTextureSize)
1705                         {
1706                                 glGetIntegerv( GL_MAX_TEXTURE_SIZE, (int*)&maximumGLTextureSize);
1707                                 assert(maximumGLTextureSize); // If you hit this then you have an invalid OpenGL context.
1708                         }
1709                         printf("maximumGLTextureSize=%d\n", maximumGLTextureSize);
1710                         textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2));
1711                         textureWidth = textureWidth > maximumGLTextureSize ? maximumGLTextureSize : textureWidth;
1712     
1713                         int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth);
1714         
1715                         textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight);
1716                         textureHeight = textureHeight > maximumGLTextureSize ? maximumGLTextureSize : textureHeight;
1717                 }
1718
1719
1720                 inline Texture * CreateTexture()
1721                 {
1722
1723                         CalculateTextureSize();
1724     
1725                         int totalMemory = textureWidth * textureHeight;
1726                         unsigned char* textureMemory = new unsigned char[totalMemory];
1727                         memset( textureMemory, 0, totalMemory);
1728
1729                         Texture *texID = new Texture(textureMemory, textureWidth, textureHeight, AM_ALPHA, AM_UBYTE, g);
1730
1731                         delete [] textureMemory;
1732
1733                         printf("now returning texID=%p\n", texID);
1734                         return texID;
1735                         /*
1736                         CalculateTextureSize();
1737
1738                         int totalMemory = textureWidth * textureHeight;
1739                         unsigned char* textureMemory = new unsigned char[totalMemory];
1740                         memset( textureMemory, 0, totalMemory);
1741
1742                         GLuint textID;
1743         /*              glGenTextures( 1, (GLuint*)&textID);
1744                         glBindTexture( GL_TEXTURE_2D, textID);
1745                         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1746                         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1747                         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1748                         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1749     
1750                         glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);
1751         */
1752                         /*      
1753                         Texture *tex = new Texture(textureMemory, textureWidth, textureHeight, AM_ALPHA, AM_UBYTE, g);
1754 //                      g->setTexture(tex);
1755                         textID = tex->gl_Tex;
1756                         delete [] textureMemory;
1757                         printf("@ createTexture returning %d\n", textID);
1758                         return textID;*/
1759
1760                 }
1761                                 
1762
1763                                 
1764                 int maximumGLTextureSize;
1765                 int textureWidth;
1766                 int textureHeight;
1767                 FTVector<Texture *> textureIDList;
1768                 int glyphHeight;
1769                 int glyphWidth;
1770                 unsigned int padding;
1771                 unsigned int numGlyphs;
1772                 unsigned int remGlyphs;
1773                 int xOffset;
1774                 int yOffset;
1775
1776         
1777         public:
1778
1779         myFont( const char* fontFilePath)       :  FTFont( fontFilePath),
1780     maximumGLTextureSize(0),
1781          textureWidth(0),
1782          textureHeight(0),
1783          glyphHeight(0),
1784          glyphWidth(0),
1785          padding(3),
1786          xOffset(0),
1787          yOffset(0)
1788 {
1789         remGlyphs = numGlyphs = face.GlyphCount();
1790 }
1791
1792 ~myFont()
1793 {
1794         ;//glDeleteTextures( textureIDList.size(), (const unsigned int*)&textureIDList[0]);
1795 }
1796
1797
1798 void print( char *str, int x1, int y1, int x2, int y2, colour c )
1799 {
1800         g->enter2dMode();
1801         glColor4f( c.r, c.g, c.b, c.a);
1802         float h= LineHeight()*0.64f;    /* factor 0.64*/
1803         glTranslatef(x1, y1 + h, 0);
1804         glScalef(1.0, -1.0, 1.0);
1805         Render(str);
1806 //      ft_print( our_font, x1 , g->getHeight() - y1 - fontSize, str);
1807         g->leave2dMode();
1808 }
1809
1810
1811
1812 bool FaceSize( const unsigned int size, const unsigned int res)
1813 {
1814         if( !textureIDList.empty())
1815         {
1816                 glDeleteTextures( textureIDList.size(), (const uint*)&textureIDList[0]);
1817                 textureIDList.clear();
1818                 remGlyphs = numGlyphs = face.GlyphCount();
1819         }
1820
1821         return FTFont::FaceSize( size, res);
1822 }
1823
1824
1825 void Render( const char* string)
1826 {   
1827 //      glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
1828         bool a = g->isAlpha();
1829         g->enableAlpha(true);    
1830 //      glEnable(GL_BLEND);
1831         
1832 //      glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
1833
1834         FTTextureGlyph::ResetActiveTexture();
1835     
1836         FTFont::Render( string);
1837
1838 //      glPopAttrib();
1839         g->enableAlpha(a);    
1840 }
1841
1842
1843 void Render( const wchar_t* string)
1844 {   
1845 //      glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
1846     
1847         //glEnable(GL_BLEND);
1848         //glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
1849         bool a = g->isAlpha();
1850         g->enableAlpha(true);
1851
1852         FTTextureGlyph::ResetActiveTexture();
1853     
1854         FTFont::Render( string);
1855         g->enableAlpha(a);
1856 //      glPopAttrib();
1857 }
1858
1859 };
1860
1861
1862
1863 myFont *f;
1864 Font *t;
1865
1866 bool init(void)
1867 {
1868         g = new Graphics(1024, 768); // bring me a 1024x768 resolution
1869         g->createDisplay();
1870         g->setBackground(COLOUR_RGBA(155, 155, 155, 255)); //green background
1871         f = new myFont("Test.ttf");
1872         f->FaceSize(16, 72);
1873         f->CharMap(ft_encoding_unicode);
1874         
1875         t = new Font(g, "Test.ttf", 16);
1876         return true;
1877 }
1878
1879
1880 bool renderFrame()
1881 {
1882         g->beginScene();
1883         
1884         f->print("MPLA", 10,10, 200,200, COLOUR_RGBA(255,255,255,255));
1885 //      t->print("hello", 10,10, 200,200, COLOUR_RGBA(255,255,255,255));
1886         g->endScene();
1887         
1888         sleep(4);
1889         return false;   
1890 }
1891
1892 bool cleanup()
1893 {
1894         delete g;
1895         return true;    
1896 }
1897