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 Jan 4, 2018
2 parents 69aba5c + ac4ecec commit c4dc465
Show file tree
Hide file tree
Showing 23 changed files with 114 additions and 67 deletions.
1 change: 1 addition & 0 deletions include/otfcc/table/otl/coverage.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct __otfcc_ICoverage {
json_value *(*dump)(const otl_Coverage *coverage);
otl_Coverage *(*parse)(const json_value *cov);
caryll_Buffer *(*build)(const otl_Coverage *coverage);
caryll_Buffer *(*buildFormat)(const otl_Coverage *coverage, uint16_t format);
void (*shrink)(otl_Coverage *coverage, bool dosort);
void (*push)(otl_Coverage *coverage, MOVE otfcc_GlyphHandle h);
};
Expand Down
83 changes: 51 additions & 32 deletions lib/table/otl/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,43 @@

#define LARGE_SUBTABLE_LIMIT 4096

static tableid_t _declare_lookup_writer(otl_LookupType type,
caryll_Buffer *(*fn)(const otl_Subtable *_subtable),
static uint32_t featureNameToTag(const sds name) {
uint32_t tag = 0;
if (sdslen(name) > 0) {
tag |= ((uint8_t)name[0]) << 24;
} else {
tag |= ((uint8_t)' ') << 24;
}
if (sdslen(name) > 1) {
tag |= ((uint8_t)name[1]) << 16;
} else {
tag |= ((uint8_t)' ') << 16;
}
if (sdslen(name) > 2) {
tag |= ((uint8_t)name[2]) << 8;
} else {
tag |= ((uint8_t)' ') << 8;
}
if (sdslen(name) > 3) {
tag |= ((uint8_t)name[3]) << 0;
} else {
tag |= ((uint8_t)' ') << 0;
}
return tag;
}

typedef caryll_Buffer *(*_otl_Builder)(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

static tableid_t _declare_lookup_writer(otl_LookupType type, _otl_Builder fn,
const otl_Lookup *lookup, caryll_Buffer ***subtables,
size_t *lastOffset, bool *preferExtensionForThisLUT) {
size_t *lastOffset, bool *preferExtensionForThisLUT,
otl_BuildHeuristics heuristics) {
if (lookup->type == type) {
NEW(*subtables, lookup->subtables.length);
size_t totalBufSizeShort = 0;
size_t totalBufSizeExt = 0;
for (tableid_t j = 0; j < lookup->subtables.length; j++) {
caryll_Buffer *buf = fn(lookup->subtables.items[j]);
caryll_Buffer *buf = fn(lookup->subtables.items[j], heuristics);
(*subtables)[j] = buf;
totalBufSizeShort += buf->size;
totalBufSizeExt += 8;
Expand All @@ -31,10 +58,10 @@ static tableid_t _declare_lookup_writer(otl_LookupType type,
#define LOOKUP_WRITER(type, fn) \
if (!written) \
written = _declare_lookup_writer(type, fn, lookup, subtables, lastOffset, \
preferExtensionForThisLUT);
preferExtensionForThisLUT, heuristics);

static tableid_t _build_lookup(const otl_Lookup *lookup, caryll_Buffer ***subtables,
size_t *lastOffset, bool *preferExtensionForThisLUT) {
size_t *lastOffset, bool *preferExtensionForThisLUT, otl_BuildHeuristics heuristics) {
if (lookup->type == otl_type_gpos_chaining || lookup->type == otl_type_gsub_chaining) {
return otfcc_classifiedBuildChaining(lookup, subtables, lastOffset);
}
Expand All @@ -54,6 +81,22 @@ static tableid_t _build_lookup(const otl_Lookup *lookup, caryll_Buffer ***subtab
return written;
}

static otl_BuildHeuristics getLookupHeuristics(const table_OTL *table, const otl_Lookup *lut){
otl_BuildHeuristics heu = OTL_BH_NORMAL;
// GSUB VERT heuristics
// GDI have some restrictions on the internal format of the lookup inisde a VERT feature
if (lut->type == otl_type_gsub_single) {
for (tableid_t j = 0; j < table->features.length; j++) {
const otl_Feature *fea = table->features.items[j];
if (featureNameToTag(fea->name) != 'vert') continue;
for (tableid_t k = 0; k < fea->lookups.length; k++) {
if (fea->lookups.items[k] == lut) heu |= OTL_BH_GSUB_VERT;
}
}
}
return heu;
}

// When writing lookups, otfcc will try to maintain everything correctly.
// That is, we will use extended layout lookups automatically when the
// offsets are too large.
Expand All @@ -68,12 +111,12 @@ static bk_Block *writeOTLLookups(const table_OTL *table, const otfcc_Options *op

size_t lastOffset = 0;
for (tableid_t j = 0; j < table->lookups.length; j++) {

otl_Lookup *lookup = table->lookups.items[j];
otl_BuildHeuristics heu = getLookupHeuristics(table, lookup);
logProgress("Building lookup %s (%u/%u)\n", lookup->name, j,
(uint32_t)table->lookups.length);
subtableQuantity[j] =
_build_lookup(lookup, &(subtables[j]), &lastOffset, &(preferExtForThisLut[j]));
_build_lookup(lookup, &(subtables[j]), &lastOffset, &(preferExtForThisLut[j]), heu);
}

size_t headerSize = 2 + 2 * table->lookups.length;
Expand Down Expand Up @@ -139,30 +182,6 @@ static bk_Block *writeOTLLookups(const table_OTL *table, const otfcc_Options *op
return root;
}

static uint32_t featureNameToTag(const sds name) {
uint32_t tag = 0;
if (sdslen(name) > 0) {
tag |= ((uint8_t)name[0]) << 24;
} else {
tag |= ((uint8_t)' ') << 24;
}
if (sdslen(name) > 1) {
tag |= ((uint8_t)name[1]) << 16;
} else {
tag |= ((uint8_t)' ') << 16;
}
if (sdslen(name) > 2) {
tag |= ((uint8_t)name[2]) << 8;
} else {
tag |= ((uint8_t)' ') << 8;
}
if (sdslen(name) > 3) {
tag |= ((uint8_t)name[3]) << 0;
} else {
tag |= ((uint8_t)' ') << 0;
}
return tag;
}
static bk_Block *writeOTLFeatures(const table_OTL *table, const otfcc_Options *options) {
bk_Block *root = bk_new_Block(b16, table->features.length, bkover);
for (tableid_t j = 0; j < table->features.length; j++) {
Expand Down
23 changes: 20 additions & 3 deletions lib/table/otl/coverage.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ static otl_Coverage *parseCoverage(const json_value *cov) {
static int by_gid(const void *a, const void *b) {
return *((glyphid_t *)a) - *((glyphid_t *)b);
}
static caryll_Buffer *buildCoverage(const otl_Coverage *coverage) {

static caryll_Buffer *buildCoverageFormat(const otl_Coverage *coverage, uint16_t format) {
// sort the gids in coverage
if (!coverage->numGlyphs) {
caryll_Buffer *buf = bufnew();
Expand Down Expand Up @@ -186,17 +187,32 @@ static caryll_Buffer *buildCoverage(const otl_Coverage *coverage) {
nRanges += 1;
bufwrite16b(format2, nRanges);
bufwrite_bufdel(format2, ranges);
if (buflen(format1) < buflen(format2)) {

if (format == 1) {
buffree(format2);
FREE(r);
return format1;
} else {
} else if (format == 2) {
buffree(format1);
FREE(r);
return format2;
} else {
if (buflen(format1) < buflen(format2)) {
buffree(format2);
FREE(r);
return format1;
} else {
buffree(format1);
FREE(r);
return format2;
}
}
}

static caryll_Buffer *buildCoverage(const otl_Coverage *coverage) {
return buildCoverageFormat(coverage, 0);
}

static int byHandleGID(const void *a, const void *b) {
return ((glyph_handle *)a)->index - ((glyph_handle *)b)->index;
}
Expand Down Expand Up @@ -234,6 +250,7 @@ const struct __otfcc_ICoverage otl_iCoverage = {
.dump = dumpCoverage,
.parse = parseCoverage,
.build = buildCoverage,
.buildFormat = buildCoverageFormat,
.shrink = shrinkCoverage,
.push = pushToCoverage,
};
8 changes: 6 additions & 2 deletions lib/table/otl/subtables/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
#include "bk/bkgraph.h"
#include "../../otl.h"

#define checkLength(offset) \
if (tableLength < offset) { goto FAIL; }
typedef enum {
OTL_BH_NORMAL = 0,
OTL_BH_GSUB_VERT = 1
} otl_BuildHeuristics;

#define checkLength(offset) if (tableLength < offset) { goto FAIL; }

#endif
3 changes: 2 additions & 1 deletion lib/table/otl/subtables/gpos-cursive.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ otl_Subtable *otl_gpos_parse_cursive(const json_value *_subtable, const otfcc_Op
return (otl_Subtable *)subtable;
}

caryll_Buffer *otfcc_build_gpos_cursive(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gpos_cursive(const otl_Subtable *_subtable,
otl_BuildHeuristics heuristics) {
const subtable_gpos_cursive *subtable = &(_subtable->gpos_cursive);
otl_Coverage *cov = Coverage.create();
for (glyphid_t j = 0; j < subtable->length; j++) {
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-cursive.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ otl_Subtable *otl_read_gpos_cursive(const font_file_pointer data, uint32_t table
const otfcc_Options *options);
json_value *otl_gpos_dump_cursive(const otl_Subtable *_subtable);
otl_Subtable *otl_gpos_parse_cursive(const json_value *_subtable, const otfcc_Options *options);
caryll_Buffer *otfcc_build_gpos_cursive(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gpos_cursive(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-mark-to-ligature.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ otl_Subtable *otl_gpos_parse_markToLigature(const json_value *_subtable,
return (otl_Subtable *)st;
}

caryll_Buffer *otfcc_build_gpos_markToLigature(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gpos_markToLigature(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
const subtable_gpos_markToLigature *subtable = &(_subtable->gpos_markToLigature);
otl_Coverage *marks = Coverage.create();
for (glyphid_t j = 0; j < subtable->markArray.length; j++) {
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-mark-to-ligature.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ otl_Subtable *otl_read_gpos_markToLigature(const font_file_pointer data, uint32_
json_value *otl_gpos_dump_markToLigature(const otl_Subtable *st);
otl_Subtable *otl_gpos_parse_markToLigature(const json_value *_subtable,
const otfcc_Options *options);
caryll_Buffer *otfcc_build_gpos_markToLigature(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gpos_markToLigature(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-mark-to-single.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ otl_Subtable *otl_gpos_parse_markToSingle(const json_value *_subtable,
return (otl_Subtable *)st;
}

caryll_Buffer *otfcc_build_gpos_markToSingle(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gpos_markToSingle(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
const subtable_gpos_markToSingle *subtable = &(_subtable->gpos_markToSingle);
otl_Coverage *marks = Coverage.create();
for (glyphid_t j = 0; j < subtable->markArray.length; j++) {
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-mark-to-single.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ otl_Subtable *otl_read_gpos_markToSingle(const font_file_pointer data, uint32_t
json_value *otl_gpos_dump_markToSingle(const otl_Subtable *st);
otl_Subtable *otl_gpos_parse_markToSingle(const json_value *_subtable,
const otfcc_Options *options);
caryll_Buffer *otfcc_build_gpos_markToSingle(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gpos_markToSingle(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-pair.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ bk_Block *otfcc_build_gpos_pair_classes(const otl_Subtable *_subtable) {
DELETE(Coverage.free, cov);
return root;
}
caryll_Buffer *otfcc_build_gpos_pair(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gpos_pair(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
bk_Block *format1 = otfcc_build_gpos_pair_individual(_subtable);
bk_Block *format2 = otfcc_build_gpos_pair_classes(_subtable);
bk_Graph *g1 = bk_newGraphFromRootBlock(format1);
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ otl_Subtable *otl_read_gpos_pair(const font_file_pointer data, uint32_t tableLen
const otfcc_Options *options);
json_value *otl_gpos_dump_pair(const otl_Subtable *_subtable);
otl_Subtable *otl_gpos_parse_pair(const json_value *_subtable, const otfcc_Options *options);
caryll_Buffer *otfcc_build_gpos_pair(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gpos_pair(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
9 changes: 5 additions & 4 deletions lib/table/otl/subtables/gpos-single.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ otl_Subtable *otl_gpos_parse_single(const json_value *_subtable, const otfcc_Opt
return (otl_Subtable *)subtable;
}

caryll_Buffer *otfcc_build_gpos_single(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gpos_single(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
const subtable_gpos_single *subtable = &(_subtable->gpos_single);
bool isConst = subtable->length > 0;
uint16_t format = 0;
Expand All @@ -102,19 +102,20 @@ caryll_Buffer *otfcc_build_gpos_single(const otl_Subtable *_subtable) {
Coverage.push(cov, Handle.dup(subtable->items[j].target));
}

caryll_Buffer *coverageBuf = Coverage.build(cov);

if (isConst) {
bk_Block *b =
(bk_new_Block(b16, 1, // Format
p16,
bk_newBlockFromBuffer(Coverage.build(cov)), // coverage
p16, bk_newBlockFromBuffer(coverageBuf), // coverage
b16, format, // format
bkembed, bk_gpos_value(subtable->items[0].value, format), // value
bkover));
Coverage.free(cov);
return bk_build_Block(b);
} else {
bk_Block *b = bk_new_Block(b16, 2, // Format
p16, bk_newBlockFromBuffer(Coverage.build(cov)), // coverage
p16, bk_newBlockFromBuffer(coverageBuf), // coverage
b16, format, // format
b16, subtable->length, // quantity
bkover);
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gpos-single.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ otl_Subtable *otl_read_gpos_single(const font_file_pointer data, uint32_t tableL
const otfcc_Options *options);
json_value *otl_gpos_dump_single(const otl_Subtable *_subtable);
otl_Subtable *otl_gpos_parse_single(const json_value *_subtable, const otfcc_Options *options);
caryll_Buffer *otfcc_build_gpos_single(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gpos_single(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gsub-ligature.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static int by_gid(ligature_aggerator *a, ligature_aggerator *b) {
return a->gid - b->gid;
}

caryll_Buffer *otfcc_build_gsub_ligature_subtable(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gsub_ligature_subtable(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
const subtable_gsub_ligature *subtable = &(_subtable->gsub_ligature);

ligature_aggerator *h = NULL, *s, *tmp;
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gsub-ligature.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ otl_Subtable *otl_read_gsub_ligature(const font_file_pointer data, uint32_t tabl
const otfcc_Options *options);
json_value *otl_gsub_dump_ligature(const otl_Subtable *_subtable);
otl_Subtable *otl_gsub_parse_ligature(const json_value *_subtable, const otfcc_Options *options);
caryll_Buffer *otfcc_build_gsub_ligature_subtable(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gsub_ligature_subtable(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gsub-multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ otl_Subtable *otl_gsub_parse_multi(const json_value *_subtable, const otfcc_Opti
return (otl_Subtable *)st;
}

caryll_Buffer *otfcc_build_gsub_multi_subtable(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gsub_multi_subtable(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
const subtable_gsub_multi *subtable = &(_subtable->gsub_multi);
otl_Coverage *cov = Coverage.create();
for (glyphid_t j = 0; j < subtable->length; j++) {
Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gsub-multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ otl_Subtable *otl_read_gsub_multi(const font_file_pointer data, uint32_t tableLe
const otfcc_Options *options);
json_value *otl_gsub_dump_multi(const otl_Subtable *_subtable);
otl_Subtable *otl_gsub_parse_multi(const json_value *_subtable, const otfcc_Options *options);
caryll_Buffer *otfcc_build_gsub_multi_subtable(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gsub_multi_subtable(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gsub-reverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ otl_Subtable *otl_gsub_parse_reverse(const json_value *_subtable, const otfcc_Op
return (otl_Subtable *)subtable;
}

caryll_Buffer *otfcc_build_gsub_reverse(const otl_Subtable *_subtable) {
caryll_Buffer *otfcc_build_gsub_reverse(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics) {
const subtable_gsub_reverse *subtable = &(_subtable->gsub_reverse);
reverseBacktracks(subtable->match, subtable->inputIndex);

Expand Down
2 changes: 1 addition & 1 deletion lib/table/otl/subtables/gsub-reverse.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ otl_Subtable *otl_read_gsub_reverse(const font_file_pointer data, uint32_t table
const otfcc_Options *options);
json_value *otl_gsub_dump_reverse(const otl_Subtable *_subtable);
otl_Subtable *otl_gsub_parse_reverse(const json_value *_subtable, const otfcc_Options *options);
caryll_Buffer *otfcc_build_gsub_reverse(const otl_Subtable *_subtable);
caryll_Buffer *otfcc_build_gsub_reverse(const otl_Subtable *_subtable, otl_BuildHeuristics heuristics);

#endif
Loading

0 comments on commit c4dc465

Please sign in to comment.