freetype渲染字型範例

NO IMAGE

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;
}