mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Fix most known issues with migrations failing to open documents from the past year (#3148)
This commit is contained in:
@@ -68,13 +68,22 @@ pub fn migrate_artboard<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Re
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum EitherFormat {
|
||||
enum ArtboardFormat {
|
||||
ArtboardGroup(ArtboardGroup),
|
||||
OldArtboardTable(OldTable<Artboard>),
|
||||
ArtboardTable(Table<Artboard>),
|
||||
}
|
||||
|
||||
Ok(match EitherFormat::deserialize(deserializer)? {
|
||||
EitherFormat::ArtboardGroup(artboard_group) => {
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OldTable<T> {
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
transform: Vec<DAffine2>,
|
||||
alpha_blending: Vec<AlphaBlending>,
|
||||
}
|
||||
|
||||
Ok(match ArtboardFormat::deserialize(deserializer)? {
|
||||
ArtboardFormat::ArtboardGroup(artboard_group) => {
|
||||
let mut table = Table::new();
|
||||
for (artboard, source_node_id) in artboard_group.artboards {
|
||||
table.push(TableRow {
|
||||
@@ -86,7 +95,18 @@ pub fn migrate_artboard<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Re
|
||||
}
|
||||
table
|
||||
}
|
||||
EitherFormat::ArtboardTable(artboard_table) => artboard_table,
|
||||
ArtboardFormat::OldArtboardTable(old_table) => old_table
|
||||
.element
|
||||
.into_iter()
|
||||
.zip(old_table.transform.into_iter().zip(old_table.alpha_blending))
|
||||
.map(|(element, (transform, alpha_blending))| TableRow {
|
||||
element,
|
||||
transform,
|
||||
alpha_blending,
|
||||
source_node_id: None,
|
||||
})
|
||||
.collect(),
|
||||
ArtboardFormat::ArtboardTable(artboard_table) => artboard_table,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::context::{CloneVarArgs, Context, ContextFeatures, Ctx, ExtractAll};
|
||||
use crate::gradient::GradientStops;
|
||||
use crate::raster_types::{CPU, GPU, Raster};
|
||||
use crate::table::Table;
|
||||
use crate::transform::Footprint;
|
||||
use crate::uuid::NodeId;
|
||||
use crate::vector::Vector;
|
||||
use crate::{Graphic, OwnedContextImpl};
|
||||
@@ -24,6 +25,7 @@ async fn context_modification<T>(
|
||||
Context -> f64,
|
||||
Context -> String,
|
||||
Context -> DAffine2,
|
||||
Context -> Footprint,
|
||||
Context -> DVec2,
|
||||
Context -> Vec<DVec2>,
|
||||
Context -> Vec<NodeId>,
|
||||
|
||||
@@ -507,15 +507,34 @@ pub fn migrate_graphic<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Res
|
||||
elements: Vec<(Graphic, Option<NodeId>)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OlderTable<T> {
|
||||
id: Vec<u64>,
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OldTable<T> {
|
||||
id: Vec<u64>,
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
transform: Vec<DAffine2>,
|
||||
alpha_blending: Vec<AlphaBlending>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum EitherFormat {
|
||||
enum GraphicFormat {
|
||||
OldGraphicGroup(OldGraphicGroup),
|
||||
OlderTableOldGraphicGroup(OlderTable<OldGraphicGroup>),
|
||||
OldTableOldGraphicGroup(OldTable<OldGraphicGroup>),
|
||||
OldTableGraphicGroup(OldTable<GraphicGroup>),
|
||||
Table(serde_json::Value),
|
||||
}
|
||||
|
||||
Ok(match EitherFormat::deserialize(deserializer)? {
|
||||
EitherFormat::OldGraphicGroup(old) => {
|
||||
Ok(match GraphicFormat::deserialize(deserializer)? {
|
||||
GraphicFormat::OldGraphicGroup(old) => {
|
||||
let mut graphic_table = Table::new();
|
||||
for (graphic, source_node_id) in old.elements {
|
||||
graphic_table.push(TableRow {
|
||||
@@ -527,7 +546,43 @@ pub fn migrate_graphic<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Res
|
||||
}
|
||||
graphic_table
|
||||
}
|
||||
EitherFormat::Table(value) => {
|
||||
GraphicFormat::OlderTableOldGraphicGroup(old) => old
|
||||
.element
|
||||
.into_iter()
|
||||
.flat_map(|element| {
|
||||
element.elements.into_iter().map(move |(graphic, source_node_id)| TableRow {
|
||||
element: graphic,
|
||||
transform: element.transform,
|
||||
alpha_blending: element.alpha_blending,
|
||||
source_node_id,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
GraphicFormat::OldTableOldGraphicGroup(old) => old
|
||||
.element
|
||||
.into_iter()
|
||||
.flat_map(|element| {
|
||||
element.elements.into_iter().map(move |(graphic, source_node_id)| TableRow {
|
||||
element: graphic,
|
||||
transform: element.transform,
|
||||
alpha_blending: element.alpha_blending,
|
||||
source_node_id,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
GraphicFormat::OldTableGraphicGroup(old) => old
|
||||
.element
|
||||
.into_iter()
|
||||
.flat_map(|element| {
|
||||
element.elements.into_iter().map(move |(graphic, source_node_id)| TableRow {
|
||||
element: graphic,
|
||||
transform: Default::default(),
|
||||
alpha_blending: Default::default(),
|
||||
source_node_id,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
GraphicFormat::Table(value) => {
|
||||
// Try to deserialize as either table format
|
||||
if let Ok(old_table) = serde_json::from_value::<Table<GraphicGroup>>(value.clone()) {
|
||||
let mut graphic_table = Table::new();
|
||||
|
||||
@@ -69,21 +69,21 @@ pub fn migrate_color<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Resul
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum EitherFormat {
|
||||
enum ColorFormat {
|
||||
Color(Color),
|
||||
OptionalColor(Option<Color>),
|
||||
ColorTable(Table<Color>),
|
||||
}
|
||||
|
||||
Ok(match EitherFormat::deserialize(deserializer)? {
|
||||
EitherFormat::Color(color) => Table::new_from_element(color),
|
||||
EitherFormat::OptionalColor(color) => {
|
||||
Ok(match ColorFormat::deserialize(deserializer)? {
|
||||
ColorFormat::Color(color) => Table::new_from_element(color),
|
||||
ColorFormat::OptionalColor(color) => {
|
||||
if let Some(color) = color {
|
||||
Table::new_from_element(color)
|
||||
} else {
|
||||
Table::new()
|
||||
}
|
||||
}
|
||||
EitherFormat::ColorTable(color_table) => color_table,
|
||||
ColorFormat::ColorTable(color_table) => color_table,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -218,7 +218,6 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
|
||||
enum RasterFrame {
|
||||
/// 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
|
||||
ImageFrame(Table<Image<Color>>),
|
||||
}
|
||||
impl<'de> serde::Deserialize<'de> for RasterFrame {
|
||||
@@ -236,9 +235,7 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, DynAny, serde::Serialize, serde::Deserialize)]
|
||||
pub enum GraphicElement {
|
||||
/// Equivalent to the SVG <g> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
|
||||
GraphicGroup(Table<GraphicElement>),
|
||||
/// A vector shape, equivalent to the SVG <path> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
|
||||
VectorData(Table<Vector>),
|
||||
RasterFrame(RasterFrame),
|
||||
}
|
||||
@@ -283,11 +280,73 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
|
||||
enum FormatVersions {
|
||||
Image(Image<Color>),
|
||||
OldImageFrame(OldImageFrame<Color>),
|
||||
OlderImageFrameTable(OlderTable<ImageFrame<Color>>),
|
||||
OldImageFrameTable(OldTable<ImageFrame<Color>>),
|
||||
OldImageTable(OldTable<Image<Color>>),
|
||||
OldRasterTable(OldTable<Raster<CPU>>),
|
||||
ImageFrameTable(Table<ImageFrame<Color>>),
|
||||
ImageTable(Table<Image<Color>>),
|
||||
RasterTable(Table<Raster<CPU>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OldTable<T> {
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
transform: Vec<DAffine2>,
|
||||
alpha_blending: Vec<AlphaBlending>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OlderTable<T> {
|
||||
id: Vec<u64>,
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
}
|
||||
|
||||
fn from_image_table(table: Table<Image<Color>>) -> Table<Raster<CPU>> {
|
||||
Table::new_from_element(Raster::new_cpu(table.iter().next().unwrap().element.clone()))
|
||||
}
|
||||
|
||||
fn old_table_to_new_table<T>(old_table: OldTable<T>) -> Table<T> {
|
||||
old_table
|
||||
.element
|
||||
.into_iter()
|
||||
.zip(old_table.transform.into_iter().zip(old_table.alpha_blending))
|
||||
.map(|(element, (transform, alpha_blending))| TableRow {
|
||||
element,
|
||||
transform,
|
||||
alpha_blending,
|
||||
source_node_id: None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn older_table_to_new_table<T>(old_table: OlderTable<T>) -> Table<T> {
|
||||
old_table
|
||||
.element
|
||||
.into_iter()
|
||||
.map(|element| TableRow {
|
||||
element,
|
||||
transform: DAffine2::IDENTITY,
|
||||
alpha_blending: AlphaBlending::default(),
|
||||
source_node_id: None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn from_image_frame_table(image_frame: Table<ImageFrame<Color>>) -> Table<Raster<CPU>> {
|
||||
Table::new_from_element(Raster::new_cpu(
|
||||
image_frame
|
||||
.iter()
|
||||
.next()
|
||||
.unwrap_or(Table::new_from_element(ImageFrame::default()).iter().next().unwrap())
|
||||
.element
|
||||
.image
|
||||
.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
Ok(match FormatVersions::deserialize(deserializer)? {
|
||||
FormatVersions::Image(image) => Table::new_from_element(Raster::new_cpu(image)),
|
||||
FormatVersions::OldImageFrame(OldImageFrame { image, transform, alpha_blending }) => {
|
||||
@@ -296,16 +355,12 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
|
||||
*image_frame_table.iter_mut().next().unwrap().alpha_blending = alpha_blending;
|
||||
image_frame_table
|
||||
}
|
||||
FormatVersions::ImageFrameTable(image_frame) => Table::new_from_element(Raster::new_cpu(
|
||||
image_frame
|
||||
.iter()
|
||||
.next()
|
||||
.unwrap_or(Table::new_from_element(ImageFrame::default()).iter().next().unwrap())
|
||||
.element
|
||||
.image
|
||||
.clone(),
|
||||
)),
|
||||
FormatVersions::ImageTable(table) => Table::new_from_element(Raster::new_cpu(table.iter().next().unwrap().element.clone())),
|
||||
FormatVersions::OlderImageFrameTable(old_table) => from_image_frame_table(older_table_to_new_table(old_table)),
|
||||
FormatVersions::OldImageFrameTable(old_table) => from_image_frame_table(old_table_to_new_table(old_table)),
|
||||
FormatVersions::OldImageTable(old_table) => from_image_table(old_table_to_new_table(old_table)),
|
||||
FormatVersions::OldRasterTable(old_table) => old_table_to_new_table(old_table),
|
||||
FormatVersions::ImageFrameTable(image_frame) => from_image_frame_table(image_frame),
|
||||
FormatVersions::ImageTable(table) => from_image_table(table),
|
||||
FormatVersions::RasterTable(table) => table,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -306,7 +306,10 @@ impl SegmentDomain {
|
||||
}
|
||||
|
||||
pub fn push(&mut self, id: SegmentId, start: usize, end: usize, handles: BezierHandles, stroke: StrokeId) {
|
||||
debug_assert!(!self.id.contains(&id), "Tried to push an existing point to a point domain");
|
||||
#[cfg(debug_assertions)]
|
||||
if self.id.contains(&id) {
|
||||
warn!("Tried to push an existing point to a point domain");
|
||||
}
|
||||
|
||||
self.id.push(id);
|
||||
self.start_point.push(start);
|
||||
|
||||
@@ -5,7 +5,7 @@ pub use super::vector_modification::*;
|
||||
use crate::bounds::{BoundingBox, RenderBoundingBox};
|
||||
use crate::math::quad::Quad;
|
||||
use crate::subpath::{BezierHandles, ManipulatorGroup, Subpath};
|
||||
use crate::table::Table;
|
||||
use crate::table::{Table, TableRow};
|
||||
use crate::transform::Transform;
|
||||
use crate::vector::click_target::{ClickTargetType, FreePoint};
|
||||
use crate::vector::misc::{HandleId, ManipulatorPointId};
|
||||
@@ -490,18 +490,35 @@ pub fn migrate_vector<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Resu
|
||||
pub upstream_graphic_group: Option<Table<Graphic>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OldTable<T> {
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
transform: Vec<DAffine2>,
|
||||
alpha_blending: Vec<AlphaBlending>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct OlderTable<T> {
|
||||
id: Vec<u64>,
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<T>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
enum EitherFormat {
|
||||
enum VectorFormat {
|
||||
Vector(Vector),
|
||||
OldVectorData(OldVectorData),
|
||||
OldVectorTable(OldTable<Vector>),
|
||||
OlderVectorTable(OlderTable<Vector>),
|
||||
VectorTable(Table<Vector>),
|
||||
}
|
||||
|
||||
Ok(match EitherFormat::deserialize(deserializer)? {
|
||||
EitherFormat::Vector(vector) => Table::new_from_element(vector),
|
||||
EitherFormat::OldVectorData(old) => {
|
||||
Ok(match VectorFormat::deserialize(deserializer)? {
|
||||
VectorFormat::Vector(vector) => Table::new_from_element(vector),
|
||||
VectorFormat::OldVectorData(old) => {
|
||||
let mut vector_table = Table::new_from_element(Vector {
|
||||
style: old.style,
|
||||
colinear_manipulators: old.colinear_manipulators,
|
||||
@@ -514,7 +531,19 @@ pub fn migrate_vector<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Resu
|
||||
*vector_table.iter_mut().next().unwrap().alpha_blending = old.alpha_blending;
|
||||
vector_table
|
||||
}
|
||||
EitherFormat::VectorTable(vector_table) => vector_table,
|
||||
VectorFormat::OlderVectorTable(older_table) => older_table.element.into_iter().map(|element| TableRow { element, ..Default::default() }).collect(),
|
||||
VectorFormat::OldVectorTable(old_table) => old_table
|
||||
.element
|
||||
.into_iter()
|
||||
.zip(old_table.transform.into_iter().zip(old_table.alpha_blending))
|
||||
.map(|(element, (transform, alpha_blending))| TableRow {
|
||||
element,
|
||||
transform,
|
||||
alpha_blending,
|
||||
source_node_id: None,
|
||||
})
|
||||
.collect(),
|
||||
VectorFormat::VectorTable(vector_table) => vector_table,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user