static void dump_lookup_subtable_gsub (int indent, int index, unsigned type,
- OTF_LookupSubTable *subtable);
+ OTF_LookupSubTableGSUB *subtable);
static void dump_lookup_subtable_gpos (int indent, int index, unsigned type,
- OTF_LookupSubTable *subtable);
+ OTF_LookupSubTableGPOS *subtable);
static void
if (gsub)
for (j = 0; j < lookup->SubTableCount; j++)
dump_lookup_subtable_gsub (indent + 1, j,
- lookup->LookupType, lookup->SubTable + j);
+ lookup->LookupType,
+ lookup->SubTable.gsub + j);
else
for (j = 0; j < lookup->SubTableCount; j++)
dump_lookup_subtable_gpos (indent + 1, j,
- lookup->LookupType, lookup->SubTable + j);
+ lookup->LookupType,
+ lookup->SubTable.gpos + j);
printf (")");
}
static void
dump_lookup_subtable_gsub (int indent, int index, unsigned type,
- OTF_LookupSubTable *subtable)
+ OTF_LookupSubTableGSUB *subtable)
{
IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
indent++;
{
dump_coverage (indent, NULL, &subtable->Coverage);
IPRINT ("(DeltaGlyhpID #x%04X)",
- subtable->sub.gsub.single1.DeltaGlyphID);
+ subtable->u.single1.DeltaGlyphID);
}
else if (subtable->Format == 2)
{
dump_coverage (indent, NULL, &subtable->Coverage);
IPRINT ("(GlyphCount %d)",
- subtable->sub.gsub.single2.GlyphCount);
+ subtable->u.single2.GlyphCount);
IPRINT ("(Substitute");
- dump_glyph_ids (subtable->sub.gsub.single2.Substitute,
- subtable->sub.gsub.single2.GlyphCount);
+ dump_glyph_ids (subtable->u.single2.Substitute,
+ subtable->u.single2.GlyphCount);
printf (")");
}
break;
{
dump_coverage (indent, NULL, &subtable->Coverage);
dump_sequence_list (indent,
- subtable->sub.gsub.multiple1.Sequence,
- subtable->sub.gsub.multiple1.SequenceCount);
+ subtable->u.multiple1.Sequence,
+ subtable->u.multiple1.SequenceCount);
}
break;
{
dump_coverage (indent, NULL, &subtable->Coverage);
dump_ligature_set_list (indent,
- subtable->sub.gsub.ligature1.LigatureSet,
- subtable->sub.gsub.ligature1.LigSetCount);
+ subtable->u.ligature1.LigatureSet,
+ subtable->u.ligature1.LigSetCount);
}
break;
{
#if 0
read_coverage (fp, offset,
- &subtable->sub.gsub.chain_context1.Coverage);
- subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
+ &subtable->u.chain_context1.Coverage);
+ subtable->u.chain_context1.ChainSubRuleSetCount
= (read_chain_subrule_set
(fp, offset,
- &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
+ &subtable->u.chain_context1.ChainSubRuleSet));
#endif
}
else if (subtable->Format == 2)
{
#if 0
read_coverage (fp, offset,
- &subtable->sub.gsub.chain_context2.Coverage);
+ &subtable->u.chain_context2.Coverage);
read_class_def (fp, offset,
- &subtable->sub.gsub.chain_context2.Backtrack);
+ &subtable->u.chain_context2.Backtrack);
read_class_def (fp, offset,
- &subtable->sub.gsub.chain_context2.Input);
+ &subtable->u.chain_context2.Input);
read_class_def (fp, offset,
- &subtable->sub.gsub.chain_context2.LookAhead);
- subtable->sub.gsub.chain_context2.ChainSubClassSetCnt
+ &subtable->u.chain_context2.LookAhead);
+ subtable->u.chain_context2.ChainSubClassSetCnt
= (read_chain_subclass_set
(fp, offset,
- &subtable->sub.gsub.chain_context2.ChainSubClassSet));
+ &subtable->u.chain_context2.ChainSubClassSet));
#endif
}
else if (subtable->Format == 3)
{
dump_coverage_list
(indent, "BackTrackGlyphCount",
- subtable->sub.gsub.chain_context3.Backtrack,
- subtable->sub.gsub.chain_context3.BacktrackGlyphCount);
+ subtable->u.chain_context3.Backtrack,
+ subtable->u.chain_context3.BacktrackGlyphCount);
dump_coverage_list
(indent, "InputGlyphCount",
- subtable->sub.gsub.chain_context3.Input,
- subtable->sub.gsub.chain_context3.InputGlyphCount);
+ subtable->u.chain_context3.Input,
+ subtable->u.chain_context3.InputGlyphCount);
dump_coverage_list
(indent, "LookaheaGlyphCount",
- subtable->sub.gsub.chain_context3.LookAhead,
- subtable->sub.gsub.chain_context3.LookaheadGlyphCount);
+ subtable->u.chain_context3.LookAhead,
+ subtable->u.chain_context3.LookaheadGlyphCount);
dump_subst_lookup_record_list
(indent,
- subtable->sub.gsub.chain_context3.SubstLookupRecord,
- subtable->sub.gsub.chain_context3.SubstCount);
+ subtable->u.chain_context3.SubstLookupRecord,
+ subtable->u.chain_context3.SubstCount);
}
break;
}
static void
dump_lookup_subtable_gpos (int indent, int index, unsigned type,
- OTF_LookupSubTable *subtable)
+ OTF_LookupSubTableGPOS *subtable)
{
IPRINT ("(SubTable (%d) (Format %d)", index, subtable->Format);
indent++;
#if 0
if (subtable->Format == 1)
{
- dump_coverage (indent, NULL, &subtable->sub.gpos.single1.Coverage);
+ dump_coverage (indent, NULL, &subtable->u.single1.Coverage);
IPRINT ("(DeltaGlyhpID #x%04X)",
- subtable->sub.gsub.single1.DeltaGlyphID);
+ subtable->u.single1.DeltaGlyphID);
}
else if (subtable->Format == 2)
{
- dump_coverage (indent, NULL, &subtable->sub.gsub.single2.Coverage);
+ dump_coverage (indent, NULL, &subtable->u.single2.Coverage);
IPRINT ("(GlyphCount %d)",
- subtable->sub.gsub.single2.GlyphCount);
+ subtable->u.single2.GlyphCount);
IPRINT ("(Substitute");
- dump_glyph_ids (subtable->sub.gsub.single2.Substitute,
- subtable->sub.gsub.single2.GlyphCount);
+ dump_glyph_ids (subtable->u.single2.Substitute,
+ subtable->u.single2.GlyphCount);
printf (")");
}
#endif
{
dump_coverage (indent, NULL, &subtable->Coverage);
IPRINT ("(ValueFormat1 #x%04X)",
- subtable->sub.gpos.pair2.ValueFormat1);
+ subtable->u.pair2.ValueFormat1);
IPRINT ("(ValueFormat2 #x%04X)",
- subtable->sub.gpos.pair2.ValueFormat2);
+ subtable->u.pair2.ValueFormat2);
dump_class_def (indent, "ClassDef1",
- &subtable->sub.gpos.pair2.ClassDef1);
+ &subtable->u.pair2.ClassDef1);
dump_class_def (indent, "ClassDef2",
- &subtable->sub.gpos.pair2.ClassDef2);
+ &subtable->u.pair2.ClassDef2);
IPRINT ("(Class1Count %d)",
- subtable->sub.gpos.pair2.Class1Count);
+ subtable->u.pair2.Class1Count);
IPRINT ("(Class2Count %d)",
- subtable->sub.gpos.pair2.Class2Count);
+ subtable->u.pair2.Class2Count);
dump_class1_record_list (indent,
- subtable->sub.gpos.pair2.Class1Count,
- subtable->sub.gpos.pair2.Class2Count,
- subtable->sub.gpos.pair2.Class1Record);
+ subtable->u.pair2.Class1Count,
+ subtable->u.pair2.Class2Count,
+ subtable->u.pair2.Class1Record);
}
break;
{
dump_coverage (indent, "Mark", &subtable->Coverage);
dump_coverage (indent, "Base",
- &subtable->sub.gpos.mark_base1.BaseCoverage);
+ &subtable->u.mark_base1.BaseCoverage);
IPRINT ("(ClassCount %d)",
- subtable->sub.gpos.mark_base1.ClassCount);
- dump_mark_array (indent, &subtable->sub.gpos.mark_base1.MarkArray);
- dump_base_array (indent, subtable->sub.gpos.mark_base1.ClassCount,
- &subtable->sub.gpos.mark_base1.BaseArray);
+ subtable->u.mark_base1.ClassCount);
+ dump_mark_array (indent, &subtable->u.mark_base1.MarkArray);
+ dump_base_array (indent, subtable->u.mark_base1.ClassCount,
+ &subtable->u.mark_base1.BaseArray);
}
break;
{
#if 0
read_coverage (fp, offset,
- &subtable->sub.gsub.chain_context1.Coverage);
- subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
+ &subtable->u.chain_context1.Coverage);
+ subtable->u.chain_context1.ChainSubRuleSetCount
= (read_chain_subrule_set
(fp, offset,
- &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
+ &subtable->u.chain_context1.ChainSubRuleSet));
#endif
}
else if (subtable->Format == 2)
{
#if 0
read_coverage (fp, offset,
- &subtable->sub.gsub.chain_context2.Coverage);
+ &subtable->u.chain_context2.Coverage);
read_class_def (fp, offset,
- &subtable->sub.gsub.chain_context2.Backtrack);
+ &subtable->u.chain_context2.Backtrack);
read_class_def (fp, offset,
- &subtable->sub.gsub.chain_context2.Input);
+ &subtable->u.chain_context2.Input);
read_class_def (fp, offset,
- &subtable->sub.gsub.chain_context2.LookAhead);
- subtable->sub.gsub.chain_context2.ChainSubClassSetCnt
+ &subtable->u.chain_context2.LookAhead);
+ subtable->u.chain_context2.ChainSubClassSetCnt
= (read_chain_subclass_set
(fp, offset,
- &subtable->sub.gsub.chain_context2.ChainSubClassSet));
+ &subtable->u.chain_context2.ChainSubClassSet));
#endif
}
else if (subtable->Format == 3)
#if 0
dump_coverage_list
(indent, "BackTrackGlyphCount",
- subtable->sub.gsub.chain_context3.Backtrack,
- subtable->sub.gsub.chain_context3.BacktrackGlyphCount);
+ subtable->u.chain_context3.Backtrack,
+ subtable->u.chain_context3.BacktrackGlyphCount);
dump_coverage_list
(indent, "InputGlyphCount",
- subtable->sub.gsub.chain_context3.Input,
- subtable->sub.gsub.chain_context3.InputGlyphCount);
+ subtable->u.chain_context3.Input,
+ subtable->u.chain_context3.InputGlyphCount);
dump_coverage_list
(indent, "LookaheaGlyphCount",
- subtable->sub.gsub.chain_context3.LookAhead,
- subtable->sub.gsub.chain_context3.LookaheadGlyphCount);
+ subtable->u.chain_context3.LookAhead,
+ subtable->u.chain_context3.LookaheadGlyphCount);
dump_subst_lookup_record_list
(indent,
- subtable->sub.gsub.chain_context3.SubstLookupRecord,
- subtable->sub.gsub.chain_context3.SubstCount);
+ subtable->u.chain_context3.SubstLookupRecord,
+ subtable->u.chain_context3.SubstCount);
#endif
}
break;
libotf_la_SOURCES = \
otf.h \
- otfutil.h otfutil.c \
+ otferror.h otferror.c \
otfopen.c \
otfdrive.c
(1-2) "head" table
(1-3) "name" table
(1-4) "cmap" table
- (1-5) Structures common to the following tables
+ (1-5) Structures common to GDEF, GSUB, and GPOS
(1-6) "GDEF" table
- (1-7) "GSUB" table
- (1-8) "GPOS" table
- (1-9) OTF
+ (1-7) Structures for ScriptList, FeatureList, and LookupList
+ (1-8) "GSUB" table
+ (1-9) "GPOS" table
+ (1-9) Structure for OTF
(2) APIs for reading OTF
- (2-1) otf_open ()
- (2-2) otf_close ()
- (2-3) otf_get_table ()
+ (2-1) otf_open()
+ (2-2) otf_close()
+ (2-3) otf_get_table()
(3) APIs for driving OTF
(3-1) Structure for glyph string
- (3-2) otf_drive_cmap ()
- (3-3) otf_drive_gdef ()
- (3-4) otf_drive_gsub ()
- (3-5) otf_drive_gpos ()
+ (3-2) otf_drive_cmap()
+ (3-3) otf_drive_gdef()
+ (3-4) otf_drive_gsub()
+ (3-5) otf_drive_gpos()
+ (3-6) otf_drive_tables()
(4) APIs for error handling
(4-1) Error codes
- (4-2) otf_perror ()
+ (4-2) otf_perror()
(5) APIs miscellaneous
-***/
+*/
/*** (1) Structures for OTF tables and OTF itself */
} f;
} OTF_ClassDef;
+
/*** (1-6) "GDEF" table */
typedef struct
OTF_ClassDef mark_attach_class_def;
} OTF_GDEF;
-\f
+/*** (1-7) Structures for ScriptList, FeatureList, and LookupList */
+/*** The structure hierarchy
-/* COMMON */
-
-/* ScriptList
+ ScriptList
ScriptRecord[]
ScriptTag
Script[]
LookupType
LookupFlag
SubTableOffset[]
- SubTable[]
+ SubTable.gsub[] or SubTable.gpos[]
*/
OTF_Feature *Feature;
} OTF_FeatureList;
-typedef struct OTF_LookupSubTable OTF_LookupSubTable;
+typedef struct OTF_LookupSubTableGSUB OTF_LookupSubTableGSUB;
+typedef struct OTF_LookupSubTableGPOS OTF_LookupSubTableGPOS;
+enum OTF_LookupFlagBit
+ {
+ OTF_RightToLeft = 0x0001,
+ OTF_IgnoreBaseGlyphs = 0x0002,
+ OTF_IgnoreLigatures = 0x0004,
+ OTF_IgnoreMarks = 0x8000,
+ OTF_Reserved = 0x00F0,
+ OTF_MarkAttachmentType = 0xFF00
+ };
+
typedef struct
{
OTF_Offset offset;
unsigned LookupFlag;
unsigned SubTableCount;
OTF_Offset *SubTableOffset;
- OTF_LookupSubTable *SubTable;
+ union {
+ OTF_LookupSubTableGSUB *gsub;
+ OTF_LookupSubTableGPOS *gpos;
+ } SubTable;
} OTF_Lookup;
typedef struct
OTF_Lookup *Lookup;
} OTF_LookupList;
-enum OTF_LookupFlagBit
- {
- OTF_RightToLeft = 0x0001,
- OTF_IgnoreBaseGlyphs = 0x0002,
- OTF_IgnoreLigatures = 0x0004,
- OTF_IgnoreMarks = 0x8000,
- OTF_Reserved = 0x00F0,
- OTF_MarkAttachmentType = 0xFF00
- };
-
-\f
-/* GSUB */
+/*** (1-8) "GSUB" table */
typedef struct
{
OTF_GlyphID *Substitute;
} OTF_GSUB_ReverseChainSingle1;
-\f
-/* GPOS */
+struct OTF_LookupSubTableGSUB
+{
+ unsigned Format;
+ OTF_Coverage Coverage;
+ union {
+ /* LookupType 1 */
+ OTF_GSUB_Single1 single1;
+ OTF_GSUB_Single2 single2;
+ /* LookupType 2 */
+ OTF_GSUB_Multiple1 multiple1;
+ /* LookupType 3 */
+ OTF_GSUB_Alternate1 alternate1;
+ /* LookupType 4 */
+ OTF_GSUB_Ligature1 ligature1;
+ /* LookupType 5 */
+ OTF_GSUB_Context1 context1;
+ OTF_GSUB_Context2 context2;
+ OTF_GSUB_Context3 context3;
+ /* LookupType 6 */
+ OTF_GSUB_ChainContext1 chain_context1;
+ OTF_GSUB_ChainContext2 chain_context2;
+ OTF_GSUB_ChainContext3 chain_context3;
+ /* LookupType 7 */
+ OTF_GSUB_Extension1 extension1;
+ /* LookupType 8 */
+ OTF_GSUB_ReverseChainSingle1 reverse_chain_single1;
+ } u;
+};
+
+typedef struct
+{
+ OTF_Fixed Version;
+ OTF_ScriptList ScriptList;
+ OTF_FeatureList FeatureList;
+ OTF_LookupList LookupList;
+} OTF_GSUB;
+
+/*** (1-8) "GPOS" table */
+
enum OTF_ValueFormat
{
OTF_XPlacement = 0x0001,
} OTF_GPOS_Extension1;
-struct OTF_LookupSubTable
+struct OTF_LookupSubTableGPOS
{
unsigned Format;
OTF_Coverage Coverage;
union {
- union { /* GSUB */
- /* LookupType 1 */
- OTF_GSUB_Single1 single1;
- OTF_GSUB_Single2 single2;
- /* LookupType 2 */
- OTF_GSUB_Multiple1 multiple1;
- /* LookupType 3 */
- OTF_GSUB_Alternate1 alternate1;
- /* LookupType 4 */
- OTF_GSUB_Ligature1 ligature1;
- /* LookupType 5 */
- OTF_GSUB_Context1 context1;
- OTF_GSUB_Context2 context2;
- OTF_GSUB_Context3 context3;
- /* LookupType 6 */
- OTF_GSUB_ChainContext1 chain_context1;
- OTF_GSUB_ChainContext2 chain_context2;
- OTF_GSUB_ChainContext3 chain_context3;
- /* LookupType 7 */
- OTF_GSUB_Extension1 extension1;
- /* LookupType 8 */
- OTF_GSUB_ReverseChainSingle1 reverse_chain_single1;
- } gsub;
-
- union { /* GPOS */
- /* LookupType 1 */
- OTF_GPOS_Single1 single1;
- OTF_GPOS_Single2 single2;
- /* LookupType 2 */
- OTF_GPOS_Pair1 pair1;
- OTF_GPOS_Pair2 pair2;
- /* LookupType 3 */
- OTF_GPOS_Cursive1 cursive1;
- /* LookupType 4 */
- OTF_GPOS_MarkBase1 mark_base1;
- /* LookupType 5 */
- OTF_GPOS_MarkLig1 mark_lig1;
- /* LookupType 6 */
- OTF_GPOS_MarkMark1 mark_mark1;
- /* LookupType 7 */
- OTF_GPOS_Context1 context1;
- OTF_GPOS_Context2 context2;
- OTF_GPOS_Context3 context3;
- /* LookupType 8 */
- OTF_GPOS_ChainContext1 chain_context1;
- OTF_GPOS_ChainContext2 chain_context2;
- OTF_GPOS_ChainContext3 chain_context3;
- /* LookupType 9 */
- OTF_GPOS_Extension1 extension1;
- } gpos;
- } sub;
+ /* LookupType 1 */
+ OTF_GPOS_Single1 single1;
+ OTF_GPOS_Single2 single2;
+ /* LookupType 2 */
+ OTF_GPOS_Pair1 pair1;
+ OTF_GPOS_Pair2 pair2;
+ /* LookupType 3 */
+ OTF_GPOS_Cursive1 cursive1;
+ /* LookupType 4 */
+ OTF_GPOS_MarkBase1 mark_base1;
+ /* LookupType 5 */
+ OTF_GPOS_MarkLig1 mark_lig1;
+ /* LookupType 6 */
+ OTF_GPOS_MarkMark1 mark_mark1;
+ /* LookupType 7 */
+ OTF_GPOS_Context1 context1;
+ OTF_GPOS_Context2 context2;
+ OTF_GPOS_Context3 context3;
+ /* LookupType 8 */
+ OTF_GPOS_ChainContext1 chain_context1;
+ OTF_GPOS_ChainContext2 chain_context2;
+ OTF_GPOS_ChainContext3 chain_context3;
+ /* LookupType 9 */
+ OTF_GPOS_Extension1 extension1;
+ } u;
};
-\f
-/* GSUB */
-
-typedef struct
-{
- OTF_Fixed Version;
- OTF_ScriptList ScriptList;
- OTF_FeatureList FeatureList;
- OTF_LookupList LookupList;
-} OTF_GSUB;
-
-\f
-
-/* GPOS */
typedef struct
{
OTF_Fixed Version;
OTF_LookupList LookupList;
} OTF_GPOS;
-\f
-/* BASE */
-typedef struct
-{
- int dummy;
-} OTF_BASE;
-
-\f
-/* JSTF */
-typedef struct
-{
- int dummy;
-} OTF_JSTF;
-
-\f
+/*** (1-9) Structure for OTF */
-/* OTF */
typedef struct
{
OTF_Fixed sfnt_version;
OTF_InternalData *internal_data;
} OTF;
+\f
+/*** (2) APIs for reading OTF */
+
+/*** (2-1) otf_open () */
+
+/***
+ Open OpenType font
+
+ The otf_open() function reads the OpenType font file whose name is
+ $NAME, and return a pointer to the structure of type OTF.
+
+ It setups these member of the structure OTF:
+ filename, offset_table, table_dirs
+
+ If the file can't be read or the file contains invalid data, NULL
+ is returned, and the variable otf_error is set to one of the
+ following values.
+
+ OTF_ERROR_MEMORY
+ OTF_ERROR_FILE
+ OTF_ERROR_TABLE
+
+ See also otf_get_table() and otf_close(). */
+
+extern OTF *otf_open (char *name);
+
+
+/*** (2-2) otf_close () */
+
+/***
+ Close OpenType font
+
+ The otf_close() function closes the OpenType font pointed by $OTF
+ which must be what the otf_open() returned.
+
+ See also otf_open(). */
+
+extern void otf_close (OTF *otf);
+
+
+/*** (2-3) otf_get_table () */
+
+/***
+ Get OpenType font table
+
+ The otf_get_table() function setups one of the OTF tables
+ specified by $NAME in the structure pointed by $OTF.
+
+ $NAME must be one of "head", "name", "cmap", "GDEF", "GSUB", and
+ "GPOS", and a member of the same name is setup.
+
+ If the table is successfully setup, return 0. Otherwise, return
+ -1, and set the variable otf_error to OTF_ERROR_TABLE.
+
+ See also otf_open(). */
+
+extern int otf_get_table (OTF *otf, char *name);
+
+
+/*** (3) APIs for driving OTF */
+
+/*** (3-1) Structure for glyph string */
+
+/***
+ The structure OTF_Glyph contains information about each glyph in
+ the structure OTF_GlyphString. */
+
typedef struct
{
/* Character code of the glyph. This is the only member that a
- client has to set before calling the function otfdrive(). */
+ client has to set before calling the function
+ otf_drive_XXX(). */
int c;
/* Glyph ID of the glyph. */
OTF_GlyphID glyph_id;
/* GlyphClass of the glyph. The value is extracted from the GDEF
- table of OTF. */
+ table. */
enum OTF_GlyphClassDef GlyphClass;
/* MarkAttachClassDef of the glyph. The value is extracted from the
GDEF table. */
unsigned MarkAttachClass;
- /* Positioning format type of the glyph. The value is the same as
- the LookupType of the GPOS's Lookup table that is used to decide
- the positioning of the glyph. */
+ /* Positioning format type of the glyph. The value specifies how
+ the glyph positioning information is encoded in the member <f>.
+ If the value is N, the union member fN, is used. If the value is
+ zero, the glyph has no positioning information, i.e. it should be
+ drawn at the normal position. */
int positioning_type;
union {
struct {
} f;
} OTF_Glyph;
+/***
+ The structure OTF_GlyphString contains an array of glyphs (type
+ OTF_Glyph). It is used as arguments of otf_drive_XXX(). */
+
typedef struct
{
+ /* How many glyphs are allocated at the memory pointed by the member
+ <glyphs>. */
int size;
+ /* How many glyphs contains valid information. */
int used;
+ /* Array of glyphs. It must be allocated by malloc(). The
+ functions otf_drive_XXX() may reallocate it and increase the
+ members <size> and <used>. */
OTF_Glyph *glyphs;
} OTF_GlyphString;
-/***
- @brief Open an OpenType font file.
+/*** (3-2) otf_drive_cmap() */
- The function otf_open () reads the OpenType font file whose name
- is $NAME, and return a pointer to the structure of type OTF. */
+/***
+ Process glyph string by cmap table.
-extern OTF *otf_open (char *name);
-extern void otf_close (OTF *otf);
-extern int otf_get_table (OTF *otf, char *name);
+ The otf_drive_cmap() function looks up the cmap table of OpenType
+ font $OTF, and setup the member <glyhph_id> of all glhphs in the
+ glyph string $GSTRING. */
extern int otf_drive_cmap (OTF *otf, OTF_GlyphString *gstring);
+
+/*** (3-3) otf_drive_gdef() */
+
+/***
+ Process glyph string by GDEF table.
+
+ The otf_drive_gdef() function looks up the GDEF table of OpenType
+ font $OTF, and setup members <GlyphClass> and <MarkAttachClass> of
+ all glhphs in the glyph string $GSTRING. */
+
extern int otf_drive_gdef (OTF *otf, OTF_GlyphString *gstring);
+
+
+/*** (3-4) otf_drive_gsub() */
+
+/***
+ Process glyph string by GSUB table.
+
+ The otf_drive_gsub() function looks up the GSUB table of OpenType
+ font $OTF, and by using features the font has for script $SCRIPT
+ and language system $LANGSYS, update member <glyphs> of the glyph
+ string $GSTRING. It may substitute, delete, insert glyphs in that
+ array. */
+
extern int otf_drive_gsub (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag,
OTF_GlyphString *gstring);
+
+/*** (3-5) otf_drive_gpos() */
+
+/***
+ Process glyph string by GPOS table.
+
+ The otf_drive_gdef() function looks up the GPOS table of $OTF of
+ OpenType font $OTF, and by using features the font has for script
+ $SCRIPT and language system $LANGSYS, setup members
+ <positioning_type> and <f> of all glhphs in the glyph string
+ $GSTRING. */
+
extern int otf_drive_gpos (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag,
OTF_GlyphString *gstring);
-extern int otf_drive_table (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag,
- OTF_GlyphString *gstring);
+
+
+/*** (3-6) otf_drive_tables() */
+
+/***
+ Process glyph string by cmap, GDEF, GSUB, and GPOS tables.
+
+ The otf_drive_tables() function calls otf_drive_cmap(),
+ otf_drive_gdef(), otf_drive_gsub(), and otf_drive_gpos() in this
+ order, and update the glyphs string GSTRING. */
+
+extern int otf_drive_tables (OTF *otf, OTF_Tag script_tag, OTF_Tag langsys_tag,
+ OTF_GlyphString *gstring);
/*** (4) APIs for error handling ***/
extern int otf_error;
/***
- Memory allocation error.
+ Memory allocation error
This error indicates that the library couldn't allocate
memory. */
#define OTF_ERROR_MEMORY 1
/***
- File error.
+ File error
This error indicates that the library fails in opening, reading,
or seeking an OTF file. */
#define OTF_ERROR_FILE 2
/***
- Invalid table contents.
+ Invalid table contents
This error indicates that an OTF file contains invalid data. */
#define OTF_ERROR_TABLE 3
/***
- CMAP driving error.
+ CMAP driving error
See the function otf_drive_cmap() for more detail. */
#define OTF_ERROR_CMAP_DRIVE 4
/***
- GDEF driving error.
+ GDEF driving error
See the function otf_drive_gdef() for more detail. */
#define OTF_ERROR_GDEF_DRIVE 5
/***
- GSUB driving error.
+ GSUB driving error
See the function otf_drive_gsub() for more detail. */
#define OTF_ERROR_GSUB_DRIVE 6
/***
- GPOS driving error.
+ GPOS driving error
See the function otf_drive_gpos() for more detail. */
#define OTF_ERROR_GPOS_DRIVE 7
+/*** (4-2) otf_perror() */
+
/***
Print an OTF error message
#include <string.h>
#include "otf.h"
-#include "otfutil.h"
+#include "otferror.h"
#define GSTRING_DELETE(gstring, from, len) \
do { \
if (! g->glyph_id
|| (g->GlyphClass
&& (flag & (1 << g->GlyphClass))))
- {
- // printf ("type %d at %d skiped\n", lookup->LookupType, gidx);
- return (gidx + 1);
- }
-
- //printf ("@%d idx:%d type:%d...",
- //gidx, lookup_list_index, lookup->LookupType);
+ return (gidx + 1);
/* Try all subtables until one of them handles the current glyph. */
for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
{
- OTF_LookupSubTable *subtable = lookup->SubTable + i;
+ OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
int coverage_idx;
- // printf ("subtype:%d ", subtable->Format);
if (subtable->Coverage.offset)
{
coverage_idx = get_coverage_index (&subtable->Coverage,
g->glyph_id);
if (coverage_idx < 0)
- {
- // printf ("not covererd ");
- continue;
- }
+ continue;
}
switch (lookup->LookupType)
{
case 1:
if (subtable->Format == 1)
- g->glyph_id += subtable->sub.gsub.single1.DeltaGlyphID;
+ g->glyph_id += subtable->u.single1.DeltaGlyphID;
else
- g->glyph_id = subtable->sub.gsub.single2.Substitute[coverage_idx];
+ g->glyph_id = subtable->u.single2.Substitute[coverage_idx];
gidx++;
break;
case 2:
{
- OTF_GSUB_Multiple1 *multiple1 = &subtable->sub.gsub.multiple1;
+ OTF_GSUB_Multiple1 *multiple1 = &subtable->u.multiple1;
OTF_Sequence *seq = multiple1->Sequence + coverage_idx;
gstring_subst (gstring, gidx, gidx + 1,
case 4:
if (subtable->Format == 1)
{
- OTF_GSUB_Ligature1 *lig1 = &subtable->sub.gsub.ligature1;
+ OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
OTF_LigatureSet *ligset = lig1->LigatureSet + coverage_idx;
int j;
else
{
OTF_GSUB_ChainContext3 *context3
- = &subtable->sub.gsub.chain_context3;
+ = &subtable->u.chain_context3;
int back_gidx = gidx - context3->BacktrackGlyphCount;
int fore_gidx = gidx + context3->InputGlyphCount;
int orig_used;
if (! g->glyph_id
|| (g->GlyphClass
&& (flag & (1 << g->GlyphClass))))
- {
- // printf ("type %d at %d skiped\n", lookup->LookupType, gidx);
- return (gidx + 1);
- }
-
- // printf ("0x%04X@%d idx:%d type:%d...",
- // g->glyph_id, gidx, lookup_list_index, lookup->LookupType);
+ return (gidx + 1);
/* Try all subtables until one of them handles the current glyph. */
for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
{
- OTF_LookupSubTable *subtable = lookup->SubTable + i;
+ OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
int coverage_idx;
// printf ("subtype:%d ", subtable->Format);
OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
else if (subtable->Format == 2)
{
- OTF_GPOS_Pair2 *pair2 = &subtable->sub.gpos.pair2;
+ OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
unsigned class1, class2;
printf ("GPOS 2-2: c:0x%x g:0x%x\n", g->c, g->glyph_id);
continue;
if (subtable->Format == 1)
{
- OTF_GPOS_MarkBase1 *mark_base1 = &subtable->sub.gpos.mark_base1;
+ OTF_GPOS_MarkBase1 *mark_base1 = &subtable->u.mark_base1;
OTF_MarkRecord *mark_record;
OTF_BaseRecord *base_record;
OTF_Anchor *anchor1, *anchor2;
}
int
-otf_drive_table (OTF *otf, OTF_Tag script, OTF_Tag langsys,
- OTF_GlyphString *gstring)
+otf_drive_tables (OTF *otf, OTF_Tag script, OTF_Tag langsys,
+ OTF_GlyphString *gstring)
{
if (otf_drive_cmap (otf, gstring) < 0)
return -1;
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "otf.h"
+
+static char *error_message;
+int otf_error;
+
+static char *error_string[] =
+ {
+ "No error",
+ "Memory shortage",
+ "File error",
+ "Invalid table"
+ "CMAP drive"
+ "GDEF drive"
+ "GSUB drive"
+ "GPOS drive"
+ };
+
+int
+otf__error (int err, char *fmt, void *arg)
+{
+ if (! error_message)
+ error_message = (char *) malloc (256);
+ sprintf (error_message, "OTF-Error (%s): ", error_string[err]);
+ sprintf (error_message + strlen (error_message), fmt, arg);
+ otf_error = err;
+ return 0;
+}
+
+void
+otf_perror (char *prefix)
+{
+ if (otf_error == 0)
+ error_message = error_string[0];
+ if (prefix)
+ fprintf (stderr, "%s: %s\n", prefix, error_message);
+ else
+ fprintf (stderr, "%s\n", error_message);
+}
--- /dev/null
+#define OTF_ERROR(err, arg) \
+ return (otf__error ((err), errfmt, (arg)), errret)
+
+extern int otf__error (int err, char *fmt, void *arg);
+
#include <string.h>
#include "otf.h"
-#include "otfutil.h"
+#include "otferror.h"
/* OTF_Stream
static int read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream,
long offset, unsigned type,
- OTF_LookupSubTable *subtable);
+ OTF_LookupSubTableGSUB *subtable);
static int read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream,
long offset, unsigned type,
- OTF_LookupSubTable *subtable);
+ OTF_LookupSubTableGPOS *subtable);
static int
read_lookup_list (OTF *otf, OTF_Stream *stream, long offset,
READ_UINT16 (stream, lookup->SubTableCount);
OTF_MALLOC (lookup->SubTableOffset, lookup->SubTableCount,
" (SubTableOffset)");
- OTF_CALLOC (lookup->SubTable, lookup->SubTableCount,
- " (SubTable)");
+ if (gsub)
+ OTF_CALLOC (lookup->SubTable.gsub, lookup->SubTableCount,
+ " (SubTable)");
+ else
+ OTF_CALLOC (lookup->SubTable.gpos, lookup->SubTableCount,
+ " (SubTable)");
for (j = 0; j < lookup->SubTableCount; j++)
READ_OFFSET (stream, lookup->SubTableOffset[j]);
- if (gsub)
- for (j = 0; j < lookup->SubTableCount; j++)
- {
- long this_offset
- = offset + lookup->offset + lookup->SubTableOffset[j];
+ for (j = 0; j < lookup->SubTableCount; j++)
+ {
+ long this_offset
+ = offset + lookup->offset + lookup->SubTableOffset[j];
- if (read_lookup_subtable_gsub (otf, stream, this_offset,
+ if (gsub
+ ? read_lookup_subtable_gsub (otf, stream, this_offset,
lookup->LookupType,
- lookup->SubTable + j) < 0)
- return errret;
- }
- else
- for (j = 0; j < lookup->SubTableCount; j++)
- {
- long this_offset
- = offset + lookup->offset + lookup->SubTableOffset[j];
-
- if (read_lookup_subtable_gpos (otf, stream, this_offset,
+ lookup->SubTable.gsub + j) < 0
+ : read_lookup_subtable_gpos (otf, stream, this_offset,
lookup->LookupType,
- lookup->SubTable + j) < 0)
- return errret;
- }
+ lookup->SubTable.gpos + j) < 0)
+ return errret;
+ }
}
return 0;
static int
read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
- unsigned type, OTF_LookupSubTable *subtable)
+ unsigned type, OTF_LookupSubTableGSUB *subtable)
{
char *errfmt = "GSUB LookupSubTable%s";
int errret = -1;
{
if (read_coverage (otf, stream, offset, &subtable->Coverage) < 0)
return -1;
- READ_INT16 (stream, subtable->sub.gsub.single1.DeltaGlyphID);
+ READ_INT16 (stream, subtable->u.single1.DeltaGlyphID);
}
else if (subtable->Format == 2)
{
if (read_coverage (otf, stream, offset, &subtable->Coverage) < 0)
return -1;
- subtable->sub.gsub.single2.GlyphCount
- = read_glyph_ids (otf, stream, &subtable->sub.gsub.single2.Substitute,
+ subtable->u.single2.GlyphCount
+ = read_glyph_ids (otf, stream, &subtable->u.single2.Substitute,
0);
- if (! subtable->sub.gsub.single2.GlyphCount)
+ if (! subtable->u.single2.GlyphCount)
return -1;
}
else
if (subtable->Format == 1)
{
read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->sub.gsub.multiple1.SequenceCount
+ subtable->u.multiple1.SequenceCount
= read_sequence (otf, stream, offset,
- &subtable->sub.gsub.multiple1.Sequence);
+ &subtable->u.multiple1.Sequence);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
read_coverage (otf, stream, offset, &subtable->Coverage);
count = (read_ligature_set
(otf, stream, offset,
- &subtable->sub.gsub.ligature1.LigatureSet));
+ &subtable->u.ligature1.LigatureSet));
if (count < 0)
return -1;
- subtable->sub.gsub.ligature1.LigSetCount = (unsigned) count;
+ subtable->u.ligature1.LigSetCount = (unsigned) count;
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
if (subtable->Format == 1)
{
read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
+ subtable->u.chain_context1.ChainSubRuleSetCount
= (read_chain_subrule_set
(otf, stream, offset,
- &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
+ &subtable->u.chain_context1.ChainSubRuleSet));
}
else if (subtable->Format == 2)
{
read_coverage (otf, stream, offset, &subtable->Coverage);
read_class_def (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.Backtrack);
+ &subtable->u.chain_context2.Backtrack);
read_class_def (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.Input);
+ &subtable->u.chain_context2.Input);
read_class_def (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.LookAhead);
- subtable->sub.gsub.chain_context2.ChainSubClassSetCnt
+ &subtable->u.chain_context2.LookAhead);
+ subtable->u.chain_context2.ChainSubClassSetCnt
= (read_chain_subclass_set
(otf, stream, offset,
- &subtable->sub.gsub.chain_context2.ChainSubClassSet));
+ &subtable->u.chain_context2.ChainSubClassSet));
}
else if (subtable->Format == 3)
{
count = (read_coverage_list
(otf, stream, offset,
- &subtable->sub.gsub.chain_context3.Backtrack));
+ &subtable->u.chain_context3.Backtrack));
if (count < 0)
return -1;
- subtable->sub.gsub.chain_context3.BacktrackGlyphCount
+ subtable->u.chain_context3.BacktrackGlyphCount
= (unsigned) count;
count = (read_coverage_list
(otf, stream, offset,
- &subtable->sub.gsub.chain_context3.Input));
+ &subtable->u.chain_context3.Input));
if (count <= 0)
return -1;
- subtable->sub.gsub.chain_context3.InputGlyphCount
+ subtable->u.chain_context3.InputGlyphCount
= (unsigned) count;
- subtable->Coverage = subtable->sub.gsub.chain_context3.Input[0];
+ subtable->Coverage = subtable->u.chain_context3.Input[0];
count = (read_coverage_list
(otf, stream, offset,
- &subtable->sub.gsub.chain_context3.LookAhead));
- subtable->sub.gsub.chain_context3.LookaheadGlyphCount
+ &subtable->u.chain_context3.LookAhead));
+ subtable->u.chain_context3.LookaheadGlyphCount
= (unsigned) count;
- subtable->sub.gsub.chain_context3.SubstCount
+ subtable->u.chain_context3.SubstCount
= (read_subst_lookup_record
(otf, stream,
- &subtable->sub.gsub.chain_context3.SubstLookupRecord));
+ &subtable->u.chain_context3.SubstLookupRecord));
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
static int
read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream,
long offset, unsigned type,
- OTF_LookupSubTable *subtable)
+ OTF_LookupSubTableGPOS *subtable)
{
char *errfmt = "GPOS LookupSubTable%s";
int errret = -1;
if (subtable->Format == 1)
{
read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->sub.gsub.single1.DeltaGlyphID = READ_INT16 (stream);
+ subtable->u.single1.DeltaGlyphID = READ_INT16 (stream);
}
else if (subtable->Format == 2)
{
read_coverage (otf, stream, offset, &subtable->Coverage);
- subtable->sub.gsub.single2.GlyphCount
+ subtable->u.single2.GlyphCount
= read_glyph_ids (otf, stream,
- &subtable->sub.gsub.single2.Substitute, 0);
+ &subtable->u.single2.Substitute, 0);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
{
SEEK_STREAM (stream, offset + 2);
read_coverage (otf, stream, offset, &subtable->Coverage);
- READ_UINT16 (stream, subtable->sub.gpos.pair2.ValueFormat1);
- READ_UINT16 (stream, subtable->sub.gpos.pair2.ValueFormat2);
+ READ_UINT16 (stream, subtable->u.pair2.ValueFormat1);
+ READ_UINT16 (stream, subtable->u.pair2.ValueFormat2);
read_class_def (otf, stream, offset,
- &subtable->sub.gpos.pair2.ClassDef1);
+ &subtable->u.pair2.ClassDef1);
read_class_def (otf, stream, offset,
- &subtable->sub.gpos.pair2.ClassDef2);
- READ_UINT16 (stream, subtable->sub.gpos.pair2.Class1Count);
- READ_UINT16 (stream, subtable->sub.gpos.pair2.Class2Count);
- subtable->sub.gpos.pair2.Class1Record
+ &subtable->u.pair2.ClassDef2);
+ READ_UINT16 (stream, subtable->u.pair2.Class1Count);
+ READ_UINT16 (stream, subtable->u.pair2.Class2Count);
+ subtable->u.pair2.Class1Record
= read_class1_record_list (otf, stream, offset,
- subtable->sub.gpos.pair2.Class1Count,
- subtable->sub.gpos.pair2.ValueFormat1,
- subtable->sub.gpos.pair2.Class2Count,
- subtable->sub.gpos.pair2.ValueFormat2);
+ subtable->u.pair2.Class1Count,
+ subtable->u.pair2.ValueFormat1,
+ subtable->u.pair2.Class2Count,
+ subtable->u.pair2.ValueFormat2);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
{
read_coverage (otf, stream, offset, &subtable->Coverage);
read_coverage (otf, stream, offset,
- &subtable->sub.gpos.mark_base1.BaseCoverage);
- READ_UINT16 (stream, subtable->sub.gpos.mark_base1.ClassCount);
+ &subtable->u.mark_base1.BaseCoverage);
+ READ_UINT16 (stream, subtable->u.mark_base1.ClassCount);
read_mark_array (otf, stream, offset,
- &subtable->sub.gpos.mark_base1.MarkArray);
+ &subtable->u.mark_base1.MarkArray);
read_base_array (otf, stream, offset,
- subtable->sub.gpos.mark_base1.ClassCount,
- &subtable->sub.gpos.mark_base1.BaseArray);
+ subtable->u.mark_base1.ClassCount,
+ &subtable->u.mark_base1.BaseArray);
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
if (subtable->Format == 1)
{
read_coverage (otf, stream, offset,
- &subtable->sub.gsub.chain_context1.Coverage);
- subtable->sub.gsub.chain_context1.ChainSubRuleSetCount
+ &subtable->u.chain_context1.Coverage);
+ subtable->u.chain_context1.ChainSubRuleSetCount
= (read_chain_subrule_set
(otf, stream, offset,
- &subtable->sub.gsub.chain_context1.ChainSubRuleSet));
+ &subtable->u.chain_context1.ChainSubRuleSet));
}
else if (subtable->Format == 2)
{
read_coverage (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.Coverage);
+ &subtable->u.chain_context2.Coverage);
read_class_def (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.Backtrack);
+ &subtable->u.chain_context2.Backtrack);
read_class_def (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.Input);
+ &subtable->u.chain_context2.Input);
read_class_def (otf, stream, offset,
- &subtable->sub.gsub.chain_context2.LookAhead);
- subtable->sub.gsub.chain_context2.ChainSubClassSetCnt
+ &subtable->u.chain_context2.LookAhead);
+ subtable->u.chain_context2.ChainSubClassSetCnt
= (read_chain_subclass_set
(otf, stream, offset,
- &subtable->sub.gsub.chain_context2.ChainSubClassSet));
+ &subtable->u.chain_context2.ChainSubClassSet));
}
else if (subtable->Format == 3)
{
- subtable->sub.gsub.chain_context3.BacktrackGlyphCount
+ subtable->u.chain_context3.BacktrackGlyphCount
= (read_coverage_list
(otf, stream, offset,
- &subtable->sub.gsub.chain_context3.Backtrack));
- subtable->sub.gsub.chain_context3.InputGlyphCount
+ &subtable->u.chain_context3.Backtrack));
+ subtable->u.chain_context3.InputGlyphCount
= (read_coverage_list
(otf, stream, offset,
- &subtable->sub.gsub.chain_context3.Input));
- subtable->sub.gsub.chain_context3.LookaheadGlyphCount
+ &subtable->u.chain_context3.Input));
+ subtable->u.chain_context3.LookaheadGlyphCount
= (read_coverage_list
(otf, stream, offset,
- &subtable->sub.gsub.chain_context3.LookAhead));
- subtable->sub.gsub.chain_context3.SubstCount
+ &subtable->u.chain_context3.LookAhead));
+ subtable->u.chain_context3.SubstCount
= (read_subst_lookup_record
(otf, stream,
- &subtable->sub.gsub.chain_context3.SubstLookupRecord));
+ &subtable->u.chain_context3.SubstLookupRecord));
}
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
OTF_InternalData *internal_data = otf->internal_data;
int i;
- //if (otf->filename)
- //free (otf->filename);
if (internal_data)
{
OTF_MemoryRecord *memrec = internal_data->memory_record;
}
free (internal_data);
}
+ free (otf);
}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "otf.h"
-
-static char *error_message;
-int otf_error;
-
-static char *error_string[] =
- {
- "No error",
- "Memory shortage",
- "File error",
- "Invalid table"
- "CMAP drive"
- "GDEF drive"
- "GSUB drive"
- "GPOS drive"
- };
-
-int
-otf__error (int err, char *fmt, void *arg)
-{
- if (! error_message)
- error_message = (char *) malloc (256);
- sprintf (error_message, "OTF-Error (%s): ", error_string[err]);
- sprintf (error_message + strlen (error_message), fmt, arg);
- otf_error = err;
- return 0;
-}
-
-void
-otf_perror (char *prefix)
-{
- if (otf_error == 0)
- error_message = error_string[0];
- if (prefix)
- fprintf (stderr, "%s: %s\n", prefix, error_message);
- else
- fprintf (stderr, "%s\n", error_message);
-}
+++ /dev/null
-#define OTF_ERROR(err, arg) \
- return (otf__error ((err), errfmt, (arg)), errret)
-
-extern int otf__error (int err, char *fmt, void *arg);
-