TextTTF.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // Code extracted from freetype-1.3.1/test/ftview.c, ftstring.c.
00004 //
00006 
00007 // this :
00008 #include "TextTTF.h"
00009 
00010 #include "OpenGL.h"
00011 
00012 #include <iostream>
00013 
00014 #ifdef HAVE_TTF
00015 #include <freetype.h>
00016 
00017 #define MAXIMUM(a,b) ((a)>(b)?a:b)
00018 #define MINIMUM(a,b) ((a)<(b)?a:b)
00019 
00020 class TextTTF_Internal {
00021 public:
00022   TT_Error loadTrueTypeChar(int);
00023   bool fOpened;
00024   TT_Face fFace;
00025   TT_CharMap fCharMap;
00026   TT_Instance fInstance;
00027   TT_Instance_Metrics fInstanceMetrics;
00028   TT_Glyph fGlyph;
00029   TT_Raster_Map fBitmap;
00030   int fNumGlyphs;
00031   bool fHinted;
00032   bool fNewLine;
00033   TT_UShort fWidth;
00034   TT_UShort fTextWidth;
00035   TT_UShort fTextHeight;
00036   float fXJustifyTranslation;
00037   float fYJustifyTranslation;
00038 };
00039 
00040 static TT_Engine* fEngine = 0;
00041 
00043 TT_Error TextTTF_Internal::loadTrueTypeChar( 
00044  int aIndex
00045 )
00048 {
00049   //int  flags = TTLOAD_SCALE_GLYPH;
00050   //if (fHinted==true) flags |= TTLOAD_HINT_GLYPH;
00051   int  flags = TTLOAD_DEFAULT;
00052   return TT_Load_Glyph( fInstance, fGlyph, aIndex, flags );
00053 }
00054 #endif
00055 
00057 hippodraw::TextTTF::TextTTF(
00058 )
00059 :fStatus(false)
00060 ,fInitFont(true)
00061 ,fPointSize(0)
00062 ,fViewportWidth(0)
00063 ,fViewportHeight(0)
00064 ,fRotated(false)
00067 {
00068 #ifdef HAVE_TTF
00069   if(!fEngine) {
00070     fEngine = new TT_Engine;
00071     TT_Error error = TT_Init_FreeType(fEngine);
00072     if(error) {
00073       std::cout << "TextTTF : could not initialise FreeType." << std::endl;
00074       return;
00075     }
00076     // When finished , should do a : TT_Done_FreeType(fEngine);
00077   }
00078 #else
00079   std::cout << "TextTTF : compiled without HAVE_TTF CPP macro" << std::endl;
00080 #endif
00081 
00082   //m_fileName = "times";
00083   m_fileName = "helvetica";
00084   m_size = 64;
00085   m_horizontalJustification = LEFT;
00086   m_verticalJustification = BOTTOM;
00087   m_viewportMapping = NONE;
00088 #ifdef HAVE_TTF
00089   fTTF = new TextTTF_Internal;
00090   fTTF->fOpened = false;
00091   fTTF->fBitmap.bitmap = 0;
00092 #else
00093   fTTF = 0;
00094 #endif
00095   
00096   fPointSize = (int)m_size;
00097   initFont();
00098   fInitFont = false;
00099 }
00101 hippodraw::TextTTF::~TextTTF (
00102 )
00105 {
00106   fStatus = false;
00107 #ifdef HAVE_TTF
00108   if(fTTF->fOpened==true) {
00109     free(fTTF->fBitmap.bitmap);
00110     TT_Done_Glyph(fTTF->fGlyph);
00111     TT_Done_Instance(fTTF->fInstance);
00112     TT_Close_Face(fTTF->fFace);
00113     fTTF->fOpened = false;
00114   }
00115   delete fTTF;
00116 #endif
00117 }
00118 void hippodraw::TextTTF::setFileName(const std::string& aFileName){
00119   m_fileName = aFileName;
00120   fInitFont = true;
00121 }
00122 void hippodraw::TextTTF::setString(const std::string& aString) {
00123   m_strings.clear();
00124   m_strings.push_back(aString);
00125   fInitFont = true;
00126 }
00127 void hippodraw::TextTTF::setStrings(const std::vector<std::string>& aStrings) {
00128   m_strings = aStrings;
00129   fInitFont = true;
00130 }
00131 void hippodraw::TextTTF::setSize(float aSize){
00132   m_size = aSize;
00133   fInitFont = true;
00134 }
00135 void hippodraw::TextTTF::setJustification(Justification aH,Justification aV){
00136   m_horizontalJustification = aH;
00137   m_verticalJustification = aV;
00138   fInitFont = true;
00139 }
00140 void hippodraw::TextTTF::setRotated(bool aYesNo){
00141   fRotated = aYesNo;
00142 }
00144 void hippodraw::TextTTF::render (
00145 )
00148 {
00149 #ifdef HAVE_TTF
00150   if(m_viewportMapping==TextTTF::NONE) {
00151     if(fInitFont) {
00152       fPointSize = (int)m_size;
00153       initFont();
00154       fInitFont = false;
00155     }
00156   } /*
00157       else if(m_viewportMapping==TextTTF::RESCALE) {
00158     SbViewportRegion vpr = SoViewportRegionElement::get(aAction->getState());
00159     const SbVec2s& win = vpr.getViewportSizePixels();
00160     if( fInitFont || (win[0]!=fViewportWidth) || (win[1]!=fViewportHeight) ) {
00161       if(win[0]<=win[1]) {
00162         fPointSize = (int)(m_size * win[0]);
00163       } else {
00164         fPointSize = (int)(m_size * win[1]);
00165       }
00166       initFont();
00167       fInitFont = false;
00168       fViewportWidth = win[0];
00169       fViewportHeight = win[1];
00170     }
00171   } else if(m_viewportMapping==TextTTF::ADJUST) {
00172     SbViewportRegion vpr = SoViewportRegionElement::get(aAction->getState());
00173     const SbVec2s& win = vpr.getViewportSizePixels();
00174     if( fInitFont || (win[0]!=fViewportWidth) || (fViewportHeight!=win[1]) ) {
00175       // Get size with current point size;
00176       SbVec2s sz = getTextSizePixels();
00177       //printf("debug : sz : %d %d : %d %d\n",win[0],win[1],sz[0],sz[1]);
00178       if( (sz[0]>0) && (sz[1]>0)) {
00179         if(win[0]<=win[1]) {
00180           if(sz[0]<=sz[1]) {
00181             fPointSize = 
00182               (int)(((float)fPointSize) * ((float)win[1])/((float)sz[1]));
00183           } else {
00184             fPointSize = (int)(fPointSize * win[0]/((float)sz[0]));
00185           }
00186         } else {
00187           if(sz[0]<=sz[1]) {    
00188             fPointSize = (int)(fPointSize * win[1]/((float)sz[1]));
00189           } else {
00190             fPointSize = (int)(fPointSize * win[0]/((float)sz[0]));
00191           }
00192         }
00193         initFont();
00194         //sz = getTextSizePixels();
00195         //printf("debug : new : sz : %d %d : %d %d\n",win[0],win[1],sz[0],sz[1]);
00196       }
00197       fInitFont = false;
00198       fViewportWidth = win[0];
00199       fViewportHeight = win[1];
00200     }
00201   }
00202     */
00203 
00204   if(fStatus==false) return;
00205 
00206   float red = 0;
00207   float green = 0;
00208   float blue = 0;
00209   glPushAttrib( (GLbitfield)(GL_CURRENT_BIT | GL_ENABLE_BIT));
00210 #ifdef WIN32  
00211   // Pb on Windows : depth test is out over bitmap !
00212   glDisable(GL_DEPTH_TEST);
00213 #endif
00214   glDisable(GL_LIGHTING);
00215   glColor3f(red,green,blue);
00216 #endif
00217 
00218 #ifdef HAVE_TTF
00219   fTTF->fXJustifyTranslation = 0;
00220   fTTF->fYJustifyTranslation = 0;
00221   short w,h;
00222   if(m_horizontalJustification==LEFT) {
00223   } else if(m_horizontalJustification==CENTER) {
00224     getTextSizePixels(w,h);
00225     fTTF->fXJustifyTranslation = 0.5F * w;
00226   } else if(m_horizontalJustification==RIGHT) {
00227     getTextSizePixels(w,h);
00228     fTTF->fXJustifyTranslation = w;
00229   }    
00230 
00231   if(m_verticalJustification==BOTTOM) {
00232   } else if(m_verticalJustification==MIDDLE) {
00233     getTextSizePixels(w,h);
00234     fTTF->fYJustifyTranslation = 0.5F * h;
00235   } else if(m_verticalJustification==TOP) {
00236     getTextSizePixels(w,h);
00237     fTTF->fYJustifyTranslation =  h;
00238   }
00239 #endif
00240 
00241   //  glRasterPos3f fixes also 
00242   // the color for rasterisation. Then
00243   // glColor3f should be done before it.
00244   //glRasterPos3f(0,0,0);
00245 
00246   glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00247   // Do a push, pop to correct a deffect of Mesa-3.1. 
00248   // If not, further line drawing will have bad colors.
00249   // The glPopAttrib will compell a reinitialisation of
00250   // some internal Mesa state.
00251   //glPushAttrib(GL_ALL_ATTRIB_BITS);
00252   //glPopAttrib();
00253 
00254   int linen = m_strings.size();
00255   for(int count=0;count<linen;count++) {
00256     renderString(m_strings[count]);
00257   }
00258 
00259   glPopAttrib();
00260 
00261 }
00264 void hippodraw::TextTTF::initFont(
00265 )
00268 {
00269   fStatus = false;
00270 #ifdef HAVE_TTF
00271   if(fPointSize<=0) return;
00272 
00273   if(fTTF->fOpened==true) {
00274     free(fTTF->fBitmap.bitmap);
00275     TT_Done_Glyph(fTTF->fGlyph);
00276     TT_Done_Instance(fTTF->fInstance);
00277     TT_Close_Face(fTTF->fFace); 
00278     fTTF->fOpened = false;
00279   }
00280 
00281   char* ttf_path = ::getenv("TTFPATH");
00282   std::string ttfpath = (!ttf_path ? "" : ttf_path);
00283   if(ttfpath=="") {
00284     std::string fullName = m_fileName;
00285     if(m_fileName.find(".ttf")==std::string::npos) fullName += ".ttf";
00286     TT_Error error = TT_Open_Face(*fEngine,fullName.c_str(),&(fTTF->fFace));
00287     if(error) {
00288       std::cout << "TextTTF::initFont : could not find or open file " 
00289                 << m_fileName << std::endl;
00290       return;
00291     }
00292   } else {
00293 
00294     char* path = (char*)ttfpath.c_str();
00295     std::vector<std::string> paths;
00296     char* token = strtok(path," ");
00297     do {
00298       paths.push_back(std::string(token));
00299     } while( (token = strtok(NULL," "))!=NULL);
00300 
00301     bool found = false;
00302     unsigned int index;
00303     for(index=0;index<paths.size();index++) {
00304       std::string fullName = paths[index];
00305 #ifdef WIN32
00306       fullName += "\\";
00307 #else
00308       fullName += "/";
00309 #endif
00310       fullName += m_fileName;
00311       if(m_fileName.find(".ttf")==std::string::npos) fullName += ".ttf";
00312       TT_Error error = 
00313         TT_Open_Face(*fEngine,fullName.c_str(),&(fTTF->fFace));
00314       if(error) continue;
00315       found = true;
00316       break;
00317     }
00318 
00319     if(found==false) {
00320       std::cout << "TextTTF::initFont : could not find or open file "
00321                 << m_fileName << std::endl;
00322       return;
00323     } 
00324   }
00325     
00326 
00327   TT_Face_Properties  properties;
00328   TT_Error error = TT_Get_Face_Properties(fTTF->fFace, &properties );
00329   if(error) {
00330     std::cout << "TextTTF::initFont : could not get face properties" << std::endl;
00331     return;
00332   }
00333 
00334   // Look for a Unicode charmap :
00335   unsigned short n = properties.num_CharMaps;
00336   unsigned short i;
00337   for ( i = 0; i < n; i++ ) {
00338     unsigned short  platform, encoding;
00339     TT_Get_CharMap_ID( fTTF->fFace, i, &platform, &encoding );
00340     if ( (platform == 3 && encoding == 1 )  ||
00341          (platform == 0 && encoding == 0 ) ) {
00342         TT_Get_CharMap( fTTF->fFace, i, &(fTTF->fCharMap) );
00343         i = n + 1;
00344       }
00345   }
00346   if ( i == n ) {
00347     std::cout << "TextTTF::initFont : this font doesn't contain any Unicode mapping table" << std::endl;
00348     return;
00349   }
00350   //printf("debug : asc %d\n",properties.vertical->Ascender);
00351 
00352   fTTF->fNumGlyphs = properties.num_Glyphs;
00353 
00354   error = TT_New_Glyph( fTTF->fFace, &(fTTF->fGlyph) );
00355   if(error) {
00356     std::cout << "TextTTF::initFont : could not create glyph container" << std::endl;
00357     return;
00358   }
00359 
00360   error = TT_New_Instance( fTTF->fFace, &(fTTF->fInstance) );
00361   if(error) {
00362     std::cout << "TextTTF::initFont : could not create instance" << std::endl;
00363     return;
00364   }
00365 
00366   // Give screen resolution.
00367   // Device resolution = # of pixels/inch. 
00368   // Around 96 for screen (300 for printer).
00369   error = TT_Set_Instance_Resolutions(fTTF->fInstance, 96, 96 );
00370   if (error) {
00371     std::cout << "TextTTF::initFont : Could not set instance resolution" << std::endl;
00372     return;
00373   }
00374 
00375   // Give size of a character in "pt" :
00376   // 1 pt = 1/72 inch.
00377   // Si n pt the char will do : n * 96 /72 pixels on screen.
00378   // Exa : 64 pt = 64 * 96 /72 = 85 pixels on screen.
00379   error = TT_Set_Instance_PointSize(fTTF->fInstance,fPointSize);
00380   //error = TT_Set_Instance_CharSize(fTTF->fInstance,fPointSize * 64);
00381   if (error) {
00382     std::cout << "TextTTF::initFont : Could not set instance point size" << std::endl;
00383     return;
00384   }
00385 
00386   error = TT_Get_Instance_Metrics(fTTF->fInstance,
00387                                   &(fTTF->fInstanceMetrics));
00388   if (error) {
00389     std::cout << "TextTTF::initFont : could not get instance metric" << std::endl;
00390     return;
00391   }
00392 
00393   // fInstanceMetrics.y_ppem, x_ppem # of screen pixels.
00394   fTTF->fBitmap.rows  = fTTF->fInstanceMetrics.y_ppem;
00395   fTTF->fBitmap.width = fTTF->fInstanceMetrics.x_ppem;
00396   // # of bytes that contains 'width'.
00397   fTTF->fBitmap.cols  = (fTTF->fBitmap.width + 7)/8;  
00398   fTTF->fBitmap.flow  = TT_Flow_Up;
00399   fTTF->fBitmap.size  = (long)(fTTF->fBitmap.rows * fTTF->fBitmap.cols);
00400   fTTF->fBitmap.bitmap = malloc( (int)fTTF->fBitmap.size );
00401   if(!fTTF->fBitmap.bitmap) return;
00402 
00403   fTTF->fHinted = true;
00404 
00405   /* printf("debug : i char size %d pt ; ppem %d %d ; res %d %d\n",
00406          fInstanceMetrics.pointSize,
00407          fInstanceMetrics.x_ppem,fInstanceMetrics.y_ppem,
00408          fInstanceMetrics.x_resolution,fInstanceMetrics.y_resolution);
00409   */
00410 
00411   //printf("debug : size rows %d cols %d\n",fBitmap.rows,fBitmap.cols);
00412 
00413   //printf("debug : TextTTF : update\n");
00414 
00415   fTTF->fOpened = true;
00416 
00417   fStatus = true;
00418 #endif
00419 }
00421 void hippodraw::TextTTF::renderString(
00422  const std::string& aString 
00423 )
00426 {
00427   if(aString=="") return;
00428 #ifdef HAVE_TTF
00429   fTTF->fNewLine = false;
00430   fTTF->fWidth = 0;
00431   int l = aString.size();
00432   for(int count=0;count<l;count++) { 
00433     if(count==l-1) fTTF->fNewLine = true;
00434     renderCharacter(aString[count]);
00435   }
00436 #endif
00437 }
00439 void hippodraw::TextTTF::renderCharacter(
00440  char aChar 
00441 )
00443 /* Convert an ASCII string to a string of glyph indexes.              */
00444 /*                                                                    */
00445 /* IMPORTANT NOTE:                                                    */
00446 /*                                                                    */
00447 /* There is no portable way to convert from any system's char. code   */
00448 /* to Unicode.  This function simply takes a char. string as argument */
00449 /* and "interprets" each character as a Unicode char. index with no   */
00450 /* further check.                                                     */
00451 /*                                                                    */
00452 /* This mapping is only valid for the ASCII character set (i.e.,      */
00453 /* codes 32 to 127); all other codes (like accentuated characters)    */
00454 /* will produce more or less random results, depending on the system  */
00455 /* being run.                                                         */
00456 
00457 
00458 {
00459 #ifdef HAVE_TTF
00460   short index = TT_Char_Index( fTTF->fCharMap, (short)aChar);
00461 
00462   if((index<0)||(index>=fTTF->fNumGlyphs)) return;
00463 
00464   //postInfo("TextTTF::renderCharacter","debug 001");
00465 
00466   TT_Error error = fTTF->loadTrueTypeChar(index);
00467   if (error) {
00468     std::cout << "TextTTF::renderCharacter." << std::endl;
00469     return;
00470   }
00471 
00472   // Metric infos are given in "Char_PointSize * 64 units".
00473   TT_Big_Glyph_Metrics  metrics;
00474   error = TT_Get_Glyph_Big_Metrics( fTTF->fGlyph, &metrics );
00475   if (error) {
00476     std::cout << "TextTTF::renderCharacter : could not get glyph metrics"
00477               << std::endl;
00478     return;
00479   }
00480 
00481   /* printf("debug : bb xmn %d ymn %d xmx %d ymx %d ; bX %d bY %d ; adv %d %d\n",
00482          metrics.bbox.xMin,metrics.bbox.yMin,
00483          metrics.bbox.xMax,metrics.bbox.yMax,
00484          metrics.horiBearingX,metrics.horiBearingY,
00485          metrics.horiAdvance,metrics.vertAdvance);
00486   */
00487   
00488   // To bring the whole glyph in the bitmap.
00489   TT_F26Dot6 xmin, ymin;
00490   xmin = metrics.bbox.xMin & -64;
00491   ymin = metrics.bbox.yMin & -64;
00492 
00493   //printf("debug : xx %d %d\n",xmin,ymin);
00494 
00495   memset( fTTF->fBitmap.bitmap, 0, fTTF->fBitmap.size );
00496   error = TT_Get_Glyph_Bitmap( fTTF->fGlyph, 
00497                                &(fTTF->fBitmap), 
00498                                -xmin, -ymin);
00499   if (error) {
00500     std::cout << "TextTTF::renderCharacter : could not get glyph bitmap"
00501               << std::endl;
00502   } else {
00503 
00504     TT_F26Dot6 xmove,ymove;
00505     if(fTTF->fNewLine==true) {
00506       xmove = -fTTF->fWidth;
00507       //ymove = -(fTTF->fInstanceMetrics.y_ppem + 10);
00508       ymove = - (metrics.vertAdvance/64);
00509       fTTF->fNewLine = false;
00510     } else {
00511       //xmove = fInstanceMetrics.x_ppem + 3;
00512       xmove = metrics.horiAdvance/64;
00513       ymove = 0;
00514       fTTF->fWidth += (TT_UShort)xmove;
00515     }
00516 
00517     float xorig = fTTF->fXJustifyTranslation;
00518     float yorig = (float)(-ymin/64)+fTTF->fYJustifyTranslation;
00519 
00520     if(fRotated) {
00521       GLubyte* pfrom = (GLubyte*)fTTF->fBitmap.bitmap;
00522       GLsizei bwidth = fTTF->fBitmap.rows;
00523       GLsizei bheight = fTTF->fBitmap.width;
00524       GLubyte* bptr = new GLubyte[bwidth * bheight];
00525       int irow;
00526       for(irow=0;irow<fTTF->fBitmap.rows;irow++) {
00527         int icol = 0;
00528         for(int ibyte=0;ibyte<fTTF->fBitmap.cols;ibyte++) {
00529           GLubyte byte = *pfrom; //Contains 8 pixels.
00530           pfrom++;
00531           GLubyte pixel8 = (byte >> 0) & 0x1;
00532           GLubyte pixel7 = (byte >> 1) & 0x1;
00533           GLubyte pixel6 = (byte >> 2) & 0x1;
00534           GLubyte pixel5 = (byte >> 3) & 0x1;
00535           GLubyte pixel4 = (byte >> 4) & 0x1;
00536           GLubyte pixel3 = (byte >> 5) & 0x1;
00537           GLubyte pixel2 = (byte >> 6) & 0x1;
00538           GLubyte pixel1 = (byte >> 7) & 0x1;
00539 
00540           int bicol = fTTF->fBitmap.rows-irow-1; // To have + 90 deg.
00541 
00542           int birow = icol;
00543           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel1;
00544           icol++;
00545 
00546           birow = icol;
00547           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel2;
00548           icol++;
00549 
00550           birow = icol;
00551           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel3;
00552           icol++;
00553 
00554           birow = icol;
00555           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel4;
00556           icol++;
00557 
00558           birow = icol;
00559           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel5;
00560           icol++;
00561 
00562           birow = icol;
00563           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel6;
00564           icol++;
00565 
00566           birow = icol;
00567           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel7;
00568           icol++;
00569 
00570           birow = icol;
00571           if(icol<fTTF->fBitmap.width) *(bptr+birow*bwidth+bicol) = pixel8;
00572           icol++;          
00573         }
00574       }
00575       GLubyte* ptr = bptr;
00576       int bcols = (bwidth + 7)/8;  
00577       GLubyte* bptr2 = new GLubyte[bheight * bcols];
00578       GLubyte* ptr2 = bptr2;
00579       for(irow=0;irow<bheight;irow++) {
00580         int icol = 0;
00581         for(int ibyte=0;ibyte<bcols;ibyte++) {
00582           GLubyte byte = 0;
00583           if(icol<bwidth) {
00584             byte = byte | ((*ptr) << 7);
00585             ptr++;icol++;
00586           }
00587           if(icol<bwidth) {
00588             byte = byte | ((*ptr) << 6);
00589             ptr++;icol++;
00590           }
00591           if(icol<bwidth) {
00592             byte = byte | ((*ptr) << 5);
00593             ptr++;icol++;
00594           }
00595           if(icol<bwidth) {
00596             byte = byte | ((*ptr) << 4);
00597             ptr++;icol++;
00598           }
00599           if(icol<bwidth) {
00600             byte = byte | ((*ptr) << 3);
00601             ptr++;icol++;
00602           }
00603           if(icol<bwidth) {
00604             byte = byte | ((*ptr) << 2);
00605             ptr++;icol++;
00606           }
00607           if(icol<bwidth) {
00608             byte = byte | ((*ptr) << 1);
00609             ptr++;icol++;
00610           }
00611           if(icol<bwidth) {
00612             byte = byte | ((*ptr) << 0);
00613             ptr++;icol++;
00614           }
00615           *ptr2 = byte;ptr2++;
00616         }
00617       }
00618       glBitmap(bwidth,bheight,xorig+bwidth,yorig,(float)ymove,(float)xmove,
00619                (GLubyte*)bptr2);
00620       delete [] bptr;
00621       delete [] bptr2;
00622     } else {
00623       glBitmap(fTTF->fBitmap.width,fTTF->fBitmap.rows,
00624                xorig,yorig,(float)xmove,(float)ymove,
00625                (GLubyte*)fTTF->fBitmap.bitmap);
00626     }
00627   }
00628 #else
00629   aChar = 0;
00630 #endif
00631 }
00633 bool hippodraw::TextTTF::getTextSizePixels(
00634  short& aWidth
00635 ,short& aHeight
00636 )
00639 {
00640   aWidth = 0;
00641   aHeight = 0;
00642   if(fStatus==false) return false;
00643 #ifdef HAVE_TTF
00644   int linen = m_strings.size();
00645   fTTF->fTextWidth = 0;
00646   fTTF->fTextHeight = 0;
00647   for(int count=0;count<linen;count++) {
00648     const std::string& s = m_strings[count];
00649     if(s=="") continue; // Must be coherent with GLRender.
00650     fTTF->fNewLine = false;
00651     fTTF->fWidth = 0;
00652     int l = s.size();
00653     TT_F26Dot6 yMax = 0;
00654     TT_F26Dot6 yMin = 0;
00655     for(int i=0;i<l;i++) { 
00656       if(i==l-1) fTTF->fNewLine = true;
00657       char c = s[i];
00658       short index = TT_Char_Index(fTTF->fCharMap,(short)c);
00659       if((index<0)||(index>=fTTF->fNumGlyphs)) continue; //?
00660       TT_Error error = fTTF->loadTrueTypeChar(index);
00661       if (error) {
00662         std::cout << "TextTTF::getTextSizePixels" << std::endl;
00663         continue; // Same as GLRender.
00664       }
00665       // Metric infos are given in "Char_PointSize * 64 units".
00666       TT_Big_Glyph_Metrics  metrics;
00667       error = TT_Get_Glyph_Big_Metrics( fTTF->fGlyph, &metrics );
00668       if (error) {
00669         std::cout << "TextTTF::getTextSizePixels : could not get glyph metrics"
00670                   << std::endl;
00671         continue; //Same as GLRender.
00672       }
00673       //TT_F26Dot6 xmin, ymin;
00674       //xmin = metrics.bbox.xMin & -64;
00675       //ymin = metrics.bbox.yMin & -64;
00676       TT_F26Dot6 xmove,ymove;
00677       if(fTTF->fNewLine==true) {
00678         fTTF->fWidth += (TT_UShort)metrics.horiAdvance/64;
00679         xmove = -fTTF->fWidth;
00680         //ymove = -(fTTF->fInstanceMetrics.y_ppem + 10);
00681         ymove = - (metrics.vertAdvance/64);
00682         fTTF->fNewLine = false;
00683         //
00684         fTTF->fTextWidth = MAXIMUM(fTTF->fTextWidth,fTTF->fWidth);
00685         if(count==0) fTTF->fTextHeight += yMax; // First line.
00686         if(count!=linen-1) fTTF->fTextHeight += (TT_UShort)-ymove;
00687         if(count==linen-1) fTTF->fTextHeight += -yMin; // Last line.
00688       } else {
00689         //xmove = fInstanceMetrics.x_ppem + 3;
00690         xmove = metrics.horiAdvance/64;
00691         ymove = 0;
00692         fTTF->fWidth += (TT_UShort)xmove;
00693       }
00694       yMax = MAXIMUM(yMax,(metrics.bbox.yMax & -64)/64);
00695       yMin = MINIMUM(yMin,(metrics.bbox.yMin & -64)/64);
00696     }
00697   }
00698   aWidth = fTTF->fTextWidth;
00699   aHeight = fTTF->fTextHeight;
00700   return true;
00701 #else
00702   return false;
00703 #endif
00704 }

Generated for HippoDraw Class Library by doxygen