diff options
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/lib/otf-writer/otf-writer.c')
-rw-r--r-- | Build/source/texk/web2c/mfluadir/otfcc/lib/otf-writer/otf-writer.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/lib/otf-writer/otf-writer.c b/Build/source/texk/web2c/mfluadir/otfcc/lib/otf-writer/otf-writer.c new file mode 100644 index 00000000000..4da56e0ed91 --- /dev/null +++ b/Build/source/texk/web2c/mfluadir/otfcc/lib/otf-writer/otf-writer.c @@ -0,0 +1,106 @@ +#include "support/util.h" +#include "otfcc/font.h" +#include "table/all.h" +#include "otfcc/sfnt-builder.h" +#include "stat.h" + +#define OTFCC_CHR(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) ) + +static void *serializeToOTF(otfcc_Font *font, const otfcc_Options *options) { + // do stat before serialize + otfcc_statFont(font, options); + + otfcc_SFNTBuilder *builder = + otfcc_newSFNTBuilder(font->subtype == FONTTYPE_CFF ? OTFCC_CHR('O','T','T','O') : 0x00010000, options); + // Outline data + if (font->subtype == FONTTYPE_TTF) { + table_GlyfAndLocaBuffers pair = otfcc_buildGlyf(font->glyf, font->head, options); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('g','l','y','f'), pair.glyf); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('l','o','c','a'), pair.loca); + } else { + table_CFFAndGlyf r = {font->CFF_, font->glyf}; + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('C','F','F',' '), otfcc_buildCFF(r, options)); + } + + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('h','e','a','d'), otfcc_buildHead(font->head, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('h','h','e','a'), otfcc_buildHhea(font->hhea, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('O','S','/','2'), otfcc_buildOS_2(font->OS_2, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('m','a','x','p'), otfcc_buildMaxp(font->maxp, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('n','a','m','e'), otfcc_buildName(font->name, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('m','e','t','a'), otfcc_buildMeta(font->meta, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('p','o','s','t'), + otfcc_buildPost(font->post, font->glyph_order, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('c','m','a','p'), otfcc_buildCmap(font->cmap, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('g','a','s','p'), otfcc_buildGasp(font->gasp, options)); + + if (font->subtype == FONTTYPE_TTF) { + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('f','p','g','m'), otfcc_buildFpgmPrep(font->fpgm, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('p','r','e','p'), otfcc_buildFpgmPrep(font->prep, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('c','v','t',' '), otfcc_buildCvt(font->cvt_, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('L','T','S','H'), otfcc_buildLTSH(font->LTSH, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('V','D','M','X'), otfcc_buildVDMX(font->VDMX, options)); + } + + if (font->hhea && font->maxp && font->hmtx) { + uint16_t hmtx_counta = font->hhea->numberOfMetrics; + uint16_t hmtx_countk = font->maxp->numGlyphs - font->hhea->numberOfMetrics; + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('h','m','t','x'), + otfcc_buildHmtx(font->hmtx, hmtx_counta, hmtx_countk, options)); + } + + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('v','h','e','a'), otfcc_buildVhea(font->vhea, options)); + if (font->vhea && font->maxp && font->vmtx) { + uint16_t vmtx_counta = font->vhea->numOfLongVerMetrics; + uint16_t vmtx_countk = font->maxp->numGlyphs - font->vhea->numOfLongVerMetrics; + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('v','m','t','x'), + otfcc_buildVmtx(font->vmtx, vmtx_counta, vmtx_countk, options)); + } + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('V','O','R','G'), otfcc_buildVORG(font->VORG, options)); + + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('G','S','U','B'), otfcc_buildOtl(font->GSUB, options, "GSUB")); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('G','P','O','S'), otfcc_buildOtl(font->GPOS, options, "GPOS")); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('G','D','E','F'), otfcc_buildGDEF(font->GDEF, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('B','A','S','E'), otfcc_buildBASE(font->BASE, options)); + + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('C','P','A','L'), otfcc_buildCPAL(font->CPAL, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('C','O','L','R'), otfcc_buildCOLR(font->COLR, options)); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('S','V','G',' '), otfcc_buildSVG(font->SVG_, options)); + + { + tsi_BuildTarget target = otfcc_buildTSI(font->TSI_01, options); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('T','S','I','0'), target.indexPart); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('T','S','I','1'), target.textPart); + } + { + tsi_BuildTarget target = otfcc_buildTSI(font->TSI_23, options); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('T','S','I','2'), target.indexPart); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('T','S','I','3'), target.textPart); + } + if (font->glyf) { + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('T','S','I','5'), + otfcc_buildTSI5(font->TSI5, options, font->glyf->length)); + } + + if (options->dummy_DSIG) { + caryll_Buffer *dsig = bufnew(); + bufwrite32b(dsig, 0x00000001); + bufwrite16b(dsig, 0); + bufwrite16b(dsig, 0); + otfcc_SFNTBuilder_pushTable(builder, OTFCC_CHR('D','S','I','G'), dsig); + } + + caryll_Buffer *otf = otfcc_SFNTBuilder_serialize(builder); + otfcc_deleteSFNTBuilder(builder); + otfcc_unstatFont(font, options); + return otf; +} +static void freeFontWriter(otfcc_IFontSerializer *self) { + free(self); +} +otfcc_IFontSerializer *otfcc_newOTFWriter() { + otfcc_IFontSerializer *writer; + NEW(writer); + writer->serialize = serializeToOTF; + writer->free = freeFontWriter; + return writer; +} |