Coverage.
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 26 Dec 2006 20:29:38 +0000 (15:29 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 26 Dec 2006 20:29:38 +0000 (15:29 -0500)
src/harfbuzz-ng.cc

index ed817c5..7fdefd6 100644 (file)
@@ -169,8 +169,9 @@ struct Tag {
 };
 
 /* 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 */
 struct Offset : USHORT {
@@ -219,7 +220,6 @@ typedef struct TableDirectory {
 } OpenTypeTable;
 
 typedef struct OffsetTable {
-  DEFINE_NOT_INSTANTIABLE(OffsetTable);
   /* OpenTypeTables, in no particular order */
   DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables);
   // TODO: Implement find_table
@@ -237,7 +237,6 @@ typedef struct OffsetTable {
  */
 
 struct TTCHeader {
-  DEFINE_NOT_INSTANTIABLE(TTCHeader);
   /* OpenTypeFonts, in no particular order */
   DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts);
 
@@ -255,7 +254,7 @@ struct TTCHeader {
  * OpenType Font File
  */
 
-typedef struct OpenTypeFontFile {
+struct OpenTypeFontFile {
   DEFINE_NOT_INSTANTIABLE(OpenTypeFontFile);
   static const hb_tag_t TrueTypeTag    = HB_TAG ( 0 , 1 , 0 , 0 );
   static const hb_tag_t CFFTag         = HB_TAG ('O','T','T','O');
@@ -322,7 +321,6 @@ typedef struct Record {
 } ScriptRecord, LangSysRecord, FeatureRecord;
 
 struct ScriptList {
-  DEFINE_NOT_INSTANTIABLE(ScriptList);
   /* Scripts, in sorted alphabetical tag order */
   DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount);
 
@@ -332,7 +330,6 @@ struct ScriptList {
 };
 
 struct Script {
-  DEFINE_NOT_INSTANTIABLE(Script);
   /* LangSys', in sorted alphabetical tag order */
   DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount);
 
@@ -357,7 +354,6 @@ struct Script {
 };
 
 struct LangSys {
-  DEFINE_NOT_INSTANTIABLE(LangSys);
   /* Feature indices, in no particular order */
   DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount);
   
@@ -381,7 +377,6 @@ struct LangSys {
 };
 
 struct FeatureList {
-  DEFINE_NOT_INSTANTIABLE(FeatureList);
   /* Feature indices, in sorted alphabetical tag order */
   DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount);
 
@@ -393,7 +388,6 @@ struct FeatureList {
 };
 
 struct Feature {
-  DEFINE_NOT_INSTANTIABLE(Feature);
   /* LookupList indices, in no particular order */
   DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount);
 
@@ -412,7 +406,6 @@ struct Feature {
 };
 
 struct LookupList {
-  DEFINE_NOT_INSTANTIABLE(LookupList);
   /* Lookup indices, in sorted alphabetical tag order */
   DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount);
 
@@ -433,7 +426,6 @@ struct LookupFlag : USHORT {
 };
 
 struct Lookup {
-  DEFINE_NOT_INSTANTIABLE(Lookup);
   /* SubTables, in the desired order */
   DEFINE_OFFSET_ARRAY_TYPE (SubTable, subTableOffset, subTableCount);
 
@@ -451,6 +443,81 @@ struct Lookup {
                                  * 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 */
+};