void font::measure(string const &text, rectangle &bounds) const { float x = 0.0f; float y = 0.0f; if (text.size() == 0) return; //y += m_common.base; for (size_t i = 0; i < text.size(); ++i) { char c = text[i]; unsigned char uc = static_cast<unsigned char>(c); ft_char const &font_char = m_chars_256[uc]; if (font_char.width == 0) continue; float a = static_cast<float>(font_char.xadvance); float w = static_cast<float>(font_char.width); float h = static_cast<float>(font_char.height); float ox = static_cast<float>(font_char.xoffset); float oy = static_cast<float>(font_char.yoffset); bounds.extend_by(x + ox, y + oy); bounds.extend_by(x + w + ox, y + oy); bounds.extend_by(x + w + ox, y + h + oy); bounds.extend_by(x + ox, y + h + oy); x += a; x += m_spacing_delta; if (i + 1 < text.size() - 1) { char next = text[i + 1]; kerning search_key(static_cast<unsigned short>(next)); compare_kerning cmp; auto j = std::lower_bound( font_char.kernings.cbegin(), font_char.kernings.cend(), search_key, cmp ); if (j != font_char.kernings.cend()) { kerning const &k = *j; x += static_cast<float>(k.amount); } } } }
size_t font::print(string const &text, rectangle &bounds, float *&ptr, float x, float y, std::size_t max_chars) const { slog_trace("font::print(ptr = %p, text = %s, x = % 7.2, y = % 7.2)", ptr, text.c_str(), x, y); if (text.size() == 0) return 0; size_t chars_printed = 0; for (size_t i = 0; i < text.size(); ++i) { char c = text[i]; unsigned char uc = static_cast<unsigned char>(c); ft_char const &font_char = m_chars_256[uc]; float a = static_cast<float>(font_char.xadvance); if (font_char.width != 0) { float w = static_cast<float>(font_char.width); float h = static_cast<float>(font_char.height); float ox = static_cast<float>(font_char.xoffset); float oy = static_cast<float>(font_char.yoffset); #if 0 glTexCoord2f(font_char.u[0], font_char.v[0]); glVertex2f(x + ox, y + oy); glTexCoord2f(font_char.u[1], font_char.v[1]); glVertex2f(x + ox + w, y + oy); glTexCoord2f(font_char.u[2], font_char.v[2]); glVertex2f(x + ox + w, y + oy + h); glTexCoord2f(font_char.u[0], font_char.v[0]); glVertex2f(x + ox, y + oy); glTexCoord2f(font_char.u[2], font_char.v[2]); glVertex2f(x + ox + w, y + oy + h); glTexCoord2f(font_char.u[3], font_char.v[3]); glVertex2f(x + ox, y + oy + h); #else *ptr++ = x + ox; *ptr++ = y + oy; *ptr++ = font_char.u[0]; *ptr++ = font_char.v[0]; *ptr++ = x + ox + w; *ptr++ = y + oy; *ptr++ = font_char.u[1]; *ptr++ = font_char.v[1]; *ptr++ = x + ox + w; *ptr++ = y + oy + h; *ptr++ = font_char.u[2]; *ptr++ = font_char.v[2]; *ptr++ = x + ox; *ptr++ = y + oy + h; *ptr++ = font_char.u[3]; *ptr++ = font_char.v[3]; #endif bounds.extend_by(x + ox , y + oy); bounds.extend_by(x + ox + w, y + oy); bounds.extend_by(x + ox + w, y + oy + h); bounds.extend_by(x + ox , y + oy + h); ++chars_printed; if (chars_printed == max_chars) break; } x += a; x += m_spacing_delta; if (i + 1 < text.size()) { char next = text[i + 1]; kerning search_key(static_cast<unsigned short>(next)); compare_kerning cmp; vector<kerning>::const_iterator j = std::lower_bound( font_char.kernings.cbegin(), font_char.kernings.cend(), search_key, cmp ); if (j != font_char.kernings.cend()) { kerning const &k = *j; x += (float)(k.amount); } } } return chars_printed; }