Skip to content
This repository has been archived by the owner on Jun 4, 2022. It is now read-only.

Commit

Permalink
Merge branch 'master' into releases
Browse files Browse the repository at this point in the history
  • Loading branch information
be5invis committed Oct 4, 2016
2 parents ccf7977 + 00680e5 commit 886c502
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 59 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ Usage : otfccbuild [OPTIONS] [input.json] -o output.[ttf|otf]
--ignore-glyph-order
--short-post
--merge-features
-O3 Most aggressive opptimization strategy will be
used. In this level, these options will be set:
--force-cid
--subroutinize
--time : Time each substep.
--verbose : Show more information when building.
Expand All @@ -98,6 +102,10 @@ Usage : otfccbuild [OPTIONS] [input.json] -o output.[ttf|otf]
--dont-merge-features : Keep duplicate OpenType feature definitions.
--merge-lookups : Merge duplicate OpenType lookups.
--dont-merge-lookups : Keep duplicate OpenType lookups.
--force-cid : Convert name-keyed CFF OTF into CID-keyed.
--subroutinize : Subroutinize CFF table.
--stub-cmap4 : Create a stub `cmap` format 4 subtable if format
12 subtable is present.
```

## Building
Expand Down
6 changes: 3 additions & 3 deletions lib/font/caryll-font.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ caryll_font_subtype caryll_decideFontSubtype(caryll_SplineFontContainer *sfnt, u
return FONTTYPE_TTF;
}

caryll_Font *caryll_read_Font(caryll_SplineFontContainer *sfnt, uint32_t index) {
caryll_Font *caryll_read_Font(caryll_SplineFontContainer *sfnt, uint32_t index, caryll_Options *options) {
if (sfnt->count - 1 < index)
return NULL;
else {
Expand Down Expand Up @@ -103,8 +103,8 @@ caryll_Font *caryll_read_Font(caryll_SplineFontContainer *sfnt, uint32_t index)
}
}
if (font->glyf) {
font->GSUB = table_read_otl(packet, 'GSUB');
font->GPOS = table_read_otl(packet, 'GPOS');
font->GSUB = table_read_otl(packet, options, 'GSUB');
font->GPOS = table_read_otl(packet, options, 'GPOS');
font->GDEF = table_read_GDEF(packet);
}
font->BASE = table_read_BASE(packet);
Expand Down
2 changes: 1 addition & 1 deletion lib/font/caryll-font.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ caryll_font_subtype caryll_decideFontSubtype(caryll_SplineFontContainer *sfnt, u
caryll_font_subtype caryll_decideFontSubtypeFromJson(json_value *root);
caryll_Font *caryll_new_Font();
void caryll_delete_Font(caryll_Font *font);
caryll_Font *caryll_read_Font(caryll_SplineFontContainer *sfnt, uint32_t index);
caryll_Font *caryll_read_Font(caryll_SplineFontContainer *sfnt, uint32_t index, caryll_Options *options);
json_value *caryll_dump_Font(caryll_Font *font, caryll_Options *options);
caryll_Font *caryll_parse_Font(json_value *root, caryll_Options *options);
caryll_buffer *caryll_build_Font(caryll_Font *font, caryll_Options *options);
Expand Down
25 changes: 21 additions & 4 deletions lib/fontops/consolidate.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ static int by_mask_pointindex(const void *a, const void *b) {
return ((glyf_PostscriptHintMask *)a)->pointsBefore - ((glyf_PostscriptHintMask *)b)->pointsBefore;
}
void caryll_font_consolidate_glyph(glyf_Glyph *g, caryll_Font *font) {
// The name field of glyf_Glyph will not be consolidated with glyphOrder
// Consolidate references
shapeid_t nReferencesConsolidated = 0;
for (shapeid_t j = 0; j < g->numberOfReferences; j++) {
caryll_GlyphOrderEntry *entry = NULL;
Expand All @@ -41,7 +43,8 @@ void caryll_font_consolidate_glyph(glyf_Glyph *g, caryll_Font *font) {
g->references = NULL;
g->numberOfReferences = 0;
} else {
glyf_ComponentReference *consolidatedReferences = calloc(nReferencesConsolidated, sizeof(glyf_ComponentReference));
glyf_ComponentReference *consolidatedReferences =
calloc(nReferencesConsolidated, sizeof(glyf_ComponentReference));
for (shapeid_t j = 0, k = 0; j < g->numberOfReferences; j++) {
if (g->references[j].glyph.name) { consolidatedReferences[k++] = g->references[j]; }
}
Expand Down Expand Up @@ -133,7 +136,7 @@ void caryll_font_consolidate_glyf(caryll_Font *font) {
}

void caryll_font_consolidate_cmap(caryll_Font *font) {
if (font->glyph_order && font->cmap) {
if (font->glyph_order && font->cmap) {
cmap_Entry *item;
foreach_hash(item, *font->cmap) {
if (item->glyph.name) {
Expand Down Expand Up @@ -201,8 +204,7 @@ void caryll_consolidate_lookup(caryll_Font *font, table_OTL *table, otl_Lookup *
LOOKUP_CONSOLIDATOR(otl_type_gpos_chaining, consolidate_chaining, otl_delete_chaining);
LOOKUP_CONSOLIDATOR(otl_type_gpos_markToBase, consolidate_mark_to_single, otl_delete_gpos_markToSingle);
LOOKUP_CONSOLIDATOR(otl_type_gpos_markToMark, consolidate_mark_to_single, otl_delete_gpos_markToSingle);
LOOKUP_CONSOLIDATOR(otl_type_gpos_markToLigature, consolidate_mark_to_ligature,
otl_delete_gpos_markToLigature);
LOOKUP_CONSOLIDATOR(otl_type_gpos_markToLigature, consolidate_mark_to_ligature, otl_delete_gpos_markToLigature);
}

void caryll_font_consolidate_otl(caryll_Font *font) {
Expand All @@ -218,6 +220,21 @@ void caryll_font_consolidate_otl(caryll_Font *font) {
}

void caryll_font_consolidate(caryll_Font *font, const caryll_Options *options) {
// In case we don’t have a glyph order, make one.
if (font->glyf && !font->glyph_order) {
caryll_GlyphOrder *go = caryll_new_GlyphOrder();
for (glyphid_t j = 0; j < font->glyf->numberGlyphs; j++) {
sds name;
sds glyfName = font->glyf->glyphs[j]->name;
if (glyfName) {
name = sdsdup(glyfName);
} else {
name = sdscatprintf(sdsempty(), "__gid%d", j);
font->glyf->glyphs[j]->name = sdsdup(name);
}
caryll_setGlyphOrderByName(go, name, j);
}
}
caryll_font_consolidate_glyf(font);
caryll_font_consolidate_cmap(font);
if (font->glyf) caryll_font_consolidate_otl(font);
Expand Down
6 changes: 2 additions & 4 deletions lib/fontops/otl/gsub-single.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ bool consolidate_gsub_single(caryll_Font *font, table_OTL *table, otl_Subtable *
subtable_gsub_single *subtable = &(_subtable->gsub_single);
fontop_consolidateCoverage(font, subtable->from, lookupName);
fontop_consolidateCoverage(font, subtable->to, lookupName);
glyphid_t len =subtable->to->numGlyphs;
if(subtable->from->numGlyphs < subtable->to->numGlyphs){
len = subtable->from->numGlyphs;
}
glyphid_t len = subtable->to->numGlyphs;
if (subtable->from->numGlyphs < subtable->to->numGlyphs) { len = subtable->from->numGlyphs; }
gsub_single_map_hash *h = NULL;
for (glyphid_t k = 0; k < len; k++) {
if (subtable->from->glyphs[k].name && subtable->to->glyphs[k].name) {
Expand Down
14 changes: 8 additions & 6 deletions lib/fontops/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,12 +572,14 @@ void caryll_font_stat(caryll_Font *font, const caryll_Options *options) {
}
if (font->glyf && font->maxp) { font->maxp->numGlyphs = font->glyf->numberGlyphs; }
if (font->glyf && font->post) { font->post->maxMemType42 = font->glyf->numberGlyphs; }
if (font->glyf && font->maxp && font->maxp->version == 0x10000) caryll_stat_maxp(font);
if (font->fpgm && font->maxp && font->fpgm->length > font->maxp->maxSizeOfInstructions) {
font->maxp->maxSizeOfInstructions = font->fpgm->length;
}
if (font->prep && font->maxp && font->prep->length > font->maxp->maxSizeOfInstructions) {
font->maxp->maxSizeOfInstructions = font->prep->length;
if (font->glyf && font->maxp && font->maxp->version == 0x10000) {
caryll_stat_maxp(font);
if (font->fpgm && font->fpgm->length > font->maxp->maxSizeOfInstructions) {
font->maxp->maxSizeOfInstructions = font->fpgm->length;
}
if (font->prep && font->prep->length > font->maxp->maxSizeOfInstructions) {
font->maxp->maxSizeOfInstructions = font->prep->length;
}
}
if (font->OS_2 && font->cmap && font->glyf) caryll_font_stat_OS_2(font, options);
if (font->subtype == FONTTYPE_TTF) {
Expand Down
12 changes: 10 additions & 2 deletions lib/support/glyph-order.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ void caryll_setGlyphOrderByNameWithOrder(caryll_GlyphOrder *go, sds name, uint8_
s->orderEntry = orderEntry;
}
}
static void caryll_escalateGlyphOrderByNameWithOrder(caryll_GlyphOrder *go, sds name, uint8_t orderType, uint32_t orderEntry) {
caryll_GlyphOrderEntry *s = NULL;
HASH_FIND(hhName, go->byName, name, sdslen(name), s);
if (s && s->orderType > orderType) {
s->orderType = orderType;
s->orderEntry = orderEntry;
}
}

static int compare_glyphorder_entry_b(caryll_GlyphOrderEntry *a, caryll_GlyphOrderEntry *b) {
if (a->orderType < b->orderType) return (-1);
Expand Down Expand Up @@ -118,7 +126,7 @@ static void placeOrderEntriesFromCmap(json_value *table, caryll_GlyphOrder *go)
int32_t unicode = atoi(unicodeStr);
if (item->type == json_string && unicode > 0 && unicode <= 0x10FFFF) { // a valid unicode codepoint
sds gname = sdsnewlen(item->u.string.ptr, item->u.string.length);
caryll_setGlyphOrderByNameWithOrder(go, gname, ORD_CMAP, unicode);
caryll_escalateGlyphOrderByNameWithOrder(go, gname, ORD_CMAP, unicode);
}
}
}
Expand All @@ -129,7 +137,7 @@ static void placeOrderEntriesFromSubtable(json_value *table, caryll_GlyphOrder *
json_value *item = table->u.array.values[j];
if (item->type == json_string) {
sds gname = sdsnewlen(item->u.string.ptr, item->u.string.length);
caryll_setGlyphOrderByNameWithOrder(go, gname, ORD_GLYPHORDER, j);
caryll_escalateGlyphOrderByNameWithOrder(go, gname, ORD_GLYPHORDER, j);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/support/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef struct {
bool force_cid;
bool cff_rollCharString;
bool cff_doSubroutinize;
bool stub_cmap4;
char *glyph_name_prefix;
} caryll_Options;

Expand Down
51 changes: 30 additions & 21 deletions lib/tables/cmap.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
#include "cmap.h"

static void encode(table_cmap *map, int c, uint16_t gid) {
void table_encodeCmapByIndex(table_cmap *map, int c, uint16_t gid) {
cmap_Entry *s;
HASH_FIND_INT(*map, &c, s);
if (s == NULL) {
s = malloc(sizeof(cmap_Entry));
s->glyph = handle_fromIndex(gid);
s->unicode = c;
HASH_ADD_INT(*map, unicode, s);
} else {
// Override existing encoding
handle_delete(&s->glyph);
s->glyph = handle_fromIndex(gid);
}
}
void table_encodeCmapByName(table_cmap *map, int c, sds name) {
cmap_Entry *s;
HASH_FIND_INT(*map, &c, s);
if (s == NULL) {
s = malloc(sizeof(cmap_Entry));
s->glyph = handle_fromName(name);
s->unicode = c;
HASH_ADD_INT(*map, unicode, s);
} else {
// Override existing encoding
handle_delete(&s->glyph);
s->glyph = handle_fromName(name);
}
}

static void caryll_read_format_12(font_file_pointer start, uint32_t lengthLimit, table_cmap *map) {
static void readFormat12(font_file_pointer start, uint32_t lengthLimit, table_cmap *map) {
if (lengthLimit < 16) return;
uint32_t nGroups = read_32u(start + 12);
if (lengthLimit < 16 + 12 * nGroups) return;
Expand All @@ -20,12 +38,12 @@ static void caryll_read_format_12(font_file_pointer start, uint32_t lengthLimit,
uint32_t endCode = read_32u(start + 16 + 12 * j + 4);
uint32_t startGID = read_32u(start + 16 + 12 * j + 8);
for (uint32_t c = startCode; c <= endCode; c++) {
encode(map, c, (c - startCode) + startGID);
table_encodeCmapByIndex(map, c, (c - startCode) + startGID);
}
}
}

static void caryll_read_format_4(font_file_pointer start, uint32_t lengthLimit, table_cmap *map) {
static void readFormat4(font_file_pointer start, uint32_t lengthLimit, table_cmap *map) {
if (lengthLimit < 14) return;
uint16_t segmentsCount = read_16u(start + 6) / 2;
if (lengthLimit < 16 + segmentsCount * 8) return;
Expand All @@ -38,25 +56,25 @@ static void caryll_read_format_4(font_file_pointer start, uint32_t lengthLimit,
if (idRangeOffset == 0) {
for (uint32_t c = startCode; c < 0xFFFF && c <= endCode; c++) {
uint16_t gid = (c + idDelta) & 0xFFFF;
encode(map, c, gid);
table_encodeCmapByIndex(map, c, gid);
}
} else {
for (uint32_t c = startCode; c < 0xFFFF && c <= endCode; c++) {
uint32_t glyphOffset = idRangeOffset + (c - startCode) * 2 + idRangeOffsetOffset;
if (glyphOffset + 2 > lengthLimit) continue; // ignore this encoding slot when o-o-r
uint16_t gid = (read_16u(start + glyphOffset) + idDelta) & 0xFFFF;
encode(map, c, gid);
table_encodeCmapByIndex(map, c, gid);
}
}
}
}

static void caryll_read_mapping_table(font_file_pointer start, uint32_t lengthLimit, table_cmap *map) {
static void readCmapMappingTable(font_file_pointer start, uint32_t lengthLimit, table_cmap *map) {
uint16_t format = read_16u(start);
if (format == 4) {
caryll_read_format_4(start, lengthLimit, map);
readFormat4(start, lengthLimit, map);
} else if (format == 12) {
caryll_read_format_12(start, lengthLimit, map);
readFormat12(start, lengthLimit, map);
}
}

Expand All @@ -83,7 +101,7 @@ table_cmap *table_read_cmap(caryll_Packet packet) {
if ((platform == 0 && encoding == 3) || (platform == 0 && encoding == 4) ||
(platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
uint32_t tableOffset = read_32u(data + 4 + 8 * j + 4);
caryll_read_mapping_table(data + tableOffset, length - tableOffset, map);
readCmapMappingTable(data + tableOffset, length - tableOffset, map);
}
};
HASH_SORT(*map, by_unicode);
Expand Down Expand Up @@ -135,16 +153,7 @@ table_cmap *table_parse_cmap(json_value *root, const caryll_Options *options) {
sdsfree(unicodeStr);
if (item->type == json_string && unicode > 0 && unicode <= 0x10FFFF) {
sds gname = sdsnewlen(item->u.string.ptr, item->u.string.length);
cmap_Entry *item = NULL;
HASH_FIND_INT(hash, &unicode, item);
if (!item) {
item = calloc(1, sizeof(cmap_Entry));
item->unicode = unicode;
item->glyph = handle_fromName(gname);
HASH_ADD_INT(hash, unicode, item);
} else {
sdsfree(gname);
}
table_encodeCmapByName(&hash, unicode, gname);
}
}
}
Expand Down Expand Up @@ -326,7 +335,7 @@ caryll_buffer *table_build_cmap(table_cmap *cmap, const caryll_Options *options)
uint32_t offset = 4 + 8 * nTables;
size_t cp = 0;
caryll_buffer *format4;
if (!hasSMP) {
if (!hasSMP || !options->stub_cmap4) {
format4 = table_build_cmap_format4(cmap);
} else {
// Write a dummy
Expand Down
2 changes: 2 additions & 0 deletions lib/tables/cmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ typedef struct {
} cmap_Entry;
typedef cmap_Entry *table_cmap;

void table_encodeCmapByIndex(table_cmap *map, int c, uint16_t gid);
void table_encodeCmapByName(table_cmap *map, int c, sds name);
table_cmap *table_read_cmap(caryll_Packet packet);
void table_delete_cmap(table_cmap *table);
void table_dump_cmap(table_cmap *table, json_value *root, const caryll_Options *options);
Expand Down
39 changes: 29 additions & 10 deletions lib/tables/otl/otl.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ static void parseLanguage(font_file_pointer data, uint32_t tableLength, uint32_t
return;
}

static table_OTL *table_read_otl_common(font_file_pointer data, uint32_t tableLength, otl_LookupType lookup_type_base) {
static table_OTL *table_read_otl_common(font_file_pointer data, uint32_t tableLength, otl_LookupType lookup_type_base,
const caryll_Options *options) {
table_OTL *table = table_new_otl();
if (!table) goto FAIL;
checkLength(10);
Expand Down Expand Up @@ -151,8 +152,13 @@ static table_OTL *table_read_otl_common(font_file_pointer data, uint32_t tableLe
NEW(feature);
features[j] = feature;
uint32_t tag = read_32u(data + featureListOffset + 2 + j * 6);
features[j]->name = sdscatprintf(sdsempty(), "%c%c%c%c_%05d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
(tag >> 8) & 0xff, tag & 0xff, j);
if (options->glyph_name_prefix) {
features[j]->name = sdscatprintf(sdsempty(), "%c%c%c%c_%s_%05d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
(tag >> 8) & 0xff, tag & 0xff, options->glyph_name_prefix, j);
} else {
features[j]->name = sdscatprintf(sdsempty(), "%c%c%c%c_%05d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
(tag >> 8) & 0xff, tag & 0xff, j);
}
uint32_t featureOffset = featureListOffset + read_16u(data + featureListOffset + 2 + j * 6 + 4);

checkLength(featureOffset + 4);
Expand All @@ -165,9 +171,15 @@ static table_OTL *table_read_otl_common(font_file_pointer data, uint32_t tableLe
if (lookupid < table->lookupCount) {
features[j]->lookups[k] = table->lookups[lookupid];
if (!features[j]->lookups[k]->name) {
features[j]->lookups[k]->name =
sdscatprintf(sdsempty(), "lookup_%c%c%c%c_%d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
(tag >> 8) & 0xff, tag & 0xff, lnk++);
if (options->glyph_name_prefix) {
features[j]->lookups[k]->name = sdscatprintf(
sdsempty(), "lookup_%s_%c%c%c%c_%d", options->glyph_name_prefix, (tag >> 24) & 0xFF,
(tag >> 16) & 0xFF, (tag >> 8) & 0xff, tag & 0xff, lnk++);
} else {
features[j]->lookups[k]->name =
sdscatprintf(sdsempty(), "lookup_%c%c%c%c_%d", (tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
(tag >> 8) & 0xff, tag & 0xff, lnk++);
}
}
}
}
Expand Down Expand Up @@ -227,8 +239,14 @@ static table_OTL *table_read_otl_common(font_file_pointer data, uint32_t tableLe
}
// name all lookups
for (tableid_t j = 0; j < table->lookupCount; j++) {
if (!table->lookups[j]->name)
table->lookups[j]->name = sdscatprintf(sdsempty(), "lookup_%02x_%d", table->lookups[j]->type, j);
if (!table->lookups[j]->name) {
if (options->glyph_name_prefix) {
table->lookups[j]->name = sdscatprintf(sdsempty(), "lookup_%s_%02x_%d", options->glyph_name_prefix,
table->lookups[j]->type, j);
} else {
table->lookups[j]->name = sdscatprintf(sdsempty(), "lookup_%02x_%d", table->lookups[j]->type, j);
}
}
}
return table;
FAIL:
Expand Down Expand Up @@ -287,14 +305,15 @@ static void table_read_otl_lookup(font_file_pointer data, uint32_t tableLength,
if (lookup->type == otl_type_gpos_context) lookup->type = otl_type_gpos_chaining;
}

table_OTL *table_read_otl(caryll_Packet packet, uint32_t tag) {
table_OTL *table_read_otl(caryll_Packet packet, const caryll_Options *options, uint32_t tag) {
table_OTL *otl = NULL;
FOR_TABLE(tag, table) {
font_file_pointer data = table.data;
uint32_t length = table.length;
otl = table_read_otl_common(
data, length,
(tag == 'GSUB' ? otl_type_gsub_unknown : tag == 'GPOS' ? otl_type_gpos_unknown : otl_type_unknown));
(tag == 'GSUB' ? otl_type_gsub_unknown : tag == 'GPOS' ? otl_type_gpos_unknown : otl_type_unknown),
options);
if (!otl) goto FAIL;
for (tableid_t j = 0; j < otl->lookupCount; j++) {
table_read_otl_lookup(data, length, otl->lookups[j]);
Expand Down
Loading

0 comments on commit 886c502

Please sign in to comment.