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); }
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 int Run(Options options) { var loggerFactory = new LoggerFactory(); if (!options.Silent) { loggerFactory.AddProvider(new BasicConsoleLogger(options.Verbose ? LogLevel.Debug : LogLevel.Information)); } var logger = loggerFactory.CreateLogger(typeof(ComponentApp)); if (!options.Input.Any()) { logger.LogError("At least one input file must be specified."); return(1); } var generators = new Dictionary <IOutputGenerator, string>(); var outputGenerators = new OutputGeneratorRepository(options.Renderer); bool outputIsDirectory = Directory.Exists(options.Output); if (options.Output != null && !outputIsDirectory) { if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(options.Output), out var generator)) { // Use the generator implied by the file extension generators.Add(generator, options.Output); } else if (options.Formats?.Any() != true) { logger.LogError("Unable to infer format from output file extension." + Environment.NewLine + "Specify a known file extension or specify explicitly using --format"); return(1); } else { logger.LogInformation("Unable to infer format from output file extension. Using formats only."); } } if (options.Formats?.Any() == true) { foreach (var format in options.Formats) { if (outputGenerators.TryGetGeneratorByFormat(format, out var generator)) { generators.Add(generator, outputIsDirectory ? options.Output : null); } else { logger.LogError($"Unknown format: {format}"); return(1); } } } var previewOptions = new PreviewGenerationOptions { Center = true, Crop = options.Autosize, Width = options.Width, Height = options.Height, Configuration = options.Configuration, DebugLayout = options.DebugLayout, Grid = options.Grid, Scale = options.Scale, Properties = new Dictionary <string, string>(), }; if (options.RenderPropertiesPath != null && File.Exists(options.RenderPropertiesPath)) { logger.LogDebug($"Applying render properties from '{options.RenderPropertiesPath}'"); PreviewGenerationOptionsReader.Read(options.RenderPropertiesPath, previewOptions); } IComponentDescriptionLookup componentDescriptionLookup; var descriptionLookupLoggerFactory = options.Verbose ? loggerFactory : (ILoggerFactory)NullLoggerFactory.Instance; if (options.ComponentsDirectory != null) { componentDescriptionLookup = new DirectoryComponentDescriptionLookup(descriptionLookupLoggerFactory, options.ComponentsDirectory, true); } else { componentDescriptionLookup = new DictionaryComponentDescriptionLookup(); } var resourceProvider = ResourceProviderFactory.Create(loggerFactory.CreateLogger(typeof(ResourceProviderFactory)), options.Resources?.ToArray() ?? new string[0]); var outputRunner = new OutputRunner(loggerFactory.CreateLogger <OutputRunner>(), resourceProvider); var compileRunner = new ComponentDescriptionRunner(loggerFactory.CreateLogger <ComponentDescriptionRunner>(), outputRunner); var configurationDefinitionRunner = new ConfigurationDefinitionRunner(loggerFactory.CreateLogger <ConfigurationDefinitionRunner>(), componentDescriptionLookup, outputRunner); var results = new List <IManifestEntry>(); var inputs = new List <string>(); if (File.Exists(options.Input)) { logger.LogDebug("Input is a file."); inputs.Add(options.Input); } else if (Directory.Exists(options.Input)) { logger.LogDebug("Input is a directory."); foreach (var generator in generators) { if (generator.Value != null && !Directory.Exists(generator.Value)) { logger.LogError("Outputs must be directories when the input is a directory."); return(1); } } foreach (var file in Directory.GetFiles(options.Input, "*.xml", options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } foreach (var file in Directory.GetFiles(options.Input, "*.yaml", options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } } else { logger.LogError($"Input is not a valid file or directory: {options.Input}"); return(1); } foreach (var file in inputs.OrderBy(x => x)) { logger.LogDebug($"Starting '{file}'"); IManifestEntry result; switch (Path.GetExtension(file)) { case ".xml": result = compileRunner.CompileOne(file, previewOptions, options.AllConfigurations, generators); break; case ".yaml": result = configurationDefinitionRunner.CompileOne(file, previewOptions, generators); break; default: throw new NotSupportedException($"File type '{Path.GetExtension(file)}' not supported."); } if (result == null) { return(2); } results.Add(result); logger.LogDebug($"Finshed '{file}'"); } if (options.Manifest != null) { using (var manifestFs = File.Open(options.Manifest, FileMode.Create)) { logger.LogInformation($"Writing manifest to {options.Manifest}"); ManifestWriter.WriteManifest(results, manifestFs); } } return(0); }