GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_rich_text_view_line_info_get.c Lines: 68 68 100.0 %
Date: 2024-12-05 08:52:37 Branches: 48 48 100.0 %

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

17279
        if ((!escape) && (text.gx_string_ptr[0] == '\\'))
111
        {
112
50
            escape = GX_TRUE;
113
50
            text.gx_string_ptr++;
114
50
            text.gx_string_length--;
115
50
            line_info -> gx_rich_text_line_info_text.gx_string_length++;
116
50
            continue;
117
        }
118
119
        /* Test rich text tags. */
120
17229
        if ((!escape) &&
121

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

663
                 line_info -> gx_rich_text_line_info_text_width && (text.gx_string_ptr[0] != ' '))
201
        {
202
470
            if (break_info.gx_rich_text_line_info_text_width == 0)
203
            {
204
40
                break;
205
            }
206
207
430
            *line_info = break_info;
208
430
            break;
209
        }
210
211
        /* Increase text width by glyph width. */
212
15087
        line_info -> gx_rich_text_line_info_text_width = (UINT)(line_info -> gx_rich_text_line_info_text_width + (USHORT)glyph_width);
213
15087
        line_info -> gx_rich_text_line_info_text.gx_string_length += glyph_len;
214
215

15087
        if ((text.gx_string_ptr[0] == ' ') || (text.gx_string_ptr[0] == ',') || (text.gx_string_ptr[0] == ';'))
216
        {
217
            /* Update line info when encounter word break character. */
218
2481
            break_info = *line_info;
219
220
2481
            if (tail_space_width)
221
            {
222
2171
                break_info.gx_rich_text_line_info_text_width -= (UINT)tail_space_width;
223
            }
224
        }
225
226
        /* Increaset next draw text length. */
227
15087
        text.gx_string_ptr += glyph_len;
228
15087
        text.gx_string_length -= glyph_len;
229
230
15087
        escape = GX_FALSE;
231
    }
232
233
1181
    return GX_SUCCESS;
234
}
235