17 #define MAXIMUM(a,b) ((a)>(b)?a:b)
18 #define MINIMUM(a,b) ((a)<(b)?a:b)
20 class TextTTF_Internal {
22 TT_Error loadTrueTypeChar(
int);
26 TT_Instance fInstance;
27 TT_Instance_Metrics fInstanceMetrics;
29 TT_Raster_Map fBitmap;
35 TT_UShort fTextHeight;
36 float fXJustifyTranslation;
37 float fYJustifyTranslation;
40 static TT_Engine* fEngine = 0;
43 TT_Error TextTTF_Internal::loadTrueTypeChar(
51 int flags = TTLOAD_DEFAULT;
52 return TT_Load_Glyph( fInstance, fGlyph, aIndex, flags );
70 fEngine =
new TT_Engine;
71 TT_Error error = TT_Init_FreeType(fEngine);
73 std::cout <<
"TextTTF : could not initialise FreeType." << std::endl;
79 std::cout <<
"TextTTF : compiled without HAVE_TTF CPP macro" << std::endl;
89 fTTF =
new TextTTF_Internal;
90 fTTF->fOpened =
false;
91 fTTF->fBitmap.bitmap = 0;
108 if(
fTTF->fOpened==
true) {
109 free(
fTTF->fBitmap.bitmap);
110 TT_Done_Glyph(
fTTF->fGlyph);
111 TT_Done_Instance(
fTTF->fInstance);
112 TT_Close_Face(
fTTF->fFace);
113 fTTF->fOpened =
false;
209 glPushAttrib( (GLbitfield)(GL_CURRENT_BIT | GL_ENABLE_BIT));
212 glDisable(GL_DEPTH_TEST);
214 glDisable(GL_LIGHTING);
215 glColor3f(red,green,blue);
219 fTTF->fXJustifyTranslation = 0;
220 fTTF->fYJustifyTranslation = 0;
225 fTTF->fXJustifyTranslation = 0.5F * w;
228 fTTF->fXJustifyTranslation = w;
234 fTTF->fYJustifyTranslation = 0.5F * h;
237 fTTF->fYJustifyTranslation = h;
246 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
255 for(
int count=0;count<linen;count++) {
273 if(
fTTF->fOpened==
true) {
274 free(
fTTF->fBitmap.bitmap);
275 TT_Done_Glyph(
fTTF->fGlyph);
276 TT_Done_Instance(
fTTF->fInstance);
277 TT_Close_Face(
fTTF->fFace);
278 fTTF->fOpened =
false;
281 char* ttf_path = ::getenv(
"TTFPATH");
282 std::string ttfpath = (!ttf_path ?
"" : ttf_path);
285 if(
m_fileName.find(
".ttf")==std::string::npos) fullName +=
".ttf";
286 TT_Error error = TT_Open_Face(*fEngine,fullName.c_str(),&(
fTTF->fFace));
288 std::cout <<
"TextTTF::initFont : could not find or open file "
294 char* path = (
char*)ttfpath.c_str();
295 std::vector<std::string> paths;
296 char* token = strtok(path,
" ");
298 paths.push_back(std::string(token));
299 }
while( (token = strtok(NULL,
" "))!=NULL);
303 for(index=0;index<paths.size();index++) {
304 std::string fullName = paths[index];
311 if(
m_fileName.find(
".ttf")==std::string::npos) fullName +=
".ttf";
313 TT_Open_Face(*fEngine,fullName.c_str(),&(
fTTF->fFace));
320 std::cout <<
"TextTTF::initFont : could not find or open file "
327 TT_Face_Properties properties;
328 TT_Error error = TT_Get_Face_Properties(
fTTF->fFace, &properties );
330 std::cout <<
"TextTTF::initFont : could not get face properties" << std::endl;
335 unsigned short n = properties.num_CharMaps;
337 for ( i = 0; i < n; i++ ) {
338 unsigned short platform, encoding;
339 TT_Get_CharMap_ID(
fTTF->fFace, i, &platform, &encoding );
340 if ( (platform == 3 && encoding == 1 ) ||
341 (platform == 0 && encoding == 0 ) ) {
342 TT_Get_CharMap(
fTTF->fFace, i, &(
fTTF->fCharMap) );
347 std::cout <<
"TextTTF::initFont : this font doesn't contain any Unicode mapping table" << std::endl;
352 fTTF->fNumGlyphs = properties.num_Glyphs;
354 error = TT_New_Glyph(
fTTF->fFace, &(
fTTF->fGlyph) );
356 std::cout <<
"TextTTF::initFont : could not create glyph container" << std::endl;
360 error = TT_New_Instance(
fTTF->fFace, &(
fTTF->fInstance) );
362 std::cout <<
"TextTTF::initFont : could not create instance" << std::endl;
369 error = TT_Set_Instance_Resolutions(
fTTF->fInstance, 96, 96 );
371 std::cout <<
"TextTTF::initFont : Could not set instance resolution" << std::endl;
382 std::cout <<
"TextTTF::initFont : Could not set instance point size" << std::endl;
386 error = TT_Get_Instance_Metrics(
fTTF->fInstance,
387 &(
fTTF->fInstanceMetrics));
389 std::cout <<
"TextTTF::initFont : could not get instance metric" << std::endl;
394 fTTF->fBitmap.rows =
fTTF->fInstanceMetrics.y_ppem;
395 fTTF->fBitmap.width =
fTTF->fInstanceMetrics.x_ppem;
397 fTTF->fBitmap.cols = (
fTTF->fBitmap.width + 7)/8;
398 fTTF->fBitmap.flow = TT_Flow_Up;
399 fTTF->fBitmap.size = (long)(
fTTF->fBitmap.rows *
fTTF->fBitmap.cols);
400 fTTF->fBitmap.bitmap = malloc( (
int)
fTTF->fBitmap.size );
401 if(!
fTTF->fBitmap.bitmap)
return;
403 fTTF->fHinted =
true;
415 fTTF->fOpened =
true;
422 const std::string& aString
427 if(aString==
"")
return;
429 fTTF->fNewLine =
false;
431 int l = aString.size();
432 for(
int count=0;count<l;count++) {
433 if(count==l-1)
fTTF->fNewLine =
true;
460 short index = TT_Char_Index(
fTTF->fCharMap, (
short)aChar);
462 if((index<0)||(index>=
fTTF->fNumGlyphs))
return;
466 TT_Error error =
fTTF->loadTrueTypeChar(index);
468 std::cout <<
"TextTTF::renderCharacter." << std::endl;
473 TT_Big_Glyph_Metrics metrics;
474 error = TT_Get_Glyph_Big_Metrics(
fTTF->fGlyph, &metrics );
476 std::cout <<
"TextTTF::renderCharacter : could not get glyph metrics"
489 TT_F26Dot6 xmin, ymin;
490 xmin = metrics.bbox.xMin & -64;
491 ymin = metrics.bbox.yMin & -64;
495 memset(
fTTF->fBitmap.bitmap, 0,
fTTF->fBitmap.size );
496 error = TT_Get_Glyph_Bitmap(
fTTF->fGlyph,
500 std::cout <<
"TextTTF::renderCharacter : could not get glyph bitmap"
504 TT_F26Dot6 xmove,ymove;
505 if(
fTTF->fNewLine==
true) {
506 xmove = -
fTTF->fWidth;
508 ymove = - (metrics.vertAdvance/64);
509 fTTF->fNewLine =
false;
512 xmove = metrics.horiAdvance/64;
514 fTTF->fWidth += (TT_UShort)xmove;
517 float xorig =
fTTF->fXJustifyTranslation;
518 float yorig = (float)(-ymin/64)+
fTTF->fYJustifyTranslation;
521 GLubyte* pfrom = (GLubyte*)
fTTF->fBitmap.bitmap;
522 GLsizei bwidth =
fTTF->fBitmap.rows;
523 GLsizei bheight =
fTTF->fBitmap.width;
524 GLubyte* bptr =
new GLubyte[bwidth * bheight];
526 for(irow=0;irow<fTTF->fBitmap.rows;irow++) {
528 for(
int ibyte=0;ibyte<
fTTF->fBitmap.cols;ibyte++) {
529 GLubyte byte = *pfrom;
531 GLubyte pixel8 = (byte >> 0) & 0x1;
532 GLubyte pixel7 = (byte >> 1) & 0x1;
533 GLubyte pixel6 = (byte >> 2) & 0x1;
534 GLubyte pixel5 = (byte >> 3) & 0x1;
535 GLubyte pixel4 = (byte >> 4) & 0x1;
536 GLubyte pixel3 = (byte >> 5) & 0x1;
537 GLubyte pixel2 = (byte >> 6) & 0x1;
538 GLubyte pixel1 = (byte >> 7) & 0x1;
540 int bicol =
fTTF->fBitmap.rows-irow-1;
543 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel1;
547 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel2;
551 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel3;
555 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel4;
559 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel5;
563 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel6;
567 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel7;
571 if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel8;
576 int bcols = (bwidth + 7)/8;
577 GLubyte* bptr2 =
new GLubyte[bheight * bcols];
578 GLubyte* ptr2 = bptr2;
579 for(irow=0;irow<bheight;irow++) {
581 for(
int ibyte=0;ibyte<bcols;ibyte++) {
584 byte = byte | ((*ptr) << 7);
588 byte = byte | ((*ptr) << 6);
592 byte = byte | ((*ptr) << 5);
596 byte = byte | ((*ptr) << 4);
600 byte = byte | ((*ptr) << 3);
604 byte = byte | ((*ptr) << 2);
608 byte = byte | ((*ptr) << 1);
612 byte = byte | ((*ptr) << 0);
618 glBitmap(bwidth,bheight,xorig+bwidth,yorig,(
float)ymove,(
float)xmove,
623 glBitmap(
fTTF->fBitmap.width,
fTTF->fBitmap.rows,
624 xorig,yorig,(
float)xmove,(
float)ymove,
625 (GLubyte*)
fTTF->fBitmap.bitmap);
642 if(
fStatus==
false)
return false;
645 fTTF->fTextWidth = 0;
646 fTTF->fTextHeight = 0;
647 for(
int count=0;count<linen;count++) {
650 fTTF->fNewLine =
false;
655 for(
int i=0;i<l;i++) {
656 if(i==l-1)
fTTF->fNewLine =
true;
658 short index = TT_Char_Index(
fTTF->fCharMap,(
short)c);
659 if((index<0)||(index>=
fTTF->fNumGlyphs))
continue;
660 TT_Error error =
fTTF->loadTrueTypeChar(index);
662 std::cout <<
"TextTTF::getTextSizePixels" << std::endl;
666 TT_Big_Glyph_Metrics metrics;
667 error = TT_Get_Glyph_Big_Metrics(
fTTF->fGlyph, &metrics );
669 std::cout <<
"TextTTF::getTextSizePixels : could not get glyph metrics"
676 TT_F26Dot6 xmove,ymove;
677 if(
fTTF->fNewLine==
true) {
678 fTTF->fWidth += (TT_UShort)metrics.horiAdvance/64;
679 xmove = -
fTTF->fWidth;
681 ymove = - (metrics.vertAdvance/64);
682 fTTF->fNewLine =
false;
684 fTTF->fTextWidth = MAXIMUM(
fTTF->fTextWidth,
fTTF->fWidth);
685 if(count==0)
fTTF->fTextHeight += yMax;
686 if(count!=linen-1)
fTTF->fTextHeight += (TT_UShort)-ymove;
687 if(count==linen-1)
fTTF->fTextHeight += -yMin;
690 xmove = metrics.horiAdvance/64;
692 fTTF->fWidth += (TT_UShort)xmove;
694 yMax = MAXIMUM(yMax,(metrics.bbox.yMax & -64)/64);
695 yMin = MINIMUM(yMin,(metrics.bbox.yMin & -64)/64);
698 aWidth =
fTTF->fTextWidth;
699 aHeight =
fTTF->fTextHeight;