GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_canvas_glyphs_draw.c Lines: 93 93 100.0 %
Date: 2024-12-05 08:52:37 Branches: 70 70 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
/**   Canvas Management (Canvas)                                          */
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
#include "gx_canvas.h"
30
31
#if defined(GX_FONT_KERNING_SUPPORT)
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_canvas_kerning_glyphs_draw                      PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function prepares to draw text.                                */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    context                               Drawing context               */
49
/*    font                                  Font used by the string       */
50
/*    draw_position                         Coord of draw position        */
51
/*    string                                Pointer to string which need  */
52
/*                                            to draw                     */
53
/*    length                                Number of string about to draw*/
54
/*    view                                  Pointer to view size          */
55
/*    draw_glyph                            Callback pointer to display   */
56
/*                                            driver text draw function   */
57
/*                                                                        */
58
/*  OUTPUT                                                                */
59
/*                                                                        */
60
/*                                                                        */
61
/*  CALLS                                                                 */
62
/*                                                                        */
63
/*    _gx_utility_utf8_string_character_get                               */
64
/*                                    Get characters of this string       */
65
/*                                                                        */
66
/*  CALLED BY                                                             */
67
/*                                                                        */
68
/*    _gx_canvas_glyph_draw                                               */
69
/*                                                                        */
70
/*  RELEASE HISTORY                                                       */
71
/*                                                                        */
72
/*    DATE              NAME                      DESCRIPTION             */
73
/*                                                                        */
74
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
75
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
76
/*                                            resulting in version 6.1    */
77
/*                                                                        */
78
/**************************************************************************/
79
static VOID _gx_canvas_kerning_glyphs_draw(GX_DRAW_CONTEXT *context, GX_FONT *font, GX_POINT *draw_position, GX_CONST GX_STRING *string, GX_RECTANGLE *view,
80
                                           VOID (*draw_glyph)(GX_DRAW_CONTEXT *, GX_RECTANGLE *, GX_POINT *, GX_CONST GX_GLYPH *))
