Main MRPT website > C++ reference for MRPT 1.9.9
CCanvas.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/utils/CCanvas.h>
13 #include <mrpt/system/os.h>
14 #include <mrpt/utils/CImage.h>
18 #include <mrpt/utils/round.h>
19 
20 #include <mrpt/compress/zip.h>
21 #include <map>
22 
23 // Include the MRPT bitmap fonts:
24 #include "mrpt_font_5x7.h"
25 #include "mrpt_font_6x13.h"
26 #include "mrpt_font_6x13B.h"
27 #include "mrpt_font_6x13O.h"
28 #include "mrpt_font_9x15.h"
29 #include "mrpt_font_9x15B.h"
30 #include "mrpt_font_10x20.h"
31 
32 // Japanese fonts?
33 #if MRPT_HAS_ASIAN_FONTS
34 #include "mrpt_font_18x18ja.h"
35 #endif
36 
37 // Each font has a block a data with this header (It's actually zip-compressed
38 // since mrpt >0.6.5)
39 // const uint32_t mrpt_font_9x15B [] = {
40 // 9,15, /* width, height */
41 // 0x0000,0x00FF, /* UNICODE characters range: */
42 
43 using namespace mrpt;
44 using namespace mrpt::utils;
45 using namespace std;
46 
47 // map<string,const uint32_t*> list_registered_fonts;
48 map<string, vector_byte> list_registered_fonts; // Each vector is the target
49 // place where to uncompress
50 // each font.
51 bool list_fonts_init = false;
52 
54 {
55  if (!list_fonts_init)
56  {
57  list_registered_fonts.clear();
58 
59 // This was used only once
60 #if 0
61 #define SAVE_COMPRESSED(ARR) \
62  { \
63  list_registered_fonts[#ARR].resize(sizeof(mrpt_font_##ARR)); \
64  memcpy( \
65  &list_registered_fonts[#ARR][0], mrpt_font_##ARR, \
66  sizeof(mrpt_font_##ARR)); \
67  cout << #ARR << " -> " << sizeof(mrpt_font_##ARR) << endl; \
68  CFileGZOutputStream f( \
69  string("mrpt_font_") + string(#ARR) + string(".gz")); \
70  f.WriteBuffer(mrpt_font_##ARR, sizeof(mrpt_font_##ARR)); \
71  /*mrpt::compress::zip::compress( list_registered_fonts[#ARR], f ); */ \
72  }
73 
74  SAVE_COMPRESSED(5x7)
75 // SAVE_COMPRESSED(6x13)
76 // SAVE_COMPRESSED(6x13B)
77 // SAVE_COMPRESSED(6x13O)
78 // SAVE_COMPRESSED(9x15)
79 // SAVE_COMPRESSED(9x15B)
80 // SAVE_COMPRESSED(10x20)
81 
82 #if MRPT_HAS_ASIAN_FONTS
83 // SAVE_COMPRESSED(18x18ja)
84 #endif
85 
86 #endif
87 
88 #if 1 // Normal operation: Load fonts and uncompress them:
89 
90 #define LOAD_FONT(FONTNAME) \
91  { \
92  vector_byte tmpBuf(sizeof(mrpt_font_gz_##FONTNAME)); \
93  memcpy( \
94  &tmpBuf[0], mrpt_font_gz_##FONTNAME, \
95  sizeof(mrpt_font_gz_##FONTNAME)); \
96  mrpt::compress::zip::decompress_gz_data_block( \
97  tmpBuf, list_registered_fonts[#FONTNAME]); \
98  }
99 
100  LOAD_FONT(5x7)
101  LOAD_FONT(6x13)
102  LOAD_FONT(6x13B)
103  LOAD_FONT(6x13O)
104  LOAD_FONT(9x15)
105  LOAD_FONT(9x15B)
106  LOAD_FONT(10x20)
107 #if MRPT_HAS_ASIAN_FONTS
108  LOAD_FONT(18x18ja)
109 #endif
110 
111 #endif
112 
113  list_fonts_init = true;
114  }
115 }
116 
117 /*---------------------------------------------------------------
118  Constructor
119 ---------------------------------------------------------------*/
120 CCanvas::CCanvas() : m_selectedFont("9x15"), m_selectedFontBitmaps(nullptr) {}
121 /*---------------------------------------------------------------
122  line
123 ---------------------------------------------------------------*/
125  int x0, int y0, int x1, int y1, const mrpt::utils::TColor color,
126  unsigned int width, TPenStyle penStyle)
127 {
129  MRPT_UNUSED_PARAM(penStyle);
130 
131  /* // JL: worthy annoying so much?
132  static bool warningFirst = true;
133  if (warningFirst)
134  {
135  warningFirst=false;
136  printf("[CCanvas::line] WARNING: Using default drawing method,
137  ignoring 'width' and 'penStyle'!!\n");
138  }*/
139 
140  float x, y;
141 
142  float Ax = (float)(x1 - x0);
143  float Ay = (float)(y1 - y0);
144 
145  // In this cases, there is nothing to do!
146  if (Ax == 0 && Ay == 0) return;
147  if (x0 < 0 && x1 < 0) return;
148  if (y0 < 0 && y1 < 0) return;
149  if (x0 >= (int)getWidth() && x1 >= (int)getWidth()) return;
150  if (y0 >= (int)getHeight() && y1 >= (int)getHeight()) return;
151 
152  float dist = sqrt(square(Ax) + square(Ay));
153  int i, N = (int)ceil(dist);
154 
155  // The N steps to perform next:
156  Ax /= N;
157  Ay /= N;
158  x = (float)x0;
159  y = (float)y0;
160 
161  for (i = 0; i < N; i++)
162  {
163  x += Ax;
164  y += Ay;
165  setPixel((int)x, (int)y, color);
166  } // end for i
167 }
168 
169 /*---------------------------------------------------------------
170  rectangle
171 ---------------------------------------------------------------*/
173  int x0, int y0, int x1, int y1, const mrpt::utils::TColor color,
174  unsigned int width)
175 {
176  int w_min = (int)-ceil(((float)width) / 2);
177  int w_max = (int)floor(((float)width) / 2);
178  // Draw "width" rectangles one into another:
179  for (int w = w_min; w <= w_max; w++)
180  {
181  line(x0 - w, y0 - w, x1 + w, y0 - w, color);
182  line(x1 + w, y0 - w, x1 + w, y1 + w, color);
183  line(x1 + w, y1 + w, x0 - w, y1 + w, color);
184  line(x0 - w, y1 + w, x0 - w, y0 - w, color);
185  } // end for "w"
186 }
187 
188 /*****************************************************AJOGD***************************************************/
189 /*---------------------------------------------------------------
190  triangle
191 ---------------------------------------------------------------*/
193  int x0, int y0, int size, const mrpt::utils::TColor color, bool inferior,
194  unsigned int width)
195 {
196  int ts = round(0.866 * size);
197  int tc = round(0.5 * size);
198  if (inferior)
199  {
200  line(x0, y0 + size, x0 + ts, y0 - tc, color, width);
201  line(x0, y0 + size, x0 - ts, y0 - tc, color, width);
202  line(x0 + ts, y0 - tc, x0 - ts, y0 - tc, color, width);
203  }
204  else
205  {
206  line(x0, y0 - size, x0 + ts, y0 + tc, color, width);
207  line(x0, y0 - size, x0 - ts, y0 + tc, color, width);
208  line(x0 + ts, y0 + tc, x0 - ts, y0 + tc, color, width);
209  }
210 }
211 /************************************************************************************************************/
212 
213 /*---------------------------------------------------------------
214  filledRectangle
215 ---------------------------------------------------------------*/
217  int x0, int y0, int x1, int y1, const mrpt::utils::TColor color)
218 {
219  int x_min = max(x0, 0);
220  int x_max = min(x1, (int)getWidth() - 1);
221  int y_min = max(y0, 0);
222  int y_max = min(y1, (int)getHeight() - 1);
223 
224  for (int y = y_min; y <= y_max; y++)
225  for (int x = x_min; x <= x_max; x++) setPixel(x, y, color);
226 }
227 
228 /*---------------------------------------------------------------
229  selectTextFont
230 ---------------------------------------------------------------*/
232 {
233  init_fonts_list();
234 
235  // Assure list name is in the list:
237  list_registered_fonts.find(fontName);
238  if (it == list_registered_fonts.end())
239  {
240  // Error
241  cerr << "[CCanvas::selectTextFont] Warning: Unknown font: " << fontName
242  << endl;
243  return;
244  }
245  else
246  {
248  reinterpret_cast<const uint32_t*>(&it->second[0]);
249  m_selectedFont = fontName;
250  }
251 }
252 
253 /*---------------------------------------------------------------
254  drawImage
255 ---------------------------------------------------------------*/
256 void CCanvas::drawImage(int x, int y, const utils::CImage& img)
257 {
258  MRPT_START
259 
260  int img_lx = img.getWidth();
261  int img_ly = img.getHeight();
262 
263  if (img.isColor())
264  {
265  for (int xx = 0; xx < img_lx; xx++)
266  for (int yy = 0; yy < img_ly; yy++)
267  setPixel(x + xx, y + yy, *((int*)img(xx, yy)));
268  }
269  else
270  {
271  unsigned char c;
272  int col;
273  for (int xx = 0; xx < img_lx; xx++)
274  for (int yy = 0; yy < img_ly; yy++)
275  {
276  c = *((unsigned char*)img(xx, yy));
277  col = c | (c << 8) | (c << 16);
278  setPixel(x + xx, y + yy, col);
279  }
280  }
281 
282  MRPT_END
283 }
284 
285 /*---------------------------------------------------------------
286  drawImage
287 ---------------------------------------------------------------*/
289  int x, int y, const utils::CImage& img, float rotation, float scale)
290 {
294  MRPT_UNUSED_PARAM(rotation);
296 
297  MRPT_START
298 
299  THROW_EXCEPTION("Not implemented yet!! Try yourself! ;-)");
300 
301  MRPT_END
302 }
303 
304 /*---------------------------------------------------------------
305  cross
306 ---------------------------------------------------------------*/
308  int x0, int y0, const mrpt::utils::TColor color, char type,
309  unsigned int size, unsigned int width)
310 {
311  switch (type)
312  {
313  case '+':
314  line(x0 - size, y0, x0 + size, y0, color, width);
315  line(x0, y0 - size, x0, y0 + size, color, width);
316  break;
317  case 'x':
318  line(x0 - size, y0 - size, x0 + size, y0 + size, color, width);
319  line(x0 + size, y0 - size, x0 - size, y0 + size, color, width);
320  break;
321  case ':':
322  line(x0 - size, y0, x0 - 2, y0, color, width);
323  line(x0 + 2, y0, x0 + size, y0, color, width);
324  line(x0, y0 - size, x0, y0 - 2, color, width);
325  line(x0, y0 + 2, x0, y0 + size, color, width);
326  break;
327  default:
328  THROW_EXCEPTION("Unexpected 'type' of cross to be drawn")
329  }
330 }
331 
332 /*---------------------------------------------------------------
333  drawCircle
334 ---------------------------------------------------------------*/
336  int x, int y, int radius, const mrpt::utils::TColor& color,
337  unsigned int width)
338 {
339  if (radius < 0) radius = -radius;
340 
341  int nSegments;
342 
343  if (radius == 0)
344  {
345  nSegments = 2;
346  }
347  else
348  {
349  nSegments = int(M_2PI * radius);
350  }
351 
352  int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
353  double ang, Aa = M_2PI / (nSegments - 1);
354  int i;
355 
356  for (i = 0, ang = 0; i < nSegments; i++, ang += Aa)
357  {
358  x2 = round(x + radius * cos(ang));
359  y2 = round(y + radius * sin(ang));
360 
361  if (i > 0) line(x1, y1, x2, y2, color, width);
362 
363  x1 = x2;
364  y1 = y2;
365  } // end for points on ellipse
366 }
367 
368 /*---------------------------------------------------------------
369  textOut
370 ---------------------------------------------------------------*/
372  int x0, int y0, const std::string& str, const mrpt::utils::TColor color)
373 {
374  MRPT_START
375 
376  if (!m_selectedFontBitmaps) // First call: load fonts
377  this->selectTextFont("9x15");
378 
379  // Am I an image?
380  bool y_axis_reversed = false;
381  CImage* im_image = dynamic_cast<CImage*>(this);
382  if (im_image) y_axis_reversed = !im_image->isOriginTopLeft();
383 
384  // Decode UNICODE string:
385  vector_word uniStr;
386  mrpt::system::decodeUTF8(str, uniStr);
387 
388  int px = x0;
389  int py = y0;
390 
391  // Char size:
392  uint32_t char_w = m_selectedFontBitmaps[0];
393  uint32_t char_h = m_selectedFontBitmaps[1];
394 
395  for (size_t i = 0; i < uniStr.size(); i++)
396  {
397  const uint16_t& unichar = uniStr[i];
398 
399  // look for the character in the table:
400  const uint32_t* table_ptr = m_selectedFontBitmaps + 2;
401  uint32_t charset_ini = table_ptr[0];
402  uint32_t charset_end = table_ptr[1];
403 
404  while (charset_end)
405  {
406  // Is in this range?
407  if (unichar <= charset_end && unichar >= charset_ini)
408  {
409  // Draw this character:
410  unsigned pyy = y_axis_reversed ? (py + char_h - 1) : py;
411  unsigned pxx;
412 
413  const uint32_t* char_bitmap =
414  table_ptr + 2 + char_h * (unichar - charset_ini);
415 
416  for (unsigned y = 0; y < char_h;
417  y++, pyy += y_axis_reversed ? -1 : 1)
418  {
419  pxx = px;
420  const uint32_t& row = *char_bitmap++;
421  for (unsigned x = 0; x < char_w; x++, pxx++)
422  if (row & (1 << x)) setPixel(pxx, pyy, color);
423  }
424 
425  // Advance the raster cursor:
426  px += char_w;
427 
428  // Next char!
429  break;
430  }
431  else
432  {
433  // No: Move to the next block and keep searching:
434  uint32_t n_chars = charset_end - charset_ini + 1;
435  table_ptr += 2 /* Header */ + n_chars * char_h;
436 
437  // get new block header:
438  charset_ini = table_ptr[0];
439  charset_end = table_ptr[1];
440  }
441  }
442  // Char not in the font!
443  }
444 
445  MRPT_END
446 }
virtual void textOut(int x0, int y0, const std::string &str, const mrpt::utils::TColor color)
Renders 2D text using bitmap fonts.
Definition: CCanvas.cpp:371
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
#define min(a, b)
unsigned __int16 uint16_t
Definition: rptypes.h:44
std::string m_selectedFont
The selected font name.
Definition: CCanvas.h:47
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:118
virtual void line(int x0, int y0, int x1, int y1, const mrpt::utils::TColor color, unsigned int width=1, TPenStyle penStyle=psSolid)
Draws a line.
Definition: CCanvas.cpp:124
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:6502
#define THROW_EXCEPTION(msg)
bool list_fonts_init
Definition: CCanvas.cpp:51
virtual size_t getHeight() const =0
Returns the height of the image in pixels.
void rectangle(int x0, int y0, int x1, int y1, const mrpt::utils::TColor color, unsigned int width=1)
Draws a rectangle (an empty rectangle, without filling)
Definition: CCanvas.cpp:172
STL namespace.
void triangle(int x0, int y0, int size, const mrpt::utils::TColor color, bool inferior=true, unsigned int width=1)
Draws a triangle.
Definition: CCanvas.cpp:192
const Scalar * const_iterator
Definition: eigen_plugins.h:27
GLenum GLsizei width
Definition: glext.h:3531
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
#define M_2PI
Definition: mrpt_macros.h:437
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
virtual void setPixel(int x, int y, size_t color)=0
Changes the value of the pixel (x,y).
GLuint color
Definition: glext.h:8300
#define LOAD_FONT(FONTNAME)
const uint32_t * m_selectedFontBitmaps
Direct access to character bitmaps.
Definition: CCanvas.h:50
void decodeUTF8(const std::string &strUTF8, vector_word &out_uniStr)
Decodes a UTF-8 string into an UNICODE string.
const GLfloat * tc
Definition: glext.h:6362
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
const GLubyte * c
Definition: glext.h:6313
GLint GLvoid * img
Definition: glext.h:3763
map< string, vector_byte > list_registered_fonts
Definition: CCanvas.cpp:48
void cross(int x0, int y0, const mrpt::utils::TColor color, char type, unsigned int size=5, unsigned int width=1)
Draw a cross.
Definition: CCanvas.cpp:307
virtual void selectTextFont(const std::string &fontName)
Select the current font used when drawing text.
Definition: CCanvas.cpp:231
A RGB color - 8bit.
Definition: TColor.h:25
GLsizei const GLchar ** string
Definition: glext.h:4101
virtual void filledRectangle(int x0, int y0, int x1, int y1, const mrpt::utils::TColor color)
Draws a filled rectangle.
Definition: CCanvas.cpp:216
virtual size_t getWidth() const =0
Returns the width of the image in pixels.
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void init_fonts_list()
Definition: CCanvas.cpp:53
virtual void drawCircle(int x, int y, int radius, const mrpt::utils::TColor &color=mrpt::utils::TColor(255, 255, 255), unsigned int width=1)
Draws a circle of a given radius.
Definition: CCanvas.cpp:335
std::vector< uint16_t > vector_word
Definition: types_simple.h:28
GLenum GLenum GLvoid * row
Definition: glext.h:3576
bool isOriginTopLeft() const
Returns true if the coordinates origin is top-left, or false if it is bottom-left.
Definition: CImage.cpp:939
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:25
GLenum GLint GLint y
Definition: glext.h:3538
GLsizeiptr size
Definition: glext.h:3923
GLenum GLint x
Definition: glext.h:3538
TPenStyle
Definition of pen styles.
Definition: CCanvas.h:57
unsigned __int32 uint32_t
Definition: rptypes.h:47
GLuint GLuint GLsizei GLenum type
Definition: glext.h:3528
virtual void drawImage(int x, int y, const utils::CImage &img)
Draws an image as a bitmap at a given position.
Definition: CCanvas.cpp:256



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019