Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  otvmath.c                                                              */
4
/*                                                                         */
5
/*    OpenType MATH table validation (body).                               */
6
/*                                                                         */
7
/*  Copyright 2007, 2008 by                                                */
8
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9
/*                                                                         */
10
/*  Written by George Williams.                                            */
11
/*                                                                         */
12
/*  This file is part of the FreeType project, and may only be used,       */
13
/*  modified, and distributed under the terms of the FreeType project      */
14
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
15
/*  this file you indicate that you have read the license and              */
16
/*  understand and accept it fully.                                        */
17
/*                                                                         */
18
/***************************************************************************/
19
 
20
 
21
#include "otvalid.h"
22
#include "otvcommn.h"
23
#include "otvgpos.h"
24
 
25
 
26
  /*************************************************************************/
27
  /*                                                                       */
28
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
29
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
30
  /* messages during execution.                                            */
31
  /*                                                                       */
32
#undef  FT_COMPONENT
33
#define FT_COMPONENT  trace_otvmath
34
 
35
 
36
 
37
  /*************************************************************************/
38
  /*************************************************************************/
39
  /*****                                                               *****/
40
  /*****                  MATH TYPOGRAPHIC CONSTANTS                   *****/
41
  /*****                                                               *****/
42
  /*************************************************************************/
43
  /*************************************************************************/
44
 
45
  static void
46
  otv_MathConstants_validate( FT_Bytes       table,
47
                              OTV_Validator  valid )
48
  {
49
    FT_Bytes  p = table;
50
    FT_UInt   i;
51
    FT_UInt   table_size;
52
 
53
    OTV_OPTIONAL_TABLE( DeviceTableOffset );
54
 
55
 
56
    OTV_NAME_ENTER( "MathConstants" );
57
 
58
    /* 56 constants, 51 have device tables */
59
    OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
60
    table_size = 2 * ( 56 + 51 );
61
 
62
    p += 4 * 2;                 /* First 4 constants have no device tables */
63
    for ( i = 0; i < 51; ++i )
64
    {
65
      p += 2;                                            /* skip the value */
66
      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
67
      OTV_SIZE_CHECK( DeviceTableOffset );
68
      if ( DeviceTableOffset )
69
        otv_Device_validate( table + DeviceTableOffset, valid );
70
    }
71
 
72
    OTV_EXIT;
73
  }
74
 
75
 
76
  /*************************************************************************/
77
  /*************************************************************************/
78
  /*****                                                               *****/
79
  /*****                   MATH ITALICS CORRECTION                     *****/
80
  /*****                 MATH TOP ACCENT ATTACHMENT                    *****/
81
  /*****                                                               *****/
82
  /*************************************************************************/
83
  /*************************************************************************/
84
 
85
  static void
86
  otv_MathItalicsCorrectionInfo_validate( FT_Bytes       table,
87
                                          OTV_Validator  valid,
88
                                          FT_Int         isItalic )
89
  {
90
    FT_Bytes  p = table;
91
    FT_UInt   i, cnt, table_size ;
92
 
93
    OTV_OPTIONAL_TABLE( Coverage );
94
    OTV_OPTIONAL_TABLE( DeviceTableOffset );
95
 
96
    FT_UNUSED( isItalic );  /* only used if tracing is active */
97
 
98
 
99
    OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
100
                             : "MathTopAccentAttachment" );
101
 
102
    OTV_LIMIT_CHECK( 4 );
103
 
104
    OTV_OPTIONAL_OFFSET( Coverage );
105
    cnt = FT_NEXT_USHORT( p );
106
 
107
    OTV_LIMIT_CHECK( 4 * cnt );
108
    table_size = 4 + 4 * cnt;
109
 
110
    OTV_SIZE_CHECK( Coverage );
111
    otv_Coverage_validate( table + Coverage, valid, cnt );
112
 
113
    for ( i = 0; i < cnt; ++i )
