300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > linux调节字体大小加粗 支持任意大小字体freetype2显示(linux frambuffer)版

linux调节字体大小加粗 支持任意大小字体freetype2显示(linux frambuffer)版

时间:2019-07-22 08:07:05

相关推荐

linux调节字体大小加粗 支持任意大小字体freetype2显示(linux frambuffer)版

#include #include #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" },

{ "Arial","./arial.ttf" }

};

static FT_Vector pen;

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_SetCharSize(PFT2FONT pFont, int nWid, int nHei)

{

FT_Error nErr;

if(NULL == pFont)

return FALSE;

nErr = FT_Set_Pixel_Sizes(pFont->face, nWid, nHei);

if(nErr != FT_Err_Ok)

{

printf("FreeType_SetCharSize->FT_Set_Pixel_Sizes fail: %d\n", nErr);

return FALSE;

}

return TRUE;

}

BOOL FreeType2_InitFont(PFT2FONT pFont, char *pszName, int nFontWidth, int nFontHeight, BOOL bBold, BOOL bItalic, BOOL bUnderline)

{

BOOL bRet;

char *pszFontFile;

FT_Error nErr;

if((NULL == pFont) || (NULL == pszName) || ('\0' == *pszName) || (nFontWidth < 0) || (nFontHeight < 0))

return FALSE;

memset((void*)pFont, 0, sizeof(FT2FONT));

pszFontFile = GetFontFile(pszName);

if(NULL == pszFontFile)

return FALSE;

nErr = FT_Init_FreeType(&pFont->library);

if(nErr != FT_Err_Ok)

{

printf("FreeType2_InitFont->FT_InitFreeType fail: %d\n", nErr);

return FALSE;

}

nErr = FT_New_Face(pFont->library, pszFontFile, 0, &pFont->face);

if(nErr != FT_Err_Ok)

{

printf("FreeType2_InitFont->FT_New_Face fail: %d\n", nErr);

goto err1;

}

nErr = FT_Select_Charmap(pFont->face, ft_encoding_unicode);

if(nErr != FT_Err_Ok)

{

nErr = FT_Select_Charmap(pFont->face, ft_encoding_latin_1);

if(nErr != FT_Err_Ok)

{

printf("FreeType2_InitFont->FT_Select_Charmap error: %d\n", nErr);

goto err0;

}

}

nErr = FT_Set_Char_Size(pFont->face, 16 << 6, 16 << 6, 300, 300);

if(nErr != FT_Err_Ok)

{

printf("FreeType2_InitFont->FT_Set_Char_Size error: %d\n", nErr);

goto err0;

}

bRet = FreeType2_SetCharSize(pFont, nFontWidth, nFontHeight);

if(!bRet)

goto err0;

pFont->bBold = bBold;

pFont->bItalic = bItalic;

pFont->bUnderline = bUnderline;

pFont->nWid = nFontWidth;

pFont->nHei = nFontHeight;

return TRUE;

err0:

FT_Done_Face(pFont->face);

err1:

FT_Done_FreeType(pFont->library);

return FALSE;

}

BOOL FreeType2_ClearNode(PFT2FONT pFont)

{

PNODE pNode;

PNODE pPrevNode;

if(NULL == pFont)

return FALSE;

for(pNode=pFont->pHeadNode; pNode!=NULL; )

{

pPrevNode = pNode;

pNode = pNode->pNext;

if(pPrevNode->pucData != NULL)

free(pPrevNode->pucData);

free(pPrevNode);

}

return TRUE;

}

BOOL FreeType2_DestroyFont(PFT2FONT pFont)

{

if(NULL == pFont)

return FALSE;

FT_Done_Face(pFont->face);

FT_Done_FreeType(pFont->library);

FreeType2_ClearNode(pFont);

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;

}

// 就是FT_Outline_Embolden

FT_Error Old_FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength )

