Domanda

Following are two characters outlines extracted using freetype and processed in some loops using the quadric bezier curve formula(helped by opensans regular ttf font). I am not sure if what i did is correct, the fonts generated by the c++ code are not identical with the official counterparts.

The code will get the outline of the letter, iterate over it, get two on points and one off point(bezier quadric control/end points), and calculate the resulting points using the conic bezier formula. The points are spewed on the console(debugging purpose). Using gnuplot to draw the resulting points, connecting each dot(with lines option in gnuplot).

This is the letter h and e:

http://imgur.com/JyHkZ7H,Aapr6zX

What is weird about the letter e is that the inner outline is ending in an outside point(Coes not connect with the starting point). This will result in problems when triangulating the oultine poligon.

Am i missing some option when loading/the font , loading the letter in freetype?

Bellow you can see the relevant portions of the code.

Opening the font:

FT_New_Face(ft, "OpenSans-Regular.ttf", 0, &this->face)

Creating the glyph:

FT_GlyphSlot g = this->face->glyph;

Creating face from letter:

for (p = text; *p; p++) {

    /* Try to load and render the character */
    if (FT_Load_Char(this->face, *p, FT_LOAD_RENDER))
        continue;

Iterating over the Freetype generated outline:

char       tag           = *g->outline.tags;
    int start_point = 0;
    int end_point;
    for(int current_contour = 0; current_contour < g->outline.n_contours; current_contour++){
        end_point = g->outline.contours[current_contour];
        for(int current_point = start_point; current_point <= end_point; current_point++){
            std::bitset<8>first_tags(tag);
            FT_Vector first_point = g->outline.points[current_point];
            tag++;current_point++;
            if(first_tags[0] == FT_CURVE_TAG_ON){
                std::bitset<8>second_tags(tag);
                FT_Vector second_point = g->outline.points[current_point];
                tag++;current_point++;
                if(second_tags[0] != FT_CURVE_TAG_ON){
                    std::bitset<8>third_tags(tag);
                    FT_Vector third_point = g->outline.points[current_point];
                    if(current_point-1 == end_point){
                        third_point = g->outline.points[start_point];
                    }
                    for(double t = 0; t <= 1; t+=0.01){
                        FT_Vector letter_point;
                        letter_point.x = (1-t)*(1-t)*first_point.x+2*(1-t)*t*second_point.x + t*t*third_point.x;
                        letter_point.y = (1-t)*(1-t)*first_point.y+2*(1-t)*t*second_point.y + t*t*third_point.y;
                        if(current_letter == 1){
                            std::cout << letter_point.x << " " << letter_point.y << std::endl;
                        }
                    }
                    current_point--;
                }
            }
        }
        start_point = end_point+1;
    }

Thanks.

È stato utile?

Soluzione

Accessing the tags array by key fixed most of the problems

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top