# Introduction

**⚠️ WARNING: This API is highly experimental and subject to change. It is not
enabled by default and should not be used in production without understanding
the stability implications. The API may change significantly in future releases.**

The dependency API provides access to a glyph dependency graph that represents
how glyphs in an OpenType font reference or produce other glyphs. The graph
maps input glyphs to output glyphs through various OpenType mechanisms:

- **Glyph substitution (GSUB)**: Tracks which glyphs can be substituted for
  other glyphs through OpenType Layout features
- **Composite glyphs (glyf, CFF)**: Records component glyphs used in composite
  glyph construction (TrueType glyf composites and CFF1 SEAC)
- **Color layers (COLR)**: Identifies glyphs used as color layers
- **Math variants (MATH)**: Tracks mathematical variant glyphs

**Note**: Unicode Variation Sequences (UVS) are not included in the dependency
graph. Handle UVS separately using `hb_font_get_variation_glyph()`.

The dependency graph enables finding the transitive closure of all glyphs
reachable from a given input set, which is useful for font subsetting,
analyzing glyph coverage, and optimizing font delivery.

# Building with the Depend API

The dependency API is guarded by `HB_NO_SUBSET_DEPEND`, which is defined by
default. To enable it, either enable the `experimental_api` build option or
define `HB_SUBSET_DEPEND_API` to opt in to just this API.

## Enabling via build option

```bash
meson setup build -Dexperimental_api=true
meson compile -C build
```

In code, check for availability:

```c
#ifdef HB_SUBSET_DEPEND_API
  // Use dependency API
#endif
```

## Enabling just the depend API

Define `HB_SUBSET_DEPEND_API` on your compiler command line or in a config
header to enable the depend API without enabling all experimental APIs:

```bash
cc ... -DHB_SUBSET_DEPEND_API ...
```

## Discovering available options

To see all available HarfBuzz build options, including `experimental_api`:

```bash
# After setting up a build directory
meson configure build

# Or to see just the option values
meson introspect build --buildoptions | jq '.[] | select(.section == "user")'
```

You can also view all available options in the source file `meson_options.txt`.

**Important:** This API is experimental and may change without notice. Do not
use in production applications without being prepared for breaking changes in
future HarfBuzz releases.

# Usage

## Basic Example

```c
#include <hb.h>

hb_blob_t *blob = hb_blob_create_from_file("font.ttf");
hb_face_t *face = hb_face_create(blob, 0);

// Extract dependency graph
hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail(face);
if (!depend) {
    // Handle error
    return;
}

// Query dependencies for a specific glyph
hb_codepoint_t gid = 42;  // Glyph to query

unsigned int total = hb_subset_depend_lookup_glyph(depend, gid, 0, NULL, NULL);
printf("Dependencies for glyph %u:\n", gid);
for (unsigned int i = 0; i < total; i++) {
    hb_subset_depend_entry_t entry;
    unsigned int count = 1;
    hb_subset_depend_lookup_glyph(depend, gid, i, &count, &entry);
    printf("  -> glyph %u via %c%c%c%c\n",
           entry.dependent, HB_UNTAG(entry.table_tag));
}

// Clean up
hb_subset_depend_destroy(depend);
hb_face_destroy(face);
hb_blob_destroy(blob);
```

## Iterating Dependencies

To programmatically access dependency information for a specific glyph:

```c
hb_codepoint_t gid = 42;  // Glyph ID to query

// Get total count, then iterate
unsigned int total = hb_subset_depend_lookup_glyph(depend, gid, 0, NULL, NULL);
for (unsigned int i = 0; i < total; i++) {
    hb_subset_depend_entry_t entry;
    unsigned int count = 1;
    hb_subset_depend_lookup_glyph(depend, gid, i, &count, &entry);

    // Process dependency information
    if (entry.table_tag == HB_OT_TAG_GSUB) {
        // GSUB dependency: layout_tag contains feature tag
        printf("GID %u -> %u via GSUB feature '%c%c%c%c'\n",
               gid, entry.dependent, HB_UNTAG(entry.layout_tag));
    } else {
        // Other dependencies (glyf, CFF, COLR, MATH, VARC)
        printf("GID %u -> %u via %c%c%c%c\n",
               gid, entry.dependent, HB_UNTAG(entry.table_tag));
    }
}
```

## Finding Reachable Glyphs

To compute all glyphs reachable from a starting set (transitive closure):