{

FT_Vector* points;

FT_Vector v_prev, v_first, v_next, v_cur;

FT_Angle rotate, angle_in, angle_out;

FT_Int c, n, first;

FT_Int orientation;

if ( !outline )

return FT_Err_Invalid_Argument;

strength /= 2;

if ( strength == 0 )

return FT_Err_Ok;

orientation = FT_Outline_Get_Orientation( outline );

if ( orientation == FT_ORIENTATION_NONE )

{

if ( outline->n_contours )

return FT_Err_Invalid_Argument;

else

return FT_Err_Ok;

}

if ( orientation == FT_ORIENTATION_TRUETYPE )

rotate = -FT_ANGLE_PI2;

else

rotate = FT_ANGLE_PI2;

points = outline->points;

first = 0;

for ( c = 0; c < outline->n_contours; c++ )

{

int last = outline->contours[c];

v_first = points[first];

v_prev = points[last];

v_cur = v_first;

for ( n = first; n <= last; n++ )

{

FT_Vector in, out;

FT_Angle angle_diff;

FT_Pos d;

FT_Fixed scale;

if ( n < last )

v_next = points[n + 1];

else

v_next = v_first;

/**//* compute the in and out vectors */

in.x = v_cur.x - v_prev.x;

in.y = v_cur.y - v_prev.y;

out.x = v_next.x - v_cur.x;

out.y = v_next.y - v_cur.y;

angle_in = FT_Atan2( in.x, in.y );

angle_out = FT_Atan2( out.x, out.y );

angle_diff = FT_Angle_Diff( angle_in, angle_out );

scale = FT_Cos( angle_diff / 2 );

if ( scale < 0x4000L && scale > -0x4000L )

in.x = in.y = 0;

else

{

d = FT_DivFix( strength, scale );

FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );

}

outline->points[n].x = v_cur.x + strength + in.x;

//伀偙傟傪僐儊儞僩傾僂僩偟偨偩偗

//outline->points[n].y = v_cur.y + strength + in.y;

v_prev = v_cur;

v_cur = v_next;

}

first = last + 1;

}

return FT_Err_Ok;

}

// 垂直加粗

FT_Error Vert_FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength )

{

FT_Vector* points;

FT_Vector v_prev, v_first, v_next, v_cur;

FT_Angle rotate, angle_in, angle_out;

FT_Int c, n, first;

FT_Int orientation;

if ( !outline )

return FT_Err_Invalid_Argument;

strength /= 2;

if ( strength == 0 )

return FT_Err_Ok;

orientation = FT_Outline_Get_Orientation( outline );

if ( orientation == FT_ORIENTATION_NONE )

{

if ( outline->n_contours )

return FT_Err_Invalid_Argument;

else

return FT_Err_Ok;

}

if ( orientation == FT_ORIENTATION_TRUETYPE )

rotate = -FT_ANGLE_PI2;

else

rotate = FT_ANGLE_PI2;

points = outline->points;

first = 0;

for ( c = 0; c < outline->n_contours; c++ )

{

int last = outline->contours[c];

v_first = points[first];

v_prev = points[last];

v_cur = v_first;

for ( n = first; n <= last; n++ )

{

FT_Vector in, out;

FT_Angle angle_diff;

FT_Pos d;

FT_Fixed scale;

if ( n < last )

v_next = points[n + 1];

else

v_next = v_first;

/**//* compute the in and out vectors */

in.x = v_cur.x - v_prev.x;

in.y = v_cur.y - v_prev.y;

out.x = v_next.x - v_cur.x;

out.y = v_next.y - v_cur.y;

angle_in = FT_Atan2( in.x, in.y );

angle_out = FT_Atan2( out.x, out.y );

angle_diff = FT_Angle_Diff( angle_in, angle_out );

scale = FT_Cos( angle_diff / 2 );

if ( scale < 0x4000L && scale > -0x4000L )

in.x = in.y = 0;

else

{

d = FT_DivFix( strength, scale );

FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );

}

//outline->points[n].x = v_cur.x + strength + in.x;

//仾偙傟傪僐儊儞僩傾僂僩偟偨偩偗

outline->points[n].y = v_cur.y + strength + in.y;

v_prev = v_cur;

v_cur = v_next;

}

first = last + 1;

}

return FT_Err_Ok;

}

// 新的加粗函数

FT_Error New_FT_Outline_Embolden( FT_Outline* outline, FT_Pos str_h, FT_Pos str_v )

{

if ( !outline ) return FT_Err_Invalid_Argument;

int orientation = FT_Outline_Get_Orientation( outline );

if ( orientation == FT_ORIENTATION_NONE )

if ( outline->n_contours ) return FT_Err_Invalid_Argument;

Vert_FT_Outline_Embolden( outline, str_v );

Old_FT_Outline_Embolden( outline, str_h );

return FT_Err_Ok;

}

// 让一个字体槽加粗,并且填充其他的大小属性

void New_GlyphSlot_Embolden( FT_GlyphSlot slot , FT_Pos x, FT_Pos y)

{

FT_Library library = slot->library;

FT_Face face = slot->face;

FT_Error error;

FT_Pos xstr = x, ystr = y;

if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&

slot->format != FT_GLYPH_FORMAT_BITMAP )

