Merge upstream main b617158 (18 more PRs landed) into next

Upstream squash-merged #142 #147 #254 #122 #224 #229 #230 #244 #247
#269 #249 #200 #276 #283 #268 #236 #272 #143 after 4fbf893. next already
holds every one of them except #200 (PDF/X-4 validation command:
designcraft-cli validate-pdf) and #268 (GitHub Actions version bumps),
which this merge brings in unchanged. Apart from those two, the merged
tree equals next's.

Each squash commit S equals the clean 3-way merge of S^ with the PR's
current head (refs/pull/N/head). For #142 #147 #254 #236 #143 that head
is newer than the one on next: the maintainer merged upstream main into
the PR before squashing.

Maintainer edits (all already on next, so nothing to carry over):
- #142 (7dd948a): control bar keeps #112's horizontal ScrollArea with
  #142's horizontal_top inside it. next has the same (plus #255's
  object_control and integration 00cf932's tests).
- #147 (fa4c605): the full-decode check at the top of lossless() kept
  with #128's interpolate flag. next has the check at the top of #223's
  lossless() with RasterMode.
- #254 (80c0ada): USAGE keeps #127's export-options note. next has the
  same USAGE line.
- #236 (504ea4a): uk entries for "Can't Open the File" and "Can't Place
  the File". next has both with the same translations (integration
  92b1a96); kept at next's position, not duplicated.
- #143 (eaa76a4, d6c9762): one test_window harness with open, wheel,
  panel_rect and click_at. next has the same module.

