public static int Run(Options options) { Console.WriteLine($"{Path.GetFileName(options.Input)} -> {Path.GetFileName(options.Output)}"); var reader = new CircuitDiagramDocumentReader(); CircuitDiagramDocument circuit; using (var fs = File.Open(options.Input, FileMode.Open, FileAccess.Read)) { circuit = reader.ReadCircuit(fs); } var loggerFactory = new LoggerFactory(); if (options.Verbose) { loggerFactory.AddConsole(LogLevel.Information); } var descriptionLookup = new DirectoryComponentDescriptionLookup(loggerFactory, options.ComponentsDirectory ?? Path.GetDirectoryName(options.Input), true); var renderer = new CircuitRenderer(descriptionLookup); var drawingContext = new SkiaDrawingContext((int)circuit.Size.Width, (int)circuit.Size.Height, SKColors.White); renderer.RenderCircuit(circuit, drawingContext); using (var outputFs = File.OpenWrite(options.Output)) { drawingContext.WriteAsPng(outputFs); } return(0); }
public static int Run(Options options) { Console.WriteLine($"{Path.GetFileName(options.Input)} -> {Path.GetFileName(options.Output)}"); var reader = new CircuitDiagramDocumentReader(); CircuitDiagramDocument circuit; using (var fs = File.Open(options.Input, FileMode.Open, FileAccess.Read)) { circuit = reader.ReadCircuit(fs); } var loggerFactory = new LoggerFactory(); if (options.Verbose) { loggerFactory.AddConsole(LogLevel.Information); } var descriptionLookup = new DirectoryComponentDescriptionLookup(loggerFactory, options.ComponentsDirectory ?? Path.GetDirectoryName(options.Input), true); var renderer = new CircuitRenderer(descriptionLookup); var drawingContext = new SkiaDrawingContext((int)circuit.Size.Width, (int)circuit.Size.Height, SKColors.White); try { renderer.RenderCircuit(circuit, drawingContext); } catch (MissingComponentDescriptionException ex) { Console.Error.WriteLine($"Unable to find component {ex.MissingType}."); var allDescriptions = descriptionLookup.GetAllDescriptions().OrderBy(x => x.ComponentName).ToList(); if (!allDescriptions.Any()) { Console.Error.Write("No components were loaded. Is the --components option set correctly?"); } else { Console.Error.WriteLine("Ensure this component is available in the --components directory. The following components were loaded:"); foreach (var description in allDescriptions) { Console.Error.WriteLine($" - {description.ComponentName} ({description.Metadata.GUID})"); } } return(1); } using (var outputFs = File.OpenWrite(options.Output)) { drawingContext.WriteAsPng(outputFs); } return(0); }
public static void Run(string[] args) { string input = null; IReadOnlyList <string> componentDirectories = Array.Empty <string>(); string output = null; var cliOptions = ArgumentSyntax.Parse(args, options => { options.ApplicationName = "cdcli circuit"; options.DefineOptionList("components", ref componentDirectories, "Path to components directory."); options.DefineOption("o|output", ref output, "Path to output file."); options.DefineParameter("input", ref input, "Path to input circuit."); }); if (input == null) { cliOptions.ReportError("Input file must be specified."); } if (componentDirectories == null) { cliOptions.ReportError("Components directory must be specified."); } if (output == null) { cliOptions.ReportError("Output path must be specified."); } Console.WriteLine($"{Path.GetFileName(input)} -> {Path.GetFileName(output)}"); var reader = new CircuitDiagramDocumentReader(); CircuitDiagramDocument circuit; using (var fs = File.Open(input, FileMode.Open, FileAccess.Read)) circuit = reader.ReadCircuit(fs); var descriptionLookup = new DirectoryComponentDescriptionLookup(componentDirectories.ToArray()); var renderer = new CircuitRenderer(descriptionLookup); var drawingContext = new SkiaDrawingContext((int)circuit.Size.Width, (int)circuit.Size.Height, SKColors.White); renderer.RenderCircuit(circuit, drawingContext); using (var outputFs = File.OpenWrite(output)) drawingContext.WriteAsPng(outputFs); }
public int Run(Options options) { _logger.LogInformation($"{Path.GetFileName(options.Input)} -> {Path.GetFileName(options.Output)}"); CircuitDocument circuit; var inputFileExtension = Path.GetExtension(options.Input); switch (inputFileExtension) { case ".cddx": { var reader = new CircuitDiagramDocumentReader(); using (var fs = File.Open(options.Input, FileMode.Open, FileAccess.Read)) { circuit = reader.ReadCircuit(fs); } break; } default: { _logger.LogError($"Unknown file type: '{inputFileExtension}'."); return(1); } } var renderer = new CircuitRenderer(_componentDescriptionLookup); var bufferRenderer = new SkiaBufferedDrawingContext(); renderer.RenderCircuit(circuit, bufferRenderer); IPngDrawingContext context; switch (options.Renderer) { case PngRenderer.Skia: context = new SkiaDrawingContext((int)circuit.Size.Width, (int)circuit.Size.Height, SKColors.White); break; case PngRenderer.ImageSharp: context = new ImageSharpDrawingContext((int)circuit.Size.Width, (int)circuit.Size.Height, SixLabors.ImageSharp.Color.White); break; default: _logger.LogError("Unsupported renderer."); return(1); } try { renderer.RenderCircuit(circuit, context); } catch (MissingComponentDescriptionException ex) { _logger.LogError($"Unable to find component {ex.MissingType}."); var allDescriptions = _componentDescriptionLookup.GetAllDescriptions().OrderBy(x => x.ComponentName).ToList(); if (!allDescriptions.Any()) { _logger.LogInformation("No components were loaded. Is the --components option set correctly?"); } else { _logger.LogInformation("Ensure this component is available in the --components directory. The following components were loaded:"); foreach (var description in allDescriptions) { _logger.LogInformation($" - {description.ComponentName} ({description.Metadata.GUID})"); } } return(1); } using (var outputFs = File.OpenWrite(options.Output)) { context.WriteAsPng(outputFs); } return(0); }
public static T RenderPreview <T>(Func <Size, T> drawingContext, ComponentDescription desc, PreviewGenerationOptions options) where T : IDrawingContext { var componentType = new ComponentType(desc.Metadata.GUID, desc.ComponentName); foreach (var property in desc.Properties) { componentType.PropertyNames.Add(property.SerializedName); } var component = new PositionalComponent(componentType); component.Layout.Location = new Point(options.Width / 2 - (options.Horizontal ? options.Size : 0), options.Height / 2 - (!options.Horizontal ? options.Size : 0)); component.Layout.Orientation = options.Horizontal ? Orientation.Horizontal : Orientation.Vertical; // Minimum size component.Layout.Size = Math.Max(desc.MinSize, options.Size); // Configuration if (options.Configuration != null) { foreach (var setter in options.Configuration.Setters) { component.Properties[setter.Key] = setter.Value; } } // Orientation FlagOptions flagOptions = desc.DetermineFlags(component); if ((flagOptions & FlagOptions.HorizontalOnly) == FlagOptions.HorizontalOnly && component.Layout.Orientation == Orientation.Vertical) { component.Layout.Orientation = Orientation.Horizontal; component.Layout.Size = desc.MinSize; } else if ((flagOptions & FlagOptions.VerticalOnly) == FlagOptions.VerticalOnly && component.Layout.Orientation == Orientation.Horizontal) { component.Layout.Orientation = Orientation.Vertical; component.Layout.Size = desc.MinSize; } CircuitDocument document = new CircuitDocument(); document.Elements.Add(component); var lookup = new DictionaryComponentDescriptionLookup(); lookup.AddDescription(componentType, desc); var docRenderer = new CircuitRenderer(lookup); var buffer = new BufferedDrawingContext(); docRenderer.RenderCircuit(document, buffer); var bb = buffer.BoundingBox; T resultContext; IDrawingContext dc; if (options.Crop) { resultContext = drawingContext(options.Crop ? bb.Size : new Size(options.Width, options.Height)); dc = new TranslationDrawingContext(new Vector(Math.Round(-bb.X), Math.Round(-bb.Y)), resultContext); } else if (options.Center) { resultContext = drawingContext(new Size(options.Width, options.Height)); var x = bb.X - options.Width / 2 + bb.Width / 2; var y = bb.Y - options.Height / 2 + bb.Height / 2; dc = new TranslationDrawingContext(new Vector(Math.Round(-x), Math.Round(-y)), resultContext); } else { resultContext = drawingContext(new Size(options.Width, options.Height)); dc = resultContext; } docRenderer.RenderCircuit(document, dc); return(resultContext); }
public static T RenderPreview <T>(Func <Size, T> drawingContext, ComponentDescription desc, PreviewGenerationOptions options) where T : IDrawingContext { var componentType = new TypeDescriptionComponentType(desc.Metadata.GUID, ComponentType.UnknownCollection, desc.ComponentName); var component = new PositionalComponent(componentType); component.Layout.Location = new Point(options.Width / 2 - (options.Horizontal ? options.Size : 0), options.Height / 2 - (!options.Horizontal ? options.Size : 0)); component.Layout.Orientation = options.Horizontal ? Orientation.Horizontal : Orientation.Vertical; // Minimum size component.Layout.Size = Math.Max(desc.MinSize, options.Size); // Configuration var configurationDesc = desc.Metadata.Configurations.FirstOrDefault(x => x.Name == options.Configuration); if (configurationDesc != null) { foreach (var setter in configurationDesc.Setters) { component.Properties[setter.Key] = setter.Value; } } // Orientation FlagOptions flagOptions = desc.DetermineFlags(component); if ((flagOptions & FlagOptions.HorizontalOnly) == FlagOptions.HorizontalOnly && component.Layout.Orientation == Orientation.Vertical) { component.Layout.Orientation = Orientation.Horizontal; } else if ((flagOptions & FlagOptions.VerticalOnly) == FlagOptions.VerticalOnly && component.Layout.Orientation == Orientation.Horizontal) { component.Layout.Orientation = Orientation.Vertical; } // Flip if ((flagOptions & FlagOptions.FlipPrimary) == FlagOptions.FlipPrimary && (options.Flip & FlipState.Primary) == FlipState.Primary) { component.Layout.Flip |= FlipState.Primary; } if ((flagOptions & FlagOptions.FlipSecondary) == FlagOptions.FlipSecondary && (options.Flip & FlipState.Secondary) == FlipState.Secondary) { component.Layout.Flip |= FlipState.Secondary; } // Properties foreach (var property in options.Properties) { // Look up serialized name var propertyInfo = desc.Properties.FirstOrDefault(x => x.Name == property.Key); if (propertyInfo != null) { component.Properties[propertyInfo.SerializedName] = PropertyValue.Dynamic(property.Value); } } foreach (var property in options.RawProperties) { component.Properties[property.Key] = property.Value; } CircuitDocument document = new CircuitDocument(); document.Elements.Add(component); var lookup = new DictionaryComponentDescriptionLookup(); lookup.AddDescription(componentType, desc); var docRenderer = new CircuitRenderer(lookup); var buffer = new SkiaBufferedDrawingContext(); docRenderer.RenderCircuit(document, buffer); var bb = buffer.BoundingBox ?? new Rect(); T resultContext; IDrawingContext dc; Vector translationOffset = new Vector(0, 0); if (options.Crop) { resultContext = drawingContext(options.Crop ? bb.Size : new Size(options.Width * options.Scale, options.Height * options.Scale)); dc = new TranslationDrawingContext(new Vector(Math.Round(-bb.X), Math.Round(-bb.Y)), resultContext); } else if (options.Center) { resultContext = drawingContext(new Size(options.Width, options.Height)); var x = bb.X - options.Width / 2 + bb.Width / 2; var y = bb.Y - options.Height / 2 + bb.Height / 2; translationOffset = new Vector(Math.Round(-x), Math.Round(-y)); dc = new TranslationDrawingContext(translationOffset, resultContext); } else { resultContext = drawingContext(new Size(options.Width, options.Height)); dc = resultContext; } if (options.Grid && resultContext is SkiaDrawingContext gridSkiaContext) { RenderGrid(gridSkiaContext, options.Width, options.Height, translationOffset); } if (options.DebugLayout && resultContext is SkiaDrawingContext debugSkiaContext) { RenderDebugLayout(debugSkiaContext, component, desc, translationOffset); } docRenderer.RenderCircuit(document, dc); return(resultContext); }