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