mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-26 03:06:56 -06:00
Merge pull request #1613 from MarekSpodBiedry/issue-1551
IDML export: write the graphic placed in a table cell (#1551)
This commit is contained in:
@@ -2797,7 +2797,25 @@ impl<'a> Ex<'a> {
|
||||
ce.set(&format!("{side}StrokePriority"), priority);
|
||||
}
|
||||
}
|
||||
for psr in self.story_paras(&cell.text) {
|
||||
let mut paras = self.story_paras(&cell.text);
|
||||
// A graphic cell holds its image as an inline object in the cell's first paragraph.
|
||||
if let Some(g) = &cell.graphic
|
||||
&& let Some(object) = self.cell_graphic_el(g)
|
||||
{
|
||||
// The cell clips its graphic on screen and in PDF; IDML does so only when asked.
|
||||
ce.set("ClipContentToCell", bool_s(true));
|
||||
let mut range = self.csr_el(&CharFormat::default());
|
||||
range.push(object);
|
||||
match paras.first_mut() {
|
||||
Some(first) => first.push(range),
|
||||
None => {
|
||||
let mut psr = self.psr_el(&ParaFormat::default());
|
||||
psr.push(range);
|
||||
paras.push(psr);
|
||||
}
|
||||
}
|
||||
}
|
||||
for psr in paras {
|
||||
ce.push(psr);
|
||||
}
|
||||
el.push(ce);
|
||||
@@ -2806,6 +2824,20 @@ impl<'a> Ex<'a> {
|
||||
el
|
||||
}
|
||||
|
||||
/// The frame of a table cell's graphic: an inline `Rectangle` around the shown image, or `None`
|
||||
/// when the graphic's asset is missing.
|
||||
fn cell_graphic_el(&mut self, g: &designcraft_doc::Graphic) -> Option<El> {
|
||||
self.d.assets.get(&g.asset)?;
|
||||
let shown = g.xf.transform_rect_bbox(designcraft_geom::Rect::new(0.0, 0.0, g.size.0, g.size.1));
|
||||
let layer = self.d.layers.first().map(|l| l.id).unwrap_or(designcraft_doc::ids::LayerId(0));
|
||||
let mut item = Item::new(designcraft_doc::ids::ItemId(0), layer, Shape::Rectangle, designcraft_geom::shapes::rectangle(shown));
|
||||
item.content = Content::Graphic(g.clone());
|
||||
let mut el = self.item_el(&item, Affine::IDENTITY);
|
||||
el.set("Self", self.fresh());
|
||||
el.push(El::new("AnchoredObjectSetting").attr("AnchoredPosition", "InlinePosition").attr("AnchorYoffset", "0"));
|
||||
Some(el)
|
||||
}
|
||||
|
||||
fn psr_el(&mut self, pf: &ParaFormat) -> El {
|
||||
let mut el = El::new("ParagraphStyleRange").attr("AppliedParagraphStyle", names::style_self("ParagraphStyle", PARA_BUILTINS, &pf.style));
|
||||
let mut props = Vec::new();
|
||||
|
||||
@@ -4368,3 +4368,37 @@ fn cell_first_baseline_comes_from_cell_styles_table_regions_and_cells_and_round_
|
||||
let s2 = back.styles.cell.iter().find(|c| c.name == "Cap").unwrap();
|
||||
assert_eq!(s2.first_baseline, Some(FirstBaseline::CapHeight));
|
||||
}
|
||||
|
||||
/// A graphic placed in a table cell is written into the cell, not dropped.
|
||||
#[test]
|
||||
fn exports_graphic_in_table_cell() {
|
||||
let mut d = Document::new(&NewDocument::default());
|
||||
let lid = d.default_layer();
|
||||
let (_, sid) = d.add_text_frame(SpreadRef::Doc(0), Rect::new(40.0, 40.0, 400.0, 400.0), lid, "Intro", ParaFormat::default()).unwrap();
|
||||
let asset = designcraft_doc::AssetId(d.alloc());
|
||||
let id = d.add_asset(designcraft_doc::Asset {
|
||||
id: asset,
|
||||
name: "tick.png".into(),
|
||||
mime: "image/png".into(),
|
||||
data: std::sync::Arc::new(vec![1, 2, 3]),
|
||||
..Default::default()
|
||||
});
|
||||
let mut t = designcraft_doc::Table::new(d.alloc(), 2, 2, 0, 0, 200.0);
|
||||
t.cell_mut(1, 0).unwrap().graphic = Some(designcraft_doc::Graphic {
|
||||
asset: id,
|
||||
size: (24.0, 24.0),
|
||||
xf: designcraft_geom::Affine::IDENTITY,
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
wrap: Default::default(),
|
||||
fill: Default::default(),
|
||||
});
|
||||
d.story_mut(sid).unwrap().insert_table(5, t);
|
||||
let story = zip_text(&export_idml(&d), "Stories/");
|
||||
let cell = story.split("<Cell ").nth(3).unwrap_or_default();
|
||||
let cell = cell.split("</Cell>").next().unwrap_or_default();
|
||||
assert!(cell.contains("<Image "), "{story}");
|
||||
assert!(cell.contains("ClipContentToCell=\"true\""), "{story}");
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level
|
||||
- Object States (`states.create/show/rename/release/list`, Object States panel): multi-state objects show one state on screen and in PDF.
|
||||
- Buttons (`button.set/clear/list`, Buttons and Forms panel): go to page / next / previous / first / last / URL as PDF link annotations. Form fields too (`form.set/clear/list`: text fields, check boxes, combo and list boxes, signature fields; required, multiline, defaults) exported as AcroForm widgets through an incremental update (not in PDF/X or PDF/A).
|
||||
- Power Zoom (Hand tool: press and hold still for half a second, or Alt-press): zoom out to the spread, aim the red view rectangle, release to zoom back in there.
|
||||
- Graphic cells (`table.placeGraphic`, `table.textCell`, Table › Convert Cell Type, Table panel): images in table cells, fitted or filled, clipped to the cell on screen and in PDF.
|
||||
- Graphic cells (`table.placeGraphic`, `table.textCell`, Table › Convert Cell Type, Table panel): images in table cells, fitted or filled, clipped to the cell on screen and in PDF; IDML export writes them as an inline graphic in the cell.
|
||||
- Live Distribute (Space while dragging a selection handle; `transform.resize {distribute}`): objects keep their size and spread with the bounds.
|
||||
- Flex Layout (InDesign 2026; `flex.add`, `flex.convert`, `flex.remove`, `flex.set`, `flex.reorder`, Window › Flex Layout and the Properties panel's Flex Layout section): a frame lays out its objects in rows or columns by direction, wrap, justification (Flex Start, Center, Flex End, Space Between, Space Around, Space Evenly), the alignment grid, Fixed/Auto width and height, padding and spacing; aligned objects are detected on Add (direction, Auto, Space Between); resizing a container reflows it; dragging an object in one reorders it. Not yet: item sizing (Fixed/Auto/Fill Space per object), object styles with Flex Layout settings, IDML (a container exports as a frame with pasted-in objects), nested selection cues on the canvas.
|
||||
- Liquid Layout (`liquid.pageRule/object`, `guide.liquid`, `layout.createAlternate`, Liquid Layout panel): scale / re-center / guide-based / object-based page rules applied on page resize and Document Setup; dashed liquid guides; alternate layouts as resized page copies in a named section. Text in an alternate layout stays linked to the original stories (Links panel shows them out of date; `story.updateLink`).
|
||||
|
||||
Reference in New Issue
Block a user