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.
Files changed (75) hide show
  1. {codimate-0.1.1 → codimate-0.1.3}/Cargo.lock +13 -1
  2. {codimate-0.1.1 → codimate-0.1.3}/PKG-INFO +3 -1
  3. {codimate-0.1.1 → codimate-0.1.3}/README.md +2 -0
  4. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/mod.rs +1 -1
  5. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/primitive.rs +64 -0
  6. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/src/lib.rs +8 -0
  7. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-math/Cargo.toml +5 -0
  8. codimate-0.1.3/crates/codimate-math/src/lib.rs +565 -0
  9. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-py/Cargo.toml +1 -1
  10. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-reconcile/Cargo.toml +6 -0
  11. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-reconcile/src/lib.rs +580 -74
  12. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/src/command.rs +125 -0
  13. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/src/raster.rs +30 -0
  14. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/tests/raster.rs +71 -0
  15. {codimate-0.1.1 → codimate-0.1.3}/pyproject.toml +1 -1
  16. {codimate-0.1.1 → codimate-0.1.3}/python/codimate/__init__.py +1 -1
  17. {codimate-0.1.1 → codimate-0.1.3}/python/codimate/scene.py +70 -2
  18. codimate-0.1.1/crates/codimate-math/src/lib.rs +0 -293
  19. {codimate-0.1.1 → codimate-0.1.3}/Cargo.toml +0 -0
  20. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/Cargo.toml +0 -0
  21. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/src/lib.rs +0 -0
  22. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/animation.rs +0 -0
  23. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/parallel.rs +0 -0
  24. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/playable.rs +0 -0
  25. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/sequence.rs +0 -0
  26. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-animation/tests/stagger.rs +0 -0
  27. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/Cargo.toml +0 -0
  28. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/builder.rs +0 -0
  29. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/easing.rs +0 -0
  30. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/glyph.rs +0 -0
  31. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/lib.rs +0 -0
  32. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/manim_palette.rs +0 -0
  33. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/path.rs +0 -0
  34. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/circle.rs +0 -0
  35. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/connection.rs +0 -0
  36. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/path.rs +0 -0
  37. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/pulse.rs +0 -0
  38. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/rect.rs +0 -0
  39. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/text.rs +0 -0
  40. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/scene/transform.rs +0 -0
  41. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/src/value.rs +0 -0
  42. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/anchors.rs +0 -0
  43. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/animated.rs +0 -0
  44. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/circle.rs +0 -0
  45. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/connection.rs +0 -0
  46. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/easing.rs +0 -0
  47. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/manim_palette.rs +0 -0
  48. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/path.rs +0 -0
  49. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/ports.rs +0 -0
  50. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/pulse.rs +0 -0
  51. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/rect.rs +0 -0
  52. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/scene.rs +0 -0
  53. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/scene_effect_helpers.rs +0 -0
  54. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-core/tests/tween.rs +0 -0
  55. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/Cargo.toml +0 -0
  56. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/tests/export.rs +0 -0
  57. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-export/tests/png.rs +0 -0
  58. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/Cargo.toml +0 -0
  59. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/build.rs +0 -0
  60. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/fonts/DejaVuSansMono.ttf +0 -0
  61. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/fonts/DroidSansFallbackFull.ttf +0 -0
  62. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/fonts/NotoSansKhmer-Regular.ttf +0 -0
  63. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-fonts/src/lib.rs +0 -0
  64. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-glyph/Cargo.toml +0 -0
  65. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-glyph/src/lib.rs +0 -0
  66. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-layout/Cargo.toml +0 -0
  67. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-layout/src/lib.rs +0 -0
  68. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-layout/tests/layout.rs +0 -0
  69. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-py/src/lib.rs +0 -0
  70. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/Cargo.toml +0 -0
  71. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/src/lib.rs +0 -0
  72. {codimate-0.1.1 → codimate-0.1.3}/crates/codimate-render/tests/render.rs +0 -0
  73. {codimate-0.1.1 → codimate-0.1.3}/python/codimate/explain.py +0 -0
  74. {codimate-0.1.1 → codimate-0.1.3}/python/codimate/layout.py +0 -0
  75. {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.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.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"