| # AGENTS.md |
| |
| HarfBuzz is a low-level text shaping engine with stable public API and ABI expectations. Keep changes narrow, preserve behavior unless the task explicitly requires otherwise, and avoid style-only churn. |
| |
| ## Read first |
| |
| Before non-trivial work, read: |
| |
| - `README.md` |
| - `BUILD.md` |
| - `TESTING.md` |
| - `CONFIG.md` |
| - `RELEASING.md` |
| |
| ## Core rules |
| |
| - Prefer minimal diffs. Do not rename, reorder, or reformat unrelated code. |
| - Scope changes to one subsystem or concern when possible. Prefer incremental follow-up commits over large rewrites. |
| - Public API and ABI are hard constraints. Do not add new API unless explicitly asked. Do not change or remove existing API/ABI unless explicitly asked. |
| - Follow local conventions in the touched file. |
| - Preserve optional-feature behavior, reduced-feature builds, and compile-time feature guards. |
| - Keep out-of-memory behavior in mind. New code should fail safely and follow existing allocation and error-handling patterns. |
| - Prefer HarfBuzz's established `likely`/`unlikely` and nil-object/null-pattern conventions where they fit the surrounding code. |
| - Prefer HarfBuzz helpers from `hb-algs.hh` such as `hb_memcpy`, `hb_memcmp`, and `hb_memset` over raw `memcpy`, `memcmp`, and `memset` where those helpers are available. |
| - Do not introduce STL containers in library code. Follow HarfBuzz container and utility patterns instead. |
| - Leave unrelated user changes and untracked artifacts alone. |
| |
| ## Repo map |
| |
| - `src/`: core library code. |
| - `src/OT/`: OpenType shaping/layout internals. |
| - `src/graph/`: subsetter graph helpers. |
| - `src/rust/`: HarfRust and fontations integration. |
| - `util/`: installed tools such as `hb-shape`, `hb-view`, `hb-info`, `hb-subset`, `hb-vector`, `hb-raster`. |
| - `test/`: API, shape, subset, vector, threads, and fuzzing tests. |
| - `perf/`: benchmarks. |
| - `docs/`: API/manual docs. |
| |
| ## Build and verify |
| |
| Default flow: |
| |
| ```sh |
| meson setup build --reconfigure |
| meson compile -C build |
| meson test -C build |
| ``` |
| |
| If `build/` does not exist yet, omit `--reconfigure`. |
| |
| General expectations: |
| |
| - Rebuild touched targets and make sure there are no new warnings. |
| - For shaping changes, run at least `meson test -C build --suite shape`. |
| - For subset changes, run at least `meson test -C build --suite subset`. |
| - For API changes, run at least `meson test -C build --suite api`. |
| - For `util/` changes, rebuild the relevant tool and exercise it on a small sample. |
| - When fixing a bug or hardening a parser, add or update the nearest regression test, fuzz seed, fuzz target, or expected output when practical. |
| - Treat portability regressions as real bugs. HarfBuzz regularly fixes GCC, Clang, MSVC, 32/64-bit, and reduced-feature build issues. |
| |
| ## Change-specific guidance |
| |
| - Shaping work: check nearby tests under `test/shape/`. |
| - Subsetting work: check `test/subset/`; `src/graph/` is part of the subsetter. |
| - Raster/vector/SVG work: prefer extracting helpers and splitting oversized files by responsibility instead of adding more branching to large translation units. |
| - Fuzzing/parser-hardening work: inspect `test/fuzzing/` and existing guardrail code first. Fuzzers run with failing-malloc enabled, so treat out-of-memory handling as part of the exercised surface. |
| - Build-system work: keep Meson options, summaries, installed tools, tests, and dependent targets in sync. If packaging or cross-build behavior is affected, inspect CMake too. |
| - Generated data work: update the generator or makefile flow, then regenerate outputs. Do not hand-edit generated tables unless the task explicitly calls for it. |
| - Rust integration work: inspect `src/rust/meson.build` and `src/rust/Cargo.toml` before changing build glue. |
| |
| For API work: |
| |
| - Public API lives in `src/hb-*.h`, not `.hh`. |
| - If new API is explicitly requested, document it in `NEWS`, add `XSince: REPLACEME` in the public header docs, and update `docs/harfbuzz-sections.txt` and `docs/harfbuzz-docs.xml` when needed. |
| - If functionality becomes user-visible through tools or libraries, update the relevant docs and install/build wiring in the same change when appropriate. |
| - Keep documentation placement consistent with local practice: public API docs may live in source files, while generated section indexes live in `docs/`. |
| |
| ## Avoid |
| |
| - Do not make broad formatting passes. |
| - Do not silently change Meson defaults or feature defaults unless required. |
| - Do not assume generated outputs, local fonts, or untracked artifacts are disposable. |
| - Do not disable tests to get a green run without documenting why. |
| |
| ## Working mindset |
| |
| - Reproduce the issue before fixing it when practical. |
| - Understand root cause before writing code. If there is real ambiguity, ask instead of guessing. |
| - Validate simplifications carefully. This repo has many targeted reverts where a local cleanup broke broader behavior. |
| - If code looks unusually complex, it probably handles a real edge case. Check history before simplifying it. |
| - Centralize duplicated parsing, caching, or helper logic once duplication starts spreading. |
| |
| ## Commit guidance |
| |
| - Before any commit, run the entire test suite with `meson test -C build`. |
| - Exception: simple documentation-only or CI-only changes may be committed without running tests if they do not affect code, build logic, generated outputs, or test inputs. |
| - Use descriptive commit messages with consistent bracketed subsystem prefixes such as `[subset]`, `[raster]`, `[util]`, or `[meson]`. |
| - Wrap commit message bodies to about 70 columns. |
| - For multi-line commit messages, write the message from a file or editor-backed input. Do not pass escaped `\n` sequences via shell `-m` arguments. |
| - Explain root cause, fix, and testing in the commit body when testing was actually performed or is relevant. |
| - When relevant, link issues or PRs with trailers such as `Fixes:`. |
| - Always include an `Assisted-by:` trailer on commits you write through the agent. |
| |
| ## Wisdom |
| |
| - HarfBuzz sits at the bottom of the stack. Small changes can have very wide effects. |
| - If code looks unusually complex, assume it handles a real edge case until proven otherwise. |
| - Simplifications and optimizations are common sources of later reverts; validate them broadly. |
| - Prefer reproducible regressions over fix-only changes. |
| - When duplication starts to spread, extract the shared helper before it calcifies. |