首页 > 解决方案 > 使用 FT_Glyph_StrokeBorder 后 FT_Glyph_To_Bitmap 因 Raster_Overflow 失败

问题描述

我一直在尝试使用 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 上仍然不能工作(这个 bug 显然在 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

标签: c++cfontsfreetypefreetype2

解决方案


推荐阅读