FT_Glyph_To_Bitmap завершается с ошибкой Raster_Overflow после использования FT_Glyph_StrokeBorder - PullRequest
1 голос
/ 25 января 2020

Я пытался получить эффект обводки моего текста, используя freetype2. Я попытался использовать некоторые примеры использования FT_Glyph_StrokeBorder, однако всякий раз, когда я вызываю FT_Glyph_To_Bitmap (после поглаживания), возвращается код ошибки Raster_Overflow (98) или Array_too_large (10) - это зависит от символа ( возможно).

Я не могу найти много о том, что означают эти коды ошибок или что мне нужно сделать, чтобы исправить их.

Рисование символа - не удается на FT_Glyph_To_Bitmap (если штрих включено):

void drawGlyph(
  FT_GlyphSlot& glyphSlot,
  cimg_t& image,
  int shiftX,
  int shiftY,
  unsigned char fontColor[] = NULL,
  FT_Stroker stroker = nullptr,
  unsigned char strokeColor[] = NULL
){
  shiftY -= tfpos2int(glyphSlot->metrics.horiBearingY);
  if (stroker != nullptr) {
    FT_Glyph glyph;
    FT_Get_Glyph(glyphSlot, &glyph);
    if (glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
      puts("Can't stroke!"); // not printed
      return;
    }
    if (FT_Glyph_StrokeBorder(&glyph, stroker, false, true) != 0) {
      puts("Stroke failed!"); // not printed
      return;
    }
    if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, nullptr, true) != 0) {
      puts("Bitmap failed!"); // printed
      return;
    }
    FT_BitmapGlyph bitmapGlyph = reinterpret_cast<FT_BitmapGlyph>(glyph);
    drawBitmap(bitmapGlyph->bitmap, image, shiftX, shiftY, strokeColor);
    FT_Done_Glyph(glyph);
  }
  // Drawing glyph without stroke works fine
  if (FT_Render_Glyph(glyphSlot, FT_RENDER_MODE_NORMAL) != 0) {
    return;
  }
  drawBitmap(glyphSlot->bitmap, image, shiftX, shiftY, fontColor);
}

Загрузка символа:

  FT_Set_Pixel_Sizes(face, 0, heightText);
  FT_GlyphSlot glyphSlot = face->glyph;

  int shiftX = leftTopX;
  int shiftY = 0;
  for(int numberSymbol = 0; numberSymbol < text.length(); ++numberSymbol){
    shiftY = leftTopY;

    bool isSpace = false;
    FT_ULong symbol = text[numberSymbol];
    if (FT_Load_Char(face, symbol, FT_LOAD_DEFAULT) != 0) {
     /* handle error */
     return;
    }

    // call drawGlyph()...

Редактировать:

Похоже, что это может быть ошибка в freetype2 https://savannah.nongnu.org/bugs/?54986

- этот код по-прежнему не работает на 2.10.1 (и эта ошибка, видимо, была исправлена ​​в 2.10).

Буду очень признателен, если кто-нибудь были какие-либо идеи - я понятия не имею, как отладить это.

Я использую этот (Unicode) шрифт: https://github.com/MacDue/DueUtil/raw/master/assets/fonts/Due_Robo.ttf

Обновление 1 : В текущей версии (2.10.1) код ошибки 0x62, что означает Raster_Overflow.

Обновление 2:

Примечания к документации:

Добавление инсульта может привести к значительным Значительно шире и выше глиф в зависимости от того, какой большой радиус был использован для обводки глифа. Возможно, вам придется вручную отрегулировать суммы авансов по горизонтали и вертикали, чтобы учесть этот добавленный размер.

Я оглянулся и предположил, что это должно относиться к свойству аванса FT_Glyph. Который является FT_Vector (для ширины и высоты), который является числом с фиксированной точкой 16,16. Так как я пытаюсь установить границу в 2 пикселя, я попытался увеличить их на 4 (чтобы немного ослабить).

glyph->advance.x += (4 << 16);
glyph->advance.y += (4 << 16);

Тем не менее, вызов FT_Glyph_To_Bitmap не удался.

Обновление 3: Похоже, что имеется целочисленное переполнение (или, возможно, там, где генерируется контур) ft_glyphslot_preset_bitmap (вызывается в средстве визуализации), когда он вызывает FT_Outline_Get_CBox, в результате ограничивающий прямоугольник является мусором.

...