mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 23:05:05 +00:00
Merge remote-tracking branch 'origin/main' into feat/width-smooth-profile
# Conflicts: # docs/target-app-parity.md
This commit is contained in:
@@ -138,6 +138,78 @@ 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");
|
||||
// A page that places the document, drawn exactly (no bitmap of the placed art).
|
||||
let page = |d: &Document, id: NodeId, key: &str| {
|
||||
use vectorcraft_doc::{ImageBlob, LinkInfo, PlacedDocument};
|
||||
let blob = ImageBlob::new("application/json", key.as_bytes().to_vec());
|
||||
let p = PlacedDocument {
|
||||
link: LinkInfo::new("/art/type.vectorcraft"),
|
||||
key: key.into(),
|
||||
bounding: false,
|
||||
page_box: Default::default(),
|
||||
width: 300.0,
|
||||
height: 150.0,
|
||||
xf: Affine::IDENTITY,
|
||||
placement: Default::default(),
|
||||
};
|
||||
let art = d.node(id).unwrap().clone();
|
||||
vectorcraft_doc::placed_document::prime(&p, blob.bytes.clone(), (d.clone(), art, Rect::new(0.0, 0.0, 300.0, 150.0)));
|
||||
let mut page = Document::new(300.0, 150.0);
|
||||
page.images.insert(key.into(), blob);
|
||||
let n = Node::new(page.alloc_id(), NodeKind::PlacedDocument(Box::new(p)));
|
||||
let l = page.layers[0].id;
|
||||
page.insert(Some(l), 0, n).unwrap();
|
||||
Renderer::new().render(&page, 300, 150, view, &opts).pixels
|
||||
};
|
||||
assert_eq!(
|
||||
page(&composite, id, "fontchange-composite-placed"),
|
||||
page(&plain, plain_id, "fontchange-plain-placed"),
|
||||
"a placed document's art drawn exactly"
|
||||
);
|
||||
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]
|
||||
|
||||
@@ -1824,6 +1824,44 @@ fn pattern_and_symbol_art_with_plugin_effects_follow_the_plugins_installed() {
|
||||
plugin_change_draws_as_new(with_art(d, vec![group]), ID, Some(triangle(82.0, 32.0, 10.0)), Some(triangle(82.0, 32.0, 30.0)));
|
||||
}
|
||||
|
||||
/// A document draws plug-in effects ([`draws_plugin_effects`]) when an object in its layers, in a
|
||||
/// symbol's or a pattern's art, or in a brush's art has a visible plug-in effect, and not when its
|
||||
/// objects have no effect, another effect or a hidden plug-in effect.
|
||||
#[test]
|
||||
fn a_document_draws_plugin_effects_where_any_of_its_art_has_one() {
|
||||
use vectorcraft_brush::{ArtBrush, Brush, BrushKind};
|
||||
use vectorcraft_geom::shapes::rectangle;
|
||||
let plugin = || effect("plugin.test.render.draws", serde_json::json!({}));
|
||||
let square = |d: &mut Document, effects: Vec<vectorcraft_doc::Effect>| {
|
||||
filled(d, rectangle(Rect::new(0.0, 0.0, 10.0, 10.0)), Paint::solid(Color::BLACK), effects)
|
||||
};
|
||||
let mut cases: Vec<(&str, Document, bool)> = vec![];
|
||||
for (name, effects, draws) in [
|
||||
("no effect", vec![], false),
|
||||
("another effect", vec![drop_shadow()], false),
|
||||
("hidden plug-in effect", vec![vectorcraft_doc::Effect { visible: false, ..plugin() }], false),
|
||||
("plug-in effect", vec![plugin()], true),
|
||||
] {
|
||||
let mut d = Document::new(200.0, 100.0);
|
||||
let n = square(&mut d, effects);
|
||||
cases.push((name, with_art(d, vec![n]), draws));
|
||||
}
|
||||
let mut d = Document::new(200.0, 100.0);
|
||||
let art = square(&mut d, vec![plugin()]);
|
||||
d.symbols.push(vectorcraft_doc::Symbol { dynamic: false, name: "Shaped".into(), art: Arc::new(art) });
|
||||
cases.push(("symbol art", d, true));
|
||||
let mut d = Document::new(200.0, 100.0);
|
||||
let art = square(&mut d, vec![plugin()]);
|
||||
d.patterns.push(vectorcraft_doc::pattern::PatternDef::new("Shaped", vec![Arc::new(art)]));
|
||||
cases.push(("pattern art", d, true));
|
||||
let mut d = Document::new(200.0, 100.0);
|
||||
let art = square(&mut d, vec![plugin()]);
|
||||
vectorcraft_brush::store(&mut d, &[Brush { name: "Shaped".into(), kind: BrushKind::Art(ArtBrush { art, ..Default::default() }) }]);
|
||||
cases.push(("brush art", d, true));
|
||||
let wrong: Vec<&str> = cases.iter().filter(|(_, d, draws)| draws_plugin_effects(d) != *draws).map(|(name, ..)| *name).collect();
|
||||
assert!(wrong.is_empty(), "{wrong:?}");
|
||||
}
|
||||
|
||||
fn effect(id: &str, params: serde_json::Value) -> vectorcraft_doc::Effect {
|
||||
vectorcraft_doc::Effect { id: id.into(), params, visible: true }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user