GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_canvas_text_draw.c Lines: 87 88 98.9 %
Date: 2026-03-06 19:21:09 Branches: 40 41 97.6 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Canvas Management (Canvas)                                          */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
#include "gx_canvas.h"
31
#include "gx_context.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_canvas_text_draw                                PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function prepares to draw text.                                */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    x_start                               X-coordinate, text left edge  */
50
/*    y_start                               Y-coordinate, text baseline   */
51
/*    string                                String to draw                */
52
/*    length                                Length of string to draw      */
53
/*                                                                        */
54
/*  OUTPUT                                                                */
55
/*                                                                        */
56
/*    status                                Completion status             */
57
/*                                                                        */
58
/*  CALLS                                                                 */
59
/*                                                                        */
60
/*    _gx_utility_string_length_check       Verify string length          */
61
/*    _gx_canvas_text_draw_ext              Actual text draw function    */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    _gx_multi_line_text_view_draw                                       */
66
/*    _gx_single_line_text_input_draw                                     */
67
/*    _gx_widget_text_draw                                                */
68
/*                                                                        */
69
/**************************************************************************/
70
#if defined(GX_ENABLE_DEPRECATED_STRING_API)
71
8999
UINT  _gx_canvas_text_draw(GX_VALUE x_start, GX_VALUE y_start, GX_CONST GX_CHAR *text, INT length)
72
{
73
GX_STRING string;
74
UINT      count;
75
UINT      status;
76
77
8999
    string.gx_string_ptr = text;
78
79
8999
    if (length >= 0)
80
    {
81
8994
        string.gx_string_length = (UINT)length;
82
    }
83
    else
84
    {
85
5
        status = _gx_utility_string_length_check(text, &count, GX_MAX_STRING_LENGTH);
86
5
        if (status != GX_SUCCESS)
87
        {
88
1
            return status;
89
        }
90
4
        string.gx_string_length = count;
91
    }
92
8998
    status = _gx_canvas_text_draw_ext(x_start, y_start, &string);
93
8998
    return status;
94
}
95
#endif
96
97
/**************************************************************************/
98
/*                                                                        */
99
/*  FUNCTION                                               RELEASE        */
100
/*                                                                        */
101
/*    _gx_canvas_text_draw_ext                            PORTABLE C      */
102
/*                                                           6.1.3        */
103
/*  AUTHOR                                                                */
104
/*                                                                        */
105
/*    Kenneth Maxwell, Microsoft Corporation                              */
106
/*                                                                        */
107
/*  DESCRIPTION                                                           */
108
/*                                                                        */
109
/*    This function prepares to draw text.                                */
110
/*                                                                        */
111
/*  INPUT                                                                 */
112
/*                                                                        */
113
/*    x_start                               X-coordinate, text left edge  */
114
/*    y_start                               Y-coordinate, text baseline   */
115
/*    string                                String to draw                */
116
/*                                                                        */
117
/*  OUTPUT                                                                */
118
/*                                                                        */
119
/*    status                                Completion status             */
120
/*                                                                        */
121
/*  CALLS                                                                 */
122
/*                                                                        */
123
/*    _gx_utility_rectangle_define          Initialize a rectangle        */
124
/*    _gx_system_string_width_get           Get width of the string in    */
125
/*                                            pixels                      */
126
/*    _gx_utility_rectangle_overlap_detect  Determine if two rectangles   */
127
/*                                            overlap                     */
128
/*    _gx_canvas_glyphs_draw                Draw glyphs on canvas         */
129
/*    [gx_display_driver_horizontal_line_draw]                            */
130
/*                                       The display driver horizontal    */
131
/*                                         line drawing function          */
132
/*                                                                        */
133
/*  CALLED BY                                                             */
134
/*                                                                        */
135
/*    _gx_multi_line_text_view_draw                                       */
136
/*    _gx_single_line_text_input_draw                                     */
137
/*    _gx_widget_text_draw                                                */
138
/*                                                                        */
139
/**************************************************************************/
140
1027693
UINT  _gx_canvas_text_draw_ext(GX_VALUE x_start, GX_VALUE y_start, GX_CONST GX_STRING *string)
141
{
142
GX_RECTANGLE bound;
143
GX_RECTANGLE clip;
144
GX_VIEW     *view;
145
GX_VALUE     width;
146
GX_POINT     draw_position;
147
GX_DISPLAY  *display;
148
VOID         (*glyph_draw)(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area,
149
                           GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph);
150
1027693
UINT         status = GX_FAILURE;
151
152
/* pickup pointer to current context */
153
1027693
GX_DRAW_CONTEXT *context = _gx_system_current_draw_context;
154
155
/* get pointer to current font */
156
1027693
GX_FONT *font = context -> gx_draw_context_brush.gx_brush_font;
157
158
1027693
    width = 0;
159
160

1027693
    if ((font == GX_NULL) || (font -> gx_font_glyphs.gx_font_normal_glyphs == GX_NULL))
161
    {
162
2
        return GX_INVALID_FONT;
163
    }
164
1027691
    display = context -> gx_draw_context_display;
165
166
1027691
    _gx_system_string_width_get_ext(font, string, &width);
167
168
    /* calculate bounding rectangle */
169
1027691
    _gx_utility_rectangle_define(&bound, x_start, y_start,
170
1027691
                                 (GX_VALUE)(x_start + width - 1),
171
1027691
                                 (GX_VALUE)(y_start + font -> gx_font_line_height));
172
173
    /* check to see if the text is in the dirty area */
174
175
1027691
    if (!_gx_utility_rectangle_overlap_detect(&bound, &context -> gx_draw_context_dirty, &bound))
176
    {
177
60210
        return(GX_SUCCESS);
178
    }
179
180
    /*  loop through viewports, painting text into each that overlaps
181
        text bound
182
     */
183
967481
    view = context -> gx_draw_context_view_head;
184
185
967481
    draw_position.gx_point_x = x_start;
186
967481
    draw_position.gx_point_y = y_start;
187
188
    /* use this for underline position, if needed */
189
967481
    y_start = (GX_VALUE)(y_start + font -> gx_font_baseline + 1);
190
191

967481
    switch (font -> gx_font_format & GX_FONT_FORMAT_BPP_MASK)
192
    {
193
248546
    case GX_FONT_FORMAT_1BPP:
194
248546
        if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
195
        {
196
410
            glyph_draw = display -> gx_display_driver_1bit_compressed_glyph_draw;
197
        }
198
        else
199
        {
200
248136
            glyph_draw = display -> gx_display_driver_1bit_glyph_draw;
201
        }
202
248546
        break;
203
204
97895
    case GX_FONT_FORMAT_4BPP:
205
97895
        if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
206
        {
207
51
            glyph_draw = display -> gx_display_driver_4bit_compressed_glyph_draw;
208
        }
209
        else
210
        {
211
97844
            glyph_draw = display -> gx_display_driver_4bit_glyph_draw;
212
        }
213
97895
        break;
214
215
621039
    case GX_FONT_FORMAT_8BPP:
216
621039
        if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
217
        {
218
78
            glyph_draw = display -> gx_display_driver_8bit_compressed_glyph_draw;
219
        }
220
        else
221
        {
222
620961
            glyph_draw = display -> gx_display_driver_8bit_glyph_draw;
223
        }
224
621039
        break;
225
226
1
    default:
227
1
        glyph_draw = GX_NULL;
228
1
        break;
229
    }
230
231
967481
    if (glyph_draw)
232
    {
233
1968007
        while (view)
234
        {
235
1000527
            if (_gx_utility_rectangle_overlap_detect(&view -> gx_view_rectangle, &bound, &clip))
236
            {
237
960993
                _gx_canvas_glyphs_draw(context, &draw_position, string, &clip, glyph_draw);
238
239
960993
                if (context -> gx_draw_context_brush.gx_brush_style & GX_BRUSH_UNDERLINE)
240
                {
241
                    /* underline the text.  */
242
243
1218
                    if (clip.gx_rectangle_top <= y_start &&
244
1217
                        clip.gx_rectangle_bottom >= y_start)
245
                    {
246
1216
                        width = context -> gx_draw_context_brush.gx_brush_width;
247
1216
                        if (width <= 0)
248
                        {
249
2
                            width = 1;
250
                        }
251
1216
                        if (y_start + width - 1 > clip.gx_rectangle_bottom)
252
                        {
253
1
                            width = (GX_VALUE)(clip.gx_rectangle_bottom - y_start + 1);
254
                        }
255
1216
                        display -> gx_display_driver_horizontal_line_draw(context,
256
1216
                                                                          clip.gx_rectangle_left,
257
1216
                                                                          clip.gx_rectangle_right,
258
                                                                          y_start, width,
259
                                                                          context -> gx_draw_context_brush.gx_brush_line_color);
260
                    }
261
                }
262
            }
263
264
1000527
            view = view -> gx_view_next;
265
        }
266
967480
        status = GX_SUCCESS;
267
    }
268
269
967481
    return(status);
270
}
271
272
/**************************************************************************/
273
/*                                                                        */
274
/*  FUNCTION                                               RELEASE        */
275
/*                                                                        */
276
/*    _gx_canvas_aligned_text_draw                        PORTABLE C      */
277
/*                                                           6.1.11       */
278
/*  AUTHOR                                                                */
279
/*                                                                        */
280
/*    Ting Zhu, Microsoft Corporation                                     */
281
/*                                                                        */
282
/*  DESCRIPTION                                                           */
283
/*                                                                        */
284
/*    This function draws text to canvas with specified alignment style.  */
285
/*                                                                        */
286
/*  INPUT                                                                 */
287
/*                                                                        */
288
/*    string                                String to draw                */
289
/*    rectangle                             Drawing area                  */
290
/*    alignment                             Alignment style               */
291
/*                                                                        */
292
/*  OUTPUT                                                                */
293
/*                                                                        */
294
/*    status                                Completion status             */
295
/*                                                                        */
296
/*  CALLS                                                                 */
297
/*                                                                        */
298
/*    _gx_context_brush_get                 Get context brush             */
299
/*    _gx_system_string_width_get_ext       Get string width              */
300
/*    _gx_canvas_text_draw_ext              Actual text draw function     */
301
/*                                                                        */
302
/*  CALLED BY                                                             */
303
/*                                                                        */
304
/*    Application Code                                                    */
305
/*    GUIX Internal Code                                                  */
306
/*                                                                        */
307
/**************************************************************************/
308
11
UINT  _gx_canvas_aligned_text_draw(GX_CONST GX_STRING *string, GX_RECTANGLE *rectangle, ULONG alignment)
309
{
310
GX_VALUE  text_width;
311
GX_VALUE  text_height;
312
GX_VALUE  x_pos;
313
GX_VALUE  y_pos;
314
GX_BRUSH *brush;
315
GX_VALUE  rect_width;
316
GX_VALUE  rect_height;
317
318
11
    _gx_context_brush_get(&brush);
319
320
11
    if (!brush -> gx_brush_font)
321
    {
322
        return GX_INVALID_FONT;
323
    }
324
325
11
    text_height = brush -> gx_brush_font -> gx_font_line_height;
326
327
11
    rect_width = (GX_VALUE)(rectangle -> gx_rectangle_right - rectangle -> gx_rectangle_left + 1);
328
11
    rect_height = (GX_VALUE)(rectangle -> gx_rectangle_bottom - rectangle -> gx_rectangle_top + 1);
329
330
11
    x_pos = rectangle -> gx_rectangle_left;
331
11
    y_pos = rectangle -> gx_rectangle_top;
332
11
    y_pos = (GX_VALUE)(y_pos + (rect_height - text_height) / 2);
333
334
11
    switch (alignment & GX_STYLE_TEXT_ALIGNMENT_MASK)
335
    {
336
2
    case GX_STYLE_TEXT_RIGHT:
337
2
        _gx_system_string_width_get_ext(brush -> gx_brush_font, string, &text_width);
338
2
        x_pos = (GX_VALUE)(x_pos + rect_width - 1);
339
2
        x_pos = (GX_VALUE)(x_pos - text_width);
340
2
        break;
341
342
2
    case GX_STYLE_TEXT_LEFT:
343
2
        break;
344
345
7
    default:
346
7
        _gx_system_string_width_get_ext(brush -> gx_brush_font, string, &text_width);
347
7
        x_pos = (GX_VALUE)(x_pos + ((rect_width - text_width) / 2));
348
7
        break;
349
    }
350
351
    /* Draw the text.  */
352
11
    return _gx_canvas_text_draw_ext(x_pos, y_pos, string);
353
}
354