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 /**************************************************************************/
_gx_canvas_kerning_glyphs_draw(GX_DRAW_CONTEXT * context,GX_FONT * font,GX_POINT * draw_position,GX_CONST GX_STRING * string,GX_RECTANGLE * view,VOID (* draw_glyph)(GX_DRAW_CONTEXT *,GX_RECTANGLE *,GX_POINT *,GX_CONST GX_GLYPH *))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 /**************************************************************************/
_gx_canvas_compressed_glyphs_draw(GX_DRAW_CONTEXT * context,GX_FONT * font,GX_POINT * draw_position,GX_CONST GX_STRING * string,GX_RECTANGLE * view,VOID (* draw_glyph)(GX_DRAW_CONTEXT *,GX_RECTANGLE *,GX_POINT *,GX_CONST GX_GLYPH *))264 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 xstart = draw_position -> gx_point_x;
295 ystart = draw_position -> gx_point_y;
296 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 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 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 font_link = font;
333 while (font_link)
334 {
335 if (char_val >= font_link -> gx_font_first_glyph &&
336 char_val <= font_link -> gx_font_last_glyph)
337 {
338 break;
339 }
340 font_link = font_link -> gx_font_next_page;
341 }
342
343 if (font_link)
344 {
345 char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
346 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 if (glyph -> gx_glyph_map)
350 {
351 x_offset = (GX_VALUE)(xstart + glyph -> gx_glyph_leading);
352 y_offset = (GX_VALUE)(ystart + font_link -> gx_font_baseline - glyph -> gx_glyph_ascent);
353
354 draw_area.gx_rectangle_left = x_offset;
355 draw_area.gx_rectangle_top = y_offset;
356 draw_area.gx_rectangle_right = (GX_VALUE)(draw_area.gx_rectangle_left + glyph -> gx_glyph_width - 1);
357 draw_area.gx_rectangle_bottom = (GX_VALUE)(draw_area.gx_rectangle_top + glyph -> gx_glyph_height - 1);
358
359 if (draw_area.gx_rectangle_bottom >= view -> gx_rectangle_top &&
360 draw_area.gx_rectangle_top <= view -> gx_rectangle_bottom &&
361 draw_area.gx_rectangle_right >= view -> gx_rectangle_left &&
362 draw_area.gx_rectangle_left <= view -> gx_rectangle_right)
363 {
364
365 map_offset.gx_point_x = 0;
366 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 if (draw_area.gx_rectangle_top < view -> gx_rectangle_top)
370 {
371 map_offset.gx_point_y = (GX_VALUE)(view -> gx_rectangle_top - draw_area.gx_rectangle_top);
372 draw_area.gx_rectangle_top = view -> gx_rectangle_top;
373 }
374
375 if (draw_area.gx_rectangle_left < view -> gx_rectangle_left)
376 {
377 map_offset.gx_point_x = (GX_VALUE)(view -> gx_rectangle_left - x_offset);
378 draw_area.gx_rectangle_left = view -> gx_rectangle_left;
379 }
380
381 if (draw_area.gx_rectangle_bottom > view -> gx_rectangle_bottom)
382 {
383 draw_area.gx_rectangle_bottom = view -> gx_rectangle_bottom;
384 }
385 if (draw_area.gx_rectangle_right > view -> gx_rectangle_right)
386 {
387 draw_area.gx_rectangle_right = view -> gx_rectangle_right;
388 }
389
390 draw_glyph(context, &draw_area, &map_offset, (const GX_GLYPH *)glyph);
391 }
392 }
393 xstart = (GX_VALUE)(xstart + glyph -> gx_glyph_advance);
394 }
395 } while (string_copy.gx_string_length > 0);
396 }
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 /**************************************************************************/
_gx_canvas_generic_glyphs_draw(GX_DRAW_CONTEXT * context,GX_FONT * font,GX_POINT * draw_position,GX_CONST GX_STRING * string,GX_RECTANGLE * view,VOID (* draw_glyph)(GX_DRAW_CONTEXT *,GX_RECTANGLE *,GX_POINT *,GX_CONST GX_GLYPH *))445 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 xstart = draw_position -> gx_point_x;
474 ystart = draw_position -> gx_point_y;
475 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 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 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 font_link = font;
512 while (font_link)
513 {
514 if (char_val >= font_link -> gx_font_first_glyph &&
515 char_val <= font_link -> gx_font_last_glyph)
516 {
517 break;
518 }
519 font_link = font_link -> gx_font_next_page;
520 }
521
522 if (font_link)
523 {
524 char_val = (GX_CHAR_CODE)(char_val - font_link -> gx_font_first_glyph);
525 glyph = &font_link -> gx_font_glyphs.gx_font_normal_glyphs[char_val];
526
527 if (glyph -> gx_glyph_map)
528 {
529 x_offset = (GX_VALUE)(xstart + glyph -> gx_glyph_leading);
530 y_offset = (GX_VALUE)(ystart + font_link -> gx_font_baseline - glyph -> gx_glyph_ascent);
531
532 draw_area.gx_rectangle_left = x_offset;
533 draw_area.gx_rectangle_top = y_offset;
534 draw_area.gx_rectangle_right = (GX_VALUE)(draw_area.gx_rectangle_left + glyph -> gx_glyph_width - 1);
535 draw_area.gx_rectangle_bottom = (GX_VALUE)(draw_area.gx_rectangle_top + glyph -> gx_glyph_height - 1);
536
537 if (draw_area.gx_rectangle_bottom >= view -> gx_rectangle_top &&
538 draw_area.gx_rectangle_top <= view -> gx_rectangle_bottom &&
539 draw_area.gx_rectangle_right >= view -> gx_rectangle_left &&
540 draw_area.gx_rectangle_left <= view -> gx_rectangle_right)
541 {
542 map_offset.gx_point_x = 0;
543 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 if (draw_area.gx_rectangle_top < view -> gx_rectangle_top)
548 {
549 map_offset.gx_point_y = (GX_VALUE)(view -> gx_rectangle_top - draw_area.gx_rectangle_top);
550 draw_area.gx_rectangle_top = view -> gx_rectangle_top;
551 }
552
553 if (draw_area.gx_rectangle_left < view -> gx_rectangle_left)
554 {
555 map_offset.gx_point_x = (GX_VALUE)(view -> gx_rectangle_left - x_offset);
556 draw_area.gx_rectangle_left = view -> gx_rectangle_left;
557 }
558
559 if (draw_area.gx_rectangle_bottom > view -> gx_rectangle_bottom)
560 {
561 draw_area.gx_rectangle_bottom = view -> gx_rectangle_bottom;
562 }
563 if (draw_area.gx_rectangle_right > view -> gx_rectangle_right)
564 {
565 draw_area.gx_rectangle_right = view -> gx_rectangle_right;
566 }
567
568 draw_glyph(context, &draw_area, &map_offset, glyph);
569 }
570 }
571 xstart = (GX_VALUE)(xstart + glyph -> gx_glyph_advance);
572 }
573 } 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 }
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 /**************************************************************************/
_gx_canvas_glyphs_draw(GX_DRAW_CONTEXT * context,GX_POINT * draw_position,GX_CONST GX_STRING * string,GX_RECTANGLE * view,VOID (* draw_glyph)(GX_DRAW_CONTEXT *,GX_RECTANGLE *,GX_POINT *,GX_CONST GX_GLYPH *))633 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 context = _gx_system_current_draw_context;
642
643 /* get the current brush */
644 brush = &context -> gx_draw_context_brush;
645
646 /* get the current font and color */
647 font = brush -> gx_brush_font;
648
649 if (!string || !font)
650 {
651 /* Return error. */
652 return;
653 }
654
655 if (font -> gx_font_format & GX_FONT_FORMAT_COMPRESSED)
656 {
657 _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 _gx_canvas_generic_glyphs_draw(context, font, draw_position, string, view, draw_glyph);
668 }
669 }
670
671