реконструкция контура свободного типа не соответствует шрифту

Ниже приведены контуры двух символов, извлеченные с использованием свободного типа и обработанные в некоторых циклах с использованием формулы квадратичной кривой Безье (с помощью обычного шрифта ttf от openans). Я не уверен, правильно ли я сделал, шрифты, сгенерированные кодом С++, не идентичны официальным аналогам.

Код получит контур буквы, переберет его, получит две точки включения и одну точку отключения (контрольные/конечные точки Безье) и вычислит полученные точки, используя коническую формулу Безье. Точки выбрасываются на консоль (цель отладки). Использование gnuplot для рисования результирующих точек, соединяющих каждую точку (с параметром линий в gnuplot).

Это буквы h и e:

http://imgur.com/JyHkZ7H,Aapr6zX

Что странно в букве e, так это то, что внутренний контур заканчивается внешней точкой (не соединяется с начальной точкой). Это приведет к проблемам при триангуляции дальнего многоугольника.

Я пропускаю какую-то опцию при загрузке/шрифте, загружая письмо в фритайпе?

Ниже вы можете увидеть соответствующие части кода.

Открытие шрифта:

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

Создание глифа:

FT_GlyphSlot g = this->face->glyph;

Создание лица из буквы:

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

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

Итерация по сгенерированному Freetype контуру:

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

Спасибо.


person Alexandru Staetu    schedule 23.03.2014    source источник
comment
tags++?! Это не указатель. Объявляйте переменные там, где вы их инициализируете (end_point). Используйте прямые линии, пока не исправите проблемы с конечной точкой. Изучите каждый бит ваших тегов и утверждайте, что все, что вы не понимаете, находится в постоянном состоянии. Создавайте журналы того, какие точечные данные вы извлекли и обработали, особенно с этой беспорядочной -- обратной итерацией и циклами, подверженными ошибкам ограждения. Напишите инварианты цикла и проверьте их.   -  person Yakk - Adam Nevraumont    schedule 23.03.2014
comment
Действительно, проблема была с операцией tag++. Доступ к массиву тегов по ключу устранил большинство проблем. Спасибо.   -  person Alexandru Staetu    schedule 24.03.2014


Ответы (1)


Доступ к массиву тегов по ключу устранил большинство проблем

person Alexandru Staetu    schedule 26.03.2014