81
{
82
GX_CONST GX_KERNING_GLYPH *glyph;
83
GX_CHAR_CODE               char_val;
84
GX_VALUE                   x_offset;
85
GX_VALUE                   y_offset;
86
GX_VALUE                   xstart;
87
GX_VALUE                   ystart;
88
GX_POINT                   map_offset;
89
GX_RECTANGLE               draw_area;
90
GX_CONST GX_FONT          *font_link;
91
92
/* Used for kerning glyph. */
93
GX_CHAR_CODE       pre_char_val = 0;
94
GX_BYTE            kerning_offset = 0;
95
GX_CONST GX_UBYTE *kerning_table;
96
INT                kerning_counts;
97
INT                index;
98
GX_UBYTE          *left_glyph_ptr;
99
GX_STRING          string_copy;
100
101
#if defined(GX_UTF8_SUPPORT)
102
UINT ret;
103
#endif /* GX_UTF8_SUPPORT */
104
105
    /* Setup local variables.  */
106
107
    xstart = draw_position -> gx_point_x;
108
    ystart = draw_position -> gx_point_y;
109
    string_copy = *string;
110
111
    /* for each character in the string */
112
    do
113
    {
114
#ifdef GX_UTF8_SUPPORT
115
        ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
116
117
        if ((ret != GX_SUCCESS) || (char_val == 0))
118
#else
119
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr++);
120
        string_copy.gx_string_length--;
121
122
        if (char_val == 0)
123
#endif /* GX_UTF8_SUPPORT */
124
        {
125
            break;
126
        }
127
128
        font_link = font;
129
        while (font_link)
130
        {
131
            if (char_val >= font_link -> gx_font_first_glyph &&
132
                char_val <= font_link -> gx_font_last_glyph)
133
            {
134
                break;
135
            }
136
            font_link = font_link -> gx_font_next_page;
137
        }
138
139
        if (font_link)
140
        {
141
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
142
143
            glyph = &((GX_CONST GX_KERNING_GLYPH *)font_link -> gx_font_glyphs.gx_font_kerning_glyphs)[char_val];
144
            kerning_table = ((GX_KERNING_GLYPH *)glyph) -> gx_kerning_table;
145
            if (kerning_table && (pre_char_val != 0))
146
            {
147
                /* Search the kerning table for the kerning value. */
148
                kerning_counts = *kerning_table;
149
                left_glyph_ptr = (GX_UBYTE *)(kerning_table + 1);
150
151
                for (index = 0; index < kerning_counts; index++)
152
                {
153
                    if ((*left_glyph_ptr) == (pre_char_val + font_link -> gx_font_first_glyph))
154
                    {
155
                        kerning_offset = (GX_CHAR)(*(left_glyph_ptr + 1));
156
                        break;
157
                    }
158
                    left_glyph_ptr += 2;
159
                }
160
            }
161
162
            if (glyph -> gx_glyph_map)
163
            {
164
                x_offset = (GX_VALUE)(xstart + glyph -> gx_glyph_leading);
165
                x_offset = (GX_VALUE)(x_offset + kerning_offset);
166
                y_offset = (GX_VALUE)(ystart + font_link -> gx_font_baseline - glyph -> gx_glyph_ascent);
167
168
                draw_area.gx_rectangle_left = x_offset;
169
                draw_area.gx_rectangle_top = y_offset;
170
                draw_area.gx_rectangle_right = (GX_VALUE)(draw_area.gx_rectangle_left + glyph -> gx_glyph_width - 1);
171
                draw_area.gx_rectangle_bottom = (GX_VALUE)(draw_area.gx_rectangle_top + glyph -> gx_glyph_height - 1);
172
173
                if (draw_area.gx_rectangle_bottom >= view -> gx_rectangle_top &&
174
                    draw_area.gx_rectangle_top <= view -> gx_rectangle_bottom &&
175
                    draw_area.gx_rectangle_right >= view -> gx_rectangle_left &&
176
                    draw_area.gx_rectangle_left <= view -> gx_rectangle_right)
177
                {
178
                    map_offset.gx_point_x = 0;
179
                    map_offset.gx_point_y = 0;
180
                    /* Calculate the y_start value, which is the offset into the row of
181
                       the glyph where we start to the draw. */
182
                    if (draw_area.gx_rectangle_top < view -> gx_rectangle_top)
183
                    {
184
                        map_offset.gx_point_y = (GX_VALUE)(view -> gx_rectangle_top - draw_area.gx_rectangle_top);
185
                        draw_area.gx_rectangle_top = view -> gx_rectangle_top;
186
                    }
187
188
                    if (draw_area.gx_rectangle_left < view -> gx_rectangle_left)
189
                    {
190
                        map_offset.gx_point_x = (GX_VALUE)(view -> gx_rectangle_left - x_offset);
191
                        draw_area.gx_rectangle_left = view -> gx_rectangle_left;
192
                    }
193
194
                    if (draw_area.gx_rectangle_bottom > view -> gx_rectangle_bottom)
195
                    {
196
                        draw_area.gx_rectangle_bottom = view -> gx_rectangle_bottom;
197
                    }
198
                    if (draw_area.gx_rectangle_right > view -> gx_rectangle_right)
199
                    {
200
                        draw_area.gx_rectangle_right = view -> gx_rectangle_right;
201
                    }
202
203
                    draw_glyph(context, &draw_area, &map_offset, (const GX_GLYPH *)glyph);
204
                }
205
            }
206
            xstart = (GX_VALUE)(xstart + glyph -> gx_glyph_advance);
207
            xstart = (GX_VALUE)(xstart + kerning_offset);
208
        }
209
210
        pre_char_val = char_val;
211
        kerning_offset = 0;
212
    } while (string_copy.gx_string_length > 0);
