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



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST