Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
bidi.hpp
Go to the documentation of this file.
1#pragma once
2
3// BidiAnalyzer — paragraph-level Unicode Bidirectional Algorithm
4// implementation backed by SheenBidi (Apache-2.0). Produces logical-
5// to-visual run segmentation for Arabic / Hebrew / mixed-direction
6// text. The output is consumable by TextShaper / TextRunPlanner /
7// SkShaper without depending on system ICU, which is the path the
8// existing core/canvas::TextRunPlanner prefers when Skia is linked.
9//
10// Why we ship our own bidi:
11// * iOS / Android / minimal-toolchain hosts may not link ICU.
12// * Headless tests want deterministic bidi without a Skia link.
13// * SheenBidi is small (~120 KB), Apache-2.0, no POSIX dependencies.
14//
15// Design contract:
16// * Input is UTF-8.
17// * `base_direction == Auto` invokes UBA rule P2/P3 (first strong
18// character wins). `LTR` / `RTL` force the paragraph level.
19// * Output runs are returned in **logical** order (the order the
20// bytes appear in the source string). Each run carries the
21// embedding `level` from UBA rule X1-I2; odd levels are RTL.
22// The caller (TextShaper / SkShaper) is responsible for emitting
23// RTL runs right-to-left during paint.
24// * The "visual order" helper rearranges the same runs into the
25// L1/L2 visual sequence required for line painting.
26//
27// Build modes:
28// * PULP_HAS_SHEENBIDI defined → real SheenBidi calls.
29// * Undefined → a single-run pass-through that infers level from
30// `base_direction` only (no codepoint analysis). Lets callers
31// compile without the dependency and ship a correct LTR-only
32// behavior while still exercising the API shape.
33
34#include <cstdint>
35#include <string>
36#include <string_view>
37#include <vector>
38
39namespace pulp::canvas {
40
42enum class BidiBaseDirection : std::uint8_t {
43 Auto = 0,
44 LTR = 1,
45 RTL = 2,
46};
47
52struct BidiRun {
53 std::uint32_t start = 0;
54 std::uint32_t length = 0;
55 std::uint8_t level = 0;
56
57 constexpr bool is_rtl() const noexcept { return (level & 1u) == 1u; }
58 constexpr std::uint32_t end() const noexcept { return start + length; }
59};
60
63 std::uint8_t base_level = 0;
64 std::vector<BidiRun> runs;
65 bool used_sheenbidi = false;
66};
67
69public:
73 static BidiParagraph analyze(std::string_view text,
75
81 static std::vector<BidiRun> visual_order(const std::vector<BidiRun>& runs);
82
85 static bool has_sheenbidi() noexcept;
86};
87
88} // namespace pulp::canvas
Definition bidi.hpp:68
static std::vector< BidiRun > visual_order(const std::vector< BidiRun > &runs)
Re-order runs (in logical order, as returned by analyze) into visual / paint order via UBA rules L1-L...
static BidiParagraph analyze(std::string_view text, BidiBaseDirection base_direction=BidiBaseDirection::Auto)
Analyze one paragraph of UTF-8 text.
static bool has_sheenbidi() noexcept
True when the build links SheenBidi.
Definition affine_transform.hpp:24
BidiBaseDirection
Paragraph base direction selector (UBA rule P2/P3 surfaces).
Definition bidi.hpp:42
@ Auto
Run UBA rule P2 (first strong character).
Definition bidi.hpp:43
@ LTR
Force paragraph level 0.
Definition bidi.hpp:44
@ RTL
Force paragraph level 1.
Definition bidi.hpp:45
@ text
Definition scene_node.hpp:96
Aggregate paragraph-level bidi result.
Definition bidi.hpp:62
std::vector< BidiRun > runs
Logical order.
Definition bidi.hpp:64
bool used_sheenbidi
False on the pass-through.
Definition bidi.hpp:65
std::uint8_t base_level
Definition bidi.hpp:63
One contiguous span of text that shares a single bidi embedding level.
Definition bidi.hpp:52
std::uint8_t level
0 = LTR; odd levels (1, 3, …) = RTL.
Definition bidi.hpp:55
std::uint32_t start
Definition bidi.hpp:53
constexpr std::uint32_t end() const noexcept
Definition bidi.hpp:58
constexpr bool is_rtl() const noexcept
Definition bidi.hpp:57
std::uint32_t length
Definition bidi.hpp:54