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
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
00170
00171 bool
00172 GltFontUnicode::makeHeader(string &header,const int compressed)
00173 {
00174
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
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