3 This file is part of libmspgltk
4 Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #include <msp/gl/immediate.h>
9 #include <msp/gl/matrix.h>
22 Text::Text(const Style &s, const string &t):
28 void Text::set_style(const Style *s)
32 float font_size=style->get_font()->get_default_size();
33 for(vector<Line>::iterator i=lines.begin(); i!=lines.end(); ++i)
34 i->width=static_cast<unsigned>(style->get_font()->get_string_width(text.substr(i->start, i->length))*font_size);
37 unsigned Text::get_width() const
40 for(vector<Line>::const_iterator i=lines.begin(); i!=lines.end(); ++i)
41 width=max(width, i->width);
45 unsigned Text::get_height() const
47 const GL::Font *font=style->get_font();
48 float font_size=font->get_default_size();
49 unsigned line_height=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
50 unsigned line_spacing=line_height*6/5;
51 return line_height+(lines.size()-1)*line_spacing;
54 void Text::set(const string &t)
60 void Text::erase(unsigned pos, unsigned len)
64 vector<Line>::iterator i;
65 for(i=lines.begin(); (i!=lines.end() && i->start+i->length<pos); ++i) ;
67 if(pos+len>i->start+i->length)
73 for(++i; i!=lines.end(); ++i)
78 void Text::insert(unsigned pos, const string &s)
82 if(s.find('\n')!=string::npos)
86 vector<Line>::iterator i;
87 for(i=lines.begin(); (i!=lines.end() && i->start+i->length<pos); ++i) ;
91 for(++i; i!=lines.end(); ++i)
96 unsigned Text::get_line_length(unsigned i) const
99 throw InvalidParameterValue("Invalid line number");
100 return lines[i].length;
103 void Text::offset_to_coords(unsigned offs, unsigned &row, unsigned &col) const
112 for(unsigned i=0; i<lines.size(); ++i)
113 if(offs>=lines[i].start && offs<=lines[i].start+lines[i].length)
116 col=offs-lines[i].start;
121 unsigned Text::coords_to_offset(unsigned row, unsigned col) const
123 if(row>=lines.size())
126 return lines[row].start+min(col, lines[row].length);
129 Geometry Text::coords_to_geometry(unsigned row, unsigned col) const
131 if(row>=lines.size())
133 const Line &line=lines[row];
137 const GL::Font *font=style->get_font();
138 float font_size=font->get_default_size();
139 unsigned line_height=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
140 unsigned line_spacing=static_cast<unsigned>(font_size*6/5);
141 unsigned height=line_height+(lines.size()-1)*line_spacing;
142 int y_offset=static_cast<int>(-font->get_descent()*font_size);
147 geom.x=static_cast<unsigned>(font->get_string_width(text.substr(line.start, col))*font_size);
148 geom.y=(lines.size()-1-row)*line_spacing+y_offset;
153 void Text::render(const Part &part, const Geometry &geom) const
158 const GL::Font *font=style->get_font();
159 float font_size=font->get_default_size();
160 unsigned line_height=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
161 unsigned line_spacing=static_cast<unsigned>(font_size*6/5);
162 unsigned height=line_height+(lines.size()-1)*line_spacing;
163 int y_offset=static_cast<int>(-font->get_descent()*font_size);
165 const GL::Color &color=style->get_font_color();
166 GL::Immediate imm((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2));
167 imm.color(color.r, color.g, color.b);
168 for(unsigned i=0; i<lines.size(); ++i)
170 const Line &line=lines[i];
175 rgeom.y=(lines.size()-1-i)*line_spacing+y_offset;
176 part.get_alignment().apply(rgeom, geom, part.get_margin());
179 GL::translate(rgeom.x, rgeom.y, 0);
180 GL::scale_uniform(font_size);
182 font->draw_string(text.substr(line.start, line.length), imm);
188 Text &Text::operator=(const string &t)
194 void Text::find_lines()
197 float font_size=style->get_font()->get_default_size();
198 string::size_type start=0;
201 string::size_type newline=text.find('\n', start);
205 line.length=(newline==string::npos ? text.size() : newline)-start;
206 line.width=static_cast<unsigned>(style->get_font()->get_string_width(text.substr(line.start, line.length))*font_size);
207 lines.push_back(line);
209 if(newline==string::npos)