Merge remote-tracking branch 'origin/master' into claude/issue-47

# Conflicts:
#	interfaces/Crafter.Graphics-UI.cppm
#	project.cpp
This commit is contained in:
catbot 2026-06-16 17:09:06 +00:00
commit e8f1c7cff9
15 changed files with 732 additions and 39 deletions

View file

@ -443,6 +443,93 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
fc.GetInterfacesAndImplementations(ifaces, fusedImpls);
fusedTest.requires_ = { "tool:glslang", "tool:spirv-val" };
cfg.tests.push_back(std::move(fusedTest));
// Issue #57: Font::GetLineWidth memoises per-codepoint advances in
// font units (Font::AdvanceUnits) and rescales per call, instead of
// calling stbtt_GetCodepointHMetrics for every glyph on every caret
// query. Pure CPU — Font only touches stb_truetype — so this drives
// the public API directly with no Vulkan device. The font file is
// copied next to the binary; the test also probes the project root.
Test advTest;
Configuration& vc = advTest.config;
vc.path = cfg.path;
vc.name = "FontAdvanceCache";
vc.outputName = "FontAdvanceCache";
vc.type = ConfigurationType::Executable;
vc.target = cfg.target;
vc.march = cfg.march;
vc.mtune = cfg.mtune;
vc.debug = cfg.debug;
vc.sysroot = cfg.sysroot;
vc.dependencies = cfg.dependencies;
vc.externalDependencies = cfg.externalDependencies;
vc.compileFlags = cfg.compileFlags;
vc.linkFlags = cfg.linkFlags;
vc.defines = cfg.defines;
vc.cFiles = cfg.cFiles;
vc.files = { fs::path("tests/FontAdvanceCache/font.ttf") };
std::vector<fs::path> advImpls(impls.begin(), impls.end());
advImpls.emplace_back("tests/FontAdvanceCache/main");
vc.GetInterfacesAndImplementations(ifaces, advImpls);
cfg.tests.push_back(std::move(advTest));
// Issue #50: uiResolveScreenPixel now gates its per-pixel clip-rect
// compares on the reserved kUIFlagClip bit, which FillHeader sets only
// when the clip rect is narrower than the surface. The decision lives
// in UIRenderer::ClipFlags — pure CPU logic over the clip rect and the
// surface size — so this test drives it directly with synthetic
// dimensions, no Window or GPU device needed at runtime.
Test clipTest;
Configuration& clc = clipTest.config;
clc.path = cfg.path;
clc.name = "UIClipFlag";
clc.outputName = "UIClipFlag";
clc.type = ConfigurationType::Executable;
clc.target = cfg.target;
clc.march = cfg.march;
clc.mtune = cfg.mtune;
clc.debug = cfg.debug;
clc.sysroot = cfg.sysroot;
clc.dependencies = cfg.dependencies;
clc.externalDependencies = cfg.externalDependencies;
clc.compileFlags = cfg.compileFlags;
clc.linkFlags = cfg.linkFlags;
clc.defines = cfg.defines;
clc.cFiles = cfg.cFiles;
std::vector<fs::path> clipImpls(impls.begin(), impls.end());
clipImpls.emplace_back("tests/UIClipFlag/main");
clc.GetInterfacesAndImplementations(ifaces, clipImpls);
cfg.tests.push_back(std::move(clipTest));
// Issue #56: InputField_HitTestCursor mapped a click x to a cursor byte
// offset by re-walking the prefix for every boundary (O(n^2) glyph
// metric lookups) over raw byte boundaries. It now delegates to
// Font::NearestCursorByte — one cumulative-advance pass over codepoint
// boundaries. The mapping is pure CPU over a TrueType file, so this test
// drives it directly: no Vulkan device or window. The font is copied
// next to the binary; the test also probes the project-root path.
Test hitTest;
Configuration& hc = hitTest.config;
hc.path = cfg.path;
hc.name = "InputFieldHitTest";
hc.outputName = "InputFieldHitTest";
hc.type = ConfigurationType::Executable;
hc.target = cfg.target;
hc.march = cfg.march;
hc.mtune = cfg.mtune;
hc.debug = cfg.debug;
hc.sysroot = cfg.sysroot;
hc.dependencies = cfg.dependencies;
hc.externalDependencies = cfg.externalDependencies;
hc.compileFlags = cfg.compileFlags;
hc.linkFlags = cfg.linkFlags;
hc.defines = cfg.defines;
hc.cFiles = cfg.cFiles;
hc.files = { fs::path("tests/InputFieldHitTest/font.ttf") };
std::vector<fs::path> hitImpls(impls.begin(), impls.end());
hitImpls.emplace_back("tests/InputFieldHitTest/main");
hc.GetInterfacesAndImplementations(ifaces, hitImpls);
cfg.tests.push_back(std::move(hitTest));
}
return cfg;