Apple's Font Interpreter Is Now Swift, and 13% Faster
Apple’s security team published the kind of result that settles arguments. The TrueType hinting interpreter, a bytecode interpreter that has parsed untrusted font data on Apple platforms since 1991, has been rewritten from C to memory-safe Swift, and “on average, our Swift interpreter runs 13% faster than the C interpreter it replaced.”1 The post is written by Scott Perry, a member of Apple’s Security team focused on Swift adoption, the source code is on GitHub as a reference implementation, and the correctness bar was not “passes tests” but pixel-identical rendering against the C original.1 Memory-safe, faster than C, and shipping in production since the Fall 2025 releases: the post is the strongest empirical answer yet to the claim that memory safety costs performance.
TL;DR
- Apple rewrote the TrueType hinting interpreter from C to Swift because font parsers are a security-critical attack surface: the interpreter runs font-embedded bytecode with “input-driven control flow, complex data structures, and careful memory management—exactly the kind of code that’s hard to make perfect and where memory errors are easier to exploit.”1
- The result shipped in the Fall 2025 releases, has had “no bugs reported against it since it was enabled,” and averages 13% faster than the C implementation.1
- The performance came from specific, portable techniques:
~Copyableand~Escapablevalue types to eliminate reference counting and exclusivity overhead,Spanfor safe sequence access, projection types over C structs that removed copies costing about 20% of runtime, and keeping generics specializable.1 - Verification was the quiet masterpiece: a unit suite with 99.7% coverage across both implementations, a fuzzer-minimized corpus of 10 million PDFs reduced to 4,200 documents embedding 25,572 fonts, 27 million glyphs rendered under four transformations each and compared bitmap-for-bitmap, and nearly four times as much test code as interpreter code.1
- The interpreter source is published at
apple/truetype-hinting-interpreter-exampleunder the MIT license, as production code intended as a reference implementation.2
Why a font interpreter is a security story
TrueType fonts can contain programs. The format Apple created in the late 1980s ships a hinting engine built around a special-purpose bytecode interpreter, designed to make outlines rasterize faithfully on low-resolution displays.1 When TrueType became embeddable in PDFs in 1994 and in web pages in 2008, that interpreter started executing programs from “untrusted fonts from anywhere on the internet.”1 Anyone who has followed iOS security history knows how that story goes: font parsers have carried some of the platform’s most famous exploit chains, and the post names the structural reason without needing the history lesson. Input-driven control flow plus manual memory management is where memory errors live.
The team’s constraints made the rewrite harder than a greenfield port. Binary compatibility meant existing programs “had to continue to function the same as they did before, effectively unaware that a new implementation was in place,” and because hinting can radically change how glyphs look on screen, correctness was defined as “exact compatibility with the C implementation’s outputs.”1 Pixel-identical, not approximately right.
The verification methodology is the craft story
Before the performance work, the team built the proof apparatus. A unit test suite targets both the C and Swift implementations with exhaustive coverage, 99.7% for both, and ships with the open source release.1 For real-world coverage, they used a fuzzer to minimize a corpus of 10 million PDF files down to 4,200 with no loss of code coverage; those documents embed 25,572 fonts whose 27 million glyphs were rendered under four transformations each, with the resulting bitmaps compared against the reference interpreter.1 By the end, the team had written nearly four times as many lines of test code as interpreter code.1
That ratio is the part worth internalizing. The rewrite was possible to do aggressively because every optimization ran against an oracle that answered, bitmap by bitmap, whether behavior had changed. The post credits exactly that loop: exhaustive coverage and well-defined internal boundaries “make refactoring substantially easier, which in turn accelerates the measure-and-fix optimization loop while minimizing the risk of introducing bugs.”1
Where the 13% came from
The post breaks the performance work into four categories, each with a portable lesson.1
Kill reference counting and exclusivity checks with noncopyable types. Swift’s ARC and runtime exclusivity checking impose overhead that aliasing makes worse, and the interpreter’s specification bakes in an irreducible amount of aliasing. The fix was architectural: adopt ~Copyable value types throughout and reserve reference types for high-level abstractions, with Span, introduced in Swift 6.2 and back-deployable all the way to macOS 10.14.4 and iOS 12.2, providing efficient access to sequences.1
Stop copying at the language boundary. The C code stored glyph points as one struct of eight arrays, cache-friendly but un-Swifty. The first bridging code copied that data into Swift and back, and those copies cost about 20% of the new interpreter’s runtime.1 The replacement was projection types that wrap the C structure and broker bounds-safe access without copying, following WebKit’s Safer Swift Guidelines: an @safe noncopyable, nonescapable struct holding a Ref to the C element, with every unsafe expression carrying a // SAFETY: comment documenting the invariant that justifies it.1
Elide short-lived allocations. Operations like filter and map allocate, and the allocation only matters if the value escapes. The interpreter’s stack-pop operation evolved from an obvious version that allocated an array of popped elements into a continuation-passing version: the caller passes a closure that operates on a borrowing Span of the elements before they are removed, with compile-time exclusivity checking guaranteeing the stack cannot be mutated from inside the closure.1 No heap allocation, no element copies, and the safety argument is structural rather than by convention.
Keep generics specializable. Dynamic dispatch from protocols and generics can usually be optimized away, but not unconditionally. The team’s guidance for profiling: “if you see unspecialized generics or protocol witness tables in hot paths, that’s a sign that the optimizer does not have sufficient visibility” and the implementation may benefit from inlining.1
The result did not trade readability for speed. The post’s framing is that Swift’s type system enabled abstractions, fixed-point numeric types, a stack element with built-in conversions, the projection types, that “added zero cost while substantially improving readability” once built with optimizations.1 And the team is candid about scope: the interpreter’s internal state is all noncopyable structures, but the top-level type stays an @objc class called from Objective-C++, because “the hot paths are fast, and the cold paths are convenient.”1
The quiet agent angle
One paragraph near the end deserves more attention than its placement suggests. After completing the migration, the team “distilled what we learned into instructions for LLM coding assistants, and have since used them successfully in other projects,” with LLMs improving the team’s efficiency at converting C and C++ to Swift.1 Apple’s security team is encoding migration expertise as agent instructions and reusing it across codebases, the same pattern Apple productized this cycle as exportable agent skills, covered in Xcode 27’s agent skills export. A hand-built migration becomes a playbook; the playbook becomes leverage for the next ten migrations.
What to take from it
The post lands three claims that used to be debatable. Memory-safe Swift can replace security-critical C in the hottest of hot paths: a bytecode interpreter. The replacement can be faster, not by magic but through noncopyable types, copy elimination, and specialization-friendly design. And the migration can be verified to pixel-identical equivalence with enough test investment, which the team sized at roughly 4:1 against the implementation. For anyone holding C or C++ parsing code that touches untrusted input, the combination of this post, the open repo, and Swift 6.4’s granular strict-memory-safety opt-ins makes “we’ll migrate someday” measurably less defensible than it was last week.
FAQ
What exactly did Apple rewrite?
The TrueType hinting interpreter: the bytecode interpreter that executes font-embedded hinting programs so glyph outlines rasterize well, part of the font stack since System 7 in 1991.1 It went from C to memory-safe Swift in the Fall 2025 releases, with rendering output pixel-identical to the C implementation.1
Is Swift really faster than C here?
On average, yes: 13% faster than the C interpreter it replaced, measured in CPU megacycles per glyph across all hinted fonts shipping on macOS plus a sample of non-system fonts.1 The gains came from eliminating reference counting via noncopyable types, removing cross-language copies with projection types, eliding short-lived allocations, and keeping generics specializable.1
Can I read the code?
Yes. Apple published the interpreter at apple/truetype-hinting-interpreter-example under the MIT license, described as production code intended as a reference implementation rather than an ongoing open source project.2 The unit test suite ships with it.1
Why does a font interpreter matter for security?
Because it executes programs from untrusted input. Fonts arrive in web pages and PDFs from anywhere, and the interpreter’s combination of input-driven control flow and careful memory management is exactly where memory-corruption exploits historically live.1 Moving that surface to a memory-safe language removes the entire class of bug, and the post reports no bugs since the Swift implementation was enabled.1
The migration validates the direction Swift’s tooling has been signaling all month: the granular memory-safety diagnostics in What’s New in Swift (2026), the performance-by-default concurrency story in Swift 6.2 concurrency in practice, and the security framing Apple put on the record in its first-party answer to prompt injection. The full series hub is the Apple Ecosystem Series.
References
-
Scott Perry, Swift at Apple: Migrating the TrueType Hinting Interpreter, Swift.org blog, June 12, 2026. Source for the author’s role (Apple Security team, focusing on Swift adoption), the security framing (font parsers process untrusted data; “input-driven control flow, complex data structures, and careful memory management—exactly the kind of code that’s hard to make perfect and where memory errors are easier to exploit”), the TrueType history (developed by Apple in the late 1980s, shipped with System 7 in 1991, embeddable in PDFs in 1994 and web pages in 2008), the Fall 2025 ship date, the 13% average performance improvement measured in CPU megacycles per glyph, the no-bugs-since-enabled statement, the binary-compatibility and pixel-identical correctness requirements, the verification methodology (99.7% coverage across both implementations, the 10-million-PDF corpus fuzzer-minimized to 4,200 documents, 25,572 embedded fonts, 27 million glyphs under four transformations, nearly 4x test code), the four optimization categories (
~Copyablevalue types andSpanwith back-deployment to macOS 10.14.4 and iOS 12.2; projection types over C structs after copies cost about 20% of runtime, following WebKit’s Safer Swift Guidelines with@safeand// SAFETY:comments; continuation-passing stack pops overborrowing Span; specialization and inlining guidance), the zero-cost-abstractions framing, the@objctop-level boundary (“the hot paths are fast, and the cold paths are convenient”), and the LLM-assistant instructions distilled from the migration and reused on other C/C++-to-Swift projects. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple, truetype-hinting-interpreter-example, GitHub, MIT license. Source for the repository’s existence, license, and its description as the Swift TrueType Interpreter, published as production code intended as a reference implementation. ↩↩