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