if (argc != 2)
{
- fprintf (stderr, "Usage, dtfdump OTF-FILE");
+ fprintf (stderr, "Usage, otfdump OTF-FILE");
exit (1);
}
break;
case 7:
+ IPRINT ("(ExtensionLookupType %d)",
+ subtable->u.extension1.ExtensionLookupType);
+ IPRINT ("(ExtensionOffset %d)",
+ subtable->u.extension1.ExtensionOffset);
+ dump_lookup_subtable_gsub (indent, index,
+ subtable->u.extension1.ExtensionLookupType,
+ (subtable
+ + subtable->u.extension1.ExtensionOffset));
+ break;
+
case 8:
printf (" not-yet-substcount");
break;
#include <stdio.h>
+#include <unistd.h>
#include <string.h>
#include <dirent.h>
}
int
-main ()
+main (int argc, char **argv)
{
struct dirent **namelist;
- int n = scandir (".", &namelist, filter, alphasort);
+ int n;
int i, j;
FT_Library ft_library;
FT_Face face;
if (FT_Init_FreeType (&ft_library))
exit (1);
+ if (argc == 2)
+ chdir (argv[1]);
+ n = scandir (".", &namelist, filter, alphasort);
+
for (i = 0; i < n; i++)
if (! FT_New_Face (ft_library, namelist[i]->d_name, 0, &face))
{
- printf ("%s: %s: %s\n", namelist[i]->d_name,
- face->family_name, face->style_name);
- if (face->num_charmaps == 0)
- continue;
+ char *name = alloca (strlen (namelist[i]->d_name)
+ + strlen (face->family_name)
+ + 4);
+ sprintf (name, "%s (%s)", namelist[i]->d_name, face->family_name);
+ printf ("%-40s %s", name, face->style_name);
for (j = 0; j < face->num_charmaps; j++)
- {
- if (face->charmaps[j]->encoding == ft_encoding_symbol)
- printf (" symbol");
- else if (face->charmaps[j]->encoding == ft_encoding_unicode)
- printf (" unicode");
- else if (face->charmaps[j]->encoding == ft_encoding_latin_1)
- printf (" latin_1");
- else if (face->charmaps[j]->encoding == ft_encoding_latin_2)
- printf (" latin_2");
- else if (face->charmaps[j]->encoding == ft_encoding_sjis)
- printf (" sjis");
- else if (face->charmaps[j]->encoding == ft_encoding_gb2312)
- printf (" gb2312");
- else if (face->charmaps[j]->encoding == ft_encoding_big5)
- printf (" big5");
- else if (face->charmaps[j]->encoding == ft_encoding_wansung)
- printf (" wansung");
- else if (face->charmaps[j]->encoding == ft_encoding_johab)
- printf (" johab");
- else if (face->charmaps[j]->encoding == ft_encoding_adobe_standard)
- printf (" adobe_standard");
- else if (face->charmaps[j]->encoding == ft_encoding_adobe_expert)
- printf (" adobe_expert");
- else if (face->charmaps[j]->encoding == ft_encoding_adobe_custom)
- printf (" adobe_custom");
- else if (face->charmaps[j]->encoding == ft_encoding_apple_roman)
- printf (" apple_roman");
- else if (face->charmaps[j]->encoding == ft_encoding_none)
- printf (" none");
- else
- printf (" 0x%X", (unsigned) face->charmaps[j]->encoding);
- printf ("(%d-%d),", face->charmaps[j]->platform_id,
- face->charmaps[j]->encoding_id);
- }
+ printf (" %d-%d", face->charmaps[j]->platform_id,
+ face->charmaps[j]->encoding_id);
printf ("\n");
}
+ else
+ {
+ printf ("%s fail to open\n", namelist[i]->d_name);
+ }
exit (0);
}
XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i);
}
- XtSetArg (arg[0], XtNlabel, "<< (P)");
+ XtSetArg (arg[0], XtNlabel, "-0x1000 (P)");
XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
navi_area, arg, 2);
XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
- XtSetArg (arg[0], XtNlabel, "< (p)");
+ XtSetArg (arg[0], XtNlabel, "-0x80 (p)");
XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
prev = XtCreateManagedWidget ("prev", commandWidgetClass,
navi_area, arg, 2);
XtSetArg (arg[0], XtNlabel, " 0000 ");
label = XtCreateManagedWidget ("label", labelWidgetClass,
navi_area, arg, 1);
- XtSetArg (arg[0], XtNlabel, "(n) >");
+ XtSetArg (arg[0], XtNlabel, "+0x80 (n)");
XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
next = XtCreateManagedWidget ("next", commandWidgetClass,
navi_area, arg, 2);
XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
- XtSetArg (arg[0], XtNlabel, "(N) >>");
+ XtSetArg (arg[0], XtNlabel, "+0x1000 (N)");
XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
navi_area, arg, 2);
int i;
int pixel_size = DEFAULT_PIXEL_SIZE;
+ {
+ char *str = getenv ("PIXEL_SIZE");
+
+ if (str && (i = atoi (str)) > 0)
+ pixel_size = i;
+ }
+
gstring.size = gstring.used = 256;
g = calloc (256, sizeof (OTF_Glyph));
gstring.glyphs = g;
(3-5) OTF_drive_gpos()
(3-6) OTF_drive_tables()
- (4) API for error handling
+ (4) API for error handling
(4-1) Error codes
(4-2) OTF_perror()
OTF_Reserved = 0x00F0,
OTF_MarkAttachmentType = 0xFF00
};
-
+
typedef struct
{
OTF_Offset offset;
typedef struct
{
unsigned ExtensionLookupType;
- unsigned ExtentionOffset;
+ unsigned ExtensionOffset;
+ OTF_LookupSubTableGSUB *ExtensionSubtable;
} OTF_GSUB_Extension1;
typedef struct
OTF_Coverage *LookAhead;
unsigned GlyphCount;
OTF_GlyphID *Substitute;
-} OTF_GSUB_ReverseChainSingle1;
+} OTF_GSUB_ReverseChain1;
struct OTF_LookupSubTableGSUB
{
/* LookupType 7 */
OTF_GSUB_Extension1 extension1;
/* LookupType 8 */
- OTF_GSUB_ReverseChainSingle1 reverse_chain_single1;
+ OTF_GSUB_ReverseChain1 reverse_chain1;
} u;
};
typedef struct
{
unsigned ValueFormat;
- OTF_ValueRecord Value;
+ OTF_ValueRecord Value;
} OTF_GPOS_Single1;
typedef struct
/* MarkAttachClassDef of the glyph. The value is extracted from the
GDEF table. */
- unsigned MarkAttachClass;
+ unsigned MarkAttachClass;
/* Positioning format type of the glyph. The value specifies how
the glyph positioning information is encoded in the member <f>.
}
static int
-get_feature_index (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList,
- char *features, int *feature_index)
+setup_lookup_indices (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList,
+ char *features, int *lookup_indices)
{
- int nfeatures = 0;
+ int i, j, n = 0;
+ OTF_Feature *feature;
if (features)
{
for (p1 = p0; *p1; p1++)
if (*p1 == ',')
*p1 = '\0';
-
- while (len > 0)
+
+ while (p0 < p1)
{
int this_len = strlen (p0) + 1;
OTF_Tag tag = OTF_tag (p0);
if (tag)
- {
- int i;
-
- for (i = 0; i < FeatureList->FeatureCount; i++)
- if (tag == FeatureList->Feature[i].FeatureTag)
- {
- feature_index[nfeatures++] = i;
- if (nfeatures == FeatureList->FeatureCount)
- break;
- }
- }
+ for (i = 0; i < FeatureList->FeatureCount; i++)
+ {
+ feature = FeatureList->Feature + i;
+ if (tag == feature->FeatureTag)
+ for (j = 0; j < feature->LookupCount; j++)
+ {
+ lookup_indices[feature->LookupListIndex[j]] = 1;
+ n++;
+ }
+ }
p0 += this_len;
- len -= this_len;
}
}
else
{
- for (; nfeatures < LangSys->FeatureCount; nfeatures++)
- feature_index[nfeatures] = LangSys->FeatureIndex[nfeatures];
+ for (i = 0; i < LangSys->FeatureCount; i++)
+ {
+ feature = FeatureList->Feature + LangSys->FeatureIndex[i];
+ for (j = 0; j < feature->LookupCount; j++)
+ {
+ lookup_indices[feature->LookupListIndex[j]] = 1;
+ n++;
+ }
+ }
}
- return nfeatures;
+ return (n > 0);
}
static int
/* Try all subtables until one of them handles the current glyph. */
for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
{
+ unsigned lookup_type = lookup->LookupType;
OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
int coverage_idx;
+ if (lookup_type == 7)
+ {
+ OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
+
+ lookup_type = extension1->ExtensionLookupType;
+ subtable = extension1->ExtensionSubtable;
+ }
+
if (subtable->Coverage.offset)
{
coverage_idx = get_coverage_index (&subtable->Coverage,
else
OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
break;
-
+
case 5:
if (subtable->Format == 1)
{
- OTF_GSUB_Context1 *context1 = &subtable->u.context1;
+ OTF_GSUB_Context1 *context1 = &subtable->u.context1;
OTF_RuleSet *set = context1->RuleSet + coverage_idx;
OTF_Rule *rule;
int orig_used;
}
else if (subtable->Format == 2)
{
- OTF_GSUB_Context2 *context2 = &subtable->u.context2;
+ OTF_GSUB_Context2 *context2 = &subtable->u.context2;
OTF_ClassSet *set;
OTF_ClassRule *rule;
unsigned class;
}
else /* subtable->Format == 3 */
{
- OTF_GSUB_Context3 *context3 = &subtable->u.context3;
+ OTF_GSUB_Context3 *context3 = &subtable->u.context3;
int orig_used;
int j, k;
case 6:
if (subtable->Format == 1)
- OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (not yet supported)");
+ {
+ OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
+ OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
+ OTF_ChainRule *rule;
+ int j, k;
+
+ for (j = 0; j < set->ChainRuleCount; j++)
+ {
+ rule = set->ChainRule + j;
+ }
+ }
else if (subtable->Format == 2)
{
OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
}
break;
+ case 8:
+ {
+ OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
+ int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
+ int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
+ int j;
+
+ if (back_gidx > gstring->used || ahead_gidx < 0)
+ break;
+
+ for (j = 0; j < reverse->BacktrackGlyphCount; j++)
+ if (get_coverage_index (reverse->Backtrack + j,
+ gstring->glyphs[gidx + 1 + j].glyph_id)
+ < 0)
+ break;
+ if (j < reverse->BacktrackGlyphCount)
+ continue;
+ for (j = 0; j < reverse->LookaheadGlyphCount; j++)
+ if (get_coverage_index (reverse->LookAhead + j,
+ gstring->glyphs[gidx - 1 - j].glyph_id)
+ < 0)
+ break;
+ if (j < reverse->LookaheadGlyphCount)
+ continue;
+ g->glyph_id = reverse->Substitute[coverage_idx];
+ gidx--;
+ }
+
default:
continue;
}
else
OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
break;
-
+
case 5:
OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
break;
int errret = -1;
OTF_GSUB *gsub;
OTF_LangSys *LangSys;
- int nfeatures;
- int *feature_index;
- int i, j;
+ int *lookup_indices;
+ int i;
if (! otf->gsub
&& OTF_get_table (otf, "GSUB") < 0)
if (! LangSys)
return errret;
- feature_index = alloca (sizeof (int) * gsub->FeatureList.FeatureCount);
- if (! feature_index)
+ i = gsub->LookupList.LookupCount;
+ lookup_indices = alloca (sizeof (int) * i);
+ if (! lookup_indices)
OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
+ memset (lookup_indices, 0, sizeof (int) * i);
+ if (setup_lookup_indices (LangSys, &gsub->FeatureList,
+ features, lookup_indices) < 0)
+ OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " no lookups");
- nfeatures = get_feature_index (LangSys, &gsub->FeatureList,
- features, feature_index);
- if (nfeatures == 0)
- OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " no feature");
-
- for (i = 0; i < nfeatures; i++)
- {
- OTF_Feature *feature = gsub->FeatureList.Feature + feature_index[i];
-
- for (j = 0; j < feature->LookupCount; j++)
- {
- int gidx = 0;
+ for (i = 0; i < gsub->LookupList.LookupCount; i++)
+ if (lookup_indices[i])
+ {
+ int gidx;
- while (gidx < gstring->used)
- {
- gidx = lookup_gsub (&gsub->LookupList,
- feature->LookupListIndex[j], gstring, gidx);
- if (gidx < 0)
- return errret;
- }
- }
- }
+ if (gsub->LookupList.Lookup[i].LookupType != 8)
+ {
+ gidx = 0;
+ while (gidx < gstring->used)
+ {
+ gidx = lookup_gsub (&gsub->LookupList, i, gstring, gidx);
+ if (gidx < 0)
+ return errret;
+ }
+ }
+ else
+ {
+ gidx = gstring->used - 1;
+ while (gidx >= 0)
+ {
+ gidx = lookup_gsub (&gsub->LookupList, i, gstring, gidx);
+ if (gidx < 0)
+ return errret;
+ }
+ }
+ }
return 0;
}
int errret = -1;
OTF_GPOS *gpos;
OTF_LangSys *LangSys;
- int nfeatures;
- int *feature_index;
- int i, j;
+ int *lookup_indices;
+ int i;
if (! otf->gpos
&& OTF_get_table (otf, "GPOS") < 0)
if (! LangSys)
return errret;
- feature_index = alloca (sizeof (int) * gpos->FeatureList.FeatureCount);
- if (! feature_index)
+ i = gpos->LookupList.LookupCount;
+ lookup_indices = alloca (sizeof (int) * i);
+ if (! lookup_indices)
OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
+ memset (lookup_indices, 0, sizeof (int) * i);
+ if (setup_lookup_indices (LangSys, &gpos->FeatureList,
+ features, lookup_indices) < 0)
+ OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " no lookups");
- nfeatures = get_feature_index (LangSys, &gpos->FeatureList,
- features, feature_index);
- if (nfeatures == 0)
- OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " no feature");
-
- for (i = 0; i < nfeatures; i++)
- {
- OTF_Feature *feature = gpos->FeatureList.Feature + feature_index[i];
-
- for (j = 0; j < feature->LookupCount; j++)
- {
- int gidx = 0;
+ for (i = 0; i < gpos->LookupList.LookupCount; i++)
+ if (lookup_indices[i])
+ {
+ int gidx = 0;
- while (gidx < gstring->used)
- {
- gidx = lookup_gpos (&gpos->LookupList,
- feature->LookupListIndex[j], gstring, gidx);
- if (gidx < 0)
- return errret;
- }
- }
- }
+ while (gidx < gstring->used)
+ {
+ gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx);
+ if (gidx < 0)
+ return errret;
+ }
+ }
return 0;
}
READ_GLYPHID (stream, (*ids)[i]);
return count;
}
-
+
static unsigned
read_range_records (OTF *otf, OTF_Stream *stream, OTF_RangeRecord **record)
{
int errret = -1;
OTF_StreamState state;
int count;
-
+
READ_OFFSET (stream, coverage->offset);
SAVE_STREAM (stream, state);
SEEK_STREAM (stream, offset + coverage->offset);
char *errfmt = "ClassDef%s";
int errret = -1;
OTF_StreamState state;
-
+
READ_OFFSET (stream, class->offset);
if (! class->offset)
return 0;
for (k = 0; k < langsys->FeatureCount; k++)
READ_USHORT (stream, langsys->FeatureIndex[k]);
}
-
+
for (j = 0; j < script->LangSysCount; j++)
{
OTF_LangSys *langsys = script->LangSys + j;
= read_glyph_ids (otf, stream,
(OTF_GlyphID **) &(*rule)[i].LookAhead, 0, -1);
(*rule)[i].LookupCount
- = read_lookup_record_list (otf, stream,
+ = read_lookup_record_list (otf, stream,
&(*rule)[i].LookupRecord, -1);
if (! (*rule)[i].LookupCount)
return errret;
return count;
}
-static int
+static int
+read_reverse_chain1 (OTF *otf, OTF_Stream *stream, long offset,
+ OTF_Coverage *coverage,
+ OTF_GSUB_ReverseChain1 *reverse_chain)
+{
+ int count;
+
+ if (read_coverage (otf, stream, offset, coverage) < 0)
+ return -1;
+ count = read_coverage_list (otf, stream, offset,
+ &reverse_chain->Backtrack, -1);
+ if (count < 0)
+ return -1;
+ reverse_chain->BacktrackGlyphCount = (unsigned) count;
+ count = read_coverage_list (otf, stream, offset,
+ &reverse_chain->LookAhead, -1);
+ if (count <= 0)
+ return -1;
+ reverse_chain->LookaheadGlyphCount = (unsigned) count;
+ count = read_glyph_ids (otf, stream, &reverse_chain->Substitute, 0, -1);
+ if (count <= 0)
+ return -1;
+ reverse_chain->GlyphCount = count;
+ return 0;
+}
+
+static int
read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
unsigned type, OTF_LookupSubTableGSUB *subtable)
{
int errret = -1;
SEEK_STREAM (stream, offset);
- READ_UINT16 (stream, subtable->Format);
+ READ_USHORT (stream, subtable->Format);
sprintf (errfmt, "GSUB Lookup %d-%d%%s", type, subtable->Format);
switch (type)
{
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
-
+
case 3:
if (subtable->Format == 1)
{
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
-
+
case 6:
if (subtable->Format == 1)
{
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
-
+
case 7:
+ if (subtable->Format == 1)
+ {
+ unsigned ex_type;
+ long ex_offset;
+ OTF_LookupSubTableGSUB *ex_subtable;
+
+ READ_USHORT (stream, ex_type);
+ READ_ULONG (stream, ex_offset);
+ OTF_CALLOC (ex_subtable, 1, " (SubTable)");
+ if (read_lookup_subtable_gsub (otf, stream, offset + ex_offset,
+ ex_type, ex_subtable) < 0)
+ return errret;
+ subtable->u.extension1.ExtensionLookupType = ex_type;
+ subtable->u.extension1.ExtensionOffset = ex_offset;
+ subtable->u.extension1.ExtensionSubtable = ex_subtable;
+ }
+ else
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
+ break;
+
case 8:
- OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
+ if (subtable->Format == 1)
+ {
+ if (read_reverse_chain1 (otf, stream, offset, &subtable->Coverage,
+ &subtable->u.reverse_chain1) < 0)
+ return errret;
+ }
+ else
+ OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
default:
int errret = -1;
OTF_StreamState state;
int i;
-
+
READ_OFFSET (stream, array->offset);
SAVE_STREAM (stream, state);
SEEK_STREAM (stream, offset + array->offset);
int errret = -1;
OTF_StreamState state;
int i, j;
-
+
READ_OFFSET (stream, array->offset);
SAVE_STREAM (stream, state);
SEEK_STREAM (stream, offset + array->offset);
return rec;
}
-static int
+static int
read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream,
long offset, unsigned type,
OTF_LookupSubTableGPOS *subtable)
else
OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
break;
-
+
case 3:
OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
break;
int
read_offset_table (OTF *otf, OTF_Stream *stream, OTF_OffsetTable *table)
-{
+{
int errret = -1;
READ_FIXED (stream, table->sfnt_version);
return -1;
internal_data->header_stream = stream;
-
+
/* Size of Offset Table is 12 bytes. */
if (setup_stream (stream, fp, 0, 12, "Offset Table") < 0)
return -1;