GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_canvas_text_draw.c Lines: 87 88 98.9 %
Date: 2024-12-05 08:52:37 Branches: 40 41 97.6 %

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

1027693
    if ((font == GX_NULL) || (font -> gx_font_glyphs.gx_font_normal_glyphs == GX_NULL))
180
    {
181
2
        return GX_INVALID_FONT;
182
    }
183
1027691
    display = context -> gx_draw_context_display;
184
185
1027691
    _gx_system_string_width_get_ext(font, string, &width);
186
187
    /* calculate bounding rectangle */
188
1027691
    _gx_utility_rectangle_define(&bound, x_start, y_start,
189
1027691
                                 (GX_VALUE)(x_start + width - 1),
190
1027691
                                 (GX_VALUE)(y_start + font -> gx_font_line_height));
191
192
    /* check to see if the text is in the dirty area */
193
194
1027691
    if (!_gx_utility_rectangle_overlap_detect(&bound, &context -> gx_draw_context_dirty, &bound))
195
    {
196
60210
        return(GX_SUCCESS);
197
    }
198
199
    /*  loop through viewports, painting text into each that overlaps
200
        text bound
201
     */
202
967481
    view = context -> gx_draw_context_view_head;
203
204
967481
    draw_position.gx_point_x = x_start;
205
967481
    draw_position.gx_point_y = y_start;
206
207
    /* use this for underline position, if needed */
208
967481
    y_start = (GX_VALUE)(y_start + font -> gx_font_baseline + 1);
209
210

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