GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_system_string_width_get.c Lines: 54 54 100.0 %
Date: 2026-03-06 19:21:09 Branches: 42 42 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
/**   System Management (System)                                          */
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
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_system_string_width_compressed_font_get         PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This service gets the width (in pixels) of the supplied string,     */
44
/*    for a given compressed font.                                        */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    font                                  Pointer to font of strings    */
49
/*    string                                Pointer to string             */
50
/*    string_length                         Raw length of string, in bytes*/
51
/*    return_width                          Destination for width of      */
52
/*                                            string                      */
53
/*                                                                        */
54
/*  OUTPUT                                                                */
55
/*                                                                        */
56
/*    status                                Completion status             */
57
/*                                                                        */
58
/*  CALLS                                                                 */
59
/*                                                                        */
60
/*    _gx_utility_utf8_string_character_get                               */
61
/*                                                                        */
62
/*  CALLED BY                                                             */
63
/*                                                                        */
64
/*    Application Code                                                    */
65
/*                                                                        */
66
/**************************************************************************/
67
1587
static UINT  _gx_system_string_width_compressed_font_get(GX_CONST GX_FONT *font,
68
                                                         GX_STRING *string,
69
                                                         GX_VALUE *return_width)
70
{
71
1587
INT                           width = 0;
72
GX_CHAR_CODE                  char_val;
73
GX_CONST GX_COMPRESSED_GLYPH *glyph;
74
GX_CONST GX_FONT             *font_link;
75
1587
GX_STRING                     string_copy = *string;
76
77
#ifdef GX_UTF8_SUPPORT
78
UINT ret;
79
#endif /* GX_UTF8_SUPPORT */
80
81
    /* Process complete string.  */
82
14534
    while (string_copy.gx_string_length > 0)
83
    {
84
#ifdef GX_UTF8_SUPPORT
85
11362
        ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
86
87

11362
        if ((ret != GX_SUCCESS) || (char_val == 0))
88
#else
89
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr);
90
        string_copy.gx_string_ptr++;
91
        string_copy.gx_string_length--;
92
93
        if (char_val == 0)
94
#endif /* GX_UTF8_SUPPORT */
95
        {
96
            break;
97
        }
98
99
11360
        font_link = font;
100
13735
        while (font_link)
101
        {
102
13714
            if (char_val >= font_link -> gx_font_first_glyph &&
103
13693
                char_val <= font_link -> gx_font_last_glyph)
104
            {
105
11339
                break;
106
            }
107
2375
            font_link = font_link -> gx_font_next_page;
108
        }
109
11360
        if (font_link)
110
        {
111
11339
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
112
11339
            glyph = &font_link -> gx_font_glyphs.gx_font_compressed_glyphs[char_val];
113
114
11339
            width += glyph -> gx_glyph_advance;
115
        }
116
    }
117
118
    /* Setup return width.  */
119
1587
    *return_width =  (GX_VALUE)width;
120
121
    /* Return successful completion.  */
122
1587
    return(GX_SUCCESS);
123
}
124
125
/**************************************************************************/
126
/*                                                                        */
127
/*  FUNCTION                                               RELEASE        */
128
/*                                                                        */
129
/*    _gx_system_string_width_kerning_font_get            PORTABLE C      */
130
/*                                                           6.1          */
131
/*  AUTHOR                                                                */
132
/*                                                                        */
133
/*    Kenneth Maxwell, Microsoft Corporation                              */
134
/*                                                                        */
135
/*  DESCRIPTION                                                           */
136
/*                                                                        */
137
/*    This service gets the width (in pixels) of the supplied string,     */
138
/*    for a given compressed font.                                        */
139
/*                                                                        */
140
/*  INPUT                                                                 */
141
/*                                                                        */
142
/*    font                                  Pointer to font of strings    */
143
/*    string                                Pointer to string             */
144
/*    string_length                         Raw length of string, in bytes*/
145
/*    return_width                          Destination for width of      */
146
/*                                            string                      */
147
/*                                                                        */
148
/*  OUTPUT                                                                */
149
/*                                                                        */
150
/*    status                                Completion status             */
151
/*                                                                        */
152
/*  CALLS                                                                 */
153
/*                                                                        */
154
/*    _gx_utility_utf8_string_character_get                               */
155
/*                                                                        */
156
/*  CALLED BY                                                             */
157
/*                                                                        */
158
/*    Application Code                                                    */
159
/*                                                                        */
160
/**************************************************************************/
161
#if defined(GX_FONT_KERNING_SUPPORT)
162
static UINT  _gx_system_string_width_kerning_font_get(GX_CONST GX_FONT *font,
163
                                                      GX_CONST GX_STRING *string,
164
                                                      GX_VALUE *return_width)
