Merge pull request #6523 from dotCooCoo/fix/render-document-composite-fonts

Render: type in a document's own composite font draws in its definition
This commit is contained in:
BFlat
2026-11-11 13:17:10 +07:00
committed by GitHub
2 changed files with 51 additions and 1 deletions
+7 -1
View File
@@ -105,8 +105,11 @@ impl Renderer {
}
}
/// Render `doc` into a `width`×`height` image using `view` (document → pixel transform).
/// Render `doc` into a `width`×`height` image using `view` (document → pixel transform). Type
/// set in one of the document's composite fonts draws in the document's definition, also when
/// no session has registered it (a document that is not in front, or read from a file).
pub fn render(&mut self, doc: &Document, width: u32, height: u32, view: Affine, opts: &RenderOptions) -> Rendered {
let _lent = vectorcraft_text::FontDb::global().lend_composite_fonts(&doc.composite_fonts);
let _frame = vectorcraft_text::KeptLayoutsFrame::begin();
self.render_as(doc, width, height, view, opts, false, 1)
}
@@ -340,6 +343,7 @@ impl Renderer {
pub fn render_region_inks(&mut self, doc: &Document, region: Rect, scale: f64, opts: &RenderOptions) -> Vec<u8> {
let (w, h) = region_pixels(region, scale);
let view = Affine::scale(scale) * Affine::translate((-region.x0, -region.y0));
let _lent = vectorcraft_text::FontDb::global().lend_composite_fonts(&doc.composite_fonts);
let _frame = vectorcraft_text::KeptLayoutsFrame::begin();
self.render_as(doc, w, h, view, opts, true, 1).pixels
}
@@ -356,6 +360,7 @@ impl Renderer {
/// [`Self::render_node`] with `opts` (e.g. [`RenderOptions::mark_undecoded_images`]).
pub fn render_node_with(&mut self, doc: &Document, n: &Arc<Node>, w: u16, h: u16, view: Affine, opts: &RenderOptions) -> Option<Rendered> {
let _lent = vectorcraft_text::FontDb::global().lend_composite_fonts(&doc.composite_fonts);
self.check_plugins(doc);
self.check_symbols(doc);
let inv = view.inverse();
@@ -395,6 +400,7 @@ impl Renderer {
background: Option<[u8; 4]>,
opts: &RenderOptions,
) -> Option<Rendered> {
let _lent = vectorcraft_text::FontDb::global().lend_composite_fonts(&doc.composite_fonts);
self.check_plugins(doc);
self.check_symbols(doc);
let b = brush_fx::cull_bounds(&doc.symbol_boxes(), n)?;
+44
View File
@@ -138,6 +138,50 @@ fn composite_font_parts_are_not_highlighted_as_substituted_glyphs() {
assert!(g.substituted_glyphs.elements().is_empty() && g.substituted_fonts.elements().is_empty());
}
/// Type in one of a document's composite fonts draws in the document's definition when nothing has
/// registered it: in a render, an ink render, a thumbnail and a placed document's art, as type set
/// in the part's font draws.
/// The font database is left without it afterwards.
#[test]
fn a_documents_own_composite_font_draws_without_being_registered() {
use vectorcraft_doc::{CompositeFont, CompositePart, CompositeParts};
let _adding = adding_fonts();
const NAME: &str = "CF Unregistered";
let db = vectorcraft_text::FontDb::global();
let typed = |family: &str| {
let mut d = Document::new(300.0, 150.0);
let style = CharStyle { size: 60.0, font_family: family.into(), ..Default::default() };
let n = Node::new(d.alloc_id(), NodeKind::Text(Box::new(TextObject::point(Point::new(10.0, 100.0), "Hamburg", style))));
let l = d.layers[0].id;
let id = d.insert(Some(l), 0, n).unwrap();
(d, id)
};
let (mut composite, id) = typed(NAME);
let mut parts = CompositeParts::all(CompositePart::new("Source Sans 3", "Regular"));
parts.roman = CompositePart::new("JetBrains Mono", "Regular");
composite.composite_fonts.push(CompositeFont { name: NAME.into(), parts });
let (plain, plain_id) = typed("JetBrains Mono");
assert!(db.composite_font(NAME).is_none());
let opts = RenderOptions { background: Some([255, 255, 255, 255]), ..Default::default() };
let view = Affine::IDENTITY;
assert_eq!(
Renderer::new().render(&composite, 300, 150, view, &opts).pixels,
Renderer::new().render(&plain, 300, 150, view, &opts).pixels,
"rendered"
);
let region = Rect::new(0.0, 0.0, 300.0, 150.0);
assert_eq!(
Renderer::new().render_region_inks(&composite, region, 1.0, &opts),
Renderer::new().render_region_inks(&plain, region, 1.0, &opts),
"rendered as ink amounts"
);
let thumbnail = |d: &Document, id| Renderer::new().render_thumbnail(d, id, 64).map(|r| r.pixels);
assert_eq!(thumbnail(&composite, id), thumbnail(&plain, plain_id), "thumbnail");
let placed = |d: &Document| crate::placed_document::render_inside(&mut Renderer::new(), d, &d.layers[0], 300, 150, view).map(|r| r.pixels);
assert_eq!(placed(&composite), placed(&plain), "a placed document's art");
assert!(db.composite_font(NAME).is_none(), "given back after each render");
}
/// Type at 80% opacity, in Multiply and with a drop shadow redraws in a font that becomes
/// available: the glyph geometry kept for it is laid out again.
#[test]