{"id":20828032,"url":"https://github.com/googlefonts/oxidize","last_synced_at":"2026-01-27T19:04:56.728Z","repository":{"id":38040238,"uuid":"446182081","full_name":"googlefonts/oxidize","owner":"googlefonts","description":"Notes on moving tools and libraries to Rust.","archived":false,"fork":false,"pushed_at":"2025-01-29T17:26:14.000Z","size":184,"stargazers_count":194,"open_issues_count":17,"forks_count":7,"subscribers_count":35,"default_branch":"main","last_synced_at":"2025-01-29T18:28:20.250Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"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/googlefonts.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/code-of-conduct.md","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":"2022-01-09T19:22:27.000Z","updated_at":"2025-01-29T17:26:14.000Z","dependencies_parsed_at":"2023-02-14T00:15:21.653Z","dependency_job_id":"280aa5d9-2050-413c-b14c-145727d79cdb","html_url":"https://github.com/googlefonts/oxidize","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Foxidize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Foxidize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Foxidize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Foxidize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/googlefonts","download_url":"https://codeload.github.com/googlefonts/oxidize/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243179821,"owners_count":20249178,"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":[],"created_at":"2024-11-17T23:13:40.035Z","updated_at":"2026-01-27T19:04:56.722Z","avatar_url":"https://github.com/googlefonts.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# oxidize\n\nWherein we contemplate moving shaping, rasterization, font compilation, and general font inspection and manipulation from Python \u0026 C++ to Rust.\n\n## Table of Contents\n\n- [Why](#why)\n- [Goals](#goals)\n   - [Support both our primary usage patterns](#support-both-our-primary-usage-patterns)\n   - [Offer memory safety for text rendering](#offer-memory-safety-for-text-rendering)\n   - [A productive codebase](#a-productive-codebase)\n   - [Prefer incremental delivery, early production use](#prefer-incremental-delivery-early-production-use)\n- [Definitions](#definitions)\n- [Where is the code?](#wheres-the-code)\n- [References](#references)    \n   - [Internal](#internal) - references within this repository\n   - [External](#external) - references outside this repository\n\n## Why\n\nWe currently rely C++ for anything high performance, e.g. shaping or subsetting, and Python for general purpose manipulation. The results are exactly what you'd expect:\n\n* Python code (fonttools, fontmake, nanoemoji, etc) have high development velocity, relatively fast developer rampup, and runtime safety, slow runtime\n   * It's SO slow that running it in production at scale causes us great pain. Queues back up, we burn memory and CPU, and it just doesn't fit our infra all that well.\n* C++ code (HarfBuzz) has fast runtime, very slow development velocity, very slow developer rampup, and any safety it might have is due to extensive fuzzing\n   * It's entirely normal to make a seemingly safe change and then see a stream of fuzzer bugs\n   * Best thing ever in production, blindingly fast and low resource cost, fits infrastructure nicely. But scary due to lack of safety.\n\nSome logic ends up implemented in both languages. For example, when it became apparent the Python subsetter was too slow for both runtime serving and future projects like [progressive font enrichment](https://www.w3.org/TR/PFE-evaluation/) the [hb-subset](https://goo.gl/Qy3Eqc) project was born.\n\nRust appears to offer us the ability to implement fast, safer code with development velocity in between Python and C++. This is a very appealing offer.\n\n## Goals\n\nOur priorities, higher priority items first, are:\n\n| What | Why |\n| --- | --- |\n| Minimal or no unsafe, fast, memory-efficient | If it's not fast enough or it hogs memory nobody will ship it. We would accept unsafe - that we can convince ourselves to be safe - if it got us substantial perf. We're not specifically aiming for `#![forbid(unsafe_code)]`, though it would be nice. |\n| Ergonomic, hackable | Ergonomic: friendly to consumers, idiomatic wherever possible. Hackable: friendly to developers modifying the code |\n\nTaken from discussion [here](https://github.com/googlefonts/oxidize/issues/10#issuecomment-1024769804).\n\n### Support both our primary usage patterns\n\n1. Performance-critical read-only users (shaping, rasterization)\n   * HarfBuzz and FreeType have *years* of performance optimizations. A replacement that is significantly slower will not land.\n1. Read/write use (compilers, utilities)\n   * Performance is less critical here. We don't want to be *slow*, but we don't need the level of performance obsession shaping needs either.\n\nFor read-only users we may need to support readonly mmap access. Crates like zerocopy and the like suggest this is possible. Establishing a clean pattern here should be tackled early. https://github.com/googlefonts/oxidize/pull/3 proposes a path forward.\n\n### Offer memory safety for text rendering \n\nChrome and Microsoft both observe that:\n\n1. 70% of high severity security bugs are memory safety issues ([Chrome](https://www.chromium.org/Home/chromium-security/memory-safety), [Microsoft](https://msrc-blog.microsoft.com/2019/07/18/we-need-a-safer-systems-programming-language/))\n1. Rust _may_ help\n   * If it can [play nice with C++](https://security.googleblog.com/2021/09/an-update-on-memory-safety-in-chrome.html)\n   * For Fonts we can, if necessary, limit ourselves to stable C ABI\n\nA safe text stack is desirable for Chrome, Android, and more. At time of writing we observe a semi-steady stream of fuzzer issues. It seems plausible a Rust rewrite can stop the bleeding. This is promising enough it's well worth giving it a try!\n\nHarfBuzz is the primary target. Some parts of FreeType used in Chrome and Android may also need to be replaced. If we do both the stream of fuzzer issues _should_ stop.\n\n### A productive codebase\n\nWe seek to provide a developer friendly codebase. For example, exploration of new structs for something COLRv1 should be readily achievable by forking and hacking around. That means the code needs to be simpler than today's C++ and as close as possible to Python level development velocity. To achieve this we will seek to establish an efficient pattern to support our two primary usage patterns. This will require that we:\n\n   * Stay DRY\n      * Don't hand-write things twice, once for high performance readonly access and once for mutable access\n      * Don't hand-write per-field parsing (struct.blah = read type of blah, etc)\n         * It's OK to *occasionally* hand-write, particularly for some of the more obtuse parts, but it should be the exception not the rule \n         * Try to continue the HarfBuzz and FontTools style of declaring the shape of things and letting automation take over wherever possible\n      * Automated authoring, such as by macro or build time tooling is acceptable\n   * Minimize unsafe code\n   * Invest in testing\n\n### Prefer incremental delivery, early production use\n\nWe will _prefer_ to:\n\n* Make incremental progress, with each milestone being used in production, rather than spend years with parallel increasingly divergent implementations.\n* Test the Rust implementation against the non-Rust implementation for both correctness and performance\n   * This has been very successful to enable replacement of Python subsetting with hb-subset\n* Fail-fast, if rebuilding in Rust is infeasible we would like to know ASAP\n   * Given the results of projects like piet-gpu and swash we currently believe the effort very feasible\n\n## Getting started\n\nUpdated 8/16/2024. Our first phase projects are:\n\n1. [Skrifa](https://docs.rs/skrifa), replace FreeType for querying metrics, loading outlines, autohinting, and executing hints\n   * https://chromestatus.com/feature/5717358869217280 tracks the Chrome status\n   * Google typically uses Skia to rasterize so we don't implement that in Skrifa\n1. [fontc](https://github.com/googlefonts/fontc), meant to replace [fontmake](https://github.com/googlefonts/fontmake)\n   * https://googlefonts.github.io/fontc_crater/ tracks progress in getting the compilers to match\n\nThe next phase is:\n\n1. [klippa](https://github.com/googlefonts/fontations/tree/main/klippa), meant to be a memory safe replacement for [hb-subset](https://harfbuzz.github.io/harfbuzz-hb-subset.html) and [fonttools subset](https://fonttools.readthedocs.io/en/latest/subset/)\n   * Google Fonts depends heavily on subsetting\n1. [harfruzz](https://github.com/harfbuzz/harfruzz), meant to replace HarfBuzz [shaping](https://harfbuzz.github.io/what-is-harfbuzz.html)\n\nBoth phases build on core read/write fonts work in https://github.com/googlefonts/fontations.\n\n## Definitions\n\n### zerocopy\n\nThe direct reading/writing of scalars and, wherever possible, aggregates (structs and slices) through reinterpretation of pointers to raw bytes in memory.\n\n## Where's the code?\n\nThe graph below depicts, and links to (*warning* copy the links rather than clicking on them until https://github.com/community/community/discussions/17545 resolves), active projects and their relationships (arrows indicate dependency):\n\n```mermaid\nflowchart TD\n    subgraph Font Compiler\n        fontc\n    end\n    fontc --\u003e read-fonts\n    fontc --\u003e write-fonts\n    \n    subgraph Typesetting Application\n         Chrome\n    end\n    Chrome --\u003e skrifa\n    \n    subgraph Load outlines and metadata\n        skrifa\n    end\n    subgraph read\n        read-fonts    \n    end\n    subgraph write\n        write-fonts    \n    end\n    \n    skrifa --\u003e read-fonts\n    write-fonts --\u003e read-fonts    \n    subgraph common\n        font-types\n    end\n    \n    read-fonts --\u003e common\n\n    click fontmake-rs \"https://github.com/googlefonts/fontmake-rs\"\n    click otexplorer \"https://github.com/googlefonts/fontations/tree/main/otexplorer\"\n    click read-fonts \"https://github.com/googlefonts/fontations/tree/main/read-fonts\"\n    click write-fonts \"https://github.com/googlefonts/fontations/tree/main/write-fonts\"\n    click font-types \"https://github.com/googlefonts/fontations/tree/main/font-types\"\n```\n\n## References\n\n### Internal\n\nReferences within this repository.\n\n* [Simon Cozens parallel font compilation experiments](text/2022-05-10-parallel-font-compile-experiments.md)\n\n### External\n\n* [Oxidize Introduction](https://docs.google.com/presentation/d/1kLB_BY7nSzNo07NrpvyJMxixGd4ULQTEEXjyO4KKM-E/edit?usp=sharing) slides from @cmyr on progress as of October 2022\n* https://github.com/drott 2023 BlinkOn [Safe and sound Rust Font Stack ](https://docs.google.com/presentation/d/1Vp8VOXbsw67mOleJTq0bYORNxkTwYpVh9F_7PS9IK5I/edit?usp=drivesdk) presentation\n* [HarfBuzz](https://github.com/harfbuzz/harfbuzz) is a world class high performance text shaper that makes extensive use of zerocopy-style access. In contemplating converting it to Rust there are a few key references to help in understanding the source:\n   * hb-subset [design doc](https://goo.gl/Qy3Eqc)\n      * Table packing (the hard part!) [design doc](https://goo.gl/bHvnTn) \n      * [Serialization](https://github.com/harfbuzz/harfbuzz/blob/main/docs/serializer.md) explains how graphs are handled during subsetting\n      * [Repacker](https://github.com/harfbuzz/harfbuzz/blob/main/docs/repacker.md) explains how layout tables are packed\n* https://security.googleblog.com/2021/09/an-update-on-memory-safety-in-chrome.html offers commentary on the feasibility of having Rust-like safety in C++\n* https://pngquant.org/rust.html offers an interesting example of a Rust migration of a small library\n* http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performance-of-c-and-rust/ another interesting example\n* https://wiki.mozilla.org/Oxidation\n* https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglefonts%2Foxidize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglefonts%2Foxidize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglefonts%2Foxidize/lists"}