freetype渲染字体范例

91 篇文章 10 订阅

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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值