GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_multi_line_text_view_display_info_get.c Lines: 68 68 100.0 %
Date: 2026-08-28 02:37:13 Branches: 52 54 96.3 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026 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
// Some portions generated by Copilot (Sonnet 4.6).
13
// Some portions generated by Claude Code (Opus 5).
14
15
16
/**************************************************************************/
17
/**************************************************************************/
18
/**                                                                       */
19
/** GUIX Component                                                        */
20
/**                                                                       */
21
/**   Multi Line Text View Management (Multi Line Text View)              */
22
/**                                                                       */
23
/**************************************************************************/
24
25
#define GX_SOURCE_CODE
26
27
28
/* Include necessary system files.  */
29
30
#include "gx_api.h"
31
#include "gx_system.h"
32
#include "gx_multi_line_text_view.h"
33
#include "gx_utility.h"
34
#include "gx_widget.h"
35
36
/**************************************************************************/
37
/*                                                                        */
38
/*  FUNCTION                                               RELEASE        */
39
/*                                                                        */
40
/*    _gx_multi_line_text_view_display_info_get           PORTABLE C      */
41
/*                                                           6.1          */
42
/*  AUTHOR                                                                */
43
/*                                                                        */
44
/*    Kenneth Maxwell, Microsoft Corporation                              */
45
/*                                                                        */
46
/*  DESCRIPTION                                                           */
47
/*                                                                        */
48
/*    This function gets the length and pixel width of one word or        */
49
/*      some characters can be displayed in one line.                     */
50
/*                                                                        */
51
/*  INPUT                                                                 */
52
/*                                                                        */
53
/*    text_view                             Multi line text view          */
54
/*                                            control block               */
55
/*    start_index                           Start character position in   */
56
/*                                            the input buffer            */
57
/*    end_index                             End character position in the */
58
/*                                            input buffer                */
59
/*    text_info                             Text and word information to  */
60
/*                                            be returned                 */
61
/*    available_width                       Width available to display    */
62
/*                                            text in current line        */
63
/*                                                                        */
64
/*  OUTPUT                                                                */
65
/*                                                                        */
66
/*    None                                                                */
67
/*                                                                        */
68
/*  CALLS                                                                 */
69
/*                                                                        */
70
/*    _gx_widget_font_get                   Retrieve font                 */
71
/*    _gx_system_string_width_get           Get the width of a string     */
72
/*    _gx_system_private_string_get         Get string pointer in a       */
73
/*                                            dynamically copied string   */
74
/*                                            buffer                      */
75
/*    _gx_utility_utf8_string_character_get Parse utf8 string to          */
76
/*                                            multi-byte glyph            */
77
/*                                                                        */
78
/*  CALLED BY                                                             */
79
/*                                                                        */
80
/*    GUIX Internal Code                                                  */
81
/*                                                                        */
82
/**************************************************************************/
83
133485
VOID _gx_multi_line_text_view_display_info_get(GX_MULTI_LINE_TEXT_VIEW *text_view, UINT start_index,
84
                                               UINT end_index, GX_MULTI_LINE_TEXT_INFO *text_info, GX_VALUE available_width)