165
{
166
INT                        width = 0;
167
GX_CHAR_CODE               char_val;
168
GX_CONST GX_KERNING_GLYPH *glyph;
169
GX_CONST GX_FONT          *font_link;
170
GX_STRING                  string_copy;
171
172
/* Used for kerning glyph. */
173
GX_CHAR_CODE       pre_char_val = 0;
174
GX_CHAR            kerning_offset = 0;
175
GX_CONST GX_UBYTE *kerning_table;
176
INT                kerning_counts;
177
INT                index;
178
GX_UBYTE          *left_glyph_ptr;
179
180
#ifdef GX_UTF8_SUPPORT
181
UINT ret;
182
#endif /* GX_UTF8_SUPPORT */
183
184
    string_copy = *string;
185
186
    /* Process complete string.  */
187
    while (string_copy.gx_string_length > 0)
188
    {
189
#ifdef GX_UTF8_SUPPORT
190
        ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
191
        if ((ret != GX_SUCCESS) || (char_val == 0))
192
#else
193
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr++);
194
        string_copy.gx_string_length--;
195
        if (char_val == 0)
196
#endif /* GX_UTF8_SUPPORT */
197
        {
198
            break;
199
        }
200
201
        font_link = font;
202
        while (font_link)
203
        {
204
            if (char_val >= font_link -> gx_font_first_glyph &&
205
                char_val <= font_link -> gx_font_last_glyph)
206
            {
207
                break;
208
            }
209
            font_link = font_link -> gx_font_next_page;
210
        }
211
        if (font_link)
212
        {
213
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
214
215
            glyph = &font_link -> gx_font_glyphs.gx_font_kerning_glyphs[char_val];
216
            kerning_table = glyph -> gx_kerning_table;
217
218
            if (kerning_table && (pre_char_val != 0))
219
            {
220
                /* Search the kerning table for the kerning value. */
221
                kerning_counts = *kerning_table;
222
                left_glyph_ptr = (GX_UBYTE *)(kerning_table + 1);
223
224
                for (index = 0; index < kerning_counts; index++)
225
                {
226
                    if ((*left_glyph_ptr) == (pre_char_val + font_link -> gx_font_first_glyph))
227
                    {
228
                        kerning_offset = (GX_CHAR)(*(left_glyph_ptr + 1));
229
                        break;
230
                    }
231
                    left_glyph_ptr += 2;
232
                }
233
            }
234
235
            width += glyph -> gx_glyph_advance;
236
            width += kerning_offset;
237
        }
238
        /* Store previous character value. */
239
        pre_char_val = char_val;
240
        kerning_offset = 0;
241
    }
242
243
    /* Setup return width.  */
244
    *return_width =  (GX_VALUE)width;
245
246
    /* Return successful completion.  */
247
    return(GX_SUCCESS);
