1 /***************************************************************************/
5 /* OpenType layout support, common tables (body). */
7 /* Copyright 2002 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
22 /*************************************************************************/
23 /*************************************************************************/
25 /***** COVERAGE TABLE *****/
27 /*************************************************************************/
28 /*************************************************************************/
31 otl_coverage_validate( OTL_Bytes table,
38 if ( table + 4 > valid->limit )
39 OTL_INVALID_TOO_SHORT;
41 format = OTL_NEXT_USHORT( p );
46 OTL_UInt count = OTL_NEXT_USHORT( p );
49 if ( p + count * 2 >= valid->limit )
50 OTL_INVALID_TOO_SHORT;
52 /* XXX: check glyph indices */
58 OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p );
59 OTL_UInt start, end, start_cover, total = 0, last = 0;
62 if ( p + num_ranges * 6 >= valid->limit )
63 OTL_INVALID_TOO_SHORT;
65 for ( n = 0; n < num_ranges; n++ )
67 start = OTL_NEXT_USHORT( p );
68 end = OTL_NEXT_USHORT( p );
69 start_cover = OTL_NEXT_USHORT( p );
71 if ( start > end || start_cover != total )
74 if ( n > 0 && start <= last )
77 total += end - start + 1;
89 OTL_LOCALDEF( OTL_UInt )
90 otl_coverage_get_count( OTL_Bytes table )
93 OTL_UInt format = OTL_NEXT_USHORT( p );
94 OTL_UInt count = OTL_NEXT_USHORT( p );
108 for ( ; count > 0; count-- )
110 start = OTL_NEXT_USHORT( p );
111 end = OTL_NEXT_USHORT( p );
112 p += 2; /* skip start_index */
114 result += end - start + 1;
127 OTL_LOCALDEF( OTL_Int )
128 otl_coverage_get_index( OTL_Bytes table,
129 OTL_UInt glyph_index )
132 OTL_UInt format = OTL_NEXT_USHORT( p );
133 OTL_UInt count = OTL_NEXT_USHORT( p );
140 OTL_UInt min = 0, max = count, mid, gindex;
146 mid = ( min + max ) >> 1;
148 gindex = OTL_PEEK_USHORT( p );
150 if ( glyph_index == gindex )
153 if ( glyph_index < gindex )
163 OTL_UInt min = 0, max = count, mid;
164 OTL_UInt start, end, delta, start_cover;
170 mid = ( min + max ) >> 1;
172 start = OTL_NEXT_USHORT( p );
173 end = OTL_NEXT_USHORT( p );
175 if ( glyph_index < start )
177 else if ( glyph_index > end )
180 return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start );
193 /*************************************************************************/
194 /*************************************************************************/
196 /***** CLASS DEFINITION TABLE *****/
198 /*************************************************************************/
199 /*************************************************************************/
202 otl_class_definition_validate( OTL_Bytes table,
203 OTL_Validator valid )
209 if ( p + 4 > valid->limit )
210 OTL_INVALID_TOO_SHORT;
212 format = OTL_NEXT_USHORT( p );
217 OTL_UInt count, start = OTL_NEXT_USHORT( p );
220 if ( p + 2 > valid->limit )
221 OTL_INVALID_TOO_SHORT;
223 count = OTL_NEXT_USHORT( p );
225 if ( p + count * 2 > valid->limit )
226 OTL_INVALID_TOO_SHORT;
228 /* XXX: check glyph indices */
234 OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p );
235 OTL_UInt start, end, value, last = 0;
238 if ( p + num_ranges * 6 > valid->limit )
239 OTL_INVALID_TOO_SHORT;
241 for ( n = 0; n < num_ranges; n++ )
243 start = OTL_NEXT_USHORT( p );
244 end = OTL_NEXT_USHORT( p );
245 value = OTL_NEXT_USHORT( p ); /* ignored */
247 if ( start > end || ( n > 0 && start <= last ) )
261 OTL_LOCALDEF( OTL_UInt )
262 otl_class_definition_get_value( OTL_Bytes table,
263 OTL_UInt glyph_index )
266 OTL_UInt format = OTL_NEXT_USHORT( p );
273 OTL_UInt start = OTL_NEXT_USHORT( p );
274 OTL_UInt count = OTL_NEXT_USHORT( p );
275 OTL_UInt idx = (OTL_UInt)( glyph_index - start );
281 return OTL_PEEK_USHORT( p );
288 OTL_UInt count = OTL_NEXT_USHORT( p );
289 OTL_UInt min = 0, max = count, mid, gindex;
295 mid = ( min + max ) >> 1;
297 start = OTL_NEXT_USHORT( p );
298 end = OTL_NEXT_USHORT( p );
300 if ( glyph_index < start )
302 else if ( glyph_index > end )
305 return OTL_PEEK_USHORT( p );
318 /*************************************************************************/
319 /*************************************************************************/
321 /***** DEVICE TABLE *****/
323 /*************************************************************************/
324 /*************************************************************************/
327 otl_device_table_validate( OTL_Bytes table,
328 OTL_Validator valid )
331 OTL_UInt start, end, count, format, count;
334 if ( p + 8 > valid->limit )
335 OTL_INVALID_TOO_SHORT;
337 start = OTL_NEXT_USHORT( p );
338 end = OTL_NEXT_USHORT( p );
339 format = OTL_NEXT_USHORT( p );
341 if ( format < 1 || format > 3 || end < start )
344 count = (OTL_UInt)( end - start + 1 );
346 if ( p + ( ( 1 << format ) * count ) / 8 > valid->limit )
347 OTL_INVALID_TOO_SHORT;
351 OTL_LOCALDEF( OTL_UInt )
352 otl_device_table_get_start( OTL_Bytes table )
357 return OTL_PEEK_USHORT( p );
361 OTL_LOCALDEF( OTL_UInt )
362 otl_device_table_get_end( OTL_Bytes table )
364 OTL_Bytes p = table + 2;
367 return OTL_PEEK_USHORT( p );
371 OTL_LOCALDEF( OTL_Int )
372 otl_device_table_get_delta( OTL_Bytes table,
377 OTL_UInt start, end, format, idx, value;
380 start = OTL_NEXT_USHORT( p );
381 end = OTL_NEXT_USHORT( p );
382 format = OTL_NEXT_USHORT( p );
384 if ( size >= start && size <= end )
386 /* we could do that with clever bit operations, but a switch is */
387 /* much simpler to understand and maintain */
392 idx = (OTL_UInt)( ( size - start ) * 2 );
394 value = OTL_PEEK_USHORT( p );
396 result = (OTL_Short)( value << shift ) >> ( 14 - shift );
401 idx = (OTL_UInt)( ( size - start ) * 4 );
403 value = OTL_PEEK_USHORT( p );
405 result = (OTL_Short)( value << shift ) >> ( 12 - shift );
410 idx = (OTL_UInt)( ( size - start ) * 8 );
412 value = OTL_PEEK_USHORT( p );
414 result = (OTL_Short)( value << shift ) >> ( 8 - shift );
427 /*************************************************************************/
428 /*************************************************************************/
430 /***** LOOKUP LISTS *****/
432 /*************************************************************************/
433 /*************************************************************************/
436 otl_lookup_validate( OTL_Bytes table,
437 OTL_Validator valid )
443 if ( table + 6 > valid->limit )
444 OTL_INVALID_TOO_SHORT;
447 num_tables = OTL_NEXT_USHORT( p );
449 if ( p + num_tables * 2 > valid->limit )
450 OTL_INVALID_TOO_SHORT;
452 for ( ; num_tables > 0; num_tables-- )
454 offset = OTL_NEXT_USHORT( p );
456 if ( table + offset >= valid->limit )
460 /* XXX: check sub-tables? */
464 OTL_LOCALDEF( OTL_UInt )
465 otl_lookup_get_count( OTL_Bytes table )
467 OTL_Bytes p = table + 4;
470 return OTL_PEEK_USHORT( p );
474 OTL_LOCALDEF( OTL_Bytes )
475 otl_lookup_get_table( OTL_Bytes table,
478 OTL_Bytes p, result = NULL;
483 count = OTL_NEXT_USHORT( p );
487 result = table + OTL_PEEK_USHORT( p );
494 /*************************************************************************/
495 /*************************************************************************/
497 /***** LOOKUP LISTS *****/
499 /*************************************************************************/
500 /*************************************************************************/
503 otl_lookup_list_validate( OTL_Bytes table,
504 OTL_Validator valid )
506 OTL_Bytes p = table, q;
507 OTL_UInt num_lookups, offset;
510 if ( p + 2 > valid->limit )
511 OTL_INVALID_TOO_SHORT;
513 num_lookups = OTL_NEXT_USHORT( p );
515 if ( p + num_lookups * 2 > valid->limit )
516 OTL_INVALID_TOO_SHORT;
518 for ( ; num_lookups > 0; num_lookups-- )
520 offset = OTL_NEXT_USHORT( p );
522 otl_lookup_validate( table + offset, valid );
527 OTL_LOCALDEF( OTL_UInt )
528 otl_lookup_list_get_count( OTL_Bytes table )
533 return OTL_PEEK_USHORT( p );
537 OTL_LOCALDEF( OTL_Bytes )
538 otl_lookup_list_get_lookup( OTL_Bytes table,
541 OTL_Bytes p, result = 0;
546 count = OTL_NEXT_USHORT( p );
550 result = table + OTL_PEEK_USHORT( p );
557 OTL_LOCALDEF( OTL_Bytes )
558 otl_lookup_list_get_table( OTL_Bytes table,
559 OTL_UInt lookup_index,
560 OTL_UInt table_index )
562 OTL_Bytes result = NULL;
565 result = otl_lookup_list_get_lookup( table, lookup_index );
567 result = otl_lookup_get_table( result, table_index );
574 otl_lookup_list_foreach( OTL_Bytes table,
575 OTL_ForeachFunc func,
576 OTL_Pointer func_data )
579 OTL_UInt count = OTL_NEXT_USHORT( p );
582 for ( ; count > 0; count-- )
583 func( table + OTL_NEXT_USHORT( p ), func_data );
587 /*************************************************************************/
588 /*************************************************************************/
590 /***** FEATURES *****/
592 /*************************************************************************/
593 /*************************************************************************/
596 otl_feature_validate( OTL_Bytes table,
597 OTL_Validator valid )
600 OTL_UInt feat_params, num_lookups;
603 if ( p + 4 > valid->limit )
604 OTL_INVALID_TOO_SHORT;
606 feat_params = OTL_NEXT_USHORT( p ); /* ignored */
607 num_lookups = OTL_NEXT_USHORT( p );
609 if ( p + num_lookups * 2 > valid->limit )
610 OTL_INVALID_TOO_SHORT;
612 /* XXX: check lookup indices */
616 OTL_LOCALDEF( OTL_UInt )
617 otl_feature_get_count( OTL_Bytes table )
619 OTL_Bytes p = table + 4;
622 return OTL_PEEK_USHORT( p );
626 OTL_LOCALDEF( OTL_UInt )
627 otl_feature_get_lookups( OTL_Bytes table,
633 OTL_UInt num_features, result = 0;
637 num_features = OTL_NEXT_USHORT( p );
641 for ( ; count > 0 && start < num_features; count--, start++ )
643 lookups[0] = OTL_NEXT_USHORT(p);
652 /*************************************************************************/
653 /*************************************************************************/
655 /***** FEATURE LIST *****/
657 /*************************************************************************/
658 /*************************************************************************/
661 otl_feature_list_validate( OTL_Bytes table,
662 OTL_Validator valid )
665 OTL_UInt num_features, offset;
668 if ( table + 2 > valid->limit )
669 OTL_INVALID_TOO_SHORT;
671 num_features = OTL_NEXT_USHORT( p );
673 if ( p + num_features * 2 > valid->limit )
674 OTL_INVALID_TOO_SHORT;
676 for ( ; num_features > 0; num_features-- )
678 p += 4; /* skip tag */
679 offset = OTL_NEXT_USHORT( p );
681 otl_feature_table_validate( table + offset, valid );
686 OTL_LOCALDEF( OTL_UInt )
687 otl_feature_list_get_count( OTL_Bytes table )
692 return OTL_PEEK_USHORT( p );
696 OTL_LOCALDEF( OTL_Bytes )
697 otl_feature_list_get_feature( OTL_Bytes table,
700 OTL_Bytes p, result = NULL;
705 count = OTL_NEXT_USHORT( p );
710 result = table + OTL_PEEK_USHORT( p );
718 otl_feature_list_foreach( OTL_Bytes table,
719 OTL_ForeachFunc func,
720 OTL_Pointer func_data )
727 count = OTL_NEXT_USHORT( p );
729 for ( ; count > 0; count-- )
730 func( table + OTL_NEXT_USHORT( p ), func_data );
734 /*************************************************************************/
735 /*************************************************************************/
737 /***** LANGUAGE SYSTEM *****/
739 /*************************************************************************/
740 /*************************************************************************/
744 otl_lang_validate( OTL_Bytes table,
745 OTL_Validator valid )
748 OTL_UInt lookup_order;
749 OTL_UInt req_feature;
750 OTL_UInt num_features;
753 if ( table + 6 >= valid->limit )
754 OTL_INVALID_TOO_SHORT;
756 lookup_order = OTL_NEXT_USHORT( p );
757 req_feature = OTL_NEXT_USHORT( p );
758 num_features = OTL_NEXT_USHORT( p );
760 /* XXX: check req_feature if not 0xFFFFU */
762 if ( p + 2 * num_features >= valid->limit )
763 OTL_INVALID_TOO_SHORT;
765 /* XXX: check features indices! */
769 OTL_LOCALDEF( OTL_UInt )
770 otl_lang_get_count( OTL_Bytes table )
772 OTL_Bytes p = table + 4;
774 return OTL_PEEK_USHORT( p );
778 OTL_LOCALDEF( OTL_UInt )
779 otl_lang_get_req_feature( OTL_Bytes table )
781 OTL_Bytes p = table + 2;
784 return OTL_PEEK_USHORT( p );
788 OTL_LOCALDEF( OTL_UInt )
789 otl_lang_get_features( OTL_Bytes table,
794 OTL_Bytes p = table + 4;
795 OTL_UInt num_features = OTL_NEXT_USHORT( p );
801 for ( ; count > 0 && start < num_features; start++, count-- )
803 features[0] = OTL_NEXT_USHORT( p );
814 /*************************************************************************/
815 /*************************************************************************/
817 /***** SCRIPTS *****/
819 /*************************************************************************/
820 /*************************************************************************/
824 otl_script_validate( OTL_Bytes table,
825 OTL_Validator valid )
827 OTL_UInt default_lang;
831 if ( table + 4 > valid->limit )
832 OTL_INVALID_TOO_SHORT;
834 default_lang = OTL_NEXT_USHORT( p );
835 num_langs = OTL_NEXT_USHORT( p );
837 if ( default_lang != 0 )
839 if ( table + default_lang >= valid->limit )
843 if ( p + num_langs * 6 >= valid->limit )
846 for ( ; num_langs > 0; num_langs-- )
851 p += 4; /* skip tag */
852 offset = OTL_NEXT_USHORT( p );
854 otl_lang_validate( table + offset, valid );
860 otl_script_list_validate( OTL_Bytes list,
861 OTL_Validator valid )
863 OTL_UInt num_scripts;
867 if ( list + 2 > valid->limit )
868 OTL_INVALID_TOO_SHORT;
870 num_scripts = OTL_NEXT_USHORT( p );
872 if ( p + num_scripts * 6 > valid->limit )
873 OTL_INVALID_TOO_SHORT;
875 for ( ; num_scripts > 0; num_scripts-- )
880 p += 4; /* skip tag */
881 offset = OTL_NEXT_USHORT( p );
883 otl_script_table_validate( list + offset, valid );
888 /*************************************************************************/
889 /*************************************************************************/
891 /***** LOOKUP LISTS *****/
893 /*************************************************************************/
894 /*************************************************************************/
897 otl_lookup_table_validate( OTL_Bytes table,
899 OTL_ValidateFunc* type_funcs,
900 OTL_Validator valid )
903 OTL_UInt lookup_type, lookup_flag, count;
904 OTL_ValidateFunc validate;
907 lookup_type = OTL_NEXT_USHORT( p );
908 lookup_flag = OTL_NEXT_USHORT( p );
909 count = OTL_NEXT_USHORT( p );
911 if ( lookup_type == 0 || lookup_type >= type_count )
914 validate = type_funcs[ lookup_type - 1 ];
916 OTL_CHECK( 2*count );
917 for ( ; count > 0; count-- )
918 validate( table + OTL_NEXT_USHORT( p ), valid );
923 otl_lookup_list_validate( OTL_Bytes table,
925 OTL_ValidateFunc* type_funcs,
926 OTL_Validator valid )
932 count = OTL_NEXT_USHORT( p );
934 OTL_CHECK( 2*count );
935 for ( ; count > 0; count-- )
936 otl_lookup_table_validate( table + OTL_NEXT_USHORT( p ),
937 type_count, type_funcs, valid );