Arm-2D  
2D Image Processing Library for Cortex-M Processors
arm_2d_draw.h
1/*
2 * Copyright (C) 2022 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: Arm-2D Library
21 * Title: #include "arm_2d_draw.h"
22 * Description: Public header file to contain the APIs for colour space
23 * conversions
24 *
25 * $Date: 07. July 2023
26 * $Revision: V.1.0.6
27 *
28 * Target Processor: Cortex-M cores
29 * -------------------------------------------------------------------- */
30
31#ifndef __ARM_2D_DRAW_H__
32#define __ARM_2D_DRAW_H__
33
34/*============================ INCLUDES ======================================*/
35
36#include "arm_2d_types.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42#if defined(__clang__)
43# pragma clang diagnostic push
44# pragma clang diagnostic ignored "-Wunknown-warning-option"
45# pragma clang diagnostic ignored "-Wreserved-identifier"
46# pragma clang diagnostic ignored "-Wdeclaration-after-statement"
47# pragma clang diagnostic ignored "-Wsign-conversion"
48# pragma clang diagnostic ignored "-Wpadded"
49# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
50#endif
51
52/*!
53 * \addtogroup Drawing 3 Drawing Operations
54 * @{
55 */
56
57/*============================ MACROS ========================================*/
58/*============================ MACROFIED FUNCTIONS ===========================*/
59
60#define arm_2dp_c8bit_draw_point arm_2dp_gray8_draw_point
61#define arm_2dp_rgb16_draw_point arm_2dp_rgb565_draw_point
62#define arm_2dp_rgb32_draw_point arm_2dp_cccn888_draw_point
63
64#define arm_2d_c8bit_draw_point(__TARGET_ADDR, /* target tile address */ \
65 __LOCATION, /* point coordinate */ \
66 __COLOUR) /* target colour */ \
67 arm_2dp_gray8_draw_point(NULL, \
68 (__TARGET_ADDR), \
69 (__LOCATION), \
70 (__COLOUR), \
71 (255))
72
73#define arm_2d_rgb16_draw_point(__TARGET_ADDR, /* target tile address */ \
74 __LOCATION, /* point coordinate */ \
75 __COLOUR) /* target colour */ \
76 arm_2dp_rgb565_draw_point(NULL, \
77 (__TARGET_ADDR), \
78 (__LOCATION), \
79 (__COLOUR), \
80 (255))
81
82#define arm_2d_rgb32_draw_point(__TARGET_ADDR, /* target tile address */ \
83 __LOCATION, /* point coordinate */ \
84 __COLOUR) /* target colour */ \
85 arm_2dp_cccn888_draw_point(NULL, \
86 (__TARGET_ADDR), \
87 (__LOCATION), \
88 (__COLOUR), \
89 (255))
90
91#define arm_2d_gray8_draw_point(__TARGET_ADDR, /* target tile address */ \
92 __LOCATION, /* point coordinate */ \
93 __COLOUR, /* target colour */ \
94 ...) \
95 arm_2dp_gray8_draw_point(NULL, \
96 (__TARGET_ADDR), \
97 (__LOCATION), \
98 (__COLOUR), \
99 (255,##__VA_ARGS__))
100
101#define arm_2d_rgb565_draw_point(__TARGET_ADDR, /* target tile address */ \
102 __LOCATION, /* point coordinate */ \
103 __COLOUR, /* target colour */ \
104 ...) \
105 arm_2dp_rgb565_draw_point(NULL, \
106 (__TARGET_ADDR), \
107 (__LOCATION), \
108 (__COLOUR), \
109 (255,##__VA_ARGS__))
110
111#define arm_2d_cccn888_draw_point(__TARGET_ADDR, /* target tile address */ \
112 __LOCATION, /* point coordinate */ \
113 __COLOUR, /* target colour */ \
114 ...) \
115 arm_2dp_cccn888_draw_point(NULL, \
116 (__TARGET_ADDR), \
117 (__LOCATION), \
118 (__COLOUR), \
119 (255,##__VA_ARGS__))
120
121
122#define arm_2d_c8bit_draw_pattern( __PATTERN_ADDR, /* pattern tile address */ \
123 __TARGET_ADDR, /* target tile address*/ \
124 __REGION_ADDR, /* target region address*/ \
125 __MODE, /* draw mode */ \
126 __FG_COLOUR, /* foreground colour */ \
127 __BG_COLOUR) /* background colour */ \
128 arm_2dp_c8bit_draw_pattern(NULL, \
129 (__PATTERN_ADDR), \
130 (__TARGET_ADDR), \
131 (__REGION_ADDR), \
132 (__MODE), \
133 (__FG_COLOUR), \
134 (__BG_COLOUR))
135
136#define arm_2d_rgb16_draw_pattern( __PATTERN_ADDR, /* pattern tile address */ \
137 __TARGET_ADDR, /* target tile address*/ \
138 __REGION_ADDR, /* target region address*/ \
139 __MODE, /* draw mode */ \
140 __FG_COLOUR, /* foreground colour */ \
141 __BG_COLOUR) /* background colour */ \
142 arm_2dp_rgb16_draw_pattern(NULL, \
143 (__PATTERN_ADDR), \
144 (__TARGET_ADDR), \
145 (__REGION_ADDR), \
146 (__MODE), \
147 (__FG_COLOUR), \
148 (__BG_COLOUR))
149
150#define arm_2d_rgb32_draw_pattern( __PATTERN_ADDR, /* pattern tile address */ \
151 __TARGET_ADDR, /* target tile address*/ \
152 __REGION_ADDR, /* target region address*/ \
153 __MODE, /* draw mode */ \
154 __FG_COLOUR, /* foreground colour */ \
155 __BG_COLOUR) /* background colour */ \
156 arm_2dp_rgb32_draw_pattern(NULL, \
157 (__PATTERN_ADDR), \
158 (__TARGET_ADDR), \
159 (__REGION_ADDR), \
160 (__MODE), \
161 (__FG_COLOUR), \
162 (__BG_COLOUR))
163
164#define arm_2d_c8bit_fill_colour( __TARGET_ADDR, /* target tile address*/ \
165 __REGION_ADDR, /* target region address*/ \
166 __COLOUR) /* colour */ \
167 arm_2dp_c8bit_fill_colour(NULL, \
168 (__TARGET_ADDR), \
169 (__REGION_ADDR), \
170 (__COLOUR))
171
172#define arm_2d_rgb16_fill_colour( __TARGET_ADDR, /* target tile address*/ \
173 __REGION_ADDR, /* target region address*/ \
174 __COLOUR) /* colour */ \
175 arm_2dp_rgb16_fill_colour(NULL, \
176 (__TARGET_ADDR), \
177 (__REGION_ADDR), \
178 (__COLOUR))
179
180#define arm_2d_rgb32_fill_colour( __TARGET_ADDR, /* target tile address*/ \
181 __REGION_ADDR, /* target region address*/ \
182 __COLOUR) /* colour */ \
183 arm_2dp_rgb32_fill_colour(NULL, \
184 (__TARGET_ADDR), \
185 (__REGION_ADDR), \
186 (__COLOUR))
187
188/*============================ TYPES =========================================*/
189
190/*!
191 * \brief the control block for colour-filling-operations
192 * \note arm_2d_op_fill_cl_t inherits from arm_2d_op_t explicitly
193 */
194typedef struct arm_2d_op_fill_cl_t {
196 struct {
197 const arm_2d_tile_t *ptTile; //!< target tile
198 const arm_2d_region_t *ptRegion; //!< target region
199 } Target;
200 union {
201 uint8_t chColour; //!< 8bit colour
202 uint16_t hwColour; //!< 16bit colour
203 uint32_t wColour; //!< 32bit colour
204 };
206
207/*!
208 * \brief the control block for drawing point
209 * \note arm_2d_op_drw_pt_t inherits from arm_2d_op_t explicitly
210 */
211typedef struct arm_2d_op_drw_pt_t {
213 struct {
214 const arm_2d_tile_t *ptTile; //!< target tile
215 const arm_2d_region_t *ptRegion; //!< target region
216 } Target;
217 union {
218 uint8_t chColour; //!< 8bit colour
219 uint16_t hwColour; //!< 16bit colour
220 uint32_t wColour; //!< 32bit colour
221 };
222 uint8_t chOpaicty;
223 arm_2d_region_t tTargetRegion;
225
226/*!
227 * \brief the control block for draw-bit-pattern operations
228 * \note arm_2d_op_drw_patn_t inherits from arm_2d_op_src_t explicitly
229 */
230typedef struct arm_2d_op_drw_patn_t {
232
233 struct {
234 const arm_2d_tile_t *ptTile; //!< target tile
235 const arm_2d_region_t *ptRegion; //!< target region
236 } Target;
237 struct {
238 const arm_2d_tile_t *ptTile; //!< source tile
239 }Source;
240 uint32_t wMode; //!< mode of the operation
241 union {
242 uint8_t chColour; //!< 8bit colour
243 uint16_t hwColour; //!< 16bit colour
244 uint32_t wColour; //!< 32bit colour
245 }Foreground; //!< forground colour
246 union {
247 uint8_t chColour; //!< 8bit colour
248 uint16_t hwColour; //!< 16bit colour
249 uint32_t wColour; //!< 32bit colour
250 }Background; //!< background colour
251
253
254
255/*!
256 * \brief modes for copying bit-patterns
257 */
258enum {
259 ARM_2D_DRW_PATN_MODE_COPY = 0, //!< copy bit pattern
260 //ARM_2D_DRW_PATN_MODE_FILL = _BV(0), //!< not support yet
261 //ARM_2D_DRW_PATN_MODE_Y_MIRROR = _BV(2), //!< not support yet
262 //ARM_2D_DRW_PATN_MODE_X_MIRROR = _BV(3), //!< not support yet
263 ARM_2D_DRW_PATN_MODE_WITH_BG_COLOR = _BV(4), //!< use user specified backgound colour
264 ARM_2D_DRW_PATN_MODE_NO_FG_COLOR = _BV(5), //!< no forground
265
266 /*! use complementary colour as foreground colour
267 *
268 * \note this option is only avaialble when ARM_2D_DRW_PATN_MODE_NO_FG_COLOR
269 * is used together.
270 */
272};
273
274/*============================ GLOBAL VARIABLES ==============================*/
275/*============================ PROTOTYPES ====================================*/
276
277/*----------------------------------------------------------------------------*
278 * Draw a point with specified colour *
279 *----------------------------------------------------------------------------*/
280
281/*!
282 * \brief draw a point on a root tile with a given 8bit colour
283 * \param[in] ptTarget the target root tile
284 * \param[in] tLocation the target location
285 * \note the point must be inside the region of the target tile
286 * \param[in] chColour an 8bit colour
287 */
288ARM_NONNULL(1)
289__STATIC_INLINE void arm_2d_c8bit_draw_point_fast( const arm_2d_tile_t *ptTarget,
290 const arm_2d_location_t tLocation,
291 uint_fast8_t chColour)
292{
293 assert(NULL != ptTarget);
294 assert(ptTarget->tInfo.bIsRoot); // must be root tile
295 assert(tLocation.iX < ptTarget->tRegion.tSize.iWidth);
296 assert(tLocation.iY < ptTarget->tRegion.tSize.iHeight);
297
298 uint8_t *pchPoint = ptTarget->pchBuffer
299 + tLocation.iY * ptTarget->tRegion.tSize.iWidth
300 + tLocation.iX;
301 *pchPoint = (uint8_t)chColour;
302}
303
304/*!
305 * \brief draw a point on a root tile with a given 16bit colour
306 * \param[in] ptTarget the target root tile
307 * \param[in] tLocation the target location
308 * \note the point must be inside the region of the target tile
309 * \param[in] hwColour an 16bit colour
310 */
311ARM_NONNULL(1)
312__STATIC_INLINE void arm_2d_rgb16_draw_point_fast(
313 const arm_2d_tile_t *ptTarget,
314 const arm_2d_location_t tLocation,
315 uint_fast16_t hwColour)
316{
317 assert(NULL != ptTarget);
318 assert(ptTarget->tInfo.bIsRoot); // must be root tile
319 assert(tLocation.iX < ptTarget->tRegion.tSize.iWidth);
320 assert(tLocation.iY < ptTarget->tRegion.tSize.iHeight);
321
322 uint16_t *phwPoint = ptTarget->phwBuffer
323 + tLocation.iY * ptTarget->tRegion.tSize.iWidth
324 + tLocation.iX;
325 *phwPoint = (uint16_t)hwColour;
326}
327
328/*!
329 * \brief draw a point on a root tile with a given 32bit colour
330 * \param[in] ptTarget the target root tile
331 * \param[in] tLocation the target location
332 * \note the point must be inside the region of the target tile
333 * \param[in] wColour an 32bit colour
334 */
335ARM_NONNULL(1)
336__STATIC_INLINE void arm_2d_rgb32_draw_point_fast(
337 const arm_2d_tile_t *ptTarget,
338 const arm_2d_location_t tLocation,
339 uint32_t wColour)
340{
341 assert(NULL != ptTarget);
342 assert(ptTarget->tInfo.bIsRoot); // must be root tile
343 assert(tLocation.iX < ptTarget->tRegion.tSize.iWidth);
344 assert(tLocation.iY < ptTarget->tRegion.tSize.iHeight);
345
346 uint32_t *pwPoint = ptTarget->pwBuffer
347 + tLocation.iY * ptTarget->tRegion.tSize.iWidth
348 + tLocation.iX;
349 *pwPoint = wColour;
350}
351
352/*!
353 * \brief draw a point with a given gray8 colour
354 * \param[in] ptOP the control block, NULL means using the default control block
355 * \param[in] ptTarget the target root tile
356 * \param[in] tLocation the target location
357 * \param[in] chColour an 8bit colour
358 * \param[in] chOpacity the point opacity
359 * \return arm_fsm_rt_t the operation result
360 *
361 * \note As those draw point APIs involve the region calculation
362 * which is only useful when partial framebuffer is used, it is slow.
363 * For gettting better performance, if the target tile is root and the
364 * target location is inside the target region, please use the
365 * functions with "_fast" posfix.
366 *
367 */
368extern
369ARM_NONNULL(2)
371 const arm_2d_tile_t *ptTarget,
372 const arm_2d_location_t tLocation,
373 uint_fast8_t chColour,
374 uint8_t chOpacity);
375
376/*!
377 * \brief draw a point with a given rgb565 colour
378 * \param[in] ptOP the control block, NULL means using the default control block
379 * \param[in] ptTarget the target root tile
380 * \param[in] tLocation the target location
381 * \param[in] hwColour an 16bit colour
382 * \param[in] chOpacity the point opacity
383 * \return arm_fsm_rt_t the operation result
384 *
385 * \note As those draw point APIs involve the region calculation
386 * which is only useful when partial framebuffer is used, it is slow.
387 * For gettting better performance, if the target tile is root and the
388 * target location is inside the target region, please use the
389 * functions with "_fast" posfix.
390 *
391 */
392extern
393ARM_NONNULL(2)
395 const arm_2d_tile_t *ptTarget,
396 const arm_2d_location_t tLocation,
397 uint_fast16_t hwColour,
398 uint8_t chOpacity);
399
400/*!
401 * \brief draw a point with a given cccn888 colour
402 * \param[in] ptOP the control block, NULL means using the default control block
403 * \param[in] ptTarget the target root tile
404 * \param[in] tLocation the target location
405 * \param[in] wColour an 32bit colour
406 * \param[in] chOpacity the point opacity
407 * \return arm_fsm_rt_t the operation result
408 *
409 * \note As those draw point APIs involve the region calculation
410 * which is only useful when partial framebuffer is used, it is slow.
411 * For gettting better performance, if the target tile is root and the
412 * target location is inside the target region, please use the
413 * functions with "_fast" posfix.
414 *
415 */
416extern
417ARM_NONNULL(2)
419 const arm_2d_tile_t *ptTarget,
420 const arm_2d_location_t tLocation,
421 uint32_t wColour,
422 uint8_t chOpacity);
423
424
425#if 0 // todo: draw point with alpha
426extern
427ARM_NONNULL(1)
428arm_fsm_rt_t arm_2d_rgba8888_draw_point(const arm_2d_tile_t *ptTarget,
429 const arm_2d_location_t tLocation,
431#endif
432
433
434/*----------------------------------------------------------------------------*
435 * Draw a bit patterns *
436 *----------------------------------------------------------------------------*/
437
438/*!
439 * \brief copy a bit-pattern with given 8bit colours
440 * \param[in] ptOP the control block, NULL means using the default control block
441 * \param[in] ptPattern the source bit pattern
442 * \param[in] ptTarget the target tile
443 * \param[in] ptRegion the target region
444 * \param[in] wMode the copy mode
445 * \param[in] chForeColour the foreground colour
446 * \param[in] chBackColour the background colour
447 * \return arm_fsm_rt_t the operation result
448 */
449extern
450ARM_NONNULL(2,3)
452 const arm_2d_tile_t *ptPattern,
453 const arm_2d_tile_t *ptTarget,
454 const arm_2d_region_t *ptRegion,
455 uint32_t wMode,
456 uint8_t chForeColour,
457 uint8_t chBackColour);
458
459/*!
460 * \brief copy a bit-pattern with given 16bit colours
461 * \param[in] ptOP the control block, NULL means using the default control block
462 * \param[in] ptPattern the source bit pattern
463 * \param[in] ptTarget the target tile
464 * \param[in] ptRegion the target region
465 * \param[in] wMode the copy mode
466 * \param[in] hwForeColour the foreground colour
467 * \param[in] hwBackColour the background colour
468 * \return arm_fsm_rt_t the operation result
469 */
470extern
471ARM_NONNULL(2,3)
473 const arm_2d_tile_t *ptPattern,
474 const arm_2d_tile_t *ptTarget,
475 const arm_2d_region_t *ptRegion,
476 uint32_t wMode,
477 uint16_t hwForeColour,
478 uint16_t hwBackColour);
479
480/*!
481 * \brief copy a bit-pattern with given 32bit colours
482 * \param[in] ptOP the control block, NULL means using the default control block
483 * \param[in] ptPattern the source bit pattern
484 * \param[in] ptTarget the target tile
485 * \param[in] ptRegion the target region
486 * \param[in] wMode the copy mode
487 * \param[in] wForeColour the foreground colour
488 * \param[in] wBackColour the background colour
489 * \return arm_fsm_rt_t the operation result
490 */
491extern
492ARM_NONNULL(2,3)
494 const arm_2d_tile_t *ptPattern,
495 const arm_2d_tile_t *ptTarget,
496 const arm_2d_region_t *ptRegion,
497 uint32_t wMode,
498 uint32_t wForeColour,
499 uint32_t wBackColour);
500
501/*----------------------------------------------------------------------------*
502 * Fill tile with a specified colour *
503 *----------------------------------------------------------------------------*/
504
505/*!
506 * \brief fill the target region with a given 8bit colour
507 * \param[in] ptOP the control block, NULL means using the default control block
508 * \param[in] ptTarget the target tile
509 * \param[in] ptRegion the target region
510 * \param[in] chColour a 8bit colour
511 * \return arm_fsm_rt_t the operation result
512 */
513extern
514ARM_NONNULL(2)
516 const arm_2d_tile_t *ptTarget,
517 const arm_2d_region_t *ptRegion,
518 uint_fast8_t chColour);
519
520/*!
521 * \brief fill the target region with a given 16bit colour
522 * \param[in] ptOP the control block, NULL means using the default control block
523 * \param[in] ptTarget the target tile
524 * \param[in] ptRegion the target region
525 * \param[in] hwColour a 16bit colour
526 * \return arm_fsm_rt_t the operation result
527 */
528extern
529ARM_NONNULL(2)
531 const arm_2d_tile_t *ptTarget,
532 const arm_2d_region_t *ptRegion,
533 uint_fast16_t hwColour);
534
535/*!
536 * \brief fill the target region with a given 32bit colour
537 * \param[in] ptOP the control block, NULL means using the default control block
538 * \param[in] ptTarget the target tile
539 * \param[in] ptRegion the target region
540 * \param[in] wColour a 32bit colour
541 * \return arm_fsm_rt_t the operations result
542 */
543extern
544ARM_NONNULL(2)
546 const arm_2d_tile_t *ptTarget,
547 const arm_2d_region_t *ptRegion,
548 uint32_t wColour);
549
550
551/*! @} */
552
553#if defined(__clang__)
554# pragma clang diagnostic pop
555#endif
556
557#ifdef __cplusplus
558}
559#endif
560
561#endif