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 }
mrpt::img::CCanvas::triangle
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
os.h
const_iterator
const Scalar * const_iterator
Definition: eigen_plugins.h:27
mrpt::img::CCanvas::setPixel
virtual void setPixel(int x, int y, size_t color)=0
Changes the value of the pixel (x,y).
mrpt_font_9x15.h
mrpt_font_18x18ja.h
mrpt_font_6x13B.h
uint16_t
unsigned __int16 uint16_t
Definition: rptypes.h:44
string_utils.h
c
const GLubyte * c
Definition: glext.h:6313
mrpt::img::CCanvas::cross
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
MRPT_UNUSED_PARAM
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
mrpt::system::decodeUTF8
void decodeUTF8(const std::string &strUTF8, std::vector< uint16_t > &out_uniStr)
Decodes a UTF-8 string into an UNICODE string.
Definition: string_utils.cpp:98
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: CKalmanFilterCapable.h:30
w
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
type
GLuint GLuint GLsizei GLenum type
Definition: glext.h:3528
THROW_EXCEPTION
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
mrpt::square
T square(const T x)
Inline function for the square of a number.
Definition: core/include/mrpt/core/bits_math.h:18
mrpt::img::CCanvas::m_selectedFont
std::string m_selectedFont
The selected font name.
Definition: CCanvas.h:46
mrpt::img::CCanvas::rectangle
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
mrpt_font_10x20.h
init_fonts_list
void init_fonts_list()
Definition: CCanvas.cpp:51
mrpt::img
Definition: CCanvas.h:17
mrpt_font_5x7.h
tc
const GLfloat * tc
Definition: glext.h:6362
mrpt::round
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23
MRPT_START
#define MRPT_START
Definition: exceptions.h:262
mrpt::img::CImage::isOriginTopLeft
bool isOriginTopLeft() const
Returns true if the coordinates origin is top-left, or false if it is bottom-left
Definition: CImage.cpp:934
mrpt::img::CCanvas::drawCircle
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
mrpt::img::TColor
A RGB color - 8bit.
Definition: TColor.h:22
round.h
CCanvas.h
color
GLuint color
Definition: glext.h:8300
mrpt_font_9x15B.h
img-precomp.h
mrpt::img::CCanvas::getHeight
virtual size_t getHeight() const =0
Returns the height of the image in pixels.
mrpt::img::CCanvas::getWidth
virtual size_t getWidth() const =0
Returns the width of the image in pixels.
mrpt::img::CImage
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:130
scale
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:6503
list_fonts_init
bool list_fonts_init
Definition: CCanvas.cpp:49
mrpt::img::CCanvas::drawImage
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
min
#define min(a, b)
Definition: rplidar_driver.cpp:42
img
GLint GLvoid * img
Definition: glext.h:3763
row
GLenum GLenum GLvoid * row
Definition: glext.h:3576
mrpt_font_6x13O.h
mrpt::img::CCanvas::CCanvas
CCanvas()
Definition: CCanvas.cpp:118
width
GLenum GLsizei width
Definition: glext.h:3531
MRPT_END
#define MRPT_END
Definition: exceptions.h:266
mrpt::img::CCanvas::m_selectedFontBitmaps
const uint32_t * m_selectedFontBitmaps
Direct access to character bitmaps.
Definition: CCanvas.h:49
M_2PI
#define M_2PI
Definition: common.h:58
string
GLsizei const GLchar ** string
Definition: glext.h:4101
CImage.h
mrpt::img::CCanvas::textOut
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
LOAD_FONT
#define LOAD_FONT(FONTNAME)
list_registered_fonts
map< string, std::vector< uint8_t > > list_registered_fonts
Definition: CCanvas.cpp:46
mrpt::img::CCanvas::line
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
mrpt_font_6x13.h
size
GLsizeiptr size
Definition: glext.h:3923
y
GLenum GLint GLint y
Definition: glext.h:3538
mrpt::img::CCanvas::TPenStyle
TPenStyle
Definition of pen styles.
Definition: CCanvas.h:56
uint32_t
unsigned __int32 uint32_t
Definition: rptypes.h:47
x
GLenum GLint x
Definition: glext.h:3538
zip.h
mrpt::img::CCanvas::filledRectangle
virtual void filledRectangle(int x0, int y0, int x1, int y1, const mrpt::img::TColor color)
Draws a filled rectangle.
Definition: CCanvas.cpp:214
mrpt::img::CCanvas::selectTextFont
virtual void selectTextFont(const std::string &fontName)
Select the current font used when drawing text.
Definition: CCanvas.cpp:229



Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST