ReactOS 0.4.16-dev-2354-g16de117
pshrec.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * pshrec.c
4 *
5 * FreeType PostScript hints recorder (body).
6 *
7 * Copyright (C) 2001-2020 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19#include <freetype/freetype.h>
23
24#include "pshrec.h"
25#include "pshalgo.h"
26
27#include "pshnterr.h"
28
29#undef FT_COMPONENT
30#define FT_COMPONENT pshrec
31
32#ifdef DEBUG_HINTER
33 PS_Hints ps_debug_hints = NULL;
34 int ps_debug_no_horz_hints = 0;
35 int ps_debug_no_vert_hints = 0;
36#endif
37
38
39 /*************************************************************************/
40 /*************************************************************************/
41 /***** *****/
42 /***** PS_HINT MANAGEMENT *****/
43 /***** *****/
44 /*************************************************************************/
45 /*************************************************************************/
46
47 /* destroy hints table */
48 static void
51 {
52 FT_FREE( table->hints );
53 table->num_hints = 0;
54 table->max_hints = 0;
55 }
56
57
58 /* ensure that a table can contain "count" elements */
59 static FT_Error
63 {
64 FT_UInt old_max = table->max_hints;
65 FT_UInt new_max = count;
67
68
69 if ( new_max > old_max )
70 {
71 /* try to grow the table */
72 new_max = FT_PAD_CEIL( new_max, 8 );
73 if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) )
74 table->max_hints = new_max;
75 }
76 return error;
77 }
78
79
80 static FT_Error
83 PS_Hint *ahint )
84 {
88
89
90 count = table->num_hints;
91 count++;
92
93 if ( count >= table->max_hints )
94 {
96 if ( error )
97 goto Exit;
98 }
99
100 hint = table->hints + count - 1;
101 hint->pos = 0;
102 hint->len = 0;
103 hint->flags = 0;
104
105 table->num_hints = count;
106
107 Exit:
108 *ahint = hint;
109 return error;
110 }
111
112
113 /*************************************************************************/
114 /*************************************************************************/
115 /***** *****/
116 /***** PS_MASK MANAGEMENT *****/
117 /***** *****/
118 /*************************************************************************/
119 /*************************************************************************/
120
121 /* destroy mask */
122 static void
125 {
126 FT_FREE( mask->bytes );
127 mask->num_bits = 0;
128 mask->max_bits = 0;
129 mask->end_point = 0;
130 }
131
132
133 /* ensure that a mask can contain "count" bits */
134 static FT_Error
138 {
139 FT_UInt old_max = ( mask->max_bits + 7 ) >> 3;
140 FT_UInt new_max = ( count + 7 ) >> 3;
142
143
144 if ( new_max > old_max )
145 {
146 new_max = FT_PAD_CEIL( new_max, 8 );
147 if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) )
148 mask->max_bits = new_max * 8;
149 }
150 return error;
151 }
152
153
154 /* test a bit value in a given mask */
155 static FT_Int
157 FT_Int idx )
158 {
159 if ( (FT_UInt)idx >= mask->num_bits )
160 return 0;
161
162 return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) );
163 }
164
165
166 /* clear a given bit */
167 static void
169 FT_UInt idx )
170 {
171 FT_Byte* p;
172
173
174 if ( idx >= mask->num_bits )
175 return;
176
177 p = mask->bytes + ( idx >> 3 );
178 p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) );
179 }
180
181
182 /* set a given bit, possibly grow the mask */
183 static FT_Error
185 FT_UInt idx,
187 {
189 FT_Byte* p;
190
191
192 if ( idx >= mask->num_bits )
193 {
195 if ( error )
196 goto Exit;
197
198 mask->num_bits = idx + 1;
199 }
200
201 p = mask->bytes + ( idx >> 3 );
202 p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) );
203
204 Exit:
205 return error;
206 }
207
208
209 /* destroy mask table */
210 static void
213 {
214 FT_UInt count = table->max_masks;
215 PS_Mask mask = table->masks;
216
217
218 for ( ; count > 0; count--, mask++ )
220
221 FT_FREE( table->masks );
222 table->num_masks = 0;
223 table->max_masks = 0;
224 }
225
226
227 /* ensure that a mask table can contain "count" masks */
228 static FT_Error
232 {
233 FT_UInt old_max = table->max_masks;
234 FT_UInt new_max = count;
236
237
238 if ( new_max > old_max )
239 {
240 new_max = FT_PAD_CEIL( new_max, 8 );
241 if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) )
242 table->max_masks = new_max;
243 }
244 return error;
245 }
246
247
248 /* allocate a new mask in a table */
249 static FT_Error
252 PS_Mask *amask )
253 {
256 PS_Mask mask = NULL;
257
258
259 count = table->num_masks;
260 count++;
261
262 if ( count > table->max_masks )
263 {
265 if ( error )
266 goto Exit;
267 }
268
269 mask = table->masks + count - 1;
270 mask->num_bits = 0;
271 mask->end_point = 0;
272 table->num_masks = count;
273
274 Exit:
275 *amask = mask;
276 return error;
277 }
278
279
280 /* return last hint mask in a table, create one if the table is empty */
281 static FT_Error
284 PS_Mask *amask )
285 {
289
290
291 count = table->num_masks;
292 if ( count == 0 )
293 {
295 if ( error )
296 goto Exit;
297 }
298 else
299 mask = table->masks + count - 1;
300
301 Exit:
302 *amask = mask;
303 return error;
304 }
305
306
307 /* set a new mask to a given bit range */
308 static FT_Error
310 const FT_Byte* source,
311 FT_UInt bit_pos,
312 FT_UInt bit_count,
314 {
317
318
320 if ( error )
321 goto Exit;
322
323 error = ps_mask_ensure( mask, bit_count, memory );
324 if ( error )
325 goto Exit;
326
327 mask->num_bits = bit_count;
328
329 /* now, copy bits */
330 {
331 FT_Byte* read = (FT_Byte*)source + ( bit_pos >> 3 );
332 FT_Int rmask = 0x80 >> ( bit_pos & 7 );
333 FT_Byte* write = mask->bytes;
334 FT_Int wmask = 0x80;
335 FT_Int val;
336
337
338 for ( ; bit_count > 0; bit_count-- )
339 {
340 val = write[0] & ~wmask;
341
342 if ( read[0] & rmask )
343 val |= wmask;
344
345 write[0] = (FT_Byte)val;
346
347 rmask >>= 1;
348 if ( rmask == 0 )
349 {
350 read++;
351 rmask = 0x80;
352 }
353
354 wmask >>= 1;
355 if ( wmask == 0 )
356 {
357 write++;
358 wmask = 0x80;
359 }
360 }
361 }
362
363 Exit:
364 return error;
365 }
366
367
368 /* test whether two masks in a table intersect */
369 static FT_Int
371 FT_UInt index1,
372 FT_UInt index2 )
373 {
374 PS_Mask mask1 = table->masks + index1;
375 PS_Mask mask2 = table->masks + index2;
376 FT_Byte* p1 = mask1->bytes;
377 FT_Byte* p2 = mask2->bytes;
378 FT_UInt count1 = mask1->num_bits;
379 FT_UInt count2 = mask2->num_bits;
381
382
383 count = FT_MIN( count1, count2 );
384 for ( ; count >= 8; count -= 8 )
385 {
386 if ( p1[0] & p2[0] )
387 return 1;
388
389 p1++;
390 p2++;
391 }
392
393 if ( count == 0 )
394 return 0;
395
396 return ( p1[0] & p2[0] ) & ~( 0xFF >> count );
397 }
398
399
400 /* merge two masks, used by ps_mask_table_merge_all */
401 static FT_Error
403 FT_UInt index1,
404 FT_UInt index2,
406 {
408
409
410 /* swap index1 and index2 so that index1 < index2 */
411 if ( index1 > index2 )
412 {
414
415
416 temp = index1;
417 index1 = index2;
418 index2 = temp;
419 }
420
421 if ( index1 < index2 && index2 < table->num_masks )
422 {
423 /* we need to merge the bitsets of index1 and index2 with a */
424 /* simple union */
425 PS_Mask mask1 = table->masks + index1;
426 PS_Mask mask2 = table->masks + index2;
427 FT_UInt count1 = mask1->num_bits;
428 FT_UInt count2 = mask2->num_bits;
429 FT_Int delta;
430
431
432 if ( count2 > 0 )
433 {
434 FT_UInt pos;
435 FT_Byte* read;
436 FT_Byte* write;
437
438
439 /* if "count2" is greater than "count1", we need to grow the */
440 /* first bitset, and clear the highest bits */
441 if ( count2 > count1 )
442 {
443 error = ps_mask_ensure( mask1, count2, memory );
444 if ( error )
445 goto Exit;
446
447 for ( pos = count1; pos < count2; pos++ )
448 ps_mask_clear_bit( mask1, pos );
449 }
450
451 /* merge (unite) the bitsets */
452 read = mask2->bytes;
453 write = mask1->bytes;
454 pos = ( count2 + 7 ) >> 3;
455
456 for ( ; pos > 0; pos-- )
457 {
458 write[0] = (FT_Byte)( write[0] | read[0] );
459 write++;
460 read++;
461 }
462 }
463
464 /* Now, remove "mask2" from the list. We need to keep the masks */
465 /* sorted in order of importance, so move table elements. */
466 mask2->num_bits = 0;
467 mask2->end_point = 0;
468
469 /* number of masks to move */
470 delta = (FT_Int)( table->num_masks - 1 - index2 );
471 if ( delta > 0 )
472 {
473 /* move to end of table for reuse */
474 PS_MaskRec dummy = *mask2;
475
476
477 ft_memmove( mask2,
478 mask2 + 1,
479 (FT_UInt)delta * sizeof ( PS_MaskRec ) );
480
481 mask2[delta] = dummy;
482 }
483
484 table->num_masks--;
485 }
486 else
487 FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n",
488 index1, index2 ));
489
490 Exit:
491 return error;
492 }
493
494
495 /* Try to merge all masks in a given table. This is used to merge */
496 /* all counter masks into independent counter "paths". */
497 /* */
498 static FT_Error
501 {
502 FT_Int index1, index2;
504
505
506 /* both loops go down to 0, thus FT_Int for index1 and index2 */
507 for ( index1 = (FT_Int)table->num_masks - 1; index1 > 0; index1-- )
508 {
509 for ( index2 = index1 - 1; index2 >= 0; index2-- )
510 {
512 (FT_UInt)index1,
513 (FT_UInt)index2 ) )
514 {
516 (FT_UInt)index2,
517 (FT_UInt)index1,
518 memory );
519 if ( error )
520 goto Exit;
521
522 break;
523 }
524 }
525 }
526
527 Exit:
528 return error;
529 }
530
531
532 /*************************************************************************/
533 /*************************************************************************/
534 /***** *****/
535 /***** PS_DIMENSION MANAGEMENT *****/
536 /***** *****/
537 /*************************************************************************/
538 /*************************************************************************/
539
540
541 /* finalize a given dimension */
542 static void
545 {
546 ps_mask_table_done( &dimension->counters, memory );
547 ps_mask_table_done( &dimension->masks, memory );
548 ps_hint_table_done( &dimension->hints, memory );
549 }
550
551
552 /* initialize a given dimension */
553 static void
555 {
556 dimension->hints.num_hints = 0;
557 dimension->masks.num_masks = 0;
558 dimension->counters.num_masks = 0;
559 }
560
561
562#if 0
563
564 /* set a bit at a given index in the current hint mask */
565 static FT_Error
566 ps_dimension_set_mask_bit( PS_Dimension dim,
567 FT_UInt idx,
569 {
572
573
574 /* get last hint mask */
576 if ( error )
577 goto Exit;
578
580
581 Exit:
582 return error;
583 }
584
585#endif
586
587 /* set the end point in a mask, called from "End" & "Reset" methods */
588 static void
590 FT_UInt end_point )
591 {
593
594
595 if ( count > 0 )
596 {
597 PS_Mask mask = dim->masks.masks + count - 1;
598
599
600 mask->end_point = end_point;
601 }
602 }
603
604
605 /* set the end point in the current mask, then create a new empty one */
606 /* (called by "Reset" method) */
607 static FT_Error
609 FT_UInt end_point,
611 {
613
614
615 /* end current mask */
616 ps_dimension_end_mask( dim, end_point );
617
618 /* allocate new one */
619 return ps_mask_table_alloc( &dim->masks, memory, &mask );
620 }
621
622
623 /* set a new mask, called from the "T2Stem" method */
624 static FT_Error
626 const FT_Byte* source,
627 FT_UInt source_pos,
628 FT_UInt source_bits,
629 FT_UInt end_point,
631 {
633
634
635 /* reset current mask, if any */
636 error = ps_dimension_reset_mask( dim, end_point, memory );
637 if ( error )
638 goto Exit;
639
640 /* set bits in new mask */
642 source_pos, source_bits, memory );
643
644 Exit:
645 return error;
646 }
647
648
649 /* add a new single stem (called from "T1Stem" method) */
650 static FT_Error
652 FT_Int pos,
653 FT_Int len,
655 FT_Int *aindex )
656 {
658 FT_UInt flags = 0;
659
660
661 /* detect ghost stem */
662 if ( len < 0 )
663 {
665 if ( len == -21 )
666 {
668 pos = ADD_INT( pos, len );
669 }
670 len = 0;
671 }
672
673 if ( aindex )
674 *aindex = -1;
675
676 /* now, lookup stem in the current hints table */
677 {
679 FT_UInt idx;
680 FT_UInt max = dim->hints.num_hints;
681 PS_Hint hint = dim->hints.hints;
682
683
684 for ( idx = 0; idx < max; idx++, hint++ )
685 {
686 if ( hint->pos == pos && hint->len == len )
687 break;
688 }
689
690 /* we need to create a new hint in the table */
691 if ( idx >= max )
692 {
694 if ( error )
695 goto Exit;
696
697 hint->pos = pos;
698 hint->len = len;
699 hint->flags = flags;
700 }
701
702 /* now, store the hint in the current mask */
704 if ( error )
705 goto Exit;
706
708 if ( error )
709 goto Exit;
710
711 if ( aindex )
712 *aindex = (FT_Int)idx;
713 }
714
715 Exit:
716 return error;
717 }
718
719
720 /* add a "hstem3/vstem3" counter to our dimension table */
721 static FT_Error
723 FT_Int hint1,
724 FT_Int hint2,
725 FT_Int hint3,
727 {
731
732
733 /* try to find an existing counter mask that already uses */
734 /* one of these stems here */
735 for ( ; count > 0; count--, counter++ )
736 {
737 if ( ps_mask_test_bit( counter, hint1 ) ||
738 ps_mask_test_bit( counter, hint2 ) ||
739 ps_mask_test_bit( counter, hint3 ) )
740 break;
741 }
742
743 /* create a new counter when needed */
744 if ( count == 0 )
745 {
747 if ( error )
748 goto Exit;
749 }
750
751 /* now, set the bits for our hints in the counter mask */
752 if ( hint1 >= 0 )
753 {
755 if ( error )
756 goto Exit;
757 }
758
759 if ( hint2 >= 0 )
760 {
762 if ( error )
763 goto Exit;
764 }
765
766 if ( hint3 >= 0 )
767 {
769 if ( error )
770 goto Exit;
771 }
772
773 Exit:
774 return error;
775 }
776
777
778 /* end of recording session for a given dimension */
779 static FT_Error
781 FT_UInt end_point,
783 {
784 /* end hint mask table */
785 ps_dimension_end_mask( dim, end_point );
786
787 /* merge all counter masks into independent "paths" */
788 return ps_mask_table_merge_all( &dim->counters, memory );
789 }
790
791
792 /*************************************************************************/
793 /*************************************************************************/
794 /***** *****/
795 /***** PS_RECORDER MANAGEMENT *****/
796 /***** *****/
797 /*************************************************************************/
798 /*************************************************************************/
799
800
801 /* destroy hints */
802 FT_LOCAL( void )
804 {
805 FT_Memory memory = hints->memory;
806
807
808 ps_dimension_done( &hints->dimension[0], memory );
809 ps_dimension_done( &hints->dimension[1], memory );
810
811 hints->error = FT_Err_Ok;
812 hints->memory = NULL;
813 }
814
815
816 FT_LOCAL( void )
819 {
820 FT_ZERO( hints );
821 hints->memory = memory;
822 }
823
824
825 /* initialize a hints for a new session */
826 static void
828 PS_Hint_Type hint_type )
829 {
830 hints->error = FT_Err_Ok;
831 hints->hint_type = hint_type;
832
833 ps_dimension_init( &hints->dimension[0] );
834 ps_dimension_init( &hints->dimension[1] );
835 }
836
837
838 /* add one or more stems to the current hints table */
839 static void
841 FT_UInt dimension,
843 FT_Long* stems )
844 {
845 PS_Dimension dim;
846
847
848 if ( hints->error )
849 return;
850
851 /* limit "dimension" to 0..1 */
852 if ( dimension > 1 )
853 {
854 FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n",
855 dimension ));
856 dimension = ( dimension != 0 );
857 }
858
859 /* record the stems in the current hints/masks table */
860 /* (Type 1 & 2's `hstem' or `vstem' operators) */
861 dim = &hints->dimension[dimension];
862
863 for ( ; count > 0; count--, stems += 2 )
864 {
866 FT_Memory memory = hints->memory;
867
868
870 (FT_Int)stems[0],
871 (FT_Int)stems[1],
872 memory,
873 NULL );
874 if ( error )
875 {
876 FT_ERROR(( "ps_hints_stem: could not add stem"
877 " (%ld,%ld) to hints table\n", stems[0], stems[1] ));
878
879 hints->error = error;
880 return;
881 }
882 }
883 }
884
885
886 /* add one Type1 counter stem to the current hints table */
887 static void
889 FT_UInt dimension,
890 FT_Fixed* stems )
891 {
893
894
895 if ( !hints->error )
896 {
897 PS_Dimension dim;
898 FT_Memory memory = hints->memory;
900 FT_Int idx[3];
901
902
903 /* limit "dimension" to 0..1 */
904 if ( dimension > 1 )
905 {
906 FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n",
907 dimension ));
908 dimension = ( dimension != 0 );
909 }
910
911 dim = &hints->dimension[dimension];
912
913 /* there must be 6 elements in the 'stem' array */
914 if ( hints->hint_type == PS_HINT_TYPE_1 )
915 {
916 /* add the three stems to our hints/masks table */
917 for ( count = 0; count < 3; count++, stems += 2 )
918 {
920 (FT_Int)FIXED_TO_INT( stems[0] ),
921 (FT_Int)FIXED_TO_INT( stems[1] ),
922 memory, &idx[count] );
923 if ( error )
924 goto Fail;
925 }
926
927 /* now, add the hints to the counters table */
928 error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2],
929 memory );
930 if ( error )
931 goto Fail;
932 }
933 else
934 {
935 FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" ));
936 error = FT_THROW( Invalid_Argument );
937 goto Fail;
938 }
939 }
940
941 return;
942
943 Fail:
944 FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" ));
945 hints->error = error;
946 }
947
948
949 /* reset hints (only with Type 1 hints) */
950 static void
952 FT_UInt end_point )
953 {
955
956
957 if ( !hints->error )
958 {
959 FT_Memory memory = hints->memory;
960
961
962 if ( hints->hint_type == PS_HINT_TYPE_1 )
963 {
964 error = ps_dimension_reset_mask( &hints->dimension[0],
965 end_point, memory );
966 if ( error )
967 goto Fail;
968
969 error = ps_dimension_reset_mask( &hints->dimension[1],
970 end_point, memory );
971 if ( error )
972 goto Fail;
973 }
974 else
975 {
976 /* invalid hint type */
977 error = FT_THROW( Invalid_Argument );
978 goto Fail;
979 }
980 }
981 return;
982
983 Fail:
984 hints->error = error;
985 }
986
987
988 /* Type2 "hintmask" operator, add a new hintmask to each direction */
989 static void
991 FT_UInt end_point,
992 FT_UInt bit_count,
993 const FT_Byte* bytes )
994 {
996
997
998 if ( !hints->error )
999 {
1000 PS_Dimension dim = hints->dimension;
1001 FT_Memory memory = hints->memory;
1002 FT_UInt count1 = dim[0].hints.num_hints;
1003 FT_UInt count2 = dim[1].hints.num_hints;
1004
1005
1006 /* check bit count; must be equal to current total hint count */
1007 if ( bit_count != count1 + count2 )
1008 {
1009 FT_TRACE0(( "ps_hints_t2mask:"
1010 " called with invalid bitcount %d (instead of %d)\n",
1011 bit_count, count1 + count2 ));
1012
1013 /* simply ignore the operator */
1014 return;
1015 }
1016
1017 /* set-up new horizontal and vertical hint mask now */
1018 error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1,
1019 end_point, memory );
1020 if ( error )
1021 goto Fail;
1022
1023 error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2,
1024 end_point, memory );
1025 if ( error )
1026 goto Fail;
1027 }
1028 return;
1029
1030 Fail:
1031 hints->error = error;
1032 }
1033
1034
1035 static void
1037 FT_UInt bit_count,
1038 const FT_Byte* bytes )
1039 {
1041
1042
1043 if ( !hints->error )
1044 {
1045 PS_Dimension dim = hints->dimension;
1046 FT_Memory memory = hints->memory;
1047 FT_UInt count1 = dim[0].hints.num_hints;
1048 FT_UInt count2 = dim[1].hints.num_hints;
1049
1050
1051 /* check bit count, must be equal to current total hint count */
1052 if ( bit_count != count1 + count2 )
1053 {
1054 FT_TRACE0(( "ps_hints_t2counter:"
1055 " called with invalid bitcount %d (instead of %d)\n",
1056 bit_count, count1 + count2 ));
1057
1058 /* simply ignore the operator */
1059 return;
1060 }
1061
1062 /* set-up new horizontal and vertical hint mask now */
1063 error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1,
1064 0, memory );
1065 if ( error )
1066 goto Fail;
1067
1068 error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2,
1069 0, memory );
1070 if ( error )
1071 goto Fail;
1072 }
1073 return;
1074
1075 Fail:
1076 hints->error = error;
1077 }
1078
1079
1080 /* end recording session */
1081 static FT_Error
1083 FT_UInt end_point )
1084 {
1086
1087
1088 error = hints->error;
1089 if ( !error )
1090 {
1091 FT_Memory memory = hints->memory;
1092 PS_Dimension dim = hints->dimension;
1093
1094
1095 error = ps_dimension_end( &dim[0], end_point, memory );
1096 if ( !error )
1097 {
1098 error = ps_dimension_end( &dim[1], end_point, memory );
1099 }
1100 }
1101
1102#ifdef DEBUG_HINTER
1103 if ( !error )
1104 ps_debug_hints = hints;
1105#endif
1106 return error;
1107 }
1108
1109
1110 /*************************************************************************/
1111 /*************************************************************************/
1112 /***** *****/
1113 /***** TYPE 1 HINTS RECORDING INTERFACE *****/
1114 /***** *****/
1115 /*************************************************************************/
1116 /*************************************************************************/
1117
1118 static void
1120 {
1122 }
1123
1124 static void
1126 FT_UInt dimension,
1127 FT_Fixed* coords )
1128 {
1129 FT_Pos stems[2];
1130
1131
1132 stems[0] = FIXED_TO_INT( coords[0] );
1133 stems[1] = FIXED_TO_INT( coords[1] );
1134
1135 ps_hints_stem( (PS_Hints)hints, dimension, 1, stems );
1136 }
1137
1138
1139 FT_LOCAL_DEF( void )
1141 {
1142 FT_ZERO( funcs );
1143
1150 }
1151
1152
1153 /*************************************************************************/
1154 /*************************************************************************/
1155 /***** *****/
1156 /***** TYPE 2 HINTS RECORDING INTERFACE *****/
1157 /***** *****/
1158 /*************************************************************************/
1159 /*************************************************************************/
1160
1161 static void
1163 {
1165 }
1166
1167
1168 static void
1170 FT_UInt dimension,
1171 FT_Int count,
1172 FT_Fixed* coords )
1173 {
1174 FT_Pos stems[32], y;
1175 FT_Int total = count, n;
1176
1177
1178 y = 0;
1179 while ( total > 0 )
1180 {
1181 /* determine number of stems to write */
1182 count = total;
1183 if ( count > 16 )
1184 count = 16;
1185
1186 /* compute integer stem positions in font units */
1187 for ( n = 0; n < count * 2; n++ )
1188 {
1189 y = ADD_LONG( y, coords[n] );
1190 stems[n] = FIXED_TO_INT( y );
1191 }
1192
1193 /* compute lengths */
1194 for ( n = 0; n < count * 2; n += 2 )
1195 stems[n + 1] = stems[n + 1] - stems[n];
1196
1197 /* add them to the current dimension */
1198 ps_hints_stem( (PS_Hints)hints, dimension, count, stems );
1199
1200 total -= count;
1201 }
1202 }
1203
1204
1205 FT_LOCAL_DEF( void )
1207 {
1208 FT_ZERO( funcs );
1209
1216 }
1217
1218
1219/* END */
#define read
Definition: acwin.h:96
#define write
Definition: acwin.h:97
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define FT_LOCAL_DEF(x)
#define FT_LOCAL(x)
#define NULL
Definition: types.h:112
DWORD amask
Definition: surface.c:189
DWORD rmask
Definition: surface.c:186
unsigned int idx
Definition: utils.c:41
int Fail
Definition: ehthrow.cxx:24
return FT_Err_Ok
Definition: ftbbox.c:526
#define FIXED_TO_INT(x)
Definition: ftcalc.h:450
#define ADD_LONG(a, b)
Definition: ftcalc.h:472
#define ADD_INT(a, b)
Definition: ftcalc.h:463
#define FT_TRACE0(varformat)
Definition: ftdebug.h:187
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:243
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_ZERO(p)
Definition: ftmemory.h:246
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:344
#define FT_MIN(a, b)
Definition: ftobjs.h:70
#define FT_PAD_CEIL(x, n)
Definition: ftobjs.h:89
#define ft_memmove
Definition: ftstdlib.h:83
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
unsigned char FT_Byte
Definition: fttypes.h:154
signed long FT_Fixed
Definition: fttypes.h:287
int FT_Error
Definition: fttypes.h:299
signed long FT_Long
Definition: fttypes.h:242
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
size_t total
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble n
Definition: glext.h:7729
GLuint coords
Definition: glext.h:7368
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
FT_Error(* T2_Hints_CloseFunc)(T2_Hints hints, FT_UInt end_point)
Definition: pshints.h:579
void(* T2_Hints_CounterFunc)(T2_Hints hints, FT_UInt bit_count, const FT_Byte *bytes)
Definition: pshints.h:549
void(* T1_Hints_SetStemFunc)(T1_Hints hints, FT_UInt dimension, FT_Fixed *coords)
Definition: pshints.h:178
void(* T1_Hints_OpenFunc)(T1_Hints hints)
Definition: pshints.h:138
void(* T1_Hints_SetStem3Func)(T1_Hints hints, FT_UInt dimension, FT_Fixed *coords)
Definition: pshints.h:212
void(* T2_Hints_StemsFunc)(T2_Hints hints, FT_UInt dimension, FT_Int count, FT_Fixed *coordinates)
Definition: pshints.h:465
FT_Error(* T1_Hints_CloseFunc)(T1_Hints hints, FT_UInt end_point)
Definition: pshints.h:265
void(* T2_Hints_OpenFunc)(T2_Hints hints)
Definition: pshints.h:425
struct T1_HintsRec_ * T1_Hints
Definition: pshints.h:103
void(* T2_Hints_MaskFunc)(T2_Hints hints, FT_UInt end_point, FT_UInt bit_count, const FT_Byte *bytes)
Definition: pshints.h:507
FT_Error(* T1_Hints_ApplyFunc)(T1_Hints hints, FT_Outline *outline, PSH_Globals globals, FT_Render_Mode hint_mode)
Definition: pshints.h:304
FT_Error(* T2_Hints_ApplyFunc)(T2_Hints hints, FT_Outline *outline, PSH_Globals globals, FT_Render_Mode hint_mode)
Definition: pshints.h:617
void(* T1_Hints_ResetFunc)(T1_Hints hints, FT_UInt end_point)
Definition: pshints.h:236
struct T2_HintsRec_ * T2_Hints
Definition: pshints.h:390
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:122
FT_Error ps_hints_apply(PS_Hints ps_hints, FT_Outline *outline, PSH_Globals globals, FT_Render_Mode hint_mode)
Definition: pshalgo.c:2069
static void ps_dimension_done(PS_Dimension dimension, FT_Memory memory)
Definition: pshrec.c:543
static FT_Error ps_dimension_set_mask_bits(PS_Dimension dim, const FT_Byte *source, FT_UInt source_pos, FT_UInt source_bits, FT_UInt end_point, FT_Memory memory)
Definition: pshrec.c:625
static FT_Int ps_mask_table_test_intersect(PS_Mask_Table table, FT_UInt index1, FT_UInt index2)
Definition: pshrec.c:370
static void t1_hints_open(T1_Hints hints)
Definition: pshrec.c:1119
static FT_Error ps_dimension_end(PS_Dimension dim, FT_UInt end_point, FT_Memory memory)
Definition: pshrec.c:780
static FT_Error ps_mask_table_merge(PS_Mask_Table table, FT_UInt index1, FT_UInt index2, FT_Memory memory)
Definition: pshrec.c:402
static FT_Error ps_hints_close(PS_Hints hints, FT_UInt end_point)
Definition: pshrec.c:1082
t1_hints_funcs_init(T1_Hints_FuncsRec *funcs)
Definition: pshrec.c:1140
static FT_Error ps_dimension_add_t1stem(PS_Dimension dim, FT_Int pos, FT_Int len, FT_Memory memory, FT_Int *aindex)
Definition: pshrec.c:651
static FT_Error ps_mask_set_bit(PS_Mask mask, FT_UInt idx, FT_Memory memory)
Definition: pshrec.c:184
ps_hints_init(PS_Hints hints, FT_Memory memory)
Definition: pshrec.c:817
static FT_Error ps_hint_table_alloc(PS_Hint_Table table, FT_Memory memory, PS_Hint *ahint)
Definition: pshrec.c:81
static void ps_hints_t2mask(PS_Hints hints, FT_UInt end_point, FT_UInt bit_count, const FT_Byte *bytes)
Definition: pshrec.c:990
static void ps_hint_table_done(PS_Hint_Table table, FT_Memory memory)
Definition: pshrec.c:49
static FT_Int ps_mask_test_bit(PS_Mask mask, FT_Int idx)
Definition: pshrec.c:156
ps_hints_done(PS_Hints hints)
Definition: pshrec.c:803
static void t1_hints_stem(T1_Hints hints, FT_UInt dimension, FT_Fixed *coords)
Definition: pshrec.c:1125
static FT_Error ps_mask_table_alloc(PS_Mask_Table table, FT_Memory memory, PS_Mask *amask)
Definition: pshrec.c:250
static void ps_hints_t1stem3(PS_Hints hints, FT_UInt dimension, FT_Fixed *stems)
Definition: pshrec.c:888
static FT_Error ps_dimension_add_counter(PS_Dimension dim, FT_Int hint1, FT_Int hint2, FT_Int hint3, FT_Memory memory)
Definition: pshrec.c:722
static void ps_hints_t1reset(PS_Hints hints, FT_UInt end_point)
Definition: pshrec.c:951
static void ps_mask_table_done(PS_Mask_Table table, FT_Memory memory)
Definition: pshrec.c:211
static void t2_hints_stems(T2_Hints hints, FT_UInt dimension, FT_Int count, FT_Fixed *coords)
Definition: pshrec.c:1169
static FT_Error ps_mask_table_set_bits(PS_Mask_Table table, const FT_Byte *source, FT_UInt bit_pos, FT_UInt bit_count, FT_Memory memory)
Definition: pshrec.c:309
static void ps_hints_t2counter(PS_Hints hints, FT_UInt bit_count, const FT_Byte *bytes)
Definition: pshrec.c:1036
static FT_Error ps_hint_table_ensure(PS_Hint_Table table, FT_UInt count, FT_Memory memory)
Definition: pshrec.c:60
t2_hints_funcs_init(T2_Hints_FuncsRec *funcs)
Definition: pshrec.c:1206
static void t2_hints_open(T2_Hints hints)
Definition: pshrec.c:1162
static void ps_mask_clear_bit(PS_Mask mask, FT_UInt idx)
Definition: pshrec.c:168
static FT_Error ps_dimension_reset_mask(PS_Dimension dim, FT_UInt end_point, FT_Memory memory)
Definition: pshrec.c:608
static void ps_mask_done(PS_Mask mask, FT_Memory memory)
Definition: pshrec.c:123
static FT_Error ps_mask_table_last(PS_Mask_Table table, FT_Memory memory, PS_Mask *amask)
Definition: pshrec.c:282
static FT_Error ps_mask_table_ensure(PS_Mask_Table table, FT_UInt count, FT_Memory memory)
Definition: pshrec.c:229
static void ps_dimension_end_mask(PS_Dimension dim, FT_UInt end_point)
Definition: pshrec.c:589
static FT_Error ps_mask_table_merge_all(PS_Mask_Table table, FT_Memory memory)
Definition: pshrec.c:499
static void ps_hints_stem(PS_Hints hints, FT_UInt dimension, FT_Int count, FT_Long *stems)
Definition: pshrec.c:840
static void ps_hints_open(PS_Hints hints, PS_Hint_Type hint_type)
Definition: pshrec.c:827
static void ps_dimension_init(PS_Dimension dimension)
Definition: pshrec.c:554
static FT_Error ps_mask_ensure(PS_Mask mask, FT_UInt count, FT_Memory memory)
Definition: pshrec.c:135
enum PS_Hint_Type_ PS_Hint_Type
@ PS_HINT_TYPE_1
Definition: pshrec.h:56
@ PS_HINT_TYPE_2
Definition: pshrec.h:57
#define PS_HINT_FLAG_GHOST
Definition: pshrec.h:63
#define PS_HINT_FLAG_BOTTOM
Definition: pshrec.h:64
typedefFT_BEGIN_HEADER struct PS_HintRec_ * PS_Hint
Definition: pshrec.h:51
static calc_node_t temp
Definition: rpn_ieee.c:38
static struct __wine_debug_functions funcs
Definition: debug.c:48
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
static void Exit(void)
Definition: sock.c:1330
PS_Mask_TableRec masks
Definition: pshrec.h:117
PS_Mask_TableRec counters
Definition: pshrec.h:118
PS_Hint_TableRec hints
Definition: pshrec.h:116
PS_Hint hints
Definition: pshrec.h:87
FT_UInt num_hints
Definition: pshrec.h:85
FT_UInt end_point
Definition: pshrec.h:98
FT_UInt num_bits
Definition: pshrec.h:95
FT_Byte * bytes
Definition: pshrec.h:97
PS_Mask masks
Definition: pshrec.h:108
FT_UInt num_masks
Definition: pshrec.h:106
#define max(a, b)
Definition: svc.c:63
DWORD hint
Definition: vfdcmd.c:88