Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46907
  • 博文数量: 14
  • 博客积分: 1485
  • 博客等级: 上尉
  • 技术积分: 160
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-13 15:44
文章分类

全部博文(14)

文章存档

2012年(1)

2011年(2)

2010年(3)

2009年(8)

我的朋友

分类: LINUX

2009-12-08 21:43:07

#include
#include
#include "gb2312.h"
#include "freetype2.h"
static struct{
 char szFontName[64];
 char szFontFile[128];
}FontInfo[] = {
 { "楷体", "./simkai.ttf"   },
 { "黑体", "./simhei.ttf"   },
 { "宋体", "./simsun.ttc"  },
 { "Uming", "./uming.ttf"  } 
};
static char* GetFontFile(char *pszFontName)
{
 int i;
 int nSize;
 
 if((NULL == pszFontName) || ('\0' == *pszFontName))
  goto err;
 
 nSize = sizeof(FontInfo) / sizeof(FontInfo[0]);
 
 for(i=0; i {
  if(!strcmp(pszFontName, FontInfo[i].szFontName))
   return FontInfo[i].szFontFile;
 }
 
err:
 return FontInfo[2].szFontFile;
}
BOOL FreeType2_InitFont(PFREETYPE2FONT pFont, char *pszName)
{
 char *pszFontFile;
 FT_Error err;
 if((NULL == pFont) || (NULL == pszName) || ('\0' == *pszName))
  return FALSE;
 pszFontFile = GetFontFile(pszName);
 if(NULL == pszFontFile)
  return FALSE;
 err = FT_Init_FreeType(&pFont->library);
 if(err != FT_Err_Ok)
 {
  printf("InitFont->FT_InitFreeType error: %d\n", err);
  pFont->library = NULL;
  return FALSE;
 }
 err = FT_New_Face(pFont->library, pszFontFile, 0, &pFont->face);
 if(err != FT_Err_Ok)
 {
  printf("InitFont->FT_New_Face error: %d\n", err);
  FT_Done_FreeType(pFont->library);
  pFont->library = NULL;
  pFont->face = NULL;
  return FALSE;
 }
 err = FT_Set_Char_Size(pFont->face, 0, 64 << 4, 300, 300);
 if(err != FT_Err_Ok)
 {
  printf("InitFont->FT_Set_Char_Size error: %d\n", err);
  FT_Done_Face(pFont->face);
  FT_Done_FreeType(pFont->library);
  pFont->library = NULL;
  pFont->face = NULL;
  return FALSE;
 }
 pFont->pucData = NULL;
 return TRUE;
}
BOOL FreeType2_DestroyFont(PFREETYPE2FONT pFont)

 if(NULL == pFont)
  return FALSE;
 if(pFont->face != NULL)
  FT_Done_Face(pFont->face);
 if(pFont->library != NULL)
  FT_Done_FreeType(pFont->library);
 pFont->face = NULL;
 pFont->library = NULL;
 if(pFont->pucData != NULL)
  free(pFont->pucData);
  
 pFont->pucData = NULL;
 return TRUE;
}
BOOL FreeType2_SetFontSize(PFREETYPE2FONT pFont, int nWid, int nHei)
{
 FT_Error err;
 if((NULL == pFont) || (NULL == pFont->face))
  return FALSE;
 err = FT_Set_Pixel_Sizes(pFont->face, nWid, nHei);
 if(err != FT_Err_Ok)
 {
  printf("SetFontSize->FT_Set_Pixel_Sizes error: %d\n", err);
  return FALSE;
 }
 return TRUE;
}
static unsigned short s_font_utf8_to_unicode (const unsigned char *utf8)
{
 unsigned short unicode;
 unicode = utf8[0];
 if (unicode >= 0xF0) {
  unicode  =  (unsigned short) (utf8[0] & 0x07) << 18;
  unicode |=  (unsigned short) (utf8[1] & 0x3F) << 12;
  unicode |=  (unsigned short) (utf8[2] & 0x3F) << 6;
  unicode |=  (unsigned short) (utf8[3] & 0x3F);
 } else if (unicode >= 0xE0) {
  unicode  =  (unsigned short) (utf8[0] & 0x0F) << 12;
  unicode |=  (unsigned short) (utf8[1] & 0x3F) << 6;
  unicode |=  (unsigned short) (utf8[2] & 0x3F);
 } else if (unicode >= 0xC0) {
  unicode  =  (unsigned short) (utf8[0] & 0x1F) << 6;
  unicode |=  (unsigned short) (utf8[1] & 0x3F);
 }
 return unicode;
}
BOOL FreeType2_GetFontChar(FT_Face face, char *pszText, PXGlyph pXGlyph, BOOL bFlag)
{
 unsigned short unicode;
 FT_UInt index;
 FT_BBox bbox;
 FT_Error err;
 FT_Vector origin;
 FT_Glyph glyph; 
 
 if((NULL == face) || (NULL == pszText) || ('\0' == *pszText) || (NULL == pXGlyph))
  return FALSE;
 
 memset((void*)pXGlyph, 0, sizeof(XGlyph));
 
 if(*pszText & 0x80)
  unicode = gb2312_0_conv_to_uc32(pszText);
 else
  unicode = s_font_utf8_to_unicode(pszText);
 index = FT_Get_Char_Index(face, unicode);
 if(!index)
 {
  printf("FreeType2_GetFontChar->FT_Get_Char_Index fail: index=0 !\n");
  return FALSE;
 }
 err = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT);
 if(err)
 {
  printf("FreeType2_GetFontChar->FT_Load_Glyph fail !\n");
  return FALSE; 
 }
 err = FT_Get_Glyph(face->glyph, &glyph);
 if(err)
 {
  printf("FreeType2_GetFontChar->FT_Get_Glyph fail !\n");
  return FALSE; 
 }
 FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_gridfit, &bbox);
 
 origin.x = -bbox.xMin;
 origin.y = -bbox.yMin;
 
 if(FT_IS_SCALABLE(face))
 {
  err = FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, &origin, 1);
  if(err)
  {
   FT_Done_Glyph(glyph);
   printf("FreeType2_GetFontChar->FT_Glyph_To_Bitmap fail !\n");
   return FALSE;
  }
  
  else
  {
   int nSize;
   FT_Bitmap bm = ((FT_BitmapGlyph)glyph)->bitmap;
   nSize = bm.pitch * bm.rows;
   if(nSize > 0)
   {
    if(bFlag)
    {
     pXGlyph->pucData = (unsigned char*)calloc(nSize, sizeof(unsigned char));
     if(NULL == pXGlyph->pucData)
     {
      FT_Done_Glyph(glyph);
      printf("FreeType2_GetFontChar->calloc unsigned char fail !\n");
      return FALSE;
     }
     memcpy((void*)pXGlyph->pucData, (void*)bm.buffer, nSize);
    }
    pXGlyph->nWid = bm.width;
    pXGlyph->nHei = bm.rows;
    pXGlyph->nLineStep = bm.pitch;    
    pXGlyph->nBearingx = face->glyph->metrics.horiBearingX / 64;
    pXGlyph->nBearingy = face->glyph->metrics.horiBearingY / 64;
    pXGlyph->nAdvance = face->glyph->metrics.horiAdvance / 64;
   }
  }
 }
 
 FT_Done_Glyph(glyph);
 return TRUE;
}
BOOL FreeType2_GetFontData(PFREETYPE2FONT pFont, char *pText)
{
 int i;
 int j;
 int n;
 int x;
 int y;
 int pen_x;
 int pen_y;
 int num_chars;
 int xmin;
 int xmax;
 int glyph_min_x = 0;
 FT_UInt previous;
 FT_UInt glyph_index;
 FT_UInt num_glyphs;
 FT_UInt glyph_advance_x;
 FT_BBox bbox;
 FT_Error Error;
 FT_Glyph glyph; 
 FT_Bool use_kerning; 
 FT_BBox glyph_bbox;
 FT_BitmapGlyph bit;
 
 unsigned short *unicode;
 char *pszTemp = NULL;
 FT_Vector *pos;
 FT_Vector *pens;
 PIMAGE pImage;
 if((NULL == pFont) || (NULL == pFont->face) || (NULL == pText) || '\0' == *pText)
  return FALSE;
 for(num_chars=0,pszTemp=pText; *pszTemp!='\0'; )
 {
  if(*pszTemp & 0x80)
   pszTemp += 2;
  else
   pszTemp++;
  num_chars++;
 }
 
 pos = (FT_Vector*)calloc(num_chars, sizeof(FT_Vector));
 if(NULL == pos)
 {
  printf("FreeType2_GetFontData->calloc FT_Vector pos fail !\n");
  return FALSE;
 }
 
 pens = (FT_Vector*)calloc(num_chars, sizeof(FT_Vector));
 if(NULL == pens)
 {
  free(pos);
  printf("FreeType2_GetFontData->calloc FT_Vector pens fail !\n");
  return FALSE;
 }
 
 pImage = (PIMAGE)calloc(num_chars, sizeof(IMAGE));
 if(NULL == pImage)
 {
  free(pos);
  free(pens);
  printf("FreeType2_GetFontData->calloc IMAGE fail !\n");
  return FALSE;
 }
 
 unicode = (unsigned short*)calloc(num_chars, sizeof(unsigned short));
 if(NULL == unicode)
 {
  free(pos);
  free(pens);
  free(pImage);
  printf("FreeType2_GetFontData->calloc unsigned short fail !\n");
  return FALSE;
 }
 for(i=0,pszTemp=pText; *pszTemp!='\0'; i++)
 {
  if(*pszTemp & 0x80)
  {
   unicode[i] = gb2312_0_conv_to_uc32(pszTemp);
   pszTemp += 2;
  }
  else
  {
   unicode[i] = s_font_utf8_to_unicode(pszTemp);
   pszTemp++;
  }
 }
 
 pen_x = 0;
 pen_y = 0;
 previous = 0;
 num_glyphs = 0;
 use_kerning = FT_HAS_KERNING(pFont->face);
 
 bbox.xMin = 32000;
 bbox.yMin = 32000;
 bbox.xMax = -32000;
 bbox.yMax = -32000;
 
 xmin = 3200;
 xmax = -3200;
 
 x = 0;
 y = 0;
 
 for(i=0; i {
  glyph_index = FT_Get_Char_Index(pFont->face, unicode[i]);
  if(!glyph_index)
   continue;
   
  if(use_kerning && previous && glyph_index)
  {
   FT_Vector delta;
   
   Error = FT_Get_Kerning(pFont->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
   if(Error)
    continue;
   
   pen_x += delta.x >> 6;
  }
  
  Error = FT_Load_Glyph(pFont->face, glyph_index, FT_LOAD_DEFAULT);
  if(Error)
   continue;
  
  Error = FT_Get_Glyph(pFont->face->glyph, &glyph);
  if(Error)
   continue;
  Error = FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
  if(Error)
   continue;
  
  FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_pixels, &glyph_bbox);
  glyph_min_x = FT_FLOOR(pFont->face->glyph->metrics.horiBearingX);
  glyph_advance_x = FT_CEIL(pFont->face->glyph->metrics.horiAdvance);
  pos[num_glyphs].x = pen_x;
  pos[num_glyphs].y = pen_y;
  pen_x += glyph_advance_x;
  
  glyph_bbox.xMin += pen_x;
  glyph_bbox.xMax += pen_x;
  glyph_bbox.yMin += pen_y;
  glyph_bbox.yMax += pen_y;
  
  if(glyph_bbox.xMin < bbox.xMin)
   bbox.xMin = glyph_bbox.xMin;
   
  if(glyph_bbox.yMin < bbox.yMin)
   bbox.yMin = glyph_bbox.yMin;
   
  if(glyph_bbox.xMax > bbox.xMax)
   bbox.xMax = glyph_bbox.xMax;
  
  if(glyph_bbox.yMax > bbox.yMax)
   bbox.yMax = glyph_bbox.yMax;
   
  bit = (FT_BitmapGlyph)glyph;
  
  pens[num_glyphs].x = pos[num_glyphs].x;
  pens[num_glyphs].y = pos[num_glyphs].y;
  
  x = pens[num_glyphs].x;
  xmin = MIN(xmin, x);
  xmax = MAX(xmax, x + bit->bitmap.width + glyph_min_x);
  pImage[num_glyphs].image = glyph;
  pImage[num_glyphs].min_x = glyph_min_x;
  pImage[num_glyphs].advance_x = glyph_advance_x;
  
  previous = glyph_index;
  num_glyphs++;
 }
 
 if(xmin > xmax)
 {
  xmin = 0;
  xmax = 0;
 }
 
 if(bbox.xMin > bbox.xMax)
 {
  bbox.xMin = 0;
  bbox.yMin = 0;
  bbox.xMax = 0;
  bbox.yMax = 0;
 }
 
 pFont->nWid = xmax - xmin;
 pFont->nHei = bbox.yMax - bbox.yMin;
 
 pFont->pucData = (unsigned char*)calloc(pFont->nWid*pFont->nHei, sizeof(unsigned char));
 if(NULL == pFont->pucData)
 {
  free(pos);
  free(pens);
  free(unicode);
  free(pImage);
  printf("FreeType2_GetFontData->calloc unsigned char fail !\n");
  return FALSE;  
 }
 
 for(n=0; n {
  unsigned char *start;
  unsigned char *end;
  unsigned char *pucBmp;
  unsigned char *pucBuf;
  
  bit = (FT_BitmapGlyph)pImage[n].image;
  
  x = pens[n].x + pImage[n].min_x;
  y = pens[n].y - bit->top + bbox.yMax;
  
  pucBuf = bit->bitmap.buffer;
  
  start = pFont->pucData;
  pucBmp = start + (x + y*pFont->nWid);
  end = start + pFont->nWid*pFont->nHei;
  
  for(i=0; ibitmap.rows; i++)
  {
   for(j=0; jbitmap.width; j++)
   {
    if(*pucBuf && (pucBmp >= start) && (pucBmp < end))
     *pucBmp = 1;
     
    pucBuf++;
    pucBmp++;
   }
   
   pucBuf += (bit->bitmap.pitch - bit->bitmap.width);
   pucBmp += (pFont->nWid - bit->bitmap.width);
  }
  
  FT_Done_Glyph(pImage[n].image);
 }
 
 free(pos);
 free(pens);
 free(unicode);
 free(pImage);
 
 return TRUE;
}
 
int FreeType2_GetHeigh(PFREETYPE2FONT pFont)
{
 if(NULL == pFont)
  return 0;
 return pFont->nHei;
}
阅读(3188) | 评论(1) | 转发(0) |
0

上一篇:点阵数据旋转

下一篇:小学奥赛

给主人留下些什么吧!~~

chinaunix网友2010-01-22 17:51:22

兄弟,这个代码不全呀,好多类型都没有。 例如:PFREETYPE2FONT、PIMAGE、PXGlyph等等。 你有完整的代码吗? 方便的话,发给我邮箱吧。 sijiu49@gmail.com 谢谢!