213
}
214
#endif
215
216
217
/**************************************************************************/
218
/*                                                                        */
219
/*  FUNCTION                                               RELEASE        */
220
/*                                                                        */
221
/*    _gx_canvas_compressed_glyphs_draw                   PORTABLE C      */
222
/*                                                           6.1          */
223
/*  AUTHOR                                                                */
224
/*                                                                        */
225
/*    Kenneth Maxwell, Microsoft Corporation                              */
226
/*                                                                        */
227
/*  DESCRIPTION                                                           */
228
/*                                                                        */
229
/*    This function prepares to draw text.                                */
230
/*                                                                        */
231
/*  INPUT                                                                 */
232
/*                                                                        */
233
/*    context                               Drawing context               */
234
/*    font                                  Font used by the string       */
235
/*    draw_position                         Coord of draw position        */
236
/*    string                                Pointer to string which need  */
237
/*                                            to draw                     */
238
/*    length                                Number of string about to draw*/
239
/*    view                                  Pointer to view size          */
240
/*    draw_glyph                            Callback pointer to display   */
241
/*                                            driver text draw function   */
242
/*                                                                        */
243
/*  OUTPUT                                                                */
244
/*                                                                        */
245
/*                                                                        */
246
/*  CALLS                                                                 */
247
/*                                                                        */
248
/*    _gx_utility_utf8_string_character_get                               */
249
/*                                    Get characters of this string       */
250
/*                                                                        */
251
/*  CALLED BY                                                             */
252
/*                                                                        */
253
/*    _gx_canvas_glyph_draw                                               */
254
/*                                                                        */
255
/*  RELEASE HISTORY                                                       */
256
/*                                                                        */
257
/*    DATE              NAME                      DESCRIPTION             */
258
/*                                                                        */
259
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
260
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
261
/*                                            resulting in version 6.1    */
262
/*                                                                        */
263
/**************************************************************************/
264
539
static VOID _gx_canvas_compressed_glyphs_draw(GX_DRAW_CONTEXT *context, GX_FONT *font, GX_POINT *draw_position, GX_CONST GX_STRING *string, GX_RECTANGLE *view,
265
                                              VOID (*draw_glyph)(GX_DRAW_CONTEXT *, GX_RECTANGLE *, GX_POINT *, GX_CONST GX_GLYPH *))
