mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-27 19:27:21 -06:00
Type: emoji go with type that effects reshape and Expand Appearance
Squashed from #3879 onto main.
This commit is contained in:
@@ -421,8 +421,15 @@ fn import_image(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let img = fileio::raster_image(&data_param(p, C)?).map_err(|e| bad(C, e.to_string()))?;
|
||||
let (sx, sy) = pt_per_px(img.ppi);
|
||||
let (w, h) = (img.width, img.height);
|
||||
let image =
|
||||
ImageObject { key: img.key.clone(), width: w, height: h, xf: Affine::scale_non_uniform(sx, sy), link: None, placement: Default::default() };
|
||||
let image = ImageObject {
|
||||
key: img.key.clone(),
|
||||
width: w,
|
||||
height: h,
|
||||
xf: Affine::scale_non_uniform(sx, sy),
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
};
|
||||
let mut clip = Clipboard { nodes: vec![Node::new(NodeId(1), NodeKind::Image(Box::new(image)))], ..Default::default() };
|
||||
clip.images.insert(img.key, img.blob);
|
||||
let count = s.load_clipboard(clip, p)?;
|
||||
|
||||
@@ -558,10 +558,12 @@ pub(crate) fn expand_node(d: &mut Document, id: NodeId, brushes: &[vectorcraft_b
|
||||
let mut listed = vec![];
|
||||
let m = expanded_node(d, n, brushes, &mut listed);
|
||||
out.extend(listed.into_iter().map(|(id, _)| id));
|
||||
if let Some(m) = m
|
||||
&& let Some(slot) = d.node_mut(id)
|
||||
{
|
||||
*slot = m;
|
||||
if let Some(mut m) = m {
|
||||
// Art made from type takes its emoji's pixels into the document.
|
||||
d.adopt_pixels(&mut m);
|
||||
if let Some(slot) = d.node_mut(id) {
|
||||
*slot = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1274,7 +1274,15 @@ impl Builder {
|
||||
let sy = img.height as f64 / f64::from(r.height.max(1));
|
||||
let xf = to_doc * affine(img.transform) * Affine::scale_non_uniform(sx, sy);
|
||||
self.doc.images.entry(r.key.clone()).or_insert(r.blob);
|
||||
Some(NodeKind::Image(Box::new(ImageObject { key: r.key, width: r.width, height: r.height, xf, link: None, placement: Default::default() })))
|
||||
Some(NodeKind::Image(Box::new(ImageObject {
|
||||
key: r.key,
|
||||
width: r.width,
|
||||
height: r.height,
|
||||
xf,
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,8 @@ fn flatten_images(d: &mut Document, images: &[(usize, NodeId)]) -> Result<()> {
|
||||
let png = flat.png;
|
||||
let key = super::super::menucmds::unique_key(d, "flattened");
|
||||
d.images.insert(key.clone(), ImageBlob::new("image/png", png));
|
||||
let image = ImageObject { key, width: flat.width, height: flat.height, xf: flat.xf, link: None, placement: Default::default() };
|
||||
let image =
|
||||
ImageObject { key, width: flat.width, height: flat.height, xf: flat.xf, link: None, placement: Default::default(), pixels: None };
|
||||
let image = Node::new(d.alloc_id(), NodeKind::Image(Box::new(image)));
|
||||
let mut group = super::super::rasterfx::clip_group(d, flat.clip, FillRule::NonZero, image);
|
||||
group.name = src.node(id).and_then(|n| n.name.clone());
|
||||
|
||||
@@ -658,8 +658,10 @@ pub(super) fn raster_doc(name: &str, bytes: &[u8]) -> Result<Document> {
|
||||
let layer = d.layers[0].id;
|
||||
let id = d.alloc_id();
|
||||
let xf = Affine::scale_non_uniform(sx, sy);
|
||||
let mut n =
|
||||
Node::new(id, NodeKind::Image(Box::new(ImageObject { key: key.clone(), width, height, xf, link: None, placement: Default::default() })));
|
||||
let mut n = Node::new(
|
||||
id,
|
||||
NodeKind::Image(Box::new(ImageObject { key: key.clone(), width, height, xf, link: None, placement: Default::default(), pixels: None })),
|
||||
);
|
||||
n.name = Some(name.to_string());
|
||||
d.images.insert(key, blob);
|
||||
d.insert(Some(layer), 0, n).map_err(err)?;
|
||||
|
||||
@@ -248,6 +248,7 @@ fn a_raster_export_says_nothing_of_images_another_thread_could_not_decode() {
|
||||
xf: vectorcraft_geom::Affine::scale(20.0),
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
};
|
||||
let (id, layer) = (broken.alloc_id(), broken.layers[0].id);
|
||||
broken.insert(Some(layer), 0, Node::new(id, NodeKind::Image(Box::new(im)))).unwrap();
|
||||
|
||||
@@ -1136,7 +1136,15 @@ fn raster_node(d: &mut Document, r: Raster) -> Node {
|
||||
d.images.insert(key.clone(), r.blob);
|
||||
let image = Node::new(
|
||||
d.alloc_id(),
|
||||
NodeKind::Image(Box::new(ImageObject { key, width: r.width, height: r.height, xf: r.xf, link: None, placement: Default::default() })),
|
||||
NodeKind::Image(Box::new(ImageObject {
|
||||
key,
|
||||
width: r.width,
|
||||
height: r.height,
|
||||
xf: r.xf,
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
})),
|
||||
);
|
||||
let Some(path) = r.clip else { return image };
|
||||
super::rasterfx::clip_group(d, path, FillRule::NonZero, image)
|
||||
|
||||
@@ -1334,6 +1334,8 @@ fn expand_envelope(d: &mut Document, id: NodeId) -> Result<()> {
|
||||
let n = d.node(id).cloned().ok_or(EngineError::NoNode(id))?;
|
||||
let mut g = vectorcraft_render::effects::expanded_live_group(Some(d), &n);
|
||||
fix_ids(d, &mut g);
|
||||
// Outlined type's emoji take their pixels into the document.
|
||||
d.adopt_pixels(&mut g);
|
||||
// Outlined type repeats its object's id on its pieces.
|
||||
vectorcraft_render::effects::fresh_ids(d, &mut g, &mut Default::default());
|
||||
*d.node_mut(id).ok_or(EngineError::NoNode(id))? = g;
|
||||
|
||||
@@ -469,7 +469,7 @@ impl Rasterized {
|
||||
let key = unique_key(d, "raster");
|
||||
d.images.insert(key.clone(), vectorcraft_doc::ImageBlob::new("image/png", self.png));
|
||||
let id = d.alloc_id();
|
||||
let image = ImageObject { key, width: self.width, height: self.height, xf: self.xf, link: None, placement: Default::default() };
|
||||
let image = ImageObject { key, width: self.width, height: self.height, xf: self.xf, link: None, placement: Default::default(), pixels: None };
|
||||
let node = Node::new(id, NodeKind::Image(Box::new(image)));
|
||||
match self.clip {
|
||||
Some((path, rule)) => super::rasterfx::clip_group(d, path, rule, node),
|
||||
@@ -721,6 +721,7 @@ fn crop_image(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
xf: Affine::translate(region.origin().to_vec2()) * Affine::scale(1.0 / scale),
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
@@ -788,6 +789,7 @@ fn trim_image(s: &mut Session, id: NodeId, im: ImageObject) -> Result<Value> {
|
||||
xf: im.xf * Affine::translate((f64::from(x0), f64::from(y0))),
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -385,6 +385,7 @@ fn build(d: &mut Document, l: Loaded, link: Option<LinkInfo>) -> Node {
|
||||
xf: Affine::scale_non_uniform(sx, sy),
|
||||
link,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
};
|
||||
Node::new(d.alloc_id(), NodeKind::Image(Box::new(im)))
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ fn bitmap_document(cmd: &str, doc: &Document, set: &PrintSettings, rich_black: b
|
||||
let key = unique_key(&out, "print-bitmap");
|
||||
out.images.insert(key.clone(), ImageBlob::new("image/png", img.to_png().map_err(EngineError::Other)?));
|
||||
let xf = Affine::translate(region.origin().to_vec2()) * Affine::scale(1.0 / scale);
|
||||
let image = ImageObject { key, width: img.width, height: img.height, xf, link: None, placement: Default::default() };
|
||||
let image = ImageObject { key, width: img.width, height: img.height, xf, link: None, placement: Default::default(), pixels: None };
|
||||
images.push(Arc::new(Node::new(out.alloc_id(), NodeKind::Image(Box::new(image)))));
|
||||
}
|
||||
let mut layer = Node::layer(out.alloc_id(), "Bitmap", LayerColor::Preset(0));
|
||||
|
||||
@@ -225,7 +225,15 @@ pub(crate) fn effect_image(out: &mut Document, whole: &Node, knockout: Option<&N
|
||||
let xf = Affine::translate(region.origin().to_vec2()) * Affine::scale(1.0 / scale);
|
||||
let mut image = Node::new(
|
||||
id,
|
||||
NodeKind::Image(Box::new(ImageObject { key, width: img.width, height: img.height, xf, link: None, placement: Default::default() })),
|
||||
NodeKind::Image(Box::new(ImageObject {
|
||||
key,
|
||||
width: img.width,
|
||||
height: img.height,
|
||||
xf,
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
})),
|
||||
);
|
||||
image.name = Some("Raster effect".into());
|
||||
Some(image)
|
||||
|
||||
@@ -92,6 +92,7 @@ mod tests {
|
||||
xf: Affine::scale(72.0 / ppi),
|
||||
link: None,
|
||||
placement: Default::default(),
|
||||
pixels: None,
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_doc::{AreaFit, Document, ImageObject, Justify, Node, NodeId, NodeKind, RubyAlign, RubyPosition, RubySpan, TextObject};
|
||||
use vectorcraft_doc::{AreaFit, Document, Justify, Node, NodeId, NodeKind, RubyAlign, RubyPosition, RubySpan, TextObject};
|
||||
use vectorcraft_geom::{Affine, PathData, Vec2};
|
||||
|
||||
use super::edit::selected_roots;
|
||||
@@ -559,18 +559,10 @@ fn create_outlines(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
children.push(Arc::new(Node::new(id, NodeKind::SymbolInstance { symbol: art.symbol.clone(), xf })));
|
||||
continue;
|
||||
}
|
||||
// Colour bitmap glyphs (emoji) become embedded images, in place; glyphs that show
|
||||
// the same image share its pixels, under a key of their own if another image has
|
||||
// taken theirs.
|
||||
if let Some((image, to_text)) = g.placed_image() {
|
||||
let mut key = format!("glyph-{}", image.blob.content_key());
|
||||
if d.images.get(&key).is_some_and(|b| b.bytes != image.blob.bytes) {
|
||||
key = super::menucmds::unique_key(d, "glyph");
|
||||
}
|
||||
d.images.entry(key.clone()).or_insert_with(|| image.blob.clone());
|
||||
let im =
|
||||
ImageObject { key, width: image.width, height: image.height, xf: t.xf * to_text, link: None, placement: Default::default() };
|
||||
children.push(Arc::new(Node::new(d.alloc_id(), NodeKind::Image(Box::new(im)))));
|
||||
// Colour bitmap glyphs (emoji) become embedded images, in place, their pixels taken
|
||||
// into the document: glyphs that show the same image share them.
|
||||
if let Some(image) = g.placed_image_node(t.xf) {
|
||||
children.push(Arc::new(d.reid(&image)));
|
||||
continue;
|
||||
}
|
||||
// COLR glyphs become groups of their layers, in place, with ids of the document's.
|
||||
|
||||
Reference in New Issue
Block a user