原來只是以左上對齊點,寬高各偏移描邊的厚度大小。可是這樣會出如今一些字體與背景陰影字對不齊的狀況。
字體
上面第一行:能、好、連、敗,顯示是不對的。下面一行是修正後的。spa
unsigned char* FontFreeType::getGlyphBitmap(unsigned short theChar, long &outWidth, long &outHeight, Rect &outRect,int &xAdvance) { bool invalidChar = true; unsigned char * ret = nullptr; do { if (!_fontRef) break; auto glyphIndex = FT_Get_Char_Index(_fontRef, theChar); if(!glyphIndex) break; if (_distanceFieldEnabled) { if (FT_Load_Glyph(_fontRef,glyphIndex,FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT)) break; } else { if (FT_Load_Glyph(_fontRef,glyphIndex,FT_LOAD_RENDER)) break; } outRect.origin.x = _fontRef->glyph->metrics.horiBearingX >> 6; outRect.origin.y = - (_fontRef->glyph->metrics.horiBearingY >> 6); outRect.size.width = (_fontRef->glyph->metrics.width >> 6); outRect.size.height = (_fontRef->glyph->metrics.height >> 6); xAdvance = (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6)); outWidth = _fontRef->glyph->bitmap.width; outHeight = _fontRef->glyph->bitmap.rows; ret = _fontRef->glyph->bitmap.buffer; if (_outlineSize > 0) { auto copyBitmap = new unsigned char[outWidth * outHeight]; memcpy(copyBitmap,ret,outWidth * outHeight * sizeof(unsigned char)); long bitmapWidth; long bitmapHeight; FT_BBox bbox; auto outlineBitmap = getGlyphBitmapWithOutline(theChar,bbox); if(outlineBitmap == nullptr) { ret = nullptr; delete [] copyBitmap; break; } bitmapWidth = (bbox.xMax - bbox.xMin)>>6; bitmapHeight = (bbox.yMax - bbox.yMin)>>6; //modify 糾正描邊時字體與陰影沒有對齊問題 int offsetWidth = 0; //X方向偏移 int offsetHeight = 0; //Y方向偏移 if(outRect.origin.x -(bbox.xMin >> 6) != _outlineSize) offsetWidth = outRect.origin.x -(bbox.xMin >> 6) - _outlineSize; if((bbox.yMax >> 6) + outRect.origin.y != _outlineSize) offsetHeight = (bbox.yMax >> 6) + outRect.origin.y - _outlineSize; long index; auto blendImage = new unsigned char[bitmapWidth * bitmapHeight * 2]; memset(blendImage, 0, bitmapWidth * bitmapHeight * 2); for (int x = 0; x < bitmapWidth; ++x) { for (int y = 0; y < bitmapHeight; ++y) { index = x + ( y * bitmapWidth ); blendImage[2 * index] = outlineBitmap[index]; } } long maxX = outWidth + _outlineSize; long maxY = outHeight + _outlineSize; for (int x = _outlineSize + offsetWidth; x < maxX + offsetWidth; ++x) { for (int y = _outlineSize + offsetHeight; y < maxY + offsetHeight; ++y) { index = x + ( y * bitmapWidth ); blendImage[2 * index + 1] = copyBitmap[outWidth * (y - _outlineSize - offsetHeight) + x - _outlineSize - offsetWidth]; } } outRect.origin.x = bbox.xMin >> 6; outRect.origin.y = - (bbox.yMax >> 6); xAdvance += bitmapWidth - outRect.size.width; outRect.size.width = bitmapWidth; outRect.size.height = bitmapHeight; outWidth = bitmapWidth; outHeight = bitmapHeight; delete [] outlineBitmap; delete [] copyBitmap; ret = blendImage; } invalidChar = false; } while (0); if (invalidChar) { outRect.size.width = 0; outRect.size.height = 0; xAdvance = 0; return nullptr; } else { return ret; } }