266
{
267
GX_CONST GX_COMPRESSED_GLYPH *glyph;
268
GX_CHAR_CODE                  char_val;
269
GX_VALUE                      x_offset;
270
GX_VALUE                      y_offset;
271
GX_VALUE                      xstart;
272
GX_VALUE                      ystart;
273
GX_POINT                      map_offset;
274
GX_RECTANGLE                  draw_area;
275
GX_CONST GX_FONT             *font_link;
276
GX_STRING                     string_copy;
277
278
#ifdef GX_UTF8_SUPPORT
279
UINT ret;
280
281
#ifdef GX_THAI_GLYPH_SHAPING_SUPPORT
282
GX_CHAR_CODE *code_list = GX_NULL;
283
UINT          code_count;
284
UINT          index = 0;
285
    if (_gx_system_text_render_style & GX_TEXT_RENDER_THAI_GLYPH_SHAPING)
286
    {
287
        ret = _gx_utility_thai_glyph_shaping(string, &code_list, &code_count);
288
    }
289
#endif
290
291
#endif /* GX_UTF8_SUPPORT */
292
293
    /* Setup local variables.  */
294
539
    xstart = draw_position -> gx_point_x;
295
539
    ystart = draw_position -> gx_point_y;
296
539
    string_copy = *string;
297
298
    /* for each character in the string */
299
    do
300
    {
301
#ifdef GX_UTF8_SUPPORT
302
#if defined(GX_THAI_GLYPH_SHAPING_SUPPORT)
303
        if (code_list)
304
        {
305
            if (index < code_count)
306
            {
307
                char_val = code_list[index++];
308
            }
309
            else
310
            {
311
                char_val = 0;
312
            }
313
        }
314
        else
315
        {
316
#endif
317
8740
            ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
318
#if defined(GX_THAI_GLYPH_SHAPING_SUPPORT)
319
        }
320
#endif
321

8740
        if ((ret != GX_SUCCESS) || (char_val == 0))
322
#else
323
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr++);
324
        string_copy.gx_string_length--;
325
326
        if (char_val == 0)
327
#endif /* GX_UTF8_SUPPORT */
328
        {
329
            break;
330
        }
331
332
8738
        font_link = font;
333
10934
        while (font_link)
334
        {
335
10920
            if (char_val >= font_link -> gx_font_first_glyph &&
336
10906
                char_val <= font_link -> gx_font_last_glyph)
337
            {
338
8724
                break;
339
            }
340
2196
            font_link = font_link -> gx_font_next_page;
341
        }
342
343
8738
        if (font_link)
344
        {
345
8724
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
346
8724
            glyph = &((GX_CONST GX_COMPRESSED_GLYPH *)font_link -> gx_font_glyphs.gx_font_compressed_glyphs)[char_val];
347
348
            /* Skip this glyph if glyph map is availlable. */
349
8724
            if (glyph -> gx_glyph_map)
350
            {
351
8148
                x_offset = (GX_VALUE)(xstart + glyph -> gx_glyph_leading);
352
8148
                y_offset = (GX_VALUE)(ystart + font_link -> gx_font_baseline - glyph -> gx_glyph_ascent);
353
354
8148
                draw_area.gx_rectangle_left = x_offset;
355
8148
                draw_area.gx_rectangle_top = y_offset;
356
8148
                draw_area.gx_rectangle_right = (GX_VALUE)(draw_area.gx_rectangle_left + glyph -> gx_glyph_width - 1);
357
8148
                draw_area.gx_rectangle_bottom = (GX_VALUE)(draw_area.gx_rectangle_top + glyph -> gx_glyph_height - 1);
358
359
8148
                if (draw_area.gx_rectangle_bottom >= view -> gx_rectangle_top &&
360
8072
                    draw_area.gx_rectangle_top <= view -> gx_rectangle_bottom &&
361
7979
                    draw_area.gx_rectangle_right >= view -> gx_rectangle_left &&
362
7894
                    draw_area.gx_rectangle_left <= view -> gx_rectangle_right)
363
                {
364
365
6334
                    map_offset.gx_point_x = 0;
366
6334
                    map_offset.gx_point_y = 0;
367
                    /* Calculate the y_start value, which is the offset into the row of
368
                       the glyph where we start to the draw. */
369
6334
                    if (draw_area.gx_rectangle_top < view -> gx_rectangle_top)
370
                    {
371
377
                        map_offset.gx_point_y = (GX_VALUE)(view -> gx_rectangle_top - draw_area.gx_rectangle_top);
372
377
                        draw_area.gx_rectangle_top = view -> gx_rectangle_top;
373
                    }
374
375
6334
                    if (draw_area.gx_rectangle_left < view -> gx_rectangle_left)
376
                    {
377
12
                        map_offset.gx_point_x = (GX_VALUE)(view -> gx_rectangle_left - x_offset);
378
12
                        draw_area.gx_rectangle_left = view -> gx_rectangle_left;
379
                    }
380
381
6334
                    if (draw_area.gx_rectangle_bottom > view -> gx_rectangle_bottom)
382
                    {
383
322
                        draw_area.gx_rectangle_bottom = view -> gx_rectangle_bottom;
384
                    }
385
6334
                    if (draw_area.gx_rectangle_right > view -> gx_rectangle_right)
386
                    {
387
85
                        draw_area.gx_rectangle_right = view -> gx_rectangle_right;
388
                    }
389
390
6334
                    draw_glyph(context, &draw_area, &map_offset, (const GX_GLYPH *)glyph);
391
                }
392
            }
393
8724
            xstart = (GX_VALUE)(xstart + glyph -> gx_glyph_advance);
394
        }
395
8738
    } while (string_copy.gx_string_length > 0);
