octave-maintainers
[Top][All Lists]
Advanced

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

Re: about contibuting to octave


From: xianghang liu
Subject: Re: about contibuting to octave
Date: Wed, 11 Mar 2009 14:37:05 +0800



On Fri, Mar 6, 2009 at 6:54 AM, xianghang liu <address@hidden> wrote:


On Fri, Mar 6, 2009 at 6:53 AM, xianghang liu <address@hidden> wrote:


On Thu, Mar 5, 2009 at 8:21 PM, Shai Ayal <address@hidden> wrote:
On Thu, Mar 5, 2009 at 12:00 PM, xianghang liu <address@hidden> wrote:
>
>
> On Wed, Mar 4, 2009 at 9:14 PM, Ben Abbott <address@hidden> wrote:
>>
>> On Mar 4, 2009, at 5:09 AM, Michael Goffioul wrote:
>>
>>> On Wed, Mar 4, 2009 at 9:22 AM, xianghang liu <address@hidden>
>>> wrote:
>>>>
>>>> In freetype, I found two functions
>>>>
>>>> FT_Outline_Get_BBox Compute the exact bounding box of an outline.
>>>> FT_Outline_Get_CBox Return an outline's ‘control box’.
>>>>
>>>> After a rough glance at ftgl's bounding box computation, I think it use
>>>> FT_Outline_Get_CBox to compute the box of each glyph and add them
>>>> together
>>>> to get the extent of the string. Shall we just follow the same method?
>>>
>>> AFAIK, depending on the font, the width of a string is not the same as
>>> the sum of the width of all its characters. OTOH, I think you can assume
>>> that the width of a string will always be <= than the sum of the width of
>>> its characters. So adding the box of each glyph should give you a maximum
>>> width anyway.
>>>
>>> Note that I'm not a font expert, so I might be wrong.
>>>
>>> Michael.
>>
>> I'm uncertain about this as well. Does anyone following along know?
>>
>> I was under the impression that the spacing between characters depends
>> upon the neighboring characters (however, I might be thinking of LaTeX,
>> which I'd expect to have a more complicated scheme). If a string's extent is
>> not the sum of is character's extents, then we will require something to
>> calculate the extents of a string directly. Which is something that gdlib
>> and ftgl provide for.
>>
>> In any event, I'm thrilled that xianghang has taken on this effort. From
>> my perspective this represents the largest obstacle to improving the
>> compatibility of the gnuplot backend.
>>
>> Ben
>
> I found two methods to get the extent of text objects by freetype:
>
> use FT_Outline_Get_CBox to get the bounding box of a single glyph and
> FT_Get_Kerning to get the kerning vector between two glyphs. This is the
> method used in FTGL and contained in FTFontImpl::BBoxI.
> in gdft.c of gd library source code, there is a function gdImageStringFTEx
> and some similiar funcions. These functions implement another method to get
> bounding box from glyph metrics. These functions are what PHP function
> imagettfbbox use to get bounding box. Call to these functions can be found
> in PHP source code  \php-5.2.9\ext\gd\gd.c
>
>  Xianghang Liu
>
I would go with freetype2, since it seems to be the current standard
librbary for font handling, and we will be using it in the
opengl-renderer anyway

Shai



What I mean is the same as you: we compute extent of text objects with freetype2 and without any dependency on backends. What I mentioned in my last email is the how backends (FTGL and GD) use freetype2 to get extent.
I would like to implement these two methods and examine whether they get the same result.
Any suggestions?

 Xianghang Liu

 
Two functions below are two methods of computing bounding box of a text object. I wrote them following algorithms used in GD and Freetype. Only a slight diiference is between them. It is the computation of bounding box of a charachter. And the final result of them are slightly different as well.
Please tell me if you find any mistakes or have suggestions.

Thanks

Xianghang

void bound_box_gd(FT_Face face, const char *text_string, float *brect,FT_Int load_tags, FT_Int kerning_mode) {
    FT_Vector penf = {0,0}, glyph_min = {0,0}, glyph_max = {0,0}, total_max,total_min;
    FT_GlyphSlot slot = face->glyph;
    int previous = 0;
    for (const char *cur = text_string; *cur != '\0'; cur++) {
        int glyph_index = FT_Get_Char_Index (face, *cur);
        FT_Load_Glyph(face,glyph_index,load_tags);     
        if (previous != -1) {
            FT_Vector delta;
            FT_Get_Kerning (face, previous, glyph_index, kerning_mode, &delta);
            penf.x += delta.x;
        }
        glyph_min.x = penf.x + slot->metrics.horiBearingX;
        glyph_max.y = slot->metrics.horiBearingY - penf.y;
        glyph_max.x = penf.x + slot->metrics.horiAdvance;
        glyph_min.y = glyph_max.y - slot->metrics.height;
        if (text_string == cur) {
            total_min = glyph_min;
            total_max = glyph_max;
        } else {
            if (glyph_min.x < total_min.x)
                total_min.x = glyph_min.x;
            if (glyph_min.y < total_min.y)
                total_min.y = glyph_min.y;
            if (glyph_max.x > total_max.x)
                total_max.x = glyph_max.x;
            if (glyph_max.y > total_max.y)
                total_max.y = glyph_max.y;
        }
        penf.x += slot->advance.x;
        previous = glyph_index;
    }   
    brect[0] = static_cast<float>(total_min.x) / 64.0;
    brect[1] = static_cast<float>(total_min.y) / 64.0;
    brect[2] = static_cast<float>(total_max.x) / 64.0;
    brect[3] = static_cast<float>(total_max.y) / 64.0;
}
void bound_box_ftgl(FT_Face face, const char *text_string, float *brect,FT_Int load_tags,FT_Int kerning_mode) {
    int previous = -1;
    FT_Vector penf = {0,0};
    FT_GlyphSlot slot = face->glyph;
    FT_BBox box_total;   
    for (const char *cur = text_string; *cur != '\0'; cur++) {
        int glyph_index = FT_Get_Char_Index (face, *cur);
        FT_Load_Glyph(face,glyph_index,load_tags);
        if (previous != -1) {
            FT_Vector delta;
            FT_Get_Kerning (face, previous, glyph_index, kerning_mode, &delta);
            penf.x += delta.x;
        }
        FT_BBox bbox;
        FT_Outline_Get_CBox(&(slot->outline), &bbox);
        bbox.xMin += penf.x;
        bbox.yMin += penf.y;
        bbox.xMax += penf.x;
        bbox.yMax += penf.y;
        if (cur == text_string) {
            box_total = bbox;
        } else {
            box_total.xMin = std::min(box_total.xMin,bbox.xMin);
            box_total.yMin = std::min(box_total.yMin,bbox.yMin);
            box_total.xMax = std::max(box_total.xMax,bbox.xMax);
            box_total.yMax = std::max(box_total.yMax,bbox.yMax);
        }
        //penf.x += slot->metrics.horiAdvance;
        penf.x += slot->advance.x;
        previous = glyph_index;
    }
    brect[0] = static_cast<float>(box_total.xMin) / 64.0;
    brect[1] = static_cast<float>(box_total.yMin) / 64.0 ;
    brect[2] = static_cast<float>(box_total.xMax) / 64.0;
    brect[3] = static_cast<float>(box_total.yMax) / 64.0 ;
}


reply via email to

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