Render: a 3-D picture's border stays centred on its edge
Follow-up to drawing picture borders outside the picture: PowerPoint does that for flat pictures only. A picture seen through a 3-D scene with a bevel (a common picture style) gets its border centred on the edge like any shape: observed with an 18 pt border, which then covers 9 pt of the picture. The corpus deck 60810 (white-framed bevelled screenshots) showed the screenshots' own edges once the border moved out; it now matches PowerPoint again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0c5ddb5dea
commit
0cbcbebf68
|
|
@ -875,7 +875,7 @@ impl Renderer {
|
|||
};
|
||||
let (base, rel) = self.line_space(m, depth);
|
||||
let lw = line.width.unwrap_or(0.75).max(0.0);
|
||||
let outside = if is_pic { outside_line(&line, lw) } else { None };
|
||||
let outside = if border_outside(is_pic, effects.as_ref()) { outside_line(&line, lw) } else { None };
|
||||
Caster { line: outside.map_or(std::borrow::Cow::Borrowed(&line), std::borrow::Cow::Owned), ph: line_ph, alpha: a, base, rel }
|
||||
});
|
||||
self.effects_below(ctx, rctx, e, fx_ph, &geo, &fill, fill_alpha, outline, content.as_ref(), m, w, h);
|
||||
|
|
@ -1000,8 +1000,8 @@ impl Renderer {
|
|||
None => std::borrow::Cow::Borrowed(&line),
|
||||
};
|
||||
// A picture's border lies outside the picture, as PowerPoint draws it: stroked twice
|
||||
// as wide, outside the outline only.
|
||||
let outside = is_pic.then(|| outside_line(&line, lw)).flatten();
|
||||
// as wide, outside the outline only (see `border_outside`).
|
||||
let outside = border_outside(is_pic, effects.as_ref()).then(|| outside_line(&line, lw)).flatten();
|
||||
let clipped = outside.is_some();
|
||||
let (line, lw) = match outside {
|
||||
Some(o) => {
|
||||
|
|
@ -1242,6 +1242,13 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether a shape's border is drawn outside its outline: a picture's is, unless the picture is
|
||||
/// drawn in 3-D (a bevel seen through a 3-D scene), where PowerPoint centres it on the edge as on
|
||||
/// any shape (observed: an 18 pt border covers 9 pt of the picture then).
|
||||
fn border_outside(is_pic: bool, effects: Option<&Effects>) -> bool {
|
||||
is_pic && !effects.is_some_and(|e| e.bevel.is_some() && e.raw3d.as_deref().is_some_and(|r| r.contains("scene3d")))
|
||||
}
|
||||
|
||||
/// The line that draws `line` (`lw` wide) outside a picture: twice as wide, so the half outside
|
||||
/// the outline is the border, with dashes kept their length. `None` for compound lines, whose
|
||||
/// bands would not survive the doubling (they stay centred on the outline).
|
||||
|
|
|
|||
|
|
@ -371,3 +371,19 @@ fn a_linear_gradient_spans_its_tile_rect() {
|
|||
assert!(img.pixel(102, 150)[0] > 240);
|
||||
assert!(img.pixel(305, 150)[0] < 15 && img.pixel(495, 150)[0] < 15, "{:?}", img.pixel(305, 150));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_3d_pictures_border_stays_centred_on_its_edge() {
|
||||
let mut p = picture_deck(Some(Line::solid(ColorRef::rgb(RED), 8.0)));
|
||||
let s = std::sync::Arc::make_mut(&mut p.slides[0]);
|
||||
if let Some(sh) = s.shapes.first_mut() {
|
||||
sh.effects = Some(deckcraft_model::Effects {
|
||||
bevel: Some("circle".into()),
|
||||
raw3d: Some("<a:scene3d><a:camera prst=\"orthographicFront\"/></a:scene3d><a:sp3d><a:bevelT/></a:sp3d>".into()),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
let img = render_slide(&p, 0, &RenderOpts { scale: 1.0, ..Default::default() });
|
||||
assert!(close(img.pixel(102, 150), RED, 30), "covers the picture's edge {:?}", img.pixel(102, 150));
|
||||
assert!(close(img.pixel(94, 150), WHITE, 10), "reaches half the width out {:?}", img.pixel(94, 150));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue