mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-02 16:30:36 -06:00
Rename SlideCraft to DeckCraft: crates, apps, binaries, app id, file extension (.deckcraft; .slidecraft files still open), packaging, docs; ROADMAP alpha and parity estimates
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
49278565ea
commit
ae9d525bce
+13
-13
@@ -1,12 +1,12 @@
|
||||
//! Charts: title, plot area with axes and gridlines, series marks, legend.
|
||||
|
||||
use deckcraft_color::{ColorTransform, Rgba, SchemeSlot};
|
||||
use deckcraft_model::Shape;
|
||||
use deckcraft_model::chart::{Chart, ChartType, nice_scale};
|
||||
use deckcraft_model::resolve::Ctx;
|
||||
use deckcraft_model::style::{ColorRef, Fill};
|
||||
use deckcraft_model::text::{Align, Anchor, Bullet, TextBody};
|
||||
use kurbo::{Affine, BezPath, Point, Rect, Shape as _};
|
||||
use slidecraft_color::{ColorTransform, Rgba, SchemeSlot};
|
||||
use slidecraft_model::Shape;
|
||||
use slidecraft_model::chart::{Chart, ChartType, nice_scale};
|
||||
use slidecraft_model::resolve::Ctx;
|
||||
use slidecraft_model::style::{ColorRef, Fill};
|
||||
use slidecraft_model::text::{Align, Anchor, Bullet, TextBody};
|
||||
use vello_cpu::RenderContext;
|
||||
|
||||
use crate::color;
|
||||
@@ -23,13 +23,13 @@ pub fn series_color(ctx: &Ctx, c: &Chart, i: usize) -> Rgba {
|
||||
let round = if mono { i } else { i / 6 };
|
||||
match round {
|
||||
0 => base,
|
||||
1 => slidecraft_color::apply(base, &[ColorTransform::Shade(60000)]),
|
||||
2 => slidecraft_color::apply(base, &[ColorTransform::Tint(60000)]),
|
||||
n => slidecraft_color::apply(base, &[ColorTransform::LumMod(100000 - (n as i32 % 5) * 12000)]),
|
||||
1 => deckcraft_color::apply(base, &[ColorTransform::Shade(60000)]),
|
||||
2 => deckcraft_color::apply(base, &[ColorTransform::Tint(60000)]),
|
||||
n => deckcraft_color::apply(base, &[ColorTransform::LumMod(100000 - (n as i32 % 5) * 12000)]),
|
||||
}
|
||||
}
|
||||
|
||||
fn series_fill(ctx: &Ctx, c: &Chart, i: usize, s: Option<&slidecraft_model::chart::Series>) -> Rgba {
|
||||
fn series_fill(ctx: &Ctx, c: &Chart, i: usize, s: Option<&deckcraft_model::chart::Series>) -> Rgba {
|
||||
match s.and_then(|s| s.fill.as_ref()) {
|
||||
Some(Fill::Solid { color: cc }) => ctx.color(cc, None),
|
||||
_ => series_color(ctx, c, i),
|
||||
@@ -56,7 +56,7 @@ fn label(ctx: &mut RenderContext, rctx: &Ctx, m: Affine, text: &str, r: Rect, si
|
||||
}
|
||||
}
|
||||
let tmp = Shape { text: Some(body.clone()), ..Default::default() };
|
||||
crate::draw_text(ctx, rctx, &tmp, &body, r, m, &slidecraft_text::NoFields, None);
|
||||
crate::draw_text(ctx, rctx, &tmp, &body, r, m, &deckcraft_text::NoFields, None);
|
||||
}
|
||||
|
||||
fn fmt_num(v: f64) -> String {
|
||||
@@ -75,7 +75,7 @@ pub fn draw(ctx: &mut RenderContext, rctx: &Ctx, c: &Chart, m: Affine, w: f64, h
|
||||
&Rect::new(0.0, 0.0, w, h).to_path(0.1),
|
||||
Rect::new(0.0, 0.0, w, h),
|
||||
m,
|
||||
slidecraft_geom::preset::FillMode::Norm,
|
||||
deckcraft_geom::preset::FillMode::Norm,
|
||||
1.0,
|
||||
rctx.pres,
|
||||
);
|
||||
@@ -173,7 +173,7 @@ pub fn draw(ctx: &mut RenderContext, rctx: &Ctx, c: &Chart, m: Affine, w: f64, h
|
||||
Rect::new(area.x0 + gutter, area.y0, area.x1, area.y1 - base * 1.8)
|
||||
};
|
||||
if let Some(f) = &c.plot_fill {
|
||||
crate::paint::fill_path(ctx, rctx, f, None, &plot.to_path(0.1), plot, m, slidecraft_geom::preset::FillMode::Norm, 1.0, rctx.pres);
|
||||
crate::paint::fill_path(ctx, rctx, f, None, &plot.to_path(0.1), plot, m, deckcraft_geom::preset::FillMode::Norm, 1.0, rctx.pres);
|
||||
}
|
||||
let span = (max - min).max(1e-9);
|
||||
let to_v = |v: f64| if horiz { plot.x0 + (v - min) / span * plot.width() } else { plot.y1 - (v - min) / span * plot.height() };
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use slidecraft_model::style::PictureAdjust;
|
||||
use deckcraft_model::style::PictureAdjust;
|
||||
use vello_cpu::Pixmap;
|
||||
|
||||
const BUDGET: usize = 512 << 20;
|
||||
|
||||
+28
-28
@@ -1,4 +1,4 @@
|
||||
//! The SlideCraft renderer: draws slides, layouts and masters with `vello_cpu`.
|
||||
//! The DeckCraft renderer: draws slides, layouts and masters with `vello_cpu`.
|
||||
//!
|
||||
//! One code path serves the editor canvas, thumbnails, image/PDF-raster export and the slide show:
|
||||
//! [`render_slide`] draws the background, the master and layout graphics, then the slide's shapes
|
||||
@@ -16,15 +16,15 @@ mod table;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deckcraft_color::Rgba;
|
||||
use deckcraft_fonts::FontDb;
|
||||
use deckcraft_geom::preset::{self, FillMode, Geometry, SubPath};
|
||||
use deckcraft_model::resolve::{self, Ctx};
|
||||
use deckcraft_model::style::{Effects, Fill, Line};
|
||||
use deckcraft_model::text::TextBody;
|
||||
use deckcraft_model::{Geom, PhType, Presentation, Shape, ShapeId, ShapeKind, Slide};
|
||||
use deckcraft_text::{Fields, Opts};
|
||||
use kurbo::{Affine, BezPath, PathEl, Point, Rect, Shape as _, Vec2};
|
||||
use slidecraft_color::Rgba;
|
||||
use slidecraft_fonts::FontDb;
|
||||
use slidecraft_geom::preset::{self, FillMode, Geometry, SubPath};
|
||||
use slidecraft_model::resolve::{self, Ctx};
|
||||
use slidecraft_model::style::{Effects, Fill, Line};
|
||||
use slidecraft_model::text::TextBody;
|
||||
use slidecraft_model::{Geom, PhType, Presentation, Shape, ShapeId, ShapeKind, Slide};
|
||||
use slidecraft_text::{Fields, Opts};
|
||||
use vello_common::filter_effects::{EdgeMode, Filter, FilterPrimitive};
|
||||
use vello_cpu::{RenderContext, Resources, peniko};
|
||||
|
||||
@@ -208,7 +208,7 @@ pub fn needs_filters(pres: &Presentation, slide: &Slide) -> bool {
|
||||
let Some(rctx) = Ctx::for_slide(pres, slide) else { return false };
|
||||
let mut any = false;
|
||||
let mut check = |shapes: &[Shape]| {
|
||||
slidecraft_model::walk(shapes, &mut |s, _| {
|
||||
deckcraft_model::walk(shapes, &mut |s, _| {
|
||||
if any {
|
||||
return;
|
||||
}
|
||||
@@ -498,7 +498,7 @@ impl Renderer {
|
||||
match &s.kind {
|
||||
ShapeKind::Group { children, child } => {
|
||||
let ch = Rect::new(child.x, child.y, child.x + child.w, child.y + child.h);
|
||||
let gm = parent * slidecraft_geom::group_child_affine(&x, ch);
|
||||
let gm = parent * deckcraft_geom::group_child_affine(&x, ch);
|
||||
for c in children {
|
||||
self.shape(ctx, f, rctx, c, gm, depth + 1);
|
||||
}
|
||||
@@ -537,7 +537,7 @@ impl Renderer {
|
||||
let outline = geo.outline();
|
||||
// Placeholders in the editor: dashed outline and prompt, nothing else when empty.
|
||||
let empty_ph = s.ph.is_some() && s.text.as_ref().is_none_or(TextBody::is_empty) && !is_pic && !matches!(s.kind, ShapeKind::Media(_));
|
||||
let fill = if let Some(t) = st.tint { Some(Fill::solid(slidecraft_model::ColorRef::rgb(t))) } else { fill };
|
||||
let fill = if let Some(t) = st.tint { Some(Fill::solid(deckcraft_model::ColorRef::rgb(t))) } else { fill };
|
||||
// Effects below the shape.
|
||||
if let Some(e) = &effects {
|
||||
self.effects_below(ctx, rctx, e, fx_ph, &geo, &fill, m, w, h);
|
||||
@@ -561,7 +561,7 @@ impl Renderer {
|
||||
ctx.set_transform(m);
|
||||
let bounds = Rect::new(0.0, 0.0, w, h);
|
||||
if let Some(p) = mc.poster {
|
||||
let pf = slidecraft_model::style::PictureFill { media: p, ..Default::default() };
|
||||
let pf = deckcraft_model::style::PictureFill { media: p, ..Default::default() };
|
||||
paint::picture(ctx, f.pres, &pf, bounds, m);
|
||||
} else if mc.video {
|
||||
ctx.set_paint(peniko::Color::from_rgba8(20, 20, 24, 255));
|
||||
@@ -640,7 +640,7 @@ impl Renderer {
|
||||
{
|
||||
let tr = geo.text_rect;
|
||||
if !body.is_empty() {
|
||||
let l = slidecraft_text::layout(rctx, s, body, &Opts { rect: tr, fields: &f.fields, prompt_color: None, no_shrink: false });
|
||||
let l = deckcraft_text::layout(rctx, s, body, &Opts { rect: tr, fields: &f.fields, prompt_color: None, no_shrink: false });
|
||||
draw_layout_with(ctx, &l, tr, m, &st.paras);
|
||||
} else if f.opts.edit && s.ph.is_some() {
|
||||
let kind = s.ph_type().unwrap_or(PhType::Body);
|
||||
@@ -747,7 +747,7 @@ fn blur(sigma: f64) -> Filter {
|
||||
}
|
||||
|
||||
fn stroke(ctx: &mut RenderContext, rctx: &Ctx, line: &Line, ph: Option<Rgba>, path: &BezPath, m: Affine, lw: f64) {
|
||||
use slidecraft_model::style::{LineCap, LineJoin};
|
||||
use deckcraft_model::style::{LineCap, LineJoin};
|
||||
let cap = match line.cap.unwrap_or_default() {
|
||||
LineCap::Flat => kurbo::Cap::Butt,
|
||||
LineCap::Round => kurbo::Cap::Round,
|
||||
@@ -896,10 +896,10 @@ fn prompt_body(rctx: &Ctx, s: &Shape, kind: PhType) -> TextBody {
|
||||
}
|
||||
let mut t = TextBody::from_text(txt);
|
||||
if matches!(kind, PhType::Picture | PhType::Chart | PhType::Table | PhType::Media | PhType::Diagram | PhType::ClipArt) {
|
||||
t.body.anchor = Some(slidecraft_model::text::Anchor::Bottom);
|
||||
t.body.anchor = Some(deckcraft_model::text::Anchor::Bottom);
|
||||
if let Some(p) = t.paragraphs.first_mut() {
|
||||
p.props.align = Some(slidecraft_model::text::Align::Center);
|
||||
p.props.bullet = Some(slidecraft_model::text::Bullet::None);
|
||||
p.props.align = Some(deckcraft_model::text::Align::Center);
|
||||
p.props.bullet = Some(deckcraft_model::text::Bullet::None);
|
||||
p.props.margin_left = Some(0.0);
|
||||
p.props.indent = Some(0.0);
|
||||
for r in &mut p.runs {
|
||||
@@ -914,7 +914,7 @@ thread_local! {
|
||||
static GLYPH_CACHE: std::cell::RefCell<HashMap<(u32, u32), Arc<BezPath>>> = std::cell::RefCell::new(HashMap::new());
|
||||
}
|
||||
|
||||
fn glyph(face: &slidecraft_fonts::FontFace, gid: u32) -> Arc<BezPath> {
|
||||
fn glyph(face: &deckcraft_fonts::FontFace, gid: u32) -> Arc<BezPath> {
|
||||
let key = (face.id(), gid);
|
||||
if let Some(p) = GLYPH_CACHE.with(|c| c.borrow().get(&key).cloned()) {
|
||||
return p;
|
||||
@@ -932,17 +932,17 @@ fn glyph(face: &slidecraft_fonts::FontFace, gid: u32) -> Arc<BezPath> {
|
||||
|
||||
/// Draw a text body into shape space `m` within the text rect.
|
||||
pub fn draw_text(ctx: &mut RenderContext, rctx: &Ctx, s: &Shape, body: &TextBody, tr: Rect, m: Affine, fields: &dyn Fields, prompt: Option<Rgba>) {
|
||||
let l = slidecraft_text::layout(rctx, s, body, &Opts { rect: tr, fields, prompt_color: prompt, no_shrink: false });
|
||||
let l = deckcraft_text::layout(rctx, s, body, &Opts { rect: tr, fields, prompt_color: prompt, no_shrink: false });
|
||||
draw_layout(ctx, &l, tr, m);
|
||||
}
|
||||
|
||||
/// Draw an already laid-out text block.
|
||||
pub fn draw_layout(ctx: &mut RenderContext, l: &slidecraft_text::TextLayout, tr: Rect, m: Affine) {
|
||||
pub fn draw_layout(ctx: &mut RenderContext, l: &deckcraft_text::TextLayout, tr: Rect, m: Affine) {
|
||||
draw_layout_with(ctx, l, tr, m, &[]);
|
||||
}
|
||||
|
||||
/// Draw a laid-out text block with per-paragraph animation states.
|
||||
pub fn draw_layout_with(ctx: &mut RenderContext, l: &slidecraft_text::TextLayout, tr: Rect, m: Affine, paras: &[(usize, ParaState)]) {
|
||||
pub fn draw_layout_with(ctx: &mut RenderContext, l: &deckcraft_text::TextLayout, tr: Rect, m: Affine, paras: &[(usize, ParaState)]) {
|
||||
let para = |i: usize| paras.iter().find(|(p, _)| *p == i).map(|(_, s)| *s).unwrap_or_default();
|
||||
let m = if l.rotation != 0.0 {
|
||||
let c = tr.center().to_vec2();
|
||||
@@ -950,7 +950,7 @@ pub fn draw_layout_with(ctx: &mut RenderContext, l: &slidecraft_text::TextLayout
|
||||
} else {
|
||||
m
|
||||
};
|
||||
let deco = |ctx: &mut RenderContext, d: &slidecraft_text::Deco| {
|
||||
let deco = |ctx: &mut RenderContext, d: &deckcraft_text::Deco| {
|
||||
let ps = para(d.para);
|
||||
if !ps.visible || ps.opacity <= 0.001 {
|
||||
return;
|
||||
@@ -1031,15 +1031,15 @@ mod mt_tests {
|
||||
/// Regression: multithreaded rendering of a slide with shadows panicked inside vello_cpu.
|
||||
#[test]
|
||||
fn effects_render_with_threads_requested() {
|
||||
let mut s = slidecraft_model::Presentation::default();
|
||||
let mut s = deckcraft_model::Presentation::default();
|
||||
let sl = std::sync::Arc::make_mut(&mut s.slides[0]);
|
||||
let mut sh = slidecraft_model::Shape {
|
||||
let mut sh = deckcraft_model::Shape {
|
||||
id: ShapeId(900),
|
||||
xfrm: Some(slidecraft_geom::Xfrm::new(10.0, 10.0, 100.0, 100.0)),
|
||||
style: Some(slidecraft_model::ShapeStyle::accent(slidecraft_color::SchemeSlot::Accent1)),
|
||||
xfrm: Some(deckcraft_geom::Xfrm::new(10.0, 10.0, 100.0, 100.0)),
|
||||
style: Some(deckcraft_model::ShapeStyle::accent(deckcraft_color::SchemeSlot::Accent1)),
|
||||
..Default::default()
|
||||
};
|
||||
sh.effects = Some(slidecraft_model::Effects { soft_edge: Some(5.0), ..Default::default() });
|
||||
sh.effects = Some(deckcraft_model::Effects { soft_edge: Some(5.0), ..Default::default() });
|
||||
sl.shapes.push(sh);
|
||||
assert!(needs_filters(&s, &s.slides[0]));
|
||||
let img = RENDERER.with(|r| r.borrow_mut().slide(&s, &s.slides[0], 0, &RenderOpts { scale: 0.5, threads: 4, ..Default::default() }));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! Fills: solid, gradient, picture and pattern paints.
|
||||
|
||||
use deckcraft_color::Rgba;
|
||||
use deckcraft_geom::preset::FillMode;
|
||||
use deckcraft_model::resolve::Ctx;
|
||||
use deckcraft_model::style::{Fill, GradientShape, PictureFill, PictureMode};
|
||||
use deckcraft_model::{PhType, Presentation};
|
||||
use kurbo::{Affine, BezPath, Point, Rect, Shape as _};
|
||||
use slidecraft_color::Rgba;
|
||||
use slidecraft_geom::preset::FillMode;
|
||||
use slidecraft_model::resolve::Ctx;
|
||||
use slidecraft_model::style::{Fill, GradientShape, PictureFill, PictureMode};
|
||||
use slidecraft_model::{PhType, Presentation};
|
||||
use vello_cpu::{RenderContext, peniko};
|
||||
|
||||
use crate::{color, images, shade};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! Laid-out text and click areas of a slide, in slide coordinates, without drawing — for exports
|
||||
//! that put real text over a raster (PDF text layer, links) and for text extraction.
|
||||
|
||||
use deckcraft_model::resolve::{self, Ctx};
|
||||
use deckcraft_model::text::{Hyperlink, TextBody};
|
||||
use deckcraft_model::{Presentation, Shape, ShapeKind};
|
||||
use deckcraft_text::{Opts, TextLayout};
|
||||
use kurbo::{Affine, Rect};
|
||||
use slidecraft_model::resolve::{self, Ctx};
|
||||
use slidecraft_model::text::{Hyperlink, TextBody};
|
||||
use slidecraft_model::{Presentation, Shape, ShapeKind};
|
||||
use slidecraft_text::{Opts, TextLayout};
|
||||
|
||||
use crate::{SlideFields, shape_geometry};
|
||||
|
||||
@@ -71,7 +71,7 @@ fn place(out: &mut Placed, rctx: &Ctx, fields: &SlideFields, s: &Shape, parent:
|
||||
match &s.kind {
|
||||
ShapeKind::Group { children, child } => {
|
||||
let ch = Rect::new(child.x, child.y, child.x + child.w, child.y + child.h);
|
||||
let gm = parent * slidecraft_geom::group_child_affine(&x, ch);
|
||||
let gm = parent * deckcraft_geom::group_child_affine(&x, ch);
|
||||
for c in children {
|
||||
place(out, rctx, fields, c, gm, depth + 1);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ fn place(out: &mut Placed, rctx: &Ctx, fields: &SlideFields, s: &Shape, parent:
|
||||
_ => {
|
||||
let Some(body) = s.text.as_ref().filter(|b| !b.is_empty()) else { return };
|
||||
let tr = shape_geometry(s, x.w, x.h).text_rect;
|
||||
let layout = slidecraft_text::layout(rctx, s, body, &Opts { rect: tr, fields, prompt_color: None, no_shrink: false });
|
||||
let layout = deckcraft_text::layout(rctx, s, body, &Opts { rect: tr, fields, prompt_color: None, no_shrink: false });
|
||||
let m = if layout.rotation != 0.0 {
|
||||
let c = tr.center().to_vec2();
|
||||
m * Affine::translate(c) * Affine::rotate(layout.rotation.to_radians()) * Affine::translate(-c)
|
||||
|
||||
+11
-11
@@ -1,12 +1,12 @@
|
||||
//! Tables: cell fills from the table style (or overrides), borders, and cell text.
|
||||
|
||||
use deckcraft_color::{ColorTransform, Rgba, SchemeSlot};
|
||||
use deckcraft_model::resolve::Ctx;
|
||||
use deckcraft_model::style::{ColorRef, Fill};
|
||||
use deckcraft_model::table::Table;
|
||||
use deckcraft_model::text::Anchor;
|
||||
use deckcraft_model::{Presentation, Shape};
|
||||
use kurbo::{Affine, BezPath, Rect, Shape as _};
|
||||
use slidecraft_color::{ColorTransform, Rgba, SchemeSlot};
|
||||
use slidecraft_model::resolve::Ctx;
|
||||
use slidecraft_model::style::{ColorRef, Fill};
|
||||
use slidecraft_model::table::Table;
|
||||
use slidecraft_model::text::Anchor;
|
||||
use slidecraft_model::{Presentation, Shape};
|
||||
use vello_cpu::{RenderContext, peniko};
|
||||
|
||||
use crate::color;
|
||||
@@ -42,7 +42,7 @@ pub fn look(ctx: &Ctx, t: &Table, r: usize, c: usize) -> CellLook {
|
||||
let body_r = if t.first_row { r.wrapping_sub(1) } else { r };
|
||||
let band = t.band_row && !header && !total && body_r % 2 == 0;
|
||||
let band_c = t.band_col && c.is_multiple_of(2);
|
||||
let tint = |k: i32| slidecraft_color::apply(a, &[ColorTransform::Tint(k)]);
|
||||
let tint = |k: i32| deckcraft_color::apply(a, &[ColorTransform::Tint(k)]);
|
||||
let white = Rgba::WHITE;
|
||||
let dark_text = ctx.color(&ColorRef::scheme(SchemeSlot::Tx1), None);
|
||||
match kind {
|
||||
@@ -64,9 +64,9 @@ pub fn look(ctx: &Ctx, t: &Table, r: usize, c: usize) -> CellLook {
|
||||
fill: Some(if header {
|
||||
Rgba::BLACK
|
||||
} else if band || band_c {
|
||||
slidecraft_color::apply(a, &[ColorTransform::Shade(60000)])
|
||||
deckcraft_color::apply(a, &[ColorTransform::Shade(60000)])
|
||||
} else {
|
||||
slidecraft_color::apply(a, &[ColorTransform::Shade(75000)])
|
||||
deckcraft_color::apply(a, &[ColorTransform::Shade(75000)])
|
||||
}),
|
||||
text: Some(white),
|
||||
bold: header || total || first_col,
|
||||
@@ -123,7 +123,7 @@ pub fn cell_rects(t: &Table) -> Vec<(usize, usize, Rect)> {
|
||||
out
|
||||
}
|
||||
|
||||
pub fn draw(ctx: &mut RenderContext, pres: &Presentation, rctx: &Ctx, t: &Table, m: Affine, _w: f64, _h: f64, fields: &dyn slidecraft_text::Fields) {
|
||||
pub fn draw(ctx: &mut RenderContext, pres: &Presentation, rctx: &Ctx, t: &Table, m: Affine, _w: f64, _h: f64, fields: &dyn deckcraft_text::Fields) {
|
||||
let _ = pres;
|
||||
let rects = cell_rects(t);
|
||||
for (r, c, rect) in &rects {
|
||||
@@ -132,7 +132,7 @@ pub fn draw(ctx: &mut RenderContext, pres: &Presentation, rctx: &Ctx, t: &Table,
|
||||
ctx.set_transform(m);
|
||||
match &cell.fill {
|
||||
Some(f) => {
|
||||
crate::paint::fill_path(ctx, rctx, f, None, &rect.to_path(0.1), *rect, m, slidecraft_geom::preset::FillMode::Norm, 1.0, rctx.pres)
|
||||
crate::paint::fill_path(ctx, rctx, f, None, &rect.to_path(0.1), *rect, m, deckcraft_geom::preset::FillMode::Norm, 1.0, rctx.pres)
|
||||
}
|
||||
None => {
|
||||
if let Some(fc) = lk.fill {
|
||||
|
||||
+13
-13
@@ -1,8 +1,8 @@
|
||||
use super::*;
|
||||
use slidecraft_model::chart::ChartType;
|
||||
use slidecraft_model::style::ColorRef;
|
||||
use slidecraft_model::text::TextBody;
|
||||
use slidecraft_model::{Chart, Geom, Presentation, Shape, ShapeId, ShapeKind, ShapeStyle, Table, Xfrm};
|
||||
use deckcraft_model::chart::ChartType;
|
||||
use deckcraft_model::style::ColorRef;
|
||||
use deckcraft_model::text::TextBody;
|
||||
use deckcraft_model::{Chart, Geom, Presentation, Shape, ShapeId, ShapeKind, ShapeStyle, Table, Xfrm};
|
||||
|
||||
fn deck_with(shapes: Vec<Shape>) -> Presentation {
|
||||
let mut p = Presentation::default();
|
||||
@@ -24,12 +24,12 @@ fn shape_fill_uses_theme_accent() {
|
||||
let sh = Shape {
|
||||
id: ShapeId(500),
|
||||
xfrm: Some(Xfrm::new(100.0, 100.0, 200.0, 100.0)),
|
||||
style: Some(ShapeStyle::accent(slidecraft_color::SchemeSlot::Accent1)),
|
||||
style: Some(ShapeStyle::accent(deckcraft_color::SchemeSlot::Accent1)),
|
||||
..Default::default()
|
||||
};
|
||||
let p = deck_with(vec![sh]);
|
||||
let img = render_slide(&p, 0, &RenderOpts { scale: 1.0, ..Default::default() });
|
||||
let accent = p.masters[0].theme.colors.get(slidecraft_color::SchemeSlot::Accent1);
|
||||
let accent = p.masters[0].theme.colors.get(deckcraft_color::SchemeSlot::Accent1);
|
||||
let px = img.pixel(200, 150);
|
||||
assert!((px[0] as i32 - accent.r as i32).abs() <= 2 && (px[2] as i32 - accent.b as i32).abs() <= 2, "{px:?} vs {accent:?}");
|
||||
assert_eq!(img.pixel(50, 50), [255, 255, 255, 255]);
|
||||
@@ -49,14 +49,14 @@ fn text_draws_ink() {
|
||||
|
||||
#[test]
|
||||
fn every_preset_renders_without_panic() {
|
||||
let shapes: Vec<Shape> = slidecraft_geom::preset::CATALOG
|
||||
let shapes: Vec<Shape> = deckcraft_geom::preset::CATALOG
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, pr)| Shape {
|
||||
id: ShapeId(1000 + i as u32),
|
||||
xfrm: Some(Xfrm::new((i % 16) as f64 * 60.0, (i / 16) as f64 * 55.0, 50.0, 45.0)),
|
||||
geom: Geom::preset(pr.name),
|
||||
style: Some(ShapeStyle::accent(slidecraft_color::SchemeSlot::Accent2)),
|
||||
style: Some(ShapeStyle::accent(deckcraft_color::SchemeSlot::Accent2)),
|
||||
..Default::default()
|
||||
})
|
||||
.collect();
|
||||
@@ -70,12 +70,12 @@ fn effects_tables_charts_render() {
|
||||
let mut sh = Shape {
|
||||
id: ShapeId(600),
|
||||
xfrm: Some(Xfrm::new(50.0, 50.0, 200.0, 100.0)),
|
||||
style: Some(ShapeStyle::accent(slidecraft_color::SchemeSlot::Accent1)),
|
||||
style: Some(ShapeStyle::accent(deckcraft_color::SchemeSlot::Accent1)),
|
||||
..Default::default()
|
||||
};
|
||||
sh.effects = Some(slidecraft_model::Effects {
|
||||
outer_shadow: Some(slidecraft_model::style::Shadow {
|
||||
color: ColorRef::rgb(slidecraft_color::Rgba::BLACK),
|
||||
sh.effects = Some(deckcraft_model::Effects {
|
||||
outer_shadow: Some(deckcraft_model::style::Shadow {
|
||||
color: ColorRef::rgb(deckcraft_color::Rgba::BLACK),
|
||||
blur: 8.0,
|
||||
dist: 6.0,
|
||||
dir: 45.0,
|
||||
@@ -87,7 +87,7 @@ fn effects_tables_charts_render() {
|
||||
align: String::new(),
|
||||
rotate_with_shape: false,
|
||||
}),
|
||||
glow: Some(slidecraft_model::style::Glow { color: ColorRef::rgb(slidecraft_color::Rgba::rgb(255, 200, 0)), radius: 6.0 }),
|
||||
glow: Some(deckcraft_model::style::Glow { color: ColorRef::rgb(deckcraft_color::Rgba::rgb(255, 200, 0)), radius: 6.0 }),
|
||||
soft_edge: Some(4.0),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user