void FallbackFontRenderer::Draw(uint32_t unicode, spades::Vector2 offset, float size, spades::Vector4 color) { renderer->SetColorAlphaPremultiplied(color); float x = offset.x; float y = offset.y; auto glyph = FindGlyph(unicode); if(glyph.img == nullptr) { // no glyph found! draw box in the last resort IImage *img = whiteImage; renderer->DrawImage(img, AABB2(x, y, size, 1.f)); renderer->DrawImage(img, AABB2(x, y + size - 1.f, size, 1.f)); renderer->DrawImage(img, AABB2(x, y + 1.f, 1.f, size - 2.f)); renderer->DrawImage(img, AABB2(x + size - 1.f, y + 1.f, 1.f, size - 2.f)); return; } if(glyph.w == 0) { // null glyph. return; } float scale = size * glyph.sizeInverse; if(roundSize || scale < 1.f) { float newScale = std::max(1.f, floorf(scale)); // vertical-align: baseline offset.y += (scale - newScale) * glyph.size; scale = newScale; } AABB2 inRect(glyph.x, glyph.y, glyph.w, glyph.h); AABB2 outRect(glyph.offX, glyph.offY, glyph.w, glyph.h); // margin to make the border completely transparent // (considering the OpenGL's linear interpolation) if(!roundSize){ inRect.min.x -= 0.5f; inRect.min.y -= 0.5f; outRect.min.x -= 0.5f; outRect.min.y -= 0.5f; inRect.max.x += 0.5f; inRect.max.y += 0.5f; outRect.max.x += 0.5f; outRect.max.y += 0.5f; } outRect.min *= scale; outRect.max *= scale; outRect.min += offset; outRect.max += offset; renderer->DrawImage(glyph.img, outRect, inRect); }