From 57664bd4098fd9a4f38f8b4e891c6828116830f2 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Fri, 28 Aug 2020 16:09:51 -0400 Subject: [PATCH] add vector image support to Multimedia plugin with vector image editor and some DataFormats --- .../VectorImage/VectorImageEditor.glade | 30 +++ .../AmigaKickstartVectorImage.uexml | 20 ++ .../Associations/VectorImage/SVG.uexml | 20 ++ ...lEditor.Content.PlatformIndependent.csproj | 4 + .../Controls/VectorImageControl.cs | 73 +++++++ .../VectorImage/VectorImageEditor.cs | 71 +++++++ ...or.Plugins.Multimedia.UserInterface.csproj | 4 + .../VectorImage/AmigaKickstartOpcode.cs | 30 +++ .../AmigaKickstartVectorImageDataFormat.cs | 149 +++++++++++++++ .../UniversalEditor.Plugins.Amiga.csproj | 11 ++ .../VectorImage/SVG/SVGDataFormat.cs | 180 ++++++++++++++++++ .../VectorImage/VectorImageObjectModel.cs | 18 ++ .../VectorImage/VectorImageStyle.cs | 39 ++++ .../Multimedia/VectorImage/VectorItem.cs | 33 ++++ .../VectorItems/PolygonVectorItem.cs | 48 +++++ .../UniversalEditor.Plugins.Multimedia.csproj | 6 + 16 files changed, 736 insertions(+) create mode 100644 Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/VectorImage/VectorImageEditor.glade create mode 100644 Content/UniversalEditor.Content.PlatformIndependent/Extensions/Amiga/Associations/VectorImage/AmigaKickstartVectorImage.uexml create mode 100644 Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/VectorImage/SVG.uexml create mode 100644 Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/Controls/VectorImageControl.cs create mode 100644 Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/VectorImageEditor.cs create mode 100644 Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartOpcode.cs create mode 100644 Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartVectorImageDataFormat.cs create mode 100644 Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/VectorImage/SVG/SVGDataFormat.cs create mode 100644 Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageStyle.cs create mode 100644 Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItem.cs create mode 100644 Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItems/PolygonVectorItem.cs diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/VectorImage/VectorImageEditor.glade b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/VectorImage/VectorImageEditor.glade new file mode 100644 index 00000000..1f4f9079 --- /dev/null +++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/Multimedia/VectorImage/VectorImageEditor.glade @@ -0,0 +1,30 @@ + + + + + + False + + + + + + True + False + vertical + + + UniversalEditor.Editors.Multimedia.VectorImage.Controls.VectorImageControl + True + False + + + True + True + 0 + + + + + + diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/Amiga/Associations/VectorImage/AmigaKickstartVectorImage.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/Amiga/Associations/VectorImage/AmigaKickstartVectorImage.uexml new file mode 100644 index 00000000..783831bf --- /dev/null +++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/Amiga/Associations/VectorImage/AmigaKickstartVectorImage.uexml @@ -0,0 +1,20 @@ + + + + + + + + *.vec + + + + + + + + + + + + \ No newline at end of file diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/VectorImage/SVG.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/VectorImage/SVG.uexml new file mode 100644 index 00000000..3e2f6056 --- /dev/null +++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/VectorImage/SVG.uexml @@ -0,0 +1,20 @@ + + + + + + + + *.svg + + + + + + + + + + + + \ No newline at end of file diff --git a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj index 3da75912..078e19b7 100644 --- a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj +++ b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj @@ -583,6 +583,9 @@ + + + @@ -651,6 +654,7 @@ + diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/Controls/VectorImageControl.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/Controls/VectorImageControl.cs new file mode 100644 index 00000000..2851e51b --- /dev/null +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/Controls/VectorImageControl.cs @@ -0,0 +1,73 @@ +// +// VectorImageControl.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; +using MBS.Framework.Drawing; +using MBS.Framework.UserInterface; +using MBS.Framework.UserInterface.Drawing; +using UniversalEditor.ObjectModels.Multimedia.VectorImage; +using UniversalEditor.ObjectModels.Multimedia.VectorImage.VectorItems; + +namespace UniversalEditor.Editors.Multimedia.VectorImage.Controls +{ + public class VectorImageControl : CustomControl + { + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + VectorImageEditor editor = (Parent as VectorImageEditor); + if (editor == null) return; + + VectorImageObjectModel vec = (editor.ObjectModel as VectorImageObjectModel); + if (vec == null) return; + + for (int i = 0; i < vec.Items.Count; i++) + { + DrawVectorItem(e.Graphics, vec.Items[i]); + } + } + + private void DrawVectorItem(Graphics graphics, VectorItem vectorItem) + { + if (vectorItem is PolygonVectorItem) + { + PolygonVectorItem poly = (vectorItem as PolygonVectorItem); + + List pts = new List(); + for (int i = 0; i < poly.Points.Count; i++) + { + pts.Add(new Vector2D(poly.Points[i].X, poly.Points[i].Y)); + } + Vector2D[] points = pts.ToArray(); + + if (poly.Style.FillColor != Colors.Transparent) + { + graphics.FillPolygon(new SolidBrush(poly.Style.FillColor), points); + } + if (poly.Style.BorderColor != Colors.Transparent) + { + graphics.DrawPolygon(new Pen(poly.Style.BorderColor), points); + } + } + } + } +} diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/VectorImageEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/VectorImageEditor.cs new file mode 100644 index 00000000..50264989 --- /dev/null +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/VectorImage/VectorImageEditor.cs @@ -0,0 +1,71 @@ +// +// VectorImageEditor.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using MBS.Framework.UserInterface; +using UniversalEditor.ObjectModels.Multimedia.VectorImage; +using UniversalEditor.UserInterface; + +namespace UniversalEditor.Editors.Multimedia.VectorImage +{ + [ContainerLayout("~/Editors/Multimedia/VectorImage/VectorImageEditor.glade")] + public class VectorImageEditor : Editor + { + private Controls.VectorImageControl veced; + + private static EditorReference _er = null; + public override EditorReference MakeReference() + { + if (_er == null) + { + _er = base.MakeReference(); + _er.SupportedObjectModels.Add(typeof(VectorImageObjectModel)); + } + return _er; + } + + public override void UpdateSelections() + { + } + + protected override Selection CreateSelectionInternal(object content) + { + return null; + } + + protected override void OnCreated(EventArgs e) + { + base.OnCreated(e); + OnObjectModelChanged(e); + } + + protected override void OnObjectModelChanged(EventArgs e) + { + base.OnObjectModelChanged(e); + + if (!IsCreated) return; + + VectorImageObjectModel vec = (ObjectModel as VectorImageObjectModel); + if (vec == null) return; + + veced.Refresh(); + } + } +} diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj index 1463df20..01abcf34 100644 --- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj @@ -57,6 +57,8 @@ + + @@ -78,6 +80,8 @@ + + diff --git a/Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartOpcode.cs b/Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartOpcode.cs new file mode 100644 index 00000000..c9ebfd50 --- /dev/null +++ b/Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartOpcode.cs @@ -0,0 +1,30 @@ +// +// AmigaKickstartOpcode.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace UniversalEditor.Plugins.Amiga.DataFormats.VectorImage +{ + public enum AmigaKickstartOpcode : byte + { + None = 0x00, + Fill = 0xFE, + Polyline = 0xFF + } +} diff --git a/Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartVectorImageDataFormat.cs b/Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartVectorImageDataFormat.cs new file mode 100644 index 00000000..a0f93235 --- /dev/null +++ b/Plugins/UniversalEditor.Plugins.Amiga/DataFormats/VectorImage/AmigaKickstartVectorImageDataFormat.cs @@ -0,0 +1,149 @@ +// +// AmigaKickstartPicture.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using MBS.Framework.Drawing; +using UniversalEditor.IO; +using UniversalEditor.ObjectModels.Multimedia.Palette; +using UniversalEditor.ObjectModels.Multimedia.VectorImage; +using UniversalEditor.ObjectModels.Multimedia.VectorImage.VectorItems; + +namespace UniversalEditor.Plugins.Amiga.DataFormats.VectorImage +{ + public class AmigaKickstartVectorImageDataFormat : DataFormat + { + private static DataFormatReference _dfr = null; + protected override DataFormatReference MakeReferenceInternal() + { + if (_dfr == null) + { + _dfr = base.MakeReferenceInternal(); + _dfr.Capabilities.Add(typeof(VectorImageObjectModel), DataFormatCapabilities.All); + } + return _dfr; + } + + public AmigaKickstartVectorImageDataFormat() + { + PaletteObjectModel palAmiga = new PaletteObjectModel(new PaletteEntry[] + { + new PaletteEntry(Color.FromRGBAByte(0xFF, 0xFF, 0xFF)), + new PaletteEntry(Color.FromRGBAByte(0x00, 0x00, 0x00)), + new PaletteEntry(Color.FromRGBAByte(0x77, 0x77, 0xCC)), + new PaletteEntry(Color.FromRGBAByte(0xBB, 0xBB, 0xBB)) + }); + Palette = palAmiga; + } + + public PaletteObjectModel Palette { get; set; } = null; + + protected override void LoadInternal(ref ObjectModel objectModel) + { + VectorImageObjectModel vec = (objectModel as VectorImageObjectModel); + if (vec == null) throw new ObjectModelNotSupportedException(); + + // https://retrocomputing.stackexchange.com/questions/13897/why-was-the-kickstart-1-x-insert-floppy-graphic-so-bad/13940 + Reader reader = Accessor.Reader; + + AmigaKickstartOpcode opcode = AmigaKickstartOpcode.None; + byte colorIndex = 0x00; + + PolygonVectorItem polyline = null; + + while (!reader.EndOfStream) + { + byte b1 = reader.ReadByte(); + byte b2 = reader.ReadByte(); + + if (b1 == 0xFF) + { + if (b2 == 0xFF) break; + + if (opcode == AmigaKickstartOpcode.Polyline || opcode == AmigaKickstartOpcode.Fill) + { + // we are done drawing the polyline + vec.Items.Add(polyline); + polyline = null; + } + + // start drawing a polyline with the color index given in the second byte. Treat any subsequent two bytes as x,y coordinates belonging to that polyline + // except if the first byte is FF (see rules 2 and 3) or FE (see rule 4), which is where you stop drawing the line. + opcode = AmigaKickstartOpcode.Polyline; + colorIndex = b2; + polyline = new PolygonVectorItem(); + polyline.Style.BorderColor = Palette.Entries[colorIndex].Color; + polyline.Style.FillColor = Colors.Transparent; + } + else if (b1 == 0xFE) + { + // If the first byte is FE, flood fill an area using the color index given in the second byte, starting from the point whose coordinates are given in + // the next two bytes. + opcode = AmigaKickstartOpcode.Fill; + colorIndex = b2; + + polyline = (polyline.Clone() as PolygonVectorItem); + + byte b3 = reader.ReadByte(), b4 = reader.ReadByte(); + polyline.Points.Insert(0, new PositionVector2(b3, b4)); + polyline.Style.BorderColor = Colors.Transparent; + polyline.Style.FillColor = Palette.Entries[colorIndex].Color; + } + else + { + if (opcode == AmigaKickstartOpcode.Polyline || opcode == AmigaKickstartOpcode.Fill) + { + polyline.Points.Add(new PositionVector2(b1, b2)); + } + } + } + + if (polyline != null) + { + // clean up just in case we get incomplete data + vec.Items.Add(polyline); + } + + double maxX = 0.0, maxY = 0.0; + for (int i = 0; i < vec.Items.Count; i++) + { + PolygonVectorItem vi = (vec.Items[i] as PolygonVectorItem); + if (vi == null) continue; + + for (int j = 0; j < vi.Points.Count; j++) + { + if (vi.Points[j].X > maxX) + maxX = vi.Points[j].X; + if (vi.Points[j].Y > maxY) + maxY = vi.Points[j].Y; + } + } + + vec.Width = (int)maxX; + vec.Height = (int)maxY; + } + + protected override void SaveInternal(ObjectModel objectModel) + { + VectorImageObjectModel vec = (objectModel as VectorImageObjectModel); + if (vec == null) throw new ObjectModelNotSupportedException(); + + } + } +} diff --git a/Plugins/UniversalEditor.Plugins.Amiga/UniversalEditor.Plugins.Amiga.csproj b/Plugins/UniversalEditor.Plugins.Amiga/UniversalEditor.Plugins.Amiga.csproj index 88f48abe..c80cf0fd 100644 --- a/Plugins/UniversalEditor.Plugins.Amiga/UniversalEditor.Plugins.Amiga.csproj +++ b/Plugins/UniversalEditor.Plugins.Amiga/UniversalEditor.Plugins.Amiga.csproj @@ -36,12 +36,15 @@ + + + @@ -56,6 +59,14 @@ {8622EBC4-8E20-476E-B284-33D472081F5C} UniversalEditor.UserInterface + + {00266B21-35C9-4A7F-A6BA-D54D7FDCC25C} + MBS.Framework + + + {BE4D0BA3-0888-42A5-9C09-FC308A4509D2} + UniversalEditor.Plugins.Multimedia + diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/VectorImage/SVG/SVGDataFormat.cs b/Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/VectorImage/SVG/SVGDataFormat.cs new file mode 100644 index 00000000..1a44ac57 --- /dev/null +++ b/Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/VectorImage/SVG/SVGDataFormat.cs @@ -0,0 +1,180 @@ +// +// SVGDataFormat.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; +using System.Text; +using MBS.Framework.Drawing; +using UniversalEditor.DataFormats.Markup.XML; +using UniversalEditor.ObjectModels.Markup; +using UniversalEditor.ObjectModels.Multimedia.VectorImage; +using UniversalEditor.ObjectModels.Multimedia.VectorImage.VectorItems; + +namespace UniversalEditor.DataFormats.Multimedia.VectorImage.SVG +{ + public class SVGDataFormat : XMLDataFormat + { + private const string SCHEMA_SVG = "http://www.w3.org/2000/svg"; + + private static DataFormatReference _dfr = null; + protected override DataFormatReference MakeReferenceInternal() + { + if (_dfr == null) + { + _dfr = new DataFormatReference(GetType()); + _dfr.Capabilities.Add(typeof(VectorImageObjectModel), DataFormatCapabilities.All); + _dfr.Title = "Scalable Vector Graphics"; + } + return _dfr; + } + + protected override void BeforeLoadInternal(Stack objectModels) + { + base.BeforeLoadInternal(objectModels); + objectModels.Push(new MarkupObjectModel()); + } + protected override void AfterLoadInternal(Stack objectModels) + { + base.AfterLoadInternal(objectModels); + + MarkupObjectModel mom = (objectModels.Pop() as MarkupObjectModel); + VectorImageObjectModel vec = (objectModels.Pop() as VectorImageObjectModel); + + MarkupTagElement tagSVG = mom.FindElementUsingSchema(SCHEMA_SVG, "svg") as MarkupTagElement; + if (tagSVG == null) throw new InvalidDataFormatException("top-level SVG element not found"); + + MarkupAttribute attViewBox = tagSVG.Attributes["viewBox"]; + if (attViewBox != null) + { + string[] viewbox = attViewBox.Value.Split(new char[] { ' ' }); + if (viewbox.Length == 4) + { + vec.ViewBox = new Rectangle(Double.Parse(viewbox[0]), Double.Parse(viewbox[1]), Double.Parse(viewbox[2]), Double.Parse(viewbox[3])); + } + } + + for (int i = 0; i < tagSVG.Elements.Count; i++) + { + MarkupTagElement tagItem = tagSVG.Elements[i] as MarkupTagElement; + if (tagItem == null) continue; + + if (tagItem.Name == "path") + { + MarkupAttribute attD = tagItem.Attributes["d"]; + if (attD == null) continue; + + Dictionary dictStyles = new Dictionary(); + MarkupAttribute attStyle = tagItem.Attributes["style"]; + if (attStyle != null) + { + string[] styles = attStyle.Value.Split(new char[] { ';' }); + for (int j = 0; j < styles.Length; j++) + { + string[] st = styles[j].Split(new char[] { ':' }); + if (st.Length == 2) + { + dictStyles[st[0]] = st[1]; + } + } + } + + string[] ds = attD.Value?.Split(new char[] { ' ' }); + + PolygonVectorItem poly = new PolygonVectorItem(); + + if (dictStyles.ContainsKey("fill")) + { + poly.Style.FillColor = Color.FromString(dictStyles["fill"]); + } + if (dictStyles.ContainsKey("stroke")) + { + poly.Style.BorderColor = Color.FromString(dictStyles["stroke"]); + } + if (ds[0] == "m" && ds[ds.Length - 1] == "z") + { + for (int j = 1; j < ds.Length - 1; j++) + { + string[] vs = ds[j].Split(new char[] { ',' }); + if (vs.Length == 2) + { + poly.Points.Add(new PositionVector2(Double.Parse(vs[0]), Double.Parse(vs[1]))); + } + } + } + + vec.Items.Add(poly); + } + } + } + + protected override void BeforeSaveInternal(Stack objectModels) + { + base.BeforeSaveInternal(objectModels); + + VectorImageObjectModel vec = (objectModels.Pop() as VectorImageObjectModel); + if (vec == null) throw new ObjectModelNotSupportedException(); + + MarkupObjectModel mom = new MarkupObjectModel(); + MarkupTagElement tagSVG = new MarkupTagElement(); + tagSVG.Name = "svg"; + + tagSVG.Attributes.Add("xmlns", "http://www.w3.org/2000/svg"); + tagSVG.Attributes.Add("height", vec.Height.ToString()); + tagSVG.Attributes.Add("width", vec.Width.ToString()); + + if (vec.ViewBox != Rectangle.Empty) + { + tagSVG.Attributes.Add("viewBox", String.Format("{0} {1} {2} {3}", vec.ViewBox.X, vec.ViewBox.Y, vec.ViewBox.Width, vec.ViewBox.Height)); + } + + for (int i = 0; i < vec.Items.Count; i++) + { + if (vec.Items[i] is PolygonVectorItem) + { + PolygonVectorItem poly = (vec.Items[i] as PolygonVectorItem); + + MarkupTagElement tagPath = new MarkupTagElement(); + tagPath.FullName = "path"; + + StringBuilder sb = new StringBuilder(); + sb.Append("m "); + for (int j = 0; j < poly.Points.Count; j++) + { + sb.Append(poly.Points[j].X.ToString()); + sb.Append(','); + sb.Append(poly.Points[j].Y.ToString()); + sb.Append(' '); + } + sb.Append('z'); + + tagPath.Attributes.Add("d", sb.ToString()); + + if (poly.Style.FillColor != Colors.Transparent) + tagPath.Attributes.Add("fill", poly.Style.FillColor.ToHexadecimalHTML()); + + tagSVG.Elements.Add(tagPath); + } + } + + mom.Elements.Add(tagSVG); + objectModels.Push(mom); + } + } +} diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageObjectModel.cs b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageObjectModel.cs index d3f182b3..dad97747 100644 --- a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageObjectModel.cs +++ b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageObjectModel.cs @@ -19,6 +19,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using MBS.Framework.Drawing; + namespace UniversalEditor.ObjectModels.Multimedia.VectorImage { /// @@ -27,6 +29,14 @@ namespace UniversalEditor.ObjectModels.Multimedia.VectorImage public class VectorImageObjectModel : ObjectModel { private static ObjectModelReference _omr = null; + + public int Width { get; set; } = 0; + public int Height { get; set; } = 0; + + public Rectangle ViewBox { get; set; } = Rectangle.Empty; + + public VectorItem.VectorItemCollection Items { get; } = new VectorItem.VectorItemCollection(); + protected override ObjectModelReference MakeReferenceInternal() { if (_omr == null) @@ -40,10 +50,18 @@ namespace UniversalEditor.ObjectModels.Multimedia.VectorImage public override void Clear() { + Items.Clear(); } public override void CopyTo(ObjectModel where) { + VectorImageObjectModel clone = (where as VectorImageObjectModel); + if (clone == null) return; + + for (int i = 0; i < Items.Count; i++) + { + clone.Items.Add(Items[i].Clone() as VectorItem); + } } } } diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageStyle.cs b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageStyle.cs new file mode 100644 index 00000000..6de09577 --- /dev/null +++ b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorImageStyle.cs @@ -0,0 +1,39 @@ +// +// VectorImageStyle.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using MBS.Framework.Drawing; + +namespace UniversalEditor.ObjectModels.Multimedia.VectorImage +{ + public class VectorImageStyle : ICloneable + { + public Color BorderColor { get; set; } + public Color FillColor { get; set; } + + public object Clone() + { + VectorImageStyle clone = new VectorImageStyle(); + clone.BorderColor = BorderColor; + clone.FillColor = FillColor; + return clone; + } + } +} diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItem.cs b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItem.cs new file mode 100644 index 00000000..6ff135dc --- /dev/null +++ b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItem.cs @@ -0,0 +1,33 @@ +// +// VectorItem.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace UniversalEditor.ObjectModels.Multimedia.VectorImage +{ + public abstract class VectorItem : ICloneable + { + public class VectorItemCollection : System.Collections.ObjectModel.Collection + { + + } + + public abstract object Clone(); + } +} diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItems/PolygonVectorItem.cs b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItems/PolygonVectorItem.cs new file mode 100644 index 00000000..05ed3e34 --- /dev/null +++ b/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/VectorImage/VectorItems/PolygonVectorItem.cs @@ -0,0 +1,48 @@ +// +// Polygon.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2020 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; + +namespace UniversalEditor.ObjectModels.Multimedia.VectorImage.VectorItems +{ + public class PolygonVectorItem : VectorItem + { + public double X { get; set; } = 0; + public double Y { get; set; } = 0; + + public VectorImageStyle Style { get; set; } = new VectorImageStyle(); + + public List Points { get; } = new List(); + + public override object Clone() + { + PolygonVectorItem clone = new PolygonVectorItem(); + clone.X = X; + clone.Y = Y; + clone.Style = Style.Clone() as VectorImageStyle; + for (int i = 0; i < Points.Count; i++) + { + clone.Points.Add((PositionVector2)Points[i].Clone()); + } + return clone; + } + } +} diff --git a/Plugins/UniversalEditor.Plugins.Multimedia/UniversalEditor.Plugins.Multimedia.csproj b/Plugins/UniversalEditor.Plugins.Multimedia/UniversalEditor.Plugins.Multimedia.csproj index ae27e3d3..2b181ddb 100644 --- a/Plugins/UniversalEditor.Plugins.Multimedia/UniversalEditor.Plugins.Multimedia.csproj +++ b/Plugins/UniversalEditor.Plugins.Multimedia/UniversalEditor.Plugins.Multimedia.csproj @@ -337,6 +337,10 @@ + + + + @@ -390,6 +394,8 @@ + + \ No newline at end of file