~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/otlayout/otlgpos.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "otlgpos.h"
 
2
#include "otlcommn.h"
 
3
 
 
4
 /* forward declaration */
 
5
  static OTL_ValidateFunc  otl_gpos_validate_funcs[];
 
6
 
 
7
 
 
8
 /************************************************************************/
 
9
 /************************************************************************/
 
10
 /*****                                                              *****/
 
11
 /*****                         VALUE RECORDS                        *****/
 
12
 /*****                                                              *****/
 
13
 /************************************************************************/
 
14
 /************************************************************************/
 
15
 
 
16
  static OTL_UInt
 
17
  otl_value_length( OTL_UInt  format )
 
18
  {
 
19
    FT_UInt  count;
 
20
 
 
21
    count = (( format & 0xAA ) >> 1) + ( format & 0x55 );
 
22
    count = (( count  & 0xCC ) >> 2) + ( count  & 0x33 );
 
23
    count = (( count  & 0xF0 ) >> 4) + ( count  & 0x0F );
 
24
 
 
25
    return count;
 
26
  }
 
27
 
 
28
 
 
29
  static void
 
30
  otl_value_validate( OTL_Bytes      table,
 
31
                      OTL_Bytes      pos_table,
 
32
                      OTL_UInt       format,
 
33
                      OTL_Validator  valid )
 
34
  {
 
35
    OTL_Bytes  p = table;
 
36
    OTL_UInt   count, device;
 
37
 
 
38
    if ( format >= 0x100U )
 
39
      OTL_INVALID_DATA;
 
40
 
 
41
    for ( count = 4; count > 0; count-- )
 
42
    {
 
43
      if ( format & 1 )
 
44
      {
 
45
        OTL_CHECK( 2 );
 
46
        p += 2;
 
47
      }
 
48
 
 
49
      format >>= 1;
 
50
    }
 
51
 
 
52
    for ( count = 4; count > 0; count-- )
 
53
    {
 
54
      if ( format & 1 )
 
55
      {
 
56
        OTL_CHECK( 2 );
 
57
        device = OTL_NEXT_USHORT( p );
 
58
        if ( device )
 
59
          otl_device_table_validate( pos_table + device, valid );
 
60
      }
 
61
      format >>= 1;
 
62
    }
 
63
  }
 
64
 
 
65
 
 
66
 /************************************************************************/
 
67
 /************************************************************************/
 
68
 /*****                                                              *****/
 
69
 /*****                          ANCHORS                             *****/
 
70
 /*****                                                              *****/
 
71
 /************************************************************************/
 
72
 /************************************************************************/
 
73
 
 
74
  static void
 
75
  otl_anchor_validate( OTL_Bytes      table,
 
76
                       OTL_Validator  valid )
 
77
  {
 
78
    OTL_Bytes  p = table;
 
79
    OTL_UInt   format;
 
80
 
 
81
    OTL_CHECK( 6 );
 
82
    format = OTL_NEXT_USHORT( p );
 
83
    p += 4;
 
84
 
 
85
    switch ( format )
 
86
    {
 
87
      case 1:
 
88
        break;
 
89
 
 
90
      case 2:
 
91
        OTL_CHECK( 2 );  /* anchor point */
 
92
        break;
 
93
 
 
94
      case 3:
 
95
        {
 
96
          OTL_UInt  x_device, y_device;
 
97
 
 
98
          OTL_CHECK( 4 );
 
99
          x_device = OTL_NEXT_USHORT( p );
 
100
          y_device = OTL_NEXT_USHORT( p );
 
101
 
 
102
          if ( x_device )
 
103
            otl_device_table_validate( table + x_device, valid );
 
104
 
 
105
          if ( y_device )
 
106
            otl_device_table_validate( table + y_device, valid );
 
107
        }
 
108
        break;
 
109
 
 
110
      default:
 
111
        OTL_INVALID_DATA;
 
112
    }
 
113
  }
 
114
 
 
115
 
 
116
 /************************************************************************/
 
117
 /************************************************************************/
 
118
 /*****                                                              *****/
 
119
 /*****                           MARK ARRAY                         *****/
 
120
 /*****                                                              *****/
 
121
 /************************************************************************/
 
122
 /************************************************************************/
 
123
 
 
124
  static void
 
125
  otl_mark_array_validate( OTL_Bytes      table,
 
126
                           OTL_Validator  valid )
 
127
  {
 
128
    OTL_Bytes  p = table;
 
129
    OTL_UInt   count;
 
130
 
 
131
    OTL_CHECK( 2 );
 
132
 
 
133
    count = OTL_NEXT_USHORT( p );
 
134
    OTL_CHECK( count * 4 );
 
135
    for ( ; count > 0; count-- )
 
136
    {
 
137
      p += 2;  /* ignore class index */
 
138
      otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid );
 
139
    }
 
