freepdfeditor/spike/C_subset_growth/SubsetGrowth.h

48 lines
2.0 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 ai-ad4 and the FreePDFEditor contributors
//
// SubsetGrowth.h — Spike C (§14 step 6): grow an existing embedded subset
// font with a new glyph using hb-subset, and verify the result.
//
// The scenario: a PDF page embeds a subset font containing only the glyphs
// originally used (say "Hello"). The user types "Ω" — that glyph is not in
// the subset. Per §4.2 resolution ladder step 1, we grow the subset from
// the installed full font (DejaVu Sans here) using hb-subset and embed the
// new subset. This spike proves the growth works and the result is a valid
// font with the new glyph and a correct cmap.
#ifndef FREEPDFEDITOR_SPIKE_C_SUBSETGROWTH_H
#define FREEPDFEDITOR_SPIKE_C_SUBSETGROWTH_H
#include <cstddef>
#include <string>
#include <vector>
namespace freepdfeditor::spike::c {
struct GrowthResult {
bool ok = false;
std::string error;
std::size_t original_glyph_count = 0; // glyphs in the initial subset
std::size_t grown_glyph_count = 0; // glyphs after adding the new char
std::size_t original_font_bytes = 0;
std::size_t grown_font_bytes = 0;
bool new_glyph_present = false; // does the grown subset contain U+03A9?
bool new_glyph_renders = false; // can FreeType load its outline?
std::string original_subset_tag; // e.g. "AAAAAA+"
std::string grown_subset_tag;
};
// Run the subset-growth scenario:
// 1. Build an initial subset of `font_path` containing the glyphs for
// "Hello" (the "originally embedded" subset).
// 2. Grow it by adding U+03A9 (GREEK CAPITAL LETTER OMEGA) — the character
// the user typed that wasn't in the original subset.
// 3. Verify the grown subset: it must contain the new glyph, have a correct
// cmap mapping U+03A9 → a glyph id, and FreeType must be able to load
// that glyph's outline (it renders).
GrowthResult grow_subset(const std::string& font_path);
} // namespace freepdfeditor::spike::c
#endif // FREEPDFEDITOR_SPIKE_C_SUBSETGROWTH_H