114
    {
115
      p += 2;                                            /* Skip the value */
116
      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
117
      OTV_SIZE_CHECK( DeviceTableOffset );
118
      if ( DeviceTableOffset )
119
        otv_Device_validate( table + DeviceTableOffset, valid );
120
    }
121
 
122
    OTV_EXIT;
123
  }
124
 
125
 
126
  /*************************************************************************/
127
  /*************************************************************************/
128
  /*****                                                               *****/
129
  /*****                           MATH KERNING                        *****/
130
  /*****                                                               *****/
131
  /*************************************************************************/
132
  /*************************************************************************/
133
 
134
  static void
135
  otv_MathKern_validate( FT_Bytes       table,
136
                         OTV_Validator  valid )
137
  {
138
    FT_Bytes  p = table;
139
    FT_UInt   i, cnt, table_size;
140
 
141
    OTV_OPTIONAL_TABLE( DeviceTableOffset );
142
 
143
 
144
    /* OTV_NAME_ENTER( "MathKern" );*/
145
 
146
    OTV_LIMIT_CHECK( 2 );
147
 
148
    cnt = FT_NEXT_USHORT( p );
149
 
150
    OTV_LIMIT_CHECK( 4 * cnt + 2 );
151
    table_size = 4 + 4 * cnt;
152
 
153
    /* Heights */
154
    for ( i = 0; i < cnt; ++i )
155
    {
156
      p += 2;                                            /* Skip the value */
157
      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
158
      OTV_SIZE_CHECK( DeviceTableOffset );
159
      if ( DeviceTableOffset )
160
        otv_Device_validate( table + DeviceTableOffset, valid );
161
    }
162
 
163
    /* One more Kerning value */
164
    for ( i = 0; i < cnt + 1; ++i )
165
    {
166
      p += 2;                                            /* Skip the value */
167
      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
168
      OTV_SIZE_CHECK( DeviceTableOffset );
169
      if ( DeviceTableOffset )
170
        otv_Device_validate( table + DeviceTableOffset, valid );
171
    }
172
 
173
    OTV_EXIT;
174
  }
175
 
176
 
177
  static void
178
  otv_MathKernInfo_validate( FT_Bytes       table,
179
                             OTV_Validator  valid )
180
  {
181
    FT_Bytes  p = table;
182
    FT_UInt   i, j, cnt, table_size;
183
 
184
    OTV_OPTIONAL_TABLE( Coverage );
185
    OTV_OPTIONAL_TABLE( MKRecordOffset );
186
 
187
 
188
    OTV_NAME_ENTER( "MathKernInfo" );
189
 
190
    OTV_LIMIT_CHECK( 4 );
191
 
192
    OTV_OPTIONAL_OFFSET( Coverage );
193
    cnt = FT_NEXT_USHORT( p );
194
 
195
    OTV_LIMIT_CHECK( 8 * cnt );
196
    table_size = 4 + 8 * cnt;
197
 
198
    OTV_SIZE_CHECK( Coverage );
199
    otv_Coverage_validate( table + Coverage, valid, cnt );
200
 
201
    for ( i = 0; i < cnt; ++i )
202
    {
203
      for ( j = 0; j < 4; ++j )
204
      {
205
        OTV_OPTIONAL_OFFSET( MKRecordOffset );
206
        OTV_SIZE_CHECK( MKRecordOffset );
207
        if ( MKRecordOffset )
208
          otv_MathKern_validate( table + MKRecordOffset, valid );
209
      }
210
    }
211
 
212
    OTV_EXIT;
213
  }
214
 
215
 
216
  /*************************************************************************/
217
  /*************************************************************************/
218
  /*****                                                               *****/
219
  /*****                         MATH GLYPH INFO                       *****/
220
  /*****                                                               *****/
221
  /*************************************************************************/
222
  /*************************************************************************/
223
 
224
  static void
225
  otv_MathGlyphInfo_validate( FT_Bytes       table,
226
                              OTV_Validator  valid )