140
  }
 
141
 
 
142
 
 
143
 /************************************************************************/
 
144
 /************************************************************************/
 
145
 /*****                                                              *****/
 
146
 /*****                 GPOS LOOKUP TYPE 1                           *****/
 
147
 /*****                                                              *****/
 
148
 /************************************************************************/
 
149
 /************************************************************************/
 
150
 
 
151
  static void
 
152
  otl_gpos_lookup1_validate( OTL_Bytes      table,
 
153
                             OTL_Validator  valid )
 
154
  {
 
155
    OTL_Bytes  p = table;
 
156
    OTL_UInt   format;
 
157
 
 
158
    OTL_CHECK( 2 );
 
159
    format = OTL_NEXT_USHORT( p );
 
160
    switch ( format )
 
161
    {
 
162
      case 1:
 
163
        {
 
164
          FT_UInt  coverage, value_format;
 
165
 
 
166
          OTL_CHECK( 4 );
 
167
          coverage     = OTL_NEXT_USHORT( p );
 
168
          value_format = OTL_NEXT_USHORT( p );
 
169
 
 
170
          otl_coverage_validate( table + coverage, valid );
 
171
          otl_value_validate( p, table, value_format, valid );
 
172
        }
 
173
        break;
 
174
 
 
175
      case 2:
 
176
        {
 
177
          FT_UInt  coverage, value_format, count, len;
 
178
 
 
179
          OTL_CHECK( 6 );
 
180
          coverage     = OTL_NEXT_USHORT( p );
 
181
          value_format = OTL_NEXT_USHORT( p );
 
182
          count        = OTL_NEXT_USHORT( p );
 
183
          len          = otl_value_length( value_format );
 
184
 
 
185
          otl_coverage_validate( table + coverage, valid );
 
186
 
 
187
          OTL_CHECK( count * len );
 
188
          for ( ; count > 0; count-- )
 
189
          {
 
190
            otl_value_validate( p, table, value_format, valid );
 
191
            p += len;
 
192
          }
 
193
        }
 
194
        break;
 
195
 
 
196
      default:
 
197
        OTL_INVALID_DATA;
 
198
    }
 
199
  }
 
200
 
 
201
 
 
202
 /************************************************************************/
 
203
 /************************************************************************/
 
204
 /*****                                                              *****/
 
205
 /*****                 GPOS LOOKUP TYPE 2                           *****/
 
206
 /*****                                                              *****/
 
207
 /************************************************************************/
 
208
 /************************************************************************/
 
209
 
 
210
  static otl_gpos_pairset_validate( OTL_Bytes      table,
 
211
                                    OTL_Bytes      pos_table,
 
212
                                    OTL_UInt       format1,
 
213
                                    OTL_UInt       format2,
 
214
                                    OTL_Validator  valid )
 
215
  {
 
216
    OTL_Bytes  p = table;
 
217
    OTL_UInt   len1, len2, count;
 
218
 
 
219
    OTL_CHECK( 2 );
 
220
    count = OTL_NEXT_USHORT( p );
 
221
    len1  = otl_value_length( format1 );
 
222
    len2  = otl_value_length( format2 );
 
223
 
 
224
    OTL_CHECK( count * (len1+len2+2) );
 
225
    for ( ; count > 0; count-- )
 
226
    {
 
227
      p += 2;  /* ignore glyph id */
 
228
      otl_value_validate( p, pos_table, format1, valid );
 
229
      p += len1;
 
230
 
 
231
      otl_value_validate( p, pos_table, format2, valid );
 
232
      p += len2;
 
233
    }
 
234
  }
 
235
 
 
236
  static void
 
237
  otl_gpos_lookup2_validate( OTL_Bytes      table,
 
238
                             OTL_Validator  valid )
 
