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 Jul 29, 2016
2 parents 092301f + 3534ce9 commit 8d1d2cf
Show file tree
Hide file tree
Showing 123 changed files with 1,458 additions and 1,463 deletions.
6 changes: 3 additions & 3 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ TabWidth: 4
IndentWidth: 4
UseTab: ForIndentation
AllowShortBlocksOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
ColumnLimit: 100
AllowShortLoopsOnASingleLine: false
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IndentCaseLabels: true
AlignOperands: true
Expand Down
53 changes: 43 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ The `otfcc` is a C library and utility used for parsing and writing OpenType fon
* Full support for OpenType features (`GSUB`, `GPOS` and `GDEF`), CID-keyed CFF, vertical metrics, and more.
* **4× faster than `ttx` on CFF OTF, and 40× on TTF.**

## Prebuilt installations

### Windows

Click the “Releases” above, and download the archives in it.

### Mac

If you have [Homebrew](http://brew.sh/), just run the following in your terminal.

```bash
brew tap caryll/tap
brew install otfcc-mac64
```

Otherwise, you may need to click the “Releases” above, and download the archives in it.

### Arch Linux

The package `otfcc` can be found [here](https://aur.archlinux.org/packages/otfcc/).

## Usage

### `otfccdump` : Dump an OpenType font file into JSON
Expand All @@ -33,7 +54,7 @@ otfccdump [OPTIONS] input.[otf|ttf|ttc]

### `otfccbuild` : Build an OpenType font file from JSON
```
otfccbuild [OPTIONS] [input.json] -o output.[ttf|otf]
Usage : otfccbuild [OPTIONS] [input.json] -o output.[ttf|otf]
input.json : Path to input file. When absent the input will
be read from the STDIN.
Expand All @@ -50,13 +71,15 @@ otfccbuild [OPTIONS] [input.json] -o output.[ttf|otf]
of using current time.
--short-post : Don't export glyph names in the result font. It
will reduce file size.
--dummy-DSIG : Include an empty DSIG table in the font. For
--dummy-dsig, -s : Include an empty DSIG table in the font. For
some Microsoft applications, a DSIG is required
to enable OpenType features.
--ship : Equivalent to the combination of these options:
* --ignore-glyph-order
* --short-post
* --dummy-dsig
-O<n> : Specify the level for optimization.
-O0 Turn off any optimization.
-O1 Default optimization.
-O2 More aggressive optimizations for web font. In
this level, the --ignore-glyph-order and
--short-post will be turned on.
```

## Building
Expand All @@ -65,7 +88,7 @@ otfccbuild [OPTIONS] [input.json] -o output.[ttf|otf]

It was developed and optimized for Clang/LLVM, therefore it is *strongly* recommended to compile with Clang/LLVM, but if that's not possible GCC is also supported, GCC version 5.1 or later being the preferred choice for performance.

### Linux
### Linux (or other Unix-like)

On Linux, Either Clang/LLVM or GCC can be used to build `otfcc`.

Expand All @@ -81,7 +104,7 @@ make

### Windows

On Windows building `otfcc` is tested under the toolchains listed below. The default `premake5 vs2015` will produce a Visual Studio solution using Clang-CL as its compiler.
On Windows, building `otfcc` is tested under the toolchains listed below. The default `premake5 vs2015` will produce a Visual Studio solution using Clang-CL as its compiler.

* GCC 5.1 included in `TDM-GCC`. Run the following from the command line:

Expand All @@ -100,10 +123,20 @@ On Windows building `otfcc` is tested under the toolchains listed below. The def

### Mac OS

premake5 provides ability to produce XCode projects. Simply type
premake5 provides ability to produce XCode projects. Run

```bash
premake5 xcode4
```

And you can find XCode project files under `build/xcode`.
And then you can open `build/xcode/otfcc.xcworkspace` and build with XCode. You can find built binaries in `bin/`.

Please ensure that Xcode’s Developer Mode is enabled.

To build binaries in your terminal, run

```bash
xcodebuild -workspace build/xcode/otfcc.xcworkspace -scheme otfccbuild -configuration Release
xcodebuild -workspace build/xcode/otfcc.xcworkspace -scheme otfccdump -configuration Release
```

159 changes: 76 additions & 83 deletions lib/font/caryll-font.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void caryll_delete_font(caryll_font *font) {
if (font->CFF_) caryll_delete_CFF(font->CFF_);
if (font->glyf) caryll_delete_glyf(font->glyf);
if (font->cmap) caryll_delete_cmap(font->cmap);
if (font->LTSH) caryll_delete_LTSH(font->LTSH);
if (font->GSUB) caryll_delete_otl(font->GSUB);
if (font->GPOS) caryll_delete_otl(font->GPOS);
if (font->GDEF) caryll_delete_GDEF(font->GDEF);
Expand All @@ -59,7 +60,9 @@ void caryll_delete_font(caryll_font *font) {

caryll_font_subtype caryll_decide_font_subtype(caryll_sfnt *sfnt, uint32_t index) {
caryll_packet packet = sfnt->packets[index];
FOR_TABLE('CFF ', table) { return FONTTYPE_CFF; }
FOR_TABLE('CFF ', table) {
return FONTTYPE_CFF;
}
return FONTTYPE_TTF;
}

Expand All @@ -85,6 +88,7 @@ caryll_font *caryll_read_font(caryll_sfnt *sfnt, uint32_t index) {
font->prep = caryll_read_fpgm_prep(packet, 'prep');
font->cvt_ = caryll_read_cvt(packet, 'cvt ');
font->gasp = caryll_read_gasp(packet);
font->LTSH = caryll_read_LTSH(packet);
font->glyf = caryll_read_glyf(packet, font->head, font->maxp);
} else {
caryll_cff_parse_result cffpr = caryll_read_CFF_and_glyf(packet);
Expand All @@ -105,119 +109,108 @@ caryll_font *caryll_read_font(caryll_sfnt *sfnt, uint32_t index) {
}
}

json_value *caryll_font_to_json(caryll_font *font, caryll_dump_options *dumpopts) {
json_value *caryll_font_to_json(caryll_font *font, caryll_options *options) {
json_value *root = json_object_new(48);
dumpopts->has_vertical_metrics = !!(font->vhea) && !!(font->vmtx);
dumpopts->export_fdselect = font->CFF_ && font->CFF_->isCID;
options->has_vertical_metrics = !!(font->vhea) && !!(font->vmtx);
options->export_fdselect = font->CFF_ && font->CFF_->isCID;
if (!root) return NULL;
caryll_head_to_json(font->head, root, dumpopts);
caryll_hhea_to_json(font->hhea, root, dumpopts);
caryll_maxp_to_json(font->maxp, root, dumpopts);
caryll_vhea_to_json(font->vhea, root, dumpopts);
caryll_post_to_json(font->post, root, dumpopts);
caryll_OS_2_to_json(font->OS_2, root, dumpopts);
caryll_name_to_json(font->name, root, dumpopts);
caryll_cmap_to_json(font->cmap, root, dumpopts);
caryll_CFF_to_json(font->CFF_, root, dumpopts);
caryll_glyf_to_json(font->glyf, root, dumpopts);
if (!dumpopts->ignore_hints) {
caryll_fpgm_prep_to_json(font->fpgm, root, dumpopts, "fpgm");
caryll_fpgm_prep_to_json(font->prep, root, dumpopts, "prep");
caryll_cvt_to_json(font->cvt_, root, dumpopts, "cvt_");
caryll_gasp_to_json(font->gasp, root, dumpopts);
caryll_head_to_json(font->head, root, options);
caryll_hhea_to_json(font->hhea, root, options);
caryll_maxp_to_json(font->maxp, root, options);
caryll_vhea_to_json(font->vhea, root, options);
caryll_post_to_json(font->post, root, options);
caryll_OS_2_to_json(font->OS_2, root, options);
caryll_name_to_json(font->name, root, options);
caryll_cmap_to_json(font->cmap, root, options);
caryll_CFF_to_json(font->CFF_, root, options);
caryll_glyf_to_json(font->glyf, root, options);
if (!options->ignore_hints) {
caryll_fpgm_prep_to_json(font->fpgm, root, options, "fpgm");
caryll_fpgm_prep_to_json(font->prep, root, options, "prep");
caryll_cvt_to_json(font->cvt_, root, options, "cvt_");
caryll_gasp_to_json(font->gasp, root, options);
}
caryll_otl_to_json(font->GSUB, root, dumpopts, "GSUB");
caryll_otl_to_json(font->GPOS, root, dumpopts, "GPOS");

caryll_GDEF_to_json(font->GDEF, root, dumpopts);
caryll_otl_to_json(font->GSUB, root, options, "GSUB");
caryll_otl_to_json(font->GPOS, root, options, "GPOS");
caryll_GDEF_to_json(font->GDEF, root, options);
return root;
}

caryll_font *caryll_font_from_json(json_value *root, caryll_dump_options *dumpopts) {
caryll_font *caryll_font_from_json(json_value *root, caryll_options *options) {
caryll_font *font = caryll_new_font();
if (!font) return NULL;
font->subtype = json_obj_get_type(root, "CFF_", json_object) != NULL;
font->glyph_order = caryll_glyphorder_from_json(root, dumpopts);
font->head = caryll_head_from_json(root, dumpopts);
font->hhea = caryll_hhea_from_json(root, dumpopts);
font->OS_2 = caryll_OS_2_from_json(root, dumpopts);
font->maxp = caryll_maxp_from_json(root, dumpopts);
font->post = caryll_post_from_json(root, dumpopts);
font->name = caryll_name_from_json(root, dumpopts);
font->cmap = caryll_cmap_from_json(root, dumpopts);
font->CFF_ = caryll_CFF_from_json(root, dumpopts);
font->glyf = caryll_glyf_from_json(root, *font->glyph_order, dumpopts);
if (!dumpopts->ignore_hints) {
font->fpgm = caryll_fpgm_prep_from_json(root, "fpgm");
font->prep = caryll_fpgm_prep_from_json(root, "prep");
font->cvt_ = caryll_cvt_from_json(root, "cvt_");
font->gasp = caryll_gasp_from_json(root);
font->glyph_order = caryll_glyphorder_from_json(root, options);
font->head = caryll_head_from_json(root, options);
font->hhea = caryll_hhea_from_json(root, options);
font->OS_2 = caryll_OS_2_from_json(root, options);
font->maxp = caryll_maxp_from_json(root, options);
font->post = caryll_post_from_json(root, options);
font->name = caryll_name_from_json(root, options);
font->cmap = caryll_cmap_from_json(root, options);
font->CFF_ = caryll_CFF_from_json(root, options);
font->glyf = caryll_glyf_from_json(root, *font->glyph_order, options);
if (!options->ignore_hints) {
font->fpgm = caryll_fpgm_prep_from_json(root, options, "fpgm");
font->prep = caryll_fpgm_prep_from_json(root, options, "prep");
font->cvt_ = caryll_cvt_from_json(root, options, "cvt_");
font->gasp = caryll_gasp_from_json(root, options);
}
font->vhea = caryll_vhea_from_json(root, dumpopts);
font->vhea = caryll_vhea_from_json(root, options);
if (font->glyf) {
font->GSUB = caryll_otl_from_json(root, dumpopts, "GSUB");
font->GPOS = caryll_otl_from_json(root, dumpopts, "GPOS");
font->GDEF = caryll_GDEF_from_json(root, dumpopts);
font->GSUB = caryll_otl_from_json(root, options, "GSUB");
font->GPOS = caryll_otl_from_json(root, options, "GPOS");
font->GDEF = caryll_GDEF_from_json(root, options);
}
return font;
}

caryll_buffer *caryll_write_font(caryll_font *font, caryll_dump_options *dumpopts) {
caryll_buffer *caryll_write_font(caryll_font *font, caryll_options *options) {
sfnt_builder *builder = new_sfnt_builder(font->subtype == FONTTYPE_CFF ? 'OTTO' : 0x00010000);

// Outline data
if (font->subtype == FONTTYPE_TTF) {
caryll_buffer *bufglyf = bufnew();
caryll_buffer *bufloca = bufnew();
if (font->glyf && font->head) {
caryll_write_glyf(font->glyf, font->head, bufglyf, bufloca, dumpopts);
}
sfnt_builder_push_table(builder, 'loca', bufloca);
sfnt_builder_push_table(builder, 'glyf', bufglyf);
glyf_loca_bufpair pair = caryll_write_glyf(font->glyf, font->head, options);
sfnt_builder_push_table(builder, 'glyf', pair.glyf);
sfnt_builder_push_table(builder, 'loca', pair.loca);
} else {
caryll_cff_parse_result r = {font->CFF_, font->glyf};
sfnt_builder_push_table(builder, 'CFF ', caryll_write_CFF(r, dumpopts));
sfnt_builder_push_table(builder, 'CFF ', caryll_write_CFF(r, options));
}

sfnt_builder_push_table(builder, 'head', caryll_write_head(font->head, dumpopts));
sfnt_builder_push_table(builder, 'hhea', caryll_write_hhea(font->hhea, dumpopts));
sfnt_builder_push_table(builder, 'OS/2', caryll_write_OS_2(font->OS_2, dumpopts));
sfnt_builder_push_table(builder, 'maxp', caryll_write_maxp(font->maxp, dumpopts));
sfnt_builder_push_table(builder, 'name', caryll_write_name(font->name, dumpopts));
sfnt_builder_push_table(builder, 'post',
caryll_write_post(font->post, font->glyph_order, dumpopts));
sfnt_builder_push_table(builder, 'cmap', caryll_write_cmap(font->cmap, dumpopts));
if (font->fpgm)
sfnt_builder_push_table(builder, 'fpgm', caryll_write_fpgm_prep(font->fpgm, dumpopts));
if (font->prep)
sfnt_builder_push_table(builder, 'prep', caryll_write_fpgm_prep(font->prep, dumpopts));
if (font->cvt_)
sfnt_builder_push_table(builder, 'cvt ', caryll_write_cvt(font->cvt_, dumpopts));
if (font->gasp)
sfnt_builder_push_table(builder, 'gasp', caryll_write_gasp(font->gasp, dumpopts));
sfnt_builder_push_table(builder, 'head', caryll_write_head(font->head, options));
sfnt_builder_push_table(builder, 'hhea', caryll_write_hhea(font->hhea, options));
sfnt_builder_push_table(builder, 'OS/2', caryll_write_OS_2(font->OS_2, options));
sfnt_builder_push_table(builder, 'maxp', caryll_write_maxp(font->maxp, options));
sfnt_builder_push_table(builder, 'name', caryll_write_name(font->name, options));
sfnt_builder_push_table(builder, 'post', caryll_write_post(font->post, font->glyph_order, options));
sfnt_builder_push_table(builder, 'cmap', caryll_write_cmap(font->cmap, options));
if (font->gasp) sfnt_builder_push_table(builder, 'gasp', caryll_write_gasp(font->gasp, options));

if (font->subtype == FONTTYPE_TTF) {
if (font->fpgm) sfnt_builder_push_table(builder, 'fpgm', caryll_write_fpgm_prep(font->fpgm, options));
if (font->prep) sfnt_builder_push_table(builder, 'prep', caryll_write_fpgm_prep(font->prep, options));
if (font->cvt_) sfnt_builder_push_table(builder, 'cvt ', caryll_write_cvt(font->cvt_, options));
if (font->LTSH) sfnt_builder_push_table(builder, 'LTSH', caryll_write_LTSH(font->LTSH, options));
}

sfnt_builder_push_table(builder, 'hmtx',
caryll_write_hmtx(font->hmtx, font->hhea->numberOfMetrics,
font->maxp->numGlyphs - font->hhea->numberOfMetrics,
dumpopts));
font->maxp->numGlyphs - font->hhea->numberOfMetrics, options));

if (font->vhea)
sfnt_builder_push_table(builder, 'vhea', caryll_write_vhea(font->vhea, dumpopts));
if (font->vhea) sfnt_builder_push_table(builder, 'vhea', caryll_write_vhea(font->vhea, options));
if (font->vmtx) {
sfnt_builder_push_table(
builder, 'vmtx',
caryll_write_vmtx(font->vmtx, font->vhea->numOfLongVerMetrics,
font->maxp->numGlyphs - font->vhea->numOfLongVerMetrics, dumpopts));
sfnt_builder_push_table(builder, 'vmtx',
caryll_write_vmtx(font->vmtx, font->vhea->numOfLongVerMetrics,
font->maxp->numGlyphs - font->vhea->numOfLongVerMetrics, options));
}
if (font->VORG) { sfnt_builder_push_table(builder, 'VORG', caryll_write_VORG(font->VORG, options)); }

if (font->GSUB)
sfnt_builder_push_table(builder, 'GSUB', caryll_write_otl(font->GSUB, dumpopts));
if (font->GPOS)
sfnt_builder_push_table(builder, 'GPOS', caryll_write_otl(font->GPOS, dumpopts));
if (font->GDEF)
sfnt_builder_push_table(builder, 'GDEF', caryll_write_GDEF(font->GDEF, dumpopts));
if (font->GSUB) sfnt_builder_push_table(builder, 'GSUB', caryll_write_otl(font->GSUB, options, "GSUB"));
if (font->GPOS) sfnt_builder_push_table(builder, 'GPOS', caryll_write_otl(font->GPOS, options, "GPOS"));
if (font->GDEF) sfnt_builder_push_table(builder, 'GDEF', caryll_write_GDEF(font->GDEF, options));

if (dumpopts->dummy_DSIG) {
if (options->dummy_DSIG) {
caryll_buffer *dsig = bufnew();
bufwrite32b(dsig, 0x00000001);
bufwrite16b(dsig, 0);
Expand Down
8 changes: 5 additions & 3 deletions lib/font/caryll-font.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ struct _caryll_font {
table_cvt *cvt_;
table_gasp *gasp;

table_LTSH *LTSH;

table_otl *GSUB;
table_otl *GPOS;
table_GDEF *GDEF;
Expand All @@ -71,8 +73,8 @@ caryll_font_subtype caryll_decide_font_subtype(caryll_sfnt *sfnt, uint32_t index
caryll_font *caryll_new_font();
caryll_font *caryll_read_font(caryll_sfnt *sfnt, uint32_t index);
void caryll_delete_font(caryll_font *font);
json_value *caryll_font_to_json(caryll_font *font, caryll_dump_options *dumpopts);
caryll_font *caryll_font_from_json(json_value *root, caryll_dump_options *dumpopts);
caryll_buffer *caryll_write_font(caryll_font *font, caryll_dump_options *dumpopts);
json_value *caryll_font_to_json(caryll_font *font, caryll_options *options);
caryll_font *caryll_font_from_json(json_value *root, caryll_options *options);
caryll_buffer *caryll_write_font(caryll_font *font, caryll_options *options);

#endif
15 changes: 10 additions & 5 deletions lib/font/caryll-sfnt-builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ static uint32_t buf_checksum(caryll_buffer *buffer) {
{
uint32_t *start = (uint32_t *)buffer->data;
uint32_t *end = start + ((actualLength + 3) & ~3) / sizeof(uint32_t);
while (start < end) { sum += caryll_endian_convert32(*start++); }
while (start < end) {
sum += caryll_endian_convert32(*start++);
}
}
return sum;
}
Expand All @@ -33,7 +35,9 @@ static sfnt_builder_entry *createSegment(uint32_t tag, caryll_buffer *buffer) {
{
uint32_t *start = (uint32_t *)buffer->data;
uint32_t *end = start + ((table->length + 3) & ~3) / sizeof(uint32_t);
while (start < end) { sum += caryll_endian_convert32(*start++); }
while (start < end) {
sum += caryll_endian_convert32(*start++);
}
}
table->checksum = sum;
return table;
Expand Down Expand Up @@ -70,7 +74,9 @@ void sfnt_builder_push_table(sfnt_builder *builder, uint32_t tag, caryll_buffer
}
}

static int byTag(sfnt_builder_entry *a, sfnt_builder_entry *b) { return (a->tag - b->tag); }
static int byTag(sfnt_builder_entry *a, sfnt_builder_entry *b) {
return (a->tag - b->tag);
}

caryll_buffer *sfnt_builder_serialize(sfnt_builder *builder) {
caryll_buffer *buffer = bufnew();
Expand Down Expand Up @@ -104,8 +110,7 @@ caryll_buffer *sfnt_builder_serialize(sfnt_builder *builder) {

// we are right after the table directory
// add copyright information
sds copyright =
sdscatprintf(sdsempty(), "-- By OTFCC %d.%d.%d --", MAIN_VER, SECONDARY_VER, PATCH_VER);
sds copyright = sdscatprintf(sdsempty(), "-- By OTFCC %d.%d.%d --", MAIN_VER, SECONDARY_VER, PATCH_VER);
sdsgrowzero(copyright, 20);
bufwrite_bytes(buffer, 20, (uint8_t *)copyright);
sdsfree(copyright);
Expand Down
Loading

0 comments on commit 8d1d2cf

Please sign in to comment.