views:

188

answers:

1

Hello, I'm searching for a library to get the outline of a glyph in a true type font on a linux system. We are using Pango and Cairo but unfortunatly I didn't find anything. I'm looking for somethig similar to GlyphTypeface.GetGlyphOutline under .NET

Any help or hints are appreciated!

Thanks in advance

+2  A: 

The solution is to use FreeType, it offers the range of function I need:

#include <string>
#include <iostream>
#include  <freetype/ftglyph.h>
#include  <freetype/freetype.h>

//******************* check error code ********************
void Check(FT_Error ErrCode, const char* OKMsg, const char* ErrMsg)
{
  if(ErrCode != 0)
  {
std::cout << ErrMsg << ": " << ErrCode << "\n";
std::cout << "program halted\n";
exit(1);
  }
  else
    std::cout << OKMsg << "\n";
  }

//******************** get outline ************************
int GetOutLine(FT_Glyph glyph, FT_OutlineGlyph* Outg)
{
  int Err = 0;

  switch ( glyph->format )
  {
    case FT_GLYPH_FORMAT_BITMAP:
      Err = 1;
      break;

    case FT_GLYPH_FORMAT_OUTLINE:
      *Outg = (FT_OutlineGlyph)glyph;
      break;

    default:
      ;
  }
  return Err;
}

//*********** print outline  to console ***************
int PrintOutLine(FT_OutlineGlyph Outg)
{
int Err = 0;
FT_Outline* Ol = &Outg->outline;
int Start = 0;                   //start index of contour
int End = 0;                     //end index of contour
short* pContEnd = Ol->contours;  //pointer to contour end
FT_Vector* pPoint = Ol->points;  //pointer to outline point
    char* pFlag = Ol->tags;          //pointer to flag

for(int c = 0; c < Ol->n_contours; c++)
{
    std::cout << "\nContour " << c << ":\n";
    End = *pContEnd++;
    for(int p = Start; p <= End; p++)
    {
        char Ch = *pFlag++ + '0';
        std::cout << "Point " << p <<": X=" << pPoint->x << " Y="<<pPoint->y << " Flag=" << Ch << "\n";
        pPoint++;
    }
    Start = End + 1;
} 

return Err;
}

//*********** get glyph index from command line *************
 FT_UInt GetGlyphIndex(int argc, char* argv[], int Nr)
 {
if(argc > Nr)
{
  return atoi(argv[Nr]);
}
else
{
  return 36;
}
 } 

//*********** get font name from command line *************
 void GetFontName(int argc, char* argv[], int Nr, std::string& FontName)
 {
if(argc > Nr)
{
  FontName += argv[Nr]; 
}
else
{
  FontName += "FreeMono.ttf";
}
 } 

 //*********** get font size from command line *************
 int GetFontSize(int argc, char* argv[], int Nr)
 {
   short FontSize = 50 * 64;
   if(argc > Nr)
     FontSize += atoi(argv[Nr]); 
   return FontSize;
 } 

//******************** M A I N ************************
// par1: FontName, par2:Glyph-Nr, par3: FontSize as FT_F26Dot6
int main(int argc, char* argv[])
{
  FT_Face face;
  FT_Library    library;
  FT_Error error;

  error = FT_Init_FreeType( &library );
  Check(error, "", "error initializing FT lib");

  std::string FontName;
  FontName = "/usr/share/fonts/truetype/freefont/";
  GetFontName(argc, argv, 1, FontName);
  error = FT_New_Face( library, FontName.c_str(), 0, &face );   
  Check(error, "",  "error loading font");

  FT_F26Dot6 font_size = GetFontSize(argc, argv, 3);
  error = FT_Set_Char_Size( face, font_size, font_size, 72, 72 );
  Check(error, "", "error setting char size");

  FT_UInt   glyph_index = GetGlyphIndex(argc, argv, 2);
  FT_Int32  load_flags = FT_LOAD_DEFAULT;   
  error = FT_Load_Glyph( face,  glyph_index, load_flags );      
  Check(error, "", "error loading glyph");

  FT_Glyph glyph; 
  error = FT_Get_Glyph( face->glyph, &glyph );  
  Check(error, "", "error getting glyph");

  FT_OutlineGlyph Outg;
  error = GetOutLine(glyph, &Outg);
  Check(error,"", "error getting outline"); 

  std::cout << "=======================================================\n";
  std::cout << "Font: " << FontName << "\n";
  std::cout << "Glyph Index: " << glyph_index << "\n";
  std::cout << "=======================================================\n";
  error = PrintOutLine(Outg);
  Check(error,"", "error printing outline"); 

  return 0;  
}
chrmue