void TTFRenderer::getFaceMetrics(int &advance, int &yOffset, int &xMin) const { FT_Glyph_Metrics &metrics = _face->glyph->metrics; xMin = ftFloor26_6(metrics.horiBearingX); yOffset = _ascent - ftFloor26_6(metrics.horiBearingY); advance = ftCeil26_6(metrics.horiAdvance); }
bool TrueTypeFont::renderGlyph(uint32 unicode, Glyph &glyph) { uint32 index = FT_Get_Char_Index(_sjisFont, unicode); if (!index) return false; FT_Error err = FT_Load_Glyph(_sjisFont, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING); if (err) return false; err = FT_Render_Glyph(_sjisFont->glyph, FT_RENDER_MODE_MONO); if (err) return false; FT_Glyph_Metrics &metrics = _sjisFont->glyph->metrics; glyph.xOffset = ftFloor26_6(metrics.horiBearingX); glyph.yOffset = _ascent - ftFloor26_6(metrics.horiBearingY); // In case we got a negative xMin we adjust that, this might make some // characters give a odd layout though. if (glyph.xOffset < 0) glyph.xOffset = 0; const FT_Bitmap &bitmap = _sjisFont->glyph->bitmap; glyph.height = bitmap.rows; glyph.width = bitmap.width; glyph.pitch = bitmap.pitch; glyph.plainData = 0; // We only accept monochrome characters. if (bitmap.pixel_mode != FT_PIXEL_MODE_MONO) return false; if (glyph.height) { glyph.plainData = new uint8[glyph.height * abs(glyph.pitch)]; if (!glyph.plainData) return false; const uint8 *src = bitmap.buffer; uint8 *dst = glyph.plainData; if (glyph.pitch < 0) dst += (glyph.height - 1) * (-glyph.pitch); for (int i = 0; i < bitmap.rows; ++i) { memcpy(dst, src, abs(glyph.pitch)); src += bitmap.pitch; dst += glyph.pitch; } } glyph.pitch = abs(glyph.pitch); return true; }
void TTFRenderer::getFaceMetrics(int &advance, int &yOffset, int &xMin) const { FT_Glyph_Metrics &metrics = _face->glyph->metrics; xMin = ftFloor26_6(metrics.horiBearingX); int xMax = xMin + ftCeil26_6(metrics.width); yOffset = _ascent - ftFloor26_6(metrics.horiBearingY); advance = ftCeil26_6(metrics.horiAdvance); // In case we got a negative xMin we adjust that, this might make some // characters look a bit odd, but it's the only way we can ensure no // invalid memory gets written to with the current font API if (xMin < 0) { xMax -= xMin; xMin = 0; if (xMax > advance) advance = xMax; } }