396
539
}
397
398
/**************************************************************************/
399
/*                                                                        */
400
/*  FUNCTION                                               RELEASE        */
401
/*                                                                        */
402
/*    _gx_canvas_generic_glyphs_draw                      PORTABLE C      */
403
/*                                                           6.1          */
404
/*  AUTHOR                                                                */
405
/*                                                                        */
406
/*    Kenneth Maxwell, Microsoft Corporation                              */
407
/*                                                                        */
408
/*  DESCRIPTION                                                           */
409
/*                                                                        */
410
/*    This function prepares to draw text.                                */
411
/*                                                                        */
412
/*  INPUT                                                                 */
413
/*                                                                        */
414
/*    context                               Drawing context               */
415
/*    font                                  Font used by the string       */
416
/*    draw_position                         Coord of draw position        */
417
/*    string                                Pointer to string which need  */
418
/*                                            to draw                     */
419
/*    length                                Number of string about to draw*/
420
/*    view                                  Pointer to view size          */
421
/*    draw_glyph                            Callback pointer to display   */
422
/*                                            driver text draw function   */
423
/*                                                                        */
424
/*  OUTPUT                                                                */
425
/*                                                                        */
426
/*                                                                        */
427
/*  CALLS                                                                 */
428
/*                                                                        */
429
/*    _gx_utility_utf8_string_character_get                               */
430
/*                                    Get characters of this string       */
431
/*                                                                        */
432
/*  CALLED BY                                                             */
433
/*                                                                        */
434
/*    _gx_canvas_glyph_draw                                               */
435
/*                                                                        */
436
/*  RELEASE HISTORY                                                       */
437
/*                                                                        */
438
/*    DATE              NAME                      DESCRIPTION             */
439
/*                                                                        */
440
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
441
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
442
/*                                            resulting in version 6.1    */
443
/*                                                                        */
444
/**************************************************************************/
445
960454
static VOID _gx_canvas_generic_glyphs_draw(GX_DRAW_CONTEXT *context, GX_FONT *font, GX_POINT *draw_position, GX_CONST GX_STRING *string, GX_RECTANGLE *view,
446
                                           VOID (*draw_glyph)(GX_DRAW_CONTEXT *, GX_RECTANGLE *, GX_POINT *, GX_CONST GX_GLYPH *))
