MRPT  2.0.4
gltext.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
12 // Stripped out version of libCVD gltext.cpp file, ported to OpenGL>=3
13 // 2-BSD License.
14 
15 #include "gltext.h"
16 
17 #include <mrpt/math/TPoint2D.h>
18 #include <algorithm>
19 #include <cassert>
20 #include <cmath>
21 #include <map>
22 
23 using namespace std;
24 
26 {
27 struct Point
28 {
29  float x, y;
30 };
31 
32 struct Font
33 {
34  typedef unsigned short Index;
35 
36  struct Char
37  {
41  int numTriangles; // was: GLsizei
43  float advance;
44  };
45 
50  string glyphs;
51 
52  const Char* findChar(const char c) const
53  {
54  size_t ind = glyphs.find(c);
55  if (ind == string::npos) return nullptr;
56  return characters + ind;
57  }
58 
59  float getAdvance(const char c) const
60  {
61  const Char* ch = findChar(c);
62  if (!ch) return 0;
63  return ch->advance;
64  }
65 
66  void fill(
67  const char c, std::vector<mrpt::opengl::TTriangle>& tris,
68  std::vector<mrpt::math::TPoint3Df>& lines,
69  const mrpt::math::TPoint2Df& cursor) const
70  {
71  const Char* ch = findChar(c);
72  if (!ch || !ch->numTriangles) return;
73  // triangles
74  const Point* vs = vertices + ch->vertexOffset;
75  for (int i = 0; i < ch->numTriangles / 3; i++)
76  {
77  const auto idx0 = triangles[ch->triangleOffset + i * 3 + 0];
78  const auto idx1 = triangles[ch->triangleOffset + i * 3 + 1];
79  const auto idx2 = triangles[ch->triangleOffset + i * 3 + 2];
80 
81  using P3f = mrpt::math::TPoint3Df;
82 
83  tris.emplace_back(
84  P3f(cursor.x + vs[idx0].x, cursor.y + vs[idx0].y, .0f),
85  P3f(cursor.x + vs[idx1].x, cursor.y + vs[idx1].y, .0f),
86  P3f(cursor.x + vs[idx2].x, cursor.y + vs[idx2].y, .0f));
87  }
88  }
89 
90  void outline(
91  const char c, std::vector<mrpt::opengl::TTriangle>& tris,
92  std::vector<mrpt::math::TPoint3Df>& lines,
93  const mrpt::math::TPoint2Df& cursor) const
94  {
95  const Char* ch = findChar(c);
96  if (!ch || !ch->numOutlines) return;
97  // lines
98  const Point* vs = vertices + ch->vertexOffset;
99  for (int i = 0; i < ch->numOutlines / 2; i++)
100  {
101  const auto idx0 = outlines[ch->outlineOffset + i * 2 + 0];
102  const auto idx1 = outlines[ch->outlineOffset + i * 2 + 1];
103 
104  lines.emplace_back(
105  cursor.x + vs[idx0].x, cursor.y + vs[idx0].y, .0f);
106  lines.emplace_back(
107  cursor.x + vs[idx1].x, cursor.y + vs[idx1].y, .0f);
108  }
109  }
110 
111  void draw(
112  const char c, std::vector<mrpt::opengl::TTriangle>& tris,
113  std::vector<mrpt::math::TPoint3Df>& lines,
114  const mrpt::math::TPoint2Df& cursor) const
115  {
116  outline(c, tris, lines, cursor);
117  fill(c, tris, lines, cursor);
118  }
119 };
120 
121 // the fonts defined in these headers are derived from Bitstream Vera fonts. See
122 // http://www.gnome.org/fonts/ for license and details
123 #include "glfont_mono.h"
124 #include "glfont_sans.h"
125 #include "glfont_serif.h"
126 
127 struct FontData
128 {
129  typedef map<string, Font*> FontMap;
130 
132  {
133  fonts["sans"] = &sans_font;
134  fonts["mono"] = &mono_font;
135  fonts["serif"] = &serif_font;
136  glSetFont("sans");
137  }
138  inline Font* currentFont() { return fonts[currentFontName]; }
139 
142 };
143 
144 static struct FontData data;
145 
146 void glSetFont(const std::string& fontname)
147 {
148  if (data.fonts.count(fontname) > 0) data.currentFontName = fontname;
149 }
150 
151 const std::string& glGetFont() { return data.currentFontName; }
152 
153 std::pair<double, double> glDrawText(
154  const std::string& text, std::vector<mrpt::opengl::TTriangle>& tris,
155  std::vector<mrpt::math::TPoint3Df>& render_lines, TEXT_STYLE style,
156  double spacing, double kerning)
157 {
158  // Was: glPushMatrix();
159  mrpt::math::TPoint2Df cursor = {0, 0};
160 
161  // figure out which operation to do on the Char (yes, this is a pointer to
162  // member function :)
163  void (Font::*operation)(
164  const char c, std::vector<mrpt::opengl::TTriangle>& tris,
165  std::vector<mrpt::math::TPoint3Df>& lines,
166  const mrpt::math::TPoint2Df& cursor) const;
167  switch (style)
168  {
169  case FILL:
170  operation = &Font::fill;
171  break;
172  case OUTLINE:
173  operation = &Font::outline;
174  break;
175  case NICE:
176  // operation = &Font::draw; (See comments in definition of "NICE")
177  operation = &Font::fill;
178  break;
179 
180  default:
181  THROW_EXCEPTION("Invalid style value");
182  };
183 
184  int lines = 0;
185  double max_total = 0;
186  double total = 0;
187  const Font* font = data.currentFont();
188  const Font::Char* space = font->findChar(' ');
189  const double tab_width = 8 * ((space) ? (space->advance) : 1);
190  for (size_t i = 0; i < text.length(); ++i)
191  {
192  char c = text[i];
193  if (c == '\n')
194  {
195  cursor.x -= total;
196  cursor.y -= spacing;
197 
198  max_total = std::max(max_total, total);
199  total = 0;
200  ++lines;
201  continue;
202  }
203  if (c == '\t')
204  {
205  const float advance = tab_width - std::fmod(total, tab_width);
206  total += advance;
207  cursor.x += advance;
208  continue;
209  }
210  const Font::Char* ch = font->findChar(c);
211  if (!ch)
212  {
213  c = toupper(c);
214  ch = font->findChar(c);
215  if (!ch)
216  {
217  c = '?';
218  ch = font->findChar(c);
219  }
220  }
221  if (!ch) continue;
222  (font->*operation)(c, tris, render_lines, cursor);
223 
224  double w = ch->advance + kerning;
225  cursor.x += w;
226  total += w;
227  }
228 
229  max_total = std::max(total, max_total);
230  return std::make_pair(max_total, (lines + 1) * spacing);
231 }
232 
233 std::pair<double, double> glGetExtends(
234  const std::string& text, double spacing, double kerning)
235 {
236  int lines = 0;
237  double max_total = 0;
238  double total = 0;
239  const Font* font = data.currentFont();
240  for (size_t i = 0; i < text.length(); ++i)
241  {
242  char c = text[i];
243  if (c == '\n')
244  {
245  max_total = std::max(max_total, total);
246  total = 0;
247  ++lines;
248  continue;
249  }
250  const Font::Char* ch = font->findChar(c);
251  if (!ch)
252  {
253  c = toupper(c);
254  ch = font->findChar(c);
255  if (!ch)
256  {
257  c = '?';
258  ch = font->findChar(c);
259  }
260  }
261  if (!ch) continue;
262  total += ch->advance + kerning;
263  }
264  max_total = std::max(total, max_total);
265  return std::make_pair(max_total, (lines + 1) * spacing);
266 }
267 
269  const std::string& text, std::vector<mrpt::opengl::TTriangle>& tris,
270  std::vector<mrpt::math::TPoint3Df>& lines,
271  std::vector<mrpt::img::TColor>& line_colors,
272  const mrpt::poses::CPose3D& text_pose, float text_scale,
273  const mrpt::img::TColor& text_color, TEXT_STYLE style, double spacing,
274  double kerning)
275 {
276  // Raw text primitives:
277  std::vector<mrpt::opengl::TTriangle> new_tris;
278  std::vector<mrpt::math::TPoint3Df> new_lines;
279  glDrawText(text, new_tris, new_lines, style, spacing, kerning);
280 
281  // Transform triangles:
282  for (auto& t : new_tris)
283  {
284  t.setColor(text_color);
285 
286  for (int i = 0; i < 3; i++)
287  {
288  text_pose.rotateVector(t.vertices[i].normal);
289  t.vertices[i].xyzrgba.pt =
290  text_pose.composePoint(t.vertices[i].xyzrgba.pt * text_scale);
291  }
292  t.computeNormals();
293  tris.emplace_back(t);
294  }
295 
296  // Transform line vertices:
297  for (auto& v : new_lines)
298  {
299  lines.emplace_back(text_pose.composePoint(v * text_scale));
300  line_colors.emplace_back(text_color);
301  }
302 }
303 
304 } // namespace mrpt::opengl::internal
const std::string & glGetFont()
returns the name of the currently active font
Definition: gltext.cpp:151
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
T x
X,Y coordinates.
Definition: TPoint2D.h:25
std::pair< double, double > glGetExtends(const std::string &text, double spacing, double kerning)
returns the size of the bounding box of a text to be rendered, similar to glDrawText but without any ...
Definition: gltext.cpp:233
Font mono_font
Definition: glfont_mono.h:2648
void fill(const char c, std::vector< mrpt::opengl::TTriangle > &tris, std::vector< mrpt::math::TPoint3Df > &lines, const mrpt::math::TPoint2Df &cursor) const
Definition: gltext.cpp:66
void outline(const char c, std::vector< mrpt::opengl::TTriangle > &tris, std::vector< mrpt::math::TPoint3Df > &lines, const mrpt::math::TPoint2Df &cursor) const
Definition: gltext.cpp:90
STL namespace.
void glDrawTextTransformed(const std::string &text, std::vector< mrpt::opengl::TTriangle > &tris, std::vector< mrpt::math::TPoint3Df > &lines, std::vector< mrpt::img::TColor > &line_colors, const mrpt::poses::CPose3D &text_pose, float text_scale, const mrpt::img::TColor &text_color, TEXT_STYLE style, double spacing, double kerning)
Appends to {tris,lines} the entities representing a given text including a pose and scale transformat...
Definition: gltext.cpp:268
renders glyphs as outlines with GL_LINES
Definition: opengl_fonts.h:22
mrpt::math::TVector3D rotateVector(const mrpt::math::TVector3D &local) const
Rotates a vector (i.e.
Definition: CPose3D.cpp:460
map< string, Font * > FontMap
Definition: gltext.cpp:129
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:19
Base template for TPoint2D and TPoint2Df.
Definition: TPoint2D.h:32
std::pair< double, double > glDrawText(const std::string &text, std::vector< mrpt::opengl::TTriangle > &tris, std::vector< mrpt::math::TPoint3Df > &render_lines, TEXT_STYLE style, double spacing, double kerning)
renders a string in GL using the current settings.
Definition: gltext.cpp:153
unsigned short Index
Definition: gltext.cpp:34
float getAdvance(const char c) const
Definition: gltext.cpp:59
Font sans_font
Definition: glfont_sans.h:2586
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:85
void glSetFont(const std::string &fontname)
sets the font to use for future font rendering commands.
Definition: gltext.cpp:146
This was "renders glyphs filled with antialiased outlines", but since antialiased is not properly imp...
Definition: opengl_fonts.h:27
const Char * findChar(const char c) const
Definition: gltext.cpp:52
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::optional_ref< mrpt::math::CMatrixDouble33 > out_jacobian_df_dpoint=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dpose=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dse3=std::nullopt, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
TPoint3D_< float > TPoint3Df
Definition: TPoint3D.h:269
A RGB color - 8bit.
Definition: TColor.h:25
void draw(const char c, std::vector< mrpt::opengl::TTriangle > &tris, std::vector< mrpt::math::TPoint3Df > &lines, const mrpt::math::TPoint2Df &cursor) const
Definition: gltext.cpp:111
renders glyphs as filled polygons
Definition: opengl_fonts.h:21
Font serif_font
static struct FontData data
Definition: gltext.cpp:144



Page generated by Doxygen 1.8.14 for MRPT 2.0.4 Git: 7b5ddf9de Fri May 29 14:02:56 2020 +0200 at vie may 29 14:15:09 CEST 2020