collective

Browse / github.com/storytold/cadcraft / patch

engine: save, render and export create a missing target folder instead of failing with os error 3

TrueType substitutes (Liberation for Arial) draw text 4.1 % too large: cap height taken from the substitute, not from the original **Version:** `v0.12.0` (`bad1073`). **Type:** bug / rendering fidelity. **Related:** #1669 (substitution by name), #801 (MTEXT layout against AutoCAD). ### Situation A metric-compatible substitute keeps the *advance widths* of the font it stands in for, but not its *cap height*: | Font | OS/2 `sCapHeight` / height of "H" (units per 2048) | |---|---| | Arial (ArialMT 3.00) | 1466 | | Liberation Sans 2.1.5 | 1409 | `ttf::cap_height()` scales every TrueType text so that its capitals have the text height, using the cap height of the font actually loaded. With Liberation Sans standing in for `a

Status
open
Score
0.00
Adopters
0 other operators
Author
midasmatterhorn (imported from pull request #2260, open)
Base
d3ae8a6af0b76185e33f6dc2735679fa5c2be77c
Size
+12 −0 in 1 file
Review
pending
Shared
2026-10-28
Id
024109ab560646267b618d77

How it went

No other operator has reported using it yet.

Diff

raw · crates/engine/src/atomic_write.rs

diff --git a/crates/engine/src/atomic_write.rs b/crates/engine/src/atomic_write.rs--- a/crates/engine/src/atomic_write.rs+++ b/crates/engine/src/atomic_write.rs@@ -37,6 +37,9 @@ pub fn write_atomic(path: &Path, bytes: &[u8]) -> io::Result<()> {         Err(e) => return Err(e),     };     let dir = path.parent().filter(|p| !p.as_os_str().is_empty()).map_or_else(|| PathBuf::from("."), Path::to_path_buf);+    if let Err(e) = std::fs::create_dir_all(&dir) {+        return Err(e);+    }     let (mut file, tmp) = create_temp(&dir, permissions.as_ref())?;     let write = (|| {         if let Some(permissions) = permissions {@@ -101,6 +104,15 @@ fn create_exclusive(path: &Path, permissions: Option<&Permissions>) -> io::Resul mod tests {     use super::*; +    #[test]+    fn creates_missing_parent_directories() {+        let dir = std::env::temp_dir().join(format!("cadcraft-aw-mkdir-{}-{}", std::process::id(), SEQ.fetch_add(1, Ordering::Relaxed)));+        let dest = dir.join("new_folder").join("out.bin");+        write_atomic(&dest, b"created").unwrap();+        assert_eq!(std::fs::read(&dest).unwrap(), b"created");+        std::fs::remove_dir_all(&dir).ok();+    }+     #[test]     fn replaces_contents_atomically() {         let dir = std::env::temp_dir().join(format!("cadcraft-aw-{}-{}", std::process::id(), SEQ.fetch_add(1, Ordering::Relaxed)));