86 lines
3.5 KiB
C++
86 lines
3.5 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// SPDX-FileCopyrightText: 2025 ai-ad4 and the FreePDFEditor contributors
|
|
//
|
|
// GlyphRun.h — the reconstruction pipeline's input model. Mirrors the L3
|
|
// GlyphRun from §3.2 of the plan: a sequence of glyphs sharing font, size,
|
|
// color and CTM, each glyph carrying its Unicode mapping and confidence.
|
|
//
|
|
// The reconstruction spike (§4.1) takes a vector of these and produces
|
|
// paragraphs. In production these come from the content-stream interpreter;
|
|
// in the spike they come from a synthetic generator so the pipeline can be
|
|
// scored against ground truth without the full L3 stack.
|
|
|
|
#ifndef FREEPDFEDITOR_SPIKE_B_GLYPHRUN_H
|
|
#define FREEPDFEDITOR_SPIKE_B_GLYPHRUN_H
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace freepdfeditor::spike::b {
|
|
|
|
struct Point { float x; float y; };
|
|
|
|
// A single glyph as the reconstruction pipeline sees it. `unicode` and
|
|
// `confidence` are produced by the glyph→Unicode step (§4.1 step 1); the
|
|
// geometry is in device space (post-CTM) so line detection works in page
|
|
// coordinates.
|
|
struct Glyph {
|
|
std::uint32_t gid = 0; // glyph id in the font
|
|
std::uint32_t code = 0; // character code in the content stream
|
|
std::uint32_t unicode = 0; // resolved Unicode codepoint (0 if unknown)
|
|
float confidence = 0.0f; // [0,1] — see §4.1 step 1 priority ladder
|
|
Point origin {}; // pen position before this glyph (device space)
|
|
float advance = 0.0f; // horizontal advance (device space)
|
|
};
|
|
|
|
// A run of glyphs sharing typography: font, size, color, text matrix. This is
|
|
// the unit the content-stream interpreter emits; the reconstruction pipeline
|
|
// merges and re-splits runs as it builds lines and paragraphs.
|
|
struct GlyphRun {
|
|
std::uint64_t font_id = 0;
|
|
float size = 0.0f; // font size in points
|
|
float char_spacing = 0.0f;
|
|
float word_spacing = 0.0f;
|
|
float rise = 0.0f; // superscript/subscript
|
|
float rotation = 0.0f; // baseline direction in radians (0 = LTR horizontal)
|
|
// Glyphs in logical order along the baseline (advance is signed along the
|
|
// baseline direction; the pipeline handles RTL by negative advance).
|
|
std::vector<Glyph> glyphs;
|
|
};
|
|
|
|
// A detected line: glyphs whose baselines agree and which read in sequence.
|
|
struct Line {
|
|
std::vector<std::size_t> run_indices; // indices into the input run vector
|
|
float baseline_y = 0.0f; // in the run's text space (cluster along baseline dir)
|
|
float x_start = 0.0f;
|
|
float x_end = 0.0f;
|
|
float size = 0.0f; // dominant font size on this line
|
|
std::u32string text; // concatenated Unicode, in reading order
|
|
std::string marker; // list marker ("•", "1.", etc.) if detected
|
|
};
|
|
|
|
// A paragraph: consecutive lines with consistent leading and extent.
|
|
struct Paragraph {
|
|
std::vector<std::size_t> line_indices; // indices into the line vector
|
|
float top = 0.0f;
|
|
float bottom = 0.0f;
|
|
float left = 0.0f;
|
|
float right = 0.0f;
|
|
std::u32string text; // full paragraph text, lines joined
|
|
bool is_list_item = false;
|
|
};
|
|
|
|
// Ground-truth label for one paragraph, used by the scorer. Coordinates are in
|
|
// the same device space as the glyph origins.
|
|
struct GroundTruthParagraph {
|
|
float top = 0.0f;
|
|
float bottom = 0.0f;
|
|
float left = 0.0f;
|
|
float right = 0.0f;
|
|
std::u32string text;
|
|
};
|
|
|
|
} // namespace freepdfeditor::spike::b
|
|
|
|
#endif // FREEPDFEDITOR_SPIKE_B_GLYPHRUN_H
|