mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-07 13:23:22 +00:00
Rasterize: Color Model is a dropdown of the document's model, Grayscale and Bitmap (#5660)
This commit is contained in:
@@ -21,7 +21,9 @@ pub(super) const SPEC: DialogSpec = DialogSpec {
|
||||
// Area Type Options: a Row Gutter still as it opened, on rows without a gutter of their own,
|
||||
// follows the Gutter as it is changed.
|
||||
let linked = d.fields.get("__rowGutterLinked").is_some() && d.fields.get("__rowGutterLinked") == d.fields.get("rowGutter");
|
||||
form::param_fields(ui, d, &|k| lengths.contains(&k), &|k| choices(&command, k), &rank, app.session.general_unit());
|
||||
let cmyk = app.session.active().is_some_and(|s| s.doc.color_mode == vectorcraft_doc::ColorMode::Cmyk);
|
||||
let choices = |k: &str| rasterize_color_models(&command, k, cmyk).or_else(|| choices(&command, k));
|
||||
form::param_fields(ui, d, &|k| lengths.contains(&k), &choices, &rank, app.session.general_unit());
|
||||
if linked
|
||||
&& d.fields.get("rowGutter") == d.fields.get("__rowGutterLinked")
|
||||
&& let Some(g) = d.fields.get("gutter").cloned()
|
||||
@@ -138,6 +140,19 @@ fn choices(command: &str, key: &str) -> Option<form::Choices> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Object › Rasterize › Color Model: the values `object.rasterize` takes, the document's own
|
||||
/// colour model first (#5660).
|
||||
fn rasterize_color_models(command: &str, key: &str, cmyk: bool) -> Option<form::Choices> {
|
||||
match (command, key) {
|
||||
("object.rasterize", "colorModel") => Some(if cmyk { RASTERIZE_CMYK } else { RASTERIZE_RGB }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Object › Rasterize › Color Model in an RGB and in a CMYK document.
|
||||
const RASTERIZE_RGB: form::Choices = &[("RGB", "rgb"), ("Grayscale", "grayscale"), ("Bitmap", "bitmap")];
|
||||
const RASTERIZE_CMYK: form::Choices = &[("CMYK", "cmyk"), ("Grayscale", "grayscale"), ("Bitmap", "bitmap")];
|
||||
|
||||
/// Type on a Path Options › Align to Path.
|
||||
const PATH_ALIGN: form::Choices = &[("Ascender", "ascender"), ("Descender", "descender"), ("Center", "center"), ("Baseline", "baseline")];
|
||||
|
||||
@@ -287,6 +302,61 @@ mod tests {
|
||||
assert_eq!(t.area.flow, vectorcraft_doc::TextFlow::Rows);
|
||||
}
|
||||
|
||||
/// Object › Rasterize › Color Model is a dropdown of the models `object.rasterize` takes, the
|
||||
/// document's own first (#5660): every value runs, and picking Grayscale rasterizes in grays.
|
||||
#[test]
|
||||
fn rasterize_color_model_is_a_dropdown_of_the_models_the_command_takes() {
|
||||
use egui::accesskit::Role;
|
||||
use egui_kittest::kittest::Queryable;
|
||||
for (mode, own) in [("rgb", "RGB"), ("cmyk", "CMYK")] {
|
||||
let models = rasterize_color_models("object.rasterize", "colorModel", mode == "cmyk").unwrap();
|
||||
assert_eq!(models.first(), Some(&(own, mode)), "the document's own model first");
|
||||
for (_, value) in models {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"width": 100, "height": 100, "colorMode": mode})).unwrap();
|
||||
s.execute("shape.rectangle", &json!({"x": 10, "y": 10, "width": 20, "height": 20})).unwrap();
|
||||
s.execute("object.rasterize", &json!({"ppi": 72, "colorModel": value})).unwrap_or_else(|e| panic!("{mode} {value}: {e}"));
|
||||
}
|
||||
}
|
||||
assert!(rasterize_color_models("object.rasterize", "background", false).is_none());
|
||||
assert!(rasterize_color_models("document.rasterEffectsSettings", "colorModel", false).is_none());
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 200, "height": 200})).unwrap();
|
||||
let id = app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 20, "height": 20})).unwrap()["id"].as_u64().unwrap();
|
||||
app.run("paint.setFill", json!({"color": "#ff0000", "ids": [id]})).unwrap();
|
||||
app.run("select.set", json!({"ids": [id]})).unwrap();
|
||||
crate::menus::invoke(&mut app, "object.rasterize", json!({}));
|
||||
assert_eq!(app.ui.dialog.as_ref().unwrap().str("colorModel"), "rgb");
|
||||
let mut fonts = false;
|
||||
let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1100.0, 900.0)).build_ui_state(
|
||||
move |ui, app: &mut VectorcraftApp| {
|
||||
if !std::mem::replace(&mut fonts, true) {
|
||||
crate::theme::install_fonts(ui.ctx());
|
||||
return;
|
||||
}
|
||||
crate::dialogs::show(app, ui.ctx());
|
||||
},
|
||||
app,
|
||||
);
|
||||
h.run_steps(5);
|
||||
assert!(h.query_by_role_and_label(Role::TextInput, "Color Model:").is_none(), "not a text field");
|
||||
h.get_by_role_and_label(Role::ComboBox, "Color Model:").click();
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Grayscale").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().ui.dialog.as_ref().unwrap().str("colorModel"), "grayscale");
|
||||
let app = h.state_mut();
|
||||
crate::dialogs::confirm(app).unwrap();
|
||||
let st = app.session.active().unwrap();
|
||||
let key = st.selection.objects.iter().find_map(|id| match st.doc.node(*id).map(|n| &n.kind) {
|
||||
Some(NodeKind::Image(i)) => Some(i.key.clone()),
|
||||
_ => None,
|
||||
});
|
||||
let img = image::load_from_memory(&st.doc.images[&key.expect("the rectangle became an image")].bytes).unwrap().to_rgba8();
|
||||
let p = img.get_pixel(img.width() / 2, img.height() / 2).0;
|
||||
assert!(p[0] == p[1] && p[1] == p[2] && p[0] < 128, "red in grayscale: {p:?}");
|
||||
}
|
||||
|
||||
/// Graph Type › Value Axis is a dropdown of the values `graph.setType` takes, and OK puts the
|
||||
/// value axis on the side picked.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user