return;

if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )

{

FT_BBox oldBox;

FT_Outline_Get_CBox(&slot->outline , &oldBox);

error = New_FT_Outline_Embolden( &slot->outline, xstr , ystr);

if ( error )

return;

FT_BBox newBox;

FT_Outline_Get_CBox(&slot->outline , &newBox);

xstr = (newBox.xMax - newBox.xMin) - (oldBox.xMax - oldBox.xMin);

ystr = (newBox.yMax - newBox.yMin) - (oldBox.yMax - oldBox.yMin);

}

else if ( slot->format == FT_GLYPH_FORMAT_BITMAP )

{

xstr = FT_PIX_FLOOR( xstr );

if ( xstr == 0 )

xstr = 1 << 6;

ystr = FT_PIX_FLOOR( ystr );

error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );

if ( error )

return;

}

if ( slot->advance.x )

slot->advance.x += xstr;

if ( slot->advance.y )

slot->advance.y += ystr;

slot->metrics.width += xstr;

slot->metrics.height += ystr;

slot->metrics.horiBearingY += ystr;

slot->metrics.horiAdvance += xstr;

slot->metrics.vertBearingX -= xstr / 2;

slot->metrics.vertBearingY += ystr;

slot->metrics.vertAdvance += ystr;

if ( slot->format == FT_GLYPH_FORMAT_BITMAP )

slot->bitmap_top += ystr >> 6;

}

BOOL FreeType2_GetFontData(PFT2FONT pFont, char *pszText)