85
{
86
#ifdef GX_UTF8_SUPPORT
87
133485
UINT      current_index = start_index;
88
#endif
89
GX_STRING string;
90
GX_STRING ch;
91
GX_VALUE  char_width;
92
USHORT    display_width;
93
USHORT    display_number;
94
133485
UINT      glyph_len = 1;
95
GX_FONT  *font;
96
97
133485
    text_info -> gx_text_display_width = 0;
98
133485
    text_info -> gx_text_display_number = 0;
99
100
✓✓
133485
    if (text_view -> gx_multi_line_text_view_text_id)
101
    {
102
1751
        _gx_widget_string_get_ext((GX_WIDGET *)text_view, text_view -> gx_multi_line_text_view_text_id, &string);
103
    }
104
    else
105
    {
106
131734
        _gx_system_private_string_get(&text_view -> gx_multi_line_text_view_text, &string, text_view -> gx_widget_style);
107
    }
108
109
110
133485
    string.gx_string_ptr += start_index;
111
133485
    string.gx_string_length = end_index - start_index;
112
113
✓✓
133485
    if (text_view -> gx_widget_status & GX_STATUS_LINE_BREAK_PROCESSED)
114
    {
115
        /* Line breaking alreay preprocessed, only need to search for line break characters to do line break. */
116
✓✓
447
        while (string.gx_string_length > 0)
117
        {
118
✓✓
434
            if (string.gx_string_ptr[0] == GX_KEY_CARRIAGE_RETURN)
119
            {
120
16
                text_info -> gx_text_display_number++;
121
122
✓✓✓✓
16
                if ((string.gx_string_length > 1) && string.gx_string_ptr[1] == GX_KEY_LINE_FEED)
123
                {
124
1
                    text_info -> gx_text_display_number++;
125
                }
126
16
                break;
127
            }
128
✓✓
418
            else if (string.gx_string_ptr[0] == GX_KEY_LINE_FEED)
129
            {
130
1
                text_info -> gx_text_display_number++;
131
1
                break;
132
            }
133
            else
134
            {
135
417
                text_info -> gx_text_display_number++;
136
            }
137
138
417
            string.gx_string_length--;
139
417
            string.gx_string_ptr++;
140
        }
141
    }
142
    else
143
    {
144
133455
        _gx_widget_font_get((GX_WIDGET *)text_view, text_view -> gx_multi_line_text_view_font_id, &font);
145
146
✓✓
133455
        if (!font)
147
        {
148
1
            return;
149
        }
150
151
133454
        display_width = 0;
152
133454
        display_number = 0;
153
154
✓✓
1217894
        while (string.gx_string_length > 0)
155
        {
156
1212203
            ch = string;
157
158
#ifdef GX_UTF8_SUPPORT
159
1212203
            _gx_utility_utf8_string_character_get(&string, GX_NULL, &glyph_len);
160
1212203
            current_index += glyph_len;
161
#else
162
            string.gx_string_ptr++;
163
            string.gx_string_length--;
164
#endif /* GX_UTF8_SUPPORT */
165
166
1212203
            ch.gx_string_length = glyph_len;
167
1212203
            _gx_system_string_width_get_ext(font, &ch, &char_width);
168
169
✓✓
1212203
            if (ch.gx_string_ptr[0] == GX_KEY_CARRIAGE_RETURN)
170
            {
171
                /* string now points at the byte after ch, and its length is the
172
                   number of bytes still readable there. A GX_STRING carries its
173
                   own length and need not be NUL terminated, so the byte after a
174
                   trailing carriage return may lie outside the caller's buffer:
175
                   it must not be examined. */
176
✓✓✓✓
90378
                if ((string.gx_string_length > 0) && (string.gx_string_ptr[0] == GX_KEY_LINE_FEED))
177
                {
178
1870
                    text_info -> gx_text_display_number = (USHORT)(text_info -> gx_text_display_number + 2);
179
                }
180
                else
181
                {
182
88508
                    text_info -> gx_text_display_number++;
183
                }
184
90378
                break;
185
            }
186
✓✓
1121825
            else if (ch.gx_string_ptr[0] == GX_KEY_LINE_FEED)
187
            {
188
11434
                text_info -> gx_text_display_number++;
189
11434
                break;
190
            }
191
✓✓
1110391
            else if (((text_info -> gx_text_display_width + char_width) > available_width - 1) &&
192
✓✓
26137
                     (text_info -> gx_text_display_number > 0))
193
            {
194
✓✓
25951
                if (ch.gx_string_ptr[0] == ' ')
195
                {
196
                    /* Space itself causes overflow: consume it and any consecutive
197
                       trailing spaces so the next line starts at the next word.
198
                       Do NOT add to display_width -- the line's visual width stays
199
                       within available_width. */
200
1821
                    text_info -> gx_text_display_number = (USHORT)(text_info -> gx_text_display_number + glyph_len);
201
✓✓✓✓
26859
                    while ((string.gx_string_length > 0) && (string.gx_string_ptr[0] == ' '))
202
                    {
203
25038
                        text_info -> gx_text_display_number++;
204
25038
                        string.gx_string_ptr++;
205
25038
                        string.gx_string_length--;
206
                    }
207
208
                    /* If that whitespace ran to the end of the source line, take the
209
                       line terminator with it. Left behind, the terminator becomes a
210
                       row of its own, which draws as a blank line that is not present
211
                       in the text. */
212
✓✓
1821
                    if (string.gx_string_length > 0)
213
                    {
214
✓✓
1791
                        if (string.gx_string_ptr[0] == GX_KEY_CARRIAGE_RETURN)
215
                        {
216
1
                            text_info -> gx_text_display_number++;
217
218
✓✗✓✗
1
                            if ((string.gx_string_length > 1) && (string.gx_string_ptr[1] == GX_KEY_LINE_FEED))
219
                            {
220
1
                                text_info -> gx_text_display_number++;
221
                            }
222
                        }
223
✓✓
1790
                        else if (string.gx_string_ptr[0] == GX_KEY_LINE_FEED)
224
                        {
225
40
                            text_info -> gx_text_display_number++;
226
                        }
227
                        else
228
                        {
229
                            /* More text follows the whitespace, so the next row starts
230
                               at the next word. */
231
                        }
232
                    }
233
234
1821
                    break;
235
                }
236
✓✓
24130
                if (display_number == 0)
237
                {
238
8028
                    break;
239
                }
240
16102
                text_info -> gx_text_display_width = display_width;
241
16102
                text_info -> gx_text_display_number = display_number;
242
16102
                break;
243
            }
244
1084440
            text_info -> gx_text_display_width = (USHORT)(text_info -> gx_text_display_width + char_width);
245
1084440
            text_info -> gx_text_display_number = (USHORT)(text_info -> gx_text_display_number + glyph_len);
246
247
✓✓✓✓
✓✓
1084440
            if ((ch.gx_string_ptr[0] == ' ') || (ch.gx_string_ptr[0] == ',') || (ch.gx_string_ptr[0] == ';'))
248
            {
249
184590
                display_width = text_info -> gx_text_display_width;
250
184590
                display_number = text_info -> gx_text_display_number;
251
            }
252
        }
253
    }
254
}
255