* src/truetype/ttgload.c (TT_Load_Glyph): finally fixing the last
bug that prevented FreeType 2.x and FreeType 1.x to produce bit-by-bit identical monochrome glyph bitmaps with native TrueType hinting. The culprit was a single-bit flag that wasn't set correctly by the TrueType glyph loader !! * src/otlayout/otlayout.h, src/otlayout/otlbase.c, src/otlayout/otlbase.h, src/otlayout/otlconf.h, src/otlayout/otlgdef.c, src/otlayout/otlgdef.h, src/otlayout/otlgpos.c, src/otlayout/otlgpos.h, src/otlayout/otlgsub.c, src/otlayout/otlgsub.h, src/otlayout/otljstf.c, src/otlayout/otljstf.h, src/otlayout/otltable.c, src/otlayout/otltable.h, src/otlayout/otltags.h: adding OpenType Layout source files. Module is still incomplete
This commit is contained in:
parent
948ee807e1
commit
8cd8907311
27
ChangeLog
27
ChangeLog
@ -1,3 +1,30 @@
|
||||
2002-05-04 David Turner <david@freetype.org>
|
||||
|
||||
* src/truetype/ttgload.c (TT_Load_Glyph): finally fixing the last
|
||||
bug that prevented FreeType 2.x and FreeType 1.x to produce
|
||||
bit-by-bit identical monochrome glyph bitmaps with native TrueType
|
||||
hinting. The culprit was a single-bit flag that wasn't set
|
||||
correctly by the TrueType glyph loader !!
|
||||
|
||||
* src/otlayout/otlayout.h,
|
||||
src/otlayout/otlbase.c,
|
||||
src/otlayout/otlbase.h,
|
||||
src/otlayout/otlconf.h,
|
||||
src/otlayout/otlgdef.c,
|
||||
src/otlayout/otlgdef.h,
|
||||
src/otlayout/otlgpos.c,
|
||||
src/otlayout/otlgpos.h,
|
||||
src/otlayout/otlgsub.c,
|
||||
src/otlayout/otlgsub.h,
|
||||
src/otlayout/otljstf.c,
|
||||
src/otlayout/otljstf.h,
|
||||
src/otlayout/otltable.c,
|
||||
src/otlayout/otltable.h,
|
||||
src/otlayout/otltags.h:
|
||||
|
||||
adding OpenType Layout source files. Module is still incomplete
|
||||
|
||||
|
||||
2002-05-02 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/sfnt/ttcmap0.c (tt_cmap4_char_index): Fix serious typo
|
||||
|
168
src/otlayout/otlayout.h
Normal file
168
src/otlayout/otlayout.h
Normal file
@ -0,0 +1,168 @@
|
||||
#ifndef __OT_LAYOUT_H__
|
||||
#define __OT_LAYOUT_H__
|
||||
|
||||
|
||||
#include "otlconf.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** BASE DATA TYPES *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
typedef unsigned char OTL_Byte;
|
||||
typedef const OTL_Byte* OTL_Bytes;
|
||||
|
||||
typedef int OTL_Error;
|
||||
|
||||
typedef void* OTL_Pointer;
|
||||
|
||||
typedef int OTL_Int;
|
||||
typedef unsigned int OTL_UInt;
|
||||
|
||||
typedef short OTL_Int16;
|
||||
typedef unsigned short OTL_UInt16;
|
||||
|
||||
#if OTL_SIZEOF_INT == 4
|
||||
|
||||
typedef int OTL_Int32;
|
||||
typedef unsigned int OTL_UInt32;
|
||||
|
||||
#elif OTL_SIZEOF_LONG == 4
|
||||
|
||||
typedef long OTL_Int32;
|
||||
typedef unsigned long OTL_UInt32;
|
||||
|
||||
#else
|
||||
# error "no 32-bits type found"
|
||||
#endif
|
||||
|
||||
typedef OTL_UInt32 OTL_Tag;
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** ERROR CODES *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OTL_Err_Ok = 0,
|
||||
OTL_Err_InvalidArgument,
|
||||
OTL_Err_InvalidFormat,
|
||||
OTL_Err_InvalidOffset,
|
||||
|
||||
} OTL_Error;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** ENUMERATIONS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#define OTL_MAKE_TAG(c1,c2,c3,c4) \
|
||||
( ( (OTL_UInt32)(c1) << 24 ) | \
|
||||
(OTL_UInt32)(c2) << 16 ) | \
|
||||
(OTL_UInt32)(c3) << 8 ) | \
|
||||
(OTL_UInt32)(c4) )
|
||||
|
||||
typedef enum OTL_ScriptTag_
|
||||
{
|
||||
OTL_SCRIPT_NONE = 0,
|
||||
|
||||
#define OTL_SCRIPT_TAG(c1,c2,c3,c4,s,n) OTL_SCRIPT_TAG_ ## n = OTL_MAKE_TAG(c1,c2,c3,c4),
|
||||
#include "otltags.h"
|
||||
|
||||
OTL_SCRIPT_MAX
|
||||
|
||||
} OTL_ScriptTag;
|
||||
|
||||
|
||||
typedef enum OTL_LangTag_
|
||||
{
|
||||
OTL_LANG_DEFAULT = 0,
|
||||
|
||||
#define OTL_LANG_TAG(c1,c2,c3,c4,s,n) OTL_LANG_TAG_ ## n = OTL_MAKE_TAG(c1,c2,c3,c4),
|
||||
#include "otltags.h"
|
||||
|
||||
OTL_LANG_MAX
|
||||
|
||||
} OTL_LangTag;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** MEMORY READS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#define OTL_PEEK_USHORT(p) ( ((OTL_UInt)((p)[0]) << 8) | \
|
||||
((OTL_UInt)((p)[1]) ) )
|
||||
|
||||
#define OTL_PEEK_ULONG(p) ( ((OTL_UInt32)((p)[0]) << 24) | \
|
||||
((OTL_UInt32)((p)[1]) << 16) | \
|
||||
((OTL_UInt32)((p)[2]) << 8) | \
|
||||
((OTL_UInt32)((p)[3]) ) )
|
||||
|
||||
#define OTL_PEEK_SHORT(p) ((OTL_Int16)OTL_PEEK_USHORT(p))
|
||||
|
||||
#define OTL_PEEK_LONG(p) ((OTL_Int32)OTL_PEEK_ULONG(p))
|
||||
|
||||
#define OTL_NEXT_USHORT(p) ( (p) += 2, OTL_PEEK_USHORT((p)-2) )
|
||||
#define OTL_NEXT_ULONG(p) ( (p) += 4, OTL_PEEK_ULONG((p)-4) )
|
||||
|
||||
#define OTL_NEXT_SHORT(p) ((OTL_Int16)OTL_NEXT_USHORT(p))
|
||||
#define OTL_NEXT_LONG(p) ((OTL_Int32)OTL_NEXT_ULONG(p))
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** VALIDATION *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
typedef struct OTL_ValidatorRec_* OTL_Validator;
|
||||
|
||||
typedef struct OTL_ValidatorRec_
|
||||
{
|
||||
OTL_Bytes limit;
|
||||
OTL_Bytes base;
|
||||
OTL_Error error;
|
||||
OTL_jmp_buf jump_buffer;
|
||||
|
||||
} OTL_ValidatorRec;
|
||||
|
||||
typedef void (*OTL_ValidateFunc)( OTL_Bytes table,
|
||||
OTL_Valid valid );
|
||||
|
||||
OTL_API( void )
|
||||
otl_validator_error( OTL_Validator validator,
|
||||
OTL_Error error );
|
||||
|
||||
#define OTL_INVALID(e) otl_validator_error( valid, e )
|
||||
|
||||
#define OTL_INVALID_TOO_SHORT OTL_INVALID( OTL_Err_InvalidOffset );
|
||||
#define OTL_INVALID_DATA OTL_INVALID( OTL_Err_InvalidFormat );
|
||||
|
||||
#define OTL_CHECK(_count) OTL_BEGIN_STMNT \
|
||||
if ( p + (_count) > valid->limit ) \
|
||||
OTL_INVALID_TOO_SHORT; \
|
||||
OTL_END_STMNT
|
||||
|
||||
/* */
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OPENTYPE_LAYOUT_H__ */
|
181
src/otlayout/otlbase.c
Normal file
181
src/otlayout/otlbase.c
Normal file
@ -0,0 +1,181 @@
|
||||
#include "otlbase.h"
|
||||
#include "otlcommn.h"
|
||||
|
||||
static void
|
||||
otl_base_coord_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
p += 2;
|
||||
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
OTL_CHECK( 4 );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
OTL_CHECK( 2 );
|
||||
otl_device_table_validate( table + OTL_PEEK_USHORT( p ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_base_tag_list_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK(2);
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( count*4 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
otl_base_values_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
|
||||
p += 2; /* skip default index */
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
otl_base_coord_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_base_minmax_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt min_coord, max_coord, count;
|
||||
|
||||
OTL_CHECK(6);
|
||||
min_coord = OTL_NEXT_USHORT( p );
|
||||
max_coord = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( min_coord )
|
||||
otl_base_coord_validate( table + min_coord, valid );
|
||||
|
||||
if ( max_coord )
|
||||
otl_base_coord_validate( table + max_coord, valid );
|
||||
|
||||
OTL_CHECK( count*8 );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
p += 4; /* ignore tag */
|
||||
min_coord = OTL_NEXT_USHORT( p );
|
||||
max_coord = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( min_coord )
|
||||
otl_base_coord_validate( table + min_coord, valid );
|
||||
|
||||
if ( max_coord )
|
||||
otl_base_coord_validate( table + max_coord, valid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_base_script_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt values, default_minmax;
|
||||
|
||||
OTL_CHECK(6);
|
||||
|
||||
values = OTL_NEXT_USHORT( p );
|
||||
default_minmax = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( values )
|
||||
otl_base_values_validate( table + values, valid );
|
||||
|
||||
if ( default_minmax )
|
||||
otl_base_minmax_validate( table + default_minmax, valid );
|
||||
|
||||
OTL_CHECK( count*6 );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
p += 4; /* ignore tag */
|
||||
otl_base_minmax_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_base_script_list_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK(2);
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK(count*6);
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
p += 4; /* ignore script tag */
|
||||
otl_base_script_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
otl_axis_table_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt tags;
|
||||
|
||||
OTL_CHECK(4);
|
||||
|
||||
tags = OTL_NEXT_USHORT( p );
|
||||
if ( tags )
|
||||
otl_base_tag_list_validate ( table + tags );
|
||||
|
||||
otl_base_script_list_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
|
||||
|
||||
OTL_LOCALDEF( void )
|
||||
otl_base_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
|
||||
OTL_CHECK(6);
|
||||
|
||||
if ( OTL_NEXT_ULONG( p ) != 0x10000UL )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
otl_axis_table_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
otl_axis_table_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
14
src/otlayout/otlbase.h
Normal file
14
src/otlayout/otlbase.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __OTL_BASE_H__
|
||||
#define __OTL_BASE_H__
|
||||
|
||||
#include "otlayout.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_base_validate( OTL_Bytes table,
|
||||
OTL_Validator valid );
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OTL_BASE_H__ */
|
@ -38,12 +38,12 @@
|
||||
if ( table + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
format = OTL_NEXT_UShort( p );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt count = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count = OTL_NEXT_USHORT( p );
|
||||
|
||||
|
||||
if ( p + count * 2 >= valid->limit )
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt n, num_ranges = OTL_NEXT_UShort( p );
|
||||
OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt start, end, start_cover, total = 0, last = 0;
|
||||
|
||||
|
||||
@ -64,9 +64,9 @@
|
||||
|
||||
for ( n = 0; n < num_ranges; n++ )
|
||||
{
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
start_cover = OTL_NEXT_UShort( p );
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
start_cover = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( start > end || start_cover != total )
|
||||
OTL_INVALID_DATA;
|
||||
@ -90,8 +90,8 @@
|
||||
otl_coverage_get_count( OTL_Bytes table )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count = OTL_NEXT_UShort( p );
|
||||
OTL_UInt format = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt count = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt result = 0;
|
||||
|
||||
|
||||
@ -107,8 +107,8 @@
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
p += 2; /* skip start_index */
|
||||
|
||||
result += end - start + 1;
|
||||
@ -129,8 +129,8 @@
|
||||
OTL_UInt glyph_index )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count = OTL_NEXT_UShort( p );
|
||||
OTL_UInt format = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt count = OTL_NEXT_USHORT( p );
|
||||
|
||||
|
||||
switch ( format )
|
||||
@ -145,7 +145,7 @@
|
||||
{
|
||||
mid = ( min + max ) >> 1;
|
||||
p = table + 2 * mid;
|
||||
gindex = OTL_PEEK_UShort( p );
|
||||
gindex = OTL_PEEK_USHORT( p );
|
||||
|
||||
if ( glyph_index == gindex )
|
||||
return (OTL_Int)mid;
|
||||
@ -169,15 +169,15 @@
|
||||
{
|
||||
mid = ( min + max ) >> 1;
|
||||
p = table + 6 * mid;
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( glyph_index < start )
|
||||
max = mid;
|
||||
else if ( glyph_index > end )
|
||||
min = mid + 1;
|
||||
else
|
||||
return (OTL_Int)( glyph_index + OTL_NEXT_UShort( p ) - start );
|
||||
return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -209,18 +209,18 @@
|
||||
if ( p + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
format = OTL_NEXT_UShort( p );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt count, start = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count, start = OTL_NEXT_USHORT( p );
|
||||
|
||||
|
||||
if ( p + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
count = OTL_NEXT_UShort( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + count * 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
@ -231,7 +231,7 @@
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt n, num_ranges = OTL_NEXT_UShort( p );
|
||||
OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt start, end, value, last = 0;
|
||||
|
||||
|
||||
@ -240,9 +240,9 @@
|
||||
|
||||
for ( n = 0; n < num_ranges; n++ )
|
||||
{
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
value = OTL_NEXT_UShort( p ); /* ignored */
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
value = OTL_NEXT_USHORT( p ); /* ignored */
|
||||
|
||||
if ( start > end || ( n > 0 && start <= last ) )
|
||||
OTL_INVALID_DATA;
|
||||
@ -263,29 +263,29 @@
|
||||
OTL_UInt glyph_index )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format = OTL_NEXT_UShort( p );
|
||||
OTL_UInt format = OTL_NEXT_USHORT( p );
|
||||
|
||||
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt start = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count = OTL_NEXT_UShort( p );
|
||||
OTL_UInt start = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt count = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt idx = (OTL_UInt)( glyph_index - start );
|
||||
|
||||
|
||||
if ( idx < count )
|
||||
{
|
||||
p += 2 * idx;
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt count = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt min = 0, max = count, mid, gindex;
|
||||
|
||||
|
||||
@ -294,15 +294,15 @@
|
||||
{
|
||||
mid = ( min + max ) >> 1;
|
||||
p = table + 6 * mid;
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( glyph_index < start )
|
||||
max = mid;
|
||||
else if ( glyph_index > end )
|
||||
min = mid + 1;
|
||||
else
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -334,9 +334,9 @@
|
||||
if ( p + 8 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
format = OTL_NEXT_UShort( p );
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( format < 1 || format > 3 || end < start )
|
||||
OTL_INVALID_DATA;
|
||||
@ -354,7 +354,7 @@
|
||||
OTL_Bytes p = table;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -364,7 +364,7 @@
|
||||
OTL_Bytes p = table + 2;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -377,9 +377,9 @@
|
||||
OTL_UInt start, end, format, idx, value;
|
||||
|
||||
|
||||
start = OTL_NEXT_UShort( p );
|
||||
end = OTL_NEXT_UShort( p );
|
||||
format = OTL_NEXT_UShort( p );
|
||||
start = OTL_NEXT_USHORT( p );
|
||||
end = OTL_NEXT_USHORT( p );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( size >= start && size <= end )
|
||||
{
|
||||
@ -391,7 +391,7 @@
|
||||
case 1:
|
||||
idx = (OTL_UInt)( ( size - start ) * 2 );
|
||||
p += idx / 16;
|
||||
value = OTL_PEEK_UShort( p );
|
||||
value = OTL_PEEK_USHORT( p );
|
||||
shift = idx & 15;
|
||||
result = (OTL_Short)( value << shift ) >> ( 14 - shift );
|
||||
|
||||
@ -400,7 +400,7 @@
|
||||
case 2:
|
||||
idx = (OTL_UInt)( ( size - start ) * 4 );
|
||||
p += idx / 16;
|
||||
value = OTL_PEEK_UShort( p );
|
||||
value = OTL_PEEK_USHORT( p );
|
||||
shift = idx & 15;
|
||||
result = (OTL_Short)( value << shift ) >> ( 12 - shift );
|
||||
|
||||
@ -409,7 +409,7 @@
|
||||
case 3:
|
||||
idx = (OTL_UInt)( ( size - start ) * 8 );
|
||||
p += idx / 16;
|
||||
value = OTL_PEEK_UShort( p );
|
||||
value = OTL_PEEK_USHORT( p );
|
||||
shift = idx & 15;
|
||||
result = (OTL_Short)( value << shift ) >> ( 8 - shift );
|
||||
|
||||
@ -444,14 +444,14 @@
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
p += 4;
|
||||
num_tables = OTL_NEXT_UShort( p );
|
||||
num_tables = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + num_tables * 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
for ( ; num_tables > 0; num_tables-- )
|
||||
{
|
||||
offset = OTL_NEXT_UShort( p );
|
||||
offset = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( table + offset >= valid->limit )
|
||||
OTL_INVALID_OFFSET;
|
||||
@ -467,7 +467,7 @@
|
||||
OTL_Bytes p = table + 4;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -480,11 +480,11 @@
|
||||
|
||||
|
||||
p = table + 4;
|
||||
count = OTL_NEXT_UShort( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
if ( idx < count )
|
||||
{
|
||||
p += idx * 2;
|
||||
result = table + OTL_PEEK_UShort( p );
|
||||
result = table + OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -510,14 +510,14 @@
|
||||
if ( p + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
num_lookups = OTL_NEXT_UShort( p );
|
||||
num_lookups = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + num_lookups * 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
for ( ; num_lookups > 0; num_lookups-- )
|
||||
{
|
||||
offset = OTL_NEXT_UShort( p );
|
||||
offset = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_lookup_validate( table + offset, valid );
|
||||
}
|
||||
@ -530,7 +530,7 @@
|
||||
OTL_Bytes p = table;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -543,11 +543,11 @@
|
||||
|
||||
|
||||
p = table;
|
||||
count = OTL_NEXT_UShort( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
if ( idx < count )
|
||||
{
|
||||
p += idx * 2;
|
||||
result = table + OTL_PEEK_UShort( p );
|
||||
result = table + OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -576,7 +576,7 @@
|
||||
OTL_Pointer func_data )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count = OTL_NEXT_UShort( p );
|
||||
OTL_UInt count = OTL_NEXT_USHORT( p );
|
||||
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
@ -603,8 +603,8 @@
|
||||
if ( p + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
feat_params = OTL_NEXT_UShort( p ); /* ignored */
|
||||
num_lookups = OTL_NEXT_UShort( p );
|
||||
feat_params = OTL_NEXT_USHORT( p ); /* ignored */
|
||||
num_lookups = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + num_lookups * 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
@ -619,7 +619,7 @@
|
||||
OTL_Bytes p = table + 4;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -634,13 +634,13 @@
|
||||
|
||||
|
||||
p = table + 4;
|
||||
num_features = OTL_NEXT_UShort( p );
|
||||
num_features = OTL_NEXT_USHORT( p );
|
||||
|
||||
p += start * 2;
|
||||
|
||||
for ( ; count > 0 && start < num_features; count--, start++ )
|
||||
{
|
||||
lookups[0] = OTL_NEXT_UShort(p);
|
||||
lookups[0] = OTL_NEXT_USHORT(p);
|
||||
lookups++;
|
||||
result++;
|
||||
}
|
||||
@ -668,7 +668,7 @@
|
||||
if ( table + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
num_features = OTL_NEXT_UShort( p );
|
||||
num_features = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + num_features * 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
@ -676,7 +676,7 @@
|
||||
for ( ; num_features > 0; num_features-- )
|
||||
{
|
||||
p += 4; /* skip tag */
|
||||
offset = OTL_NEXT_UShort( p );
|
||||
offset = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_feature_table_validate( table + offset, valid );
|
||||
}
|
||||
@ -689,7 +689,7 @@
|
||||
OTL_Bytes p = table;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -702,12 +702,12 @@
|
||||
|
||||
|
||||
p = table;
|
||||
count = OTL_NEXT_UShort( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( idx < count )
|
||||
{
|
||||
p += idx * 2;
|
||||
result = table + OTL_PEEK_UShort( p );
|
||||
result = table + OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -724,10 +724,10 @@
|
||||
|
||||
|
||||
p = table;
|
||||
count = OTL_NEXT_UShort( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
func( table + OTL_NEXT_UShort( p ), func_data );
|
||||
func( table + OTL_NEXT_USHORT( p ), func_data );
|
||||
}
|
||||
|
||||
|
||||
@ -753,9 +753,9 @@
|
||||
if ( table + 6 >= valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
lookup_order = OTL_NEXT_UShort( p );
|
||||
req_feature = OTL_NEXT_UShort( p );
|
||||
num_features = OTL_NEXT_UShort( p );
|
||||
lookup_order = OTL_NEXT_USHORT( p );
|
||||
req_feature = OTL_NEXT_USHORT( p );
|
||||
num_features = OTL_NEXT_USHORT( p );
|
||||
|
||||
/* XXX: check req_feature if not 0xFFFFU */
|
||||
|
||||
@ -769,10 +769,19 @@
|
||||
OTL_LOCALDEF( OTL_UInt )
|
||||
otl_lang_get_count( OTL_Bytes table )
|
||||
{
|
||||
OTL_Bytes p = table + 4;
|
||||
OTL_Bytes p = table + 4;
|
||||
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
OTL_LOCALDEF( OTL_UInt )
|
||||
otl_lang_get_req_feature( OTL_Bytes table )
|
||||
{
|
||||
OTL_Bytes p = table + 2;
|
||||
|
||||
|
||||
return OTL_PEEK_USHORT( p );
|
||||
}
|
||||
|
||||
|
||||
@ -783,7 +792,7 @@
|
||||
OTL_UInt *features )
|
||||
{
|
||||
OTL_Bytes p = table + 4;
|
||||
OTL_UInt num_features = OTL_NEXT_UShort( p );
|
||||
OTL_UInt num_features = OTL_NEXT_USHORT( p );
|
||||
OTL_UInt result = 0;
|
||||
|
||||
|
||||
@ -791,7 +800,7 @@
|
||||
|
||||
for ( ; count > 0 && start < num_features; start++, count-- )
|
||||
{
|
||||
features[0] = OTL_NEXT_UShort( p );
|
||||
features[0] = OTL_NEXT_USHORT( p );
|
||||
features++;
|
||||
result++;
|
||||
}
|
||||
@ -800,14 +809,6 @@
|
||||
}
|
||||
|
||||
|
||||
OTL_LOCALDEF( OTL_UInt )
|
||||
otl_lang_get_req_feature( OTL_Bytes table )
|
||||
{
|
||||
OTL_Bytes p = table + 2;
|
||||
|
||||
|
||||
return OTL_PEEK_UShort( p );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -820,8 +821,8 @@
|
||||
|
||||
|
||||
OTL_LOCALDEF( void )
|
||||
otl_script_table_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
otl_script_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_UInt default_lang;
|
||||
OTL_Bytes p = table;
|
||||
@ -830,8 +831,8 @@
|
||||
if ( table + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
default_lang = OTL_NEXT_UShort( p );
|
||||
num_langs = OTL_NEXT_UShort( p );
|
||||
default_lang = OTL_NEXT_USHORT( p );
|
||||
num_langs = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( default_lang != 0 )
|
||||
{
|
||||
@ -848,7 +849,7 @@
|
||||
|
||||
|
||||
p += 4; /* skip tag */
|
||||
offset = OTL_NEXT_UShort( p );
|
||||
offset = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_lang_validate( table + offset, valid );
|
||||
}
|
||||
@ -866,7 +867,7 @@
|
||||
if ( list + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
num_scripts = OTL_NEXT_UShort( p );
|
||||
num_scripts = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + num_scripts * 6 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
@ -877,11 +878,63 @@
|
||||
|
||||
|
||||
p += 4; /* skip tag */
|
||||
offset = OTL_NEXT_UShort( p );
|
||||
offset = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_script_table_validate( list + offset, valid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** LOOKUP LISTS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static void
|
||||
otl_lookup_table_validate( OTL_Bytes table,
|
||||
OTL_UInt type_count,
|
||||
OTL_ValidateFunc* type_funcs,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt lookup_type, lookup_flag, count;
|
||||
OTL_ValidateFunc validate;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
lookup_type = OTL_NEXT_USHORT( p );
|
||||
lookup_flag = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( lookup_type == 0 || lookup_type >= type_count )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
validate = type_funcs[ lookup_type - 1 ];
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
OTL_LOCALDEF( void )
|
||||
otl_lookup_list_validate( OTL_Bytes table,
|
||||
OTL_UInt type_count,
|
||||
OTL_ValidateFunc* type_funcs,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_lookup_table_validate( table + OTL_NEXT_USHORT( p ),
|
||||
type_count, type_funcs, valid );
|
||||
}
|
||||
|
||||
/* END */
|
||||
|
@ -208,6 +208,65 @@ OTL_BEGIN_HEADER
|
||||
OTL_ForeachFunc func,
|
||||
OTL_Pointer func_data );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** LANGUAGE SYSTEM *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_lang_validate( OTL_Bytes table,
|
||||
OTL_Validator valid );
|
||||
|
||||
|
||||
OTL_LOCAL( OTL_UInt )
|
||||
otl_lang_get_req_feature( OTL_Bytes table );
|
||||
|
||||
|
||||
OTL_LOCAL( OTL_UInt )
|
||||
otl_lang_get_count( OTL_Bytes table );
|
||||
|
||||
|
||||
OTL_LOCAL( OTL_UInt )
|
||||
otl_lang_get_features( OTL_Bytes table,
|
||||
OTL_UInt start,
|
||||
OTL_UInt count,
|
||||
OTL_UInt *features );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** SCRIPTS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_script_list_validate( OTL_Bytes list,
|
||||
OTL_Validator valid );
|
||||
|
||||
OTL_LOCAL( OTL_Bytes )
|
||||
otl_script_list_get_script( OTL_Bytes table );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
/***** LOOKUP LISTS *****/
|
||||
/***** *****/
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_lookup_list_validate( OTL_Bytes list,
|
||||
OTL_UInt type_count,
|
||||
OTL_ValidateFunc* type_funcs,
|
||||
OTL_Validator valid );
|
||||
|
||||
/* */
|
||||
|
||||
OTL_END_HEADER
|
||||
|
73
src/otlayout/otlconf.h
Normal file
73
src/otlayout/otlconf.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef __OT_LAYOUT_CONFIG_H__
|
||||
#define __OT_LAYOUT_CONFIG_H__
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** CONFIGURATION MACROS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define OTL_BEGIN_HEADER extern "C" {
|
||||
#else
|
||||
# define OTL_BEGIN_HEADER /* nothing */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define OTL_END_HEADER }
|
||||
#else
|
||||
# define OTL_END_HEADER /* nothing */
|
||||
#endif
|
||||
|
||||
#ifndef OTL_API
|
||||
# ifdef __cplusplus
|
||||
# define OTL_API( x ) extern "C"
|
||||
# else
|
||||
# define OTL_API( x ) extern x
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef OTL_APIDEF
|
||||
# define OTL_APIDEF( x ) x
|
||||
#endif
|
||||
|
||||
#ifndef OTL_LOCAL
|
||||
# define OTL_LOCAL( x ) extern x
|
||||
#endif
|
||||
|
||||
#ifndef OTL_LOCALDEF
|
||||
# define OTL_LOCALDEF( x ) x
|
||||
#endif
|
||||
|
||||
#define OTL_BEGIN_STMNT do {
|
||||
#define OTL_END_STMNT } while (0)
|
||||
#define OTL_DUMMY_STMNT do { } while (0)
|
||||
|
||||
#define OTL_UNUSED( x ) (x)=(x)
|
||||
#define OTL_UNUSED_CONST(x) (void)(x)
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#if UINT_MAX == 0xFFFFU
|
||||
# define OTL_SIZEOF_INT 2
|
||||
#elif UINT_MAX == 0xFFFFFFFFU
|
||||
# define OTL_SIZEOF_INT 4
|
||||
#elif UINT_MAX > 0xFFFFFFFFU && UINT_MAX == 0xFFFFFFFFFFFFFFFFU
|
||||
# define OTL_SIZEOF_INT 8
|
||||
#else
|
||||
# error "unsupported number of bytes in 'int' type!"
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFFU
|
||||
# define OTL_SIZEOF_LONG 4
|
||||
#elif ULONG_MAX > 0xFFFFFFFFU && ULONG_MAX == 0xFFFFFFFFFFFFFFFFU
|
||||
# define OTL_SIZEOF_LONG 8
|
||||
#else
|
||||
# error "unsupported number of bytes in 'long' type!"
|
||||
#endif
|
||||
|
||||
/* */
|
||||
|
||||
#endif /* __OT_LAYOUT_CONFIG_H__ */
|
175
src/otlayout/otlgdef.c
Normal file
175
src/otlayout/otlgdef.c
Normal file
@ -0,0 +1,175 @@
|
||||
#include "otlgdef.h"
|
||||
#include "otlcommn.h"
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** ATTACHMENTS LIST *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_attach_point_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
if ( p + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
if ( table + count*2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_attach_list_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_Bytes coverage;
|
||||
OTL_UInt count;
|
||||
|
||||
if ( p + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
coverage = table + OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( coverage, valid );
|
||||
if ( count != otl_coverage_get_count( coverage ) )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
if ( p + count*2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
otl_attach_point_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** LIGATURE CARETS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_caret_value_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
|
||||
if ( p + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
OTL_Bytes device;
|
||||
|
||||
p += 2;
|
||||
if ( p + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
otl_device_table_validate( table + OTL_PEEK_USHORT( p ) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_ligature_glyph_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
if ( p + 2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( p + count*2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
otl_caret_value_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_ligature_caret_list_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_Bytes coverage;
|
||||
OTL_UInt count;
|
||||
|
||||
if ( p + 4 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
coverage = table + OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( coverage, valid );
|
||||
if ( count != otl_coverage_get_count( coverage ) )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
if ( p + count*2 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
otl_ligature_glyph_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GDEF TABLE *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
OTL_APIDEF( void )
|
||||
otl_gdef_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
|
||||
if ( p + 12 > valid->limit )
|
||||
OTL_INVALID_TOO_SHORT;
|
||||
|
||||
/* check format */
|
||||
if ( OTL_NEXT_ULONG( p ) != 0x00010000UL )
|
||||
OTL_INVALID_FORMAT;
|
||||
|
||||
/* validate class definition table */
|
||||
otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
|
||||
/* validate attachment point list */
|
||||
otl_attach_list_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
|
||||
/* validate ligature caret list */
|
||||
otl_ligature_caret_list_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
|
||||
/* validate mark attach class */
|
||||
otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
|
14
src/otlayout/otlgdef.h
Normal file
14
src/otlayout/otlgdef.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __OTL_GDEF_H__
|
||||
#define __OTL_GDEF_H__
|
||||
|
||||
#include "otltable.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
OTL_API( void )
|
||||
otl_gdef_validate( OTL_Bytes table,
|
||||
OTL_Valid valid );
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OTL_GDEF_H__ */
|
980
src/otlayout/otlgpos.c
Normal file
980
src/otlayout/otlgpos.c
Normal file
@ -0,0 +1,980 @@
|
||||
#include "otlgpos.h"
|
||||
#include "otlcommn.h"
|
||||
|
||||
/* forward declaration */
|
||||
static OTL_ValidateFunc otl_gpos_validate_funcs[];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** VALUE RECORDS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static OTL_UInt
|
||||
otl_value_length( OTL_UInt format )
|
||||
{
|
||||
FT_UInt count;
|
||||
|
||||
count = (( format & 0xAA ) >> 1) + ( format & 0x55 );
|
||||
count = (( count & 0xCC ) >> 2) + ( count & 0x33 );
|
||||
count = (( count & 0xF0 ) >> 4) + ( count & 0x0F );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_value_validate( OTL_Bytes table,
|
||||
OTL_Bytes pos_table,
|
||||
OTL_UInt format,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count, device;
|
||||
|
||||
if ( format >= 0x100U )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
for ( count = 4; count > 0; count-- )
|
||||
{
|
||||
if ( format & 1 )
|
||||
{
|
||||
OTL_CHECK( 2 );
|
||||
p += 2;
|
||||
}
|
||||
|
||||
format >>= 1;
|
||||
}
|
||||
|
||||
for ( count = 4; count > 0; count-- )
|
||||
{
|
||||
if ( format & 1 )
|
||||
{
|
||||
OTL_CHECK( 2 );
|
||||
device = OTL_NEXT_USHORT( p );
|
||||
if ( device )
|
||||
otl_device_table_validate( pos_table + device, valid );
|
||||
}
|
||||
format >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** ANCHORS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_anchor_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
p += 4;
|
||||
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
OTL_CHECK( 2 ); /* anchor point */
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
OTL_UInt x_device, y_device;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
x_device = OTL_NEXT_USHORT( p );
|
||||
y_device = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( x_device )
|
||||
otl_device_table_validate( table + x_device, valid );
|
||||
|
||||
if ( y_device )
|
||||
otl_device_table_validate( table + y_device, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** MARK ARRAY *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_mark_array_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( count * 4 );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
p += 2; /* ignore class index */
|
||||
otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 1 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_gpos_lookup1_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
FT_UInt coverage, value_format;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
value_format = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
otl_value_validate( p, table, value_format, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
FT_UInt coverage, value_format, count, len;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
value_format = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
len = otl_value_length( value_format );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( count * len );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
otl_value_validate( p, table, value_format, valid );
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 2 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static otl_gpos_pairset_validate( OTL_Bytes table,
|
||||
OTL_Bytes pos_table,
|
||||
OTL_UInt format1,
|
||||
OTL_UInt format2,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt len1, len2, count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
len1 = otl_value_length( format1 );
|
||||
len2 = otl_value_length( format2 );
|
||||
|
||||
OTL_CHECK( count * (len1+len2+2) );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
p += 2; /* ignore glyph id */
|
||||
otl_value_validate( p, pos_table, format1, valid );
|
||||
p += len1;
|
||||
|
||||
otl_value_validate( p, pos_table, format2, valid );
|
||||
p += len2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
otl_gpos_lookup2_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, value1, value2, count;
|
||||
|
||||
OTL_CHECK( 8 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
value1 = OTL_NEXT_USHORT( p );
|
||||
value2 = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
otl_gpos_pairset_validate( table + OTL_NEXT_USHORT( p ),
|
||||
table, value1, value2, valid );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt coverage, value1, value2, class1, class2, count1, count2;
|
||||
OTL_UInt len1, len2;
|
||||
|
||||
OTL_CHECK( 14 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
value1 = OTL_NEXT_USHORT( p );
|
||||
value2 = OTL_NEXT_USHORT( p );
|
||||
class1 = OTL_NEXT_USHORT( p );
|
||||
class2 = OTL_NEXT_USHORT( p );
|
||||
count1 = OTL_NEXT_USHORT( p );
|
||||
count2 = OTL_NEXT_USHORT( p );
|
||||
|
||||
len1 = otl_value_length( value1 );
|
||||
len2 = otl_value_length( value2 );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( count1*count2*(len1+len2) );
|
||||
for ( ; count1 > 0; count1-- )
|
||||
{
|
||||
for ( ; count2 > 0; count2-- )
|
||||
{
|
||||
otl_value_validate( p, table, value1, valid );
|
||||
p += len1;
|
||||
|
||||
otl_value_validate( p, table, value2, valid );
|
||||
p += len2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 3 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_gpos_lookup3_validate( OTL_Bytes table,
|
||||
OTL_Valid valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count, anchor1, anchor2;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( count*4 );
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
anchor1 = OTL_NEXT_USHORT( p );
|
||||
anchor2 = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( anchor1 )
|
||||
otl_anchor_validate( table + anchor1, valid );
|
||||
|
||||
if ( anchor2 )
|
||||
otl_anchor_validate( table + anchor2, valid );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 4 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_base_array_validate( OTL_Bytes table,
|
||||
OTL_UInt class_count,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count, count2;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*class_count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
for ( count2 = class_count; count2 > 0; count2-- )
|
||||
otl_anchor_validate( table + OTL_NEXT_USHORT( p ) );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gpos_lookup4_validate( OTL_Bytes table,
|
||||
OTL_Valid valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt mark_coverage, base_coverage, class_count;
|
||||
OTL_UInt mark_array, base_array;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
mark_coverage = OTL_NEXT_USHORT( p );
|
||||
base_coverage = OTL_NEXT_USHORT( p );
|
||||
class_count = OTL_NEXT_USHORT( p );
|
||||
mark_array = OTL_NEXT_USHORT( p );
|
||||
base_array = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + mark_coverage, valid );
|
||||
otl_coverage_validate( table + base_coverage, valid );
|
||||
|
||||
otl_mark_array_validate( table + mark_array, valid );
|
||||
otl_base_array_validate( table, class_count, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 5 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_liga_attach_validate( OTL_Bytes table,
|
||||
OTL_UInt class_count,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count, count2;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*class_count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
for ( count2 = class_count; class_count > 0; class_count-- )
|
||||
otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_liga_array_validate( OTL_Bytes table,
|
||||
OTL_UInt class_count,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count, count2;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_liga_attach_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gpos_lookup5_validate( OTL_Bytes table,
|
||||
OTL_Valid valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt mark_coverage, lig_coverage, class_count;
|
||||
OTL_UInt mar_array, lig_array;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
mark_coverage = OTL_NEXT_USHORT( p );
|
||||
liga_coverage = OTL_NEXT_USHORT( p );
|
||||
class_count = OTL_NEXT_USHORT( p );
|
||||
mark_array = OTL_NEXT_USHORT( p );
|
||||
liga_array = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + mark_coverage, valid );
|
||||
otl_coverage_validate( table + liga_coverage, valid );
|
||||
|
||||
otl_mark_array_validate( table + mark_array, valid );
|
||||
otl_liga_array_validate( table + liga_array, class_count, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 6 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
static void
|
||||
otl_mark2_array_validate( OTL_Bytes table,
|
||||
OTL_UInt class_count,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count, count2;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*class_count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
for ( count2 = class_count; class_count > 0; class_count-- )
|
||||
otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gpos_lookup6_validate( OTL_Bytes table,
|
||||
OTL_Valid valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage1, coverage2, class_count, array1, array2;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
coverage1 = OTL_NEXT_USHORT( p );
|
||||
coverage2 = OTL_NEXT_USHORT( p );
|
||||
class_count = OTL_NEXT_USHORT( p );
|
||||
array1 = OTL_NEXT_USHORT( p );
|
||||
array2 = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage1, valid );
|
||||
otl_coverage_validate( table + coverage2, valid );
|
||||
|
||||
otl_mark_array_validate( table + array1, valid );
|
||||
otl_mark2_array_validate( table + array2, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 7 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_pos_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt glyph_count, pos_count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_count = OTL_NEXT_USHORT( p );
|
||||
pos_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( glyph_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( (glyph_count-1)*2 + pos_count*4 );
|
||||
|
||||
/* XXX: check glyph indices and pos lookups */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_pos_rule_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
otl_pos_class_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt glyph_count, pos_count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_count = OTL_NEXT_USHORT( p );
|
||||
pos_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( glyph_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( (glyph_count-1)*2 + pos_count*4 );
|
||||
|
||||
/* XXX: check glyph indices and pos lookups */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_pos_class_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gpos_lookup7_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt coverage, class_def, count;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
class_def = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate ( table + coverage, valid );
|
||||
otl_class_definition_validate( table + class_def, valid );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
OTL_UInt glyph_count, pos_count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_count = OTL_NEXT_USHORT( p );
|
||||
pos_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( glyph_count*2 + pos_count*4 );
|
||||
for ( ; glyph_count > 0; glyph_count )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
/* XXX: check pos lookups */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 8 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_chain_pos_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt back_count, input_count, ahead_count, pos_count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
back_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( back_count*2 + 2 );
|
||||
p += back_count*2;
|
||||
|
||||
input_count = OTL_NEXT_USHORT( p );
|
||||
if ( input_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( input_count*2 );
|
||||
p += (input_count-1)*2;
|
||||
|
||||
ahead_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( ahead_count*2 + 2 );
|
||||
p += ahead_count*2;
|
||||
|
||||
pos_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( pos_count*4 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_pos_rule_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_pos_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_pos_class_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt back_count, input_count, ahead_count, pos_count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
back_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( back_count*2 + 2 );
|
||||
p += back_count*2;
|
||||
|
||||
input_count = OTL_NEXT_USHORT( p );
|
||||
if ( input_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( input_count*2 );
|
||||
p += (input_count-1)*2;
|
||||
|
||||
ahead_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( ahead_count*2 + 2 );
|
||||
p += ahead_count*2;
|
||||
|
||||
pos_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( pos_count*4 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_pos_class_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_pos_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gpos_lookup8_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ),
|
||||
valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt coverage, back_class, input_class, ahead_class, count;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
back_class = OTL_NEXT_USHORT( p );
|
||||
input_class = OTL_NEXT_USHORT( p );
|
||||
ahead_class = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
otl_class_definition_validate( table + back_class, valid );
|
||||
otl_class_definition_validate( table + input_class, valid );
|
||||
otl_class_definition_validate( table + ahead_class, valid );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_pos_class_set_validate( table + OTL_NEXT_USHORT( p ),
|
||||
valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
OTL_UInt back_count, input_count, ahead_count, pos_count, count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
back_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*back_count+2 );
|
||||
for ( count = back_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
input_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*input_count+2 );
|
||||
for ( count = input_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
ahead_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*ahead_count+2 );
|
||||
for ( count = ahead_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
pos_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( pos_count*4 );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS LOOKUP TYPE 9 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_gpos_lookup9_validate( OTL_Bytes table,
|
||||
OTL_Valid valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt lookup_type, lookup_offset;
|
||||
OTL_ValidateFunc validate;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
lookup_type = OTL_NEXT_USHORT( p );
|
||||
lookup_offset = OTL_NEXT_ULONG( p );
|
||||
|
||||
if ( lookup_type == 0 || lookup_type >= 9 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
validate = otl_gpos_validate_funcs[ lookup_type-1 ];
|
||||
validate( table + lookup_offset, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
static OTL_ValidateFunc otl_gpos_validate_funcs[ 9 ] =
|
||||
{
|
||||
otl_gpos_lookup1_validate,
|
||||
otl_gpos_lookup2_validate,
|
||||
otl_gpos_lookup3_validate,
|
||||
otl_gpos_lookup4_validate,
|
||||
otl_gpos_lookup5_validate,
|
||||
otl_gpos_lookup6_validate,
|
||||
otl_gpos_lookup7_validate,
|
||||
otl_gpos_lookup8_validate,
|
||||
otl_gpos_lookup9_validate,
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GPOS TABLE *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
OTL_LOCALDEF( void )
|
||||
otl_gpos_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt scripts, features, lookups;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
|
||||
if ( OTL_NEXT_USHORT( p ) != 0x10000UL )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
scripts = OTL_NEXT_USHORT( p );
|
||||
features = OTL_NEXT_USHORT( p );
|
||||
lookups = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_script_list_validate ( table + scripts, valid );
|
||||
otl_feature_list_validate( table + features, valid );
|
||||
|
||||
otl_lookup_list_validate( table + lookups, 9, otl_gpos_validate_funcs,
|
||||
valid );
|
||||
}
|
||||
|
14
src/otlayout/otlgpos.h
Normal file
14
src/otlayout/otlgpos.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __OTL_GPOS_H__
|
||||
#define __OTL_GPOS_H__
|
||||
|
||||
#include "otlayout.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_gpos_validate( OTL_Bytes table,
|
||||
OTL_Validator valid );
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OTL_GPOS_H__ */
|
654
src/otlayout/otlgsub.c
Normal file
654
src/otlayout/otlgsub.c
Normal file
@ -0,0 +1,654 @@
|
||||
#include "otlgsub.h"
|
||||
#include "otlcommn.h"
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 1 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_gsub_lookup1_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 2 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_seq_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
/* check glyph indices */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gsub_lookup2_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format, coverage;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, seq_count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
seq_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( seq_count*2 );
|
||||
for ( ; seq_count > 0; seq_count-- )
|
||||
otl_seq_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 3 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_alternate_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
/* XXX: check glyph indices */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gsub_lookup3_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format, coverage;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_alternate_set_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 4 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_ligature_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_UInt glyph_id, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_id = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( 2*(count-1) );
|
||||
/* XXX: check glyph indices */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_ligature_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_ligature_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gsub_lookup4_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format, coverage;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_ligature_set_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 5 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
static void
|
||||
otl_sub_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt glyph_count, subst_count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_count = OTL_NEXT_USHORT( p );
|
||||
subst_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( glyph_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( (glyph_count-1)*2 + substcount*4 );
|
||||
|
||||
/* XXX: check glyph indices and subst lookups */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_sub_rule_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_sub_class_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_UInt glyph_count, subst_count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_count = OTL_NEXT_USHORT( p );
|
||||
subst_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( glyph_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( (glyph_count-1)*2 + substcount*4 );
|
||||
|
||||
/* XXX: check glyph indices and subst lookups */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_sub_class_rule_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_sub_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gsub_lookup5_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format, coverage;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_sub_rule_set_validate( table + coverage, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt coverage, class_def, count;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
class_def = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate ( table + coverage, valid );
|
||||
otl_class_definition_validate( table + class_def, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_sub_class_rule_set_validate( table + coveragen valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
OTL_UInt glyph_count, subst_count, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
glyph_count = OTL_NEXT_USHORT( p );
|
||||
subst_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*glyph_count + 4*subst_count );
|
||||
for ( count = glyph_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 6 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_sub_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt back_count, input_count, ahead_count, subst_count, count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
back_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*back_count+2 );
|
||||
p += 2*back_count;
|
||||
|
||||
input_count = OTL_NEXT_USHORT( p );
|
||||
if ( input_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( 2*input_count );
|
||||
p += 2*(input_count-1);
|
||||
|
||||
ahead_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( 2*ahead_count + 2 );
|
||||
p += 2*ahead_count;
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( 4*count );
|
||||
|
||||
/* XXX: check glyph indices and subst lookups */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_sub_rule_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_sub_class_rule_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt back_count, input_count, ahead_count, subst_count, count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
back_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*back_count+2 );
|
||||
p += 2*back_count;
|
||||
|
||||
input_count = OTL_NEXT_USHORT( p );
|
||||
if ( input_count == 0 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
OTL_CHECK( 2*input_count );
|
||||
p += 2*(input_count-1);
|
||||
|
||||
ahead_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( 2*ahead_count + 2 );
|
||||
p += 2*ahead_count;
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( 4*count );
|
||||
|
||||
/* XXX: check class indices and subst lookups */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
otl_chain_sub_class_set_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_gsub_lookup6_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format, coverage;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt coverage, count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_sub_rule_set_validate( table + coverage, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
OTL_UInt coverage, back_class, input_class, ahead_class, count;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
coverage = OTL_NEXT_USHORT( p );
|
||||
back_class = OTL_NEXT_USHORT( p );
|
||||
input_class = OTL_NEXT_USHORT( p );
|
||||
ahead_class = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_coverage_validate( table + coverage, valid );
|
||||
|
||||
otl_class_definition_validate( table + back_class, valid );
|
||||
otl_class_definition_validate( table + input_class, valid );
|
||||
otl_class_definition_validate( table + ahead_class, valid );
|
||||
|
||||
OTL_CHECK( 2*count );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_chain_sub_class_set( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
OTL_UInt back_count, input_count, ahead_count, subst_count, count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
back_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*back_count+2 );
|
||||
for ( count = back_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
input_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*input_count+2 );
|
||||
for ( count = input_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
ahead_count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2*ahead_count+2 );
|
||||
for ( count = ahead_count; count > 0; count-- )
|
||||
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
|
||||
subst_count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( subst_count*4 );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB LOOKUP TYPE 6 *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
otl_gsub_lookup7_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt format, coverage;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
format = OTL_NEXT_USHORT( p );
|
||||
switch ( format )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
OTL_UInt lookup_type, lookup_offset;
|
||||
OTL_ValidateFunc validate;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
lookup_type = OTL_NEXT_USHORT( p );
|
||||
lookup_offset = OTL_NEXT_ULONG( p );
|
||||
|
||||
if ( lookup_type == 0 || lookup_type >= 7 )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
validate = otl_gsub_validate_funcs[ lookup_type-1 ];
|
||||
validate( table + lookup_offset, valid );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
OTL_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const OTL_ValidateFunc otl_gsub_validate_funcs[ 7 ] =
|
||||
{
|
||||
otl_gsub_lookup1_validate,
|
||||
otl_gsub_lookup2_validate,
|
||||
otl_gsub_lookup3_validate,
|
||||
otl_gsub_lookup4_validate,
|
||||
otl_gsub_lookup5_validate,
|
||||
otl_gsub_lookup6_validate
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** GSUB TABLE *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
OTL_LOCALDEF( void )
|
||||
otl_gsub_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt scripts, features, lookups;
|
||||
|
||||
OTL_CHECK( 10 );
|
||||
|
||||
if ( OTL_NEXT_USHORT( p ) != 0x10000UL )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
scripts = OTL_NEXT_USHORT( p );
|
||||
features = OTL_NEXT_USHORT( p );
|
||||
lookups = OTL_NEXT_USHORT( p );
|
||||
|
||||
otl_script_list_validate ( table + scripts, valid );
|
||||
otl_feature_list_validate( table + features, valid );
|
||||
|
||||
otl_lookup_list_validate( table + lookups, 7, otl_gsub_validate_funcs,
|
||||
valid );
|
||||
}
|
14
src/otlayout/otlgsub.h
Normal file
14
src/otlayout/otlgsub.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __OTL_GSUB_H__
|
||||
#define __OTL_GSUB_H__
|
||||
|
||||
#include "otlayout.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_gsub_validate( OTL_Bytes table,
|
||||
OTL_Validator valid );
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OTL_GSUB_H__ */
|
189
src/otlayout/otljstf.c
Normal file
189
src/otlayout/otljstf.c
Normal file
@ -0,0 +1,189 @@
|
||||
#include "otljstf.h"
|
||||
#include "otlcommn.h"
|
||||
#include "otlgpos.h"
|
||||
|
||||
static void
|
||||
otl_jstf_extender_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_jstf_gsub_mods_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( count*2 );
|
||||
|
||||
/* XXX: check GSUB lookup indices */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_jstf_gpos_mods_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( count*2 );
|
||||
|
||||
/* XXX: check GPOS lookup indices */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_jstf_max_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_gpos_subtable_check( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_jstf_priority_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt offset;
|
||||
|
||||
OTL_CHECK( 20 );
|
||||
|
||||
/* shrinkage GSUB enable/disable */
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gsub_mods_validate( table + val, valid );
|
||||
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gsub_mods_validate( table + val, valid );
|
||||
|
||||
/* shrinkage GPOS enable/disable */
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gpos_mods_validate( table + val, valid );
|
||||
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gpos_mods_validate( table + val, valid );
|
||||
|
||||
/* shrinkage JSTF max */
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_max_validate( table + val, valid );
|
||||
|
||||
/* extension GSUB enable/disable */
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gsub_mods_validate( table + val, valid );
|
||||
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gsub_mods_validate( table + val, valid );
|
||||
|
||||
/* extension GPOS enable/disable */
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gpos_mods_validate( table + val, valid );
|
||||
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_gpos_mods_validate( table + val, valid );
|
||||
|
||||
/* extension JSTF max */
|
||||
val = OTL_NEXT_USHORT( p );
|
||||
if ( val )
|
||||
otl_jstf_max_validate( table + val, valid );
|
||||
}
|
||||
|
||||
static void
|
||||
otl_jstf_lang_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 2 );
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( count*2 );
|
||||
for ( ; count > 0; count-- )
|
||||
otl_jstf_priority_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
otl_jstf_script_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count, extender, default_lang;
|
||||
|
||||
OTL_CHECK( 6 );
|
||||
extender = OTL_NEXT_USHORT( p );
|
||||
default_lang = OTL_NEXT_USHORT( p );
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
|
||||
if ( extender )
|
||||
otl_jstf_extender_validate( table + extender, valid );
|
||||
|
||||
if ( default_lang )
|
||||
otl_jstf_lang_validate( table + default_lang, valid );
|
||||
|
||||
OTL_CHECK( 6*count );
|
||||
|
||||
for ( ; count > 0; count-- )
|
||||
{
|
||||
p += 4; /* ignore tag */
|
||||
otl_jstf_lang_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OTL_LOCALDEF( void )
|
||||
otl_jstf_validate( OTL_Bytes table,
|
||||
OTL_Validator valid )
|
||||
{
|
||||
OTL_Bytes p = table;
|
||||
OTL_UInt count;
|
||||
|
||||
OTL_CHECK( 4 );
|
||||
|
||||
if ( OTL_NEXT_ULONG( p ) != 0x10000UL )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
count = OTL_NEXT_USHORT( p );
|
||||
OTL_CHECK( count*6 );
|
||||
|
||||
for ( ; count > 0; count++ )
|
||||
{
|
||||
p += 4; /* ignore tag */
|
||||
otl_jstf_script_validate( table + OTL_NEXT_USHORT( p ), valid );
|
||||
}
|
||||
}
|
||||
|
14
src/otlayout/otljstf.h
Normal file
14
src/otlayout/otljstf.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __OTL_JSTF_H__
|
||||
#define __OTL_JSTF_H__
|
||||
|
||||
#include "otlayout.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
OTL_LOCAL( void )
|
||||
otl_jstf_validate( OTL_Bytes table,
|
||||
OTL_Validator valid );
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OTL_JSTF_H__ */
|
60
src/otlayout/otltable.h
Normal file
60
src/otlayout/otltable.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef __OTL_TABLE_H__
|
||||
#define __OTL_TABLE_H__
|
||||
|
||||
#include "otlayout.h"
|
||||
|
||||
OTL_BEGIN_HEADER
|
||||
|
||||
typedef struct OTL_TableRec_* OTL_Table;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OTL_TABLE_TYPE_GDEF = 1,
|
||||
OTL_TABLE_TYPE_GSUB,
|
||||
OTL_TABLE_TYPE_GPOS,
|
||||
OTL_TABLE_TYPE_BASE,
|
||||
OTL_TABLE_TYPE_JSTF
|
||||
|
||||
} OTL_TableType;
|
||||
|
||||
|
||||
/* this may become a private structure later */
|
||||
typedef struct OTL_TableRec_
|
||||
{
|
||||
OTL_TableType type;
|
||||
OTL_Bytes base;
|
||||
OTL_Bytes limit;
|
||||
|
||||
OTL_Tag script_tag;
|
||||
OTL_Tag lang_tag;
|
||||
|
||||
OTL_UInt lookup_count;
|
||||
OTL_Byte* lookup_flags;
|
||||
|
||||
OTL_UInt feature_count;
|
||||
OTL_Tag feature_tags;
|
||||
OTL_Byte* feature_flags;
|
||||
|
||||
} OTL_TableRec;
|
||||
|
||||
|
||||
OTL_API( OTL_Error )
|
||||
otl_table_validate( OTL_Bytes table,
|
||||
OTL_Size size,
|
||||
OTL_TableType type,
|
||||
OTL_Size *abyte_size );
|
||||
|
||||
OTL_API( void )
|
||||
otl_table_init( OTL_Table table,
|
||||
OTL_TableType type,
|
||||
OTL_Bytes base,
|
||||
OTL_Size size );
|
||||
|
||||
OTL_API( void )
|
||||
otl_table_set_script( OTL_Table table,
|
||||
OTL_ScriptTag script,
|
||||
OTL_LangTag language );
|
||||
|
||||
OTL_END_HEADER
|
||||
|
||||
#endif /* __OTL_TABLE_H__ */
|
86
src/otlayout/otltags.h
Normal file
86
src/otlayout/otltags.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* this file may be included several times by other parts of */
|
||||
/* the OpenType Layout library.. don't add #ifdef .. #endif */
|
||||
/* delimiters to it... */
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** SCRIPT TAGS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef OTL_SCRIPT_TAG
|
||||
#define OTL_SCRIPT_TAG(c1,c2,c3,c4,s,n) /* void */
|
||||
#endif
|
||||
|
||||
OTL_SCRIPT_TAG( 'a','r','a','b', "Arabic", ARABIC )
|
||||
OTL_SCRIPT_TAG( 'a','r','m','n', "Armenian", ARMENIAN )
|
||||
OTL_SCRIPT_TAG( 'b','e','n','g', "Bengali", BENGALI )
|
||||
OTL_SCRIPT_TAG( 'b','o','p','o', "Bopomofo", BOPOMOFO )
|
||||
OTL_SCRIPT_TAG( 'b','r','a','i', "Braille", BRAILLE )
|
||||
OTL_SCRIPT_TAG( 'c','a','n','s', "Canadian Syllabic", CANADIAN )
|
||||
OTL_SCRIPT_TAG( 'c','h','e','r', "Cherokee", CHEROKEE )
|
||||
OTL_SCRIPT_TAG( 'h','a','n','i', "CJK Ideographic", CJK )
|
||||
OTL_SCRIPT_TAG( 'c','y','r','l', "Cyrillic", CYRILLIC )
|
||||
OTL_SCRIPT_TAG( 'd','e','v','a', "Devanagari", DEVANAGARI )
|
||||
OTL_SCRIPT_TAG( 'e','t','h','i', "Ethiopic", ETHIOPIC )
|
||||
OTL_SCRIPT_TAG( 'g','e','o','r', "Georgian", GEORGIAN )
|
||||
OTL_SCRIPT_TAG( 'g','r','e','k', "Greek", GREEK )
|
||||
OTL_SCRIPT_TAG( 'g','u','j','r', "Gujarati", GUJARATI )
|
||||
OTL_SCRIPT_TAG( 'g','u','r','u', "Gurmukhi", GURMUKHI )
|
||||
OTL_SCRIPT_TAG( 'j','a','m','o', "Hangul Jamo", JAMO )
|
||||
OTL_SCRIPT_TAG( 'h','a','n','g', "Hangul", HANGUL )
|
||||
OTL_SCRIPT_TAG( 'h','e','b','r', "Hebrew", HEBREW )
|
||||
OTL_SCRIPT_TAG( 'h','i','r','a', "Hiragana", HIRAGANA )
|
||||
OTL_SCRIPT_TAG( 'k','n','d','a', "Kannada", KANNADA )
|
||||
OTL_SCRIPT_TAG( 'k','a','n','a', "Katakana", KATAKANA )
|
||||
OTL_SCRIPT_TAG( 'k','h','m','r', "Khmer", KHMER )
|
||||
OTL_SCRIPT_TAG( 'l','a','o',' ', "Lao", LAO )
|
||||
OTL_SCRIPT_TAG( 'l','a','t','n', "Latin", LATIN )
|
||||
OTL_SCRIPT_TAG( 'm','l','y','m', "Malayalam", MALAYALAM )
|
||||
OTL_SCRIPT_TAG( 'm','o','n','g', "Mongolian", MONGOLIAN )
|
||||
OTL_SCRIPT_TAG( 'm','y','m','r', "Myanmar", MYANMAR )
|
||||
OTL_SCRIPT_TAG( 'o','g','a','m', "Ogham", OGHAM )
|
||||
OTL_SCRIPT_TAG( 'o','r','y','a', "Oriya", ORIYA )
|
||||
OTL_SCRIPT_TAG( 'r','u','n','r', "Runic", RUNIC )
|
||||
OTL_SCRIPT_TAG( 's','i','n','h', "Sinhala", SINHALA )
|
||||
OTL_SCRIPT_TAG( 's','y','r','c', "Syriac", SYRIAC )
|
||||
OTL_SCRIPT_TAG( 't','a','m','l', "Tamil", TAMIL )
|
||||
OTL_SCRIPT_TAG( 't','e','l','u', "Telugu", TELUGU )
|
||||
OTL_SCRIPT_TAG( 't','h','a','a', "Thaana", THAANA )
|
||||
OTL_SCRIPT_TAG( 't','h','a','i', "Thai", THAI )
|
||||
OTL_SCRIPT_TAG( 't','i','b','t', "Tibetan", TIBETAN )
|
||||
OTL_SCRIPT_TAG( 'y','i',' ',' ', "Yi", YI )
|
||||
|
||||
#undef OTL_SCRIPT_TAG
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** LANGUAGE TAGS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef OTL_LANG_TAG
|
||||
#define OTL_LANG_TAG(c1,c2,c3,c4,s,n) /* void */
|
||||
#endif
|
||||
|
||||
#undef OTL_LANG_TAG
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
/***** *****/
|
||||
/***** FEATURE TAGS *****/
|
||||
/***** *****/
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef OTL_FEATURE_TAG
|
||||
#define OTL_FEATURE_TAG(c1,c2,c3,c4,s,n) /* void */
|
||||
#endif
|
||||
|
||||
#undef OTL_FEATURE_TAG
|
||||
|
@ -1543,9 +1543,6 @@
|
||||
/* clear all outline flags, except the `owner' one */
|
||||
glyph->outline.flags = 0;
|
||||
|
||||
if ( size && size->root.metrics.y_ppem < 24 )
|
||||
glyph->outline.flags |= ft_outline_high_precision;
|
||||
|
||||
/* let's initialize the rest of our loader now */
|
||||
|
||||
loader.load_flags = load_flags;
|
||||
@ -1581,6 +1578,14 @@
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
|
||||
/* Don't forget to set the 'high precision' bit flag !! */
|
||||
/* This is _critical_ to get correct output for monochrome */
|
||||
/* TrueType glyphs at all sizes using the bytecode interpreter */
|
||||
/* */
|
||||
if ( size && size->root.metrics.y_ppem < 24 )
|
||||
glyph->outline.flags |= ft_outline_high_precision;
|
||||
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user