Coverage.

This commit is contained in:
Behdad Esfahbod 2006-12-26 15:29:38 -05:00
parent 882e52f591
commit 0c0d55330e
1 changed files with 79 additions and 12 deletions

View File

@ -169,8 +169,9 @@ struct Tag {
}; };
/* Glyph index number, same as uint16 (length = 16 bits) */ /* Glyph index number, same as uint16 (length = 16 bits) */
struct GlyphID : USHORT { //struct GlyphID : USHORT {
}; //};
DEFINE_INT_TYPE (GlyphID, u, 16); /* 16-bit unsigned integer. */
/* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ /* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */
struct Offset : USHORT { struct Offset : USHORT {
@ -219,7 +220,6 @@ typedef struct TableDirectory {
} OpenTypeTable; } OpenTypeTable;
typedef struct OffsetTable { typedef struct OffsetTable {
DEFINE_NOT_INSTANTIABLE(OffsetTable);
/* OpenTypeTables, in no particular order */ /* OpenTypeTables, in no particular order */
DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables);
// TODO: Implement find_table // TODO: Implement find_table
@ -237,7 +237,6 @@ typedef struct OffsetTable {
*/ */
struct TTCHeader { struct TTCHeader {
DEFINE_NOT_INSTANTIABLE(TTCHeader);
/* OpenTypeFonts, in no particular order */ /* OpenTypeFonts, in no particular order */
DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts);
@ -255,7 +254,7 @@ struct TTCHeader {
* OpenType Font File * OpenType Font File
*/ */
typedef struct OpenTypeFontFile { struct OpenTypeFontFile {
DEFINE_NOT_INSTANTIABLE(OpenTypeFontFile); DEFINE_NOT_INSTANTIABLE(OpenTypeFontFile);
static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 );
static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O');
@ -322,7 +321,6 @@ typedef struct Record {
} ScriptRecord, LangSysRecord, FeatureRecord; } ScriptRecord, LangSysRecord, FeatureRecord;
struct ScriptList { struct ScriptList {
DEFINE_NOT_INSTANTIABLE(ScriptList);
/* Scripts, in sorted alphabetical tag order */ /* Scripts, in sorted alphabetical tag order */
DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount);
@ -332,7 +330,6 @@ struct ScriptList {
}; };
struct Script { struct Script {
DEFINE_NOT_INSTANTIABLE(Script);
/* LangSys', in sorted alphabetical tag order */ /* LangSys', in sorted alphabetical tag order */
DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount);
@ -357,7 +354,6 @@ struct Script {
}; };
struct LangSys { struct LangSys {
DEFINE_NOT_INSTANTIABLE(LangSys);
/* Feature indices, in no particular order */ /* Feature indices, in no particular order */
DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount);
@ -381,7 +377,6 @@ struct LangSys {
}; };
struct FeatureList { struct FeatureList {
DEFINE_NOT_INSTANTIABLE(FeatureList);
/* Feature indices, in sorted alphabetical tag order */ /* Feature indices, in sorted alphabetical tag order */
DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount); DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount);
@ -393,7 +388,6 @@ struct FeatureList {
}; };
struct Feature { struct Feature {
DEFINE_NOT_INSTANTIABLE(Feature);
/* LookupList indices, in no particular order */ /* LookupList indices, in no particular order */
DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount);
@ -412,7 +406,6 @@ struct Feature {
}; };
struct LookupList { struct LookupList {
DEFINE_NOT_INSTANTIABLE(LookupList);
/* Lookup indices, in sorted alphabetical tag order */ /* Lookup indices, in sorted alphabetical tag order */
DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount);
@ -433,7 +426,6 @@ struct LookupFlag : USHORT {
}; };
struct Lookup { struct Lookup {
DEFINE_NOT_INSTANTIABLE(Lookup);
/* SubTables, in the desired order */ /* SubTables, in the desired order */
DEFINE_OFFSET_ARRAY_TYPE (SubTable, subTableOffset, subTableCount); DEFINE_OFFSET_ARRAY_TYPE (SubTable, subTableOffset, subTableCount);
@ -451,6 +443,81 @@ struct Lookup {
* entries long. */ * entries long. */
}; };
struct CoverageFormat1 {
/* GlyphIDs, in sorted numerical order */
DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount);
inline unsigned int get_coverage (uint16_t glyph_id) const {
GlyphID gid (glyph_id);
// TODO: bsearch
for (int i = 0; i < glyphCount; i++)
if (gid == glyphArray[i])
return i;
return -1;
}
USHORT coverageFormat; /* Format identifier--format = 1 */
USHORT glyphCount; /* Number of glyphs in the GlyphArray */
GlyphID glyphArray[]; /* Array of GlyphIDs--in numerical
* order. glyphCount entries long */
};
struct RangeRecord {
inline unsigned int get_coverage (uint16_t glyph_id) const {
if (glyph_id >= start && glyph_id <= end)
return startCoverageIndex + (glyph_id - start);
return -1;
}
GlyphID start; /* First GlyphID in the range */
GlyphID end; /* Last GlyphID in the range */
USHORT startCoverageIndex; /* Coverage Index of first GlyphID in
* range */
};
struct CoverageFormat2 {
/* RangeRecords, in sorted numerical start order */
DEFINE_ARRAY_TYPE (RangeRecord, rangeRecord, rangeCount);
inline unsigned int get_coverage (uint16_t glyph_id) const {
// TODO: bsearch
for (int i = 0; i < rangeCount; i++) {
int coverage = rangeRecord[i].get_coverage (glyph_id);
if (coverage >= 0)
return coverage;
}
return -1;
}
USHORT coverageFormat; /* Format identifier--format = 2 */
USHORT rangeCount; /* Number of RangeRecords */
RangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by
* Start GlyphID. rangeCount entries
* long */
};
struct CoverageFormat {
DEFINE_NOT_INSTANTIABLE(CoverageFormat);
inline unsigned int get_size (void) const {
switch (coverageFormat) {
case 1: return ((const CoverageFormat1&)*this).get_size ();
case 2: return ((const CoverageFormat2&)*this).get_size ();
default: return sizeof (coverageFormat);
}
}
/* Returns -1 if not covered. */
inline unsigned int get_coverage (uint16_t glyph_id) const {
switch (coverageFormat) {
case 1: return ((const CoverageFormat1&)*this).get_coverage(glyph_id);
case 2: return ((const CoverageFormat2&)*this).get_coverage(glyph_id);
default: return -1;
}
}
USHORT coverageFormat; /* Format identifier */
};