int TTFFont::getKerningOffset(uint32 left, uint32 right) const { if (!_hasKerning) return 0; assureCached(left); assureCached(right); FT_UInt leftGlyph, rightGlyph; GlyphCache::const_iterator glyphEntry; glyphEntry = _glyphs.find(left); if (glyphEntry != _glyphs.end()) { leftGlyph = glyphEntry->_value.slot; } else { return 0; } glyphEntry = _glyphs.find(right); if (glyphEntry != _glyphs.end()) { rightGlyph = glyphEntry->_value.slot; } else { return 0; } if (!leftGlyph || !rightGlyph) return 0; FT_Vector kerningVector; FT_Get_Kerning(_face, leftGlyph, rightGlyph, FT_KERNING_DEFAULT, &kerningVector); return (kerningVector.x / 64); }
int TTFFont::getCharWidth(byte chr) const { GlyphCache::const_iterator glyphEntry = _glyphs.find(chr); if (glyphEntry == _glyphs.end()) return 0; else return glyphEntry->_value.advance; }
Common::Rect TTFFont::getBoundingBox(uint32 chr) const { assureCached(chr); GlyphCache::const_iterator glyphEntry = _glyphs.find(chr); if (glyphEntry == _glyphs.end()) { return Common::Rect(); } else { const int xOffset = glyphEntry->_value.xOffset; const int yOffset = glyphEntry->_value.yOffset; const Graphics::Surface &image = glyphEntry->_value.image; return Common::Rect(xOffset, yOffset, xOffset + image.w, yOffset + image.h); } }
void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const { GlyphCache::const_iterator glyphEntry = _glyphs.find(chr); if (glyphEntry == _glyphs.end()) return; const Glyph &glyph = glyphEntry->_value; x += glyph.xOffset; y += glyph.yOffset; if (x > dst->w) return; if (y > dst->h) return; int w = glyph.image.w; int h = glyph.image.h; const uint8 *srcPos = (const uint8 *)glyph.image.getBasePtr(0, 0); // Make sure we are not drawing outside the screen bounds if (x < 0) { srcPos -= x; w += x; x = 0; } if (x + w > dst->w) w = dst->w - x; if (w <= 0) return; if (y < 0) { srcPos -= y * glyph.image.pitch; h += y; y = 0; } if (y + h > dst->h) h = dst->h - y; if (h <= 0) return; uint8 *dstPos = (uint8 *)dst->getBasePtr(x, y); if (dst->format.bytesPerPixel == 1) { for (int cy = 0; cy < h; ++cy) { uint8 *rDst = dstPos; const uint8 *src = srcPos; for (int cx = 0; cx < w; ++cx) { // We assume a 1Bpp mode is a color indexed mode, thus we can // not take advantage of anti-aliasing here. if (*src >= 0x80) *rDst = color; ++rDst; ++src; } dstPos += dst->pitch; srcPos += glyph.image.pitch; } } else if (dst->format.bytesPerPixel == 2) { renderGlyph<uint16>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format); } else if (dst->format.bytesPerPixel == 4) { renderGlyph<uint32>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format); } }