void Font::draw_text_ellipsis(Canvas &canvas, float dest_x, float dest_y, Rectf content_box, const std::string &text, const Colorf &color) { if (impl) { FontMetrics fm = get_font_metrics(); int ascent = fm.get_ascent(); int descent = fm.get_descent(); int line_spacing = fm.get_height() + fm.get_external_leading(); std::vector<std::string> lines = StringHelp::split_text(text, "\n", false); for (std::vector<std::string>::size_type i=0; i<lines.size(); i++) { if (i == 0 || (dest_y - ascent >= content_box.top && dest_y + descent < content_box.bottom)) { Size size = get_text_size(canvas, lines[i]); if (dest_x + size.width <= content_box.right) { draw_text(canvas, dest_x, dest_y, lines[i], color); } else { Size ellipsis = get_text_size(canvas, "..."); int seek_start = 0; int seek_end = lines[i].size(); int seek_center = (seek_start + seek_end) / 2; UTF8_Reader utf8_reader(lines[i].data(), lines[i].length()); while (true) { utf8_reader.set_position(seek_center); utf8_reader.move_to_leadbyte(); if (seek_center != utf8_reader.get_position()) utf8_reader.next(); seek_center = utf8_reader.get_position(); if (seek_center == seek_end) break; utf8_reader.set_position(seek_start); utf8_reader.next(); if (utf8_reader.get_position() == seek_end) break; Size text_size = get_text_size(canvas, lines[i].substr(0, seek_center)); if (dest_x + text_size.width + ellipsis.width >= content_box.right) seek_end = seek_center; else seek_start = seek_center; seek_center = (seek_start+seek_end)/2; } draw_text(canvas, dest_x, dest_y, lines[i].substr(0, seek_center) + "...", color); } dest_y += line_spacing; } } } }
Font::Font(Canvas &canvas, const std::string &typeface_name, Sprite &sprite, const std::string &glyph_list, float spacelen, bool monospace, const FontMetrics &metrics) { FontDescription desc; desc.set_height(metrics.get_height()); FontFamily font_family(typeface_name); font_family.add(canvas, sprite, glyph_list, spacelen, monospace, metrics); impl = std::make_shared<Font_Impl>(font_family, desc); }
void Font::draw_text(Canvas &canvas, float dest_x, float dest_y, const std::string &text, const Colorf &color) { if (impl) { FontMetrics fm = get_font_metrics(); int line_spacing = fm.get_height() + fm.get_external_leading(); std::vector<std::string> lines = StringHelp::split_text(text, "\n", false); for (std::vector<std::string>::size_type i=0; i<lines.size(); i++) { impl->draw_text(canvas, dest_x, dest_y, lines[i], color); dest_y += line_spacing; } } }
int GlyphCache::get_character_index(FontEngine *font_engine, GraphicContext &gc, const std::string &text, const Point &point) { int dest_x = 0; int dest_y = 0; int character_counter = 0; FontMetrics fm = get_font_metrics(); int font_height = fm.get_height(); int font_ascent = fm.get_ascent(); int font_external_leading = fm.get_external_leading(); std::vector<std::string> lines = StringHelp::split_text(text, "\n", false); for (std::vector<std::string>::size_type i=0; i<lines.size(); i++) { int xpos = dest_x; int ypos = dest_y; std::string &textline = lines[i]; std::string::size_type string_length = textline.length(); // Scan the string UTF8_Reader reader(textline.data(), textline.length()); while(!reader.is_end()) { unsigned int glyph = reader.get_char(); std::string::size_type glyph_pos = reader.get_position(); reader.next(); Font_TextureGlyph *gptr = get_glyph(font_engine, gc, glyph); if (gptr == NULL) continue; Rect position(xpos, ypos - font_ascent, Size(gptr->increment.x, gptr->increment.y + font_height + font_external_leading)); if (position.contains(point)) { return glyph_pos + character_counter; } xpos += gptr->increment.x; ypos += gptr->increment.y; } dest_y += font_height + font_external_leading; character_counter += string_length + 1; // (Including the '\n') } return -1; // Not found }
int FontProvider_Sprite::get_character_index(GraphicContext &gc, const std::string &text, const Point &point) { int dest_x = 0; int dest_y = 0; int character_counter = 0; FontMetrics fm = get_font_metrics(); int font_height = fm.get_height(); int font_external_leading = fm.get_external_leading(); std::vector<std::string> lines = StringHelp::split_text(text, "\n", false); for (std::vector<std::string>::size_type i=0; i<lines.size(); i++) { int xpos = dest_x; int ypos = dest_y; std::string &textline = lines[i]; std::string::size_type string_length = textline.length(); // Scan the string for (std::string::size_type p = 0; p < string_length; p++) { Font_Sprite_Glyph *gptr = get_glyph(textline[p]); int glyph_width; if (gptr) { glyph_width = spr_glyphs.get_frame_size(gptr->sprite_index).width; } else { glyph_width = spacelen; } Rect position(xpos, ypos - font_height, Size(glyph_width, font_height + font_external_leading)); if (position.contains(point)) return ((int) p) + character_counter; xpos += glyph_width; } dest_y += font_height + font_external_leading; character_counter += string_length + 1; // (Including the '\n') } return -1; // Not found }