Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glt/fontunic.cpp

Go to the documentation of this file.
00001 #include "fontunic.h"
00002 
00015 #include <fstream>
00016 #include <algorithm>
00017 #include <cstring>
00018 #include <cassert>
00019 #include <cstdio>
00020 #include <vector>
00021 #include <iostream>
00022 using namespace std;
00023 
00024 #include <misc/compress.h>
00025 #include <math/real.h>
00026 
00027 GltFontUnicode::GltFontUnicode(void *data)
00028 : GltDisplayListCache(3000), _data(NULL)
00029 {
00030     _hStep = 16;
00031     _vStep = 16;
00032     init(data);
00033 }
00034 
00035 GltFontUnicode::~GltFontUnicode()
00036 {
00037     init(NULL);
00038 }
00039 
00040 void 
00041 GltFontUnicode::init(void *data)
00042 {
00043     clear();
00044 
00045     if (!data)
00046         return;
00047 
00048     int compressed;
00049     void *font = getHeader((const byte *) data,compressed);
00050     
00051     string tmp;
00052     
00053     if (compressed)
00054     {
00055         decompress(tmp,font);
00056         font = (void *) tmp.data();
00057     }
00058 
00059     //
00060 
00061     byte *p = (byte *) font;
00062 
00063     uint32 size = 0;
00064     int i = 0;
00065     for (; i<0x10000; i++)
00066     {
00067         _index[i] = size;
00068         size += *(p++);
00069     }
00070     _index[i] = size;
00071 
00072     //
00073 
00074     _data = new byte [size];
00075     memcpy(_data,p,size);
00076 
00077     _init = true;
00078 }
00079 
00080 void 
00081 GltFontUnicode::clear()
00082 {
00083     if (_data)
00084     {
00085         delete [] _data;
00086         _data = NULL;
00087         memset(_index,0,sizeof(_index));
00088     }
00089 
00090     GltDisplayListCache::clear();
00091 
00092     _init = false;
00093 }
00094 
00095 bool 
00096 GltFontUnicode::print(const wchar_t ch) const
00097 {
00098     assert(_init);
00099 
00100     if (_init)
00101     {
00102         ((GltDisplayListCache *)this)->draw(ch);
00103         return true;
00104     }
00105     else
00106         return false;
00107 }
00108 
00109 bool 
00110 GltFontUnicode::print(const std::wstring &str) const
00111 {
00112     assert(_init);
00113 
00114     if (_init)
00115     {
00116         bool ok = true;
00117 
00118         glPushAttrib(GL_CURRENT_BIT);
00119         for (uint32 i=0; i<str.length(); i++)
00120             ok = ok && print(str[i]);
00121         glPopAttrib();
00122 
00123         // Advance OpenGL raster position to next line
00124         glBitmap(0,0,0,0,0,-_vStep,NULL);
00125 
00126         return ok;
00127     }
00128     else
00129         return false;
00130 }
00131 
00132 int
00133 GltFontUnicode::width(const wchar_t ch) const
00134 {
00135     assert(_init);
00136 
00137     if (_init)
00138         return (_index[ch+1] - _index[ch])>>1;
00139     else
00140         return 0;
00141 }
00142 
00143 void 
00144 GltFontUnicode::OnDraw(const uint32 seed) const
00145 {
00146     assert(_init);
00147 
00148     if (_init)
00149     {
00150         const wchar_t ch = wchar_t(seed);
00151 
00152         if (_data)
00153         {       
00154             const int w = width(ch);
00155 
00156             assert(w==0 || w==8 || w==16);
00157 
00158             if (w>0)
00159             {
00160                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00161                 glBitmap(w,16,0,15,w,0,(GLubyte *) _data + _index[ch]);
00162             }
00163         }
00164     }
00165 }
00166 
00168 
00169 // Create variable-length header for font data
00170 
00171 bool 
00172 GltFontUnicode::makeHeader(string &header,const int compressed)
00173 {
00174     // 11 characters is big enough for integer 2^32 + \0
00175 
00176     char buffer[5+11];
00177     sprintf(buffer,"GLTU %u",compressed);
00178     header = buffer;
00179     header += '\0';
00180 
00181     return true;
00182 }
00183 
00184 // Decode variable-length header for texture data
00185 
00186 void *
00187 GltFontUnicode::getHeader(const void * const data,int &compressed)
00188 {
00189     const char * const h = (const char * const) data;
00190     
00191     if (h[0]=='G' && h[1]=='L' && h[2]=='T' && h[3]=='U' && h[4]==' ')
00192     {
00193         if (sscanf(h+5,"%i",&compressed)==1)
00194             return (void *) (h + strlen(h) + 1);
00195     }
00196 
00197     return NULL;
00198 }
00199 
00200 #if 0
00201 
00202 bool 
00203 GltFontUnicode::writeSrc(ostream &os)
00204 {
00205     if (!_size)
00206         return false;
00207         
00208     os << "/* This source file written by GltFontUnicode::writeSrc()    */" << endl;
00209     os << "/* Refer to GltFontUnicode Documentation                     */" << endl;
00210     os << "/*                                                           */" << endl;
00211     os << "/* GNU Unicode Font         http://czyborra.com/unifont/     */" << endl;
00212     os << "/* GLT OpenGL Integeration: http://www.nigels.com/glt/       */" << endl;
00213     os << endl;
00214     
00215     os << "unsigned int unifontSize = " << _size << ';' << endl << endl;
00216     
00217     os << "unsigned char unifontData[] = " << endl;
00218     bin2src(os,(unsigned char *) _data,_size);
00219     os << endl;
00220 
00221     os << "unsigned char unifontIndex[] = " << endl;
00222     bin2src(os,(unsigned char *) _index,sizeof(_index));
00223     os << endl;
00224 
00225     return false;
00226 }
00227 
00228 bool 
00229 GltFontUnicode::writeAsm(ostream &os)
00230 {
00231     if (!_size)
00232         return false;
00233         
00234     os << "/* This source file written by GltFontUnicode::writeAsm()    */" << endl;
00235     os << "/* Refer to GltFontUnicode Documentation                     */" << endl;
00236     os << "/*                                                           */" << endl;
00237     os << "/* GNU Unicode Font         http://czyborra.com/unifont/     */" << endl;
00238     os << "/* GLT OpenGL Integeration: http://www.nigels.com/glt/       */" << endl;
00239     os << endl;
00240 
00241     os << ".globl _unifontSize\n.balign 4\n_unifontSize:\n";
00242     bin2asm(os,(unsigned char *) &_size,sizeof(_size));
00243     os << endl;
00244 
00245     os << ".globl _unifontData\n.balign 4\n_unifontData:\n";
00246     bin2asm(os,(unsigned char *) _data,_size);
00247     os << endl;
00248 
00249     os << ".globl _unifontIndex\n.balign 4\n_unifontIndex:\n";
00250     bin2asm(os,(unsigned char *) _index,sizeof(_index));
00251     os << endl;
00252 
00253     return false;
00254 }
00255 
00256 #endif

Generated on Tue Nov 5 11:11:03 2002 for GLT by doxygen1.2.18