227
  {
228
    FT_Bytes  p = table;
229
    FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
230
    FT_UInt   ExtendedShapeCoverage, MathKernInfo;
231
 
232
 
233
    OTV_NAME_ENTER( "MathGlyphInfo" );
234
 
235
    OTV_LIMIT_CHECK( 8 );
236
 
237
    MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
238
    MathTopAccentAttachment   = FT_NEXT_USHORT( p );
239
    ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
240
    MathKernInfo              = FT_NEXT_USHORT( p );
241
 
242
    if ( MathItalicsCorrectionInfo )
243
      otv_MathItalicsCorrectionInfo_validate(
244
        table + MathItalicsCorrectionInfo, valid, TRUE );
245
 
246
    /* Italic correction and Top Accent Attachment have the same format */
247
    if ( MathTopAccentAttachment )
248
      otv_MathItalicsCorrectionInfo_validate(
249
        table + MathTopAccentAttachment, valid, FALSE );
250
 
251
    if ( ExtendedShapeCoverage )
252
    {
253
      OTV_NAME_ENTER( "ExtendedShapeCoverage" );
254
      otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
255
      OTV_EXIT;
256
    }
257
 
258
    if ( MathKernInfo )
259
      otv_MathKernInfo_validate( table + MathKernInfo, valid );
260
 
261
    OTV_EXIT;
262
  }
263
 
264
 
265
  /*************************************************************************/
266
  /*************************************************************************/
267
  /*****                                                               *****/
268
  /*****                    MATH GLYPH CONSTRUCTION                    *****/
269
  /*****                                                               *****/
270
  /*************************************************************************/
271
  /*************************************************************************/
272
 
273
  static void
274
  otv_GlyphAssembly_validate( FT_Bytes       table,
275
                              OTV_Validator  valid )
276
  {
277
    FT_Bytes  p = table;
278
    FT_UInt   pcnt, table_size;
279
    FT_UInt   i;
280
 
281
    OTV_OPTIONAL_TABLE( DeviceTableOffset );
282
 
283
 
284
    /* OTV_NAME_ENTER( "GlyphAssembly" ); */
285
 
286
    OTV_LIMIT_CHECK( 6 );
287
 
288
    p += 2;                           /* Skip the Italics Correction value */
289
    OTV_OPTIONAL_OFFSET( DeviceTableOffset );
290
    pcnt = FT_NEXT_USHORT( p );
291
 
292
    OTV_LIMIT_CHECK( 8 * pcnt );
293
    table_size = 6 + 8 * pcnt;
294
 
295
    OTV_SIZE_CHECK( DeviceTableOffset );
296
    if ( DeviceTableOffset )
297
      otv_Device_validate( table + DeviceTableOffset, valid );
298
 
299
    for ( i = 0; i < pcnt; ++i )
300
    {
301
      FT_UInt  gid;
302
 
303
 
304
      gid = FT_NEXT_USHORT( p );
305
      if ( gid >= valid->glyph_count )
306
        FT_INVALID_GLYPH_ID;
307
      p += 2*4;             /* skip the Start, End, Full, and Flags fields */
308
    }
309
 
310
    /* OTV_EXIT; */
311
  }
312
 
313
 
314
  static void
315
  otv_MathGlyphConstruction_validate( FT_Bytes       table,
316
                                      OTV_Validator  valid )
317
  {
318
    FT_Bytes  p = table;
319
    FT_UInt   vcnt, table_size;
320
    FT_UInt   i;
321
 
322
    OTV_OPTIONAL_TABLE( GlyphAssembly );
323
 
324
 
325
    /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
326
 
327
    OTV_LIMIT_CHECK( 4 );
328
 
329
    OTV_OPTIONAL_OFFSET( GlyphAssembly );
330
    vcnt = FT_NEXT_USHORT( p );
331
 
332
    OTV_LIMIT_CHECK( 4 * vcnt );
333
    table_size = 4 + 4 * vcnt;
334
 
335
    for ( i = 0; i < vcnt; ++i )
336
    {
337
      FT_UInt  gid;
338
 
339
 
340
      gid = FT_NEXT_USHORT( p );
341
      if ( gid >= valid->glyph_count )
342
        FT_INVALID_GLYPH_ID;
343
      p += 2;                          /* skip the size */
344
    }
345
 
346
    OTV_SIZE_CHECK( GlyphAssembly );
347
    if ( GlyphAssembly )
348
      otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
349
 
350
    /* OTV_EXIT; */
351
  }
