NXWidgets: cgraphicsport.cxx Source File

NXWidgets 1.19

cgraphicsport.cxx
Go to the documentation of this file.
1 /****************************************************************************
2 * NxWidgets/libnxwidgets/src/cgraphicsport.cxx
3 *
4 * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
5 * Author: Gregory Nutt <gnutt@nuttx.org>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
18 * me be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ****************************************************************************
35 *
36 * Portions of this package derive from Woopsi (http://woopsi.org/) and
37 * portions are original efforts. It is difficult to determine at this
38 * point what parts are original efforts and which parts derive from Woopsi.
39 * However, in any event, the work of Antony Dzeryn will be acknowledged
40 * in most NxWidget files. Thanks Antony!
41 *
42 * Copyright (c) 2007-2011, Antony Dzeryn
43 * All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions are met:
47 *
48 * * Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * * Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * * Neither the names "Woopsi", "Simian Zombie" nor the
54 * names of its contributors may be used to endorse or promote products
55 * derived from this software without specific prior written permission.
56 *
57 * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``AS IS'' AND ANY
58 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60 * DISCLAIMED. IN NO EVENT SHALL Antony Dzeryn BE LIABLE FOR ANY
61 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 *
68 ****************************************************************************/
69
70 /****************************************************************************
71 * Included Files
72 ****************************************************************************/
73
74 #include <nuttx/config.h>
75
76 #include <sys/types.h>
77 #include <stdint.h>
78 #include <stdbool.h>
79 #include <cerrno>
80 #include <debug.h>
81
82 #include <nuttx/nx/nxglib.h>
83 #include <nuttx/video/rgbcolors.h>
84
85 #include "nxconfig.hxx"
86 #include "inxwindow.hxx"
87 #include "cnxstring.hxx"
88 #include "crect.hxx"
89 #include "cnxfont.hxx"
90 #include "cgraphicsport.hxx"
91 #include "cwidgetstyle.hxx"
92 #include "cbitmap.hxx"
93 #include "singletons.hxx"
94
95 /****************************************************************************
96 * Pre-Processor Definitions
97 ****************************************************************************/
98
99 /****************************************************************************
100 * Method Implementations
101 ****************************************************************************/
102
103 using namespace NXWidgets;
104
105 /**
106 * Constructor.
107 *
108 * @param pNxWnd. An instance of the underlying window type.
109 * @param backColor. The background color is only needed if we
110 * cannot read from the graphics device.
111 */
112
113 #ifdef CONFIG_NX_WRITEONLY
114 CGraphicsPort::CGraphicsPort(INxWindow *pNxWnd, nxgl_mxpixel_t backColor)
115 {
116 m_pNxWnd = pNxWnd;
117 m_backColor = backColor;
118 }
119 #else
120 CGraphicsPort::CGraphicsPort(INxWindow *pNxWnd)
121 {
122 m_pNxWnd = pNxWnd;
123 }
124 #endif
125
126 /**
127 * Destructor.
128 */
129
130 CGraphicsPort::~CGraphicsPort(void)
131 {
132 // m_pNxWnd is not deleted. This is an abstract base class and
133 // the caller of the CGraphicsPort instance is responsible for
134 // the window destruction.
135 };
136
137 /**
138 * Return the absolute x coordinate of the upper left hand corner of the
139 * underlying window.
140 *
141 * @return The x coordinate of the underlying window.
142 */
143
144 const nxgl_coord_t CGraphicsPort::getX(void) const
145 {
146 struct nxgl_point_s pos;
147 (void)m_pNxWnd->getPosition(&pos);
148 return pos.x;
149 };
150
151 /**
152 * Return the absolute y coordinate of the upper left hand corner of the
153 * underlying window.
154 *
155 * @return The y coordinate of the underlying window.
156 */
157
158 const nxgl_coord_t CGraphicsPort::getY(void) const
159 {
160 struct nxgl_point_s pos;
161 (void)m_pNxWnd->getPosition(&pos);
162 return pos.y;
163 };
164
165 /**
166 * Draw a pixel into the window.
167 *
168 * @param x The window-relative x coordinate of the pixel.
169 * @param y The window-relative y coordinate of the pixel.
170 * @param color The color of the pixel.
171 */
172
173 void CGraphicsPort::drawPixel(nxgl_coord_t x, nxgl_coord_t y,
174 nxgl_mxpixel_t color)
175 {
176 struct nxgl_point_s pos;
177 pos.x = x;
178 pos.y = y;
179 m_pNxWnd->setPixel(&pos, color);
180 }
181
182 /**
183 * Draw a horizontal line of the specified start position, width, and color.
184 *
185 * @param x The x coordinate of the line.
186 * @param y The y coordinate of the top-most end of the line.
187 * @param width The width of the line in pixels.
188 * @param color The color of the line.
189 */
190
191 void CGraphicsPort::drawHorizLine(nxgl_coord_t x, nxgl_coord_t y,
192 nxgl_coord_t width, nxgl_mxpixel_t color)
193 {
194 FAR struct nxgl_rect_s dest;
195
196 // Express the line as a rectangle
197
198 dest.pt1.x = x;
199 dest.pt1.y = y;
200 dest.pt2.x = x + width - 1;
201 dest.pt2.y = y;
202
203 // Draw the line
204
205 if (!m_pNxWnd->fill(&dest, color))
206 {
207 gerr("ERROR: INxWindow::fill failed\n");
208 }
209 }
210
211 /**
212 * Draw a vertical line of the specified start position, width, and
213 * color.
214 *
215 * @param x The x coordinate of the left-most end of the line.
216 * @param y The y coordinate of the line.
217 * @param height The height of the line in rows.
218 * @param color The color of the line.
219 */
220
221 void CGraphicsPort::drawVertLine(nxgl_coord_t x, nxgl_coord_t y,
222 nxgl_coord_t height, nxgl_mxpixel_t color)
223 {
224 FAR struct nxgl_rect_s dest;
225
226 // Express the line as a rectangle
227
228 dest.pt1.x = x;
229 dest.pt1.y = y;
230 dest.pt2.x = x;
231 dest.pt2.y = y + height - 1;
232
233 // Draw the line
234
235 if (!m_pNxWnd->fill(&dest, color))
236 {
237 gerr("ERROR: INxWindow::fill failed\n");
238 }
239 }
240
241 /**
242 * Draw a line of a fixed color in the window.
243 *
244 * @param x1 - The x coordinate of the start point of the line.
245 * @param y1 - The y coordinate of the start point of the line.
246 * @param x2 - The x coordinate of the end point of the line.
247 * @param y2 - The y coordinate of the end point of the line.
248 * @param color - The color of the line.
249 * @param caps - Draw a circular cap one the ends of the line to support
250 * - better line joins
251 */
252
253 void CGraphicsPort::drawLine(nxgl_coord_t x1, nxgl_coord_t y1,
254 nxgl_coord_t x2, nxgl_coord_t y2,
255 nxgl_mxpixel_t color, enum INxWindow::ELineCaps caps)
256 {
257 struct nxgl_vector_s vector;
258
259 vector.pt1.x = x1;
260 vector.pt1.y = y1;
261 vector.pt2.x = x2;
262 vector.pt2.y = y2;
263
264 if (!m_pNxWnd->drawLine(&vector, 1, color, caps))
265 {
266 gerr("ERROR: INxWindow::drawLine failed\n");
267 }
268 }
269
270 /**
271 * Draw a filled rectangle to the bitmap.
272 *
273 * @param x The window-relative x coordinate of the rectangle.
274 * @param y The window-relative y coordinate of the rectangle.
275 * @param width The width of the rectangle in pixels.
276 * @param height The height of the rectangle in rows.
277 * @param color The color of the rectangle.
278 */
279
280 void CGraphicsPort::drawFilledRect(nxgl_coord_t x, nxgl_coord_t y,
281 nxgl_coord_t width, nxgl_coord_t height,
282 nxgl_mxpixel_t color)
283 {
284 struct nxgl_rect_s rect;
285 rect.pt1.x = x;
286 rect.pt1.y = y;
287 rect.pt2.x = x + width - 1;
288 rect.pt2.y = y + height - 1;
289 m_pNxWnd->fill(&rect, color);
290 }
291
292 /**
293 * Draw an unfilled rectangle to the window
294 *
295 * @param x The window-relative x coordinate of the rectangle.
296 * @param y The window-relative y coordinate of the rectangle.
297 * @param width The width of the rectangle.
298 * @param height The height of the rectangle.
299 * @param color The color of the rectangle outline.
300 */
301
302 void CGraphicsPort::drawRect(nxgl_coord_t x, nxgl_coord_t y,
303 nxgl_coord_t width, nxgl_coord_t height,
304 nxgl_mxpixel_t color)
305 {
306 drawHorizLine(x, y, width, color);
307 drawHorizLine(x, y + height - 1, width, color);
308 drawVertLine(x, y, height, color);
309 drawVertLine(x + width -1, y, height, color);
310 }
311
312 /**
313 * Draw a bevelled rectangle to the window.
314 *
315 * @param x The x coordinate of the rectangle.
316 * @param y The y coordinate of the rectangle.
317 * @param width The width of the rectangle.
318 * @param height The height of the rectangle.
319 * @param shineColor The color of the top/left sides.
320 * @param shadowColor The color of the bottom/right sides.
321 */
322
323 void CGraphicsPort::drawBevelledRect(nxgl_coord_t x, nxgl_coord_t y,
324 nxgl_coord_t width, nxgl_coord_t height,
325 nxgl_mxpixel_t shineColor,
326 nxgl_mxpixel_t shadowColor)
327 {
328 drawHorizLine(x, y, width, shineColor); // Top
329 drawHorizLine(x, y + height - 1, width, shadowColor); // Bottom
330 drawVertLine(x, y + 1, height - 2, shineColor); // Left
331 drawVertLine(x + width - 1, y + 1, height - 2, shadowColor); // Right
332 }
333
334 /**
335 * Draw an opaque bitmap to the window.
336 *
337 * @param x The window-relative x coordinate to draw the bitmap to.
338 * @param y The window-relative y coordinate to draw the bitmap to.
339 * @param width The width of the bitmap to draw.
340 * @param height The height of the bitmap to draw.
341 * @param bitmap Pointer to the bitmap to draw.
342 * @param bitmapX The window-relative x coordinate within the supplied
343 * bitmap to use as the origin.
344 * @param bitmapY The window-relative y coordinate within the supplied
345 * bitmap to use as the origin.
346 */
347
348 void CGraphicsPort::drawBitmap(nxgl_coord_t x, nxgl_coord_t y,
349 nxgl_coord_t width, nxgl_coord_t height,
350 const struct SBitmap *bitmap,
351 int bitmapX, int bitmapY)
352 {
353 // origin - The origin of the upper, left-most corner of the full bitmap.
354 // Both dest and origin are in window coordinates, however, origin
355 // may lie outside of the display.
356
357 struct nxgl_point_s origin;
358 origin.x = x - bitmapX;
359 origin.y = y - bitmapY;
360
361 // dest - Describes the rectangular on the display that will receive the
362 // the bit map.
363
364 struct nxgl_rect_s dest;
365 dest.pt1.x = x;
366 dest.pt1.y = y;
367 dest.pt2.x = x + width - 1;
368 dest.pt2.y = y + height - 1;
369
370 // Blit the bitmap
371
372 (void)m_pNxWnd->bitmap(&dest, (FAR const void *)bitmap->data, &origin, bitmap->stride);
373 }
374
375 /**
376 * Draw a bitmap to the window, using the supplied transparent
377 * color as an invisible color.
378 *
379 * @param x The window-relative x coordinate to draw the bitmap to.
380 * @param y The window-relative y coordinate to draw the bitmap to.
381 * @param width The width of the bitmap to draw.
382 * @param height The height of the bitmap to draw.
383 * @param bitmap Pointer to the bitmap to draw.
384 * @param bitmapX The window-relative x coordinate within the supplied bitmap to use as
385 * the origin.
386 * @param bitmapY The window-relative y coordinate within the supplied bitmap to use as
387 * the origin.
388 * @param transparentColor The transparent color used in the bitmap.
389 */
390
391 void CGraphicsPort::drawBitmap(nxgl_coord_t x, nxgl_coord_t y,
392 nxgl_coord_t width, nxgl_coord_t height,
393 const struct SBitmap *bitmap,
394 int bitmapX, int bitmapY,
395 nxgl_mxpixel_t transparentColor)
396 {
397 // Get the starting position in the image, offset by bitmapX and bitmapY into the image.
398
399 FAR uint8_t *srcLine = (uint8_t *)bitmap->data +
400 bitmapY * bitmap->stride +
401 ((bitmapX * bitmap->bpp + 7) >> 3);
402 FAR nxwidget_pixel_t *srcPtr = (nxwidget_pixel_t *)srcLine;
403
404 // Loop until all rows have been displayed
405
406 nxgl_coord_t firstX = x;
407 nxgl_coord_t lastX = x + width;
408 nxgl_coord_t lastY = y + height;
409
410 while (y < lastY)
411 {
412 // Search for the next non-transparent pixel in the source image
413
414 while (*srcPtr == transparentColor)
415 {
416 // The pixel is transparent. Move to the next column
417
418 if (++x >= lastX)
419 {
420 // We are at the end of the row. Reset to the next row
421
422 x = firstX;
423 y++;
424
425 // Was that the last row:
426
427 if (y >= lastY)
428 {
429 // Yes, then we are finished
430
431 return;
432 }
433
434 // Update the source data pointers to the beginning of the next
435 // row
436
437 srcLine += bitmap->stride;
438 srcPtr = (nxwidget_pixel_t *)srcLine;
439 }
440 else
441 {
442 // This is another transparent pixel on the same row
443
444 srcPtr++;
445 }
446 }
447
448 // srcPtr points to the next non-transparent color. Save this
449 // as the start of a run that has length of at least one
450
451 FAR nxwidget_pixel_t *runPtr = srcPtr;
452 nxgl_coord_t runX = x;
453 nxgl_coord_t runWidth = 0;
454
455 // Now search for the next transparent pixel on the same row.
456 // This will determine the length of the run
457
458 do
459 {
460 // This is another non-transparent pixel on the same row
461
462 runWidth++;
463 srcPtr++;
464
465 // Move to the next column
466
467 if (++x >= lastX)
468 {
469 // We are at the end of the row. Reset to the next row
470
471 x = firstX;
472 y++;
473
474 // Update the source data pointers to the beginning of the next
475 // row
476
477 srcLine += bitmap->stride;
478 srcPtr = (nxwidget_pixel_t *)srcLine;
479
480 // And break out of this loop
481
482 break;
483 }
484 }
485 while (*srcPtr != transparentColor);
486
487 // When we come out of the above loop, either (1) srcPtr points to the
488 // next transparent pixel on the same row, or (2) srcPtr points to the
489 // first pixel in the next row.
490
491 // origin - The origin of the upper, left-most corner of the full bitmap.
492 // Both dest and origin are in window coordinates, however, origin
493 // may lie outside of the display.
494
495 struct nxgl_point_s origin;
496 origin.x = runX;
497 origin.y = y;
498
499 // dest - Describes the rectangular on the display that will receive the
500 // the bit map.
501
502 struct nxgl_rect_s dest;
503 dest.pt1.x = runX;
504 dest.pt1.y = y;
505 dest.pt2.x = runX + runWidth - 1;
506 dest.pt2.y = y;
507
508 // Blit the bitmap
509
510 (void)m_pNxWnd->bitmap(&dest, (FAR const void *)runPtr, &origin, bitmap->stride);
511 }
512 }
513
514 /**
515 * Draw a bitmap to the port in greyscale.
516 *
517 * @param x The window-relative x coordinate to draw the bitmap to.
518 * @param y The window-relative y coordinate to draw the bitmap to.
519 * @param width The width of the bitmap to draw.
520 * @param height The height of the bitmap to draw.
521 * @param bitmap Pointer to the bitmap to draw.
522 * @param bitmapX The window-relative x coordinate within the supplied bitmap to use as
523 * the origin.
524 * @param bitmapY The window-relative y coordinate within the supplied bitmap to use as
525 * the origin.
526 */
527
528 void CGraphicsPort::drawBitmapGreyScale(nxgl_coord_t x, nxgl_coord_t y,
529 nxgl_coord_t width, nxgl_coord_t height,
530 const struct SBitmap *bitmap,
531 int bitmapX, int bitmapY)
532 {
533 // Working buffer. Holds one converted row from the bitmap
534
535 FAR nxwidget_pixel_t *run = new nxwidget_pixel_t[width];
536 if (!run)
537 {
538 ginfo("ERROR: Failed to allocated run buffer\n");
539 return;
540 }
541
542 // Pointer to the beginning of the first source row
543
544 FAR uint8_t *src = (FAR uint8_t *)bitmap->data + bitmapY * bitmap->stride + bitmapX;
545
546 // Setup non-changing blit parameters
547
548 struct nxgl_point_s origin;
549 origin.x = x;
550 origin.y = y;
551
552 struct nxgl_rect_s dest;
553 dest.pt1.x = x;
554 dest.pt1.y = y;
555 dest.pt2.x = x + width - 1;
556 dest.pt2.y = y;
557
558 // Convert each row to greyscale and send it to the display
559
560 for (int row = 0; row < height; row++)
561 {
562 // Convert the next row
563
564 FAR nxwidget_pixel_t *runSrc = (FAR nxwidget_pixel_t *)src;
565 FAR nxwidget_pixel_t *runDest = run;
566
567 for (int col = 0; col < width; col++)
568 {
569 // Get the next RGB pixel and break out the individual components
570
571 nxwidget_pixel_t rgb = *runSrc++;
572 nxwidget_pixel_t r = RGB2RED(rgb);
573 nxwidget_pixel_t g = RGB2GREEN(rgb);
574 nxwidget_pixel_t b = RGB2BLUE(rgb);
575
576 // A truly accurate greyscale conversion would be complex. Let's
577 // just average.
578
579 nxwidget_pixel_t avg = (r + g + b) / 3;
580 *runDest++ = MKRGB(avg, avg, avg);
581 }
582
583 // Now blit the single row
584
585 (void)m_pNxWnd->bitmap(&dest, run, &origin, bitmap->stride);
586
587 // Setup for the next source row
588
589 y++;
590 origin.y = y;
591 dest.pt1.y = y;
592 dest.pt2.y = y;
593
594 src += bitmap->stride;
595 }
596
597 delete run;
598 }
599
600 /**
601 * Draw a string to the window.
602 *
603 * @param pos The window-relative x/y coordinate of the string.
604 * @param bound The window-relative bounds of the string.
605 * @param font The font to draw with.
606 * @param string The string to output.
607 */
608
609 void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound,
610 CNxFont *font, const CNxString &string)
611 {
612 _drawText(pos, bound, font, string, 0, string.getLength(), 0, true);
613 }
614
615 /**
616 * Draw a particular length of a string to the window in a secific color.
617 *
618 * @param pos The window-relative x/y coordinate of the string.
619 * @param bound The window-relative bounds of the string.
620 * @param font The font to draw with.
621 * @param string The string to output.
622 * @param startIndex The start index within the string from which
623 * drawing will commence.
624 * @param length The number of characters to draw.
625 * @param color The color of the string.
626 */
627
628 void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound,
629 CNxFont *font, const CNxString &string,
630 int startIndex, int length,
631 nxgl_mxpixel_t color)
632 {
633 // Temporarily change the font color
634
635 nxgl_mxpixel_t savedColor = font->getColor();
636 font->setColor(color);
637
638 // Draw the string with this new color
639
640 _drawText(pos, bound, font, string, startIndex, length, 0, true);
641
642 // Restore the font color
643
644 font->setColor(savedColor);
645 }
646
647 /**
648 * Draw a portion of a string to the window.
649 * @param pos The window-relative x/y coordinate of the string.
650 * @param bound The window-relative bounds of the string.
651 * @param font The font to draw with.
652 * @param string The string to output.
653 * @param startIndex The start index within the string from which
654 * drawing will commence.
655 * @param length The number of characters to draw.
656 */
657
658 void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound,
659 CNxFont *font, const CNxString &string,
660 int startIndex, int length)
661 {
662 _drawText(pos, bound, font, string, startIndex, length, 0, true);
663 }
664
665 /**
666 * Draw a portion of a string to the window and fill the background
667 * in one go.
668 * @param pos The window-relative x/y coordinate of the string.
669 * @param bound The window-relative bounds of the string.
670 * @param font The font to draw with.
671 * @param string The string to output.
672 * @param startIndex The start index within the string from which
673 * drawing will commence.
674 * @param length The number of characters to draw.
675 * @param color Foreground color
676 * @param background Background color
677 */
678
679 void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound,
680 CNxFont *font, const CNxString &string,
681 int startIndex, int length,
682 nxgl_mxpixel_t color,
683 nxgl_mxpixel_t background)
684 {
685 nxgl_mxpixel_t savedColor = font->getColor();
686 font->setColor(color);
687
688 _drawText(pos, bound, font, string, startIndex, length, background, false);
689
690 font->setColor(savedColor);
691 }
692
693 /**
694 * The underlying implementation for drawText functions
695 * @param pos The window-relative x/y coordinate of the string.
696 * @param bound The window-relative bounds of the string.
697 * @param font The font to draw with.
698 * @param string The string to output.
699 * @param startIndex The start index within the string from which
700 * drawing will commence.
701 * @param length The number of characters to draw.
702 * @param background Color to use for background if transparent is false.
703 * @param transparent Whether to fill the background.
704 */
705
706 void CGraphicsPort::_drawText(struct nxgl_point_s *pos, CRect *bound,
707 CNxFont *font, const CNxString &string,
708 int startIndex, int length,
709 nxgl_mxpixel_t background,
710 bool transparent)
711 {
712 // Verify index and length
713
714 int stringLength = string.getLength();
715 if (startIndex >= stringLength)
716 {
717 return;
718 }
719
720 int endIndex = startIndex + length;
721 if (endIndex > stringLength)
722 {
723 endIndex = stringLength;
724 }
725
726 #ifdef CONFIG_NX_WRITEONLY
727 if (transparent)
728 {
729 // Can't render transparently without reading memory.
730
731 transparent = false;
732 background = m_backColor;
733 }
734 #endif
735
736 // Allocate a bit of memory to hold the largest rendered font
737
738 unsigned int bmWidth = ((unsigned int)font->getMaxWidth() * CONFIG_NXWIDGETS_BPP + 7) >> 3;
739 unsigned int bmHeight = (unsigned int)font->getHeight();
740
741 unsigned int glyphSize = bmWidth * bmHeight;
742 FAR uint8_t *glyph = new uint8_t[glyphSize];
743
744 // Get the bounding rectangle in NX form
745
746 struct nxgl_rect_s boundingBox;
747 bound->getNxRect(&boundingBox);
748
749 // Loop setup
750
751 struct SBitmap bitmap;
752 bitmap.bpp = CONFIG_NXWIDGETS_BPP;
753 bitmap.fmt = CONFIG_NXWIDGETS_FMT;
754 bitmap.data = (FAR const nxgl_mxpixel_t*)glyph;
755
756 // Loop for each letter in the sub-string
757
758 for (int i = startIndex; i < endIndex; i++)
759 {
760 // Get the next letter in the string
761
762 const nxwidget_char_t letter = string.getCharAt(i);
763
764 // Get the font metrics for this letter
765
766 struct nx_fontmetric_s metrics;
767 font->getCharMetrics(letter, &metrics);
768
769 // Get the width of the font (in pixels)
770
771 nxgl_coord_t fontWidth = (nxgl_coord_t)(metrics.width + metrics.xoffset);
772
773 // Does the letter have height? Spaces have width, but no height
774
775 if (metrics.height > 0 || !transparent)
776 {
777 // Set the current, effective size of the bitmap
778
779 bitmap.width = fontWidth;
780 bitmap.height = bmHeight;
781 bitmap.stride = (fontWidth * bitmap.bpp + 7) >> 3;
782
783 // Describe the destination of the font as a bounding box
784
785 struct nxgl_rect_s dest;
786 dest.pt1.x = pos->x;
787 dest.pt1.y = pos->y;
788 dest.pt2.x = pos->x + fontWidth - 1;
789 dest.pt2.y = pos->y + bmHeight - 1;
790
791 // Get the interection of the font box and the bounding box
792
793 struct nxgl_rect_s intersection;
794 nxgl_rectintersect(&intersection, &dest, &boundingBox);
795
796 // Skip to the next character if this one is completely outside
797 // the bounding box.
798
799 if (!nxgl_nullrect(&intersection))
800 {
801 // If we have been given a background color, use it to fill the array.
802 // Otherwise initialize the bitmap memory by reading from the display.
803 // The font renderer always renders the fonts on a transparent background.
804
805 if (!transparent)
806 {
807 // Set the glyph memory to the background color
808
809 nxwidget_pixel_t *bmPtr = (nxwidget_pixel_t *)bitmap.data;
810 unsigned int npixels = fontWidth * bmHeight;
811 for (unsigned int j = 0; j < npixels; j++)
812 {
813 *bmPtr++ = background;
814 }
815 }
816 else
817 {
818 // Read the current contents of the destination into the glyph memory
819
820 m_pNxWnd->getRectangle(&dest, &bitmap);
821 }
822
823 // Render the font into the initialized bitmap
824
825 font->drawChar(&bitmap, letter);
826
827 // Then put the font on the display
828
829 if (!m_pNxWnd->bitmap(&intersection, (FAR const void *)bitmap.data,
830 pos, bitmap.stride))
831 {
832 ginfo("nx_bitmapwindow failed: %d\n", errno);
833 }
834 }
835 }
836
837 // Adjust the X position for the next character in the string
838
839 pos->x += fontWidth;
840 }
841
842 delete glyph;
843 }
844
845 /**
846 * Copy a rectangular region from the source coordinates to the
847 * destination coordinates.
848 *
849 * @param sourceX Source x coordinate.
850 * @param sourceY Source y coordinate.
851 * @param destX Destination x coordinate.
852 * @param destY Destination y coordinate.
853 * @param width Width of the rectangle to copy.
854 * @param height Height of the rectangle to copy.
855 */
856
857 void CGraphicsPort::copy(nxgl_coord_t sourceX, nxgl_coord_t sourceY,
858 nxgl_coord_t destX, nxgl_coord_t destY,
859 nxgl_coord_t width, nxgl_coord_t height)
860 {
861 struct nxgl_rect_s rect;
862 struct nxgl_point_s offset;
863
864 rect.pt1.x = sourceX;
865 rect.pt1.y = sourceY;
866 rect.pt1.x = sourceX + width - 1;
867 rect.pt1.y = sourceY + height - 1;
868
869 offset.x = destX - sourceX;
870 offset.y = destY - sourceY;
871
872 (void)m_pNxWnd->move(&rect, &offset);
873 }
874
875 /**
876 * Move a region by a specified distance in two dimensions.
877 *
878 * @param x X coordinate of the source area to move.
879 * @param y Y coordinate of the source area to move.
880 * @param deltaX Horizontal distance to move.
881 * @param deltaY Vertical distance to move.
882 * @param width Width of the area to move.
883 * @param height Height of the area to move.
884 */
885
886 void CGraphicsPort::move(nxgl_coord_t x, nxgl_coord_t y,
887 nxgl_coord_t deltaX, nxgl_coord_t deltaY,
888 nxgl_coord_t width, nxgl_coord_t height)
889 {
890 struct nxgl_rect_s rect;
891 rect.pt1.x = x;
892 rect.pt1.y = y;
893 rect.pt2.x = x + width - 1;
894 rect.pt2.y = y + height - 1;
895
896 struct nxgl_point_s offset;
897 offset.x = deltaX;
898 offset.y = deltaY;
899
900 (void)m_pNxWnd->move(&rect, &offset);
901 }
902
903 /**
904 * Convert the region to greyscale.
905 *
906 * @param x X coordinate of the region to change.
907 * @param y Y coordinate of the region to change.
908 * @param width Width of the region to change.
909 * @param height Height of the region to change.
910 */
911
912 void CGraphicsPort::greyScale(nxgl_coord_t x, nxgl_coord_t y,
913 nxgl_coord_t width, nxgl_coord_t height)
914 {
915 // Allocate memory to hold one row of graphics data
916
917 unsigned int stride = ((unsigned int)width * CONFIG_NXWIDGETS_BPP + 7) >> 3;
918 FAR uint8_t *rowBuffer = new uint8_t[height * stride];
919 if (!rowBuffer)
920 {
921 return;
922 }
923
924 // Describe the receiving bitmap memory
925
926 SBitmap rowBitmap;
927 rowBitmap.bpp = CONFIG_NXWIDGETS_BPP;
928 rowBitmap.fmt = CONFIG_NXWIDGETS_FMT;
929 rowBitmap.width = width;
930 rowBitmap.height = 1;
931 rowBitmap.stride = stride;
932 rowBitmap.data = (FAR const nxgl_mxpixel_t *)rowBuffer;
933
934 // Partially describe the source rectangle
935
936 struct nxgl_rect_s rect;
937 rect.pt1.x = x;
938 rect.pt2.x = x + width - 1;
939
940 // Partially setup the graphics origin
941
942 struct nxgl_point_s origin;
943 origin.x = x;
944
945 // Loop for each row in the region to be inverted
946
947 for (int row = 0; row < height; row++)
948 {
949 // Read the graphic memory corresponding to the row
950
951 rect.pt1.y = rect.pt2.y = y + row;
952 m_pNxWnd->getRectangle(&rect, &rowBitmap);
953
954 // Convert each bit to each bit
955
956 nxwidget_pixel_t *ptr = (nxwidget_pixel_t *)rowBuffer;
957 for (int col = 0; col < width; col++)
958 {
959 // Get the next RGB pixel and break out the individual components
960
961 nxwidget_pixel_t color = *ptr;
962 uint8_t red = RGB2RED(color);
963 uint8_t green = RGB2GREEN(color);
964 uint8_t blue = RGB2BLUE(color);
965
966 // A truly accurate greyscale conversion would be complex. Let's
967 // just average.
968
969 nxwidget_pixel_t avg = (red + green + blue) / 3;
970 *ptr++ = MKRGB(avg, avg, avg);
971 }
972
973 // Then write the row back to graphics memory
974
975 origin.y = rect.pt1.y;
976 m_pNxWnd->bitmap(&rect, (FAR const void *)rowBitmap.data,
977 &origin, rowBitmap.stride) ;
978 }
979
980 delete rowBuffer;
981 }
982
983 /**
984 * Invert colors in a region. NOTE: This allocates an in-memory
985 * buffer the size of one row in graphic memory. So it may only be
986 * useful for inverting small regions and its only current use of for
987 * the inverted cursor text.
988 *
989 * @param x X coordinate of the region to change.
990 * @param y Y coordinate of the region to change.
991 * @param width Width of the region to change.
992 * @param height Height of the region to change.
993 */
994
995 void CGraphicsPort::invert(nxgl_coord_t x, nxgl_coord_t y,
996 nxgl_coord_t width, nxgl_coord_t height)
997 {
998 // Allocate memory to hold one row of graphics data
999
1000 unsigned int stride = ((unsigned int)width * CONFIG_NXWIDGETS_BPP + 7) >> 3;
1001 FAR uint8_t *rowBuffer = new uint8_t[height * stride];
1002 if (!rowBuffer)
1003 {
1004 return;
1005 }
1006
1007 // Describe the receiving bitmap memory
1008
1009 SBitmap rowBitmap;
1010 rowBitmap.bpp = CONFIG_NXWIDGETS_BPP;
1011 rowBitmap.fmt = CONFIG_NXWIDGETS_FMT;
1012 rowBitmap.width = width;
1013 rowBitmap.height = 1;
1014 rowBitmap.stride = stride;
1015 rowBitmap.data = (FAR const nxgl_mxpixel_t *)rowBuffer;
1016
1017 // Partially describe the source rectangle
1018
1019 struct nxgl_rect_s rect;
1020 rect.pt1.x = x;
1021 rect.pt2.x = x + width - 1;
1022
1023 // Partially setup the graphics origin
1024
1025 struct nxgl_point_s origin;
1026 origin.x = x;
1027
1028 // Loop for each row in the region to be inverted
1029
1030 for (int row = 0; row < height; row++)
1031 {
1032 // Read the graphic memory corresponding to the row
1033
1034 rect.pt1.y = rect.pt2.y = y + row;
1035 m_pNxWnd->getRectangle(&rect, &rowBitmap);
1036
1037 // Invert each bit
1038
1039 nxwidget_pixel_t *ptr = (nxwidget_pixel_t *)rowBuffer;
1040 for (int col = 0; col < width; col++)
1041 {
1042 nxwidget_pixel_t color = *ptr;
1043 uint8_t red = RGB2RED(color);
1044 uint8_t green = RGB2GREEN(color);
1045 uint8_t blue = RGB2BLUE(color);
1046 *ptr++ = MKRGB(~red, ~green, ~blue);
1047 }
1048
1049 // Then write the row back to graphics memory
1050
1051 origin.y = rect.pt1.y;
1052 m_pNxWnd->bitmap(&rect, (FAR const void *)rowBitmap.data,
1053 &origin, rowBitmap.stride) ;
1054 }
1055
1056 delete rowBuffer;
1057 };
1058
NXWidgets::CGraphicsPort::m_pNxWnd
INxWindow * m_pNxWnd
Definition: cgraphicsport.hxx:109
NXWidgets::INxWindow::bitmap
virtual bool bitmap(FAR const struct nxgl_rect_s *pDest, FAR const void *pSrc, FAR const struct nxgl_point_s *pOrigin, unsigned int stride)=0
NXWidgets::CGraphicsPort::copy
void copy(nxgl_coord_t sourceX, nxgl_coord_t sourceY, nxgl_coord_t destX, nxgl_coord_t destY, nxgl_coord_t width, nxgl_coord_t height)
Definition: cgraphicsport.cxx:857
NXWidgets::CGraphicsPort::drawVertLine
void drawVertLine(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t height, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:221
NXWidgets::CGraphicsPort::getY
const nxgl_coord_t getY(void) const
Definition: cgraphicsport.cxx:158
NXWidgets::CRect::getNxRect
void getNxRect(FAR struct nxgl_rect_s *rect) const
Definition: crect.hxx:215
NXWidgets::CGraphicsPort::m_backColor
nxgl_mxpixel_t m_backColor
Definition: cgraphicsport.hxx:111
singletons.hxx
NXWidgets::INxWindow::move
virtual bool move(FAR const struct nxgl_rect_s *pRect, FAR const struct nxgl_point_s *pOffset)=0
NXWidgets::CGraphicsPort::CGraphicsPort
CGraphicsPort(INxWindow *pNxWnd, nxgl_mxpixel_t backColor=CONFIG_NXWIDGETS_DEFAULT_BACKGROUNDCOLOR)
Definition: cgraphicsport.cxx:114
NXWidgets::CGraphicsPort::drawBevelledRect
void drawBevelledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t shineColor, nxgl_mxpixel_t shadowColor)
Definition: cgraphicsport.cxx:323
cgraphicsport.hxx
NXWidgets::CGraphicsPort::drawBitmap
void drawBitmap(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, const struct SBitmap *bitmap, int bitmapX, int bitmapY)
Definition: cgraphicsport.cxx:348
NXWidgets::SBitmap::fmt
uint8_t fmt
Definition: cbitmap.hxx:106
NXWidgets::CGraphicsPort::~CGraphicsPort
virtual ~CGraphicsPort()
Definition: cgraphicsport.cxx:130
NXWidgets::INxWindow::getRectangle
virtual void getRectangle(FAR const struct nxgl_rect_s *rect, struct SBitmap *dest)=0
NXWidgets::CGraphicsPort::drawHorizLine
void drawHorizLine(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:191
cwidgetstyle.hxx
NXWidgets::CGraphicsPort::drawBitmapGreyScale
void drawBitmapGreyScale(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, const struct SBitmap *bitmap, int bitmapX, int bitmapY)
Definition: cgraphicsport.cxx:528
NXWidgets::nxwidget_pixel_t
uint8_t nxwidget_pixel_t
Definition: nxconfig.hxx:442
NXWidgets::CONFIG_NXWIDGETS_FMT
CONFIG_NXWIDGETS_FMT
Definition: glyph_nxlogo160x160.cxx:3443
NXWidgets::CNxFont::getColor
const nxgl_mxpixel_t getColor() const
Definition: cnxfont.hxx:115
NXWidgets::INxWindow::setPixel
virtual bool setPixel(FAR const struct nxgl_point_s *pPos, nxgl_mxpixel_t color)=0
NXWidgets
Definition: cbgwindow.hxx:65
NXWidgets::CNxFont::getMaxWidth
const uint8_t getMaxWidth(void) const
Definition: cnxfont.hxx:218
NXWidgets::CNxFont::setColor
void setColor(const nxgl_mxpixel_t color)
Definition: cnxfont.hxx:126
NXWidgets::CGraphicsPort::greyScale
void greyScale(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height)
Definition: cgraphicsport.cxx:912
NXWidgets::INxWindow::ELineCaps
ELineCaps
Definition: inxwindow.hxx:86
NXWidgets::nxwidget_char_t
uint16_t nxwidget_char_t
Definition: nxconfig.hxx:454
nxconfig.hxx
NXWidgets::INxWindow::drawLine
virtual bool drawLine(FAR struct nxgl_vector_s *vector, nxgl_coord_t width, nxgl_mxpixel_t color, enum ELineCaps caps)=0
inxwindow.hxx
NXWidgets::CNxFont
Definition: cnxfont.hxx:70
NXWidgets::SBitmap::bpp
uint8_t bpp
Definition: cbitmap.hxx:105
NXWidgets::CGraphicsPort::drawFilledRect
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:280
NXWidgets::CNxFont::drawChar
void drawChar(FAR SBitmap *bitmap, nxwidget_char_t letter)
Definition: cnxfont.cxx:114
NXWidgets::CGraphicsPort::drawLine
void drawLine(nxgl_coord_t x1, nxgl_coord_t y1, nxgl_coord_t x2, nxgl_coord_t y2, nxgl_mxpixel_t color, enum INxWindow::ELineCaps caps)
Definition: cgraphicsport.cxx:253
NXWidgets::INxWindow::getPosition
virtual bool getPosition(FAR struct nxgl_point_s *pPos)=0
NXWidgets::CGraphicsPort::invert
void invert(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height)
Definition: cgraphicsport.cxx:995
NXWidgets::SBitmap::height
nxgl_coord_t height
Definition: cbitmap.hxx:108
NXWidgets::SBitmap::data
FAR const void * data
Definition: cbitmap.hxx:110
NXWidgets::CNxFont::getHeight
const uint8_t getHeight(void) const
Definition: cnxfont.hxx:229
NXWidgets::CRect
Definition: crect.hxx:101
NXWidgets::CGraphicsPort::getX
const nxgl_coord_t getX(void) const
Definition: cgraphicsport.cxx:144
NXWidgets::SBitmap::width
nxgl_coord_t width
Definition: cbitmap.hxx:107
cnxfont.hxx
NXWidgets::CGraphicsPort::drawPixel
void drawPixel(nxgl_coord_t x, nxgl_coord_t y, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:173
NXWidgets::INxWindow::fill
virtual bool fill(FAR const struct nxgl_rect_s *pRect, nxgl_mxpixel_t color)=0
cbitmap.hxx
NXWidgets::CNxString
Definition: cnxstring.hxx:121
NXWidgets::SBitmap
Definition: cbitmap.hxx:103
NXWidgets::CGraphicsPort::move
void move(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t deltaX, nxgl_coord_t deltaY, nxgl_coord_t width, nxgl_coord_t height)
Definition: cgraphicsport.cxx:886
bitmap
static const NXWidgets::SRlePaletteBitmapEntry bitmap[]
Definition: glyph_mediaplayer24x24.cxx:85
NXWidgets::CONFIG_NXWIDGETS_BPP
CONFIG_NXWIDGETS_BPP
Definition: glyph_arrowdown.cxx:146
NXWidgets::INxWindow
Definition: inxwindow.hxx:83
cnxstring.hxx
NXWidgets::CGraphicsPort::_drawText
void _drawText(struct nxgl_point_s *pos, CRect *bound, CNxFont *font, const CNxString &string, int startIndex, int length, nxgl_mxpixel_t background, bool transparent)
Definition: cgraphicsport.cxx:706
NXWidgets::SBitmap::stride
uint16_t stride
Definition: cbitmap.hxx:109
NXWidgets::CNxFont::getCharMetrics
void getCharMetrics(nxwidget_char_t letter, FAR struct nx_fontmetric_s *metrics) const
Definition: cnxfont.cxx:220
NXWidgets::CGraphicsPort::drawText
void drawText(struct nxgl_point_s *pos, CRect *bound, CNxFont *font, const CNxString &string)
Definition: cgraphicsport.cxx:609
NXWidgets::CGraphicsPort::drawRect
void drawRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:302
crect.hxx