239
  {
 
240
    OTL_Bytes  p = table;
 
241
    OTL_UInt   format;
 
242
 
 
243
    OTL_CHECK( 2 );
 
244
    format = OTL_NEXT_USHORT( p );
 
245
    switch (format)
 
246
    {
 
247
      case 1:
 
248
        {
 
249
          OTL_UInt  coverage, value1, value2, count;
 
250
 
 
251
          OTL_CHECK( 8 );
 
252
          coverage = OTL_NEXT_USHORT( p );
 
253
          value1   = OTL_NEXT_USHORT( p );
 
254
          value2   = OTL_NEXT_USHORT( p );
 
255
          count    = OTL_NEXT_USHORT( p );
 
256
 
 
257
          otl_coverage_validate( table + coverage, valid );
 
258
 
 
259
          OTL_CHECK( count*2 );
 
260
          for ( ; count > 0; count-- )
 
261
          {
 
262
            otl_gpos_pairset_validate( table + OTL_NEXT_USHORT( p ),
 
263
                                       table, value1, value2, valid );
 
264
          }
 
265
        }
 
266
        break;
 
267
 
 
268
      case 2:
 
269
        {
 
270
          OTL_UInt  coverage, value1, value2, class1, class2, count1, count2;
 
271
          OTL_UInt  len1, len2;
 
272
 
 
273
          OTL_CHECK( 14 );
 
274
          coverage = OTL_NEXT_USHORT( p );
 
275
          value1   = OTL_NEXT_USHORT( p );
 
276
          value2   = OTL_NEXT_USHORT( p );
 
277
          class1   = OTL_NEXT_USHORT( p );
 
278
          class2   = OTL_NEXT_USHORT( p );
 
279
          count1   = OTL_NEXT_USHORT( p );
 
280
          count2   = OTL_NEXT_USHORT( p );
 
281
 
 
282
          len1 = otl_value_length( value1 );
 
283
          len2 = otl_value_length( value2 );
 
284
 
 
285
          otl_coverage_validate( table + coverage, valid );
 
286
 
 
287
          OTL_CHECK( count1*count2*(len1+len2) );
 
288
          for ( ; count1 > 0; count1-- )
 
289
          {
 
290
            for ( ; count2 > 0; count2-- )
 
291
            {
 
292
              otl_value_validate( p, table, value1, valid );
 
293
              p += len1;
 
294
 
 
295
              otl_value_validate( p, table, value2, valid );
 
296
              p += len2;
 
297
            }
 
298
          }
 
299
        }
 
300
        break;
 
301
 
 
302
      default:
 
303
        OTL_INVALID_DATA;
 
304
    }
 
305
  }
 
306
 
 
307
 
 
308
 /************************************************************************/
 
309
 /************************************************************************/
 
310
 /*****                                                              *****/
 
311
 /*****                 GPOS LOOKUP TYPE 3                           *****/
 
312
 /*****                                                              *****/
 
313
 /************************************************************************/
 
314
 /************************************************************************/
 
315
 
 
316
  static void
 
317
  otl_gpos_lookup3_validate( OTL_Bytes  table,
 
318
                             OTL_Valid  valid )
 
319
  {
 
320
    OTL_Bytes  p = table;
 
321
    OTL_UInt   format;
 
322
 
 
323
    OTL_CHECK( 2 );
 
324
    format = OTL_NEXT_USHORT( p );
 
325
    switch (format)
 
326
    {
 
327
      case 1:
 
328
        {
 
329
          OTL_UInt  coverage, count, anchor1, anchor2;
 
330
 
 
331
          OTL_CHECK( 4 );
 
332
          coverage = OTL_NEXT_USHORT( p );
 
333
          count    = OTL_NEXT_USHORT( p );
 
334
 
 
335
          otl_coverage_validate( table + coverage, valid );
 
336
 
 
337
          OTL_CHECK( count*4 );
 
338
          for ( ; count > 0; count-- )
 
339
          {
 
340
            anchor1 = OTL_NEXT_USHORT( p );
 
341
            anchor2 = OTL_NEXT_USHORT( p );
 
342
 
 
343
            if ( anchor1 )
 
344
              otl_anchor_validate( table + anchor1, valid );
 
345
 
 
346
            if ( anchor2 )
 
347
              otl_anchor_validate( table + anchor2, valid );
 
348
          }
 
349
        }
 
350
        break;
 
351
 
 
352
      default:
 
353
        OTL_INVALID_DATA;
 
354
    }
 
355
  }
 
356
 
 
357
 
 
358
 /************************************************************************/
 
359
 /************************************************************************/
 
360
 /*****                                                              *****/
 
361
 /*****                 GPOS LOOKUP TYPE 4                           *****/
 
362
 /*****                                                              *****/
 
363
 /************************************************************************/
 
364
 /************************************************************************/
 
365
 
 
366
  static void
 
367
  otl_base_array_validate( OTL_Bytes      table,
 
368
                           OTL_UInt       class_count,
 
369
                           OTL_Validator  valid )
 
370
  {
 
371
    OTL_Bytes  p = table;
 
372
    OTL_UInt   count, count2;
 
373
 
 
374
    OTL_CHECK( 2 );
 
375
    count = OTL_NEXT_USHORT( p );
 
376
 
 
377
    OTL_CHECK( count*class_count*2 );
 
378
    for ( ; count > 0; count-- )
 
379
      for ( count2 = class_count; count2 > 0; count2-- )
 
380
        otl_anchor_validate( table + OTL_NEXT_USHORT( p ) );
 
381
  }
 
