From 3fc431475c0077cfa3a9a7869846a8fe73ef17e9 Mon Sep 17 00:00:00 2001 From: warrengalyen Date: Thu, 11 Jan 2024 08:48:21 -0800 Subject: [PATCH] Revert "Remove export code as it's not needed" This reverts commit 8bab9abbf5da3c196078f66b49f401cf84a324db. --- .../IO/PaletteParsers/CorelDrawPalParser.cs | 96 ++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/src/PixiEditor/Models/IO/PaletteParsers/CorelDrawPalParser.cs b/src/PixiEditor/Models/IO/PaletteParsers/CorelDrawPalParser.cs index ce32db6cc..cd1398d31 100644 --- a/src/PixiEditor/Models/IO/PaletteParsers/CorelDrawPalParser.cs +++ b/src/PixiEditor/Models/IO/PaletteParsers/CorelDrawPalParser.cs @@ -10,6 +10,9 @@ internal class CorelDrawPalParser : PaletteFileParser public override string FileName { get; } = "CorelDRAW! 3.0 Palette"; public override string[] SupportedFileExtensions { get; } = { ".pal" }; + // Default name to use for colors (color name is required by format) + private const string SWATCH_NAME = "PixiEditor Color"; + public override async Task Parse(string path) { try @@ -69,9 +72,51 @@ private async Task ParseFile(string path) public override bool CanSave => false; + // NOTE: saving data works but PixiEditor defaults to first .pal parser which + // is JASC so saving to an actual file is currently not available. + // Palette exporter needs to be refactored to support multiple formats of + // same file extension. public override async Task Save(string path, PaletteFileData data) { - throw new SavingNotSupportedException("Saving palette as CorelDRAW! 3.0 palette directly is not supported."); + StringBuilder sb = new StringBuilder(SWATCH_NAME.Length + 20); + + try + { + await using (Stream stream = File.OpenWrite(path)) + { + using (TextWriter writer = new StreamWriter(stream, Encoding.ASCII, 1024, true)) + { + foreach (var color in data.Colors) + { + this.ConvertRgbToCmyk(color, out byte c, out byte m, out byte y, out byte k); + + this.WriteName(sb, SWATCH_NAME); + this.WriteNumber(sb, c); + this.WriteNumber(sb, m); + this.WriteNumber(sb, y); + this.WriteNumber(sb, k); + + writer.WriteLine(sb.ToString()); + sb.Length = 0; + } + } + } + return true; + } + catch + { + return false; + } + } + + private static byte ClampCmyk(float value) + { + if (value < 0 || float.IsNaN(value)) + { + value = 0; + } + + return Convert.ToByte(value * 100); } private PaletteColor ConvertCmykToRgb(int c, int m, int y, int k) @@ -88,6 +133,23 @@ private PaletteColor ConvertCmykToRgb(int c, int m, int y, int k) return new PaletteColor((byte)r, (byte)g, (byte)b); } + private void ConvertRgbToCmyk(PaletteColor color, out byte c, out byte m, out byte y, out byte k) + { + float r, g, b; + float divisor; + + r = color.R / 255F; + g = color.G / 255F; + b = color.B / 255F; + + divisor = 1 - Math.Max(Math.Max(r, g), b); + + c = ClampCmyk((1 - r - divisor) / (1 - divisor)); + m = ClampCmyk((1 - g - divisor) / (1 - divisor)); + y = ClampCmyk((1 - b - divisor) / (1 - divisor)); + k = ClampCmyk(divisor); + } + private byte NextNumber(string line, ref int start) { int length; @@ -123,4 +185,36 @@ private byte NextNumber(string line, ref int start) return result; } + + private void WriteName(StringBuilder sb, string name) + { + sb.Append('"'); + sb.Append(name); + sb.Append('"'); + + for (int j = (name ?? string.Empty).Length; j < name.Length; j++) + { + sb.Append(' '); + } + } + + private void WriteNumber(StringBuilder sb, byte value) + { + if (value == 100) + { + sb.Append("100 "); + } + else + { + sb.Append(' '); + if (value < 10) + { + sb.Append(' '); + } + + sb.Append(value); + + sb.Append(' '); + } + } }