{

int i;

int x = 0;

int yPos;

int nSize;

int nLen;

int nStep;

unsigned short unicode;

FT_Error nErr;

FT_Matrix matrix;

FT_GlyphSlot slot;

PNODE pNode;

PNODE pTempNode;

if((NULL == pFont) || (NULL == pszText) || ('\0' == *pszText))

return FALSE;

slot = pFont->face->glyph;

nLen = strlen(pszText);

matrix.xx = 1 << 16;

matrix.xy = 0x5800;

matrix.yx = 0;

matrix.yy = 1 << 16;

FreeType2_ClearNode(pFont);

pFont->nRealWid = 0;

pFont->nRealHei = 0;

pFont->nTopBorder = 0;

pFont->nUnderlineY = 0;

pFont->nUnderlineWid = 0;

for(i=0; i{

if(pFont->bBold)//粗体

{

//FT_Pos strength = (1 << 6);

FT_Pos nx, ny;

nx = 3000000;

ny = 3000000;

New_GlyphSlot_Embolden(slot, nx, ny);

//FT_Outline_Embolden(&pFont->face->glyph->outline, strength);

}

if(pFont->bItalic)//斜体

FT_Set_Transform(pFont->face, &matrix, &pen);

if(*(pszText+i) & 0x80)//中文

{

unicode = gb2312_0_conv_to_uc32((const unsigned char*)(pszText+i));

i++;

}

else//ascii

unicode = s_font_utf8_to_unicode((const unsigned char*)(pszText+i));

nErr = FT_Load_Char(pFont->face, unicode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);

if(nErr != FT_Err_Ok)

continue;

if(pFont->bBold)

FT_GlyphSlot_Embolden(slot);

pNode = (PNODE)calloc(1, sizeof(NODE));

if(NULL == pNode)

{

printf("FreeType2_DrawText->calloc fail !\n");

return FALSE;

}

pNode->nWid = slot->bitmap.width;

pNode->nHei = slot->bitmap.rows;

pNode->nPitch = slot->bitmap.pitch;

pNode->nLeft = x + slot->bitmap_left;

pNode->nTop = slot->bitmap_top;

pNode->pNext = NULL;

pFont->nMode = slot->bitmap.pixel_mode;

nSize = pNode->nPitch * pNode->nHei;

pNode->pucData = (unsigned char*)calloc(nSize, sizeof(unsigned char));

if(NULL == pNode->pucData)

{

printf("FreeType2->DrawText->calloc fail !\n");

free(pNode);

return FALSE;

}

memcpy((void*)pNode->pucData, (void*)slot->bitmap.buffer, nSize*sizeof(char));

if(NULL == pFont->pHeadNode)

pFont->pHeadNode = pNode;

else

pTempNode->pNext = pNode;

pTempNode = pNode;

//FreeType2_DrawBitmap(hDC, &slot->bitmap,

//x+slot->bitmap_left, y-slot->bitmap_top);

x += slot->advance.x >> 6;

pFont->nRealHei = (pFont->nRealHei < slot->bitmap.rows) ? slot->bitmap.rows : pFont->nRealHei;

pFont->nTopBorder = (pFont->nTopBorder < slot->bitmap_top) ? slot->bitmap_top : pFont->nTopBorder;

yPos = slot->bitmap.rows - slot->bitmap_top;

if(pFont->nUnderlineY < yPos)

pFont->nUnderlineY = yPos;

}

pFont->nRealWid = x;

pFont->nUnderlineWid = x;

nStep = pFont->bBold ? 20 : 30;

pFont->nUnderlineHei = (pFont->nHei / nStep) + ((pFont->nHei % nStep) ? 1 : 0);

return TRUE;

}

BOOL FreeType2_DrawText(PFT2FONT pFont, HDC hDC, int x, int y, char *pszText)

{

int i, j;

int xPos;

int yPos;

unsigned char gray;

BOOL bRet;

PNODE pNode;

PNODE pPrevNode;

if((NULL == pFont) || (NULL == pszText) || ('\0' == *pszText))

return FALSE;

bRet = FreeType2_GetFontData(pFont, pszText);

if(bRet)

{

pNode = pFont->pHeadNode;

while(pNode != NULL)

{

pPrevNode = pNode;

xPos = x + pNode->nLeft;

yPos = y - pNode->nTop;

switch(pFont->nMode)

{

case FT_PIXEL_MODE_GRAY:

for(i=0; inHei; i++)

{

for(j=0; jnWid; j++)

{

gray = pNode->pucData[i*pNode->nPitch + j];

if(gray > 0)

SetPixel(hDC, xPos+j, yPos+i, RGB(0, 0, 0));

else

SetPixel(hDC, xPos+j, yPos+i, RGB(255, 255, 255));

}

}

break;

case FT_PIXEL_MODE_MONO:

for(i=0; inHei; i++)

{

for(j=0; jnWid; j++)

{

if(pNode->pucData[i*pNode->nPitch + j/8] & (0x80 >> (j & 7)))

SetPixel(hDC, xPos+j, yPos+i, RGB(0, 0, 0));

else

SetPixel(hDC, xPos+j, yPos+i, RGB(255, 255, 255));

}

}

break;

}

pNode = pNode->pNext;

if(pPrevNode->pucData)

free(pPrevNode->pucData);

free(pPrevNode);

}

pFont->pHeadNode = NULL;

if(pFont->bUnderline)

{

for(i=0; inUnderlineHei; i++)

{

for(j=0; jnUnderlineWid; j++)

SetPixel(hDC, x+j, y+pFont->nUnderlineY+1+i, RGB(0, 0, 0));

}

}

}

return FALSE;

}

BOOL DrawText(HDC hDC, LPSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)

{

int i, j;

int x, y;

int xPos;

int yPos;

BOOL bRet;

PFT2FONT pFont;

if((NULL == hDC) || (NULL == hDC->hFont) || (NULL == lpString) || ('\0' == lpString) || (NULL == lpRect))

{

printf("DrawText: param format error !\n");

return FALSE;

}

printf("DrawText begin....\n");

pFont = (PFT2FONT)hDC->hFont;

bRet = FreeType2_GetFontData(pFont, lpString);

if(bRet)

{

printf("pFont->nRealWid=%d, pFont->nRealHei=%d\n", pFont->nRealWid, pFont->nRealHei);

if((pFont->nRealWid > 0) && (pFont->nRealHei > 0))

{

int nDy;

unsigned char gray;

PNODE pNode;

PNODE pPrevNode;

x = lpRect->left;

y = lpRect->top;

switch(uFormat & 0xf0)

{

case DT_RIGHT:

x += lpRect->right - pFont->nRealWid;

break;

case DT_HCENTER:

x = (lpRect->left + lpRect->right - pFont->nRealWid) / 2;

break;

}

nDy = pFont->bUnderline ? (pFont->nUnderlineHei+1) : 0;

switch(uFormat & 0x0f)

{

case DT_VCENTER:

printf("nDy=%d, pFont->nTopBorder=%d, pFont->nRealHei=%d, %d, %d,\n",

nDy, pFont->nTopBorder, pFont->nRealHei, lpRect->top, lpRect->bottom);

y = (lpRect->top + lpRect->bottom - (pFont->nRealHei /*+ pFont->nTopBorder*/ + nDy)) / 2;

printf("y=%d\n", y);

break;

case DT_BOTTOM:

y += lpRect->bottom - (pFont->nRealHei + /*pFont->nTopBorder +*/ nDy);

break;

}

if(x <= lpRect->left)

x = lpRect->left;

if(y <= lpRect->top)

y = lpRect->top;

pNode = pFont->pHeadNode;

while(pNode != NULL)

{

pPrevNode = pNode;

xPos = x + pNode->nLeft;

yPos = y + pFont->nTopBorder - pNode->nTop;

printf("xPos=%d, yPos=%d, nHei=%d, nWid=%d\n", xPos, yPos, pNode->nHei, pNode->nWid);

switch(pFont->nMode)

{

case FT_PIXEL_MODE_GRAY:

for(i=0; inHei; i++)

{

for(j=0; jnWid; j++)

{

gray = pNode->pucData[i*pNode->nPitch + j];

if((gray > 0) && (xPos+j < lpRect->right) && (yPos+i < lpRect->bottom))

SetPixel(hDC, xPos+j, yPos+i, hDC->clrPen);

}

}

break;

case FT_PIXEL_MODE_MONO:

for(i=0; inHei; i++)

{

for(j=0; jnWid; j++)

{

if(pNode->pucData[i*pNode->nPitch + j/8] & (0x80 >> (j & 7)))

{

if((xPos+j < lpRect->right) && (yPos+i < lpRect->bottom))

SetPixel(hDC, xPos+j, yPos+i, hDC->clrPen);

}

}

}

break;

}

pNode = pNode->pNext;

if(pPrevNode->pucData)

free(pPrevNode->pucData);

free(pPrevNode);

}

pFont->pHeadNode = NULL;

if(pFont->bUnderline)

{

for(i=0; inUnderlineHei; i++)

{

for(j=0; jnUnderlineWid; j++)

{

if((x+j < lpRect->right) && (y+pFont->nUnderlineY+pFont->nTopBorder+1+i < lpRect->bottom))

SetPixel(hDC, x+j, y+pFont->nUnderlineY+pFont->nTopBorder+1+i, hDC->clrPen);

}

}

}

}

}

printf("DrawText end !\n");

return TRUE;

}

BOOL TextOut(HDC hDC, int x, int y, LPSTR lpString, int nLen)

{

int i, j;

int xPos;

int yPos;

BOOL bRet;

PFT2FONT pFont;

if((NULL == hDC) || (NULL == hDC->hFont) || (NULL == lpString) || ('\0' == lpString))

{

printf("TextOut: param format error !\n");

return FALSE;

}

printf("TextOut begin....\n");

pFont = (PFT2FONT)hDC->hFont;

bRet = FreeType2_GetFontData(pFont, lpString);

if(bRet)

{

printf("pFont->nRealWid=%d, pFont->nRealHei=%d\n", pFont->nRealWid, pFont->nRealHei);

if((pFont->nRealWid > 0) && (pFont->nRealHei > 0))

{

int nDy;

unsigned char gray;

PNODE pNode;

PNODE pPrevNode;

nDy = pFont->bUnderline ? (pFont->nUnderlineHei+1) : 0;

pNode = pFont->pHeadNode;

while(pNode != NULL)

{

pPrevNode = pNode;

xPos = x + pNode->nLeft;

yPos = y + pFont->nTopBorder - pNode->nTop;

printf("xPos=%d, yPos=%d, nHei=%d, nWid=%d\n", xPos, yPos, pNode->nHei, pNode->nWid);

switch(pFont->nMode)

{

case FT_PIXEL_MODE_GRAY:

for(i=0; inHei; i++)

{

for(j=0; jnWid; j++)

{

gray = pNode->pucData[i*pNode->nPitch + j];

if(gray > 0)

SetPixel(hDC, xPos+j, yPos+i, hDC->clrPen);

}

}

break;

case FT_PIXEL_MODE_MONO:

for(i=0; inHei; i++)

{

for(j=0; jnWid; j++)

{

if(pNode->pucData[i*pNode->nPitch + j/8] & (0x80 >> (j & 7)))

SetPixel(hDC, xPos+j, yPos+i, hDC->clrPen);

}

}

break;

}

pNode = pNode->pNext;

if(pPrevNode->pucData)

free(pPrevNode->pucData);

free(pPrevNode);

}

pFont->pHeadNode = NULL;

if(pFont->bUnderline)

{

for(i=0; inUnderlineHei; i++)

{

for(j=0; jnUnderlineWid; j++)

SetPixel(hDC, x+j, y+pFont->nUnderlineY+pFont->nTopBorder+1+i, hDC->clrPen);

}

}

}

}

printf("TextOut end !\n");

return TRUE;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。