382
 
 
383
 
 
384
  static void
 
385
  otl_gpos_lookup4_validate( OTL_Bytes  table,
 
386
                             OTL_Valid  valid )
 
387
  {
 
388
    OTL_Bytes  p = table;
 
389
    OTL_UInt   format;
 
390
 
 
391
    OTL_CHECK( 2 );
 
392
    format = OTL_NEXT_USHORT( p );
 
393
    switch (format)
 
394
    {
 
395
      case 1:
 
396
        {
 
397
          OTL_UInt  mark_coverage, base_coverage, class_count;
 
398
          OTL_UInt  mark_array, base_array;
 
399
 
 
400
          OTL_CHECK( 10 );
 
401
          mark_coverage = OTL_NEXT_USHORT( p );
 
402
          base_coverage = OTL_NEXT_USHORT( p );
 
403
          class_count   = OTL_NEXT_USHORT( p );
 
404
          mark_array    = OTL_NEXT_USHORT( p );
 
405
          base_array    = OTL_NEXT_USHORT( p );
 
406
 
 
407
          otl_coverage_validate( table + mark_coverage, valid );
 
408
          otl_coverage_validate( table + base_coverage, valid );
 
409
 
 
410
          otl_mark_array_validate( table + mark_array, valid );
 
411
          otl_base_array_validate( table, class_count, valid );
 
412
        }
 
413
        break;
 
414
 
 
415
      default:
 
416
        OTL_INVALID_DATA;
 
417
    }
 
418
  }
 
419
 
 
420
 /************************************************************************/
 
421
 /************************************************************************/
 
422
 /*****                                                              *****/
 
423
 /*****                 GPOS LOOKUP TYPE 5                           *****/
 
424
 /*****                                                              *****/
 
425
 /************************************************************************/
 
426
 /************************************************************************/
 
427
 
 
428
  static void
 
429
  otl_liga_attach_validate( OTL_Bytes      table,
 
430
                            OTL_UInt       class_count,
 
431
                            OTL_Validator  valid )
 
432
  {
 
433
    OTL_Bytes  p = table;
 
434
    OTL_UInt   count, count2;
 
435
 
 
436
    OTL_CHECK( 2 );
 
437
    count = OTL_NEXT_USHORT( p );
 
438
 
 
439
    OTL_CHECK( count*class_count*2 );
 
440
    for ( ; count > 0; count-- )
 
441
      for ( count2 = class_count; class_count > 0; class_count-- )
 
442
        otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid );
 
443
  }
 
444
 
 
445
 
 
446
  static void
 
447
  otl_liga_array_validate( OTL_Bytes      table,
 
448
                           OTL_UInt       class_count,
 
449
                           OTL_Validator  valid )
 
450
  {
 
451
    OTL_Bytes  p = table;
 
452
    OTL_UInt   count, count2;
 
453
 
 
454
    OTL_CHECK( 2 );
 
455
    count = OTL_NEXT_USHORT( p );
 
456
 
 
457
    OTL_CHECK( count*2 );
 
458
    for ( ; count > 0; count-- )
 
459
      otl_liga_attach_validate( table + OTL_NEXT_USHORT( p ), valid );
 
460
  }
 
461
 
 
462
 
 
463
  static void
 
464
  otl_gpos_lookup5_validate( OTL_Bytes  table,
 
465
                             OTL_Valid  valid )
 
466
  {
 
467
    OTL_Bytes  p = table;
 
468
    OTL_UInt   format;
 
469
 
 
470
    OTL_CHECK( 2 );
 
471
    format = OTL_NEXT_USHORT( p );
 
472
    switch (format)
 
473
    {
 
474
      case 1:
 
475
        {
 
476
          OTL_UInt  mark_coverage, lig_coverage, class_count;
 
477
          OTL_UInt  mar_array, lig_array;
 
478
 
 
479
          OTL_CHECK( 10 );
 
480
          mark_coverage = OTL_NEXT_USHORT( p );
 
481
          liga_coverage = OTL_NEXT_USHORT( p );
 
482
          class_count   = OTL_NEXT_USHORT( p );
 
483
          mark_array    = OTL_NEXT_USHORT( p );
 
484
          liga_array    = OTL_NEXT_USHORT( p );
 
485
 
 
486
          otl_coverage_validate( table + mark_coverage, valid );
 
487
          otl_coverage_validate( table + liga_coverage, valid );
 
488
 
 
489
          otl_mark_array_validate( table + mark_array, valid );
 
490
          otl_liga_array_validate( table + liga_array, class_count, valid );
 
491
        }
 
492
        break;
 
493
 
 
494
      default:
 
495
        OTL_INVALID_DATA;
 
496
    }
 
497
  }
 