Conflict: ROADMAP.md: next's lines (CJK-MOJI block, Text engine line, RTL and Interface language with Italian and Ukrainian)
Conflict: apps/designcraft/src/main.rs: next's `mod graphics` (#168)
Conflict: crates/compose/src/lib.rs: next's paragraph start via `go` (#285 with #276's next_column), ends_para via is_break_char, in-paragraph break through break_start, Cursor without the second resume(); git auto-merged #276's band-closing block a second time, kept once
Conflict: crates/compose/src/tests.rs: next's tests; #283's line_before_a_break_character_is_a_last_line, auto-merged a second time, kept once
Conflict: crates/engine/src/cmd/fonts.rs: tests only; next's composite_tests (#126) kept
Conflict: crates/engine/src/cmd/interchange.rs: tests only; next's INDD routing test kept
Conflict: crates/fonts/src/fontdb.rs: next's plausible/typo_ascent (#81), style_traits/traits_of with exact_style_traits and canonical_family (#81, #126, #247), face() through canonical_family and find_or_load
Conflict: crates/idml/src/import.rs: next's tint() helper (#83) for #230's colour tint
Conflict: crates/idml/src/tests.rs: tests only; next's drop cap and anchored frame tests kept
Conflict: crates/pdf/src/export.rs: next's RasterMode image path (#223 with #147's decode check)
Conflict: crates/ui-egui/src/dialogs.rs: next's paragraph style dialog (new style, #144's basic_character_formats and character_color sections), Find Font FALLBACK_FAMILY default (#126)
Conflict: crates/ui-egui/src/i18n.rs: next's Italian (#218) beside #236 and #272
Conflict: crates/ui-egui/src/i18n/uk.rs: next's table (see #236 above)
Conflict: crates/ui-egui/src/lib.rs: next's Control bar second-row test via the object_control group (00cf932), browser import tests (#119)
Conflict: crates/ui-egui/src/menus.rs: next's language lists with it; #236's ukrainian_language test, auto-merged a second time, kept once
This commit is contained in:
aiongg
2026-10-10 05:59:50 +00:00
6 changed files with 53 additions and 49 deletions
+3 -4
View File
@@ -27,16 +27,15 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 300
steps:
- uses: actions/checkout@v4
# The Japanese font tests run against craft-fonts (an optional build input; they skip without it).
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
path: craft-fonts
- name: Build and test in a FreeBSD VM
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1.5.9
with:
release: "14.3"
usesh: true
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
env:
ACTIONLINT_VERSION: 1.7.12
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install tools
run: |
sudo apt-get update
+29 -34
View File
@@ -44,7 +44,7 @@ jobs:
date: ${{ steps.v.outputs.date }}
prerelease: ${{ steps.v.outputs.prerelease }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: v
name: Resolve version
run: |
@@ -72,18 +72,17 @@ jobs:
DESIGNCRAFT_VERSION: ${{ needs.version.outputs.version }}
DESIGNCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
steps:
- uses: actions/checkout@v4
# Optional font input (docs: storytold/craft-fonts docs/integration.md); releases always embed it.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
path: craft-fonts
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@686976e191b89faba57d3206551f0f330d8cb249 # stable
with:
targets: aarch64-apple-darwin, x86_64-apple-darwin
- uses: Swatinem/rust-cache@v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: release-macos-universal
- name: Apply version override
@@ -103,7 +102,7 @@ jobs:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: packaging/macos/package.sh --arch universal
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-macos
path: dist/release/*
@@ -131,18 +130,17 @@ jobs:
DESIGNCRAFT_VERSION: ${{ needs.version.outputs.version }}
DESIGNCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
steps:
- uses: actions/checkout@v4
# Optional font input (docs: storytold/craft-fonts docs/integration.md); releases always embed it.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
path: craft-fonts
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@686976e191b89faba57d3206551f0f330d8cb249 # stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: release-windows-${{ matrix.arch }}
- name: Apply version override
@@ -166,7 +164,7 @@ jobs:
AZURE_SIGNING_ACCOUNT: ${{ secrets.AZURE_SIGNING_ACCOUNT }}
AZURE_CERT_PROFILE: ${{ secrets.AZURE_CERT_PROFILE }}
run: ./packaging/windows/package.ps1 -Arch ${{ matrix.arch }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-windows-${{ matrix.arch }}
path: dist/release/*
@@ -190,10 +188,9 @@ jobs:
DESIGNCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
NFPM_VERSION: 2.47.0
steps:
- uses: actions/checkout@v4
# Optional font input (docs: storytold/craft-fonts docs/integration.md); releases always embed it.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
@@ -207,8 +204,8 @@ jobs:
curl -fsSL -o "$RUNNER_TEMP/nfpm.deb" \
"https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${NFPM_VERSION}_${{ matrix.deb }}.deb"
sudo dpkg -i "$RUNNER_TEMP/nfpm.deb"
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@686976e191b89faba57d3206551f0f330d8cb249 # stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: release-linux-${{ matrix.arch }}
- name: Apply version override
@@ -232,7 +229,7 @@ jobs:
"$appimage" --appimage-updateinformation | grep -F 'gh-releases-zsync|'
test -s "$appimage.zsync"
done
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-linux-${{ matrix.arch }}
path: dist/release/*
@@ -255,8 +252,8 @@ jobs:
DESIGNCRAFT_VERSION: ${{ needs.version.outputs.version }}
DESIGNCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: release-linux-${{ matrix.arch }}
path: dist/linux
@@ -270,7 +267,7 @@ jobs:
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- name: Build the Flatpak bundle
run: packaging/linux/flatpak-bundle.sh "dist/linux/designcraft-$DESIGNCRAFT_VERSION-linux-${{ matrix.arch }}.tar.gz"
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-flatpak-${{ matrix.arch }}
path: dist/release/*.flatpak
@@ -288,17 +285,16 @@ jobs:
DESIGNCRAFT_VERSION: ${{ needs.version.outputs.version }}
DESIGNCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
steps:
- uses: actions/checkout@v4
# Optional font input (docs: storytold/craft-fonts docs/integration.md); releases always embed it.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
path: craft-fonts
- name: Build and package in a FreeBSD VM (tar.gz)
# vmactions/freebsd-vm v1.5.9, pinned by commit (it runs our build).
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1.5.9
with:
release: "14.3"
usesh: true
@@ -323,7 +319,7 @@ jobs:
bash packaging/freebsd/package.sh
tar -tzf dist/release/designcraft-*-freebsd-x86_64.tar.gz \
| grep -E '/bin/designcraft$|/bin/designcraft-cli$|/share/applications/ai\.storyteller\.designcraft\.desktop$|/share/doc/designcraft/LICENSE-MIT$'
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-freebsd-x86_64
path: dist/release/*
@@ -339,18 +335,17 @@ jobs:
DESIGNCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
TRUNK_VERSION: 0.21.14
steps:
- uses: actions/checkout@v4
# Optional font input (docs: storytold/craft-fonts docs/integration.md); releases always embed it.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
path: craft-fonts
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@686976e191b89faba57d3206551f0f330d8cb249 # stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: release-web
- name: Install trunk
@@ -366,7 +361,7 @@ jobs:
CRAFT_FONTS_DIR: ${{ github.workspace }}/craft-fonts
CRAFT_FONTS_REQUIRED: "1"
run: packaging/web/package.sh
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-web
path: dist/release/*
@@ -385,7 +380,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
pattern: release-*
path: artifacts
+5 -5
View File
@@ -36,11 +36,11 @@ jobs:
runs-on: windows-latest
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@89b12181fb390509a0842a86cc55eeb8eb928c1d # stable
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@686976e191b89faba57d3206551f0f330d8cb249 # stable
with:
targets: aarch64-pc-windows-msvc
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: windows-arm64-package
- name: Install WiX
@@ -51,7 +51,7 @@ jobs:
env:
DIST: ${{ github.workspace }}\dist\arm64
run: ./packaging/windows/package.ps1 -Arch arm64
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: designcraft-windows-arm64
path: dist/arm64/*
@@ -64,7 +64,7 @@ jobs:
runs-on: windows-11-arm
timeout-minutes: 30
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: designcraft-windows-arm64
path: dist
+12
View File
@@ -12,6 +12,7 @@
//! designcraft-cli mcp [--connect PORT] [--sample] # MCP server over stdio (docs/mcp.md)
//! designcraft-cli perf [--pages N] [--frames N] [--chars N] [--images N] [--runs N] [--strict] # budgets on a synthetic stress document
//! designcraft-cli bench FILE [--runs N] # the same measurements on one document
//! designcraft-cli validate-pdf FILE.pdf # run the built-in PDF/X-4 conformance checks
//! designcraft-cli links # Discord, website, app page and GitHub links
//! designcraft-cli --version # print the version
//! ```
@@ -84,6 +85,7 @@ fn main() -> ExitCode {
Some("mcp") => report(mcp(&args[1..])),
Some("perf") => report(perf::perf(&args[1..])),
Some("bench") => report(perf::bench(&args[1..])),
Some("validate-pdf") => report(validate_pdf(args.get(1).map(String::as_str))),
Some("links") => {
use designcraft_engine::links::*;
outln!("Discord {DISCORD}\nWebsite {WEBSITE}\nApp page {APP_PAGE}\nGitHub {GITHUB}\nIssues {ISSUES}");
@@ -114,6 +116,16 @@ fn report(r: Result<(), String>) -> ExitCode {
}
}
fn validate_pdf(path: Option<&str>) -> Result<(), String> {
let path = path.ok_or("usage: designcraft-cli validate-pdf FILE.pdf")?;
let bytes = std::fs::read(path).map_err(|e| format!("{path}: {e}"))?;
let issues = designcraft_pdf::check_pdfx4(&bytes);
let valid = issues.is_empty();
let report = json!({"path": path, "standard": "PDF/X-4", "valid": valid, "issues": issues});
outln!("{}", serde_json::to_string_pretty(&report).map_err(|e| e.to_string())?);
if valid { Ok(()) } else { Err(format!("{path} failed PDF/X-4 validation")) }
}
/// `mcp` (headless, in-process engine) or `mcp --connect PORT|HOST:PORT` (drive a running app
/// started with `designcraft --control PORT`). JSON-RPC on stdin/stdout; logs on stderr.
fn mcp(args: &[String]) -> Result<(), String> {
+3 -5
View File
@@ -22,9 +22,8 @@
//! Unicode mapping taken from the story text (ligatures, page numbers and inserted hyphens get the
//! right characters), so text is selectable and searchable.
//! - **Marks:** crop marks, bleed marks and a page-information line, drawn in `[Registration]`.
//! - **Standards:** PDF/A-2b through krilla's validator. PDF/X-4 writes PDF 1.6 with trim/bleed
//! boxes, but the PDF/X output intent and identification are not written yet (krilla 0.8 has no
//! PDF/X support) — the export report says so.
//! - **Standards:** PDF/A-2b through krilla's validator and PDF/X-4 output intent/identification
//! with built-in conformance checks. `designcraft-cli validate-pdf` exposes those checks for CI.
//!
//! Not yet: tagged PDF, bookmarks, hyperlinks, overprint, layers as optional content.
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
@@ -48,8 +47,7 @@ pub enum Standard {
/// Plain PDF 1.7.
#[default]
None,
/// PDF/X-4 (PDF 1.6, trim/bleed boxes). TODO: OutputIntent + GTS_PDFXVersion once krilla
/// supports PDF/X.
/// PDF/X-4 (PDF 1.6, trim/bleed boxes, output intent and identification).
PdfX4,
/// PDF/A-2b (archival; validated by krilla).
PdfA2b,