freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] Why my memory is not been freed?


From: Werner LEMBERG
Subject: Re: [ft-devel] Why my memory is not been freed?
Date: Tue, 10 Mar 2009 07:32:34 +0100 (CET)

> I use Arial.ttf. I uploaded my test project. Please Check.
> http://www.nabble.com/file/p22413476/GenfontData.rar

I slightly modified (and formatted) your program so that it runs
without errors using g++ -- in particular, g++ doesn't like jumps
which cross an initialization.  I compiled with

  g++ -Wall -O0 -g \
      -o GenfontData \
      GenfontData.cpp \
      -l freetype

(with proper -I and -L options to set the include and library
directories) using the current CVS version of FreeType.

BTW, have you ever run your example by yourself?  In its unmodified
form it always crashes due to the redundant FT_Done_FreeType call
right before the `OUT0' label.  Besides that, everything is fine!

Sorry that I don't have time to modify FreeType as indicated by you
for the tests.

Attached you can see the output of valgrind.  The call was

  valgrind ./GenfontData > GenfontData.out 2> GenfontData.log

It reports that there is no memory leak.


    Werner


PS: The next time please send a *simple* C or C++ source file -- I
    don't need a complete project since I don't use Windows.  In your
    example, there's far too much stuff which is not related to the
    very problems you have with FreeType.
// GenfontData.cpp : Defines the entry point for the console application.
//

#include <ft2build.h>
#include <freetype/freetype.h>

#define TTF_FONT_SIZE       (48)

static FT_Library g_freetype2_library = NULL;
static FT_Face    g_FTFace;
static int        g_MaxPixelHeight = 0;
static int        g_Baseline;
static int        g_Space;
static int        g_AverageWidth;

#define ROUND_26_6_TO_INT(vale)       ((vale + 63) >> 6)
#define LOOKUP_CHAR(pf_, face_, ch_)   (FT_Get_Char_Index(face_, ch_))

static void
freetype2_setFontSize(int fontsize);
static int
freetype2_getGlyphSize(int glyph_index,
                       int *pAdvance);

static unsigned short
aUnicode[] = {
    0x0041,
    0x0042,
    0x0043,
    0x0060,
    0x0061,
    0x0062
};


int
main(int argc,
     char* argv[])
{
    FT_Error error;
    unsigned int uiUnicode;
    unsigned int uiUnicodeCount = sizeof(aUnicode) / sizeof(aUnicode[0]);

    error = FT_Init_FreeType(&g_freetype2_library);
    if (error) {
        g_freetype2_library = NULL;
        printf("There is some err or when Init Library...");
        return 1;
    }

    error = FT_New_Face(g_freetype2_library,
                        "arial.ttf",
                        0,
                        &g_FTFace);
    if (error) {
        goto OUT;
    }

    error = FT_Select_Charmap(g_FTFace,
                              FT_ENCODING_UNICODE);
    if (error) {
        printf("\nFT_Select_Charmap error!");
        goto OUT0;
    }

    freetype2_setFontSize(TTF_FONT_SIZE);

    printf("\nint     g_MaxPixelHeight = %d;", g_MaxPixelHeight);
    printf("\nint     g_Baseline = %d;", g_Baseline);
    printf("\nint     g_AverageWidth = %d;", g_AverageWidth);
    
printf("\n//---------------------------------------------------------------------");
    
printf("\n//---------------------------------------------------------------------");

    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        int currChar = LOOKUP_CHAR(NULL,
                                   g_FTFace,
                                   aUnicode[uiUnicode]);
        error = FT_Load_Glyph(g_FTFace,
                              currChar,
                              FT_LOAD_RENDER);
        if (error) {
            printf("\nFT_Load_Glyph error, unicode = 0x%04X!",
                   aUnicode[uiUnicode]);
            goto OUT0;
        }

        if (g_FTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
            printf("\nFT_Load_Glyph error, format = %d!",
                   g_FTFace->glyph->format);
            goto OUT0;
        }

        FT_Bitmap *bitmap = &g_FTFace->glyph->bitmap;

        int iPixMode = g_FTFace->glyph->bitmap.pixel_mode;
        int bitmap_top = g_FTFace->glyph->bitmap_top;
        int bitmap_left = g_FTFace->glyph->bitmap_left;
        int bitmap_rows = bitmap->rows;
        int bitmap_width = bitmap->width;
        int bitmap_pitch = bitmap->pitch;

        unsigned char* pucBuf = bitmap->buffer;

        if (bitmap_rows > g_MaxPixelHeight) {
            bitmap_rows = g_MaxPixelHeight;
        }

        //printf glyph data
        printf("\nunsigned short unicode_%d = 0x%04X;", uiUnicode, 
aUnicode[uiUnicode]);
        printf("\nint            iPixMode_%d = %d;", uiUnicode, iPixMode);
        printf("\nint            bitmap_top_%d = %d;", uiUnicode, bitmap_top);
        printf("\nint            bitmap_left_%d = %d;", uiUnicode, bitmap_left);
        printf("\nint            bitmap_rows_%d = %d;", uiUnicode, bitmap_rows);
        printf("\nint            bitmap_width_%d = %d;", uiUnicode, 
bitmap_width);
        printf("\nint            bitmap_pitch_%d = %d;", uiUnicode, 
bitmap_pitch);
        printf("\n/*");
        printf("\n");

        int iRow, iLine;
        for (iRow = 0;
             iRow < bitmap_rows;
             iRow++) {
            for (iLine = 0;
                 iLine < bitmap_width;
                 iLine++) {
                printf("%c",
                       pucBuf[iRow * bitmap->pitch + iLine] >0 ? '0' : '_');
            }
            printf("\n");
        }
        printf("*/");

        printf("\nunsigned char aBMPData_%d[] = {\n",
               uiUnicode);
        for (iRow = 0;
             iRow < bitmap_rows;
             iRow++) {
            for (iLine = 0;
                 iLine < bitmap_width;
                 iLine++) {
                if ((iRow == bitmap_rows - 1)
                    && (iLine == bitmap_width - 1))
                    printf("0x%02X",
                           pucBuf[iRow * bitmap->pitch + iLine]);
                else
                    printf("0x%02X,",
                           pucBuf[iRow * bitmap->pitch + iLine]);
            }
            printf("\n");
        }
        printf("};");
        
printf("\n//---------------------------------------------------------------------");
    }

    printf("\nunsigned int g_uuiUnicodeCharCount = %d;",
           uiUnicodeCount);

    printf("\nint unicode_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("unicode_%d",
                   uiUnicode);
        else
            printf("unicode_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nint pixelMode_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("iPixMode_%d",
                   uiUnicode);
        else
            printf("iPixMode_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nint bitmap_top_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("bitmap_top_%d",
                   uiUnicode);
        else
            printf("bitmap_top_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nint bitmap_left_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("bitmap_left_%d",
            uiUnicode);
        else
            printf("bitmap_left_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nint bitmap_rows_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("bitmap_rows_%d",
                   uiUnicode);
        else
            printf("bitmap_rows_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nint bitmap_width_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("bitmap_width_%d",
                   uiUnicode);
        else
            printf("bitmap_width_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nint bitmap_pitch_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("bitmap_pitch_%d",
                   uiUnicode);
        else
            printf("bitmap_pitch_%d,",
                   uiUnicode);
    }
    printf("};");

    printf("\nunsigned char *BMPData_Array[] = {");
    for (uiUnicode = 0;
         uiUnicode < uiUnicodeCount;
         uiUnicode++) {
        if (uiUnicode == uiUnicodeCount - 1)
            printf("aBMPData_%d",
                   uiUnicode);
        else
            printf("aBMPData_%d,",
                   uiUnicode);
    }
    printf("};");
    printf("\n");

OUT0:
    FT_Done_Face(g_FTFace);

OUT:
    FT_Done_FreeType(g_freetype2_library);
    g_freetype2_library = NULL;

    return 0;
}


static void
freetype2_setFontSize(int fontsize)
{
    FT_Size size;
    int pixel_width, pixel_height;
    FT_Size_Metrics *metrics;
    int fontBaseline, fontDescent;

    pixel_height = pixel_width = fontsize;
    while(1) {
        FT_Set_Pixel_Sizes(g_FTFace, pixel_width, pixel_height);
        size = g_FTFace->size;
        metrics = &(size->metrics);

        fontBaseline = ROUND_26_6_TO_INT(metrics->ascender);
        fontDescent = ROUND_26_6_TO_INT(abs(metrics->descender));

        g_MaxPixelHeight = fontBaseline + fontDescent;
        if (g_MaxPixelHeight < fontsize)
          break;

        pixel_height = pixel_width = pixel_height - 1;
    }

    g_Baseline = fontBaseline;
    g_Space = ROUND_26_6_TO_INT(metrics->max_advance) / 4;
    g_Space = g_Space < 8 ? 8:g_Space;
    //average width is the width of 'x'
    if (freetype2_getGlyphSize(LOOKUP_CHAR(NULL,
                                           g_FTFace,
                                           0x0078),
                               &g_AverageWidth))
        g_AverageWidth = g_Space;
}


static int
freetype2_getGlyphSize(int glyph_index,
                       int *pAdvance)
{
    FT_Error err;

    err = FT_Load_Glyph(g_FTFace,
                        glyph_index,
                        FT_LOAD_RENDER);
    if (err)
        return 1;

    if (pAdvance) {
        FT_Bitmap *bitmap;
        bitmap = &(g_FTFace->glyph->bitmap);
        *pAdvance = g_FTFace->glyph->bitmap_left + bitmap->width;
    }

    return 0;
}

Attachment: GenfontData.out.gz
Description: Binary data

==7161== Memcheck, a memory error detector.
==7161== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==7161== Using LibVEX rev 1854, a library for dynamic binary translation.
==7161== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==7161== Using valgrind-3.3.1, a dynamic binary instrumentation framework.
==7161== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==7161== For more details, rerun with: -v
==7161== 
==7161== 
==7161== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 3 from 1)
==7161== malloc/free: in use at exit: 0 bytes in 0 blocks.
==7161== malloc/free: 143 allocs, 143 frees, 101,016 bytes allocated.
==7161== For counts of detected errors, rerun with: -v
==7161== All heap blocks were freed -- no leaks are possible.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]