498
 
 
499
 /************************************************************************/
 
500
 /************************************************************************/
 
501
 /*****                                                              *****/
 
502
 /*****                 GPOS LOOKUP TYPE 6                           *****/
 
503
 /*****                                                              *****/
 
504
 /************************************************************************/
 
505
 /************************************************************************/
 
506
 
 
507
 
 
508
  static void
 
509
  otl_mark2_array_validate( OTL_Bytes      table,
 
510
                            OTL_UInt       class_count,
 
511
                            OTL_Validator  valid )
 
512
  {
 
513
    OTL_Bytes  p = table;
 
514
    OTL_UInt   count, count2;
 
515
 
 
516
    OTL_CHECK( 2 );
 
517
    count = OTL_NEXT_USHORT( p );
 
518
 
 
519
    OTL_CHECK( count*class_count*2 );
 
520
    for ( ; count > 0; count-- )
 
521
      for ( count2 = class_count; class_count > 0; class_count-- )
 
522
        otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid );
 
523
  }
 
524
 
 
525
 
 
526
  static void
 
527
  otl_gpos_lookup6_validate( OTL_Bytes  table,
 
528
                             OTL_Valid  valid )
 
529
  {
 
530
    OTL_Bytes  p = table;
 
531
    OTL_UInt   format;
 
532
 
 
533
    OTL_CHECK( 2 );
 
534
    format = OTL_NEXT_USHORT( p );
 
535
    switch (format)
 
536
    {
 
537
      case 1:
 
538
        {
 
539
          OTL_UInt  coverage1, coverage2, class_count, array1, array2;
 
540
 
 
541
          OTL_CHECK( 10 );
 
542
          coverage1   = OTL_NEXT_USHORT( p );
 
543
          coverage2   = OTL_NEXT_USHORT( p );
 
544
          class_count = OTL_NEXT_USHORT( p );
 
545
          array1      = OTL_NEXT_USHORT( p );
 
546
          array2      = OTL_NEXT_USHORT( p );
 
547
 
 
548
          otl_coverage_validate( table + coverage1, valid );
 
549
          otl_coverage_validate( table + coverage2, valid );
 
550
 
 
551
          otl_mark_array_validate( table + array1, valid );
 
552
          otl_mark2_array_validate( table + array2, valid );
 
553
        }
 
554
        break;
 
555
 
 
556
      default:
 
557
        OTL_INVALID_DATA;
 
558
    }
 
559
  }
 
560
 
 
561
 
 
562
 /************************************************************************/
 
563
 /************************************************************************/
 
564
 /*****                                                              *****/
 
565
 /*****                 GPOS LOOKUP TYPE 7                           *****/
 
566
 /*****                                                              *****/
 
567
 /************************************************************************/
 
568
 /************************************************************************/
 
569
 
 
570
  static void
 
571
  otl_pos_rule_validate( OTL_Bytes      table,
 
572
                         OTL_Validator  valid )
 
573
  {
 
574
    OTL_Bytes  p = table;
 
575
    OTL_UInt   glyph_count, pos_count;
 
576
 
 
577
    OTL_CHECK( 4 );
 
578
    glyph_count = OTL_NEXT_USHORT( p );
 
579
    pos_count   = OTL_NEXT_USHORT( p );
 
580
 
 
581
    if ( glyph_count == 0 )
 
582
      OTL_INVALID_DATA;
 
583
 
 
584
    OTL_CHECK( (glyph_count-1)*2 + pos_count*4 );
 
585
 
 
586
    /* XXX: check glyph indices and pos lookups */
 
587
  }
 
588
 
 
589
 
 
590
  static void
 
591
  otl_pos_rule_set_validate( OTL_Bytes      table,
 
592
                             OTL_Validator  valid )
 
593
  {
 
594
    OTL_Bytes  p = table;
 
595
    OTL_UInt   count;
 
596
 
 
597
    OTL_CHECK( 2 );
 
598
    count = OTL_NEXT_USHORT( p );
 
599
 
 
600
    OTL_CHECK( count*2 );
 
601
    for ( ; count > 0; count-- )
 
602
      otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid );
 
603
  }
 
604
 
 
605
 
 
606
 
 
607
  static void
 
608
  otl_pos_class_rule_validate( OTL_Bytes      table,
 
609
                               OTL_Validator  valid )
 
610
  {
 
611
    OTL_Bytes  p = table;
 
612
    OTL_UInt   glyph_count, pos_count;
 
613
 
 
614
    OTL_CHECK( 4 );
 
615
    glyph_count = OTL_NEXT_USHORT( p );
 
616
    pos_count   = OTL_NEXT_USHORT( p );
 
617
 
 
618
    if ( glyph_count == 0 )
 
619
      OTL_INVALID_DATA;
 
620
 
 
621
    OTL_CHECK( (glyph_count-1)*2 + pos_count*4 );
 
622
 
 
623
    /* XXX: check glyph indices and pos lookups */
 
624
  }
 
