private static string GetFormattedVariable(string variableName, PositionalComponent instance, ComponentDescription description) { string propertyName = variableName.Substring(1); return(description.Properties.First(x => x.Name == propertyName) .Format(instance, description, description.GetProperty(instance, propertyName))); }
public virtual void RenderComponent(PositionalComponent component, IDrawingContext drawingContext, bool ignoreOffset = true) { var description = descriptionLookup.GetDescription(component.Type); if (description == null) { throw new ApplicationException($"No component description available for {component.Type}"); } var flags = description.DetermineFlags(component); var layoutOptions = new LayoutOptions { Absolute = !ignoreOffset, AlignMiddle = (flags & FlagOptions.MiddleMustAlign) == FlagOptions.MiddleMustAlign, GridSize = 10.0 }; var layoutContext = new LayoutContext(layoutOptions, p => GetFormattedVariable(p, component, description)); foreach (var renderDescription in description.RenderDescriptions) { if (renderDescription.Conditions.IsMet(component, description)) { renderDescription.Render(component, layoutContext, drawingContext); } } }
public void Render(PositionalComponent component, LayoutContext layoutContext, IDrawingContext dc) { foreach (IRenderCommand command in Value) { command.Render(component.Layout, layoutContext, dc); } }
public ElementDrawingVisual(ICircuitRenderer renderer, PositionalComponent circuitElement) { this.renderer = renderer; CircuitElement = circuitElement; ResizeHandleBrush = Brushes.MediumOrchid; Offset = circuitElement.Layout.Location.ToWinVector(); UpdateVisual(); }
public bool IsMet(PositionalComponent component, ComponentDescription description) { if (Type == ConditionType.Empty) { return(true); } if (Type == ConditionType.State) { if (VariableName.ToLower() == "horizontal") { if (Comparison == ConditionComparison.Truthy || Comparison == ConditionComparison.Equal) { return((component.Layout.Orientation == Orientation.Horizontal) == CompareTo.BooleanValue); } return((component.Layout.Orientation == Orientation.Horizontal) != CompareTo.BooleanValue); } } else { var propertyValue = description.GetProperty(component, VariableName); if (Comparison == ConditionComparison.Truthy) { return(propertyValue.IsTruthy()); } if (Comparison == ConditionComparison.Falsy) { return(!propertyValue.IsTruthy()); } int cv = propertyValue.CompareTo(CompareTo); switch (Comparison) { case ConditionComparison.Equal: return(cv == 0); case ConditionComparison.Greater: return(cv == 1); case ConditionComparison.GreaterOrEqual: return(cv >= 0); case ConditionComparison.Less: return(cv == -1); case ConditionComparison.LessOrEqual: return(cv <= 0); case ConditionComparison.NotEqual: return(cv != 0); } } return(false); }
public void OnMouseDown(Point mousePosition, EditorOperationHitTest hitTest, IEditorOperationalContext context) { initialMousePosition = mousePosition; element = new PositionalComponent(context.PlaceType.Type, context.PlaceType.Configuration, initialMousePosition.ToCdPoint()); SizeComponent(element, initialMousePosition.ToCdPoint(), initialMousePosition.ToCdPoint(), context.GridSize); SetDefaultProperties(element); SetConfigurationProperties(element); context.AddElement(element); }
public string Format(PositionalComponent component, ComponentDescription description, PropertyValue value) { foreach (ComponentPropertyFormat formatRule in FormatRules) { if (formatRule.Conditions.IsMet(component, description)) { return(formatRule.Format(component, description)); } } return(value.ToString()); }
private IList <ConnectionPoint> GetConnectionPoints(PositionalComponent component, LayoutOptions layoutOptions) { var description = descriptionLookup.GetDescription(component.Type); if (description == null) { throw new ApplicationException($"No component description available for {component.Type}"); } return(connectionPositioner.PositionConnections(component, description, layoutOptions)); }
public FlagOptions DetermineFlags(PositionalComponent component) { FlagOptions returnOptions = FlagOptions.None; foreach (Conditional <FlagOptions> option in Flags) { if (option.Conditions.IsMet(component, this)) { returnOptions |= option.Value; } } return(returnOptions); }
public bool IsMet(PositionalComponent component, ComponentDescription description) { if (this.Operator == ConditionOperator.AND) { return(Left.IsMet(component, description) && Right.IsMet(component, description)); } else if (this.Operator == ConditionOperator.OR) { return(Left.IsMet(component, description) || Right.IsMet(component, description)); } else { return(false); // Unknown operator } }
public void LayoutHorizontal() { var instance = new PositionalComponent(new ComponentType(ComponentType.UnknownCollection, "test")); instance.Layout.Size = 100; var connectionGroups = new[] { new ConnectionGroup(ConditionTree.Empty, new[] { new ConnectionDescription(new ComponentPoint(ComponentPosition.Start, ComponentPosition.Start, new Vector()), new ComponentPoint(ComponentPosition.Start, ComponentPosition.Start, new Vector(45, 0)), ConnectionEdge.Start, "Connection1"), }) }; var description = new ComponentDescription { Connections = connectionGroups }; var positioned = positioner.PositionConnections(instance, description, new LayoutOptions { GridSize = 10.0 }); Assert.That(positioned, Has.Count.EqualTo(5)); // First is edge Assert.That(positioned[0].Location, Is.EqualTo(new Point(0, 0))); Assert.That(positioned[0].Flags, Is.EqualTo(ConnectionFlags.Horizontal | ConnectionFlags.Edge)); // Remaining are not edges for (int i = 1; i < positioned.Count; i++) { var c = positioned[i]; Assert.That(c.Location, Is.EqualTo(new Point(i * 10, 0))); Assert.That(c.Flags, Is.EqualTo(ConnectionFlags.Horizontal)); } }
public CircuitDocument OpenDocument(Stream input) { var document = reader.ReadCircuit(input); // Convert wires to components var wireType = new ComponentType(Guid.Parse("6353882b-5208-4f88-a83b-2271cc82b94f"), ComponentTypeCollection.Unknown, new ComponentTypeCollectionItem("wire"), "Wire", new PropertyName[0], new[] { new ConnectionName("#") }, new ComponentConfiguration[0]); var wires = document.Wires.ToList(); foreach (var wire in wires) { document.Elements.Remove(wire); var component = new PositionalComponent(wireType, null, wire.Layout.Location); component.Layout.Size = wire.Layout.Size; component.Layout.Orientation = wire.Layout.Orientation; document.Elements.Add(component); } return(document); }
public CircuitDocument OpenDocument(Stream input) { var document = reader.ReadCircuit(input); // Convert wires to components var wireType = new ComponentType(Guid.Parse("6353882b-5208-4f88-a83b-2271cc82b94f"), "Wire"); var wires = document.Wires.ToList(); foreach (var wire in wires) { document.Elements.Remove(wire); var component = new PositionalComponent(wireType, null, wire.Layout.Location); component.Layout.Size = wire.Layout.Size; component.Layout.Orientation = wire.Layout.Orientation; document.Elements.Add(component); } return(document); }
private bool MatchesSelection(PositionalComponent element) { return(element != null && element == selectionElement && element.Layout.Location == initialLocation.Value && element.Layout.Size == initialSize.Value); }
public void OnMouseDown(Point mousePosition, EditorOperationHitTest hitTest, IEditorOperationalContext context) { selectionElement = hitTest?.Element; initialLocation = selectionElement?.Layout.Location; initialSize = selectionElement?.Layout.Size; }
public void Abort() { element = null; }
public void ReadElements(CircuitDiagramDocument document, XElement elements, ReaderContext context) { var components = from el in elements.Elements() where el.Name == Ns.Document + "c" select el; foreach (var componentElement in components) { var typeAttr = componentElement.Attribute("tp"); if (typeAttr == null) { context.Log(ReaderErrorCodes.MissingRequiredAttribute, componentElement, "tp"); continue; } var componentType = context.GetComponentType(ParseType(typeAttr.Value)); if (componentType == null) { context.Log(ReaderErrorCodes.UnknownComponentType, typeAttr, typeAttr.Value); continue; } Component component; if (componentElement.Attribute("x") != null) { component = new PositionalComponent(componentType, new LayoutInformation()); // Layout ReadLayout((PositionalComponent)component, componentElement, context); } else { component = new Component(componentType); } // Properties var propertiesElement = componentElement.Elements(Ns.Document + "prs").SingleOrDefault(); var properties = propertiesElement != null ? from el in propertiesElement.Elements() where el.Name == Ns.Document + "p" select el : new XElement[0]; foreach (var propertyElement in properties) { var keyAttr = propertyElement.Attribute("k"); if (keyAttr == null) { context.Log(ReaderErrorCodes.MissingRequiredAttribute, propertyElement, "k"); continue; } var valueAttr = propertyElement.Attribute("v"); if (valueAttr == null) { context.Log(ReaderErrorCodes.MissingRequiredAttribute, propertyElement, "v"); continue; } component.Properties[keyAttr.Value] = PropertyValue.Dynamic(valueAttr.Value); } // Connections var connectionsElement = componentElement.Elements(Ns.Document + "cns").SingleOrDefault(); var connections = connectionsElement != null ? from el in connectionsElement.Elements() where el.Name == Ns.Document + "cn" select el : new XElement[0]; foreach (var connectionElement in connections) { var idAttr = connectionElement.Attribute("id"); if (idAttr == null) { context.Log(ReaderErrorCodes.MissingRequiredAttribute, connectionElement, "id"); continue; } var pointAttr = connectionElement.Attribute("pt"); if (pointAttr == null) { context.Log(ReaderErrorCodes.MissingRequiredAttribute, connectionElement, "pt"); continue; } var namedConnection = component.Connections.FirstOrDefault(x => x.Value.Name.Value == pointAttr.Value).Value ?? new NamedConnection(pointAttr.Value, component); context.ApplyConnection(idAttr.Value, namedConnection); } document.Elements.Add(component); } var wires = from el in elements.Elements() where el.Name == Ns.Document + "w" select el; foreach (var wireElement in wires) { var wire = new Wire(new LayoutInformation()); ReadLayout(wire, wireElement, context); document.Elements.Add(wire); } }
private static Wire ComponentToWire(PositionalComponent c) { return(new Wire(c.Layout)); }
private IList <ConnectionPoint> GetConnectionPoints(PositionalComponent component, LayoutOptions layoutOptions) { var description = descriptionLookup.GetDescription(component.Type); return(connectionPositioner.PositionConnections(component, description, layoutOptions)); }
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 IList <ConnectionPoint> PositionConnections(PositionalComponent instance, ComponentDescription description, LayoutOptions layoutOptions) { var connections = new List <ConnectionPoint>(); foreach (ConnectionGroup group in description.Connections) { if (group.Conditions.IsMet(instance, description)) { foreach (ConnectionDescription connectionDescription in group.Value) { Point start = connectionDescription.Start.Resolve(instance.Layout, layoutOptions); start = start.WithNewX(Math.Ceiling(start.X / layoutOptions.GridSize) * layoutOptions.GridSize); start = start.WithNewY(Math.Ceiling(start.Y / layoutOptions.GridSize) * layoutOptions.GridSize); Point end = connectionDescription.End.Resolve(instance.Layout, layoutOptions); end = end.WithNewX(Math.Floor(end.X / layoutOptions.GridSize) * layoutOptions.GridSize); end = end.WithNewY(Math.Floor(end.Y / layoutOptions.GridSize) * layoutOptions.GridSize); // Reverse if in the wrong order bool reversed = false; if ((start.X == end.X && end.Y < start.Y) || (start.Y == end.Y && end.X < start.X)) { Point temp = start; start = end; end = temp; reversed = true; } if (connectionDescription.Start.Resolve(instance.Layout, layoutOptions).X == connectionDescription.End.Resolve(instance.Layout, layoutOptions).X) // use original coordinates to check correctly when single point { for (double i = start.Y; i <= end.Y; i += layoutOptions.GridSize) { var flags = ConnectionFlags.Vertical; if (!reversed) { if (i == start.Y && (connectionDescription.Edge == ConnectionEdge.Start || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } else if (i == end.Y && (connectionDescription.Edge == ConnectionEdge.End || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } } else if (instance.Layout.Orientation == Orientation.Vertical) { if (i == start.Y && (connectionDescription.Edge == ConnectionEdge.End || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } else if (i == end.Y && (connectionDescription.Edge == ConnectionEdge.Start || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } } var location = new Point(instance.Layout.Location.X + start.X, instance.Layout.Location.Y + i); connections.Add(new ConnectionPoint(location, connectionDescription.Name, flags)); } } else if (start.Y == end.Y) { for (double i = start.X; i <= end.X; i += layoutOptions.GridSize) { ConnectionFlags flags = ConnectionFlags.Horizontal; if (!reversed) { if (i == start.X && (connectionDescription.Edge == ConnectionEdge.Start || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } else if (i == end.X && (connectionDescription.Edge == ConnectionEdge.End || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } } else if (instance.Layout.Orientation == Orientation.Horizontal && reversed) { if (i == start.X && (connectionDescription.Edge == ConnectionEdge.End || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } else if (i == end.X && (connectionDescription.Edge == ConnectionEdge.Start || connectionDescription.Edge == ConnectionEdge.Both)) { flags |= ConnectionFlags.Edge; } } var location = new Point(instance.Layout.Location.X + i, instance.Layout.Location.Y + start.Y); connections.Add(new ConnectionPoint(location, connectionDescription.Name, flags)); } } } } } return(connections); }
protected void SizeComponent(PositionalComponent component, Primitives.Point start, Primitives.Point end, double gridSize) { // reverse points if necessary Primitives.Point newStart = start; Primitives.Point newEnd = end; bool switched = false; if (start.X < end.X) { newStart = end; newEnd = start; switched = true; } if (true) // snap to grid { if (Math.IEEERemainder(newStart.X, 20d) != 0) { newStart = newStart.WithNewX(newStart.SnapToGrid(gridSize).X); } if (Math.IEEERemainder(newStart.Y, 20d) != 0) { newStart = newStart.WithNewY(newStart.SnapToGrid(gridSize).Y); } if (Math.IEEERemainder(newEnd.X, 20d) != 0) { newEnd = newEnd.WithNewX(newEnd.SnapToGrid(gridSize).X); } if (Math.IEEERemainder(newEnd.Y, 20d) != 0) { newEnd = newEnd.WithNewY(newEnd.SnapToGrid(gridSize).Y); } } if (true) // snap to horizontal or vertical { double height = Math.Max(newStart.Y, newEnd.Y) - Math.Min(newStart.Y, newEnd.Y); double length = Math.Sqrt(Math.Pow(newEnd.X - newStart.X, 2d) + Math.Pow(newEnd.Y - newStart.Y, 2d)); double bearing = Math.Acos(height / length) * (180 / Math.PI); if (bearing <= 45 && switched) { newStart = newStart.WithNewX(newEnd.X); } else if (bearing <= 45 && !switched) { newEnd = newEnd.WithNewX(newStart.X); } else if (bearing > 45 && switched) { newStart = newStart.WithNewY(newEnd.Y); } else { newEnd = newEnd.WithNewY(newStart.Y); } } if (newStart.X > newEnd.X || newStart.Y > newEnd.Y) { component.Layout.Location = new Primitives.Point(newEnd.X, newEnd.Y); if (newStart.X == newEnd.X) { component.Layout.Size = newStart.Y - newEnd.Y; component.Layout.Orientation = Orientation.Vertical; } else { component.Layout.Size = newStart.X - newEnd.X; component.Layout.Orientation = Orientation.Horizontal; } } else { component.Layout.Location = new Primitives.Point(newStart.X, newStart.Y); if (newStart.X == newEnd.X) { component.Layout.Size = newEnd.Y - newStart.Y; component.Layout.Orientation = Orientation.Vertical; } else { component.Layout.Size = newEnd.X - newStart.X; component.Layout.Orientation = Orientation.Horizontal; } } var description = descriptionLookup.GetDescription(component.Type); //FlagOptions flagOptions = ApplyFlags(component); //if ((flagOptions & FlagOptions.HorizontalOnly) == FlagOptions.HorizontalOnly && component.Layout.Orientation == Orientation.Vertical) //{ // component.Layout.Orientation = Orientation.Horizontal; // component.Layout.Size = component.Layout.Description.MinSize; //} //else if ((flagOptions & FlagOptions.VerticalOnly) == FlagOptions.VerticalOnly && component.Layout.Orientation == Orientation.Horizontal) //{ // component.Layout.Orientation = Orientation.Vertical; // component.Layout.Size = component.Layout.Description.MinSize; //} double minAllowedSize = Math.Max(description.MinSize, gridSize); if (component.Layout.Size < minAllowedSize) { component.Layout.Size = minAllowedSize; } }
private static void RenderDebugLayout( SkiaDrawingContext skiaContext, PositionalComponent component, ComponentDescription desc, Vector translationOffset) { var layoutOptions = new LayoutOptions { AlignMiddle = (desc.DetermineFlags(component) & FlagOptions.MiddleMustAlign) == FlagOptions.MiddleMustAlign, GridSize = 10.0 }; skiaContext.Mutate(canvas => { canvas.Save(); canvas.Translate((float)translationOffset.X, (float)translationOffset.Y); var connectionDebugPaint = new SKPaint { Color = SKColors.CornflowerBlue.WithAlpha(150), StrokeWidth = 1.0f, FilterQuality = SKFilterQuality.High, }; var connectionPositioner = new ConnectionPositioner(); var connectionPoints = connectionPositioner.PositionConnections(component, desc, layoutOptions); foreach (var connection in connectionPoints) { canvas.DrawLine( (float)connection.Location.X - 4, (float)connection.Location.Y - 4, (float)connection.Location.X + 4, (float)connection.Location.Y + 4, connectionDebugPaint); canvas.DrawLine( (float)connection.Location.X + 4, (float)connection.Location.Y - 4, (float)connection.Location.X - 4, (float)connection.Location.Y + 4, connectionDebugPaint); if (connection.Orientation == Orientation.Horizontal) { if (connection.IsEdge) { canvas.DrawLine( (float)connection.Location.X, (float)connection.Location.Y - 20, (float)connection.Location.X, (float)connection.Location.Y + 20, connectionDebugPaint); } else if (connection.Location.X % 20.0 == 0.0) { canvas.DrawLine( (float)connection.Location.X, (float)connection.Location.Y - 10, (float)connection.Location.X, (float)connection.Location.Y, connectionDebugPaint); } else { canvas.DrawLine( (float)connection.Location.X, (float)connection.Location.Y, (float)connection.Location.X, (float)connection.Location.Y + 10, connectionDebugPaint); } } else { if (connection.IsEdge) { canvas.DrawLine( (float)connection.Location.X - 20, (float)connection.Location.Y, (float)connection.Location.X + 20, (float)connection.Location.Y, connectionDebugPaint); } else if (connection.Location.Y % 20.0 == 0.0) { canvas.DrawLine( (float)connection.Location.X - 10, (float)connection.Location.Y, (float)connection.Location.X, (float)connection.Location.Y, connectionDebugPaint); } else { canvas.DrawLine( (float)connection.Location.X, (float)connection.Location.Y, (float)connection.Location.X + 10, (float)connection.Location.Y, connectionDebugPaint); } } } // Start and end points var paint = new SKPaint { Color = SKColors.CornflowerBlue, IsAntialias = true, Style = SKPaintStyle.StrokeAndFill, StrokeWidth = 2f, StrokeCap = SKStrokeCap.Square, }; canvas.DrawOval(component.Layout.Location.ToSkPoint(), new SKSize(2f, 2f), paint); var endOffset = new Vector( component.Layout.Orientation == Orientation.Horizontal ? component.Layout.Size : 0.0, component.Layout.Orientation == Orientation.Vertical ? component.Layout.Size : 0.0); canvas.DrawOval(component.Layout.Location.Add(endOffset).ToSkPoint(), new SKSize(2f, 2f), paint); canvas.Restore(); }); }
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); }