414 lines
12 KiB
C
414 lines
12 KiB
C
|
|
#include <InsCfg.h>
|
|||
|
|
#include <lib/InsFont.h>
|
|||
|
|
|
|||
|
|
#include <ft2build.h>
|
|||
|
|
#include <freetype/freetype.h>
|
|||
|
|
#include <freetype/ftglyph.h>
|
|||
|
|
|
|||
|
|
#define DBG_LEVEL DBG_INFO
|
|||
|
|
#define DBG_TAG "LibFont"
|
|||
|
|
#include <InsDbg.h>
|
|||
|
|
|
|||
|
|
static FT_Library mFtLib = NULL;
|
|||
|
|
static FT_Face mFtFace[MAX_FT_FACE_NUM];
|
|||
|
|
static Int32 mFtFaceIdCnt = 0;
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ftLib,
|
|||
|
|
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ins_TRUE, libIDs<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>ų<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>ftLib ID
|
|||
|
|
ʧ<EFBFBD>ܻ<EFBFBD><EFBFBD>߲<EFBFBD><EFBFBD>ֳɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ins_FALSE, libIDs<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><EFBFBD>ܻᱻ<EFBFBD><EFBFBD>ֵΪINS_INVALID_RES_ID
|
|||
|
|
*/
|
|||
|
|
Bool InitFtLibs
|
|||
|
|
(
|
|||
|
|
const char *ftFiles[], /*[in] <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
|||
|
|
Int32 *libIDs, /*[out] ftLib id<69><64><EFBFBD><EFBFBD>, <20><>0<EFBFBD><30>ʼ[0,n]*/
|
|||
|
|
Int32 num /*[in] <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>, ftLib<69><62><EFBFBD><EFBFBD>*/
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
Int32 i;
|
|||
|
|
Bool retv = INS_TRUE;
|
|||
|
|
|
|||
|
|
if(mFtLib == NULL && FT_Init_FreeType(&mFtLib) != 0)
|
|||
|
|
{
|
|||
|
|
for(i = 0; i < num; i++)libIDs[i] = INS_INVALID_RES_ID;
|
|||
|
|
printf("FT_Init_FreeType fail\n");
|
|||
|
|
return INS_FALSE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for(i = 0; i < num && i < MAX_FT_FACE_NUM; i++)
|
|||
|
|
{
|
|||
|
|
if(FT_New_Face(mFtLib, ftFiles[i], 0, &mFtFace[mFtFaceIdCnt]) != 0)
|
|||
|
|
{
|
|||
|
|
mFtFace[mFtFaceIdCnt] = NULL;
|
|||
|
|
retv = INS_FALSE;
|
|||
|
|
libIDs[i] = INS_INVALID_RES_ID;
|
|||
|
|
printf("FT_New_Face %s fail\n", ftFiles[i]);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
libIDs[i] = mFtFaceIdCnt;
|
|||
|
|
mFtFaceIdCnt++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for(; i < num; i++) /*(num >= MAX_FT_FACE_NUM)out of range?*/
|
|||
|
|
{
|
|||
|
|
retv = INS_FALSE;
|
|||
|
|
libIDs[i] = INS_INVALID_RES_ID;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return retv;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*<2A>ͷ<EFBFBD>ftLibռ<62>õ<EFBFBD><C3B5><EFBFBD>Դ*/
|
|||
|
|
void DeInitFtLibs
|
|||
|
|
(
|
|||
|
|
Int32 *libIDs, /*[in] <20><>Ҫ<EFBFBD>ͷŵ<CDB7>ftLib ID<49><44><EFBFBD><EFBFBD>*/
|
|||
|
|
Int32 num /*[in]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С*/
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
if(mFtLib == NULL)return;
|
|||
|
|
|
|||
|
|
int i;
|
|||
|
|
|
|||
|
|
for(i = 0; i < MAX_FT_FACE_NUM; i++)
|
|||
|
|
{
|
|||
|
|
if(mFtFace[i] != NULL)
|
|||
|
|
{
|
|||
|
|
FT_Done_Face(mFtFace[i]);
|
|||
|
|
mFtFace[i] = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
FT_Done_FreeType(mFtLib);
|
|||
|
|
mFtLib = NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ftLib ID<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
|||
|
|
*/
|
|||
|
|
Bool GenFontBmps
|
|||
|
|
(
|
|||
|
|
Int32 libID, /*[in] ftLib ID*/
|
|||
|
|
Int32 charSize, /*[in] <20><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD>1.5<EFBFBD><EFBFBD>)*/
|
|||
|
|
Int32 texWidth, /*[in] <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>(=2^n)*/
|
|||
|
|
Int32 codeNum, /*[in] <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С*/
|
|||
|
|
const UInt32 *ucsCode, /*[in] <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
|||
|
|
Int32 *texHigh, /*[out] <20><><EFBFBD><EFBFBD>ͼ<EFBFBD>а<EFBFBD><D0B0><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>ظ߶<D8B8>*/
|
|||
|
|
UInt08 **pixelBuff, /*[out] <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>(<28>Ҷ<EFBFBD>/Alpha)<29><><EFBFBD><EFBFBD>(һ<><D2BB><EFBFBD>ֽڶ<D6BD>Ӧһ<D3A6><D2BB><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>Alphaֵ), <20>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>texWidth x texHigh */
|
|||
|
|
Flt32 **widthRate, /*[out] <20><><EFBFBD><EFBFBD>ʵ<EFBFBD>ʿ<EFBFBD><CABF>ȱ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>(ʵ<>ʿ<EFBFBD><CABF><EFBFBD>/charSize)*/
|
|||
|
|
Flt32 **texcoord, /*[out] <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>OpenGL<47><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>Ͻǡ<CFBD><C7A1><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)*/
|
|||
|
|
Bool tight /*[in] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Ins_FALSE<53><45><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռcharSize<7A><65><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>"<22><><EFBFBD><EFBFBD>"*/
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
Int32 x, y, n, column, row;
|
|||
|
|
Int32 texX0, texY0;
|
|||
|
|
UInt08 *tmpBuff;
|
|||
|
|
|
|||
|
|
if(charSize > texWidth
|
|||
|
|
|| pixelBuff == NULL
|
|||
|
|
|| texHigh == NULL
|
|||
|
|
|| codeNum < 1
|
|||
|
|
|| libID >= mFtFaceIdCnt
|
|||
|
|
|| libID < 0)
|
|||
|
|
{
|
|||
|
|
return INS_FALSE;
|
|||
|
|
}
|
|||
|
|
FT_Set_Pixel_Sizes(mFtFace[libID], charSize, charSize);
|
|||
|
|
texX0 = 0;
|
|||
|
|
texY0 = 0;
|
|||
|
|
column = texWidth/charSize; /*glyph_num per line */
|
|||
|
|
row = (codeNum+column-1)/column; /*line count*/
|
|||
|
|
tmpBuff = (UInt08*)malloc(row*3*charSize/2*texWidth); /*glyph high is [3 x charSize / 2]*/
|
|||
|
|
if(widthRate != NULL)widthRate[0] = (Flt32*)malloc(codeNum*sizeof(Flt32));
|
|||
|
|
if(texcoord != NULL)texcoord[0] = (Flt32*)malloc(codeNum*4*sizeof(Flt32));
|
|||
|
|
memset(tmpBuff, 0, row*3*charSize/2*texWidth);
|
|||
|
|
for(n = 0; n < codeNum; n++)
|
|||
|
|
{
|
|||
|
|
FT_Glyph glyph;
|
|||
|
|
UInt08 *bmpBuff;
|
|||
|
|
Int32 left, top, innx, inny, w, h;
|
|||
|
|
|
|||
|
|
FT_Load_Glyph(mFtFace[libID], FT_Get_Char_Index(mFtFace[libID], ucsCode[n]), FT_LOAD_DEFAULT);
|
|||
|
|
if(FT_Get_Glyph(mFtFace[libID]->glyph, &glyph) != 0)
|
|||
|
|
{
|
|||
|
|
if(texcoord != NULL)
|
|||
|
|
{
|
|||
|
|
texcoord[0][4*n+0] = 0.0f;
|
|||
|
|
texcoord[0][4*n+1] = 0.0f;
|
|||
|
|
texcoord[0][4*n+2] = 0.0f;
|
|||
|
|
texcoord[0][4*n+3] = 0.0f;
|
|||
|
|
}
|
|||
|
|
if(widthRate != NULL)widthRate[0][n] = 0.0f;
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
|||
|
|
{
|
|||
|
|
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
|
|||
|
|
}
|
|||
|
|
FT_BitmapGlyph bmpGlyph = (FT_BitmapGlyph)glyph;
|
|||
|
|
|
|||
|
|
w = bmpGlyph->bitmap.width;
|
|||
|
|
h = bmpGlyph->bitmap.rows;
|
|||
|
|
left = bmpGlyph->left;
|
|||
|
|
top = bmpGlyph->top;
|
|||
|
|
if(top > charSize)
|
|||
|
|
top = charSize;
|
|||
|
|
|
|||
|
|
bmpBuff = bmpGlyph->bitmap.buffer;
|
|||
|
|
if(w == 0) /*space*/
|
|||
|
|
{
|
|||
|
|
w = charSize/2;
|
|||
|
|
h = 0;
|
|||
|
|
left = 0;
|
|||
|
|
top = 0;
|
|||
|
|
bmpBuff = NULL;
|
|||
|
|
}
|
|||
|
|
if(tight)
|
|||
|
|
{
|
|||
|
|
if(widthRate != NULL)widthRate[0][n] = 1.0f*w/charSize;
|
|||
|
|
if(texX0 + w > texWidth)
|
|||
|
|
{
|
|||
|
|
texX0 = 0;
|
|||
|
|
texY0 += 3*charSize/2;
|
|||
|
|
}
|
|||
|
|
x = texX0;
|
|||
|
|
y = texY0 + charSize - top;
|
|||
|
|
if(texcoord != NULL)
|
|||
|
|
{
|
|||
|
|
texcoord[0][4*n+0] = 1.0f*texX0/texWidth;
|
|||
|
|
texcoord[0][4*n+1] = texY0;
|
|||
|
|
texcoord[0][4*n+2] = 1.0f*(texX0+w)/texWidth;
|
|||
|
|
texcoord[0][4*n+3] = texY0+3.0f*charSize/2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if(widthRate != NULL)widthRate[0][n] = 1.0f;
|
|||
|
|
if(texX0 + charSize > texWidth)
|
|||
|
|
{
|
|||
|
|
texX0 = 0;
|
|||
|
|
texY0 += 3*charSize/2;
|
|||
|
|
}
|
|||
|
|
x = texX0 + left;
|
|||
|
|
y = texY0 + charSize - top;
|
|||
|
|
if(texcoord != NULL)
|
|||
|
|
{
|
|||
|
|
texcoord[0][4*n+0] = 1.0f*texX0/texWidth;
|
|||
|
|
texcoord[0][4*n+1] = texY0;
|
|||
|
|
texcoord[0][4*n+2] = 1.0f*(texX0+charSize)/texWidth;
|
|||
|
|
texcoord[0][4*n+3] = texY0+3.0f*charSize/2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for(inny = 0; inny < h; inny++)
|
|||
|
|
{
|
|||
|
|
for(innx = 0; innx < w; innx++)
|
|||
|
|
{
|
|||
|
|
tmpBuff[(y+inny)*texWidth + x + innx] = bmpBuff[inny*w+innx];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(tight)
|
|||
|
|
{
|
|||
|
|
texX0 += w+2;/* +2 to make a gap between glyphs*/
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
texX0 += charSize;
|
|||
|
|
}
|
|||
|
|
//printf("texX0:%d\n", texX0);
|
|||
|
|
FT_Done_Glyph(glyph);
|
|||
|
|
}
|
|||
|
|
pixelBuff[0] = tmpBuff;
|
|||
|
|
*texHigh = texY0 + 3.0f*charSize/2;
|
|||
|
|
if(texcoord != NULL)for(n = 0; n < codeNum; n++)
|
|||
|
|
{
|
|||
|
|
texcoord[0][4*n+1] = *texHigh - texcoord[0][4*n+1];
|
|||
|
|
texcoord[0][4*n+3] = *texHigh - texcoord[0][4*n+3];
|
|||
|
|
texcoord[0][4*n+1] /= *texHigh;
|
|||
|
|
texcoord[0][4*n+3] /= *texHigh;
|
|||
|
|
//printf("(%f, %f), (%f, %f)\n", texcoord[0][4*n+0], texcoord[0][4*n+1], texcoord[0][4*n+2], texcoord[0][4*n+3]);
|
|||
|
|
}
|
|||
|
|
/*
|
|||
|
|
if(widthRate != NULL)for(n = 0; n < codeNum; n++)
|
|||
|
|
{
|
|||
|
|
printf("%f\n", widthRate[0][n]);
|
|||
|
|
}
|
|||
|
|
for(y = 0; y < 0; y++)// *texHigh; y++)
|
|||
|
|
{
|
|||
|
|
for(x = 0; x < texWidth; x++)
|
|||
|
|
{
|
|||
|
|
if(pixelBuff[0][y*texWidth+x] < 10)printf("00%d ", pixelBuff[0][y*texWidth+x]);
|
|||
|
|
else if(pixelBuff[0][y*texWidth+x] < 100)printf("0%d ", pixelBuff[0][y*texWidth+x]);
|
|||
|
|
else printf("%d ", pixelBuff[0][y*texWidth+x]);
|
|||
|
|
}
|
|||
|
|
printf("\n");
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
for(y = 0; y < *texHigh/2; y++)
|
|||
|
|
{
|
|||
|
|
for(x = 0; x < texWidth; x++)
|
|||
|
|
{
|
|||
|
|
texY0 = *texHigh-y-1;
|
|||
|
|
n = pixelBuff[0][y*texWidth + x];
|
|||
|
|
pixelBuff[0][y*texWidth + x] = pixelBuff[0][texY0*texWidth + x];
|
|||
|
|
pixelBuff[0][texY0*texWidth + x] = n;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return INS_TRUE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Bool DrawSingleLineTxtBmp
|
|||
|
|
(
|
|||
|
|
Int32 libID,
|
|||
|
|
Int32 charSize,
|
|||
|
|
Int32 *bmpWidth,
|
|||
|
|
Int32 *bmpHigh,
|
|||
|
|
const UInt32 *ucsCode,
|
|||
|
|
UInt08 *bmpPixel,
|
|||
|
|
Bool tight,
|
|||
|
|
Int32 *numDrawn
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
Int32 x, y, n, cursorX, failWidth;
|
|||
|
|
FT_Glyph glyph[1];
|
|||
|
|
|
|||
|
|
if(charSize > *bmpWidth
|
|||
|
|
|| bmpPixel == NULL
|
|||
|
|
|| libID >= mFtFaceIdCnt
|
|||
|
|
|| libID < 0)
|
|||
|
|
{
|
|||
|
|
if(numDrawn != NULL)*numDrawn = 0;
|
|||
|
|
return INS_FALSE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FT_Set_Pixel_Sizes(mFtFace[libID], charSize, charSize);
|
|||
|
|
|
|||
|
|
/* use '_' rectangle info for invalid(fail) character */
|
|||
|
|
if(FT_Load_Glyph(mFtFace[libID], FT_Get_Char_Index(mFtFace[libID], '_'), FT_LOAD_DEFAULT) != 0
|
|||
|
|
|| FT_Get_Glyph(mFtFace[libID]->glyph, glyph) != 0)
|
|||
|
|
{
|
|||
|
|
failWidth = charSize/2;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if(glyph[0]->format != FT_GLYPH_FORMAT_BITMAP)
|
|||
|
|
{
|
|||
|
|
FT_Glyph_To_Bitmap(glyph, FT_RENDER_MODE_NORMAL, 0, 1);
|
|||
|
|
}
|
|||
|
|
FT_BitmapGlyph bmpGlyph = (FT_BitmapGlyph)glyph[0];
|
|||
|
|
|
|||
|
|
failWidth = bmpGlyph->bitmap.width;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FT_Done_Glyph(glyph[0]);
|
|||
|
|
glyph[0] = NULL;
|
|||
|
|
|
|||
|
|
cursorX = 0;
|
|||
|
|
for(n = 0; ucsCode[n] != 0; n++)
|
|||
|
|
{
|
|||
|
|
UInt08 *buff = NULL;
|
|||
|
|
UInt32 idx, innx, inny;
|
|||
|
|
Int32 glyphLeft, glyphTop, glyphWidth, glyphHeight;
|
|||
|
|
|
|||
|
|
if((idx = FT_Get_Char_Index(mFtFace[libID], ucsCode[n])) == 0 /*invalid character*/
|
|||
|
|
|| FT_Load_Glyph(mFtFace[libID], idx, FT_LOAD_DEFAULT) != 0 /*load fail*/
|
|||
|
|
|| FT_Get_Glyph(mFtFace[libID]->glyph, glyph) != 0) /*get fail*/
|
|||
|
|
{
|
|||
|
|
printf("load glyph fail[ucs:0x%x]\n", ucsCode[n]);
|
|||
|
|
glyphWidth = 0;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if(glyph[0]->format != FT_GLYPH_FORMAT_BITMAP)
|
|||
|
|
{
|
|||
|
|
FT_Glyph_To_Bitmap(glyph, FT_RENDER_MODE_NORMAL, 0, 1);
|
|||
|
|
}
|
|||
|
|
FT_BitmapGlyph bmpGlyph = (FT_BitmapGlyph)glyph[0];
|
|||
|
|
|
|||
|
|
glyphWidth = bmpGlyph->bitmap.width;
|
|||
|
|
glyphHeight = bmpGlyph->bitmap.rows;
|
|||
|
|
glyphLeft = bmpGlyph->left;
|
|||
|
|
glyphTop = bmpGlyph->top;
|
|||
|
|
// printf("load glyph ok[ucs:0x%x]\n", ucsCode[n]);
|
|||
|
|
// printf("(%d, %d, %d, %d)\n", glyphLeft, glyphTop, glyphWidth, glyphHeight);
|
|||
|
|
|
|||
|
|
buff = bmpGlyph->bitmap.buffer;
|
|||
|
|
}
|
|||
|
|
if(glyphWidth == 0)
|
|||
|
|
{
|
|||
|
|
glyphWidth = failWidth;
|
|||
|
|
glyphHeight = 0;
|
|||
|
|
glyphLeft = 0;
|
|||
|
|
glyphTop = 0;
|
|||
|
|
}
|
|||
|
|
if(tight)
|
|||
|
|
{
|
|||
|
|
if(cursorX + glyphWidth > (*bmpWidth))
|
|||
|
|
{
|
|||
|
|
FT_Done_Glyph(glyph[0]);
|
|||
|
|
glyph[0] = NULL;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
x = cursorX;
|
|||
|
|
y = charSize - glyphTop;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if(cursorX + charSize > (*bmpWidth))
|
|||
|
|
{
|
|||
|
|
FT_Done_Glyph(glyph[0]);
|
|||
|
|
glyph[0] = NULL;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
x = cursorX + glyphLeft;
|
|||
|
|
y = charSize - glyphTop;
|
|||
|
|
}
|
|||
|
|
if(y < 0)y = 0;
|
|||
|
|
|
|||
|
|
// printf("cursorX:%d, bmpWidth:%d, bmpHeight:%d, (%d,%d)\n", cursorX, *bmpWidth, *bmpHigh, x, y);
|
|||
|
|
for(inny = 0; inny < glyphHeight; inny++)
|
|||
|
|
{
|
|||
|
|
for(innx = 0; innx < glyphWidth; innx++)
|
|||
|
|
{
|
|||
|
|
// printf("%x%x,", buff[inny*glyphWidth+innx]/16, buff[inny*glyphWidth+innx]%16);
|
|||
|
|
if((*bmpHigh) <= y+inny)continue;
|
|||
|
|
bmpPixel[((*bmpHigh)-y-inny-1)*(*bmpWidth) + x + innx] = buff[inny*glyphWidth+innx];
|
|||
|
|
// bmpPixel[(y+inny)*(*bmpWidth) + x + innx] = buff[inny*glyphWidth+innx];
|
|||
|
|
}
|
|||
|
|
// printf("\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(tight)
|
|||
|
|
{
|
|||
|
|
cursorX += glyphWidth+2;/* +2 to make a gap between glyphs*/
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
cursorX += charSize;
|
|||
|
|
}
|
|||
|
|
FT_Done_Glyph(glyph[0]);
|
|||
|
|
glyph[0] = NULL;
|
|||
|
|
}
|
|||
|
|
if(numDrawn != NULL)*numDrawn = n;
|
|||
|
|
|
|||
|
|
if(tight)cursorX -= 2;
|
|||
|
|
for(y = 1; y < *bmpHigh; y++)
|
|||
|
|
{
|
|||
|
|
for(x = 0; x < cursorX; x++)
|
|||
|
|
{
|
|||
|
|
bmpPixel[y*cursorX+x] = bmpPixel[y*(*bmpWidth)+x];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
x = (*bmpHigh)*cursorX;
|
|||
|
|
y = (*bmpHigh)*(*bmpWidth);
|
|||
|
|
while(x < y)bmpPixel[(x++)] = 0;
|
|||
|
|
|
|||
|
|
*(bmpWidth) = cursorX;
|
|||
|
|
// printf("width:%d, height:%d\n", (*bmpWidth), (*bmpHigh));
|
|||
|
|
|
|||
|
|
return INS_TRUE;
|
|||
|
|
}
|
|||
|
|
|