625
 
 
626
 
 
627
  static void
 
628
  otl_pos_class_set_validate( OTL_Bytes      table,
 
629
                              OTL_Validator  valid )
 
630
  {
 
631
    OTL_Bytes  p = table;
 
632
    OTL_UInt   count;
 
633
 
 
634
    OTL_CHECK( 2 );
 
635
    count = OTL_NEXT_USHORT( p );
 
636
 
 
637
    OTL_CHECK( count*2 );
 
638
    for ( ; count > 0; count-- )
 
639
      otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid );
 
640
  }
 
641
 
 
642
 
 
643
  static void
 
644
  otl_gpos_lookup7_validate( OTL_Bytes      table,
 
645
                             OTL_Validator  valid )
 
646
  {
 
647
    OTL_Bytes  p = table;
 
648
    OTL_UInt   format;
 
649
 
 
650
    OTL_CHECK( 2 );
 
651
    format = OTL_NEXT_USHORT( p );
 
652
    switch (format)
 
653
    {
 
654
      case 1:
 
655
        {
 
656
          OTL_UInt  coverage, count;
 
657
 
 
658
          OTL_CHECK( 4 );
 
659
          coverage = OTL_NEXT_USHORT( p );
 
660
          count    = OTL_NEXT_USHORT( p );
 
661
 
 
662
          otl_coverage_validate( table + coverage, valid );
 
663
 
 
664
          OTL_CHECK( count*2 );
 
665
          for ( ; count > 0; count-- )
 
666
            otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid );
 
667
        }
 
668
        break;
 
669
 
 
670
      case 2:
 
671
        {
 
672
          OTL_UInt  coverage, class_def, count;
 
673
 
 
674
          OTL_CHECK( 6 );
 
675
          coverage  = OTL_NEXT_USHORT( p );
 
676
          class_def = OTL_NEXT_USHORT( p );
 
677
          count     = OTL_NEXT_USHORT( p );
 
678
 
 
679
          otl_coverage_validate        ( table + coverage, valid );
 
680
          otl_class_definition_validate( table + class_def, valid );
 
681
 
 
682
          OTL_CHECK( count*2 );
 
683
          for ( ; count > 0; count-- )
 
684
            otl_
 
685
        }
 
686
        break;
 
687
 
 
688
      case 3:
 
689
        {
 
690
          OTL_UInt  glyph_count, pos_count;
 
691
 
 
692
          OTL_CHECK( 4 );
 
693
          glyph_count = OTL_NEXT_USHORT( p );
 
694
          pos_count   = OTL_NEXT_USHORT( p );
 
695
 
 
696
          OTL_CHECK( glyph_count*2 + pos_count*4 );
 
697
          for ( ; glyph_count > 0; glyph_count )
 
698
            otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
 
699
 
 
700
          /* XXX: check pos lookups */
 
701
        }
 
702
        break;
 
703
 
 
704
      default:
 
705
        OTL_INVALID_DATA;
 
706
    }
 
707
  }
 
708
 
 
709
 
 
710
 /************************************************************************/
 
711
 /************************************************************************/
 
712
 /*****                                                              *****/
 
713
 /*****                 GPOS LOOKUP TYPE 8                           *****/
 
714
 /*****                                                              *****/
 
715
 /************************************************************************/
 
716
 /************************************************************************/
 
717
 
 
718
  static void
 
719
  otl_chain_pos_rule_validate( OTL_Bytes      table,
 
720
                               OTL_Validator  valid )
 
721
  {
 
722
    OTL_Bytes  p = table;
 
723
    OTL_UInt   back_count, input_count, ahead_count, pos_count;
 
724
 
 
725
    OTL_CHECK( 2 );
 
726
    back_count = OTL_NEXT_USHORT( p );
 
727
 
 
728
    OTL_CHECK( back_count*2 + 2 );
 
729
    p += back_count*2;
 
730
 
 
731
    input_count = OTL_NEXT_USHORT( p );
 
732
    if ( input_count == 0 )
 
733
      OTL_INVALID_DATA;
 
734
 
 
735
    OTL_CHECK( input_count*2 );
 
736
    p += (input_count-1)*2;
 
737
 
 
738
    ahead_count = OTL_NEXT_USHORT( p );
 
739
    OTL_CHECK( ahead_count*2 + 2 );
 
740
    p += ahead_count*2;
 
741
 
 
742
    pos_count = OTL_NEXT_USHORT( p );
 
743
    OTL_CHECK( pos_count*4 );
 
744
  }
 
