freetype初始化如下:
if (mFTFace == 0 )
{
if (FT_Init_FreeType( &mFTLibrary ))
return;
if (FT_New_Face( mFTLibrary, "/system/fonts/DroidSansFallback.ttf", 0, &mFTFace ))
return;
FT_Select_Charmap(mFTFace, FT_ENCODING_UNICODE);
//FT_Set_Pixel_Sizes(mFTFace,0, 12);
InitFontBuffer();
}
if (m_nFontStyle & XF_UPDATE)
{
m_nFontStyle &= ~XF_UPDATE;
m_nTextHeight = (m_nFontStyle & 0x0000ff00) >>8;
m_nTextHeight += 13;
//LOGWHEREVAL( m_nTextHeight );
FT_Set_Pixel_Sizes(mFTFace,0,m_nTextHeight);
}
字体绘制如下:pText是宽字节字符串,x,y是绘制的位置,nLength是字符串的长度
void FTDrawString(XPCWSTR pText,XINT x,XINT y,XINT nLength )
{LOGWHEREGRAPHICS();
FT_UInt glyph_index;
int pen_x = 0, pen_y = 0;
pen_x = x;
pen_y = y + m_nTextHeight * 2/3 + 2;
FT_Error error;
XU32 rgb = m_nTextColor & 0xFFFFFF00;
XU32 src_r = (m_nTextColor & 0xff000000) >> 24;
XU32 src_g = (m_nTextColor & 0x00ff0000) >> 16;
XU32 src_b = (m_nTextColor & 0x0000ff00) >> 8;
XU32 src_a = (m_nTextColor & 0x000000ff);
gdx2d_pixmap* pImg = m_pBitmap->GetImage();
//gdx2d_set_blend(1);
for(int i = 0; i < nLength; i++)
{
int pos = FindFontIndex( pText[i] );
if( pos == -1 )
{
FT_GlyphSlot slot = mFTFace->glyph;
FT_Error error = FT_Load_Char( mFTFace, pText[i], FT_LOAD_DEFAULT);
//if(m_nFontStyle & XF_BOLD)
//{
// int strength = 1 << 6;
// FT_Outline_Embolden(&(mFTFace->glyph->outline), 1 << 6);
//}
error = FT_Render_Glyph(mFTFace->glyph, FT_RENDER_MODE_NORMAL);
int delpos = DeleteOneFont();
FT_Bitmap_Done( mFTLibrary, gFonts[delpos].bitmap );
pos = InsertFont( pText[i], delpos );
FT_Bitmap_Copy( mFTLibrary, &mFTFace->glyph->bitmap, gFonts[pos].bitmap );
gFonts[pos].index = pText[i];
gFonts[pos].left = mFTFace->glyph->bitmap_left;
gFonts[pos].top = mFTFace->glyph->bitmap_top;
gFonts[pos].width = slot->advance.x >> 6;
gFonts[pos].fontStyle = m_nFontStyle;
}
else if( (m_nFontStyle & 0x0000ff00) != (gFonts[pos].fontStyle & 0x0000ff00 ) )
{
FT_GlyphSlot slot = mFTFace->glyph;
FT_Error error = FT_Load_Char( mFTFace, pText[i], FT_LOAD_DEFAULT);
//if(m_nFontStyle & XF_BOLD)
//{
// int strength = 1 << 6;
// FT_Outline_Embolden(&(mFTFace->glyph->outline), 1 << 6);
//}
error = FT_Render_Glyph(mFTFace->glyph, FT_RENDER_MODE_NORMAL);
FT_Bitmap_Done( mFTLibrary, gFonts[pos].bitmap );
FT_Bitmap_Copy( mFTLibrary, &mFTFace->glyph->bitmap, gFonts[pos].bitmap );
gFonts[pos].index = pText[i];
gFonts[pos].left = mFTFace->glyph->bitmap_left;
gFonts[pos].top = mFTFace->glyph->bitmap_top;
gFonts[pos].width = slot->advance.x >> 6;
gFonts[pos].fontStyle = m_nFontStyle;
}
// else if( (m_nFontStyle & XF_BOLD) && !(gFonts[pos].fontStyle & XF_BOLD) )
// {
// FT_GlyphSlot slot = mFTFace->glyph;
// FT_Error error = FT_Load_Char( mFTFace, pText[i], FT_LOAD_DEFAULT);
// //int strength = 1 << 6;
// //FT_Outline_Embolden(&(mFTFace->glyph->outline), 1 << 6);
// error = FT_Render_Glyph(mFTFace->glyph, FT_RENDER_MODE_NORMAL);
// FT_Bitmap_Done( mFTLibrary, gFonts[pos].bitmap );
// FT_Bitmap_Copy( mFTLibrary, &mFTFace->glyph->bitmap, gFonts[pos].bitmap );
//
// gFonts[pos].index = pText[i];
// gFonts[pos].left = mFTFace->glyph->bitmap_left;
// gFonts[pos].top = mFTFace->glyph->bitmap_top;
// gFonts[pos].width = slot->advance.x >> 6;
// gFonts[pos].fontStyle = m_nFontStyle;
// }
// else if( !(m_nFontStyle & XF_BOLD) && (gFonts[pos].fontStyle & XF_BOLD) )
// {
// FT_GlyphSlot slot = mFTFace->glyph;
// FT_Error error = FT_Load_Char( mFTFace, pText[i], FT_LOAD_DEFAULT);
// error = FT_Render_Glyph(mFTFace->glyph, FT_RENDER_MODE_NORMAL);
// FT_Bitmap_Done( mFTLibrary, gFonts[pos].bitmap );
// FT_Bitmap_Copy( mFTLibrary, &mFTFace->glyph->bitmap, gFonts[pos].bitmap );
//
// gFonts[pos].index = pText[i];
// gFonts[pos].left = mFTFace->glyph->bitmap_left;
// gFonts[pos].top = mFTFace->glyph->bitmap_top;
// gFonts[pos].width = slot->advance.x >> 6;
// gFonts[pos].fontStyle = m_nFontStyle;
// }
gFonts[pos].usecount++;
//LOGWHEREVAL( pos );
FT_Bitmap *bitmap = gFonts[pos].bitmap;
int width = bitmap->width;
int height = bitmap->rows;
int posx = pen_x + gFonts[pos].left;
int posy = pen_y - gFonts[pos].top;
//LOGE("m_clip->left: %d, right: %d, top: %d, bottom: %d", m_clip.left, m_clip.right, m_clip.top, m_clip.bottom );
if( posy < 0 )
{
height = height + posy;
unsigned char * psrc = bitmap->buffer - posy * width;
unsigned char * pdst = pImg->pixels + ( posx << 2 );
for(int j=0; j < height; j++)
{
unsigned char *pixel = pdst;
pdst += (pImg->width << 2);
for(int i=0; i < width; i++)
{
if( posx + i >= m_clip.right )
{
psrc += (width - i);
break;
}
if( posx + i < m_clip.left )
{
psrc++;
pixel += 4;
continue;
}
if( *psrc )
{
src_a = (*psrc);
XU32 dst_r = pixel[0];
XU32 dst_g = pixel[1];
XU32 dst_b = pixel[2];
//XU32 dst_a = pixel[3];
dst_r = dst_r + (src_a * (src_r - dst_r) >> 8 );
dst_g = dst_g + (src_a * (src_g - dst_g) >> 8 );
dst_b = dst_b + (src_a * (src_b - dst_b) >> 8 );
//dst_a = (int32_t)((1.0f - (1.0f - src_a / 255.0f) * (1.0f - dst_a / 255.0f)) * 255);
pixel[0] = dst_r & 0xFF;
pixel[1] = dst_g & 0xFF;
pixel[2] = dst_b & 0xFF;
//pixel[3] = src_a & 0xFF;
}
psrc++;
pixel += 4;
} // end of width
} // end of height
} // end of if
else if( m_clip.top > 0 && posy < m_clip.top )
{
height = height - ( m_clip.top -posy);
unsigned char * psrc = bitmap->buffer + (m_clip.top -posy) * width;
unsigned char * pdst = pImg->pixels + ((posx + m_clip.top * pImg->width) << 2);
for(int j=0; j < height; j++)
{
if( posy + j >= m_clip.bottom )
{
break;
}
unsigned char *pixel = pdst;
pdst += (pImg->width << 2);
for(int i=0; i < width; i++)
{
if( posx + i >= m_clip.right )
{
psrc += (width - i);
break;
}
if( posx + i < m_clip.left )
{
psrc++;
pixel += 4;
continue;
}
if( *psrc )
{
src_a = (*psrc);
XU32 dst_r = pixel[0];
XU32 dst_g = pixel[1];
XU32 dst_b = pixel[2];
//XU32 dst_a = pixel[3];
dst_r = dst_r + (src_a * (src_r - dst_r) >> 8 );
dst_g = dst_g + (src_a * (src_g - dst_g) >> 8 );
dst_b = dst_b + (src_a * (src_b - dst_b) >> 8 );
//dst_a = (int32_t)((1.0f - (1.0f - src_a / 255.0f) * (1.0f - dst_a / 255.0f)) * 255);
pixel[0] = dst_r & 0xFF;
pixel[1] = dst_g & 0xFF;
pixel[2] = dst_b & 0xFF;
//pixel[3] = src_a & 0xFF;
}
psrc++;
pixel += 4;
} // end of width
} // end of height
} // end of if
else
{
unsigned char * psrc = bitmap->buffer;
unsigned char * pdst = pImg->pixels + ((posx + posy * pImg->width) << 2);
for(int j=0; j < height; j++)
{
if( posy + j >= m_clip.bottom )
{
break;
}
unsigned char *pixel = pdst;
pdst += (pImg->width << 2);
for(int i=0; i < width; i++)
{
if( posx + i >= m_clip.right )
{
psrc += (width - i);
break;
}
if( posx + i < m_clip.left )
{
psrc++;
pixel += 4;
continue;
}
if( *psrc )
{
src_a = (*psrc);
XU32 dst_r = pixel[0];
XU32 dst_g = pixel[1];
XU32 dst_b = pixel[2];
dst_r = dst_r + (src_a * (src_r - dst_r) >> 8 );
dst_g = dst_g + (src_a * (src_g - dst_g) >> 8 );
dst_b = dst_b + (src_a * (src_b - dst_b) >> 8 );
//dst_a = (int32_t)((1.0f - (1.0f - src_a / 255.0f) * (1.0f - dst_a / 255.0f)) * 255);
pixel[0] = dst_r & 0xFF;
pixel[1] = dst_g & 0xFF;
pixel[2] = dst_b & 0xFF;
}
psrc++;
pixel += 4;
}
}
} // end of else
pen_x += gFonts[pos].width;
}
// // underline
if (m_nFontStyle & XF_UNDERLINE)
{
int iUnderlinePos = 0;
if( FT_IS_SCALABLE(mFTFace) )
{
iUnderlinePos = FT_MulFix( mFTFace->underline_position , mFTFace->size->metrics.y_scale);
iUnderlinePos >>= 6;
}
gdx2d_draw_line( m_pBitmap->GetImage(), x, pen_y - iUnderlinePos, pen_x, pen_y - iUnderlinePos, m_nTextColor );
}
//gdx2d_set_blend(0);
//LOGWHERE();
return;
}