Files
pdfcraft/crates/engine/tests/it/support/font_fixture.rs
T
aiongg 9526363152 Build each crate's integration tests as one binary (#4087)
* Build each crate's integration tests as one binary

Every tests/*.rs file is its own executable that links the whole crate
graph. Move each crate's test files into tests/it/ as modules of one
tests/it/main.rs, for apps/pdfcraft, apps/pdfcraft-cli, automation, cos,
crypt, engine, render, sign and ui-egui. ui-egui's ui_group binary and
the support modules move into tests/it/ too. Crates with a single test
file keep it. The test executables go from 150 to 52, and every crate
runs the same number of tests as before.

ui-egui perf keeps its own binary (own process): its frame-time budgets
would charge each measurement for the other tests running beside it.

What the move needs:
- include_str!/include_bytes! and #[path] paths gain one "../".
- ui-egui: one GPU lock in tests/it/main.rs replaces the five per-file
  ones (content, document_links, editing, fill_sign, view), so one
  process creates one wgpu device at a time. The drop-line test in ui.rs
  and the screenshot blocks behind PDFCRAFT_*_SHOT(S) and
  CRAFT_UI_DOCKING_DIR, which render without holding it, take it too.
- pdfcraft winit_wayland_scroll: the vendored winit source it compiles
  names crate::event, so that shim lives in main.rs.
- parity evidence names the new paths.

* Name the one-binary test paths in docs and comments

- READMEs, docs, ATTRIBUTION and source comments name tests/it/<file>.rs.
- The oracle README's example filters with --test it encryption::qpdf_agrees.
- pdfcraft's GPU lock comment points at the UI tests' shared lock in
  crates/ui-egui/tests/it/main.rs.
2026-10-22 11:28:58 -04:00

129 lines
4.0 KiB
Rust

//! Contributor-original rectangle font, generated entirely in memory: no binary fixture.
fn be16(out: &mut Vec<u8>, n: u16) {
out.extend_from_slice(&n.to_be_bytes());
}
fn be32(out: &mut Vec<u8>, n: u32) {
out.extend_from_slice(&n.to_be_bytes());
}
fn number(n: i16) -> Vec<u8> {
let mut v = vec![28];
v.extend_from_slice(&n.to_be_bytes());
v
}
fn index(items: &[Vec<u8>]) -> Vec<u8> {
let mut out = Vec::new();
be16(&mut out, items.len() as u16);
if items.is_empty() {
return out;
}
out.push(1);
let mut at = 1;
out.push(at);
for i in items {
at += i.len() as u8;
out.push(at);
}
for i in items {
out.extend(i);
}
out
}
pub fn cff_font() -> Vec<u8> {
let name = index(&[b"RectFont".to_vec()]);
let mut dict = Vec::new();
for n in [0, 0, 500, 700] {
dict.extend(number(n));
}
dict.push(5);
// All CFF integers are fixed-width, so the CharStrings absolute offset is stable.
let offset = 4 + name.len() + index(&[vec![0; dict.len() + 4]]).len() + 4;
dict.extend(number(offset as i16));
dict.push(17);
let mut rectangle = number(600);
rectangle.extend([139, 139, 21]);
for n in [500, 0, 0, 700, -500, 0, 0, -700] {
rectangle.extend(number(n));
}
rectangle.extend([5, 14]);
let mut cff = vec![1, 0, 4, 4];
cff.extend(name);
cff.extend(index(&[dict]));
cff.extend([0, 0, 0, 0]);
cff.extend(index(&[
vec![14],
{
let mut v = number(300);
v.push(14);
v
},
rectangle,
]));
let mut head = vec![0; 54];
head[0..4].copy_from_slice(&[0, 1, 0, 0]);
head[12..16].copy_from_slice(&0x5f0f3cf5u32.to_be_bytes());
head[18..20].copy_from_slice(&1000u16.to_be_bytes());
head[40..42].copy_from_slice(&500i16.to_be_bytes());
head[42..44].copy_from_slice(&700i16.to_be_bytes());
let mut hhea = vec![0; 36];
hhea[0..4].copy_from_slice(&[0, 1, 0, 0]);
hhea[4..6].copy_from_slice(&700i16.to_be_bytes());
hhea[6..8].copy_from_slice(&(-200i16).to_be_bytes());
hhea[34..36].copy_from_slice(&3u16.to_be_bytes());
let mut hmtx = Vec::new();
for w in [600, 300, 600] {
be16(&mut hmtx, w);
be16(&mut hmtx, 0);
}
let mut maxp = vec![0, 0, 0x50, 0];
be16(&mut maxp, 3);
let mut cmap = vec![0, 0, 0, 1, 0, 3, 0, 10];
be32(&mut cmap, 12);
be16(&mut cmap, 12);
be16(&mut cmap, 0);
be32(&mut cmap, 40);
be32(&mut cmap, 0);
be32(&mut cmap, 2);
for (cp, gid) in [(32, 1), (65, 2)] {
be32(&mut cmap, cp);
be32(&mut cmap, cp);
be32(&mut cmap, gid);
}
let names = [(1, "Rect Font"), (2, "Regular"), (6, "RectFont-Regular"), (13, "MIT License")];
let mut name = Vec::new();
be16(&mut name, 0);
be16(&mut name, names.len() as u16);
be16(&mut name, (6 + 12 * names.len()) as u16);
let mut data = Vec::new();
for (id, text) in names {
let bytes: Vec<_> = text.encode_utf16().flat_map(u16::to_be_bytes).collect();
for n in [3, 1, 0x409, id, bytes.len() as u16, data.len() as u16] {
be16(&mut name, n);
}
data.extend(bytes);
}
name.extend(data);
let tables = [(*b"CFF ", cff), (*b"cmap", cmap), (*b"head", head), (*b"hhea", hhea), (*b"hmtx", hmtx), (*b"maxp", maxp), (*b"name", name)];
let mut out = b"OTTO".to_vec();
be16(&mut out, 7);
be16(&mut out, 64);
be16(&mut out, 2);
be16(&mut out, 48);
let mut payload = Vec::new();
let mut offset = 12 + 16 * tables.len();
for (tag, bytes) in tables {
out.extend(tag);
let mut padded = bytes.clone();
while padded.len() % 4 != 0 {
padded.push(0);
}
let sum = padded.as_chunks::<4>().0.iter().fold(0u32, |s, b| s.wrapping_add(u32::from_be_bytes(*b)));
be32(&mut out, sum);
be32(&mut out, offset as u32);
be32(&mut out, bytes.len() as u32);
offset += padded.len();
payload.extend(padded);
}
out.extend(payload);
out
}