248
}
249
#endif
250
251
/**************************************************************************/
252
/*                                                                        */
253
/*  FUNCTION                                               RELEASE        */
254
/*                                                                        */
255
/*    _gx_system_string_width_get                         PORTABLE C      */
256
/*                                                           6.1          */
257
/*  AUTHOR                                                                */
258
/*                                                                        */
259
/*    Kenneth Maxwell, Microsoft Corporation                              */
260
/*                                                                        */
261
/*  DESCRIPTION                                                           */
262
/*                                                                        */
263
/*    This service gets the width (in pixels) of the supplied string,     */
264
/*    for a given font.                                                   */
265
/*                                                                        */
266
/*  INPUT                                                                 */
267
/*                                                                        */
268
/*    font                                  Pointer to font of strings    */
269
/*    string                                Pointer to string             */
270
/*    string_length                         Raw length of string, in bytes*/
271
/*    return_width                          Destination for width of      */
272
/*                                            string                      */
273
/*                                                                        */
274
/*  OUTPUT                                                                */
275
/*                                                                        */
276
/*    status                                Completion status             */
277
/*                                                                        */
278
/*  CALLS                                                                 */
279
/*                                                                        */
280
/*    _gx_utility_utf8_string_character_get                               */
281
/*                                                                        */
282
/*  CALLED BY                                                             */
283
/*                                                                        */
284
/*    Application Code                                                    */
285
/*                                                                        */
286
/**************************************************************************/
287
#if defined(GX_ENABLE_DEPRECATED_STRING_API)
288
3
UINT  _gx_system_string_width_get(GX_CONST GX_FONT *font, GX_CONST GX_CHAR *text, INT string_length, GX_VALUE *return_width)
289
{
290
3
UINT      status = GX_SUCCESS;
291
3
UINT      length = 0;
292
GX_STRING string;
293
294
3
    string.gx_string_ptr = text;
295
3
    if (string_length >= 0)
296
    {
297
1
        string.gx_string_length = (UINT)string_length;
298
    }
299
    else
300
    {
301
2
        status = _gx_utility_string_length_check(text, &length, GX_MAX_STRING_LENGTH);
302
2
        if (status == GX_SUCCESS)
303
        {
304
1
            string.gx_string_length = length;
305
        }
306
    }
307
3
    if (status == GX_SUCCESS)
308
    {
309
2
        status = _gx_system_string_width_get_ext(font, &string, return_width);
310
    }
311
3
    return status;
312
}
313
#endif
314
315
/**************************************************************************/
316
/*                                                                        */
317
/*  FUNCTION                                               RELEASE        */
318
/*                                                                        */
319
/*    _gx_system_string_width_get_ext                     PORTABLE C      */
320
/*                                                           6.1          */
321
/*  AUTHOR                                                                */
322
/*                                                                        */
323
/*    Kenneth Maxwell, Microsoft Corporation                              */
324
/*                                                                        */
325
/*  DESCRIPTION                                                           */
326
/*                                                                        */
327
/*    This service gets the width (in pixels) of the supplied string,     */
328
/*    for a given font.                                                   */
329
/*                                                                        */
330
/*  INPUT                                                                 */
331
/*                                                                        */
332
/*    font                                  Pointer to font of strings    */
333
/*    string                                Pointer to string             */
334
/*    string_length                         Raw length of string, in bytes*/
335
/*    return_width                          Destination for width of      */
336
/*                                            string                      */
337
/*                                                                        */
338
/*  OUTPUT                                                                */
339
/*                                                                        */
340
/*    status                                Completion status             */
341
/*                                                                        */
342
/*  CALLS                                                                 */
343
/*                                                                        */
344
/*    _gx_utility_utf8_string_character_get                               */
345
/*                                                                        */
346
/*  CALLED BY                                                             */
347
/*                                                                        */
348
/*    Application Code                                                    */
349
/*                                                                        */
350
/**************************************************************************/
351
2971059
UINT  _gx_system_string_width_get_ext(GX_CONST GX_FONT *font, GX_CONST GX_STRING *string, GX_VALUE *return_width)
352
{
353
354
2971059
INT                width = 0;
355
GX_CHAR_CODE       char_val;
356
GX_CONST GX_GLYPH *glyph;
357
GX_CONST GX_FONT  *font_link;
358
2971059
GX_STRING          string_copy = *string;
359
360
#ifdef GX_UTF8_SUPPORT
361
UINT ret;
362
#endif /* GX_UTF8_SUPPORT */
363
364
    /* Check for NULL pointers.  */
365

2971059
    if (!font || !string_copy.gx_string_ptr)
366
    {
367
        /* Yes, one of the input pointers are NULL.  */
368
388
        return(GX_PTR_ERROR);
369
    }
370
371
2970671
    if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
372
    {
373
1587
        return _gx_system_string_width_compressed_font_get(font, &string_copy, return_width);
374
    }
375
#if defined(GX_FONT_KERNING_SUPPORT)
376
    else
377
    {
378
        if (font -> gx_font_format & GX_FONT_FORMAT_KERNING)
379
        {
380
            return _gx_system_string_width_kerning_font_get(font, &string_copy, return_width);
381
        }
382
    }
383
#endif
384
385
    /* Process complete string.  */
386
25219647
    while (string_copy.gx_string_length > 0)
387
    {
388
        /* Pickup first character of the string.  */
389
#ifdef GX_UTF8_SUPPORT
390
19281799
        ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
391
392

19281799
        if ((ret != GX_SUCCESS) || (char_val == 0))
393
#else
394
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr);
395
        string_copy.gx_string_ptr++;
396
        string_copy.gx_string_length--;
397
398
        if (char_val == 0)
399
#endif /* GX_UTF8_SUPPORT */
400
        {
401
            break;
402
        }
403
404
19281479
        font_link = font;
405
21825578
        while (font_link)
406
        {
407
21566041
            if (char_val >= font_link -> gx_font_first_glyph &&
408
21125313
                char_val <= font_link -> gx_font_last_glyph)
409
            {
410
19021942
                break;
411
            }
412
2544099
            font_link = font_link -> gx_font_next_page;
413
        }
414
19281479
        if (font_link)
415
        {
416
19021942
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
417
19021942
            glyph = &font_link -> gx_font_glyphs.gx_font_normal_glyphs[char_val];
418
19021942
            width += glyph -> gx_glyph_advance;
419
        }
420
    }
421
422
    /* Setup return width.  */
423
2969084
    if (width > 0x7fff)
424
    {
425
1
        width = 0x7fff;
426
    }
427
2969084
    *return_width =  (GX_VALUE)width;
428
429
    /* Return successful completion.  */
430
2969084
    return(GX_SUCCESS);
431
}
432