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 );