Обрезание текста PangoCairo при использовании PANGO_ALIGN_MIDDLE

В игре на C++ мы используем Pango для рендеринга текста с помощью cairo и оттуда в текстуру OpenGL. Недавно я заметил эту проблему, работая над реализацией переноса текста через Pango.

Что я делаю, так это вычисляю ширину, переводя нашу собственную систему координат в пиксели, а затем используя ее как часть ширины окна в PANGO UNITS или в коде:

        float screenEdge = _w * m * static_cast<float>(PANGO_SCALE);
        float tempMaxWidth = _owner->m_wrapping.m_maxWidth;
        tempMaxWidth = std::min(_owner->m_wrapping.m_maxWidth, (0.48f - _owner->dimensions().x1()));
        float wrapWidth = screenEdge * tempMaxWidth;
        maxWidth = static_cast<int>(std::round(wrapWidth));
        pango_layout_set_width(_owner->m_pangoLayout.get(), maxWidth);

Затем мы получаем прямоугольник из макета и передаем его в cairo с помощью:

        float border = 2.0f;
        PangoRectangle lRec;
        pango_layout_get_pixel_extents(_owner->m_pangoLayout.get(), nullptr, &lRec);
        m_width = (lRec.width + border);  // Add twice half a border for margins
        m_height = (lRec.height + border);
    std::unique_ptr<cairo_surface_t, decltype(&cairo_surface_destroy)> m_cairoSurface(
      cairo_image_surface_create(CAIRO_FORMAT_ARGB32, m_width, m_height),
      &cairo_surface_destroy);
    std::unique_ptr<cairo_t, decltype(&cairo_destroy)> m_cairoDc(
      cairo_create(m_cairoSurface.get()),
      &cairo_destroy);
    cairo_set_antialias(m_cairoDc.get(), CAIRO_ANTIALIAS_FAST);
    cairo_push_group_with_content (m_cairoDc.get(), CAIRO_CONTENT_COLOR_ALPHA);
    cairo_set_operator(m_cairoDc.get(), CAIRO_OPERATOR_SOURCE);
    // Add Pango line and path to proper position on the DC
    cairo_move_to(m_cairoDc.get(), (0.5f * border), (0.5f * border));  // Margins needed for border stroke to fit in

Но вывод, как вы можете видеть ниже, обрезан; этого не произойдет, если я использую PANGO_ALIGN_LEFT Поиск здесь, я нашел макет Cairo + Pango не- выравнивание по левому краю

Что кажется связанным с моей проблемой, но не совсем дает решение (или я не понял его должным образом); я попытался вычислить разницу между координатами x и y логического и чернильного прямоугольников и добавить это к cairo_move_to, но это не имело реальной разницы в выводе, поэтому я просто вставил сюда исходный код.

Вывод текстуры (должна быть выполнена загрузка! Загружено 24 песни.)


person Gregorio Litenstein    schedule 17.12.2020    source источник
comment
У вас случайно нет небольшой автономной программы-примера для экспериментов, верно? Все, что я могу догадаться из вашего примера кода, это то, что m_width и m_maxWidth не согласуются друг с другом, но я не могу понять математику здесь, извините.   -  person Uli Schlachter    schedule 18.12.2020
comment
Я не знаю, но на самом деле я думаю, что, возможно, нашел проблему (ы); 1) Моя математика была неправильной при вычитании смещений, но также был какой-то старый код, о котором я забыл, для некоторого самодельного выравнивания, манипулируя размещением текстуры напрямую, поэтому выровненный по центру текст фактически отображался, как будто выровненный по правому краю.   -  person Gregorio Litenstein    schedule 18.12.2020