- float font_size=style->get_font()->get_default_size();
- for(vector<Line>::iterator i=lines.begin(); i!=lines.end(); ++i)
- i->width=static_cast<unsigned>(style->get_font()->get_string_width(text.substr(i->start, i->length))*font_size);
+ if(i>=lines.size())
+ throw InvalidParameterValue("Invalid line number");
+ return lines[i].length;
+}
+
+void Text::offset_to_coords(unsigned offs, unsigned &row, unsigned &col) const
+{
+ if(lines.empty())
+ {
+ row = 0;
+ col = 0;
+ return;
+ }
+
+ for(unsigned i=0; i<lines.size(); ++i)
+ if(offs>=lines[i].start && offs<=lines[i].start+lines[i].length)
+ {
+ row = i;
+ col = offs-lines[i].start;
+ return;
+ }
+}
+
+unsigned Text::coords_to_offset(unsigned row, unsigned col) const
+{
+ if(row>=lines.size())
+ return text.size();
+
+ return lines[row].start+min(col, lines[row].length);
+}
+
+Geometry Text::coords_to_geometry(unsigned row, unsigned col) const
+{
+ if(row>=lines.size())
+ row = lines.size()-1;
+ const Line &line = lines[row];
+ if(col>line.length)
+ col = line.length;
+
+ const GL::Font *font = style->get_font();
+ float font_size = font->get_default_size();
+ unsigned line_height = static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
+ unsigned line_spacing = static_cast<unsigned>(font_size*6/5);
+ unsigned height = line_height+(lines.size()-1)*line_spacing;
+ int y_offset = static_cast<int>(-font->get_descent()*font_size);
+
+ Geometry geom;
+ geom.w = line.width;
+ geom.h = height;
+ geom.x = static_cast<unsigned>(font->get_string_width(text.substr(line.start, col))*font_size);
+ geom.y = (lines.size()-1-row)*line_spacing+y_offset;
+
+ return geom;