FreeType ¹®ÀÚ¿­ Ãâ·Â

¹®ÀÚ¿­À» ÇÒ´çÇÑ ¸Þ¸ð¸® ¹öÆÛ¿¡ Ãâ·ÂÇÏ°í pgm À̹ÌÁö·Î ÀúÀåÇØ º¸ÀÚ.



FreeType ¿Ü°û¼± ±×¸°ÈÄ ºñÆ®¸ÊÀ» ¾ò¾î¿Ã¶§ FT_Bitmap ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°´Ù.

rows ¼¼·Î Çȼ¿ »çÀÌÁî
width °¡·Î Çȼ¿ »çÀÌÁî
pitch °¡·Î ¹ÙÀÌÆ® »çÀÌÁî
buffer ºñÆ® ¸Ê Æ÷ÀÎÅÍ

ÆùÆ® ³ôÀÌ ±¸Çϱâ :
 - Çà°£ÀÇ °£°ÝÀ¸·Î »ç¿ë ÇÒ¼ö ÀÖ´Ù.
 - ÆùÆ® ³ôÀÌ ±¸ÇÏ´Â ¹æ¹ýÀ» ´ÙÀ½ ½ÄÀ¸·Î º¯°æÇÑ´Ù.

//int fontHeight = ::FT_MulFix(face->bbox.yMax - face->bbox.yMin, face->size->metrics.y_scale)/64;
int fontHeight = face->size->metrics.height/64;

ÆùÆ® ±âÁØ ¶óÀÎ :
 - º£À̽º ±âÁضóÀο¡¼­ °¡Àå ³ôÀº ÁÂÇ¥±îÁöÀÇ °Å¸®
int fontAscender = face->size->metrics.ascender / 64;

ÆùÆ®¸¦ ±×¸®¸¦¶§ "ÆùÆ® ³ôÀÌ" ¿Í  "ÆùÆ® ³ôÀÌ ±âÁØ ¶óÀÎ"Àº ÆùÆ® Å©±â( FT_Set_Char_Size ) ¸¦ ¼³Á¤ÇÑ ÈÄ ¹®ÀÚÄڵ忡 »ó°ü ¾øÀÌ Çѹø¸¸ ±¸Çؼ­ °øÅëÀûÀ¸·Î »ç¿ëÇÒ¼ö ÀÖ´Ù.

FT_Load_Char¿¡¼­ 3¹ø° ÀÎÀÚ¿¡¼­ FT_LOAD_NO_BITMAP Ç÷¡±×¸¦ ÁÖ´Â ÀÌÀ¯?
ÁöÁ¤ÇÑ Å©±âÀÇ ºñÆ®¸ÊÀÌ ÀÖ´õ¶óµµ ¿Ü°û¼±À¸·Î ·ÎµåÇϴ°ÍÀº ºñÆ®¸Ê ±Û²ÃÀÌ Èæ¹éÀ̱⠶§¹®¿¡ ¾Ù¸®¾î½ÌÀÌ µÈ ¿Ü°û¹®ÀÚ¿Í  ºñÆ®¸ÊÀº Â÷ÀÌ°¡ ³ª±â ¶§¹®¿¡ ÀÏ°ü¼ºÀ» ÁÖ±â À§Çؼ­ÀÌ´Ù.

int DrawFont(char* buff, int width, int height, int fontAscender, int x, int y, FT_Face& face, TCHAR ch, Point2<int>& advance)
{
    //±Û¸®ÇÁ À妽º ±¸ÇÔ
    int index = FT_Get_Char_Index(face, ch);

    //·Îµå ±Û¸®ÇÁ
    int error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP);
    if(error)
        return error;

    //·£´õ¸µ
    error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
    if(error)
        return error;

    advance.x = face->glyph->advance.x >> 6;
    advance.y = face->glyph->advance.y >> 6; //y°ªÀº Ç×»ó 0À» ¸®ÅÏÇÏ°í ÀÖ´Ù.

    //È­¸é¿¡ Ãâ·ÂÇϱâ À§ÇØ bitmapÀÇ width, rows¸¦ ±¸ÇÑ´Ù.
    int bitmapWidth = face->glyph->bitmap.width;
    int bitmapHeight = face->glyph->bitmap.rows;
    char* bitmapBuff = (char*)face->glyph->bitmap.buffer;
    int bitmapLeft = face->glyph->bitmap_left;
    int bitmapTop = face->glyph->bitmap_top;

    if(( bitmapWidth  + x + bitmapLeft) > width)
        return 1;  //ÆùÆ®°¡ width À̹ÌÁö Å©±âº¸´Ù Å©´Ù.

    
    for (int n = 0 ; n < bitmapHeight; n++)
    {
        for(int m = 0; m < bitmapWidth; m++)
        {
            buff[width*(n + y + (fontAscender-bitmapTop)) + m + x + bitmapLeft]  = bitmapBuff[bitmapWidth*n + m];
        }
    }

    return 0;
}

