char *errfmt = "cmap%s";
void *errret = NULL;
OTF_cmap *cmap;
- int unicode_index = -1;
+ int unicode_bmp_index = -1, unicode_full_index = -1;
int i;
OTF_CALLOC (cmap, 1, "");
OTF_MALLOC (cmap->EncodingRecord, cmap->numTables, "");
for (i = 0; i < cmap->numTables; i++)
{
- READ_USHORT (stream, cmap->EncodingRecord[i].platformID);
- READ_USHORT (stream, cmap->EncodingRecord[i].encodingID);
+ unsigned platformID, encodingID;
+
+ READ_USHORT (stream, platformID);
+ cmap->EncodingRecord[i].platformID = platformID;
+ READ_USHORT (stream, encodingID);
+ cmap->EncodingRecord[i].encodingID = encodingID;
READ_ULONG (stream, cmap->EncodingRecord[i].offset);
- if (cmap->EncodingRecord[i].platformID == 3
- && cmap->EncodingRecord[i].encodingID == 1)
- unicode_index = i;
+ if (platformID == 0)
+ {
+ if (encodingID <= 3)
+ unicode_bmp_index = i;
+ else
+ unicode_full_index = i;
+ }
+ else if (platformID == 3)
+ {
+ if (encodingID == 1)
+ unicode_bmp_index = i;
+ else if (encodingID == 10)
+ unicode_full_index = i;
+ }
}
for (i = 0; i < cmap->numTables; i++)
{
break;
case 2:
+ {
+ OTF_EncodingSubtable2 *sub2;
+ int j, max_key, remaining_bytes;
+
+ OTF_MALLOC (sub2, 1, " (EncodingSubtable2)");
+ cmap->EncodingRecord[i].subtable.f.f2 = sub2;
+ for (j = 0, max_key = 0; j < 256; j++)
+ {
+ READ_USHORT (stream, sub2->subHeaderKeys[j]);
+ if (max_key < sub2->subHeaderKeys[j])
+ max_key = sub2->subHeaderKeys[j];
+ }
+ max_key += 8;
+ sub2->subHeaderCount = max_key / 8;
+ OTF_MALLOC (sub2->subHeaders, max_key / 8, " (subHeaders)");
+ for (j = 0; j < sub2->subHeaderCount; j++)
+ {
+ READ_USHORT (stream, sub2->subHeaders[j].firstCode);
+ READ_USHORT (stream, sub2->subHeaders[j].entryCount);
+ READ_SHORT (stream, sub2->subHeaders[j].idDelta);
+ READ_USHORT (stream, sub2->subHeaders[j].idRangeOffset);
+ /* Make it offset from sub2->glyphIndexArray. */
+ sub2->subHeaders[j].idRangeOffset -= max_key - (j * 8 + 6);
+ }
+ sub2->glyphIndexCount = (cmap->EncodingRecord[i].subtable.length
+ - 262 - max_key);
+ OTF_MALLOC (sub2->glyphIndexArray, sub2->glyphIndexCount,
+ " (glyphIndexArray)");
+ READ_BYTES (stream, sub2->glyphIndexArray, sub2->glyphIndexCount);
+ }
break;
case 4:
for (j = 0; j < sub6->entryCount; j++)
READ_USHORT (stream, sub6->glyphIdArray[j]);
}
+ break;
+
+ case 8:
+ {
+ OTF_EncodingSubtable8 *sub8;
+ int j;
+
+ OTF_MALLOC (sub8, 1, " (EncodingSubtable8)");
+ cmap->EncodingRecord[i].subtable.f.f8 = sub8;
+ for (j = 0; j < 8192; j++)
+ READ_BYTES (stream, sub8->is32, 8192);
+ READ_ULONG (stream, sub8->nGroups);
+ OTF_MALLOC (sub8->Groups, sub8->nGroups, " (Groups)");
+ for (j = 0; j < sub8->nGroups; j++)
+ {
+ READ_ULONG (stream, sub8->Groups[i].startCharCode);
+ READ_ULONG (stream, sub8->Groups[i].endCharCode);
+ READ_ULONG (stream, sub8->Groups[i].startGlyphID);
+ }
+ }
+ break;
+
+ case 10:
+ {
+ OTF_EncodingSubtable10 *sub10;
+ int j;
+
+ OTF_MALLOC (sub10, 1, " (EncodingSubtable10)");
+ cmap->EncodingRecord[i].subtable.f.f10 = sub10;
+ READ_ULONG (stream, sub10->startCharCode);
+ READ_ULONG (stream, sub10->numChars);
+ OTF_MALLOC (sub10->glyphs, sub10->numChars, " (GlyphCount)");
+ for (j = 0; j < sub10->numChars; j++)
+ READ_USHORT (stream, sub10->glyphs[j]);
+ }
+ break;
+
+ case 12:
+ {
+ OTF_EncodingSubtable12 *sub12;
+ int j;
+
+ OTF_MALLOC (sub12, 1, " (EncodingSubtable12)");
+ cmap->EncodingRecord[i].subtable.f.f12 = sub12;
+ READ_ULONG (stream, sub12->nGroups);
+ OTF_MALLOC (sub12->Groups, sub12->nGroups, " (Groups)");
+ for (j = 0; j < sub12->nGroups; j++)
+ {
+ READ_ULONG (stream, sub12->Groups[i].startCharCode);
+ READ_ULONG (stream, sub12->Groups[i].endCharCode);
+ READ_ULONG (stream, sub12->Groups[i].startGlyphID);
+ }
+ }
+ break;
+
+ default:
+ OTF_ERROR (OTF_ERROR_TABLE, " (invalid Subtable format)");
}
}
- if (unicode_index >= 0)
+ if (unicode_bmp_index >= 0)
{
- OTF_EncodingRecord *rec = cmap->EncodingRecord + unicode_index;
+ OTF_EncodingRecord *rec = cmap->EncodingRecord + unicode_bmp_index;
OTF_GlyphID glyph_id, max_glyph_id = 0;
OTF_CALLOC (cmap->unicode_table, 0x10000, "");
READ_UINT16 (stream, count);
if (! count)
OTF_ERROR (OTF_ERROR_TABLE, " (zero count)");
- OTF_MALLOC (*set, count, "");
+ OTF_CALLOC (*set, count, "");
for (i = 0; i < count; i++)
/* Offset can be zero. */
READ_OFFSET (stream, (*set)[i].offset);
if (bit & OTF_XPlacement)
READ_INT16 (stream, value_record->XPlacement);
- if (bit & OTF_XPlacement)
+ if (bit & OTF_YPlacement)
READ_INT16 (stream, value_record->YPlacement);
if (bit & OTF_XAdvance)
READ_INT16 (stream, value_record->XAdvance);
}
for (i = 0; i < attach->ComponentCount; i++)
for (j = 0; j < ClassCount; j++)
- if (read_anchor (otf, stream, offset + attach->offset,
- &attach->ComponentRecord[i].LigatureAnchor[j]) < 0)
- return -1;
+ {
+ if (attach->ComponentRecord[i].LigatureAnchor[j].offset)
+ {
+ if (read_anchor (otf, stream, offset + attach->offset,
+ &attach->ComponentRecord[i].LigatureAnchor[j]) < 0)
+ return -1;
+ }
+ else
+ attach->ComponentRecord[i].LigatureAnchor[j].AnchorFormat = 0;
+ }
return 0;
}
void *errret = NULL;
OTF *otf;
OTF_InternalData *internal_data;
-
+ int len = strlen (otf_name);
+ const char *ext = otf_name + (len - 4);
+
+ if (len < 4
+ || ext[0] != '.'
+ || (ext[1] != 'O' && ext[1] != 'T' && ext[1] != 'o' && ext[1] != 't')
+ || (ext[2] != 'T' && ext[2] != 't')
+ || (ext[3] != 'F' && ext[3] != 'f'))
+ OTF_ERROR (OTF_ERROR_FILE, otf_name);
fp = fopen (otf_name, "r");
if (! fp)
OTF_ERROR (OTF_ERROR_FILE, otf_name);