/* COMMON */
static void
-dump_glyph_ids (OTF_GlyphID *ids, unsigned num)
+dump_glyph_ids (int indent, char *title, OTF_GlyphID *ids, unsigned count)
{
- while (num-- > 0)
+ IPRINT ("(%s (count %d)", title, count);
+ while (count-- > 0)
{
printf (" #x%04X", *ids);
ids++;
}
+ printf (")");
}
static void
indent++;
if (coverage->CoverageFormat == 1)
{
- IPRINT ("(GlyphCount %d)", coverage->Count);
- IPRINT ("(GlyphArray");
- dump_glyph_ids (coverage->table.GlyphArray, coverage->Count);
- printf (")");
+ dump_glyph_ids (indent, "GlyphArray", coverage->table.GlyphArray,
+ coverage->Count);
}
else
{
IPRINT ("(%s (offset #x%04X) (ClassFormat %d)",
(title ? title : "ClassDef"),
class->offset, class->ClassFormat);
- indent++;
- if (class->ClassFormat == 1)
+ if (class->offset)
{
- IPRINT ("(StartGlyph #x%04X)", class->f.f1.StartGlyph);
- IPRINT ("(GlyphCount %d)", class->f.f1.GlyphCount);
- IPRINT ("(ClassValueArray");
- dump_glyph_ids ((OTF_GlyphID *) class->f.f1.ClassValueArray,
- class->f.f1.GlyphCount);
- printf (")");
- }
- else if (class->ClassFormat == 2)
- {
- int i;
-
- IPRINT ("(ClassRangeCount %d)", class->f.f2.ClassRangeCount);
- IPRINT ("(ClassRangeRecord");
indent++;
- for (i = 0; i < class->f.f2.ClassRangeCount; i++)
- IPRINT ("((Start #x%04X) (End #x%04X) (class %d))",
- class->f.f2.ClassRangeRecord[i].Start,
- class->f.f2.ClassRangeRecord[i].End,
- class->f.f2.ClassRangeRecord[i].Class);
- printf (")");
+ if (class->ClassFormat == 1)
+ {
+ IPRINT ("(StartGlyph #x%04X)", class->f.f1.StartGlyph);
+ dump_glyph_ids (indent, "ClassValueArray",
+ (OTF_GlyphID *) class->f.f1.ClassValueArray,
+ class->f.f1.GlyphCount);
+ }
+ else if (class->ClassFormat == 2)
+ {
+ int i;
+
+ IPRINT ("(ClassRangeCount %d)", class->f.f2.ClassRangeCount);
+ IPRINT ("(ClassRangeRecord");
+ indent++;
+ for (i = 0; i < class->f.f2.ClassRangeCount; i++)
+ IPRINT ("((Start #x%04X) (End #x%04X) (class %d))",
+ class->f.f2.ClassRangeRecord[i].Start,
+ class->f.f2.ClassRangeRecord[i].End,
+ class->f.f2.ClassRangeRecord[i].Class);
+ printf (")");
+ }
+ else
+ printf (" UnknownClassFormat");
}
- else
- printf ("UknownClassFormat");
printf (")");
}
{
IPRINT ("(Sequence (%d) (offset #x%04X)",
i, sequence[i].offset);
- indent++;
- IPRINT ("(GlyphCount %d)", sequence[i].GlyphCount);
- IPRINT ("(Substitute");
- dump_glyph_ids (sequence[i].Substitute, sequence[i].GlyphCount);
- printf ("))");
- indent--;
+ dump_glyph_ids (indent + 1, "Substitute", sequence[i].Substitute,
+ sequence[i].GlyphCount);
+ printf (")");
}
}
static void
+dump_alternate_set_list (int indent, OTF_AlternateSet *altset, unsigned num)
+{
+ int i;
+
+ IPRINT ("(AlternateSetCount %d)", num);
+ for (i = 0; i < num; i++)
+ {
+ IPRINT ("(AlternateSet (%d) (offset #x%04X)",
+ i, altset[i].offset);
+ dump_glyph_ids (indent + 1, "Alternate", altset[i].Alternate,
+ altset[i].GlyphCount);
+ printf (")");
+ }
+}
+
+
+static void
dump_ligature_set_list (int indent, OTF_LigatureSet *ligset, unsigned num)
{
int i, j;
indent++;
IPRINT ("(LigGlyph #x%04X)",
ligset[i].Ligature[j].LigGlyph);
- IPRINT ("(ComCount %d)",
- ligset[i].Ligature[j].CompCount);
- IPRINT ("(Component");
- dump_glyph_ids (ligset[i].Ligature[j].Component,
+ dump_glyph_ids (indent, "Component", ligset[i].Ligature[j].Component,
ligset[i].Ligature[j].CompCount - 1);
- printf ("))");
+ printf (")");
indent--;
}
indent--;
}
static void
-dump_base_array (int indent, unsigned ClassCount, OTF_BaseArray *array)
+dump_anchor_array (int indent, unsigned ClassCount, OTF_AnchorArray *array)
{
int i, j;
- IPRINT ("(BaseArray (BaseCount %d)", array->BaseCount);
+ IPRINT ("(AnchorArray (Count %d)", array->Count);
indent++;
- for (i = 0; i < array->BaseCount; i++)
+ for (i = 0; i < array->Count; i++)
{
- IPRINT ("(BaseRecord (%d) ", i);
+ IPRINT ("(AnchorRecord (%d) ", i);
for (j = 0; j < ClassCount; j++)
- dump_anchor (indent + 1, array->BaseRecord[i].BaseAnchor + j);
+ dump_anchor (indent + 1, array->AnchorRecord[i].Anchor + j);
printf (")");
}
printf (")");
static void
-dump_subst_lookup_record_list (int indent,
- OTF_SubstLookupRecord *rec, unsigned num)
+dump_lookup_record_list (int indent, OTF_LookupRecord *rec, unsigned num)
{
int i;
- IPRINT ("(SubstCount %d)", num);
+ IPRINT ("(LookupCount %d)", num);
for (i = 0; i < num; i++)
{
- IPRINT ("(SubstLookupRecord (%d)", i);
+ IPRINT ("(LookupRecord (%d)", i);
indent++;
IPRINT ("(SequenceIndex %d)", rec[i].SequenceIndex);
IPRINT ("(LookupListIndex %d))", rec[i].LookupListIndex);
printf (")");
}
+static void
+dump_rule_list (int indent, OTF_Rule *rule, int count)
+{
+ int i;
+
+ IPRINT ("(RuleCount %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(Rule (%d)", i);
+ indent++;
+ IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
+ IPRINT ("(LookupCount %d)", rule[i].LookupCount);
+ dump_glyph_ids (indent, "Input", rule[i].Input, rule[i].GlyphCount - 1);
+ dump_lookup_record_list (indent, rule[i].LookupRecord,
+ rule[i].LookupCount);
+ printf (")");
+ indent--;
+ }
+}
+
+static void
+dump_rule_set_list (int indent, OTF_RuleSet *set, int count)
+{
+ int i;
+
+ IPRINT ("(RuleSetCount %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(RuleSet (%d)", i);
+ dump_rule_list (indent + 1, set[i].Rule, set[i].RuleCount);
+ printf (")");
+ }
+}
+
+static void
+dump_class_rule_list (int indent, OTF_ClassRule *rule, int count)
+{
+ int i, j;
+
+ IPRINT ("(ClassRuleCnt %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(ClassRule (%d)", i);
+ indent++;
+ IPRINT ("(GlyphCount %d)", rule[i].GlyphCount);
+ IPRINT ("(LookupCount %d)", rule[i].LookupCount);
+ IPRINT ("(Class");
+ for (j = 0; j < rule[i].GlyphCount - 1; j++)
+ printf (" %d", rule[i].Class[j]);
+ printf (")");
+ dump_lookup_record_list (indent, rule[i].LookupRecord,
+ rule[i].LookupCount);
+ printf (")");
+ indent--;
+ }
+}
+
+static void
+dump_class_set_list (int indent, OTF_ClassSet *set, int count)
+{
+ int i;
+
+ IPRINT ("(ClassSetCount %d)", count);
+ for (i = 0; i < count; i++)
+ if (set[i].offset)
+ {
+ IPRINT ("(ClassSet (%d)", i);
+ dump_class_rule_list (indent + 1, set[i].ClassRule,
+ set[i].ClassRuleCnt);
+ printf (")");
+ }
+}
+
+static void
+dump_chain_rule_list (int indent, OTF_ChainRule *rule, int count)
+{
+ int i;
+
+ IPRINT ("(ChainRuleCount %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(ChainRule (%d)", i);
+ dump_glyph_ids (indent + 1, "Backtrack",
+ rule[i].Backtrack, rule[i].BacktrackGlyphCount);
+ dump_glyph_ids (indent + 1, "Input",
+ rule[i].Input, rule[i].InputGlyphCount - 1);
+ dump_glyph_ids (indent + 1, "LookAhead",
+ rule[i].LookAhead, rule[i].LookaheadGlyphCount);
+ dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
+ rule[i].LookupCount);
+ printf (")");
+ }
+}
+
+static void
+dump_chain_rule_set_list (int indent, OTF_ChainRuleSet *set, int count)
+{
+ int i;
+
+ IPRINT ("(ChainRuleSetCount %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(ChainRuleSet (%d)", i);
+ dump_chain_rule_list (indent + 1,
+ set[i].ChainRule, set[i].ChainRuleCount);
+ printf (")");
+ }
+}
+
+static void
+dump_chain_class_rule_list (int indent, OTF_ChainClassRule *rule, int count)
+{
+ int i;
+
+ IPRINT ("(ChainClassRuleCount %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(ChainClassRule (%d)", i);
+ dump_glyph_ids (indent + 1, "Backtrack",
+ rule[i].Backtrack, rule[i].BacktrackGlyphCount);
+ dump_glyph_ids (indent + 1, "Input",
+ rule[i].Input, rule[i].InputGlyphCount - 1);
+ dump_glyph_ids (indent + 1, "LookAhead",
+ rule[i].LookAhead, rule[i].LookaheadGlyphCount);
+ dump_lookup_record_list (indent + 1, rule[i].LookupRecord,
+ rule[i].LookupCount);
+ printf (")");
+ }
+}
+
+static void
+dump_chain_class_set_list (int indent, OTF_ChainClassSet *set, int count)
+{
+ int i;
+
+ IPRINT ("(ChainClassSetCount %d)", count);
+ for (i = 0; i < count; i++)
+ {
+ IPRINT ("(ChainClassSet (%d)", i);
+ dump_chain_class_rule_list (indent + 1,
+ set[i].ChainClassRule,
+ set[i].ChainClassRuleCnt);
+ printf (")");
+ }
+}
\f
/* GSUB */
else if (subtable->Format == 2)
{
dump_coverage (indent, NULL, &subtable->Coverage);
- IPRINT ("(GlyphCount %d)",
- subtable->u.single2.GlyphCount);
- IPRINT ("(Substitute");
- dump_glyph_ids (subtable->u.single2.Substitute,
+ dump_glyph_ids (indent, "Substitute", subtable->u.single2.Substitute,
subtable->u.single2.GlyphCount);
- printf (")");
}
+ else
+ printf (" invalid");
break;
case 2:
subtable->u.multiple1.Sequence,
subtable->u.multiple1.SequenceCount);
}
+ else
+ printf (" invalid");
break;
+ case 3:
+ if (subtable->Format == 1)
+ {
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_alternate_set_list (indent, subtable->u.alternate1.AlternateSet,
+ subtable->u.alternate1.AlternateSetCount);
+ }
+ else
+ printf (" invalid");
+ break;
+
case 4:
if (subtable->Format == 1)
{
subtable->u.ligature1.LigatureSet,
subtable->u.ligature1.LigSetCount);
}
+ else
+ printf (" invalid");
+ break;
+
+ case 5:
+ if (subtable->Format == 1)
+ {
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_rule_set_list (indent, subtable->u.context1.SubRuleSet,
+ subtable->u.context1.SubRuleSetCount);
+ }
+ else if (subtable->Format == 2)
+ {
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
+ dump_class_set_list (indent, subtable->u.context2.SubClassSet,
+ subtable->u.context2.SubClassSetCnt);
+ }
+ else if (subtable->Format == 3)
+ {
+ dump_coverage_list (indent, "Coverage",
+ subtable->u.context3.Coverage,
+ subtable->u.context3.GlyphCount);
+ dump_lookup_record_list (indent,
+ subtable->u.context3.LookupRecord,
+ subtable->u.context3.SubstCount);
+ }
+ else
+ printf (" invalid");
break;
case 6:
if (subtable->Format == 1)
{
-#if 0
- read_coverage (fp, offset,
- &subtable->u.chain_context1.Coverage);
- subtable->u.chain_context1.ChainSubRuleSetCount
- = (read_chain_subrule_set
- (fp, offset,
- &subtable->u.chain_context1.ChainSubRuleSet));
-#endif
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_chain_rule_set_list
+ (indent,
+ subtable->u.chain_context1.ChainSubRuleSet,
+ subtable->u.chain_context1.ChainSubRuleSetCount);
}
else if (subtable->Format == 2)
{
-#if 0
- read_coverage (fp, offset,
- &subtable->u.chain_context2.Coverage);
- read_class_def (fp, offset,
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_class_def (indent, "BacktrackClassDef",
&subtable->u.chain_context2.Backtrack);
- read_class_def (fp, offset,
+ dump_class_def (indent, "InputClassDef",
&subtable->u.chain_context2.Input);
- read_class_def (fp, offset,
+ dump_class_def (indent, "LookaheadClassDef",
&subtable->u.chain_context2.LookAhead);
- subtable->u.chain_context2.ChainSubClassSetCnt
- = (read_chain_subclass_set
- (fp, offset,
- &subtable->u.chain_context2.ChainSubClassSet));
-#endif
+ dump_chain_class_set_list
+ (indent,
+ subtable->u.chain_context2.ChainSubClassSet,
+ subtable->u.chain_context2.ChainSubClassSetCnt);
}
else if (subtable->Format == 3)
{
subtable->u.chain_context3.Input,
subtable->u.chain_context3.InputGlyphCount);
dump_coverage_list
- (indent, "LookaheaGlyphCount",
+ (indent, "LookaheadGlyphCount",
subtable->u.chain_context3.LookAhead,
subtable->u.chain_context3.LookaheadGlyphCount);
- dump_subst_lookup_record_list
+ dump_lookup_record_list
(indent,
- subtable->u.chain_context3.SubstLookupRecord,
+ subtable->u.chain_context3.LookupRecord,
subtable->u.chain_context3.SubstCount);
}
+ else
+ printf (" invalid");
+ break;
+
+ case 7:
+ case 8:
+ printf (" not-yet-substcount");
break;
+
+ default:
+ printf (" invalid");
}
printf (")");
}
switch (type)
{
case 1:
-#if 0
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->u.single1.Coverage);
- IPRINT ("(DeltaGlyhpID #x%04X)",
- subtable->u.single1.DeltaGlyphID);
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ IPRINT ("(ValueFormat #x%04X)",
+ subtable->u.single1.ValueFormat);
+ dump_value_record (indent, "Value", &subtable->u.single1.Value);
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->u.single2.Coverage);
- IPRINT ("(GlyphCount %d)",
- subtable->u.single2.GlyphCount);
- IPRINT ("(Substitute");
- dump_glyph_ids (subtable->u.single2.Substitute,
- subtable->u.single2.GlyphCount);
- printf (")");
+ int i;
+
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ IPRINT ("(ValueFormat #x%04X)",
+ subtable->u.single2.ValueFormat);
+ IPRINT ("(ValueCount %d)",
+ subtable->u.single2.ValueCount);
+ for (i = 0; i < subtable->u.single2.ValueCount; i++)
+ dump_value_record (indent, "Value", &subtable->u.single2.Value[i]);
}
-#endif
+ else
+ printf (" invalid");
break;
case 2:
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->Coverage);
+ printf (" not-yet-supported");
}
else if (subtable->Format == 2)
{
subtable->u.pair2.Class2Count,
subtable->u.pair2.Class1Record);
}
+ else
+ printf (" invalid");
break;
+ case 3:
+ if (subtable->Format == 1)
+ {
+ printf (" not-yet-supported");
+ }
+ else
+ printf (" invalid");
+ break;
+
case 4:
if (subtable->Format == 1)
{
IPRINT ("(ClassCount %d)",
subtable->u.mark_base1.ClassCount);
dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
- dump_base_array (indent, subtable->u.mark_base1.ClassCount,
+ dump_anchor_array (indent, subtable->u.mark_base1.ClassCount,
&subtable->u.mark_base1.BaseArray);
}
break;
+ case 5:
+ if (subtable->Format == 1)
+ {
+ printf (" not-yet-supported");
+ }
+ else
+ printf (" invalid");
+ break;
+
case 6:
if (subtable->Format == 1)
{
-#if 0
- read_coverage (fp, offset,
- &subtable->u.chain_context1.Coverage);
- subtable->u.chain_context1.ChainSubRuleSetCount
- = (read_chain_subrule_set
- (fp, offset,
- &subtable->u.chain_context1.ChainSubRuleSet));
-#endif
+ dump_coverage (indent, "Mark1", &subtable->Coverage);
+ dump_coverage (indent, "Mark2",
+ &subtable->u.mark_mark1.Mark2Coverage);
+ IPRINT ("(ClassCount %d)",
+ subtable->u.mark_mark1.ClassCount);
+ dump_mark_array (indent, &subtable->u.mark_mark1.Mark1Array);
+ dump_anchor_array (indent, subtable->u.mark_mark1.ClassCount,
+ &subtable->u.mark_mark1.Mark2Array);
+ }
+ else
+ printf (" invalid");
+ break;
+
+ case 7:
+ if (subtable->Format == 1)
+ {
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_rule_set_list (indent, subtable->u.context1.PosRuleSet,
+ subtable->u.context1.PosRuleSetCount);
}
else if (subtable->Format == 2)
{
-#if 0
- read_coverage (fp, offset,
- &subtable->u.chain_context2.Coverage);
- read_class_def (fp, offset,
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_class_def (indent, NULL, &subtable->u.context2.ClassDef);
+ dump_class_set_list (indent, subtable->u.context2.PosClassSet,
+ subtable->u.context2.PosClassSetCnt);
+ }
+ else if (subtable->Format == 3)
+ {
+ dump_coverage_list (indent, "Coverage",
+ subtable->u.context3.Coverage,
+ subtable->u.context3.GlyphCount);
+ dump_lookup_record_list (indent,
+ subtable->u.context3.LookupRecord,
+ subtable->u.context3.PosCount);
+ }
+ else
+ printf (" invalid");
+ break;
+
+ case 8:
+ if (subtable->Format == 1)
+ {
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_chain_rule_set_list
+ (indent,
+ subtable->u.chain_context1.ChainPosRuleSet,
+ subtable->u.chain_context1.ChainPosRuleSetCount);
+ }
+ else if (subtable->Format == 2)
+ {
+ dump_coverage (indent, NULL, &subtable->Coverage);
+ dump_class_def (indent, "BacktrackClassDef",
&subtable->u.chain_context2.Backtrack);
- read_class_def (fp, offset,
+ dump_class_def (indent, "InputClassDef",
&subtable->u.chain_context2.Input);
- read_class_def (fp, offset,
+ dump_class_def (indent, "LookaheadClassDef",
&subtable->u.chain_context2.LookAhead);
- subtable->u.chain_context2.ChainSubClassSetCnt
- = (read_chain_subclass_set
- (fp, offset,
- &subtable->u.chain_context2.ChainSubClassSet));
-#endif
+ dump_chain_class_set_list
+ (indent,
+ subtable->u.chain_context2.ChainPosClassSet,
+ subtable->u.chain_context2.ChainPosClassSetCnt);
}
else if (subtable->Format == 3)
{
-#if 0
dump_coverage_list
(indent, "BackTrackGlyphCount",
subtable->u.chain_context3.Backtrack,
(indent, "LookaheaGlyphCount",
subtable->u.chain_context3.LookAhead,
subtable->u.chain_context3.LookaheadGlyphCount);
- dump_subst_lookup_record_list
+ dump_lookup_record_list
(indent,
- subtable->u.chain_context3.SubstLookupRecord,
- subtable->u.chain_context3.SubstCount);
-#endif
+ subtable->u.chain_context3.LookupRecord,
+ subtable->u.chain_context3.PosCount);
}
+ else
+ printf (" invalid");
break;
}
printf (")");
}
+/* Read Glyph-IDs from STREAM. Allocate memory for IDS, and store the
+ Glyph-IDs there. If COUNT is negative, read the number of
+ Glyphs-IDs at first. MINUS if nozero is how few the actual
+ Glyph-IDs are in STREAM than COUNT. */
+
static int
-read_glyph_ids (OTF *otf, OTF_Stream *stream, OTF_GlyphID **ids, int minus)
+read_glyph_ids (OTF *otf, OTF_Stream *stream, OTF_GlyphID **ids,
+ int minus, int count)
{
char *errfmt = "GlyphID List%s";
int errret = -1;
- unsigned count;
int i;
- READ_UINT16 (stream, count);
+ if (count < 0)
+ READ_UINT16 (stream, count);
if (! count)
return 0;
OTF_MALLOC (*ids, count, "");
for (i = 0; i < count + minus; i++)
READ_GLYPHID (stream, (*ids)[i]);
- return (int) count;
+ return count;
}
static unsigned
SEEK_STREAM (stream, offset + coverage->offset);
READ_UINT16 (stream, coverage->CoverageFormat);
if (coverage->CoverageFormat == 1)
- count = read_glyph_ids (otf, stream, &coverage->table.GlyphArray, 0);
+ count = read_glyph_ids (otf, stream, &coverage->table.GlyphArray, 0, -1);
else if (coverage->CoverageFormat == 2)
count = read_range_records (otf, stream, &coverage->table.RangeRecord);
else
return 0;
}
+/* Read list of Coverages from STREAM. Allocate memory for COVERAGE,
+ and store the Coverages there. If COUNT is negative, read the
+ number of Coverages at first. */
+
static int
read_coverage_list (OTF *otf, OTF_Stream *stream, long offset,
- OTF_Coverage **coverage)
+ OTF_Coverage **coverage, int count)
{
char *errfmt = "Coverage List%s";
int errret = -1;
- int count;
int i;
- READ_UINT16 (stream, count);
+ if (count < 0)
+ READ_UINT16 (stream, count);
if (! count)
return 0;
OTF_MALLOC (*coverage, count, "");
READ_GLYPHID (stream, class->f.f1.StartGlyph);
class->f.f1.GlyphCount
= (read_glyph_ids
- (otf, stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0));
+ (otf, stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0, -1));
if (! class->f.f1.GlyphCount)
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
}
OTF_StreamState state;
READ_OFFSET (stream, class->offset);
+ if (! class->offset)
+ return 0;
SAVE_STREAM (stream, state);
SEEK_STREAM (stream, offset + class->offset);
READ_UINT16 (stream, class->ClassFormat);
{
READ_GLYPHID (stream, class->f.f1.StartGlyph);
class->f.f1.GlyphCount
- = (read_glyph_ids
- (otf, stream, (OTF_GlyphID **) &class->f.f1.ClassValueArray, 0));
+ = read_glyph_ids (otf, stream,
+ (OTF_GlyphID **) &class->f.f1.ClassValueArray,
+ 0, -1);
if (! class->f.f1.GlyphCount)
return -1;
}
else if (class->ClassFormat == 2)
{
class->f.f2.ClassRangeCount
- = (read_range_records
- (otf, stream, (OTF_RangeRecord **) &class->f.f2.ClassRangeRecord));
+ = read_range_records (otf, stream,
+ (OTF_RangeRecord **)
+ &class->f.f2.ClassRangeRecord);
if (! class->f.f2.ClassRangeCount)
return -1;
}
return 0;
}
-\f
-/* GSUB */
-
-static void *
-read_gsub_table (OTF *otf, OTF_Stream *stream)
+static unsigned
+read_lookup_record_list (OTF *otf, OTF_Stream *stream,
+ OTF_LookupRecord **record, int count)
{
- char *errfmt = "GSUB%s";
- void *errret = NULL;
- OTF_GSUB *gsub;
+ char *errfmt = "LookupRecord%s";
+ unsigned errret = 0;
+ int i;
- OTF_CALLOC (gsub, 1, "");
- READ_FIXED (stream, gsub->Version);
- READ_OFFSET (stream, gsub->ScriptList.offset);
- READ_OFFSET (stream, gsub->FeatureList.offset);
- READ_OFFSET (stream, gsub->LookupList.offset);
-
- if (read_script_list (otf, stream, gsub->ScriptList.offset,
- &gsub->ScriptList) < 0
- || read_feature_list (otf, stream, gsub->FeatureList.offset,
- &gsub->FeatureList) < 0
- || read_lookup_list (otf, stream, gsub->LookupList.offset,
- &gsub->LookupList, 1) < 0)
- return NULL;
- return gsub;
+ if (count < 0)
+ READ_UINT16 (stream, count);
+ if (! count)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ OTF_MALLOC (*record, count, "");
+ for (i = 0; i < count; i++)
+ {
+ READ_UINT16 (stream, (*record)[i].SequenceIndex);
+ READ_UINT16 (stream, (*record)[i].LookupListIndex);
+ }
+ return count;
}
static unsigned
-read_sequence (OTF *otf, OTF_Stream *stream, long offset, OTF_Sequence **seq)
+read_rule_list (OTF *otf, OTF_Stream *stream, long offset, OTF_Rule **rule)
{
- char *errfmt = "Sequence%s";
+ char *errfmt = "List of Rule%s";
unsigned errret = 0;
+ OTF_StreamState state;
unsigned count;
int i;
READ_UINT16 (stream, count);
- OTF_MALLOC (*seq, count, "");
if (! count)
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ OTF_MALLOC (*rule, count, "");
for (i = 0; i < count; i++)
- READ_OFFSET (stream, (*seq)[i].offset);
+ {
+ READ_OFFSET (stream, (*rule)[i].offset);
+ if (! (*rule)[i].offset)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero offset)");
+ }
+ SAVE_STREAM (stream, state);
for (i = 0; i < count; i++)
{
- SEEK_STREAM (stream, offset + (*seq)[i].offset);
- (*seq)[i].GlyphCount = read_glyph_ids (otf, stream,
- &(*seq)[i].Substitute, 0);
- if (! (*seq)[i].GlyphCount)
- return 0;
+ SEEK_STREAM (stream, offset + (*rule)[i].offset);
+ READ_UINT16 (stream, (*rule)[i].GlyphCount);
+ if ((*rule)[i].GlyphCount == 0)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ READ_UINT16 (stream, (*rule)[i].LookupCount);
+ if (read_glyph_ids (otf, stream, &(*rule)[i].Input, 0,
+ (*rule)[i].GlyphCount) < 0)
+ return errret;
+ if (read_lookup_record_list (otf, stream, &(*rule)[i].LookupRecord,
+ (*rule)[i].LookupCount) == 0)
+ return errret;
}
+ RESTORE_STREAM (stream, state);
return count;
}
-static int
-read_ligature (OTF *otf, OTF_Stream *stream, long offset,
- OTF_Ligature **ligature)
+
+static unsigned
+read_rule_set_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_RuleSet **set)
{
- char *errfmt = "Ligature%s";
- int errret = -1;
- int count;
+ char *errfmt = "List of RuleSet%s";
+ unsigned errret = 0;
+ OTF_StreamState state;
+ unsigned count;
int i;
READ_UINT16 (stream, count);
if (! count)
- return 0;
- OTF_MALLOC (*ligature, count, "");
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ OTF_MALLOC (*set, count, "");
for (i = 0; i < count; i++)
- READ_OFFSET (stream, (*ligature)[i].offset);
+ {
+ READ_OFFSET (stream, (*set)[i].offset);
+ if (! (*set)[i].offset)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero offset)");
+ }
+ SAVE_STREAM (stream, state);
for (i = 0; i < count; i++)
{
- SEEK_STREAM (stream, offset + (*ligature)[i].offset);
- READ_GLYPHID (stream, (*ligature)[i].LigGlyph);
- (*ligature)[i].CompCount
- = read_glyph_ids (otf, stream, &(*ligature)[i].Component, -1);
- if (! (*ligature)[i].CompCount)
- return -1;
+ SEEK_STREAM (stream, offset + (*set)[i].offset);
+ (*set)[i].RuleCount
+ = read_rule_list (otf, stream, offset + (*set)[i].offset,
+ &(*set)[i].Rule);
+ if (! (*set)[i].RuleCount)
+ return errret;
}
+ RESTORE_STREAM (stream, state);
return count;
}
-static int
-read_ligature_set (OTF *otf, OTF_Stream *stream, long offset,
- OTF_LigatureSet **ligset)
+static unsigned
+read_class_rule_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_ClassRule **rule)
{
- char *errfmt = "LigatureSet%s";
- int errret = -1;
- int count;
+ char *errfmt = "ClassRule%s";
+ unsigned errret = 0;
+ OTF_StreamState state;
+ unsigned count;
int i;
READ_UINT16 (stream, count);
if (! count)
- return 0;
- OTF_MALLOC (*ligset, count, "");
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ OTF_MALLOC (*rule, count, "");
for (i = 0; i < count; i++)
- READ_OFFSET (stream, (*ligset)[i].offset);
+ {
+ READ_OFFSET (stream, (*rule)[i].offset);
+ if (! (*rule)[i].offset)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero offset)");
+ }
+ SAVE_STREAM (stream, state);
for (i = 0; i < count; i++)
{
- int lig_count;
-
- SEEK_STREAM (stream, offset + (*ligset)[i].offset);
- lig_count = read_ligature (otf, stream, offset + (*ligset)[i].offset,
- &(*ligset)[i].Ligature);
- if (lig_count < 0)
- return -1;
- (*ligset)[i].LigatureCount = (unsigned) lig_count;
+ SEEK_STREAM (stream, offset + (*rule)[i].offset);
+ READ_USHORT (stream, (*rule)[i].GlyphCount);
+ if (! (*rule)[i].GlyphCount)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ READ_USHORT (stream, (*rule)[i].LookupCount);
+ if (read_glyph_ids (otf, stream, (OTF_GlyphID **) &(*rule)[i].Class,
+ 0, (*rule)[i].GlyphCount - 1) < 0)
+ return errret;
+ if (read_lookup_record_list (otf, stream, &(*rule)[i].LookupRecord,
+ (*rule)[i].LookupCount) == 0)
+ return errret;
}
+ RESTORE_STREAM (stream, state);
return count;
}
static unsigned
-read_subst_lookup_record (OTF *otf, OTF_Stream *stream,
- OTF_SubstLookupRecord **record)
+read_class_set_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_ClassSet **set)
{
- char *errfmt = "SubstLookupRecord%s";
+ char *errfmt = "ClassSet%s";
unsigned errret = 0;
+ OTF_StreamState state;
unsigned count;
int i;
READ_UINT16 (stream, count);
if (! count)
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
- OTF_MALLOC (*record, count, "");
+ OTF_MALLOC (*set, count, "");
for (i = 0; i < count; i++)
- {
- READ_UINT16 (stream, (*record)[i].SequenceIndex);
- READ_UINT16 (stream, (*record)[i].LookupListIndex);
- }
+ /* Offset can be zero. */
+ READ_OFFSET (stream, (*set)[i].offset);
+ SAVE_STREAM (stream, state);
+ for (i = 0; i < count; i++)
+ if ((*set)[i].offset)
+ {
+ SEEK_STREAM (stream, offset + (*set)[i].offset);
+ (*set)[i].ClassRuleCnt
+ = read_class_rule_list (otf, stream, offset + (*set)[i].offset,
+ &(*set)[i].ClassRule);
+ if (! (*set)[i].ClassRuleCnt)
+ return errret;
+ }
+ RESTORE_STREAM (stream, state);
return count;
}
static unsigned
-read_chain_subrule (OTF *otf, OTF_Stream *stream, long offset,
- OTF_ChainSubRule **rule)
+read_chain_rule_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_ChainRule **rule)
{
- char *errfmt = "ChainSubRule%s";
+ char *errfmt = "ChainRule%s";
unsigned errret = 0;
unsigned count;
int i;
{
SEEK_STREAM (stream, offset + (*rule)[i].offset);
(*rule)[i].BacktrackGlyphCount
- = read_glyph_ids (otf, stream, &(*rule)[i].Backtrack, 0);
- if (! (*rule)[i].BacktrackGlyphCount)
- return 0;
+ = read_glyph_ids (otf, stream, &(*rule)[i].Backtrack, 0, -1);
(*rule)[i].InputGlyphCount
- = read_glyph_ids (otf, stream, &(*rule)[i].Input, -1);
+ = read_glyph_ids (otf, stream, &(*rule)[i].Input, -1, -1);
if (! (*rule)[i].InputGlyphCount)
- return 0;
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
(*rule)[i].LookaheadGlyphCount
- = read_glyph_ids (otf, stream, &(*rule)[i].LookAhead, 0);
- if (! (*rule)[i].LookaheadGlyphCount)
- return 0;
- (*rule)[i].SubstCount
- = read_subst_lookup_record (otf, stream, &(*rule)[i].SubstLookupRecord);
- if (! (*rule)[i].SubstCount)
- return 0;
+ = read_glyph_ids (otf, stream, &(*rule)[i].LookAhead, 0, -1);
+ (*rule)[i].LookupCount
+ = read_lookup_record_list (otf, stream,
+ &(*rule)[i].LookupRecord, -1);
+ if (! (*rule)[i].LookupCount)
+ return errret;
}
return count;
}
static unsigned
-read_chain_subrule_set (OTF *otf, OTF_Stream *stream, long offset,
- OTF_ChainSubRuleSet **set)
+read_chain_rule_set_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_ChainRuleSet **set)
{
- char *errfmt = "ChainSubRuleSet%s";
+ char *errfmt = "ChainRuleSet%s";
unsigned errret = 0;
+ OTF_StreamState state;
unsigned count;
int i;
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
OTF_MALLOC (*set, count, "");
for (i = 0; i < count; i++)
- READ_OFFSET (stream, (*set)[i].offset);
+ {
+ READ_OFFSET (stream, (*set)[i].offset);
+ if (! (*set)[i].offset)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero offset)");
+ }
+ SAVE_STREAM (stream, state);
for (i = 0; i < count; i++)
{
SEEK_STREAM (stream, offset + (*set)[i].offset);
- (*set)[i].ChainSubRuleCount
- = read_chain_subrule (otf, stream, offset + (*set)[i].offset,
- &(*set)[i].ChainSubRule);
- if (! (*set)[i].ChainSubRuleCount)
- return 0;
+ (*set)[i].ChainRuleCount
+ = read_chain_rule_list (otf, stream, offset + (*set)[i].offset,
+ &(*set)[i].ChainRule);
+ if (! (*set)[i].ChainRuleCount)
+ return errret;
}
+ RESTORE_STREAM (stream, state);
return count;
}
static unsigned
-read_chain_subclass_rule (OTF *otf, OTF_Stream *stream, long offset,
- OTF_ChainSubClassRule **rule)
+read_chain_class_rule_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_ChainClassRule **rule)
{
- char *errfmt = "ChainSubClassRule%s";
+ char *errfmt = "ChainClassRule%s";
unsigned errret = 0;
unsigned count;
int i;
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
OTF_MALLOC (*rule, count, "");
for (i = 0; i < count; i++)
- READ_OFFSET (stream, (*rule)[i].offset);
+ {
+ READ_OFFSET (stream, (*rule)[i].offset);
+ if (! (*rule)[i].offset)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero offset)");
+ }
for (i = 0; i < count; i++)
{
SEEK_STREAM (stream, offset + (*rule)[i].offset);
(*rule)[i].BacktrackGlyphCount
= read_glyph_ids (otf, stream,
- (OTF_GlyphID **) &(*rule)[i].Backtrack, 0);
- if (! (*rule)[i].BacktrackGlyphCount)
- return 0;
+ (OTF_GlyphID **) &(*rule)[i].Backtrack, 0, -1);
(*rule)[i].InputGlyphCount
- = read_glyph_ids (otf, stream, (OTF_GlyphID **) &(*rule)[i].Input, -1);
+ = read_glyph_ids (otf, stream,
+ (OTF_GlyphID **) &(*rule)[i].Input, -1, -1);
if (! (*rule)[i].InputGlyphCount)
- return 0;
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
(*rule)[i].LookaheadGlyphCount
- = read_glyph_ids (otf, stream, (OTF_GlyphID **) &(*rule)[i].LookAhead, 0);
- if (! (*rule)[i].LookaheadGlyphCount)
- return 0;
- (*rule)[i].SubstCount
- = read_subst_lookup_record (otf, stream, &(*rule)[i].SubstLookupRecord);
- if (! (*rule)[i].SubstCount)
- return 0;
+ = read_glyph_ids (otf, stream,
+ (OTF_GlyphID **) &(*rule)[i].LookAhead, 0, -1);
+ (*rule)[i].LookupCount
+ = read_lookup_record_list (otf, stream,
+ &(*rule)[i].LookupRecord, -1);
+ if (! (*rule)[i].LookupCount)
+ return errret;
}
return count;
}
static unsigned
-read_chain_subclass_set (OTF *otf, OTF_Stream *stream, long offset,
- OTF_ChainSubClassSet **set)
+read_chain_class_set_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_ChainClassSet **set)
{
- char *errfmt = "ChainSubClassSet%s";
+ char *errfmt = "ChainClassSet%s";
unsigned errret = 0;
+ OTF_StreamState state;
unsigned count;
int i;
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
OTF_MALLOC (*set, count, "");
for (i = 0; i < count; i++)
+ /* Offset may be zero. */
READ_OFFSET (stream, (*set)[i].offset);
+ SAVE_STREAM (stream, state);
+ for (i = 0; i < count; i++)
+ if ((*set)[i].offset)
+ {
+ SEEK_STREAM (stream, offset + (*set)[i].offset);
+ (*set)[i].ChainClassRuleCnt
+ = read_chain_class_rule_list (otf, stream, offset + (*set)[i].offset,
+ &(*set)[i].ChainClassRule);
+ if (! (*set)[i].ChainClassRuleCnt)
+ return errret;
+ }
+ RESTORE_STREAM (stream, state);
+ return count;
+}
+
+\f
+/* GSUB */
+
+static void *
+read_gsub_table (OTF *otf, OTF_Stream *stream)
+{
+ char *errfmt = "GSUB%s";
+ void *errret = NULL;
+ OTF_GSUB *gsub;
+
+ OTF_CALLOC (gsub, 1, "");
+ READ_FIXED (stream, gsub->Version);
+ READ_OFFSET (stream, gsub->ScriptList.offset);
+ READ_OFFSET (stream, gsub->FeatureList.offset);
+ READ_OFFSET (stream, gsub->LookupList.offset);
+
+ if (read_script_list (otf, stream, gsub->ScriptList.offset,
+ &gsub->ScriptList) < 0
+ || read_feature_list (otf, stream, gsub->FeatureList.offset,
+ &gsub->FeatureList) < 0
+ || read_lookup_list (otf, stream, gsub->LookupList.offset,
+ &gsub->LookupList, 1) < 0)
+ return NULL;
+ return gsub;
+}
+
+static unsigned
+read_sequence (OTF *otf, OTF_Stream *stream, long offset, OTF_Sequence **seq)
+{
+ char *errfmt = "Sequence%s";
+ unsigned errret = 0;
+ unsigned count;
+ int i;
+
+ READ_UINT16 (stream, count);
+ if (! count)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ OTF_MALLOC (*seq, count, "");
+ for (i = 0; i < count; i++)
+ READ_OFFSET (stream, (*seq)[i].offset);
for (i = 0; i < count; i++)
{
- SEEK_STREAM (stream, offset + (*set)[i].offset);
- (*set)[i].ChainSubClassRuleCnt
- = read_chain_subclass_rule (otf, stream, offset + (*set)[i].offset,
- &(*set)[i].ChainSubClassRule);
- if (! (*set)[i].ChainSubClassRuleCnt)
+ SEEK_STREAM (stream, offset + (*seq)[i].offset);
+ (*seq)[i].GlyphCount = read_glyph_ids (otf, stream,
+ &(*seq)[i].Substitute, 0, -1);
+ if (! (*seq)[i].GlyphCount)
return 0;
}
return count;
}
+static int
+read_ligature (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_Ligature **ligature)
+{
+ char *errfmt = "Ligature%s";
+ int errret = -1;
+ int count;
+ int i;
+
+ READ_UINT16 (stream, count);
+ if (! count)
+ return 0;
+ OTF_MALLOC (*ligature, count, "");
+ for (i = 0; i < count; i++)
+ READ_OFFSET (stream, (*ligature)[i].offset);
+ for (i = 0; i < count; i++)
+ {
+ SEEK_STREAM (stream, offset + (*ligature)[i].offset);
+ READ_GLYPHID (stream, (*ligature)[i].LigGlyph);
+ (*ligature)[i].CompCount
+ = read_glyph_ids (otf, stream, &(*ligature)[i].Component, -1, -1);
+ if (! (*ligature)[i].CompCount)
+ return -1;
+ }
+ return count;
+}
+
+static unsigned
+read_ligature_set_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_LigatureSet **ligset)
+{
+ char *errfmt = "LigatureSet%s";
+ int errret = 0;
+ int count;
+ int i;
+
+ READ_UINT16 (stream, count);
+ if (! count)
+ return errret;
+ OTF_MALLOC (*ligset, count, "");
+ for (i = 0; i < count; i++)
+ READ_OFFSET (stream, (*ligset)[i].offset);
+ for (i = 0; i < count; i++)
+ {
+ int lig_count;
+
+ SEEK_STREAM (stream, offset + (*ligset)[i].offset);
+ lig_count = read_ligature (otf, stream, offset + (*ligset)[i].offset,
+ &(*ligset)[i].Ligature);
+ if (lig_count < 0)
+ return errret;
+ (*ligset)[i].LigatureCount = (unsigned) lig_count;
+ }
+ return count;
+}
+
+static unsigned
+read_alternate_set_list (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_AlternateSet **altset)
+{
+ char *errfmt = "AlternateSet%s";
+ int errret = -1;
+ unsigned count;
+ int i;
+
+ READ_UINT16 (stream, count);
+ if (! count)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ OTF_MALLOC (*altset, count, "");
+ for (i = 0; i < count; i++)
+ READ_OFFSET (stream, (*altset)[i].offset);
+ for (i = 0; i < count; i++)
+ {
+ int alt_count;
+
+ SEEK_STREAM (stream, offset + (*altset)[i].offset);
+ alt_count = read_glyph_ids (otf, stream, &(*altset)[i].Alternate, 0, -1);
+ if (alt_count < 0)
+ return errret;
+ (*altset)[i].GlyphCount = (unsigned) alt_count;
+ }
+ return count;
+}
static int
read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
unsigned type, OTF_LookupSubTableGSUB *subtable)
{
- char *errfmt = "GSUB LookupSubTable%s";
+ char errfmt[256];
int errret = -1;
int count;
SEEK_STREAM (stream, offset);
READ_UINT16 (stream, subtable->Format);
+ sprintf (errfmt, "GSUB Lookup %d-%d%%s", type, subtable->Format);
switch (type)
{
case 1:
return -1;
subtable->u.single2.GlyphCount
= read_glyph_ids (otf, stream, &subtable->u.single2.Substitute,
- 0);
+ 0, -1);
if (! subtable->u.single2.GlyphCount)
return -1;
}
break;
case 3:
+ if (subtable->Format == 1)
+ {
+ if (read_coverage (otf, stream, offset, &subtable->Coverage) < 0)
+ return -1;
+ subtable->u.alternate1.AlternateSetCount
+ = read_alternate_set_list (otf, stream, offset,
+ &subtable->u.alternate1.AlternateSet);
+ if (! subtable->u.alternate1.AlternateSetCount)
+ return -1;
+ }
+ else
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
case 4:
if (subtable->Format == 1)
{
- read_coverage (otf, stream, offset, &subtable->Coverage);
- count = (read_ligature_set
- (otf, stream, offset,
- &subtable->u.ligature1.LigatureSet));
- if (count < 0)
+ if (read_coverage (otf, stream, offset, &subtable->Coverage) < 0)
+ return -1;
+ subtable->u.ligature1.LigSetCount
+ = read_ligature_set_list (otf, stream, offset,
+ &subtable->u.ligature1.LigatureSet);
+ if (! subtable->u.ligature1.LigSetCount)
return -1;
- subtable->u.ligature1.LigSetCount = (unsigned) count;
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
+ case 5:
+ if (subtable->Format == 1)
+ {
+ OTF_GSUB_Context1 *context1 = &subtable->u.context1;
+
+ read_coverage (otf, stream, offset, &subtable->Coverage);
+ context1->SubRuleSetCount
+ = read_rule_set_list (otf, stream, offset, &context1->SubRuleSet);
+ }
+ else if (subtable->Format == 2)
+ {
+ OTF_GSUB_Context2 *context2 = &subtable->u.context2;
+
+ read_coverage (otf, stream, offset, &subtable->Coverage);
+ read_class_def (otf, stream, offset, &context2->ClassDef);
+ context2->SubClassSetCnt
+ = read_class_set_list (otf, stream, offset, &context2->SubClassSet);
+ }
+ else if (subtable->Format == 3)
+ {
+ OTF_GSUB_Context3 *context3 = &subtable->u.context3;
+
+ READ_USHORT (stream, context3->GlyphCount);
+ if (context3->GlyphCount < 0)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ READ_USHORT (stream, context3->SubstCount);
+ if (read_coverage_list (otf, stream, offset,
+ &context3->Coverage,
+ context3->GlyphCount) < 0)
+ return -1;
+ if (read_lookup_record_list (otf, stream,
+ &context3->LookupRecord,
+ context3->SubstCount) < 0)
+ return -1;
+ }
+ else
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
+ break;
+
case 6:
if (subtable->Format == 1)
{
+ OTF_GSUB_ChainContext1 *chain_context1 = &subtable->u.chain_context1;
+
read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->u.chain_context1.ChainSubRuleSetCount
- = (read_chain_subrule_set
- (otf, stream, offset,
- &subtable->u.chain_context1.ChainSubRuleSet));
+ chain_context1->ChainSubRuleSetCount
+ = read_chain_rule_set_list (otf, stream, offset,
+ &chain_context1->ChainSubRuleSet);
}
else if (subtable->Format == 2)
{
+ OTF_GSUB_ChainContext2 *chain_context2 = &subtable->u.chain_context2;
+
read_coverage (otf, stream, offset, &subtable->Coverage);
- read_class_def (otf, stream, offset,
- &subtable->u.chain_context2.Backtrack);
- read_class_def (otf, stream, offset,
- &subtable->u.chain_context2.Input);
- read_class_def (otf, stream, offset,
- &subtable->u.chain_context2.LookAhead);
- subtable->u.chain_context2.ChainSubClassSetCnt
- = (read_chain_subclass_set
- (otf, stream, offset,
- &subtable->u.chain_context2.ChainSubClassSet));
+ read_class_def (otf, stream, offset, &chain_context2->Backtrack);
+ read_class_def (otf, stream, offset, &chain_context2->Input);
+ read_class_def (otf, stream, offset, &chain_context2->LookAhead);
+ chain_context2->ChainSubClassSetCnt
+ = read_chain_class_set_list (otf, stream, offset,
+ &chain_context2->ChainSubClassSet);
}
else if (subtable->Format == 3)
{
- count = (read_coverage_list
- (otf, stream, offset,
- &subtable->u.chain_context3.Backtrack));
+ OTF_GSUB_ChainContext3 *chain_context3 = &subtable->u.chain_context3;
+
+ count = read_coverage_list (otf, stream, offset,
+ &chain_context3->Backtrack, -1);
if (count < 0)
return -1;
- subtable->u.chain_context3.BacktrackGlyphCount
- = (unsigned) count;
- count = (read_coverage_list
- (otf, stream, offset,
- &subtable->u.chain_context3.Input));
+ chain_context3->BacktrackGlyphCount = (unsigned) count;
+ count = read_coverage_list (otf, stream, offset,
+ &chain_context3->Input, -1);
if (count <= 0)
return -1;
- subtable->u.chain_context3.InputGlyphCount
- = (unsigned) count;
- subtable->Coverage = subtable->u.chain_context3.Input[0];
- count = (read_coverage_list
- (otf, stream, offset,
- &subtable->u.chain_context3.LookAhead));
- subtable->u.chain_context3.LookaheadGlyphCount
- = (unsigned) count;
- subtable->u.chain_context3.SubstCount
- = (read_subst_lookup_record
- (otf, stream,
- &subtable->u.chain_context3.SubstLookupRecord));
+ chain_context3->InputGlyphCount = (unsigned) count;
+ subtable->Coverage = chain_context3->Input[0];
+ count = read_coverage_list (otf, stream, offset,
+ &chain_context3->LookAhead, -1);
+ chain_context3->LookaheadGlyphCount = (unsigned) count;
+ chain_context3->SubstCount
+ = read_lookup_record_list (otf, stream,
+ &chain_context3->LookupRecord, -1);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
+ case 7:
+ case 8:
+ OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
+ break;
default:
- OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
}
return 0;
}
}
static int
-read_base_array (OTF *otf, OTF_Stream *stream, long offset,
- unsigned ClassCount, OTF_BaseArray *array)
+read_anchor_array (OTF *otf, OTF_Stream *stream, long offset,
+ unsigned ClassCount, OTF_AnchorArray *array)
{
- char *errfmt = "BaseArray%s";
+ char *errfmt = "AnchorArray%s";
int errret = -1;
OTF_StreamState state;
int i, j;
READ_OFFSET (stream, array->offset);
SAVE_STREAM (stream, state);
SEEK_STREAM (stream, offset + array->offset);
- READ_UINT16 (stream, array->BaseCount);
- OTF_MALLOC (array->BaseRecord, array->BaseCount, "");
- for (i = 0; i < array->BaseCount; i++)
+ READ_UINT16 (stream, array->Count);
+ OTF_MALLOC (array->AnchorRecord, array->Count, "");
+ for (i = 0; i < array->Count; i++)
{
- OTF_MALLOC (array->BaseRecord[i].BaseAnchor, ClassCount,
- " (BaseRecord)");
+ OTF_MALLOC (array->AnchorRecord[i].Anchor, ClassCount,
+ " (AnchorRecord)");
for (j = 0; j < ClassCount; j++)
- READ_OFFSET (stream, array->BaseRecord[i].BaseAnchor[j].offset);
+ READ_OFFSET (stream, array->AnchorRecord[i].Anchor[j].offset);
}
- for (i = 0; i < array->BaseCount; i++)
+ for (i = 0; i < array->Count; i++)
for (j = 0; j < ClassCount; j++)
if (read_anchor (otf, stream, offset + array->offset,
- &array->BaseRecord[i].BaseAnchor[j]) < 0)
+ &array->AnchorRecord[i].Anchor[j]) < 0)
return -1;
RESTORE_STREAM (stream, state);
return 0;
return rec;
}
-
static int
read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream,
long offset, unsigned type,
OTF_LookupSubTableGPOS *subtable)
{
- char *errfmt = "GPOS LookupSubTable%s";
+ char errfmt[256];
int errret = -1;
+ int count;
SEEK_STREAM (stream, offset);
READ_UINT16 (stream, subtable->Format);
+ sprintf (errfmt, "GPOS Lookup %d-%d%%s", type, subtable->Format);
switch (type)
{
case 1:
-#if 0
if (subtable->Format == 1)
{
- read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->u.single1.DeltaGlyphID = READ_INT16 (stream);
+ READ_UINT16 (stream, subtable->u.single1.ValueFormat);
+ read_value_record (otf, stream, offset,
+ subtable->u.single1.ValueFormat,
+ &subtable->u.single1.Value);
}
else if (subtable->Format == 2)
{
- read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->u.single2.GlyphCount
- = read_glyph_ids (otf, stream,
- &subtable->u.single2.Substitute, 0);
+ OTF_GPOS_Single2 *single2 = &subtable->u.single2;
+ int i;
+
+ READ_UINT16 (stream, single2->ValueFormat);
+ READ_UINT16 (stream, single2->ValueCount);
+ OTF_CALLOC (single2->Value, single2->ValueCount," (ValueRecord)");
+ for (i = 0; i < single2->ValueCount; i++)
+ read_value_record (otf, stream, offset, single2->ValueFormat,
+ single2->Value + i);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
-#endif
break;
case 2:
if (subtable->Format == 1)
{
- read_coverage (otf, stream, offset, &subtable->Coverage);
+ OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
}
else if (subtable->Format == 2)
{
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
+ case 3:
+ OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
+ break;
+
case 4:
if (subtable->Format == 1)
{
READ_UINT16 (stream, subtable->u.mark_base1.ClassCount);
read_mark_array (otf, stream, offset,
&subtable->u.mark_base1.MarkArray);
- read_base_array (otf, stream, offset,
- subtable->u.mark_base1.ClassCount,
- &subtable->u.mark_base1.BaseArray);
+ read_anchor_array (otf, stream, offset,
+ subtable->u.mark_base1.ClassCount,
+ &subtable->u.mark_base1.BaseArray);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
+ case 5:
+ OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
+ break;
+
case 6:
-#if 0
if (subtable->Format == 1)
{
+ read_coverage (otf, stream, offset, &subtable->Coverage);
read_coverage (otf, stream, offset,
- &subtable->u.chain_context1.Coverage);
- subtable->u.chain_context1.ChainSubRuleSetCount
- = (read_chain_subrule_set
- (otf, stream, offset,
- &subtable->u.chain_context1.ChainSubRuleSet));
+ &subtable->u.mark_mark1.Mark2Coverage);
+ READ_UINT16 (stream, subtable->u.mark_base1.ClassCount);
+ read_mark_array (otf, stream, offset,
+ &subtable->u.mark_mark1.Mark1Array);
+ read_anchor_array (otf, stream, offset,
+ subtable->u.mark_mark1.ClassCount,
+ &subtable->u.mark_mark1.Mark2Array);
+ }
+ else
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
+ break;
+
+ case 7:
+ if (subtable->Format == 1)
+ {
+ OTF_GPOS_Context1 *context1 = &subtable->u.context1;
+
+ read_coverage (otf, stream, offset, &subtable->Coverage);
+ context1->PosRuleSetCount
+ = read_rule_set_list (otf, stream, offset, &context1->PosRuleSet);
}
else if (subtable->Format == 2)
{
- read_coverage (otf, stream, offset,
- &subtable->u.chain_context2.Coverage);
- read_class_def (otf, stream, offset,
- &subtable->u.chain_context2.Backtrack);
- read_class_def (otf, stream, offset,
- &subtable->u.chain_context2.Input);
- read_class_def (otf, stream, offset,
- &subtable->u.chain_context2.LookAhead);
- subtable->u.chain_context2.ChainSubClassSetCnt
- = (read_chain_subclass_set
- (otf, stream, offset,
- &subtable->u.chain_context2.ChainSubClassSet));
+ OTF_GPOS_Context2 *context2 = &subtable->u.context2;
+
+ read_coverage (otf, stream, offset, &subtable->Coverage);
+ read_class_def (otf, stream, offset, &context2->ClassDef);
+ context2->PosClassSetCnt
+ = read_class_set_list (otf, stream, offset, &context2->PosClassSet);
+
+ }
+ else if (subtable->Format == 3)
+ {
+ OTF_GPOS_Context3 *context3 = &subtable->u.context3;
+
+ READ_USHORT (stream, context3->GlyphCount);
+ if (context3->GlyphCount < 0)
+ OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
+ READ_USHORT (stream, context3->PosCount);
+ if (read_coverage_list (otf, stream, offset,
+ &context3->Coverage,
+ context3->GlyphCount) < 0)
+ return -1;
+ if (read_lookup_record_list (otf, stream,
+ &context3->LookupRecord,
+ context3->PosCount) < 0)
+ return -1;
+ }
+ else
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
+ break;
+
+ case 8:
+ if (subtable->Format == 1)
+ {
+ OTF_GPOS_ChainContext1 *chain_context1 = &subtable->u.chain_context1;
+
+ read_coverage (otf, stream, offset, &subtable->Coverage);
+ chain_context1->ChainPosRuleSetCount
+ = read_chain_rule_set_list (otf, stream, offset,
+ &chain_context1->ChainPosRuleSet);
+ }
+ else if (subtable->Format == 2)
+ {
+ OTF_GPOS_ChainContext2 *chain_context2 = &subtable->u.chain_context2;
+
+ read_coverage (otf, stream, offset, &subtable->Coverage);
+ read_class_def (otf, stream, offset, &chain_context2->Backtrack);
+ read_class_def (otf, stream, offset, &chain_context2->Input);
+ read_class_def (otf, stream, offset, &chain_context2->LookAhead);
+ chain_context2->ChainPosClassSetCnt
+ = read_chain_class_set_list (otf, stream, offset,
+ &chain_context2->ChainPosClassSet);
}
else if (subtable->Format == 3)
{
- subtable->u.chain_context3.BacktrackGlyphCount
- = (read_coverage_list
- (otf, stream, offset,
- &subtable->u.chain_context3.Backtrack));
- subtable->u.chain_context3.InputGlyphCount
- = (read_coverage_list
- (otf, stream, offset,
- &subtable->u.chain_context3.Input));
- subtable->u.chain_context3.LookaheadGlyphCount
- = (read_coverage_list
- (otf, stream, offset,
- &subtable->u.chain_context3.LookAhead));
- subtable->u.chain_context3.SubstCount
- = (read_subst_lookup_record
- (otf, stream,
- &subtable->u.chain_context3.SubstLookupRecord));
+ OTF_GPOS_ChainContext3 *chain_context3 = &subtable->u.chain_context3;
+
+ count = read_coverage_list (otf, stream, offset,
+ &chain_context3->Backtrack, -1);
+ if (count < 0)
+ return -1;
+ chain_context3->BacktrackGlyphCount = (unsigned) count;
+ count = read_coverage_list (otf, stream, offset,
+ &chain_context3->Input, -1);
+ if (count <= 0)
+ return -1;
+ chain_context3->InputGlyphCount = (unsigned) count;
+ subtable->Coverage = chain_context3->Input[0];
+ count = read_coverage_list (otf, stream, offset,
+ &chain_context3->LookAhead, -1);
+ chain_context3->LookaheadGlyphCount = (unsigned) count;
+ chain_context3->PosCount
+ = read_lookup_record_list (otf, stream,
+ &chain_context3->LookupRecord, -1);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
-#endif
+ break;
+
+ case 9:
+ OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
+ break;
default:
- OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid LookupType)");
}
return 0;
}
return jstf;
}
-#endif
+#endif /* 0 */
\f
/* GDEF */
static int
int
OTF_get_table (OTF *otf, char *name)
{
- char *errfmt = "OTF Table Read";
+ char *errfmt = "OTF Table Read%s";
int errret = -1;
OTF_InternalData *internal_data = otf->internal_data;
OTF_TableInfo *table_info;
OTF_Tag tag = OTF_tag (name);
if (! tag)
- OTF_ERROR (OTF_ERROR_TABLE, " (unknown)");
+ OTF_ERROR (OTF_ERROR_TABLE, " (invalid table name)");
if (tag == OTF_tag ("head"))
table_info = internal_data->table_info + OTF_TABLE_TYPE_HEAD;
else if (tag == OTF_tag ("GPOS"))
table_info = internal_data->table_info + OTF_TABLE_TYPE_GPOS;
else
- OTF_ERROR (OTF_ERROR_TABLE, " (unsupported)");
+ OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported table name)");
if (*table_info->address)
+ /* Already read. */
return 0;
if (! table_info->stream)
- OTF_ERROR (OTF_ERROR_TABLE, " (not found)");
+ OTF_ERROR (OTF_ERROR_TABLE, " (table not found)");
if (! table_info->reader)
OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)");
if (! *table_info->address)
{
table_info->reader = NULL;
- OTF_ERROR (OTF_ERROR_TABLE, " (invalid contents)");
+ return errret;
}
return 0;