352
 
353
 
354
  static void
355
  otv_MathVariants_validate( FT_Bytes       table,
356
                             OTV_Validator  valid )
357
  {
358
    FT_Bytes  p = table;
359
    FT_UInt   vcnt, hcnt, i, table_size;
360
 
361
    OTV_OPTIONAL_TABLE( VCoverage );
362
    OTV_OPTIONAL_TABLE( HCoverage );
363
    OTV_OPTIONAL_TABLE( Offset );
364
 
365
 
366
    OTV_NAME_ENTER( "MathVariants" );
367
 
368
    OTV_LIMIT_CHECK( 10 );
369
 
370
    p += 2;                       /* Skip the MinConnectorOverlap constant */
371
    OTV_OPTIONAL_OFFSET( VCoverage );
372
    OTV_OPTIONAL_OFFSET( HCoverage );
373
    vcnt = FT_NEXT_USHORT( p );
374
    hcnt = FT_NEXT_USHORT( p );
375
 
376
    OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
377
    table_size = 10 + 2 * vcnt + 2 * hcnt;
378
 
379
    OTV_SIZE_CHECK( VCoverage );
380
    if ( VCoverage )
381
      otv_Coverage_validate( table + VCoverage, valid, vcnt );
382
 
383
    OTV_SIZE_CHECK( HCoverage );
384
    if ( HCoverage )
385
      otv_Coverage_validate( table + HCoverage, valid, hcnt );
386
 
387
    for ( i = 0; i < vcnt; ++i )
388
    {
389
      OTV_OPTIONAL_OFFSET( Offset );
390
      OTV_SIZE_CHECK( Offset );
391
      otv_MathGlyphConstruction_validate( table + Offset, valid );
392
    }
393
 
394
    for ( i = 0; i < hcnt; ++i )
395
    {
396
      OTV_OPTIONAL_OFFSET( Offset );
397
      OTV_SIZE_CHECK( Offset );
398
      otv_MathGlyphConstruction_validate( table + Offset, valid );
399
    }
400
 
401
    OTV_EXIT;
402
  }
403
 
404
 
405
  /*************************************************************************/
406
  /*************************************************************************/
407
  /*****                                                               *****/
408
  /*****                          MATH TABLE                           *****/
409
  /*****                                                               *****/
410
  /*************************************************************************/
411
  /*************************************************************************/
412
 
413
  /* sets valid->glyph_count */
414
 
415
  FT_LOCAL_DEF( void )
416
  otv_MATH_validate( FT_Bytes      table,
417
                     FT_UInt       glyph_count,
418
                     FT_Validator  ftvalid )
419
  {
420
    OTV_ValidatorRec  validrec;
421
    OTV_Validator     valid = &validrec;
422
    FT_Bytes          p     = table;
423
    FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
424
 
425
 
426
    valid->root = ftvalid;
427
 
428
    FT_TRACE3(( "validating MATH table\n" ));
429
    OTV_INIT;
430
 
431
    OTV_LIMIT_CHECK( 10 );
432
 
433
    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
434
      FT_INVALID_FORMAT;
435
 
436
    MathConstants = FT_NEXT_USHORT( p );
437
    MathGlyphInfo = FT_NEXT_USHORT( p );
438
    MathVariants  = FT_NEXT_USHORT( p );
439
 
440
    valid->glyph_count = glyph_count;
441
 
442
    otv_MathConstants_validate( table + MathConstants,
443
                                valid );
444
    otv_MathGlyphInfo_validate( table + MathGlyphInfo,
445
                                valid );
446
    otv_MathVariants_validate ( table + MathVariants,
447
                                valid );
448
 
449
    FT_TRACE4(( "\n" ));
450
  }
451
 
452
 
453
/* END */