745
 
 
746
 
 
747
  static void
 
748
  otl_chain_pos_rule_set_validate( OTL_Bytes      table,
 
749
                                   OTL_Validator  valid )
 
750
  {
 
751
    OTL_Bytes  p = table;
 
752
    OTL_UInt   count;
 
753
 
 
754
    OTL_CHECK( 2 );
 
755
    count = OTL_NEXT_USHORT( p );
 
756
 
 
757
    OTL_CHECK( 2*count );
 
758
    for ( ; count > 0; count-- )
 
759
      otl_chain_pos_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
 
760
  }
 
761
 
 
762
 
 
763
 
 
764
  static void
 
765
  otl_chain_pos_class_rule_validate( OTL_Bytes      table,
 
766
                                     OTL_Validator  valid )
 
767
  {
 
768
    OTL_Bytes  p = table;
 
769
    OTL_UInt   back_count, input_count, ahead_count, pos_count;
 
770
 
 
771
    OTL_CHECK( 2 );
 
772
    back_count = OTL_NEXT_USHORT( p );
 
773
 
 
774
    OTL_CHECK( back_count*2 + 2 );
 
775
    p += back_count*2;
 
776
 
 
777
    input_count = OTL_NEXT_USHORT( p );
 
778
    if ( input_count == 0 )
 
779
      OTL_INVALID_DATA;
 
780
 
 
781
    OTL_CHECK( input_count*2 );
 
782
    p += (input_count-1)*2;
 
783
 
 
784
    ahead_count = OTL_NEXT_USHORT( p );
 
785
    OTL_CHECK( ahead_count*2 + 2 );
 
786
    p += ahead_count*2;
 
787
 
 
788
    pos_count = OTL_NEXT_USHORT( p );
 
789
    OTL_CHECK( pos_count*4 );
 
790
  }
 
791
 
 
792
 
 
793
  static void
 
794
  otl_chain_pos_class_set_validate( OTL_Bytes      table,
 
795
                                   OTL_Validator  valid )
 
796
  {
 
797
    OTL_Bytes  p = table;
 
798
    OTL_UInt   count;
 
799
 
 
800
    OTL_CHECK( 2 );
 
801
    count = OTL_NEXT_USHORT( p );
 
802
 
 
803
    OTL_CHECK( 2*count );
 
804
    for ( ; count > 0; count-- )
 
805
      otl_chain_pos_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
 
806
  }
 
807
 
 
808
 
 
809
  static void
 
810
  otl_gpos_lookup8_validate( OTL_Bytes      table,
 
811
                             OTL_Validator  valid )
 
812
  {
 
813
    OTL_Bytes  p = table;
 
814
    OTL_UInt   format;
 
815
 
 
816
    OTL_CHECK( 2 );
 
817
    format = OTL_NEXT_USHORT( p );
 
818
    switch (format)
 
819
    {
 
820
      case 1:
 
821
        {
 
822
          OTL_UInt  coverage, count;
 
823
 
 
824
          OTL_CHECK( 4 );
 
825
          coverage = OTL_NEXT_USHORT( p );
 
826
          count    = OTL_NEXT_USHORT( p );
 
827
 
 
828
          otl_coverage_validate( table + coverage, valid );
 
829
 
 
830
          OTL_CHECK( count*2 );
 
831
          for ( ; count > 0; count-- )
 
832
            otl_chain_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ),
 
833
                                             valid );
 
834
        }
 
835
        break;
 
836
 
 
837
      case 2:
 
838
        {
 
839
          OTL_UInt  coverage, back_class, input_class, ahead_class, count;
 
840
 
 
841
          OTL_CHECK( 10 );
 
842
          coverage    = OTL_NEXT_USHORT( p );
 
843
          back_class  = OTL_NEXT_USHORT( p );
 
844
          input_class = OTL_NEXT_USHORT( p );
 
845
          ahead_class = OTL_NEXT_USHORT( p );
 
846
          count       = OTL_NEXT_USHORT( p );
 
847
 
 
848
          otl_coverage_validate( table + coverage, valid );
 
849
 
 
850
          otl_class_definition_validate( table + back_class,  valid );
 
851
          otl_class_definition_validate( table + input_class, valid );
 
852
          otl_class_definition_validate( table + ahead_class, valid );
 
853
 
 
854
          OTL_CHECK( count*2 );
 
855
          for ( ; count > 0; count-- )
 
856
            otl_chain_pos_class_set_validate( table + OTL_NEXT_USHORT( p ),
 
857
                                              valid );
 
858
        }
 
859
        break;
 
860
 
 
861
      case 3:
 