#define FONT_LINE_GAP 0  //Çà°£À» ÁÖ¾î ±ÛÀÚ¸¦ Àбâ ÆíÇϵµ·Ï ÇÑ´Ù.
int StringPGM::WriteGlyphString(FT_Face& face, const char* szPath, TCHAR *str)
{
    int width = 1024;
    int height = 1024;
    char* buff = new char[1024*1024];
    memset(buff, 0, 1024*1024);

    Point2<int> advance = {0, 0}, pos = {0, 0};
    int len = (int)_tcslen(str);

    // fill glyphHeight with simple index
    //int fontHeight = ::FT_MulFix(face->bbox.yMax - face->bbox.yMin, face->size->metrics.y_scale)/64;
    int fontHeight = face->size->metrics.height/64;
    int fontAscender = face->size->metrics.ascender / 64;

    for(int n = 0; n < len; n++)
    {
        if(DrawFont(buff, width, height, fontAscender, pos.x, pos.y, face, str[n], advance) == 1)
        {
            pos.x = 0;
            pos.y += (fontHeight + FONT_LINE_GAP);
            DrawFont(buff, width, height, fontAscender, pos.x, pos.y, face, str[n], advance);
        }
        pos.x += advance.x;
    }
    StringPGM::WritePGM(szPath, width, height, (const char *)buff);

    delete [] buff;
    return 0;
}

DrawFont·Î ¸Þ¸ð¸®¿¡ ÆùÆ®¸¦ ±×¸±¶§ ¸®ÅÏ°ªÀÌ 1À̸é x°ªÀÌ ¹öÆÛ °¡·Î ÆøÀ» ³Ñ¾î°¡±â ¶§¹®¿¡ ´ÙÀ½ ¶óÀÎÀÇ Ã¹Ä­À¸·Î À̵¿ÇÑ´Ù.
fontHeight´Â Çà°£ÀÇ °£°Ý ±âÁØÀÌ µÈ´Ù. ÆùÆ®°¡ º¸±â ÁÁ°Ô º¸À̵µ·Ï FONT_LINE_GAP ¸¸Å­ ´õ °£°ÝÀ» ÁÖ¾ú´Ù.
DrawFontÀÇ ¸¶Áö¸· ÀÎÀÚ´Â ¾ó¸¶³ª ÁøÇàÇØ¾ß ÇÒÁö ¾ò¾î¿À´Â ÇÔ¼öÀÌ´Ù.
xÃàÀº °ªÀÌ ³Ñ¾î ¿ÀÁö¸¸ yÃàÀº 0ÀÌ ³Ñ¾î ¿Â´Ù.

    for(int n = 0; n < len; n++)
    {
        if(DrawFont(buff, width, height, fontAscender, pos.x, pos.y, face, str[n], advance) == 1)
        {
            pos.x = 0;
            pos.y += (fontHeight + FONT_LINE_GAP);
            DrawFont(buff, width, height, fontAscender, pos.x, pos.y, face, str[n], advance);
        }
        pos.x += advance.x;
    }


ÆùÆ® ³ôÀ̸¦ ±¸ÇÏ´Â ¹æ¹ýÀº 2°¡ÁöÀÌ´Ù.
1.  ÆùÆ® ³ôÀÌ = "font height" - "bitmap top"
2.  ÆùÆ® ³ôÀÌ = "ascender height" - "bitmap top"

¿©±â¼­´Â µÎ¹ø° ¹æ¹ýÀ» »ç¿ëÇÑ´Ù. ù¹ø° ¹æ¹ý º¸´Ù Á»ó ¾ÞÄ¿¿Í °Å¸® Â÷ÀÌ°¡ ´õ Àû±â ¶§¹®ÀÌ´Ù.

buff[width*(n + y + (fontAscender-bitmapTop)) + m + x + bitmapLeft]  = bitmapBuff[bitmapWidth*n + m];

ÇÔ¼ö È£Ãâ ¼ø¼­ : SaveFont > WriteGlyphString > DrawFont

¼Ò½º:  02_string_pgm.cpp

ÂüÁ¶)
https://bab2min.tistory.com/322
http://www.soen.kr/lecture/library/freetype/ft3.htm
https://tnzk.hatenadiary.org/entry/20081005/1223208785