Arm-2D  
2D Image Processing Library for Cortex-M Processors
 
Loading...
Searching...
No Matches
arm_2d_helper_font.h
1/*
2 * Copyright (c) 2009-2021 Arm Limited. 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_helper_font.h"
22 * Description: the font helper service header file
23 *
24 * $Date: 29 July 2025
25 * $Revision: V.3.0.1
26 *
27 * Target Processor: Cortex-M cores
28 * -------------------------------------------------------------------- */
29
30#ifndef __ARM_2D_HELPER_FONT_H__
31#define __ARM_2D_HELPER_FONT_H__
32
33/*============================ INCLUDES ======================================*/
34#include <stdint.h>
35#include "arm_2d_helper.h"
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41#if defined(__clang__)
42# pragma clang diagnostic push
43# pragma clang diagnostic ignored "-Wunknown-warning-option"
44# pragma clang diagnostic ignored "-Wreserved-identifier"
45# pragma clang diagnostic ignored "-Wmissing-declarations"
46# pragma clang diagnostic ignored "-Wpadded"
47#elif __IS_COMPILER_ARM_COMPILER_5__
48# pragma diag_suppress 64
49#elif __IS_COMPILER_GCC__
50# pragma GCC diagnostic push
51# pragma GCC diagnostic ignored "-Wformat="
52# pragma GCC diagnostic ignored "-Wpedantic"
53# pragma GCC diagnostic ignored "-Wpadded"
54#endif
55
56
57/*============================ MACROS ========================================*/
58#ifndef __GLCD_CFG_COLOUR_DEPTH__
59# warning Please specify the colour depth by defining the macro __GLCD_CFG_COLOUR_DEPTH__, default value 16 is used for now
60# define __GLCD_CFG_COLOUR_DEPTH__ 16
61#endif
62
63/*!
64 * \addtogroup Deprecated
65 * @{
66 */
67/*! todo: COLOUR_INT_TYPE is deprecated, should be removed in the future */
68#if __GLCD_CFG_COLOUR_DEPTH__ == 8
69# define COLOUR_INT_TYPE uint8_t
70
71#elif __GLCD_CFG_COLOUR_DEPTH__ == 16
72# define COLOUR_INT_TYPE uint16_t
73
74#elif __GLCD_CFG_COLOUR_DEPTH__ == 32
75# define COLOUR_INT_TYPE uint32_t
76
77#else
78# error Unsupported colour depth!
79#endif
80
81/*! @} */
82
83
84#ifndef __GLCD_CFG_SCEEN_WIDTH__
85#warning Please specify the screen width by defining the macro __GLCD_CFG_SCEEN_WIDTH__, default value 320 is used for now
86#define __GLCD_CFG_SCEEN_WIDTH__ 320
87#endif
88
89#ifndef __GLCD_CFG_SCEEN_HEIGHT__
90# warning Please specify the screen height by defining the macro __GLCD_CFG_SCEEN_HEIGHT__, default value 240 is used for now
91# define __GLCD_CFG_SCEEN_HEIGHT__ 320
92#endif
93
94
95/*!
96 * \addtogroup gHelper 8 Helper Services
97 * @{
98 */
99/*============================ MACROFIED FUNCTIONS ===========================*/
100
101#if 0 // TODO in the future version when string alignment feature is available
102#define arm_lcd_banner_printf(__REGION, __FONT_PTR, __FORMAT_STR, ...) \
103 do { \
104 if (NULL != (__FONT_PTR)) { \
105 arm_lcd_text_set_font((const arm_2d_font_t *)(__FONT_PTR)); \
106 } \
107 arm_2d_region_t ARM_2D_SAFE_NAME(tTargetRegion) = (__REGION); \
108 arm_2d_align_centre( \
109 ARM_2D_SAFE_NAME(tTargetRegion), \
110 arm_lcd_get_string_line_box((__STR),(__FONT_PTR))) {\
111 arm_lcd_text_set_draw_region(&__centre_region); \
112 arm_lcd_printf(__FORMAT_STR, ##__VA_ARGS__); \
113 } \
114 } while(0)
115#endif
116
117#define __arm_print_banner3(__STR, __REGION, __FONT_PTR) \
118 do { \
119 if (NULL != (__FONT_PTR)) { \
120 arm_lcd_text_set_font((const arm_2d_font_t *)(__FONT_PTR)); \
121 } \
122 arm_2d_region_t ARM_2D_SAFE_NAME(tTargetRegion) = (__REGION); \
123 arm_2d_align_centre( \
124 ARM_2D_SAFE_NAME(tTargetRegion), \
125 arm_lcd_get_string_line_box((__STR),(__FONT_PTR))) {\
126 arm_lcd_text_set_draw_region(&__centre_region); \
127 arm_lcd_puts(__STR); \
128 } \
129 } while(0)
130
131#define __arm_print_banner2(__STR, __REGION) \
132 __arm_print_banner3(__STR, __REGION, NULL)
133
134#define __arm_print_banner1(__STR) \
135 do { \
136 arm_2d_tile_t *ARM_2D_SAFE_NAME(ptTile) \
137 = arm_2d_get_default_frame_buffer(); \
138 arm_2d_canvas(ARM_2D_SAFE_NAME(ptTile), __banner_canvas) { \
139 __arm_print_banner3(__STR, __banner_canvas, NULL); \
140 } \
141 } while(0)
142
143#define arm_print_banner(...) \
144 ARM_CONNECT2( __arm_print_banner, \
145 __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
146
147#define arm_lcd_print_banner(...) arm_print_banner(__VA_ARGS__)
148
149#define arm_lcd_get_string_line_box(__STR, ...) \
150 __arm_lcd_get_string_line_box( \
151 (__STR), \
152 (const arm_2d_font_t *)(NULL, ##__VA_ARGS__))
153
154#define arm_lcd_get_string_box(__STR, ...) \
155 __arm_lcd_get_string_box( \
156 (__STR), \
157 (const arm_2d_font_t *)(NULL, ##__VA_ARGS__))
158
159#define IMPL_FONT_DRAW_CHAR(__NAME) \
160 arm_fsm_rt_t __NAME(const arm_2d_tile_t *ptTile, \
161 const arm_2d_region_t *ptRegion, \
162 const arm_2d_font_t *ptFont, \
163 arm_2d_tile_t *ptileChar, \
164 COLOUR_INT tForeColour, \
165 uint_fast8_t chOpacity, \
166 q16_t q16Scale)
167
168#define IMPL_FONT_GET_CHAR_DESCRIPTOR(__NAME) \
169 arm_2d_char_descriptor_t *__NAME( \
170 const arm_2d_font_t *ptFont, \
171 arm_2d_char_descriptor_t *ptDescriptor, \
172 uint8_t *pchCharCode)
173
174/*============================ TYPES =========================================*/
175
176typedef struct {
177 arm_2d_tile_t tileChar;
178 int16_t iAdvance;
179 int16_t iBearingX;
180 int16_t iBearingY;
181 int8_t chCodeLength;
182 int8_t : 8;
184
185typedef struct arm_2d_font_t arm_2d_font_t;
186
187typedef arm_2d_char_descriptor_t *arm_2d_font_get_char_descriptor_handler_t(
188 const arm_2d_font_t *ptFont,
189 arm_2d_char_descriptor_t *ptDescriptor,
190 uint8_t *pchCharCode);
191
192typedef arm_fsm_rt_t arm_2d_font_draw_char_handler_t(
193 const arm_2d_tile_t *ptTile,
194 const arm_2d_region_t *ptRegion,
195 const arm_2d_font_t *ptFont,
196 arm_2d_tile_t *ptileChar,
197 COLOUR_INT tForeColour,
198 uint_fast8_t chOpacity,
199 q16_t q16Scale);
200
201/* Font definitions */
203 arm_2d_tile_t tileFont;
205 uint32_t nCount; //!< Character count
206
207 arm_2d_font_get_char_descriptor_handler_t *fnGetCharDescriptor; //!< On-Get-Char-Descriptor event handler
208 arm_2d_font_draw_char_handler_t *fnDrawChar; //!< On-Draw-Char event handler
209};
210
211typedef struct arm_2d_char_idx_t {
212 uint8_t chStartCode[4];
213 uint16_t hwCount;
214 uint16_t hwOffset;
216
217typedef struct arm_2d_user_font_t {
219 uint16_t hwCount;
220 uint16_t hwDefaultCharIndex;
221 arm_2d_char_idx_t tLookUpTable[];
223
224typedef struct arm_2d_a1_font_t {
226 uint32_t nOffset; //!< Character offset
228
229/*============================ GLOBAL VARIABLES ==============================*/
230
231extern const arm_2d_a1_font_t ARM_2D_FONT_16x24;
232extern const arm_2d_a1_font_t ARM_2D_FONT_6x8;
233
234extern
235arm_2d_font_get_char_descriptor_handler_t
236 ARM_2D_A1_FONT_GET_CHAR_DESCRIPTOR_HANDLER;
237
238/*============================ PROTOTYPES ====================================*/
239
240/*!
241 * \brief return a valid code length of a given UTF8 char
242 * \param[in] pchChar the start address of an UTF8 char
243 * \retval -1 this isn't a legal UTF8 char
244 * \retval >0 the UTF8 char length
245 */
246__STATIC_INLINE
247ARM_NONNULL(1)
248int8_t arm_2d_helper_get_utf8_byte_valid_length(const uint8_t *pchChar)
249{
250
251 switch(__CLZ( ~((uint32_t)pchChar[0] << 24) )) {
252 case 0: /* BYTE0: 0xxx-xxxx */
253 return 1;
254 case 1:
255 break;
256 case 2: /* BYTE0: 110x-xxxx */
257 if ((pchChar[1] & 0xC0) == 0x80) { /* BYTE1: 10xx-xxxx */
258 return 2;
259 }
260 break;
261 case 3: /* BYTE0: 1110-xxxx */
262 if (((pchChar[1] & 0xC0) == 0x80) /* BYTE1: 10xx-xxxx */
263 && ((pchChar[2] & 0xC0) == 0x80)) { /* BYTE2: 10xx-xxxx */
264 return 3;
265 }
266 break;
267 case 4:
268 if (((pchChar[1] & 0xC0) == 0x80) /* BYTE1: 10xx-xxxx */
269 && ((pchChar[2] & 0xC0) == 0x80) /* BYTE2: 10xx-xxxx */
270 && ((pchChar[3] & 0xC0) == 0x80)) { /* BYTE3: 10xx-xxxx */
271 return 4;
272 }
273 break;
274 default:
275 break;
276 }
277
278 return -1;
279}
280
281/*!
282 * \brief return the code length based on the first byte of a given UTF8 char
283 * \param[in] pchChar the start address of an UTF8 char
284 * \retval -1 this isn't a legal UTF8 char
285 * \retval >0 the UTF8 char length
286 */
287__STATIC_INLINE
288ARM_NONNULL(1)
289int8_t arm_2d_helper_get_utf8_byte_length(const uint8_t *pchChar)
290{
291 switch(__CLZ( ~((uint32_t)pchChar[0] << 24) )) {
292 case 0:
293 return 1;
294 case 1:
295 break;
296 case 2:
297 return 2;
298 case 3:
299 return 3;
300 case 4:
301 return 4;
302 default:
303 break;
304 }
305
306 return -1;
307}
308
309/*!
310 * \brief convert an UTF8 char into unicode char
311 *
312 * \param[in] pchUTF8
313 * \return uint32_t generated unicode
314 */
315ARM_NONNULL(1)
316extern
317uint32_t arm_2d_helper_utf8_to_unicode(const uint8_t *pchUTF8);
318
319/*!
320 * \brief get char descriptor
321 * \param[in] ptFont the target font
322 * \param[in] ptDescriptor a buffer to store a char descriptor
323 * \param[in] pchCharCode an UTF8 Char
324 * \return arm_2d_char_descriptor_t * the descriptor
325 */
326ARM_NONNULL(1,2,3)
329 arm_2d_char_descriptor_t *ptDescriptor,
330 uint8_t *pchCharCode);
331
332/*!
333 * \brief get char advance with char spacing and scaling into consideration
334 * \param[in] pchChar a UTF8 char buffer
335 * \return int16_t the advance
336 */
337extern
338ARM_NONNULL(1)
339int16_t arm_lcd_get_char_advance(uint8_t *pchChar);
340
341/*!
342 * \brief initialize lcd text display service
343 * \param[in] ptScreen the default display area
344 */
345extern
347
348extern
349int arm_lcd_printf(const char *format, ...);
350
351/*!
352 * \brief pre-printf a string to the internal text buffer and return the string box size
353 *
354 * \param[in] ptFont the target front, passing NULL means using the previous font
355 * \param[in] format the printf format string
356 * \param[in] ... the optional argument list
357 * \return arm_2d_size_t the string box size
358 */
359extern
361 const char *format,
362 ...);
363
364extern
365ARM_NONNULL(1)
366/*!
367 * \brief put a char to line buffer
368 *
369 * \param[in] pchChar a buffer storing an UTF8 char
370 * \param[in] chUTF8Size the UTF8 size in byte
371 * \return true successful
372 * \return false line buffer is full
373 */
374bool arm_lcd_putchar_to_buffer(uint8_t *pchChar, uint_fast8_t chUTF8Size);
375
376/*!
377 * \brief print the text buffer
378 * \param[in] number of chars to print. Here:
379 * 0 means printing all chars in the text buffer
380 * >0 means printing a specified number of chars
381 * <0 means keeping a specified number of chars in the tail and printing the rest of the string
382 */
383extern
384void arm_lcd_printf_buffer(int16_t iNumber);
385
386/*!
387 * \brief get the box size of the string in the text buffer
388 *
389 * \return arm_2d_size_t the size of the text buffer
390 */
391extern
393
394/*!
395 * \brief get the residual text length in the text buffer
396 *
397 * \return size_t number of chars left
398 */
399extern
401
402extern
403void arm_lcd_clear_text_buffer(void);
404
405extern
406ARM_NONNULL(1)
407void arm_lcd_puts_label( const char *pchString,
408 arm_2d_align_t tAlignment);
409
410
411extern
412ARM_NONNULL(2)
413int arm_lcd_printf_label(arm_2d_align_t tAlignment, const char *format, ...);
414
415extern
416void arm_lcd_puts(const char *str);
417
418extern
419void arm_lcd_text_location(int16_t iRow, uint16_t iColumn);
420
421extern
422void arm_lcd_text_insert_line_space(int16_t iWidth);
423
424extern
425void arm_lcd_text_reset_display_region_tracking(void);
426
427extern
428arm_2d_region_t *arm_lcd_text_get_last_display_region(void);
429
430/*!
431 * \brief draw a char to a given location in the draw region
432 * \param[in] iX the x coordinate
433 * \param[in] iY the y coordinate
434 * \param[in] ppchCharCode a pointer of pointer that points to the string
435 *
436 * \note this function will advance the pointer automatically
437 *
438 * \param[in] chOpacity the opacity of the char
439 *
440 * \note this chOpacity has NO effect on the default monochrome(A1) font
441 *
442 * \return int16_t char advance in pixels
443 */
444extern
445int16_t lcd_draw_char(int16_t iX,
446 int16_t iY,
447 uint8_t **ppchCharCode,
448 uint_fast8_t chOpacity);
449
450extern
451void arm_lcd_putchar(const char *str);
452
453extern
454void arm_lcd_text_set_colour( COLOUR_INT wForeground,
455 COLOUR_INT wBackground);
456
457extern
458void arm_lcd_text_set_opacity(uint8_t chOpacity);
459
460extern
461void arm_lcd_text_set_scale(float fScale);
462
463extern
464int8_t arm_lcd_text_set_char_spacing(int8_t chNewSpacing);
465
466extern
467int8_t arm_lcd_text_set_line_spacing(int8_t chNewSpacing);
468
469extern
470arm_2d_size_t arm_lcd_text_get_actual_spacing(void);
471
472extern
473arm_2d_size_t arm_lcd_text_get_actual_char_size(void);
474
475extern
476arm_2d_region_t arm_lcd_text_get_char_validation_box(void);
477
478extern
479arm_2d_size_t arm_lcd_text_get_actual_char_box(void);
480
481/*!
482 * \brief Force all char use the same width
483 *
484 * \param[in] bForced force or not
485 * \return boolean the original configuration
486 */
487extern
489
490extern
491void arm_lcd_text_set_target_framebuffer(const arm_2d_tile_t *ptFrameBuffer);
492
493/*!
494 * \brief set the display mode for characters
495 * \param[in] wMode the display mode which could be the combination of following
496 enum values:
497 - ARM_2D_DRW_PATN_MODE_COPY (default) - Copy without background colour
498 - ARM_2D_DRW_PATN_MODE_WITH_BG_COLOR - with background colour
499 - ARM_2D_DRW_PATN_MODE_NO_FG_COLOR - without foreground colour
500 - ARM_2D_DRW_PATH_MODE_COMP_FG_COLOUR - use complement value as the foreground colour
501 */
502
503extern
504void arm_lcd_text_set_display_mode(uint32_t wMode);
505
506extern
507void arm_lcd_text_set_draw_region(arm_2d_region_t *ptRegion);
508
509extern
510arm_2d_err_t arm_lcd_text_set_font(const arm_2d_font_t *ptFont);
511
512extern
513/*!
514 * \brief get the string line actual size.
515 * \note the calculation stops at the first `\n`
516 *
517 * \param[in] pchString the target UTF8 string
518 * \param[in] ptFont the target Font, NULL means using the current font
519 * return arm_2d_size_t the string line size
520 */
521ARM_NONNULL(1)
522arm_2d_size_t __arm_lcd_get_string_line_box(const char *pchString, const arm_2d_font_t *ptFont);
523
524extern
525/*!
526 * \brief get the string actual size.
527 *
528 * \param[in] pchString the target UTF8 string
529 * \param[in] ptFont the target Font, NULL means using the current font
530 * return arm_2d_size_t the string line size
531 */
532ARM_NONNULL(1)
533arm_2d_size_t __arm_lcd_get_string_box(const char *pchString, const arm_2d_font_t *ptFont);
534
535extern
536IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a8_font_draw_char);
537
538extern
539IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a4_font_draw_char);
540
541extern
542IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a2_font_draw_char);
543
544extern
545IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a1_font_draw_char);
546
547/*! @} */
548
549#if defined(__clang__)
550# pragma clang diagnostic pop
551#elif __IS_COMPILER_GCC__
552# pragma GCC diagnostic pop
553#endif
554
555#ifdef __cplusplus
556}
557#endif
558
559#endif