862
        {
 
863
          OTL_UInt  back_count, input_count, ahead_count, pos_count, count;
 
864
 
 
865
          OTL_CHECK( 2 );
 
866
          back_count = OTL_NEXT_USHORT( p );
 
867
 
 
868
          OTL_CHECK( 2*back_count+2 );
 
869
          for ( count = back_count; count > 0; count-- )
 
870
            otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
 
871
 
 
872
          input_count = OTL_NEXT_USHORT( p );
 
873
 
 
874
          OTL_CHECK( 2*input_count+2 );
 
875
          for ( count = input_count; count > 0; count-- )
 
876
            otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
 
877
 
 
878
          ahead_count = OTL_NEXT_USHORT( p );
 
879
 
 
880
          OTL_CHECK( 2*ahead_count+2 );
 
881
          for ( count = ahead_count; count > 0; count-- )
 
882
            otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
 
883
 
 
884
          pos_count = OTL_NEXT_USHORT( p );
 
885
          OTL_CHECK( pos_count*4 );
 
886
        }
 
887
        break;
 
888
 
 
889
      default:
 
890
        OTL_INVALID_DATA;
 
891
    }
 
892
  }
 
893
 
 
894
 /************************************************************************/
 
895
 /************************************************************************/
 
896
 /*****                                                              *****/
 
897
 /*****                 GPOS LOOKUP TYPE 9                           *****/
 
898
 /*****                                                              *****/
 
899
 /************************************************************************/
 
900
 /************************************************************************/
 
901
 
 
902
  static void
 
903
  otl_gpos_lookup9_validate( OTL_Bytes  table,
 
904
                             OTL_Valid  valid )
 
905
  {
 
906
    OTL_Bytes  p = table;
 
907
    OTL_UInt   format;
 
908
 
 
909
    OTL_CHECK( 2 );
 
910
    format = OTL_NEXT_USHORT( p );
 
911
    switch (format)
 
912
    {
 
913
      case 1:
 
914
        {
 
915
          OTL_UInt          lookup_type, lookup_offset;
 
916
          OTL_ValidateFunc  validate;
 
917
 
 
918
          OTL_CHECK( 6 );
 
919
          lookup_type   = OTL_NEXT_USHORT( p );
 
920
          lookup_offset = OTL_NEXT_ULONG( p );
 
921
 
 
922
          if ( lookup_type == 0 || lookup_type >= 9 )
 
923
            OTL_INVALID_DATA;
 
924
 
 
925
          validate = otl_gpos_validate_funcs[ lookup_type-1 ];
 
926
          validate( table + lookup_offset, valid );
 
927
        }
 
928
        break;
 
929
 
 
930
      default:
 
931
        OTL_INVALID_DATA;
 
932
    }
 
933
  }
 
934
 
 
935
  static OTL_ValidateFunc  otl_gpos_validate_funcs[ 9 ] =
 
936
  {
 
937
    otl_gpos_lookup1_validate,
 
938
    otl_gpos_lookup2_validate,
 
939
    otl_gpos_lookup3_validate,
 
940
    otl_gpos_lookup4_validate,
 
941
    otl_gpos_lookup5_validate,
 
942
    otl_gpos_lookup6_validate,
 
943
    otl_gpos_lookup7_validate,
 
944
    otl_gpos_lookup8_validate,
 
945
    otl_gpos_lookup9_validate,
 
946
  };
 
947
 
 
948
 
 
949
 /************************************************************************/
 
950
 /************************************************************************/
 
951
 /*****                                                              *****/
 
952
 /*****                         GPOS TABLE                           *****/
 
953
 /*****                                                              *****/
 
954
 /************************************************************************/
 
955
 /************************************************************************/
 
956
 
 
957
 
 
958
  OTL_LOCALDEF( void )
 
959
  otl_gpos_validate( OTL_Bytes      table,
 
960
                     OTL_Validator  valid )
 
961
  {
 
962
    OTL_Bytes  p = table;
 
963
    OTL_UInt   scripts, features, lookups;
 
964
 
 
965
    OTL_CHECK( 10 );
 
966
 
 
967
    if ( OTL_NEXT_USHORT( p ) != 0x10000UL )
 
968
      OTL_INVALID_DATA;
 
969
 
 
970
    scripts  = OTL_NEXT_USHORT( p );
 
971
    features = OTL_NEXT_USHORT( p );
 
972
    lookups  = OTL_NEXT_USHORT( p );
 
973
 
 
974
    otl_script_list_validate ( table + scripts, valid );
 
975
    otl_feature_list_validate( table + features, valid );
 
976
 
 
977
    otl_lookup_list_validate( table + lookups, 9, otl_gpos_validate_funcs,
 
978
                              valid );
 
979
  }
 
980
  
 
 
b'\\ No newline at end of file'