代碼中,先把字型矩陣轉換為bit,再進行旋轉。關鍵有幾點:
- 計算數組大小。
size = (w+7) * (h+7) / 8;
- 正确旋轉的算法。這個通過byte旋轉代碼得到。參考:
- bit坐标轉換。代碼是這樣的:
int srcPos = (offset + x);
int srcPosByte = srcPos / 8;
int srcPosBit = srcPos % 8;
int value = (pBuffer[srcPosByte] & (0x01 << srcPosBit)) != 0 ? 1 : 0;
int dstPosByte = i / 8;
int dstPosBite = i % 8;
pRotated[dstPosByte] |= (value << dstPosBite);
全部源碼:
看到這麼整齊的源碼,肯定是本人所寫。如此漂亮,閣下應該學習國中。
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <ft2build.h>
#include <freetype/freetype.h>
#include FT_FREETYPE_H
#define FONT_FILE "/home/uos/font/simsun.ttc"
static void dumpByte(char* pBuffer, int w, int h)
{
int i=0;
int j=0;
//printf("w=%d, h=%d\n", w, h);
for (i=0; i<h; i++)
{
printf("|");
for (j=0; j<w; j++)
{
printf((pBuffer[i * w + j]) ? "1" : " ");
}
printf("|\n");
}
}
static void dumpFontBmp(FT_Bitmap* pBmp)
{
int w = pBmp->width;
int h = pBmp->rows;
dumpByte(pBmp->buffer, w, h);
}
static char* byteToBit(char* pBuffer, int w, int h)
{
int i=0;
int j=0;
int size = (w+7) * (h+7) / 8;
char* bits = (char*)malloc(size);
memset(bits, 0, size);
for (i=0; i<h; i++)
{
for (j=0; j<w; j++)
{
int srcPos = (i * w + j);
int srcPosByte = srcPos / 8;
int srcPosBit = srcPos % 8;
bits[srcPosByte] |= (pBuffer[i * w + j] == 0 ? 0 : (0x01 << srcPosBit));
}
}
return bits;
}
static void dumpBit(char* pBuffer, int w, int h)
{
int i=0;
int j=0;
printf("w=%d, h=%d\n", w, h);
for (i=0; i<h; i++)
{
printf("|");
for (j=0; j<w; j++)
{
int srcPos = (i * w + j);
int posByte = srcPos / 8;
int posBit = srcPos % 8;
int bitValue = (pBuffer[posByte] & (0x01 << posBit)) != 0 ? 1 : 0;
printf(bitValue ? "1" : " ");
}
printf("|\n");
}
}
static char* rotate_90(char* pBuffer, int w, int h)
{
int i=0;
char* pRotated;
int size;
int offset=0;
size = (w+7) * (h+7) / 8;
pRotated = (char*)malloc(size);
memset(pRotated, 0, size);
int startPos = (h - 1) * w;
i = 0;
for (int x = 0; x < w; x++)
{
int offset = startPos;
for (int y = h - 1; y >= 0; y--)
{
int srcPos = (offset + x);
int srcPosByte = srcPos / 8;
int srcPosBit = srcPos % 8;
int srcBitValue = (pBuffer[srcPosByte] & (0x01 << srcPosBit)) != 0 ? 1 : 0;
int dstPosByte = (i)/8;
int dstPosBit = (i)%8;
pRotated[dstPosByte] |= (srcBitValue << dstPosBit);
i++;
offset -= w;
}
}
dumpBit(pRotated, h, w);
return pRotated;
}
static char* rotate_270(char* pBuffer, int w, int h)
{
int i=0;
char* pRotated;
int size;
int offset=0;
size = (w+7) * (h+7)/8;
pRotated = (char*)malloc(size);
memset(pRotated, 0, size);
i = 0;
for (int x = w-1; x >= 0; x--)
{
int offset = 0;
for (int y = 0; y < h; y++)
{
int srcPos = (offset + x);
int srcPosByte = srcPos / 8;
int srcPosBit = srcPos % 8;
int srcBitValue = (pBuffer[srcPosByte] & (0x01 << srcPosBit)) != 0 ? 1 : 0;
int dstPosByte = i / 8;
int dstPosBit = i % 8;
pRotated[dstPosByte] |= (srcBitValue << dstPosBit);
i++;
offset += w;
}
}
dumpBit(pRotated, h, w);
return pRotated;
}
int main()
{
FT_Library m_pFTLib;
FT_Face m_pFTFace;
wchar_t chinese_char = L'泰';
FT_Error result = FT_Init_FreeType(&m_pFTLib);
if(FT_New_Face(m_pFTLib, FONT_FILE, 0, &m_pFTFace))
{
printf("FT_New_Face error!\n");
return -1;
}
//FT_ENCODING_GB2312, FT_ENCODING_UNICODE
FT_Select_Charmap(m_pFTFace, FT_ENCODING_UNICODE);
FT_Set_Char_Size(m_pFTFace, 0, 12<<6, 200, 200);
result = FT_Load_Glyph(m_pFTFace, FT_Get_Char_Index(m_pFTFace, chinese_char), FT_LOAD_DEFAULT);
// 第二個參數為渲染模式
result = FT_Render_Glyph(m_pFTFace->glyph, FT_RENDER_MODE_NORMAL);
printf("result=%d\n", result);
FT_Bitmap* pBmp = &(m_pFTFace->glyph->bitmap);
//dumpFontBmp(pBmp);
int w = pBmp->width;
int h = pBmp->rows;
char* bits = byteToBit(m_pFTFace->glyph->bitmap.buffer, w, h);
dumpBit(bits, w, h);
rotate_90( bits, w, h);
rotate_270(bits, w, h);
return 0;
}