```c
void find_reachable_glyphs(hb_subset_depend_t *depend, hb_set_t *reachable)
{
    hb_set_t *to_process = hb_set_create();
    hb_set_union(to_process, reachable);

    // Process glyphs until none remain
    while (!hb_set_is_empty(to_process)) {
        hb_codepoint_t gid = hb_set_get_min(to_process);
        hb_set_del(to_process, gid);

        unsigned int total = hb_subset_depend_lookup_glyph(depend, gid, 0, NULL, NULL);
        for (unsigned int i = 0; i < total; i++) {
            hb_subset_depend_entry_t entry;
            unsigned int count = 1;
            hb_subset_depend_lookup_glyph(depend, gid, i, &count, &entry);

            if (!hb_set_has(reachable, entry.dependent)) {
                hb_set_add(reachable, entry.dependent);
                hb_set_add(to_process, entry.dependent);
            }
        }
    }

    hb_set_destroy(to_process);
}

// Usage:
hb_set_t *reachable = hb_set_create();
hb_set_add(reachable, 100);
hb_set_add(reachable, 101);

find_reachable_glyphs(depend, reachable);

printf("Found %u reachable glyphs\n", hb_set_get_population(reachable));
hb_set_destroy(reachable);
```

**Note:** This simple algorithm doesn't handle ligature dependencies or context sets
correctly. Ligatures should only be added when all component glyphs in their ligature
set are present, and contextual dependencies should only be followed when their positional
requirements are satisfied. For a production-quality implementation that correctly handles
ligatures, context filtering, and feature filtering to compute closures similar to
HarfBuzz's subset API, see `compute_depend_closure()` in `test/fuzzing/hb-depend-closure-parity.cc`
and `docs/depend-for-closure.md`.

## Working with Ligature Sets

When a dependency entry belongs to a ligature set, you can find all other members
of that set using `hb_subset_depend_lookup_set()`:

```c
// After finding entry.ligature_set_index != HB_CODEPOINT_INVALID...

// Get all glyphs in this ligature set
hb_set_t *ligature_glyphs = hb_set_create();
if (hb_subset_depend_lookup_set(depend, entry.ligature_set_index, ligature_glyphs)) {
    hb_codepoint_t lig_gid = HB_SET_VALUE_INVALID;

    printf("Members of ligature set %u:\n", entry.ligature_set_index);
    while (hb_set_next(ligature_glyphs, &lig_gid)) {
        // Find the dependency entry index for this glyph in this ligature set
        unsigned int lig_total = hb_subset_depend_lookup_glyph(depend, lig_gid, 0, NULL, NULL);
        for (unsigned int j = 0; j < lig_total; j++) {
            hb_subset_depend_entry_t lig_entry;
            unsigned int count = 1;
            hb_subset_depend_lookup_glyph(depend, lig_gid, j, &count, &lig_entry);
            if (lig_entry.ligature_set_index == entry.ligature_set_index) {
                printf("  gid=%u, index=%u\n", lig_gid, j);
                break;
            }
        }
    }
}
hb_set_destroy(ligature_glyphs);
```

## Working with Context Sets

Context and ChainContext GSUB rules apply lookups only when specific backtrack and/or
lookahead glyphs are present. The depend API records these requirements in
`context_set_index` fields as optional information that can refine dependency traversal.

**Note:** Context sets are optional refinement information. Uses of the dependency graph
that ignore `context_set_index` (treating it as always satisfied) work fine - they produce a
conservative over-approximation. Context sets allow more precise closure computation when
desired.

### Understanding Context Sets

When `entry.context_set_index != HB_CODEPOINT_INVALID`, the edge includes positional
requirements from a Context or ChainContext rule. Context set elements use two encodings:

1. **Direct GID reference** (value < 0x80000000): A specific glyph ID
2. **Indirect set reference** (value >= 0x80000000): An index into the sets array
   (mask off high bit with `value & 0x7FFFFFFF` to get the set index)

The high bit (0x80000000) distinguishes between direct and indirect references. For an
edge to apply, ALL elements in the context set must be satisfied:
- Direct references: that specific glyph must be present in the closure
- Indirect references: at least ONE glyph from the referenced set must be present (disjunction)

### Checking Context Requirements

