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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at lun oct 28 00:14:14 CET 2019