{"id":13648608,"url":"https://github.com/harfbuzz/ttf-parser","last_synced_at":"2025-12-12T13:11:04.265Z","repository":{"id":34931092,"uuid":"191013541","full_name":"harfbuzz/ttf-parser","owner":"harfbuzz","description":"A high-level, safe, zero-allocation TrueType font parser.","archived":false,"fork":false,"pushed_at":"2025-04-21T15:06:06.000Z","size":1826,"stargazers_count":695,"open_issues_count":17,"forks_count":75,"subscribers_count":23,"default_branch":"main","last_synced_at":"2025-04-28T11:52:39.898Z","etag":null,"topics":["opentype","otf","truetype","ttf"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/harfbuzz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-09T14:02:47.000Z","updated_at":"2025-04-23T09:11:54.000Z","dependencies_parsed_at":"2024-01-01T13:26:16.413Z","dependency_job_id":"464219e8-2823-4348-be4d-fd9041dcc32f","html_url":"https://github.com/harfbuzz/ttf-parser","commit_stats":{"total_commits":476,"total_committers":27,"mean_commits":17.62962962962963,"dds":"0.10924369747899154","last_synced_commit":"56c33b910b03ca152f78363ec471c5dfd97c3069"},"previous_names":["harfbuzz/ttf-parser","razrfalcon/ttf-parser"],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harfbuzz%2Fttf-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harfbuzz%2Fttf-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harfbuzz%2Fttf-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harfbuzz%2Fttf-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/harfbuzz","download_url":"https://codeload.github.com/harfbuzz/ttf-parser/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251584156,"owners_count":21612975,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["opentype","otf","truetype","ttf"],"created_at":"2024-08-02T01:04:23.319Z","updated_at":"2025-12-12T13:11:04.207Z","avatar_url":"https://github.com/harfbuzz.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"## ttf-parser\n![Build Status](https://github.com/harfbuzz/ttf-parser/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/ttf-parser.svg)](https://crates.io/crates/ttf-parser)\n[![Documentation](https://docs.rs/ttf-parser/badge.svg)](https://docs.rs/ttf-parser)\n[![Rust 1.59+](https://img.shields.io/badge/rust-1.59+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\nA high-level, safe, zero-allocation font parser for\n[TrueType](https://docs.microsoft.com/en-us/typography/truetype/),\n[OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/), and\n[AAT](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html).\n\nCan be used as a Rust or C library.\n\n### Features\n\n- A high-level API for most common properties, hiding all parsing and data resolving logic.\n- A low-level, but safe API to access TrueType tables data.\n- Highly configurable. You can disable most of the features, reducing binary size.\n  You can also parse TrueType tables separately, without loading the whole font/face.\n- Zero heap allocations.\n- Zero unsafe.\n- Zero dependencies.\n- `no_std`/WASM compatible.\n- A basic [C API](./c-api).\n- Fast.\n- Stateless. All parsing methods are immutable.\n- Simple and maintainable code (no magic numbers).\n\n### Safety\n\n- The library must not panic. Any panic considered as a critical bug and should be reported.\n- The library forbids unsafe code.\n- No heap allocations, so crash due to OOM is not possible.\n- All recursive methods have a depth limit.\n- Technically, should use less than 64KiB of stack in the worst case scenario.\n- Most of arithmetic operations are checked.\n- Most of numeric casts are checked.\n\n### Alternatives\n\nIt's very hard to compare different libraries, so we are using table-based comparison.\nThere are roughly three types of TrueType tables:\n\n- A table with a list of properties (like `head`, `OS/2`, etc.).\u003cbr/\u003e\n  If a library tries to parse it at all then we mark it as supported.\n- A table that contains a single type of data (`glyf`, `CFF` (kinda), `hmtx`, etc.).\u003cbr/\u003e\n  Can only be supported or not.\n- A table that contains multiple subtables (`cmap`, `kern`, `GPOS`, etc.).\u003cbr/\u003e\n  Can be partially supported and we note which subtables are actually supported.\n\n| Feature/Library   | ttf-parser             | FreeType            | stb_truetype                   |\n| ----------------- | :--------------------: | :-----------------: | :----------------------------: |\n| Memory safe       | ✓                      |                     |                                |\n| Thread safe       | ✓                      |                     | ~ (mostly reentrant)           |\n| Zero allocation   | ✓                      |                     |                                |\n| Variable fonts    | ✓                      | ✓                   |                                |\n| Rendering         | -\u003csup\u003e1\u003c/sup\u003e          | ✓                   | ~ (very primitive)             |\n| `ankr` table      | ✓                      |                     |                                |\n| `avar` table      | ✓                      | ✓                   |                                |\n| `bdat` table      | ~ (no 4)               | ✓                   |                                |\n| `bloc` table      | ✓                      | ✓                   |                                |\n| `CBDT` table      | ~ (no 8, 9)            | ✓                   |                                |\n| `CBLC` table      | ✓                      | ✓                   |                                |\n| `COLR` table      | ✓                      | ✓                   |                                |\n| `CPAL` table      | ✓                      | ✓                   |                                |\n| `CFF `\u0026nbsp;table | ✓                      | ✓                   | ~ (no `seac` support)          |\n| `CFF2` table      | ✓                      | ✓                   |                                |\n| `cmap` table      | ~ (no 8)               | ✓                   | ~ (no 2,8,10,14; Unicode-only) |\n| `EBDT` table      | ~ (no 8, 9)            | ✓                   |                                |\n| `EBLC` table      | ✓                      | ✓                   |                                |\n| `feat` table      | ✓                      |                     |                                |\n| `fvar` table      | ✓                      | ✓                   |                                |\n| `gasp` table      |                        | ✓                   |                                |\n| `GDEF` table      | ~                      |                     |                                |\n| `glyf` table      | ~\u003csup\u003e2\u003c/sup\u003e          | ✓                   | ~\u003csup\u003e2\u003c/sup\u003e                  |\n| `GPOS` table      | ✓                      |                     | ~ (only 2)                     |\n| `GSUB` table      | ✓                      |                     |                                |\n| `gvar` table      | ✓                      | ✓                   |                                |\n| `head` table      | ✓                      | ✓                   | ✓                              |\n| `hhea` table      | ✓                      | ✓                   | ✓                              |\n| `hmtx` table      | ✓                      | ✓                   | ✓                              |\n| `HVAR` table      | ✓                      | ✓                   |                                |\n| `kern` table      | ✓                      | ~ (only 0)          | ~ (only 0)                     |\n| `kerx` table      | ✓                      |                     |                                |\n| `MATH` table      | ✓                      |                     |                                |\n| `maxp` table      | ✓                      | ✓                   | ✓                              |\n| `morx` table      | ✓                      |                     |                                |\n| `MVAR` table      | ✓                      | ✓                   |                                |\n| `name` table      | ✓                      | ✓                   |                                |\n| `OS/2` table      | ✓                      | ✓                   |                                |\n| `post` table      | ✓                      | ✓                   |                                |\n| `sbix` table      | ~ (PNG only)           | ~ (PNG only)        |                                |\n| `STAT` table      | ✓                      |                     |                                |\n| `SVG `\u0026nbsp;table | ✓                      | ✓                   | ✓                              |\n| `trak` table      | ✓                      |                     |                                |\n| `vhea` table      | ✓                      | ✓                   |                                |\n| `vmtx` table      | ✓                      | ✓                   |                                |\n| `VORG` table      | ✓                      | ✓                   |                                |\n| `VVAR` table      | ✓                      | ✓                   |                                |\n| Language          | Rust + C API           | C                   | C                              |\n| Tested version    | 0.17.0                 | 2.12.0              | 1.24                           |\n| License           | MIT / Apache-2.0       | FTL / GPLv2         | public domain                  |\n\nLegend:\n\n- ✓ - supported\n- ~ - partial\n- *nothing* - not supported\n\nNotes:\n\n1. While `ttf-parser` doesn't support rendering by itself,\n   there are multiple rendering libraries on top of it:\n   [rusttype](https://gitlab.redox-os.org/redox-os/rusttype),\n   [ab-glyph](https://github.com/alexheretic/ab-glyph)\n   and [fontdue](https://github.com/mooman219/fontdue).\n2. Matching points are not supported.\n\n### Performance\n\nTrueType fonts designed for fast querying, so most of the methods are very fast.\nThe main exception is glyph outlining. Glyphs can be stored using two different methods:\nusing [Glyph Data Format](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf)\nand [Compact Font Format](http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf) (pdf).\nThe first one is fairly simple which makes it faster to process.\nThe second one is basically a tiny language with a stack-based VM, which makes it way harder to process.\n\nThe [benchmark](./benches/outline/) tests how long it takes to outline all glyphs in a font.\n\nx86 (AMD 3700X)\n\n| Table/Library | ttf-parser     | FreeType   | stb_truetype   |\n| ------------- | -------------: | ---------: | -------------: |\n| `glyf`        |   `0.901 ms`   | `1.171 ms` | **`0.675 ms`** |\n| `gvar`        | **`2.972 ms`** | `4.132 ms` |              - |\n| `CFF`         | **`1.197 ms`** | `5.647 ms` |   `2.813 ms`   |\n| `CFF2`        | **`1.968 ms`** | `6.392 ms` |              - |\n\nARM (Apple M1)\n\n| Table/Library | ttf-parser     | FreeType   | stb_truetype   |\n| ------------- | -------------: | ---------: | -------------: |\n| `glyf`        | **`0.550 ms`** | `0.854 ms` |   `0.703 ms`   |\n| `gvar`        | **`2.270 ms`** | `4.594 ms` |              - |\n| `CFF`         | **`1.054 ms`** | `5.223 ms` |   `3.262 ms`   |\n| `CFF2`        | **`1.765 ms`** | `5.995 ms` |              - |\n\n**Note:** FreeType is surprisingly slow, so I'm worried that I've messed something up.\n\nAnd here are some methods benchmarks:\n\n```text\ntest outline_glyph_276_from_cff2 ... bench:         867 ns/iter (+/- 15)\ntest from_data_otf_cff           ... bench:         968 ns/iter (+/- 13)\ntest from_data_otf_cff2          ... bench:         887 ns/iter (+/- 25)\ntest outline_glyph_276_from_cff  ... bench:         678 ns/iter (+/- 41)\ntest outline_glyph_276_from_glyf ... bench:         649 ns/iter (+/- 11)\ntest outline_glyph_8_from_cff2   ... bench:         534 ns/iter (+/- 14)\ntest from_data_ttf               ... bench:         467 ns/iter (+/- 11)\ntest glyph_name_post_276         ... bench:         223 ns/iter (+/- 5)\ntest outline_glyph_8_from_cff    ... bench:         315 ns/iter (+/- 13)\ntest outline_glyph_8_from_glyf   ... bench:         291 ns/iter (+/- 5)\ntest family_name                 ... bench:         183 ns/iter (+/- 102)\ntest glyph_name_cff_276          ... bench:          62 ns/iter (+/- 1)\ntest glyph_index_u41             ... bench:          16 ns/iter (+/- 0)\ntest glyph_name_cff_8            ... bench:           5 ns/iter (+/- 0)\ntest glyph_name_post_8           ... bench:           2 ns/iter (+/- 0)\ntest subscript_metrics           ... bench:           2 ns/iter (+/- 0)\ntest glyph_hor_advance           ... bench:           2 ns/iter (+/- 0)\ntest glyph_hor_side_bearing      ... bench:           2 ns/iter (+/- 0)\ntest glyph_name_8                ... bench:           1 ns/iter (+/- 0)\ntest ascender                    ... bench:           1 ns/iter (+/- 0)\ntest underline_metrics           ... bench:           1 ns/iter (+/- 0)\ntest strikeout_metrics           ... bench:           1 ns/iter (+/- 0)\ntest x_height                    ... bench:           1 ns/iter (+/- 0)\ntest units_per_em                ... bench:         0.5 ns/iter (+/- 0)\ntest width                       ... bench:         0.2 ns/iter (+/- 0)\n```\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharfbuzz%2Fttf-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharfbuzz%2Fttf-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharfbuzz%2Fttf-parser/lists"}