GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_rich_text_view_line_info_get.c Lines: 68 68 100.0 %
Date: 2026-03-06 19:21:09 Branches: 48 48 100.0 %

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
/**   Rich Text View Management (Rich Text View)                          */
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_canvas.h"
30
#include "gx_rich_text_view.h"
31
#include "gx_utility.h"
32
#include "gx_widget.h"
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _gx_rich_text_view_line_info_get                    PORTABLE C      */
39
/*                                                           6.1.5        */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This function prepares one line text for drawing.                   */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    text_view                              Rich text view control block */
51
/*    text                                   String to process            */
52
/*    line_info                              Retrieved line information   */
53
/*                                             for drawing next line      */
54
/*    availlable_width                       Availlable width for drawing */
55
/*                                                                        */
56
/*  OUTPUT                                                                */
57
/*                                                                        */
58
/*    None                                                                */
59
/*                                                                        */
60
/*  CALLS                                                                 */
61
/*                                                                        */
62
/*    _gx_widget_font_get                   Retireve font by id           */
63
/*    _gx_rich_text_view_tag_enter          Process rich text tag         */
64
/*    _gx_utility_utf8_string_character_get Retrieve glyph length         */
65
/*    _gx_system_string_width_get           Retrieve string width         */
66
/*    _gx_system_rich_text_format_stack_clear                             */
67
/*                                          Clear rich text format stack  */
68
/*                                                                        */
69
/*  CALLED BY                                                             */
70
/*                                                                        */
71
/*    GUIX Internal Code                                                  */
72
/*                                                                        */
73
/**************************************************************************/
74
1185
UINT  _gx_rich_text_view_line_info_get(GX_RICH_TEXT_VIEW *text_view, GX_STRING text, GX_RICH_TEXT_LINE_INFO *line_info, GX_VALUE availlable_width)
75
{
76
GX_STRING              string;
77
GX_FONT               *font;
78
1185
UINT                   glyph_len = 1;
79
GX_VALUE               glyph_width;
80
GX_RICH_TEXT_LINE_INFO break_info;
81
GX_RICH_TEXT_FORMAT    text_format;
82
GX_UBYTE               processed_count;
83
1185
GX_BOOL                escape = GX_FALSE;
84
GX_RESOURCE_ID         font_id;
85
1185
INT                    tail_space_width = 0;
86
87
1185
    text_format = line_info -> gx_rich_text_line_info_start_format;
88
1185
    break_info = *line_info;
89
1185
    font_id = text_format.gx_rich_text_font_id;
90
91
    /* Pickup draw font. */
92
1185
    _gx_widget_font_get((GX_WIDGET *)text_view, text_format.gx_rich_text_font_id, &font);
93
94
1185
    if (!font)
95
    {
96
1
        return GX_INVALID_FONT;
97
    }
98
99
    /* Calculate the total rows of text view string. */
100
17621
    while (text.gx_string_length > 0)
101
    {
102

17279
        if ((!escape) && (text.gx_string_ptr[0] == '\\'))
103
        {
104
50
            escape = GX_TRUE;
105
50
            text.gx_string_ptr++;
106
50
            text.gx_string_length--;
107
50
            line_info -> gx_rich_text_line_info_text.gx_string_length++;
108
50
            continue;
109
        }
110
111
        /* Test rich text tags. */
112
17229
        if ((!escape) &&
113

18888
            (text.gx_string_ptr[0] == '<') &&
114
1709
            (_gx_rich_text_view_tag_enter(text_view, &text, &text_format, &processed_count) == GX_SUCCESS))
115
        {
116
1302
            if (text_format.gx_rich_text_font_id != font_id)
117
            {
118
                /* Font changed. */
119
632
                _gx_widget_font_get((GX_WIDGET *)text_view, text_format.gx_rich_text_font_id, &font);
120
121
632
                if (!font)
122
                {
123
2
                    return GX_INVALID_FONT;
124
                }
125
126
                /* Calculate maximum font height for one line text. */
127
630
                if (line_info -> gx_rich_text_line_info_line_height < font -> gx_font_line_height)
128
                {
129
192
                    line_info -> gx_rich_text_line_info_line_height = font -> gx_font_line_height;
130
192
                    line_info -> gx_rich_text_line_info_baseline = font -> gx_font_baseline;
131
                }
132
133
630
                font_id = text_format.gx_rich_text_font_id;
134
            }
135
136
1300
            line_info -> gx_rich_text_line_info_text.gx_string_length += processed_count;
137
1300
            line_info -> gx_rich_text_line_info_end_format = text_format;
138
139
1300
            text.gx_string_ptr += processed_count;
140
1300
            text.gx_string_length -= processed_count;
141
1300
            continue;
142
        }
143
144
#if defined GX_UTF8_SUPPORT
145
15927
        string = text;
146
147
        /* Pick up glyph length. */
148
15927
        if (_gx_utility_utf8_string_character_get(&string, GX_NULL, &glyph_len) != GX_SUCCESS)
149
        {
150
            /* Invalid UTF8 string. */
151
1
            return GX_INVALID_STRING;
152
        }
153
#endif
154
15926
        string.gx_string_ptr = text.gx_string_ptr;
155
15926
        string.gx_string_length = glyph_len;
156
157
        /* Calculate glyph width. */
158
15926
        _gx_system_string_width_get_ext(font, &string, &glyph_width);
159
160
        /* Calculate the successive space width in the end of the line. */
161
15926
        if ((text.gx_string_ptr[0] == ' '))
162
        {
163
2171
            tail_space_width += glyph_width;
164
        }
165
        else
166
        {
167
13755
            tail_space_width = 0;
168
        }
169
170
15926
        if (text.gx_string_ptr[0] == GX_KEY_CARRIAGE_RETURN)
171
        {
172
            /* Line break charater \r. */
173
367
            glyph_len = 1;
174
175
367
            if ((text.gx_string_length > 1) &&
176
366
                (text.gx_string_ptr[1] == GX_KEY_LINE_FEED))
177
            {
178
                /* Line break character \r\n. */
179
2
                glyph_len++;
180
            }
181
182
367
            line_info -> gx_rich_text_line_info_text.gx_string_length += glyph_len;
183
367
            break;
184
        }
185
15559
        else if (text.gx_string_ptr[0] == GX_KEY_LINE_FEED)
186
        {
187
            /* Line break character \n. */
188
2
            line_info -> gx_rich_text_line_info_text.gx_string_length += glyph_len;
189
2
            break;
190
        }
191
15557
        else if (((UINT)(line_info -> gx_rich_text_line_info_text_width + (USHORT)glyph_width) > (UINT)availlable_width) &&
192

663
                 line_info -> gx_rich_text_line_info_text_width && (text.gx_string_ptr[0] != ' '))
193
        {
194
470
            if (break_info.gx_rich_text_line_info_text_width == 0)
195
            {
196
40
                break;
197
            }
198
199
430
            *line_info = break_info;
200
430
            break;
201
        }
202
203
        /* Increase text width by glyph width. */
204
15087
        line_info -> gx_rich_text_line_info_text_width = (UINT)(line_info -> gx_rich_text_line_info_text_width + (USHORT)glyph_width);
205
15087
        line_info -> gx_rich_text_line_info_text.gx_string_length += glyph_len;
206
207

15087
        if ((text.gx_string_ptr[0] == ' ') || (text.gx_string_ptr[0] == ',') || (text.gx_string_ptr[0] == ';'))
208
        {
209
            /* Update line info when encounter word break character. */
210
2481
            break_info = *line_info;
211
212
2481
            if (tail_space_width)
213
            {
214
2171
                break_info.gx_rich_text_line_info_text_width -= (UINT)tail_space_width;
215
            }
216
        }
217
218
        /* Increaset next draw text length. */
219
15087
        text.gx_string_ptr += glyph_len;
220
15087
        text.gx_string_length -= glyph_len;
221
222
15087
        escape = GX_FALSE;
223
    }
224
225
1181
    return GX_SUCCESS;
226
}
227