Skip to content

Commit 08474b1

Browse files
committed
Partial commit 3/3: Document upgrade code
1 parent 3c94603 commit 08474b1

File tree

4 files changed

+206
-6
lines changed

4 files changed

+206
-6
lines changed

node-graph/gcore/src/application_io.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::instances::Instances;
21
use crate::text::FontCache;
32
use crate::transform::Footprint;
43
use crate::vector::style::ViewMode;
@@ -53,9 +52,6 @@ impl Size for web_sys::HtmlCanvasElement {
5352
}
5453
}
5554

56-
// TODO: Rename to ImageTextureTable
57-
pub type TextureFrameTable = Instances<ImageTexture>;
58-
5955
#[derive(Debug, Clone)]
6056
pub struct ImageTexture {
6157
#[cfg(feature = "wgpu")]

node-graph/gcore/src/raster/brush_cache.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ struct BrushCacheImpl {
1616
prev_input: Vec<BrushStroke>,
1717

1818
// The strokes that have been fully processed and blended into the background.
19+
#[cfg_attr(feature = "serde", serde(deserialize_with = "crate::graphene_core::raster::image::migrate_image_frame_instance"))]
1920
background: Instance<Image<Color>>,
21+
#[cfg_attr(feature = "serde", serde(deserialize_with = "crate::graphene_core::raster::image::migrate_image_frame_instance"))]
2022
blended_image: Instance<Image<Color>>,
23+
#[cfg_attr(feature = "serde", serde(deserialize_with = "crate::graphene_core::raster::image::migrate_image_frame_instance"))]
2124
last_stroke_texture: Instance<Image<Color>>,
2225

2326
// A cache for brush textures.

node-graph/gcore/src/raster/image.rs

Lines changed: 202 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use super::Color;
22
use super::discrete_srgb::float_to_srgb_u8;
3+
use crate::AlphaBlending;
34
use crate::instances::{Instance, Instances};
45
use alloc::vec::Vec;
56
use core::hash::{Hash, Hasher};
6-
use dyn_any::StaticType;
7-
use glam::DVec2;
7+
use dyn_any::{DynAny, StaticType};
8+
use glam::{DAffine2, DVec2};
89

910
#[cfg(feature = "serde")]
1011
mod base64_serde {
@@ -205,6 +206,205 @@ impl<P: Pixel> IntoIterator for Image<P> {
205206
}
206207
}
207208

209+
// TODO: Eventually remove this migration document upgrade code
210+
pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<RasterDataTable<Color>, D::Error> {
211+
use serde::Deserialize;
212+
213+
type ImageFrameTable<P> = Instances<Image<P>>;
214+
215+
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
216+
enum RasterFrame {
217+
/// A CPU-based bitmap image with a finite position and extent, equivalent to the SVG <image> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image
218+
ImageFrame(ImageFrameTable<Color>),
219+
}
220+
impl<'de> serde::Deserialize<'de> for RasterFrame {
221+
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
222+
Ok(RasterFrame::ImageFrame(ImageFrameTable::new(Image::deserialize(deserializer)?)))
223+
}
224+
}
225+
impl serde::Serialize for RasterFrame {
226+
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
227+
match self {
228+
RasterFrame::ImageFrame(image_instances) => image_instances.serialize(serializer),
229+
}
230+
}
231+
}
232+
233+
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
234+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
235+
pub enum GraphicElement {
236+
/// Equivalent to the SVG <g> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
237+
GraphicGroup(GraphicGroupTable),
238+
/// A vector shape, equivalent to the SVG <path> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
239+
VectorData(VectorDataTable),
240+
RasterFrame(RasterFrame),
241+
}
242+
243+
#[derive(Clone, Default, Debug, PartialEq, specta::Type)]
244+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
245+
pub struct ImageFrame<P: Pixel> {
246+
pub image: Image<P>,
247+
}
248+
impl From<ImageFrame<Color>> for GraphicElement {
249+
fn from(image_frame: ImageFrame<Color>) -> Self {
250+
GraphicElement::RasterFrame(RasterFrame::ImageFrame(ImageFrameTable::new(image_frame.image)))
251+
}
252+
}
253+
impl From<GraphicElement> for ImageFrame<Color> {
254+
fn from(element: GraphicElement) -> Self {
255+
match element {
256+
GraphicElement::RasterFrame(RasterFrame::ImageFrame(image)) => Self {
257+
image: image.instance_ref_iter().next().unwrap().instance.clone(),
258+
},
259+
_ => panic!("Expected Image, found {:?}", element),
260+
}
261+
}
262+
}
263+
264+
#[cfg(feature = "dyn-any")]
265+
unsafe impl<P> StaticType for ImageFrame<P>
266+
where
267+
P: dyn_any::StaticTypeSized + Pixel,
268+
P::Static: Pixel,
269+
{
270+
type Static = ImageFrame<P::Static>;
271+
}
272+
273+
#[derive(Clone, Default, Debug, PartialEq, specta::Type)]
274+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
275+
pub struct OldImageFrame<P: Pixel> {
276+
image: Image<P>,
277+
transform: DAffine2,
278+
alpha_blending: AlphaBlending,
279+
}
280+
281+
#[derive(serde::Serialize, serde::Deserialize)]
282+
#[serde(untagged)]
283+
enum FormatVersions {
284+
Image(Image<Color>),
285+
OldImageFrame(OldImageFrame<Color>),
286+
ImageFrame(Instances<ImageFrame<Color>>),
287+
ImageFrameTable(ImageFrameTable<Color>),
288+
RasterDataTable(RasterDataTable<Color>),
289+
}
290+
291+
Ok(match FormatVersions::deserialize(deserializer)? {
292+
FormatVersions::Image(image) => ImageFrameTable::new(image),
293+
FormatVersions::OldImageFrame(image_frame_with_transform_and_blending) => {
294+
let OldImageFrame { image, transform, alpha_blending } = image_frame_with_transform_and_blending;
295+
let mut image_frame_table = ImageFrameTable::new(image);
296+
*image_frame_table.instance_mut_iter().next().unwrap().transform = transform;
297+
*image_frame_table.instance_mut_iter().next().unwrap().alpha_blending = alpha_blending;
298+
image_frame_table
299+
}
300+
FormatVersions::ImageFrame(image_frame) => ImageFrameTable::new(image_frame.instance_ref_iter().next().unwrap().instance.image.clone()),
301+
FormatVersions::ImageFrameTable(image_frame_table) => image_frame_table,
302+
FormatVersions::RasterDataTable(raster_data_table) => raster_data_table,
303+
})
304+
}
305+
306+
// TODO: Eventually remove this migration document upgrade code
307+
pub fn migrate_image_frame_instance<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Instance<Image<Color>>, D::Error> {
308+
use serde::Deserialize;
309+
310+
type ImageFrameTable<P> = Instances<Image<P>>;
311+
312+
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
313+
enum RasterFrame {
314+
/// A CPU-based bitmap image with a finite position and extent, equivalent to the SVG <image> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image
315+
ImageFrame(ImageFrameTable<Color>),
316+
}
317+
impl<'de> serde::Deserialize<'de> for RasterFrame {
318+
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
319+
Ok(RasterFrame::ImageFrame(ImageFrameTable::new(Image::deserialize(deserializer)?)))
320+
}
321+
}
322+
impl serde::Serialize for RasterFrame {
323+
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
324+
match self {
325+
RasterFrame::ImageFrame(image_instances) => image_instances.serialize(serializer),
326+
}
327+
}
328+
}
329+
330+
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
331+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
332+
pub enum GraphicElement {
333+
/// Equivalent to the SVG <g> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
334+
GraphicGroup(GraphicGroupTable),
335+
/// A vector shape, equivalent to the SVG <path> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
336+
VectorData(VectorDataTable),
337+
RasterFrame(RasterFrame),
338+
}
339+
340+
#[derive(Clone, Default, Debug, PartialEq, specta::Type)]
341+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
342+
pub struct ImageFrame<P: Pixel> {
343+
pub image: Image<P>,
344+
}
345+
impl From<ImageFrame<Color>> for GraphicElement {
346+
fn from(image_frame: ImageFrame<Color>) -> Self {
347+
GraphicElement::RasterFrame(RasterFrame::ImageFrame(ImageFrameTable::new(image_frame.image)))
348+
}
349+
}
350+
impl From<GraphicElement> for ImageFrame<Color> {
351+
fn from(element: GraphicElement) -> Self {
352+
match element {
353+
GraphicElement::RasterFrame(RasterFrame::ImageFrame(image)) => Self {
354+
image: image.instance_ref_iter().next().unwrap().instance.clone(),
355+
},
356+
_ => panic!("Expected Image, found {:?}", element),
357+
}
358+
}
359+
}
360+
361+
#[cfg(feature = "dyn-any")]
362+
unsafe impl<P> StaticType for ImageFrame<P>
363+
where
364+
P: dyn_any::StaticTypeSized + Pixel,
365+
P::Static: Pixel,
366+
{
367+
type Static = ImageFrame<P::Static>;
368+
}
369+
370+
#[derive(Clone, Default, Debug, PartialEq, specta::Type)]
371+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
372+
pub struct OldImageFrame<P: Pixel> {
373+
image: Image<P>,
374+
transform: DAffine2,
375+
alpha_blending: AlphaBlending,
376+
}
377+
378+
#[derive(serde::Serialize, serde::Deserialize)]
379+
#[serde(untagged)]
380+
enum FormatVersions {
381+
Image(Image<Color>),
382+
OldImageFrame(OldImageFrame<Color>),
383+
ImageFrame(Instances<ImageFrame<Color>>),
384+
ImageFrameTable(ImageFrameTable<Color>),
385+
ImageInstance(Instance<Image<Color>>),
386+
}
387+
388+
Ok(match FormatVersions::deserialize(deserializer)? {
389+
FormatVersions::Image(image) => Instance {
390+
instance: image,
391+
..Default::default()
392+
},
393+
FormatVersions::OldImageFrame(image_frame_with_transform_and_blending) => Instance {
394+
instance: image_frame_with_transform_and_blending.image,
395+
transform: image_frame_with_transform_and_blending.transform,
396+
alpha_blending: image_frame_with_transform_and_blending.alpha_blending,
397+
source_node_id: None,
398+
},
399+
FormatVersions::ImageFrame(image_frame) => Instance {
400+
instance: image_frame.instance_ref_iter().next().unwrap().instance.image.clone(),
401+
..Default::default()
402+
},
403+
FormatVersions::ImageFrameTable(image_frame_table) => image_frame_table.instance_iter().next().unwrap_or_default(),
404+
FormatVersions::ImageInstance(image_instance) => image_instance,
405+
})
406+
}
407+
208408
// TODO: Rename to ImageTable
209409
pub type RasterDataTable<P> = Instances<Image<P>>;
210410

node-graph/graph-craft/src/document/value.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ tagged_value! {
187187
GraphicElement(graphene_core::GraphicElement),
188188
#[cfg_attr(all(feature = "serde", target_arch = "wasm32"), serde(deserialize_with = "graphene_core::vector::migrate_vector_data"))] // TODO: Eventually remove this migration document upgrade code
189189
VectorData(graphene_core::vector::VectorDataTable),
190+
#[cfg_attr(all(feature = "serde", target_arch = "wasm32"), serde(alias = "ImageFrame", deserialize_with = "graphene_core::raster::image::migrate_image_frame"))] // TODO: Eventually remove this migration document upgrade code
190191
RasterData(graphene_core::raster::image::RasterDataTable<Color>),
191192
#[cfg_attr(all(feature = "serde", target_arch = "wasm32"), serde(deserialize_with = "graphene_core::migrate_graphic_group"))] // TODO: Eventually remove this migration document upgrade code
192193
GraphicGroup(graphene_core::GraphicGroupTable),

0 commit comments

Comments
 (0)