447
{
448
GX_CONST GX_GLYPH *glyph;
449
GX_CHAR_CODE       char_val;
450
GX_VALUE           x_offset;
451
GX_VALUE           y_offset;
452
GX_VALUE           xstart;
453
GX_VALUE           ystart;
454
GX_POINT           map_offset;
455
GX_RECTANGLE       draw_area;
456
GX_CONST GX_FONT  *font_link;
457
GX_STRING          string_copy;
458
459
#ifdef GX_UTF8_SUPPORT
460
UINT          ret;
461
#ifdef GX_THAI_GLYPH_SHAPING_SUPPORT
462
GX_CHAR_CODE *code_list = GX_NULL;
463
UINT          code_count;
464
UINT          index = 0;
465
    if (_gx_system_text_render_style & GX_TEXT_RENDER_THAI_GLYPH_SHAPING)
466
    {
467
        ret = _gx_utility_thai_glyph_shaping(string, &code_list, &code_count);
468
    }
469
#endif
470
#endif /* GX_UTF8_SUPPORT */
471
472
    /* Setup local variables.  */
473
960454
    xstart = draw_position -> gx_point_x;
474
960454
    ystart = draw_position -> gx_point_y;
475
960454
    string_copy = *string;
476
477
    /* for each character in the string */
478
    do
479
    {
480
#ifdef GX_UTF8_SUPPORT
481
#if defined(GX_THAI_GLYPH_SHAPING_SUPPORT)
482
        if (code_list)
483
        {
484
            if (index < code_count)
485
            {
486
                char_val = code_list[index++];
487
            }
488
            else
489
            {
490
                char_val = 0;
491
            }
492
        }
493
        else
494
        {
495
#endif
496
11573923
            ret = _gx_utility_utf8_string_character_get(&string_copy, &char_val, GX_NULL);
497
#if defined(GX_THAI_GLYPH_SHAPING_SUPPORT)
498
        }
499
#endif
500

11573923
        if ((ret != GX_SUCCESS) || (char_val == 0))
501
#else
502
        char_val = (GX_CHAR_CODE)(*string_copy.gx_string_ptr++);
503
        string_copy.gx_string_length--;
504
505
        if (char_val == 0)
506
#endif /* GX_UTF8_SUPPORT */
507
        {
508
            break;
509
        }
510
511
11573800
        font_link = font;
512
12128648
        while (font_link)
513
        {
514
12077557
            if (char_val >= font_link -> gx_font_first_glyph &&
515
11987788
                char_val <= font_link -> gx_font_last_glyph)
516
            {
517
11522709
                break;
518
            }
519
554848
            font_link = font_link -> gx_font_next_page;
520
        }
521
522
11573800
        if (font_link)
523
        {
524
11522709
            char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
525
11522709
            glyph = &font_link -> gx_font_glyphs.gx_font_normal_glyphs[char_val];
526
527
11522709
            if (glyph -> gx_glyph_map)
528
            {
529
10041851
                x_offset = (GX_VALUE)(xstart + glyph -> gx_glyph_leading);
530
10041851
                y_offset = (GX_VALUE)(ystart + font_link -> gx_font_baseline - glyph -> gx_glyph_ascent);
531
532
10041851
                draw_area.gx_rectangle_left = x_offset;
533
10041851
                draw_area.gx_rectangle_top = y_offset;
534
10041851
                draw_area.gx_rectangle_right = (GX_VALUE)(draw_area.gx_rectangle_left + glyph -> gx_glyph_width - 1);
535
10041851
                draw_area.gx_rectangle_bottom = (GX_VALUE)(draw_area.gx_rectangle_top + glyph -> gx_glyph_height - 1);
536
537
10041851
                if (draw_area.gx_rectangle_bottom >= view -> gx_rectangle_top &&
538
9992308
                    draw_area.gx_rectangle_top <= view -> gx_rectangle_bottom &&
539
9979410
                    draw_area.gx_rectangle_right >= view -> gx_rectangle_left &&
540
9251886
                    draw_area.gx_rectangle_left <= view -> gx_rectangle_right)
541
                {
542
8503522
                    map_offset.gx_point_x = 0;
543
8503522
                    map_offset.gx_point_y = 0;
544
545
                    /* Calculate the y_start value, which is the offset into the row of
546
                       the glyph where we start to the draw. */
547
8503522
                    if (draw_area.gx_rectangle_top < view -> gx_rectangle_top)
548
                    {
549
32580
                        map_offset.gx_point_y = (GX_VALUE)(view -> gx_rectangle_top - draw_area.gx_rectangle_top);
550
32580
                        draw_area.gx_rectangle_top = view -> gx_rectangle_top;
551
                    }
552
553
8503522
                    if (draw_area.gx_rectangle_left < view -> gx_rectangle_left)
554
                    {
555
24802
                        map_offset.gx_point_x = (GX_VALUE)(view -> gx_rectangle_left - x_offset);
556
24802
                        draw_area.gx_rectangle_left = view -> gx_rectangle_left;
557
                    }
558
559
8503522
                    if (draw_area.gx_rectangle_bottom > view -> gx_rectangle_bottom)
560
                    {
561
37618
                        draw_area.gx_rectangle_bottom = view -> gx_rectangle_bottom;
562
                    }
563
8503522
                    if (draw_area.gx_rectangle_right > view -> gx_rectangle_right)
564
                    {
565
84055
                        draw_area.gx_rectangle_right = view -> gx_rectangle_right;
566
                    }
567
568
8503522
                    draw_glyph(context, &draw_area, &map_offset, glyph);
569
                }
570
            }
571
11522709
            xstart = (GX_VALUE)(xstart + glyph -> gx_glyph_advance);
572
        }
573
11573800
    } while (string_copy.gx_string_length > 0);
574
575
#ifdef GX_UTF8_SUPPORT
576
#if defined(GX_THAI_GLYPH_SHAPING_SUPPORT)
577
    if (code_list)
578
    {
579
        _gx_system_memory_free((void *)code_list);
580
    }
581
#endif
582
#endif
583
960454
}
584
585
/**************************************************************************/
586
/*                                                                        */
587
/*  FUNCTION                                               RELEASE        */
588
/*                                                                        */
589
/*    _gx_canvas_glyphs_draw                              PORTABLE C      */
590
/*                                                           6.1          */
591
/*  AUTHOR                                                                */
592
/*                                                                        */
593
/*    Kenneth Maxwell, Microsoft Corporation                              */
594
/*                                                                        */
595
/*  DESCRIPTION                                                           */
596
/*                                                                        */
597
/*    This function prepares to draw text.                                */
598
/*                                                                        */
599
/*  INPUT                                                                 */
600
/*                                                                        */
601
/*    context                               Drawing context               */
602
/*    draw_position                         Coord of draw position        */
603
/*    string                                Pointer to string which need  */
604
/*                                            to draw                     */
605
/*    length                                Number of string about to draw*/
606
/*    view                                  Pointer to view size          */
607
/*    draw_glyph                            Callback pointer to display   */
608
/*                                            driver text draw function   */
609
/*                                                                        */
610
/*  OUTPUT                                                                */
611
/*                                                                        */
612
/*                                                                        */
613
/*  CALLS                                                                 */
614
/*                                                                        */
615
/*    _gx_utility_utf8_string_character_get                               */
616
/*                                    Get characters of this string       */
617
/*                                                                        */
618
/*  CALLED BY                                                             */
619
/*                                                                        */
620
/*    _gx_canvas_compressed_glyphs_draw                                   */
621
/*    _gx_canvas_kerning_glyphs_draw                                      */
622
/*    _gx_canvas_generic_glyphs_draw                                      */
623
/*                                                                        */
624
/*  RELEASE HISTORY                                                       */
625
/*                                                                        */
626
/*    DATE              NAME                      DESCRIPTION             */
627
/*                                                                        */
628
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
629
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
630
/*                                            resulting in version 6.1    */
631
/*                                                                        */
632
/**************************************************************************/
633
960995
VOID _gx_canvas_glyphs_draw(GX_DRAW_CONTEXT *context, GX_POINT *draw_position, GX_CONST GX_STRING *string,
634
                            GX_RECTANGLE *view,
635
                            VOID (*draw_glyph)(GX_DRAW_CONTEXT *, GX_RECTANGLE *, GX_POINT *, GX_CONST GX_GLYPH *))
636
{
637
GX_BRUSH *brush;
638
GX_FONT  *font;
639
640
    /* pickup pointer to current drawing context */
641
960995
    context =   _gx_system_current_draw_context;
642
643
    /* get the current brush */
644
960995
    brush =     &context -> gx_draw_context_brush;
645
646
    /* get the current font and color */
647
960995
    font =      brush -> gx_brush_font;
648
649

960995
    if (!string || !font)
650
    {
651
        /* Return error.  */
652
2
        return;
653
    }
654
655
960993
    if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
656
    {
657
539
        _gx_canvas_compressed_glyphs_draw(context, font, draw_position, string, view, draw_glyph);
658
    }
659
#if defined(GX_FONT_KERNING_SUPPORT)
660
    else if (font -> gx_font_format & GX_FONT_FORMAT_KERNING)
661
    {
662
        _gx_canvas_kerning_glyphs_draw(context, font, draw_position, string, view, draw_glyph);
663
    }
664
#endif
665
    else
666
    {
667
960454
        _gx_canvas_generic_glyphs_draw(context, font, draw_position, string, view, draw_glyph);
668
    }
669
}
670