codimate 0.1.1__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codimate-0.1.1 → codimate-0.1.3}/Cargo.lock +13 -1
- {codimate-0.1.1 → codimate-0.1.3}/PKG-INFO +3 -1
- {codimate-0.1.1 → codimate-0.1.3}/README.md +2 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/mod.rs +1 -1
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/primitive.rs +64 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/src/lib.rs +8 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-math/Cargo.toml +5 -0
- codimate-0.1.3/crates/codimate-math/src/lib.rs +565 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-py/Cargo.toml +1 -1
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-reconcile/Cargo.toml +6 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-reconcile/src/lib.rs +580 -74
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/src/command.rs +125 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/src/raster.rs +30 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/tests/raster.rs +71 -0
- {codimate-0.1.1 → codimate-0.1.3}/pyproject.toml +1 -1
- {codimate-0.1.1 → codimate-0.1.3}/python/codimate/__init__.py +1 -1
- {codimate-0.1.1 → codimate-0.1.3}/python/codimate/scene.py +70 -2
- codimate-0.1.1/crates/codimate-math/src/lib.rs +0 -293
- {codimate-0.1.1 → codimate-0.1.3}/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/animation.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/parallel.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/playable.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/sequence.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/stagger.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/builder.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/easing.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/glyph.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/manim_palette.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/path.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/circle.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/connection.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/path.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/pulse.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/rect.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/text.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/transform.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/value.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/anchors.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/animated.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/circle.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/connection.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/easing.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/manim_palette.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/path.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/ports.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/pulse.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/rect.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/scene.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/scene_effect_helpers.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/tween.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/tests/export.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/tests/png.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/build.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/fonts/DejaVuSansMono.ttf +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/fonts/DroidSansFallbackFull.ttf +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/fonts/NotoSansKhmer-Regular.ttf +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-glyph/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-glyph/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-layout/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-layout/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-layout/tests/layout.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-py/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/Cargo.toml +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/src/lib.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/tests/render.rs +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/python/codimate/explain.py +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/python/codimate/layout.py +0 -0
- {codimate-0.1.1 → codimate-0.1.3}/python/codimate/trace.py +0 -0
|
@@ -211,12 +211,13 @@ version = "0.1.0"
|
|
|
211
211
|
dependencies = [
|
|
212
212
|
"codimate-core",
|
|
213
213
|
"mitex",
|
|
214
|
+
"roxmltree",
|
|
214
215
|
"usvg",
|
|
215
216
|
]
|
|
216
217
|
|
|
217
218
|
[[package]]
|
|
218
219
|
name = "codimate-py"
|
|
219
|
-
version = "0.1.
|
|
220
|
+
version = "0.1.3"
|
|
220
221
|
dependencies = [
|
|
221
222
|
"codimate-animation",
|
|
222
223
|
"codimate-core",
|
|
@@ -235,6 +236,8 @@ dependencies = [
|
|
|
235
236
|
"codimate-core",
|
|
236
237
|
"codimate-math",
|
|
237
238
|
"codimate-render",
|
|
239
|
+
"jpeg-decoder",
|
|
240
|
+
"png",
|
|
238
241
|
]
|
|
239
242
|
|
|
240
243
|
[[package]]
|
|
@@ -585,6 +588,15 @@ version = "1.0.18"
|
|
|
585
588
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
586
589
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
587
590
|
|
|
591
|
+
[[package]]
|
|
592
|
+
name = "jpeg-decoder"
|
|
593
|
+
version = "0.3.2"
|
|
594
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
595
|
+
checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
|
|
596
|
+
dependencies = [
|
|
597
|
+
"rayon",
|
|
598
|
+
]
|
|
599
|
+
|
|
588
600
|
[[package]]
|
|
589
601
|
name = "jpeg-encoder"
|
|
590
602
|
version = "0.6.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codimate
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Topic :: Multimedia :: Video
|
|
@@ -182,6 +182,8 @@ scene.circle(name, r=, at=)
|
|
|
182
182
|
scene.text(name, content, size=, at=)
|
|
183
183
|
scene.polygon(name, points) # cm.ngon, cm.star
|
|
184
184
|
scene.curve(name, points, w=) # smooth, through the points
|
|
185
|
+
scene.svg(name, "logo.svg", size=) # vector art, as real geometry
|
|
186
|
+
scene.image(name, "photo.jpg", size=) # a picture: PNG or JPEG
|
|
185
187
|
scene.line(name, start=slot_or_point, end=slot_or_point, w=)
|
|
186
188
|
scene.formula(name, r"\frac{a}{b}", size=, at=) # LaTeX, needs `typst`
|
|
187
189
|
cm.measure(text, size) -> (w, h) # to size a box around text
|
|
@@ -170,6 +170,8 @@ scene.circle(name, r=, at=)
|
|
|
170
170
|
scene.text(name, content, size=, at=)
|
|
171
171
|
scene.polygon(name, points) # cm.ngon, cm.star
|
|
172
172
|
scene.curve(name, points, w=) # smooth, through the points
|
|
173
|
+
scene.svg(name, "logo.svg", size=) # vector art, as real geometry
|
|
174
|
+
scene.image(name, "photo.jpg", size=) # a picture: PNG or JPEG
|
|
173
175
|
scene.line(name, start=slot_or_point, end=slot_or_point, w=)
|
|
174
176
|
scene.formula(name, r"\frac{a}{b}", size=, at=) # LaTeX, needs `typst`
|
|
175
177
|
cm.measure(text, size) -> (w, h) # to size a box around text
|
|
@@ -27,7 +27,7 @@ pub use connection::{connection, Connection};
|
|
|
27
27
|
pub use path::{path_node, ConcretePath, PathNode};
|
|
28
28
|
pub use primitive::{
|
|
29
29
|
primitive_circle, primitive_path, primitive_rect, primitive_text, ConcreteGeometry,
|
|
30
|
-
ConcretePrimitive, Geometry, Primitive, Transformable,
|
|
30
|
+
ConcretePrimitive, Geometry, Pixels, Primitive, Transformable,
|
|
31
31
|
};
|
|
32
32
|
pub use pulse::{pulse_on, Pulse};
|
|
33
33
|
pub use rect::{rect, ConcreteRect, Rect};
|
|
@@ -34,6 +34,36 @@ pub enum Geometry {
|
|
|
34
34
|
font_size: Animated<f32>,
|
|
35
35
|
align: TextAlign,
|
|
36
36
|
},
|
|
37
|
+
/// A decoded raster picture, drawn into a box (ADR 0013).
|
|
38
|
+
///
|
|
39
|
+
/// The pixels are shared rather than owned: a 1,200-frame render resolves
|
|
40
|
+
/// this once per frame, and copying a megabyte each time would be the
|
|
41
|
+
/// whole cost of the feature.
|
|
42
|
+
Image {
|
|
43
|
+
pixels: std::sync::Arc<Pixels>,
|
|
44
|
+
width: Animated<f32>,
|
|
45
|
+
height: Animated<f32>,
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Decoded pixels: premultiplied RGBA, ready to blit.
|
|
50
|
+
///
|
|
51
|
+
/// Core does no decoding — it would need a codec and an opinion about file
|
|
52
|
+
/// formats, and neither belongs in the layer that owns no I/O. Something
|
|
53
|
+
/// upstream hands these over already decoded.
|
|
54
|
+
#[derive(Clone, PartialEq)]
|
|
55
|
+
pub struct Pixels {
|
|
56
|
+
pub width: u32,
|
|
57
|
+
pub height: u32,
|
|
58
|
+
pub rgba: Vec<u8>,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Dimensions only. The derived version would print several megabytes of
|
|
62
|
+
// channel bytes the first time anyone put a Scene in a debug log.
|
|
63
|
+
impl std::fmt::Debug for Pixels {
|
|
64
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
65
|
+
write!(f, "Pixels({}x{})", self.width, self.height)
|
|
66
|
+
}
|
|
37
67
|
}
|
|
38
68
|
|
|
39
69
|
/// A `Geometry` resolved at a specific `t` — plain shape data, still local-space.
|
|
@@ -54,6 +84,11 @@ pub enum ConcreteGeometry {
|
|
|
54
84
|
font_size: f32,
|
|
55
85
|
align: TextAlign,
|
|
56
86
|
},
|
|
87
|
+
Image {
|
|
88
|
+
pixels: std::sync::Arc<Pixels>,
|
|
89
|
+
width: f32,
|
|
90
|
+
height: f32,
|
|
91
|
+
},
|
|
57
92
|
}
|
|
58
93
|
|
|
59
94
|
impl Geometry {
|
|
@@ -110,6 +145,7 @@ impl Geometry {
|
|
|
110
145
|
}
|
|
111
146
|
}
|
|
112
147
|
Geometry::Text { .. } => Vec2::new(0.0, 0.0),
|
|
148
|
+
Geometry::Image { .. } => Vec2::new(0.0, 0.0),
|
|
113
149
|
}
|
|
114
150
|
}
|
|
115
151
|
|
|
@@ -134,10 +170,34 @@ impl Geometry {
|
|
|
134
170
|
font_size: font_size.resolve(t),
|
|
135
171
|
align: *align,
|
|
136
172
|
},
|
|
173
|
+
Geometry::Image {
|
|
174
|
+
pixels,
|
|
175
|
+
width,
|
|
176
|
+
height,
|
|
177
|
+
} => ConcreteGeometry::Image {
|
|
178
|
+
pixels: pixels.clone(),
|
|
179
|
+
width: width.resolve(t),
|
|
180
|
+
height: height.resolve(t),
|
|
181
|
+
},
|
|
137
182
|
}
|
|
138
183
|
}
|
|
139
184
|
|
|
140
185
|
pub(crate) fn ease_with(self, curve: super::TimeCurve) -> Self {
|
|
186
|
+
// An image eases by its box; the pixels are the same pixels whatever
|
|
187
|
+
// the time is.
|
|
188
|
+
if let Geometry::Image {
|
|
189
|
+
pixels,
|
|
190
|
+
width,
|
|
191
|
+
height,
|
|
192
|
+
} = self
|
|
193
|
+
{
|
|
194
|
+
let width_curve = curve.clone();
|
|
195
|
+
return Geometry::Image {
|
|
196
|
+
pixels,
|
|
197
|
+
width: Animated::new(move |t| width.resolve(width_curve(t))),
|
|
198
|
+
height: Animated::new(move |t| height.resolve(curve(t))),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
141
201
|
match self {
|
|
142
202
|
Geometry::Circle { radius } => Geometry::Circle {
|
|
143
203
|
radius: Animated::new(move |t| radius.resolve(curve(t))),
|
|
@@ -164,6 +224,9 @@ impl Geometry {
|
|
|
164
224
|
align,
|
|
165
225
|
}
|
|
166
226
|
}
|
|
227
|
+
// Handled above, before the match, because it needs to move its
|
|
228
|
+
// Arc rather than borrow it.
|
|
229
|
+
Geometry::Image { .. } => unreachable!("eased before the match"),
|
|
167
230
|
}
|
|
168
231
|
}
|
|
169
232
|
|
|
@@ -239,6 +302,7 @@ impl Geometry {
|
|
|
239
302
|
Geometry::Rect { .. } => "Rect",
|
|
240
303
|
Geometry::Path { .. } => "Path",
|
|
241
304
|
Geometry::Text { .. } => "Text",
|
|
305
|
+
Geometry::Image { .. } => "Image",
|
|
242
306
|
}
|
|
243
307
|
}
|
|
244
308
|
}
|
|
@@ -294,6 +294,14 @@ pub fn export_mp4(
|
|
|
294
294
|
let mut command = Command::new(encoder_binary());
|
|
295
295
|
command
|
|
296
296
|
.arg("-y")
|
|
297
|
+
// ffmpeg's default is 46 lines of banner, build configuration and
|
|
298
|
+
// libx264 internals per render, which buries anything that actually
|
|
299
|
+
// went wrong and is the first thing a new author sees. `error` keeps
|
|
300
|
+
// the failures; `-stats` keeps the one rewriting progress line, so a
|
|
301
|
+
// two-minute render still looks alive rather than hung.
|
|
302
|
+
.arg("-loglevel")
|
|
303
|
+
.arg("error")
|
|
304
|
+
.arg("-stats")
|
|
297
305
|
.arg("-f")
|
|
298
306
|
.arg("rawvideo")
|
|
299
307
|
.arg("-pix_fmt")
|
|
@@ -8,3 +8,8 @@ codimate-core = { path = "../codimate-core" }
|
|
|
8
8
|
# See docs/adr/0005; pinned for deterministic golden images.
|
|
9
9
|
mitex = "0.2" # LaTeX -> Typst markup
|
|
10
10
|
usvg = { version = "0.47", default-features = false } # SVG -> path geometry
|
|
11
|
+
# Already in the tree as a usvg dependency. Declared directly so an imported
|
|
12
|
+
# SVG's `<text>` can be read: usvg is built without its `text` feature and
|
|
13
|
+
# discards those elements while parsing, so they have to be picked up from the
|
|
14
|
+
# source (ADR 0014).
|
|
15
|
+
roxmltree = "0.21"
|