/// <summary> /// Reads a Quill project folder and imports it in a Sequence object. /// A project consists in a json-based scene hierarchy, a json-based state file, and binary data. /// </summary> public static Sequence Read(string path) { if (string.IsNullOrEmpty(path) || !Directory.Exists(path)) { return(null); } string sequenceFilename = Path.Combine(path, "Quill.json"); string paintDataFilename = Path.Combine(path, "Quill.qbin"); if (!File.Exists(sequenceFilename) || !File.Exists(paintDataFilename)) { return(null); } Sequence seq = null; try { string json = File.ReadAllText(sequenceFilename); dynamic document = JsonConvert.DeserializeObject(json); seq = Parse(document); } catch (JsonReaderException e) { // The JSON is invalid. // This happened sometimes in the early days of Quill when the transforms exploded and "inf" or "nan" was written in the matrix array. Console.WriteLine("JSON parsing error: {0}", e.Message); } catch (Exception e) { Console.WriteLine("Error during the parsing of the Quill.json document: {0}", e.Message); } if (seq == null) { return(null); } // Now that we have loaded the scene hierarchy, read the actual attached data from the qbin. using (Stream stream = File.OpenRead(paintDataFilename)) { QBinReader qbinReader = new QBinReader(stream); seq.LastStrokeId = qbinReader.ReadUInt32(); ReadLayerData(seq.RootLayer, qbinReader); } return(seq); }
/// <summary> /// Recursive function reading binary data for the entire hierarchy. /// </summary> private static void ReadLayerData(Layer layer, QBinReader qbinReader) { if (layer.Type == LayerType.Group) { foreach (Layer l in ((LayerGroup)layer).Children) { ReadLayerData(l, qbinReader); } } else if (layer.Type == LayerType.Paint) { foreach (Drawing drawing in ((LayerPaint)layer).Drawings) { qbinReader.BaseStream.Seek(drawing.DataFileOffset, SeekOrigin.Begin); drawing.Data = qbinReader.ReadDrawingData(); } } }