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: 28 April 2025
25 * $Revision: V.2.11.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 IMPL_FONT_DRAW_CHAR(__NAME) \
155 arm_fsm_rt_t __NAME(const arm_2d_tile_t *ptTile, \
156 const arm_2d_region_t *ptRegion, \
157 const arm_2d_font_t *ptFont, \
158 arm_2d_tile_t *ptileChar, \
159 COLOUR_INT tForeColour, \
160 uint_fast8_t chOpacity, \
161 q16_t q16Scale)
162
163#define IMPL_FONT_GET_CHAR_DESCRIPTOR(__NAME) \
164 arm_2d_char_descriptor_t *__NAME( \
165 const arm_2d_font_t *ptFont, \
166 arm_2d_char_descriptor_t *ptDescriptor, \
167 uint8_t *pchCharCode)
168
169/*============================ TYPES =========================================*/
170
171typedef struct {
172 arm_2d_tile_t tileChar;
173 int16_t iAdvance;
174 int16_t iBearingX;
175 int16_t iBearingY;
176 int8_t chCodeLength;
177 int8_t : 8;
179
180typedef struct arm_2d_font_t arm_2d_font_t;
181
182typedef arm_2d_char_descriptor_t *arm_2d_font_get_char_descriptor_handler_t(
183 const arm_2d_font_t *ptFont,
184 arm_2d_char_descriptor_t *ptDescriptor,
185 uint8_t *pchCharCode);
186
187typedef arm_fsm_rt_t arm_2d_font_draw_char_handler_t(
188 const arm_2d_tile_t *ptTile,
189 const arm_2d_region_t *ptRegion,
190 const arm_2d_font_t *ptFont,
191 arm_2d_tile_t *ptileChar,
192 COLOUR_INT tForeColour,
193 uint_fast8_t chOpacity,
194 q16_t q16Scale);
195
196/* Font definitions */
198 arm_2d_tile_t tileFont;
200 uint32_t nCount; //!< Character count
201
202 arm_2d_font_get_char_descriptor_handler_t *fnGetCharDescriptor; //!< On-Get-Char-Descriptor event handler
203 arm_2d_font_draw_char_handler_t *fnDrawChar; //!< On-Draw-Char event handler
204};
205
206typedef struct arm_2d_char_idx_t {
207 uint8_t chStartCode[4];
208 uint16_t hwCount;
209 uint16_t hwOffset;
211
212typedef struct arm_2d_user_font_t {
214 uint16_t hwCount;
215 uint16_t hwDefaultCharIndex;
216 arm_2d_char_idx_t tLookUpTable[];
218
219typedef struct arm_2d_a1_font_t {
221 uint32_t nOffset; //!< Character offset
223
224/*============================ GLOBAL VARIABLES ==============================*/
225
226extern const arm_2d_a1_font_t ARM_2D_FONT_16x24;
227extern const arm_2d_a1_font_t ARM_2D_FONT_6x8;
228
229extern
230arm_2d_font_get_char_descriptor_handler_t
231 ARM_2D_A1_FONT_GET_CHAR_DESCRIPTOR_HANDLER;
232
233/*============================ PROTOTYPES ====================================*/
234
235/*!
236 * \brief return a valid code length of a given UTF8 char
237 * \param[in] pchChar the start address of an UTF8 char
238 * \retval -1 this isn't a legal UTF8 char
239 * \retval >0 the UTF8 char length
240 */
241__STATIC_INLINE
242ARM_NONNULL(1)
243int8_t arm_2d_helper_get_utf8_byte_valid_length(const uint8_t *pchChar)
244{
245
246 switch(__CLZ( ~((uint32_t)pchChar[0] << 24) )) {
247 case 0: /* BYTE0: 0xxx-xxxx */
248 return 1;
249 case 1:
250 break;
251 case 2: /* BYTE0: 110x-xxxx */
252 if ((pchChar[1] & 0xC0) == 0x80) { /* BYTE1: 10xx-xxxx */
253 return 2;
254 }
255 break;
256 case 3: /* BYTE0: 1110-xxxx */
257 if (((pchChar[1] & 0xC0) == 0x80) /* BYTE1: 10xx-xxxx */
258 && ((pchChar[2] & 0xC0) == 0x80)) { /* BYTE2: 10xx-xxxx */
259 return 3;
260 }
261 break;
262 case 4:
263 if (((pchChar[1] & 0xC0) == 0x80) /* BYTE1: 10xx-xxxx */
264 && ((pchChar[2] & 0xC0) == 0x80) /* BYTE2: 10xx-xxxx */
265 && ((pchChar[3] & 0xC0) == 0x80)) { /* BYTE3: 10xx-xxxx */
266 return 4;
267 }
268 break;
269 default:
270 break;
271 }
272
273 return -1;
274}
275
276/*!
277 * \brief return the code length based on the first byte of a given UTF8 char
278 * \param[in] pchChar the start address of an UTF8 char
279 * \retval -1 this isn't a legal UTF8 char
280 * \retval >0 the UTF8 char length
281 */
282__STATIC_INLINE
283ARM_NONNULL(1)
284int8_t arm_2d_helper_get_utf8_byte_length(const uint8_t *pchChar)
285{
286 switch(__CLZ( ~((uint32_t)pchChar[0] << 24) )) {
287 case 0:
288 return 1;
289 case 1:
290 break;
291 case 2:
292 return 2;
293 case 3:
294 return 3;
295 case 4:
296 return 4;
297 default:
298 break;
299 }
300
301 return -1;
302}
303
304/*!
305 * \brief convert an UTF8 char into unicode char
306 *
307 * \param[in] pchUTF8
308 * \return uint32_t generated unicode
309 */
310ARM_NONNULL(1)
311extern
312uint32_t arm_2d_helper_utf8_to_unicode(const uint8_t *pchUTF8);
313
314/*!
315 * \brief get char descriptor
316 * \param[in] ptFont the target font
317 * \param[in] ptDescriptor a buffer to store a char descriptor
318 * \param[in] pchCharCode an UTF8 Char
319 * \return arm_2d_char_descriptor_t * the descriptor
320 */
321ARM_NONNULL(1,2,3)
324 arm_2d_char_descriptor_t *ptDescriptor,
325 uint8_t *pchCharCode);
326
327/*!
328 * \brief get char advance with char spacing and scaling into consideration
329 * \param[in] pchChar a UTF8 char buffer
330 * \return int16_t the advance
331 */
332extern
333ARM_NONNULL(1)
334int16_t arm_lcd_get_char_advance(uint8_t *pchChar);
335
336/*!
337 * \brief initialize lcd text display service
338 * \param[in] ptScreen the default display area
339 */
340extern
342
343extern
344int arm_lcd_printf(const char *format, ...);
345
346/*!
347 * \brief pre-printf a string to the internal text buffer and return the string box size
348 *
349 * \param[in] ptFont the target front, passing NULL means using the previous font
350 * \param[in] format the printf format string
351 * \param[in] ... the optional argument list
352 * \return arm_2d_size_t the string box size
353 */
354extern
356 const char *format,
357 ...);
358
359extern
360ARM_NONNULL(1)
361/*!
362 * \brief put a char to line buffer
363 *
364 * \param[in] pchChar a buffer storing an UTF8 char
365 * \param[in] chUTF8Size the UTF8 size in byte
366 * \return true successful
367 * \return false line buffer is full
368 */
369bool arm_lcd_putchar_to_buffer(uint8_t *pchChar, uint_fast8_t chUTF8Size);
370
371/*!
372 * \brief print the text buffer
373 * \param[in] number of chars to print. Here:
374 * 0 means printing all chars in the text buffer
375 * >0 means printing a specified number of chars
376 * <0 means keeping a specified number of chars in the tail and printing the rest of the string
377 */
378extern
379void arm_lcd_printf_buffer(int16_t iNumber);
380
381/*!
382 * \brief get the box size of the string in the text buffer
383 *
384 * \return arm_2d_size_t the size of the text buffer
385 */
386extern
388
389/*!
390 * \brief get the residual text length in the text buffer
391 *
392 * \return size_t number of chars left
393 */
394extern
396
397extern
398ARM_NONNULL(1)
399void arm_lcd_puts_label( const char *pchString,
400 arm_2d_align_t tAlignment);
401
402
403extern
404ARM_NONNULL(2)
405int arm_lcd_printf_label(arm_2d_align_t tAlignment, const char *format, ...);
406
407extern
408void arm_lcd_puts(const char *str);
409
410extern
411void arm_lcd_text_location(uint8_t chY, uint8_t chX);
412
413extern
414void arm_lcd_text_insert_line_space(int16_t iWidth);
415
416extern
417void arm_lcd_text_reset_display_region_tracking(void);
418
419extern
420arm_2d_region_t *arm_lcd_text_get_last_display_region(void);
421
422/*!
423 * \brief draw a char to a given location in the draw region
424 * \param[in] iX the x coordinate
425 * \param[in] iY the y coordinate
426 * \param[in] ppchCharCode a pointer of pointer that points to the string
427 *
428 * \note this function will advance the pointer automatically
429 *
430 * \param[in] chOpacity the opacity of the char
431 *
432 * \note this chOpacity has NO effect on the default monochrome(A1) font
433 *
434 * \return int16_t char advance in pixels
435 */
436extern
437int16_t lcd_draw_char(int16_t iX,
438 int16_t iY,
439 uint8_t **ppchCharCode,
440 uint_fast8_t chOpacity);
441
442extern
443void arm_lcd_putchar(const char *str);
444
445extern
446void arm_lcd_text_set_colour( COLOUR_INT wForeground,
447 COLOUR_INT wBackground);
448
449extern
450void arm_lcd_text_set_opacity(uint8_t chOpacity);
451
452extern
453void arm_lcd_text_set_scale(float fScale);
454
455extern
456int8_t arm_lcd_text_set_char_spacing(int8_t chNewSpacing);
457
458extern
459int8_t arm_lcd_text_set_line_spacing(int8_t chNewSpacing);
460
461extern
462arm_2d_size_t arm_lcd_text_get_actual_spacing(void);
463
464extern
465arm_2d_size_t arm_lcd_text_get_actual_char_size(void);
466
467extern
468arm_2d_region_t arm_lcd_text_get_char_validation_box(void);
469
470extern
471arm_2d_size_t arm_lcd_text_get_actual_char_box(void);
472
473/*!
474 * \brief Force all char use the same width
475 *
476 * \param[in] bForced force or not
477 * \return boolean the original configuration
478 */
479extern
481
482extern
483void arm_lcd_text_set_target_framebuffer(const arm_2d_tile_t *ptFrameBuffer);
484
485/*!
486 * \brief set the display mode for characters
487 * \param[in] wMode the display mode which could be the combination of following
488 enum values:
489 - ARM_2D_DRW_PATN_MODE_COPY (default) - Copy without background colour
490 - ARM_2D_DRW_PATN_MODE_WITH_BG_COLOR - with background colour
491 - ARM_2D_DRW_PATN_MODE_NO_FG_COLOR - without foreground colour
492 - ARM_2D_DRW_PATH_MODE_COMP_FG_COLOUR - use complement value as the foreground colour
493 */
494
495extern
496void arm_lcd_text_set_display_mode(uint32_t wMode);
497
498extern
499void arm_lcd_text_set_draw_region(arm_2d_region_t *ptRegion);
500
501extern
502arm_2d_err_t arm_lcd_text_set_font(const arm_2d_font_t *ptFont);
503
504extern
505arm_2d_size_t __arm_lcd_get_string_line_box(const char *str, const arm_2d_font_t *ptFont);
506
507extern
508IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a8_font_draw_char);
509
510extern
511IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a4_font_draw_char);
512
513extern
514IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a2_font_draw_char);
515
516extern
517IMPL_FONT_DRAW_CHAR(__arm_2d_lcd_text_default_a1_font_draw_char);
518
519/*! @} */
520
521#if defined(__clang__)
522# pragma clang diagnostic pop
523#elif __IS_COMPILER_GCC__
524# pragma GCC diagnostic pop
525#endif
526
527#ifdef __cplusplus
528}
529#endif
530
531#endif