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

全部博文(14)

文章存档

2012年(1)

2011年(2)

2010年(3)

2009年(8)

我的朋友

分类: 嵌入式

2009-09-08 12:52:11

#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;
 printf("%s, %s\n", pszName, pszFontFile);
 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->nCount = 0;
 return TRUE;
}
BOOL FreeType2_DestroyFont(PFREETYPE2FONT pFont)
{
 int i;
 
 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;
 for(i=0; inCount; i++)
 {
  if(pFont->lpclrData[i] != NULL)
   free(pFont->lpclrData[i]);
   
  pFont->lpclrData[i] = 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_GetFontData(PFREETYPE2FONT pFont, char *pText, COLORREF clr, COLORREF clrBk)
{
 int n;
 int nSize;
 int nWid = 64;
 int nHei = 64;
 int num_chars;
 int pen_x;
 int pen_y;
 int nWidth;
 int nHeigh;
 char *pTemp = NULL;
 unsigned short *unicode = NULL;
 float fAngle = 0;
 FT_Error Error;
 FT_GlyphSlot slot;
 FT_UInt num_glyphs;
 FT_Bool use_kerning;
 FT_UInt previous;
 TGlyph glyphs[UNICODE_MAX+1];
 PGlyph pglyph;
 FT_BBox bbox;
 FT_Vector start;
 FT_Matrix matrix;
 if((NULL == pFont) || (NULL == pFont->face) || (NULL == pText) || '\0' == *pText)
  return FALSE;
 fAngle = -pFont->nEscapement/180. * 3.14;
 for(num_chars=0,pTemp=pText; *pTemp!='\0'; )
 {
  if(*pTemp & 0x80)
   pTemp += 2;
  else
   pTemp++;
  num_chars++;
 }
 
 if(num_chars > UNICODE_MAX)
  num_chars = UNICODE_MAX;
 pen_x = 0;
 pen_y = 0;
 num_glyphs = 0;
 previous = 0;
 slot = pFont->face->glyph;
 use_kerning = FT_HAS_KERNING(pFont->face);
 unicode = (unsigned short*)malloc(sizeof(unsigned short*)*(num_chars + 1));
 if(NULL == unicode)
  return FALSE;
 for(n=0,pTemp=pText; *pTemp!='\0'; n++)
 {
  if(*pTemp & 0x80)
  {
   pFont->nFlags[n] = FONT_CHINA;
   unicode[n] = gb2312_0_conv_to_uc32(pTemp);
   pTemp += 2;
  }
  else
  {
   pFont->nFlags[n] = FONT_ASCII;
   unicode[n] = s_font_utf8_to_unicode(pTemp);
   pTemp++;
  }
 }
 
 num_chars = n;
 pglyph = glyphs;
 for(n=0; n {
  pglyph->index = FT_Get_Char_Index(pFont->face, unicode[n]);
  if(use_kerning && previous && pglyph->index)
  {
   FT_Vector delta;
   FT_Get_Kerning(pFont->face, previous, pglyph->index, FT_KERNING_DEFAULT, &delta);
   pen_x += delta.x >> 6; //pen_x += delta.x & (~63);
  }
  Error = FT_Load_Glyph(pFont->face, pglyph->index, FT_LOAD_DEFAULT);
  if(Error)
   continue;
  Error = FT_Get_Glyph(pFont->face->glyph, &pglyph->image);
  if(Error)
   continue;
  pen_x += slot->advance.x >> 6;
  previous = pglyph->index;
  pglyph++;
 }
 
 num_glyphs = pglyph - glyphs;
 pFont->nCount = num_glyphs;
 bbox.xMin = bbox.yMin =  32000;
 bbox.xMax = bbox.yMax = -32000;
 for(n=0; n {
  FT_BBox glyph_bbox;
  FT_Glyph_Get_CBox(glyphs[n].image, ft_glyph_bbox_pixels, &glyph_bbox);
  bbox.xMin = (glyph_bbox.xMin < bbox.xMin) ? glyph_bbox.xMin : bbox.xMin;
  bbox.yMin = (glyph_bbox.yMin < bbox.yMin) ? glyph_bbox.yMin : bbox.yMin;
  bbox.xMax = (glyph_bbox.xMax > bbox.xMax) ? glyph_bbox.xMax : bbox.xMax;
  bbox.yMax = (glyph_bbox.yMax > bbox.yMax) ? glyph_bbox.yMax : bbox.yMax;
 }
 if(bbox.xMin > bbox.xMax)
 {
  bbox.xMin = 0;
  bbox.yMin = 0;
  bbox.xMax = 0;
  bbox.yMax = 0;
 }
 nWidth = (bbox.xMax - bbox.xMin) / 64;
 nHeigh = (bbox.yMax - bbox.yMin) / 64;
 start.x = 64*(nWid - nWidth) / 2;
 start.y = 64*(nHei - nHeigh) / 2;
 matrix.xx = (FT_Fixed)( cos(fAngle) * 0x10000L);
 matrix.xy = (FT_Fixed)(-sin(fAngle) * 0x10000L);
 matrix.yx = (FT_Fixed)( sin(fAngle) * 0x10000L);
 matrix.yy = (FT_Fixed)( cos(fAngle) * 0x10000L);
 pFont->nWid = 0;
 pFont->nHei = 0;
 
 for(n=0; n {
  FT_Glyph image;
  Error = FT_Glyph_Copy(glyphs[n].image, &image);
  if(Error)
   continue;
  FT_Glyph_Transform(image, &matrix, &start);
  Error = FT_Glyph_To_Bitmap(&image, FT_RENDER_MODE_NORMAL, 0, 1);
  if(FT_Err_Ok == Error)
  {
   int i, j;
   unsigned char *pBuf = NULL;
   FT_BitmapGlyph bit = (FT_BitmapGlyph)image;
   pFont->nWids[n] = bit->bitmap.width;
   pFont->nHeis[n] = bit->bitmap.rows;
   
   pFont->nWid = (bit->bitmap.width > pFont->nWid) ? bit->bitmap.width : pFont->nWid;
   pFont->nHei = (bit->bitmap.rows  > pFont->nHei) ? bit->bitmap.rows  : pFont->nHei;
   
   nSize = bit->bitmap.width * bit->bitmap.rows;
   
   pFont->lpclrData[n] = (LPCOLORREF)malloc(sizeof(COLORREF)*nSize);
   if(NULL == pFont->lpclrData[n])
   {
    FT_Done_Glyph(image);
    continue;
   }
   
   pBuf = bit->bitmap.buffer;
   for(i=0; ibitmap.rows; i++)
   {
    for(j=0; jbitmap.width; j++)
    {
     if(*pBuf)
      *(pFont->lpclrData[n] + i*bit->bitmap.width + j) = clr;
     else
      *(pFont->lpclrData[n] + i*bit->bitmap.width + j) = clrBk;
     pBuf++;
    }
    
    pBuf += (bit->bitmap.pitch - bit->bitmap.width);
   }
   FT_Done_Glyph(image);
  }
 }
 
 free(unicode);
 return TRUE;
}
int FreeType2_GetWidth(PFREETYPE2FONT pFont)
{
 int i;
 int nWid;
 if(NULL == pFont)
  return 0;
 nWid = -pFont->nSpace;
 for(i=0; inCount; i++)
 {
  if(FONT_ASCII == pFont->nFlags[i])
   nWid += pFont->nWid - pFont->nWids[i];
  else
   nWid += pFont->pFont->nWid;
  nWid += pFont->nSpace;
 }
 return nWid;
}
int FreeType2_GetHeigh(PFREETYPE2FONT pFont)
{
 if(NULL == pFont)
  return 0;
 return pFont->nHei;
}
阅读(1344) | 评论(0) | 转发(0) |
0

上一篇:freetype2数据提取

下一篇:点阵数据旋转

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