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

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

2971059
    if (!font || !string_copy.gx_string_ptr)
397
    {
398
        /* Yes, one of the input pointers are NULL.  */
399
388
        return(GX_PTR_ERROR);
400
    }
401
402
2970671
    if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
403
    {
404
1587
        return _gx_system_string_width_compressed_font_get(font, &string_copy, return_width);
405
    }
406
#if defined(GX_FONT_KERNING_SUPPORT)
407
    else
408
    {
409
        if (font -> gx_font_format & GX_FONT_FORMAT_KERNING)
410
        {
411
            return _gx_system_string_width_kerning_font_get(font, &string_copy, return_width);
412
        }
413
    }
414
#endif
415
416
    /* Process complete string.  */
417
22250563
    while (string_copy.gx_string_length > 0)
418
    {
419
        /* Pickup first character of the string.  */
420
#ifdef GX_UTF8_SUPPORT
421
19281799
        ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
422
423

19281799
        if ((ret != GX_SUCCESS) || (char_val == 0))
424
#else
425
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr);
426
        string_copy.gx_string_ptr++;
427
        string_copy.gx_string_length--;
428
429
        if (char_val == 0)
430
#endif /* GX_UTF8_SUPPORT */
431
        {
432
            break;
433
        }
434
435
19281479
        font_link = font;
436
21825578
        while (font_link)
437
        {
438
21566041
            if (char_val >= font_link -> gx_font_first_glyph &&
439
21125313
                char_val <= font_link -> gx_font_last_glyph)
440
            {
441
19021942
                break;
442
            }
443
2544099
            font_link = font_link -> gx_font_next_page;
444
        }
445
19281479
        if (font_link)
446
        {
447
19021942
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
448
19021942
            glyph = &font_link -> gx_font_glyphs.gx_font_normal_glyphs[char_val];
449
19021942
            width += glyph -> gx_glyph_advance;
450
        }
451
    }
452
453
    /* Setup return width.  */
454
2969084
    if (width > 0x7fff)
455
    {
456
1
        width = 0x7fff;
457
    }
458
2969084
    *return_width =  (GX_VALUE)width;
459
460
    /* Return successful completion.  */
461
2969084
    return(GX_SUCCESS);
462
}
463