mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
Text frames: opening a file keeps its auto-size frame sizes
This commit is contained in:
+1
-1
@@ -129,7 +129,7 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m
|
||||
|
||||
Newest first.
|
||||
|
||||
- **2026-10-12** · Text frame auto-size: Height Only, Width Only, Height and Width (also keeping proportions) frames grow and shrink to fit their text after edits and IDML import, around their reference point, with minimum sizes and No Line Breaks, in the same undo step (#180). No readiness percentage change.
|
||||
- **2026-10-12** · Text frame auto-size: Height Only, Width Only, Height and Width (also keeping proportions) frames grow and shrink to fit their text after edits, around their reference point, with minimum sizes and No Line Breaks, in the same undo step (#180). No readiness percentage change.
|
||||
- **2026-10-12** · Orderly native exit writes the latest recovery state after finalizing current quit approvals; incomplete or stale plans keep their documents, and Undo to the saved state clears stale recovery. Unavailable or failed recovery is reported. Cancelable macOS Dock Quit remains open (#544). No readiness percentage change.
|
||||
- **2026-10-12** · Recovered documents keep a checkpoint until saved, closed or reverted, including a second crash before autosave. Restarted document IDs and explicit recovery folders preserve other snapshots; failed republishing retains the original. No readiness percentage change.
|
||||
- **2026-10-12** · Book numbering and style updates prepare every chapter before saving. Only closed native chapters are changed; imported IDML remains a read-only style/PDF source. If a later disk write fails, the error names the completed chapters; the batch is not a whole-book transaction. No readiness percentage change.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! Text frame auto-size (Text Frame Options › Auto-Size): frames grow and shrink to fit their text.
|
||||
//!
|
||||
//! [`apply`] runs after every undoable command (so the resize is part of the same undo step) and
|
||||
//! after IDML import. It measures each auto-size frame whose story, styles or own item changed,
|
||||
//! [`apply`] runs after every undoable command (so the resize is part of the same undo step). Opening
|
||||
//! a file leaves frames at the sizes it gives them: those were fitted to the document's own fonts,
|
||||
//! and a substitute font would otherwise move frames around text nobody edited. It measures each auto-size frame whose story, styles or own item changed,
|
||||
//! with the frame opened to [`MAX_SIDE`], and resizes it in its inner space around its reference
|
||||
//! point, so that point stays put in spread space whatever the frame's transform.
|
||||
//!
|
||||
|
||||
@@ -646,9 +646,6 @@ fn file_revert(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
};
|
||||
// As opened again: the fonts beside it now (unchanged files are shared, not read again).
|
||||
let (fonts, _, _) = load_document_fonts(&mut d, &path);
|
||||
if path.to_ascii_lowercase().ends_with(".idml") {
|
||||
crate::autosize::apply(&mut d, None);
|
||||
}
|
||||
let uid = s.doc()?.uid;
|
||||
let recovery_dir = s.recovery_dir.clone();
|
||||
let index = s.active_index().ok_or(EngineError::NoDocument)?;
|
||||
|
||||
@@ -157,8 +157,6 @@ pub(crate) fn open_idml(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
None => (None, 0, Vec::new()),
|
||||
};
|
||||
warnings.extend(font_warnings);
|
||||
// Auto-size frames fit their text as set here (with the document's fonts loaded).
|
||||
crate::autosize::apply(&mut d, None);
|
||||
// Never save over the .idml with the native format: the document starts unsaved.
|
||||
let mut st = DocState::new(d, None);
|
||||
st.fonts = fonts;
|
||||
|
||||
@@ -138,8 +138,8 @@ fn a_threaded_frame_before_the_last_does_not_auto_size() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn idml_import_fits_height_only_frames() {
|
||||
// A 36 pt label in a frame 0.8 × its size tall: overset until auto-size grows it.
|
||||
fn opening_leaves_auto_size_frames_as_they_are() {
|
||||
// A 36 pt label in a frame 0.8 × its size tall: overset until an edit fits it.
|
||||
let mut s = session();
|
||||
let r = s.execute("frame.create", &json!({"rect": [36.0, 36.0, 300.0, 64.8], "content": "text"})).unwrap();
|
||||
let (id, sid) = (ItemId(r["id"].as_u64().unwrap()), StoryId(r["story"].as_u64().unwrap()));
|
||||
@@ -160,9 +160,14 @@ fn idml_import_fits_height_only_frames() {
|
||||
s.execute("file.openIdml", &json!({"base64": idml, "name": "labels.idml"})).unwrap();
|
||||
let d = &s.doc().unwrap().doc;
|
||||
let (fid, story) = d.stories.values().find(|st| st.text == "Brand Bible").map(|st| (st.frames[0], st.id)).unwrap();
|
||||
let cs = designcraft_compose::compose_story(d, story, &Default::default());
|
||||
assert!(!cs.is_overset(), "the label shows after import");
|
||||
let b = d.item(fid).unwrap().bounds();
|
||||
let b = bounds(&s, fid);
|
||||
assert!((b.height() - orig.height()).abs() < 1e-3 && (b.y0 - orig.y0).abs() < 1e-3, "{b:?}");
|
||||
assert!(overset(&s, story));
|
||||
// The first edit to the story fits the frame.
|
||||
s.execute("text.select", &json!({"story": story.0, "anchor": 11, "focus": 11})).unwrap();
|
||||
s.execute("text.insert", &json!({"text": "!"})).unwrap();
|
||||
assert!(!overset(&s, story));
|
||||
let b = bounds(&s, fid);
|
||||
assert!(b.height() > 36.0 && (b.y0 - orig.y0).abs() < 1e-3, "{b:?}");
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ Kind: **F** feature · **U** UI/UX · **T** typography · **FF** file format ·
|
||||
black-box, results kept under `plan/`) and by DesignCraft, comparing line breaks, overset and
|
||||
frame fit. Known differences: optical kerning falls back to metrics, so imported text sets
|
||||
wider (#181); a frame goes overset when descenders don't fit, InDesign needs only the baseline
|
||||
(#180; auto-size frames fit their text on import); setting the text language was missing (#130; Language is now in Properties, #145, the issue is still open); "hyphenation doesn't work"
|
||||
(#180); setting the text language was missing (#130; Language is now in Properties, #145, the issue is still open); "hyphenation doesn't work"
|
||||
(#87).
|
||||
- **Impact:** an opened IDML reflows: different line breaks, different page count, overset text.
|
||||
Professionals notice on the first page.
|
||||
|
||||
@@ -337,7 +337,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- Stroke styles: striped (thick-thin… and custom bands), wavy and straight-hash strokes now draw on screen and in PDF; named custom stripe/dash/dot styles (`strokeStyle.new/delete/list`, Stroke panel Type list; IDML Striped/Dashed/DottedStrokeStyle).
|
||||
- Object ▸ Primary Text Frame (`object.primaryTextFrame`): any text frame's story can become (or stop being) the primary story Smart Text Reflow follows.
|
||||
- Column rules (Text Frame Options › Column Rules, `object.textFrameOptions {columnRule, columnRuleWeight, columnRuleColor, columnRuleTint, columnRuleOffset, columnRuleTopInset, columnRuleBottomInset}`, reported by `document.inspect`): a bar centred in each gutter of a multi-column frame, inside the insets and between the columns of right-to-left and vertical frames too, broken around paragraphs that span columns, with weight, colour, tint, horizontal offset and top/bottom insets; on screen, in PDF (tagged as an artifact) and in IDML (`ColumnRule…` attributes of `TextFramePreference`, also in object styles). The dialog shows the frame's options and changes only the fields edited. Rule stroke types and overprint aren't there yet.
|
||||
- Auto-size (Text Frame Options › Auto-Size, `object.textFrameOptions {autoSize: off|heightOnly|widthOnly|heightAndWidth|heightAndWidthProportionally, autoSizeReference, useMinimumHeight, minimumHeight, useMinimumWidth, minimumWidth, noLineBreaks}`): the frame fits its text exactly after every edit (typing, pasting, style changes, option changes) in the same undo step, and after IDML import; it grows and shrinks around the reference point, which stays put in spread space for rotated frames too, never below the minimum height/width and never past 10,000 pt. Width Only and No Line Breaks set each paragraph on one line; Height and Width without No Line Breaks keeps the width; Keep Proportions scales both sides until the text fits. IDML keeps all the options (`AutoSizing…`, `…ForAutoSizing` attributes). Not covered: frames of a thread other than the last, vertical frames, type on a path, and multi-column balancing in Keep Proportions.
|
||||
- Auto-size (Text Frame Options › Auto-Size, `object.textFrameOptions {autoSize: off|heightOnly|widthOnly|heightAndWidth|heightAndWidthProportionally, autoSizeReference, useMinimumHeight, minimumHeight, useMinimumWidth, minimumWidth, noLineBreaks}`): the frame fits its text exactly after every edit (typing, pasting, style changes, option changes) in the same undo step (opening a file keeps the frame sizes it gives); it grows and shrinks around the reference point, which stays put in spread space for rotated frames too, never below the minimum height/width and never past 10,000 pt. Width Only and No Line Breaks set each paragraph on one line; Height and Width without No Line Breaks keeps the width; Keep Proportions scales both sides until the text fits. IDML keeps all the options (`AutoSizing…`, `…ForAutoSizing` attributes). Not covered: frames of a thread other than the last, vertical frames, type on a path, and multi-column balancing in Keep Proportions.
|
||||
- Place a page of an IDML or DesignCraft document (`file.place {layoutPage}`): its objects, stories, styles and swatches as one group (INDD files are not readable).
|
||||
- Articles panel (`article.new/add/remove/options/delete/list`): reading order and content of EPUB and HTML exports.
|
||||
- Object ▸ Clipping Path (`object.clippingPath {type: alpha|edges, threshold, tolerance}`): traces the placed image and makes the outline the frame.
|
||||
|
||||
Reference in New Issue
Block a user