```c
bool check_context_satisfied(hb_subset_depend_t *depend,
                             hb_codepoint_t context_set_idx,
                             hb_set_t *current_closure)
{
    if (context_set_idx == HB_CODEPOINT_INVALID)
        return true;  // No context requirements

    hb_set_t *context_elements = hb_set_create();
    if (!hb_subset_depend_lookup_set(depend, context_set_idx, context_elements))
    {
        hb_set_destroy(context_elements);
        return false;  // Error retrieving context
    }

    bool satisfied = true;
    hb_codepoint_t elem = HB_SET_VALUE_INVALID;

    while (hb_set_next(context_elements, &elem))
    {
        if (elem < 0x80000000)
        {
            // Direct reference: check if specific glyph is in closure
            if (!hb_set_has(current_closure, elem))
            {
                satisfied = false;
                break;
            }
        }
        else
        {
            // Indirect reference: check if ANY glyph from set is in closure
            hb_codepoint_t set_idx = elem & 0x7FFFFFFF;
            hb_set_t *required_set = hb_set_create();

            if (hb_subset_depend_lookup_set(depend, set_idx, required_set))
            {
                // Check if ANY element from required_set is in current_closure
                bool any_found = false;
                hb_codepoint_t glyph = HB_SET_VALUE_INVALID;
                while (hb_set_next(required_set, &glyph))
                {
                    if (hb_set_has(current_closure, glyph))
                    {
                        any_found = true;
                        break;
                    }
                }
                if (!any_found)
                    satisfied = false;
            }
            else
            {
                satisfied = false;  // Error retrieving set
            }

            hb_set_destroy(required_set);
            if (!satisfied)
                break;
        }
    }

    hb_set_destroy(context_elements);
    return satisfied;
}
```

For a complete implementation of context-aware closure computation, see the
`compute_depend_closure()` function in `test/fuzzing/hb-depend-closure-parity.cc`.

# API Details

## Dependency Entry Fields

Each `hb_subset_depend_entry_t` filled by `hb_subset_depend_lookup_glyph()` contains:

- **table_tag**: Source table (e.g., `HB_OT_TAG_GSUB`,
  `HB_TAG('g','l','y','f')`, `HB_TAG('C','F','F',' ')`, `HB_TAG('C','O','L','R')`,
  `HB_TAG('M','A','T','H')`, `HB_TAG('V','A','R','C')`)
- **dependent**: The dependent glyph ID
- **layout_tag**:
  - For GSUB: the feature tag (e.g., `HB_TAG('l','i','g','a')`)
  - Otherwise: `HB_CODEPOINT_INVALID`
- **ligature_set_index**: For ligatures, identifies which ligature set; otherwise
  `HB_CODEPOINT_INVALID`
- **context_set_index**: Optional refinement information for Context and ChainContext GSUB
  rules. When not `HB_CODEPOINT_INVALID`, identifies positional requirements
  (backtrack/lookahead) for this dependency. Can be ignored (treated as always satisfied)
  for conservative over-approximation, or checked for more precise closure computation.
  See "Working with Context Sets" section for details.
- **flags**: Edge metadata flags (`hb_subset_depend_edge_flags_t`). Currently defined:
  - `HB_SUBSET_DEPEND_EDGE_FLAG_FROM_CONTEXT_POSITION` (0x01): Edge created from a
    multi-position contextual rule (Context or ChainContext with inputCount > 1). Depend
    extraction records edges based on what glyphs COULD be at each position according to
    the static input coverage/class. But during closure computation, lookups within the
    rule are applied sequentially: lookups at earlier positions may transform glyphs at
    later positions, and multiple lookups at the same position may interact (one produces
    a glyph, another immediately consumes it as an "intermediate"). So a glyph matching
    the coverage might not actually persist at that position when closure traverses the
    rule. These edges may cause over-approximation.
  - `HB_SUBSET_DEPEND_EDGE_FLAG_FROM_NESTED_CONTEXT` (0x02): Edge created from a lookup
    that was called from within another contextual lookup (nested context). The outer
    context's requirements are not preserved on this edge, so it may over-approximate.

  These flags help distinguish between "true" over-approximation (a bug) and "expected"
  over-approximation (a known limitation of the static dependency analysis). Closure
  implementations can use these flags to report which type of over-approximation occurred.

# Implementation Notes

**⚠️ Warning: Graph Cycles in Invalid Fonts**

The dependency graph may contain cycles when processing invalid or malicious fonts.
While the OpenType specification requires COLR paint graphs to be directed acyclic
graphs (DAGs), the depend API faithfully reports the graph structure as it exists
in the font, including any cycles that may be present. Implementations traversing
the depend graph should implement cycle detection to protect against invalid fonts.

For details on how cycles can occur and how PaintGlyph self-references are filtered,
see the "COLR Cycles and Self-References" section in `docs/depend-implementation.md`.

For detailed information about the depend API implementation, including memory
management, data structures, and performance characteristics, see
`docs/depend-implementation.md`.

# Use Cases

## Font Subsetting

Determine which glyphs must be retained to properly render a specific set of
characters, accounting for all OpenType substitutions and compositions.

## Coverage Analysis

Analyze which features or scripts require which glyphs, useful for font
optimization and planning.

## Font Segmentation

Partition a font into smaller subsets where each segment contains glyphs reachable
from a specific set of input characters, enabling more efficient font delivery
for web applications.

## Testing

Verify that font modifications haven't inadvertently broken glyph references or
substitution chains.
