public SvgPoint(string x, string y) { TypeConverter converter = TypeDescriptor.GetConverter(typeof(SvgUnit)); this.x = (SvgUnit)converter.ConvertFrom(x); this.y = (SvgUnit)converter.ConvertFrom(y); }
/// <summary> /// Initializes a new instance of the <see cref="SvgRadialGradientServer"/> class. /// </summary> public SvgRadialGradientServer() { //Apply default values of 50% to cX,cY and r CenterX = new SvgUnit(SvgUnitType.Percentage, 50); CenterY = new SvgUnit(SvgUnitType.Percentage, 50); Radius = new SvgUnit(SvgUnitType.Percentage, 50); }
/// <summary> /// Initializes a new instance of the <see cref="SvgPatternServer"/> class. /// </summary> public SvgPatternServer() { this._x = new SvgUnit(0.0f); this._y = new SvgUnit(0.0f); this._width = new SvgUnit(0.0f); this._height = new SvgUnit(0.0f); }
public SvgLinearGradientServer() { this._x1 = new SvgUnit(0.0f); this._y1 = new SvgUnit(0.0f); this._x2 = new SvgUnit(0.0f); this._y2 = new SvgUnit(0.0f); }
/// <summary> /// Initializes a new instance of the <see cref="SvgGradientStop"/> class. /// </summary> public SvgGradientStop() { this._offset = new SvgUnit(0.0f); this._colour = Color.Transparent; this._opacity = 1.0f; }
/// <summary> /// Initializes a new instance of the <see cref="SvgCircle"/> class. /// </summary> public SvgCircle() { CenterX = new SvgUnit(0.0f); CenterY = new SvgUnit(0.0f); }
protected SvgUnit NormalizeUnit(SvgUnit orig) { return(orig.Type == SvgUnitType.Percentage && GradientUnits == SvgCoordinateUnits.ObjectBoundingBox ? new SvgUnit(SvgUnitType.User, orig.Value / 100f) : orig); }
/// <summary> /// Initializes a new instance of the <see cref="SvgText"/> class. /// </summary> public SvgText() { this._font = new Font(new FontFamily("Times New Roman"), 1.0f); this._fontSize = new SvgUnit(0.0f); }
public static System.Drawing.PointF GetDevicePointOffset(SvgUnit x, SvgUnit y, ISvgRenderer renderer, SvgElement owner) { return new System.Drawing.PointF(x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner), y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner)); }
public bool Equals(SvgUnit other) { return(this._type == other._type && (this._value == other._value)); }
/// <summary> /// Initializes a new instance of the <see cref="SvgText"/> class. /// </summary> public SvgText() { this._fontFamily = DefaultFontFamily; this._fontSize = new SvgUnit(0.0f); }
public SvgPoint(SvgUnit x, SvgUnit y) { this.x = x; this.y = y; }
public Vector2 ToDeviceValue(ISvgRenderer renderer, SvgElement owner) { return(SvgUnit.GetDevicePoint(this.X, this.Y, renderer, owner)); }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> public override GraphicsPath Path(ISvgRenderer renderer) { if (_path == null || IsPathDirty) { // If the corners aren't to be rounded just create a rectangle if (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f) { var rectangle = new RectangleF(Location.ToDeviceValue(renderer, this), SvgUnit.GetDeviceSize(this.Width, this.Height, renderer, this)); _path = new GraphicsPath(); _path.StartFigure(); _path.AddRectangle(rectangle); _path.CloseFigure(); } else { _path = new GraphicsPath(); var arcBounds = new RectangleF(); var lineStart = new PointF(); var lineEnd = new PointF(); var width = Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); var height = Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); var rx = Math.Min(CornerRadiusX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) * 2, width); var ry = Math.Min(CornerRadiusY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) * 2, height); var location = Location.ToDeviceValue(renderer, this); // Start _path.StartFigure(); // Add first arc arcBounds.Location = location; arcBounds.Width = rx; arcBounds.Height = ry; _path.AddArc(arcBounds, 180, 90); // Add first line lineStart.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineStart.Y = location.Y; lineEnd.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add second arc arcBounds.Location = new PointF(location.X + width - rx, location.Y); _path.AddArc(arcBounds, 270, 90); // Add second line lineStart.X = location.X + width; lineStart.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(location.X + width - rx, location.Y + height - ry); _path.AddArc(arcBounds, 0, 90); // Add third line lineStart.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineStart.Y = location.Y + height; lineEnd.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(location.X, location.Y + height - ry); _path.AddArc(arcBounds, 90, 90); // Add fourth line lineStart.X = location.X; lineStart.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Close _path.CloseFigure(); } IsPathDirty = false; } return(_path); }
public TrackView(TLTrackBase track, TimelineView tv, RulerView rv) : base(track, tv) { Model = track; Parent = tv; FRuler = rv; MainGroup.Transforms = new SvgTransformCollection(); MainGroup.Transforms.Add(new SvgTranslate(0, 0)); var width = new SvgUnit(SvgUnitType.Percentage, 100); Label.FontSize = 12; Label.X = 5; Label.Y = Label.FontSize; Label.Text = Model.Label.Value; Label.ID = "label"; Label.MouseDown += Background_MouseDown; Label.MouseUp += Background_MouseUp; Label.CustomAttributes["class"] = "trackfont"; SizeBarDragRect.FillOpacity = 0.3f; SizeBarDragRect.Visible = false; SizeBarDragRect.CustomAttributes["pointer-events"] = "none"; Background.Width = width; Background.Height = 1; // this is the value range, not the actual track size Background.ID ="bg"; ClipRect.Width = width; ClipRect.Height = Background.Height; ClipRect.ID = "ClipRect"; //document roots id is "svg". this is where the trackclips are added to TrackClipPath.ID = "svg_clip" + IDGenerator.NewID; TrackClipPath.Children.Add(ClipRect); TrackGroup.ID = "Clip"; TrackGroup.Transforms = new SvgTransformCollection(); TrackGroup.Transforms.Add(new SvgScale(1, 1)); var uri = new Uri("url(#" + TrackClipPath.ID + ")", UriKind.Relative); TrackGroup.ClipPath = uri; PanZoomGroup.ID = "PanZoom"; PanZoomGroup.Transforms = new SvgTransformCollection(); PanZoomGroup.Transforms.Add(FRuler.PanZoomMatrix); //pan/zoom PanZoomGroup.Transforms.Add(new SvgTranslate(0)); //min/max SizeBar.Width = width; SizeBar.Height = 3; SizeBar.ID = "SizeBar"; SizeBar.CustomAttributes["class"] = "sizebar"; SizeBar.Y = Background.Height.Value; //register event handlers Background.MouseDown += Background_MouseDown; Background.MouseUp += Background_MouseUp; Background.MouseMove += Background_MouseMove; SizeBar.MouseDown += Background_MouseDown; SizeBar.MouseMove += Background_MouseMove; SizeBar.MouseUp += Background_MouseUp; CreateTrackMenu(); CreateKeyframeMenu(); }
/// <summary> /// Initializes a new instance of the <see cref="SvgRectangle"/> class. /// </summary> public SvgRectangle() { _width = new SvgUnit(0.0f); _height = new SvgUnit(0.0f); }
private SvgUnit FixY(SvgUnit OldY) { float newvalue = (OldY.Value > CentreY) ? OldY.Value + AddY : OldY.Value - AddY; return new SvgUnit(newvalue); }
public static System.Drawing.PointF GetDevicePointOffset(SvgUnit x, SvgUnit y, ISvgRenderer renderer, SvgElement owner) { return(new System.Drawing.PointF(x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner), y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner))); }
public bool Equals(SvgUnit other) { return this._type == other._type && (this._value == other._value); }
public static System.Drawing.SizeF GetDeviceSize(SvgUnit width, SvgUnit height, ISvgRenderer renderer, SvgElement owner) { return(new System.Drawing.SizeF(width.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner), height.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner))); }
/// <summary> /// Initializes a new instance of the <see cref="SvgFragment"/> class. /// </summary> public SvgFragment() { this._height = new SvgUnit(SvgUnitType.Percentage, 100.0f); this._width = 1000.0f; this.ViewBox = SvgViewBox.Empty; }
private SvgUnit NormalizeUnit(SvgUnit orig) { return(orig.Type == SvgUnitType.Percentage && this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox ? new SvgUnit(SvgUnitType.User, orig.Value / 100) : orig); }
public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke = false) { LoadStops(renderingElement); if (this.Stops.Count < 1) { return(null); } if (this.Stops.Count == 1) { var stopColor = this.Stops[0].GetColor(renderingElement); int alpha = (int)((opacity * (stopColor.A / 255.0f)) * 255); Color colour = System.Drawing.Color.FromArgb(alpha, stopColor); return(new SolidBrush(colour)); } try { if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { renderer.SetBoundable(renderingElement); } var points = new PointF[] { SvgUnit.GetDevicePoint(NormalizeUnit(this.X1), NormalizeUnit(this.Y1), renderer, this), SvgUnit.GetDevicePoint(NormalizeUnit(this.X2), NormalizeUnit(this.Y2), renderer, this) }; var bounds = renderer.GetBoundable().Bounds; if (bounds.Width <= 0 || bounds.Height <= 0 || ((points[0].X == points[1].X) && (points[0].Y == points[1].Y))) { if (this.GetCallback != null) { return(GetCallback().GetBrush(renderingElement, renderer, opacity, forStroke)); } return(null); } using (var transform = EffectiveGradientTransform) { var midPoint = new PointF((points[0].X + points[1].X) / 2, (points[0].Y + points[1].Y) / 2); transform.Translate(bounds.X, bounds.Y, MatrixOrder.Prepend); if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { // Transform a normal (i.e. perpendicular line) according to the transform transform.Scale(bounds.Width, bounds.Height, MatrixOrder.Prepend); transform.RotateAt(-90.0f, midPoint, MatrixOrder.Prepend); } transform.TransformPoints(points); } if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { // Transform the normal line back to a line such that the gradient still starts in the correct corners, but // has the proper normal vector based on the transforms. If you work out the geometry, these formulas should work. var midPoint = new PointF((points[0].X + points[1].X) / 2, (points[0].Y + points[1].Y) / 2); var dy = (points[1].Y - points[0].Y); var dx = (points[1].X - points[0].X); var x2 = points[0].X; var y2 = points[1].Y; if (Math.Round(dx, 4) == 0) { points[0] = new PointF(midPoint.X + dy / 2 * bounds.Width / bounds.Height, midPoint.Y); points[1] = new PointF(midPoint.X - dy / 2 * bounds.Width / bounds.Height, midPoint.Y); } else if (Math.Round(dy, 4) == 0) { points[0] = new PointF(midPoint.X, midPoint.Y - dx / 2 * bounds.Height / bounds.Width); points[1] = new PointF(midPoint.X, midPoint.Y + dx / 2 * bounds.Height / bounds.Width);; } else { var startX = (float)((dy * dx * (midPoint.Y - y2) + Math.Pow(dx, 2) * midPoint.X + Math.Pow(dy, 2) * x2) / (Math.Pow(dx, 2) + Math.Pow(dy, 2))); var startY = dy * (startX - x2) / dx + y2; points[0] = new PointF(startX, startY); points[1] = new PointF(midPoint.X + (midPoint.X - startX), midPoint.Y + (midPoint.Y - startY)); } } var effectiveStart = points[0]; var effectiveEnd = points[1]; if (PointsToMove(renderingElement, points[0], points[1]) > LinePoints.None) { var expansion = ExpandGradient(renderingElement, points[0], points[1]); effectiveStart = expansion.StartPoint; effectiveEnd = expansion.EndPoint; } var result = new LinearGradientBrush(effectiveStart, effectiveEnd, System.Drawing.Color.Transparent, System.Drawing.Color.Transparent) { InterpolationColors = CalculateColorBlend(renderer, opacity, points[0], effectiveStart, points[1], effectiveEnd), WrapMode = WrapMode.TileFlipX }; return(result); } finally { if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { renderer.PopBoundable(); } } }
/// <summary> /// Initializes a new instance of the <see cref="SvgImage"/> class. /// </summary> public SvgImage() { Width = new SvgUnit(0.0f); Height = new SvgUnit(0.0f); }
/// <summary> /// Initializes a new instance of the <see cref="SvgGradientStop"/> class. /// </summary> public SvgGradientStop() { this._offset = new SvgUnit(0.0f); }
/// <summary> /// Initializes a new instance of the <see cref="SvgGradientStop"/> class. /// </summary> /// <param name="offset">The offset.</param> /// <param name="colour">The colour.</param> public SvgGradientStop(SvgUnit offset, Color colour) { this._offset = offset; this._colour = colour; this._opacity = 1.0f; }
/// <summary> /// Initializes a new instance of the <see cref="SvgGradientStop"/> class. /// </summary> /// <param name="offset">The offset.</param> /// <param name="colour">The colour.</param> public SvgGradientStop(SvgUnit offset, Color colour) { this._offset = offset; }
public RulerView(TLRuler ruler, TimelineView tv) : base(ruler, tv) { Model = ruler; Parent = tv; PanZoomMatrix = new SvgMatrix(FView.Elements.ToList()); MainGroup.Transforms = new SvgTransformCollection(); MainGroup.Transforms.Add(new SvgTranslate(0, 0)); var width = new SvgUnit(SvgUnitType.Percentage, 100); Background.Width = width; Background.Height = 25; Background.ID = "bg"; Background.CustomAttributes["class"] = "ruler"; //register event handlers Background.MouseDown += Background_MouseDown; Background.MouseUp += Background_MouseUp; Background.MouseMove += Background_MouseMove; var caller = Parent.Document.Mapper.Map<ISvgEventCaller>(); PlayButton = SvgDocumentWidget.Load(Path.Combine(TimelineView.ResourcePath, "PlayButton.svg"), caller, 2); StopButton = SvgDocumentWidget.Load(Path.Combine(TimelineView.ResourcePath, "StopButton.svg"), caller, 1); StopButton.X = 25; PlayButton.Click += PlayButton_Click; StopButton.Click += StopButton_Click; TimeCodeLabelBackground.Width = CLeftOffset; TimeCodeLabelBackground.Height = Background.Height; TimeCodeLabelBackground.CustomAttributes["class"] = "ruler"; TimeCodeLabelBackground.MouseDown += Background_MouseDown; TimeCodeLabel.FontSize = 20; TimeCodeLabel.X = 55; TimeCodeLabel.Y = TimeCodeLabel.FontSize; TimeCodeLabel.CustomAttributes["class"] = "time"; TimeCodeLabel.ID = Model.GetID() + "_label"; TimeCodeLabel.Text = "00:00:00:000"; TimeCodeLabel.CustomAttributes["class"] = "time"; TimeCodeLabel.MouseDown += Background_MouseDown; SizeBar.Width = Background.Width; SizeBar.Height = 10; SizeBar.ID = "SizeBar"; SizeBar.Y = Background.Height; SizeBar.MouseDown += Background_MouseDown; SizeBar.MouseMove += Background_MouseMove; SizeBar.MouseUp += Background_MouseUp; MouseTimeLabel.ID = "MouseTimeLabel"; MouseTimeLabel.Y = Height; MouseTimeLabel.FontSize = 14; ClipRect.Width = width; ClipRect.Height = Height; ClipRect.ID = "ClipRect"; //document roots id is "svg". this is where the trackclips are added to RulerClipPath.ID = "svg_clip" + IDGenerator.NewID; RulerClipPath.Children.Add(ClipRect); var uri = new Uri("url(#" + RulerClipPath.ID + ")", UriKind.Relative); MainGroup.ClipPath = uri; NumberGroup.ID = "Ticks"; NumberGroup.Transforms = new SvgTransformCollection(); NumberGroup.Transforms.Add(PanZoomMatrix); PanZoomGroup.ID = "PanZoom"; PanZoomGroup.Transforms = new SvgTransformCollection(); PanZoomGroup.Transforms.Add(PanZoomMatrix); for (int i=0; i<70; i++) { var num = new SvgText(i.ToString()); num.FontSize = 20; num.Y = num.FontSize; num.CustomAttributes["class"] = "time hair"; num.Transforms = new SvgTransformCollection(); num.Transforms.Add(new SvgTranslate(i)); num.Transforms.Add(new SvgScale(1/Timer.PPS, 1)); NumberGroup.Children.Add(num); } LoopRegion.ID = "LoopRegion"; LoopRegion.Y = Background.Height / 4; LoopRegion.Height = Background.Height / 2; LoopRegion.FillOpacity = 0.7f; LoopRegion.CustomAttributes["pointer-events"] = "fill"; LoopRegion.CustomAttributes["class"] = "loop"; LoopRegion.MouseDown += Background_MouseDown; LoopRegion.MouseUp += Parent.Default_MouseUp; LoopRegion.MouseMove += Parent.Default_MouseMove; PanZoomGroup.Children.Add(LoopRegion); LoopStart.ID = "LoopStart"; LoopStart.Width = 1/Timer.PPS * CHandlerWidth; LoopStart.Height = Background.Height; PanZoomGroup.Children.Add(LoopStart); LoopStart.MouseDown += Background_MouseDown; LoopStart.MouseUp += Parent.Default_MouseUp; LoopStart.MouseMove += Parent.Default_MouseMove; LoopStart.CustomAttributes["pointer-events"] = "fill"; LoopStart.CustomAttributes["class"] = "loopcap"; LoopEnd.ID = "LoopEnd"; LoopEnd.Width = 1/Timer.PPS * CHandlerWidth; LoopEnd.Height = Background.Height; PanZoomGroup.Children.Add(LoopEnd); LoopEnd.MouseDown += Background_MouseDown; LoopEnd.MouseUp += Parent.Default_MouseUp; LoopEnd.MouseMove += Parent.Default_MouseMove; LoopEnd.CustomAttributes["pointer-events"] = "fill"; LoopEnd.CustomAttributes["class"] = "loopcap"; CreateMenu(); //init scalings PanZoom(0, 0, 0); UpdateScene(); }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> public override GraphicsPath Path(ISvgRenderer renderer) { if ((_path == null || IsPathDirty) && base.StrokeWidth > 0) { float halfStrokeWidth = base.StrokeWidth / 2; // If it is to render, don't need to consider stroke if (renderer != null) { halfStrokeWidth = 0; this.IsPathDirty = false; } // If the corners aren't to be rounded just create a rectangle if (CornerRadiusX.Value == 0.0f && CornerRadiusY.Value == 0.0f) { // Starting location which take consideration of stroke width SvgPoint strokedLocation = new SvgPoint(Location.X - halfStrokeWidth, Location.Y - halfStrokeWidth); var rectangle = new RectangleF(strokedLocation.ToDeviceValue(renderer, this), SvgUnit.GetDeviceSize(this.Width + halfStrokeWidth * 2, this.Height + halfStrokeWidth * 2, renderer, this)); _path = new GraphicsPath(); _path.StartFigure(); _path.AddRectangle(rectangle); _path.CloseFigure(); } else { _path = new GraphicsPath(); var arcBounds = new RectangleF(); var lineStart = new PointF(); var lineEnd = new PointF(); var width = Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); var height = Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); var rx = Math.Min(CornerRadiusX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) * 2, width); var ry = Math.Min(CornerRadiusY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) * 2, height); var location = Location.ToDeviceValue(renderer, this); // Start _path.StartFigure(); // Add first arc arcBounds.Location = location; arcBounds.Width = rx; arcBounds.Height = ry; _path.AddArc(arcBounds, 180, 90); // Add first line lineStart.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineStart.Y = location.Y; lineEnd.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add second arc arcBounds.Location = new PointF(location.X + width - rx, location.Y); _path.AddArc(arcBounds, 270, 90); // Add second line lineStart.X = location.X + width; lineStart.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(location.X + width - rx, location.Y + height - ry); _path.AddArc(arcBounds, 0, 90); // Add third line lineStart.X = Math.Max(location.X + width - rx, location.X + width * 0.5f); lineStart.Y = location.Y + height; lineEnd.X = Math.Min(location.X + rx, location.X + width * 0.5f); lineEnd.Y = lineStart.Y; _path.AddLine(lineStart, lineEnd); // Add third arc arcBounds.Location = new PointF(location.X, location.Y + height - ry); _path.AddArc(arcBounds, 90, 90); // Add fourth line lineStart.X = location.X; lineStart.Y = Math.Max(location.Y + height - ry, location.Y + height * 0.5f); lineEnd.X = lineStart.X; lineEnd.Y = Math.Min(location.Y + ry, location.Y + height * 0.5f); _path.AddLine(lineStart, lineEnd); // Close _path.CloseFigure(); } } return(_path); }
public void DrawString(string value) { // Get any defined anchors var xAnchors = GetValues(value.Length, e => e._x, UnitRenderingType.HorizontalOffset); var yAnchors = GetValues(value.Length, e => e._y, UnitRenderingType.VerticalOffset); using (var font = this.Element.GetFont(this.Renderer)) { var fontBaselineHeight = font.Ascent(this.Renderer); PathStatistics pathStats = null; var pathScale = 1.0; if (BaselinePath != null) { pathStats = new PathStatistics(BaselinePath.PathData); if (_authorPathLength > 0) { pathScale = _authorPathLength / pathStats.TotalLength; } } // Get all of the offsets (explicit and defined by spacing) IList <float> xOffsets; IList <float> yOffsets; IList <float> rotations; float baselineShift = 0.0f; try { this.Renderer.SetBoundable(new FontBoundable(font, (float)(pathStats == null ? 1 : pathStats.TotalLength))); xOffsets = GetValues(value.Length, e => e._dx, UnitRenderingType.Horizontal); yOffsets = GetValues(value.Length, e => e._dy, UnitRenderingType.Vertical); if (StartOffsetAdjust != 0.0f) { if (xOffsets.Count < 1) { xOffsets.Add(StartOffsetAdjust); } else { xOffsets[0] += StartOffsetAdjust; } } if (this.Element.LetterSpacing.Value != 0.0f || this.Element.WordSpacing.Value != 0.0f || this.LetterSpacingAdjust != 0.0f) { var spacing = this.Element.LetterSpacing.ToDeviceValue(this.Renderer, UnitRenderingType.Horizontal, this.Element) + this.LetterSpacingAdjust; var wordSpacing = this.Element.WordSpacing.ToDeviceValue(this.Renderer, UnitRenderingType.Horizontal, this.Element); if (this.Parent == null && this.NumChars == 0 && xOffsets.Count < 1) { xOffsets.Add(0); } for (int i = (this.Parent == null && this.NumChars == 0 ? 1 : 0); i < value.Length; i++) { if (i >= xOffsets.Count) { xOffsets.Add(spacing + (char.IsWhiteSpace(value[i]) ? wordSpacing : 0)); } else { xOffsets[i] += spacing + (char.IsWhiteSpace(value[i]) ? wordSpacing : 0); } } } rotations = GetValues(value.Length, e => e._rotations); // Calculate Y-offset due to baseline shift. Don't inherit the value so that it is not accumulated multiple times. var baselineShiftText = this.Element.Attributes.GetAttribute <string>("baseline-shift"); switch (baselineShiftText) { case null: case "": case "baseline": case "inherit": // do nothing break; case "sub": baselineShift = new SvgUnit(SvgUnitType.Ex, 1).ToDeviceValue(this.Renderer, UnitRenderingType.Vertical, this.Element); break; case "super": baselineShift = -1 * new SvgUnit(SvgUnitType.Ex, 1).ToDeviceValue(this.Renderer, UnitRenderingType.Vertical, this.Element); break; default: var convert = new SvgUnitConverter(); var shiftUnit = (SvgUnit)convert.ConvertFromInvariantString(baselineShiftText); baselineShift = -1 * shiftUnit.ToDeviceValue(this.Renderer, UnitRenderingType.Vertical, this.Element); break; } if (baselineShift != 0.0f) { if (yOffsets.Any()) { yOffsets[0] += baselineShift; } else { yOffsets.Add(baselineShift); } } } finally { this.Renderer.PopBoundable(); } var xTextStart = Current.X; // NOTE: Assuming a horizontal left-to-right font // Render absolutely positioned items in the horizontal direction var yPos = Current.Y; for (int i = 0; i < xAnchors.Count - 1; i++) { FlushPath(); _xAnchor = xAnchors[i] + (xOffsets.Count > i ? xOffsets[i] : 0); EnsurePath(); yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0); xTextStart = xTextStart.Equals(Current.X) ? _xAnchor : xTextStart; DrawStringOnCurrPath(value[i].ToString(), font, new PointF(_xAnchor, yPos), fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault())); } // Render any remaining characters var renderChar = 0; var xPos = this.Current.X; if (xAnchors.Any()) { FlushPath(); renderChar = xAnchors.Count - 1; xPos = xAnchors.Last(); _xAnchor = xPos; } EnsurePath(); // Render individual characters as necessary var lastIndividualChar = renderChar + Math.Max(Math.Max(Math.Max(Math.Max(xOffsets.Count, yOffsets.Count), yAnchors.Count), rotations.Count) - renderChar - 1, 0); if (rotations.LastOrDefault() != 0.0f || pathStats != null) { lastIndividualChar = value.Length; } if (lastIndividualChar > renderChar) { var charBounds = font.MeasureCharacters(this.Renderer, value.Substring(renderChar, Math.Min(lastIndividualChar + 1, value.Length) - renderChar)); PointF pathPoint; float rotation; float halfWidth; for (int i = renderChar; i < lastIndividualChar; i++) { xPos += (float)pathScale * (xOffsets.Count > i ? xOffsets[i] : 0) + (charBounds[i - renderChar].X - (i == renderChar ? 0 : charBounds[i - renderChar - 1].X)); yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0); if (pathStats == null) { xTextStart = xTextStart.Equals(Current.X) ? xPos : xTextStart; DrawStringOnCurrPath(value[i].ToString(), font, new PointF(xPos, yPos), fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault())); } else { xPos = Math.Max(xPos, 0); halfWidth = charBounds[i - renderChar].Width / 2; if (pathStats.OffsetOnPath(xPos + halfWidth)) { pathStats.LocationAngleAtOffset(xPos + halfWidth, out pathPoint, out rotation); pathPoint = new PointF((float)(pathPoint.X - halfWidth * Math.Cos(rotation * Math.PI / 180) - (float)pathScale * yPos * Math.Sin(rotation * Math.PI / 180)), (float)(pathPoint.Y - halfWidth * Math.Sin(rotation * Math.PI / 180) + (float)pathScale * yPos * Math.Cos(rotation * Math.PI / 180))); xTextStart = xTextStart.Equals(Current.X) ? pathPoint.X : xTextStart; DrawStringOnCurrPath(value[i].ToString(), font, pathPoint, fontBaselineHeight, rotation); } } } // Add the kerning to the next character if (lastIndividualChar < value.Length) { xPos += charBounds[charBounds.Count - 1].X - charBounds[charBounds.Count - 2].X; } else { xPos += charBounds.Last().Width; } } // Render the string normally if (lastIndividualChar < value.Length) { xPos += (xOffsets.Count > lastIndividualChar ? xOffsets[lastIndividualChar] : 0); yPos = (yAnchors.Count > lastIndividualChar ? yAnchors[lastIndividualChar] : yPos) + (yOffsets.Count > lastIndividualChar ? yOffsets[lastIndividualChar] : 0); xTextStart = xTextStart.Equals(Current.X) ? xPos : xTextStart; DrawStringOnCurrPath(value.Substring(lastIndividualChar), font, new PointF(xPos, yPos), fontBaselineHeight, rotations.LastOrDefault()); var bounds = font.MeasureString(this.Renderer, value.Substring(lastIndividualChar)); xPos += bounds.Width; } NumChars += value.Length; // Undo any baseline shift. This is not persisted, unlike normal vertical offsets. this.Current = new PointF(xPos, yPos - baselineShift); this.TextBounds = new RectangleF(xTextStart, 0, this.Current.X - xTextStart, 0); } }
private SvgUnit FixX(SvgUnit OldX) { float newvalue = (OldX.Value > CentreX) ? OldX.Value + AddX : OldX.Value - AddX; return new SvgUnit(newvalue); }
/// <summary> /// Initializes a new instance of the <see cref="SvgUse"/> class. /// </summary> public SvgUse() { this.X = 0; this.Y = 0; }
public static System.Drawing.SizeF GetDeviceSize(SvgUnit width, SvgUnit height, ISvgRenderer renderer, SvgElement owner) { return new System.Drawing.SizeF(width.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner), height.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner)); }
private void DrawString(GraphicsPath path, SvgUnit x, SvgUnit y, SvgUnit dx, SvgUnit dy, Font font, float fontSize, string text) { PointF location = PointF.Empty; SizeF stringBounds; lock (_stringMeasure) { stringBounds = _stringMeasure.MeasureString(text, font); } float xToDevice = x.ToDeviceValue(this) + dx.ToDeviceValue(this); float yToDevice = y.ToDeviceValue(this, true) + dy.ToDeviceValue(this, true); // Minus FontSize because the x/y coords mark the bottom left, not bottom top. switch (this.TextAnchor) { case SvgTextAnchor.Start: location = new PointF(xToDevice, yToDevice - stringBounds.Height); break; case SvgTextAnchor.Middle: location = new PointF(xToDevice - (stringBounds.Width / 2), yToDevice - stringBounds.Height); break; case SvgTextAnchor.End: location = new PointF(xToDevice - stringBounds.Width, yToDevice - stringBounds.Height); break; } // No way to do letter-spacing or word-spacing, so do manually if (this.LetterSpacing.Value > 0.0f || this.WordSpacing.Value > 0.0f) { // Cut up into words, or just leave as required string[] words = (this.WordSpacing.Value > 0.0f) ? text.Split(' ') : new string[] { text }; float wordSpacing = this.WordSpacing.ToDeviceValue(this); float letterSpacing = this.LetterSpacing.ToDeviceValue(this); float start = this.X.ToDeviceValue(this); foreach (string word in words) { // Only do if there is line spacing, just write the word otherwise if (this.LetterSpacing.Value > 0.0f) { char[] characters = word.ToCharArray(); foreach (char currentCharacter in characters) { path.AddString(currentCharacter.ToString(), new FontFamily(this._fontFamily), (int)font.Style, fontSize, location, StringFormat.GenericTypographic); location = new PointF(path.GetBounds().Width + start + letterSpacing, location.Y); } } else { path.AddString(word, new FontFamily(this._fontFamily), (int)font.Style, fontSize, location, StringFormat.GenericTypographic); } // Move the location of the word to be written along location = new PointF(path.GetBounds().Width + start + wordSpacing, location.Y); } } else { if (!string.IsNullOrEmpty(text)) { path.AddString(text, new FontFamily(this._fontFamily), (int)font.Style, fontSize, location, StringFormat.GenericTypographic); } } }
public SvgCoordinateContext MapPoint(Point point, double rotation, SvgUnitType unitType) { if (point.Y < 0) { point.Y = Math.Abs(point.Y) - _offset.X; } else { point.Y = Height - point.Y; } var svgStartX = new SvgUnit(unitType, (float)point.X); var svgStartY = new SvgUnit(unitType, (float)point.Y); var context = new SvgCoordinateContext { X = svgStartX, Y = svgStartY, Rotation = new SvgRotate((float)-rotation, svgStartX, svgStartY) }; return context; }
public SvgRadialGradientServer() { CenterX = new SvgUnit(SvgUnitType.Percentage, 50F); CenterY = new SvgUnit(SvgUnitType.Percentage, 50F); Radius = new SvgUnit(SvgUnitType.Percentage, 50F); }
public void DrawString(string value) { // Get any defined anchors var xAnchors = GetValues(value.Length, e => e._x, UnitRenderingType.HorizontalOffset); var yAnchors = GetValues(value.Length, e => e._y, UnitRenderingType.VerticalOffset); using (var font = this.Element.GetFont(this.Renderer)) { var fontBaselineHeight = font.Ascent(this.Renderer); PathStatistics pathStats = null; var pathScale = 1.0; if (BaselinePath != null) { pathStats = new PathStatistics(BaselinePath.PathData); if (_authorPathLength > 0) pathScale = _authorPathLength / pathStats.TotalLength; } // Get all of the offsets (explicit and defined by spacing) IList<float> xOffsets; IList<float> yOffsets; IList<float> rotations; float baselineShift = 0.0f; try { this.Renderer.SetBoundable(new FontBoundable(font, (float)(pathStats == null ? 1 : pathStats.TotalLength))); xOffsets = GetValues(value.Length, e => e._dx, UnitRenderingType.Horizontal); yOffsets = GetValues(value.Length, e => e._dy, UnitRenderingType.Vertical); if (StartOffsetAdjust != 0.0f) { if (xOffsets.Count < 1) { xOffsets.Add(StartOffsetAdjust); } else { xOffsets[0] += StartOffsetAdjust; } } if (this.Element.LetterSpacing.Value != 0.0f || this.Element.WordSpacing.Value != 0.0f || this.LetterSpacingAdjust != 0.0f) { var spacing = this.Element.LetterSpacing.ToDeviceValue(this.Renderer, UnitRenderingType.Horizontal, this.Element) + this.LetterSpacingAdjust; var wordSpacing = this.Element.WordSpacing.ToDeviceValue(this.Renderer, UnitRenderingType.Horizontal, this.Element); if (this.Parent == null && this.NumChars == 0 && xOffsets.Count < 1) xOffsets.Add(0); for (int i = (this.Parent == null && this.NumChars == 0 ? 1 : 0); i < value.Length; i++) { if (i >= xOffsets.Count) { xOffsets.Add(spacing + (char.IsWhiteSpace(value[i]) ? wordSpacing : 0)); } else { xOffsets[i] += spacing + (char.IsWhiteSpace(value[i]) ? wordSpacing : 0); } } } rotations = GetValues(value.Length, e => e._rotations); // Calculate Y-offset due to baseline shift. Don't inherit the value so that it is not accumulated multiple times. var baselineShiftText = this.Element.Attributes.GetAttribute<string>("baseline-shift"); switch (baselineShiftText) { case null: case "": case "baseline": case "inherit": // do nothing break; case "sub": baselineShift = new SvgUnit(SvgUnitType.Ex, 1).ToDeviceValue(this.Renderer, UnitRenderingType.Vertical, this.Element); break; case "super": baselineShift = -1 * new SvgUnit(SvgUnitType.Ex, 1).ToDeviceValue(this.Renderer, UnitRenderingType.Vertical, this.Element); break; default: var convert = new SvgUnitConverter(); var shiftUnit = (SvgUnit)convert.ConvertFromInvariantString(baselineShiftText); baselineShift = -1 * shiftUnit.ToDeviceValue(this.Renderer, UnitRenderingType.Vertical, this.Element); break; } if (baselineShift != 0.0f) { if (yOffsets.Any()) { yOffsets[0] += baselineShift; } else { yOffsets.Add(baselineShift); } } } finally { this.Renderer.PopBoundable(); } // NOTE: Assuming a horizontal left-to-right font // Render absolutely positioned items in the horizontal direction var yPos = Current.Y; for (int i = 0; i < xAnchors.Count - 1; i++) { FlushPath(); _xAnchor = xAnchors[i] + (xOffsets.Count > i ? xOffsets[i] : 0); EnsurePath(); yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0); DrawStringOnCurrPath(value[i].ToString(), font, new PointF(_xAnchor, yPos), fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault())); } // Render any remaining characters var renderChar = 0; var xPos = this.Current.X; if (xAnchors.Any()) { FlushPath(); renderChar = xAnchors.Count - 1; xPos = xAnchors.Last(); _xAnchor = xPos; } EnsurePath(); // Render individual characters as necessary var lastIndividualChar = renderChar + Math.Max(Math.Max(Math.Max(Math.Max(xOffsets.Count, yOffsets.Count), yAnchors.Count), rotations.Count) - renderChar - 1, 0); if (rotations.LastOrDefault() != 0.0f || pathStats != null) lastIndividualChar = value.Length; if (lastIndividualChar > renderChar) { var charBounds = font.MeasureCharacters(this.Renderer, value.Substring(renderChar, Math.Min(lastIndividualChar + 1, value.Length) - renderChar)); PointF pathPoint; float rotation; float halfWidth; for (int i = renderChar; i < lastIndividualChar; i++) { xPos += (float)pathScale * (xOffsets.Count > i ? xOffsets[i] : 0) + (charBounds[i - renderChar].X - (i == renderChar ? 0 : charBounds[i - renderChar - 1].X)); yPos = (yAnchors.Count > i ? yAnchors[i] : yPos) + (yOffsets.Count > i ? yOffsets[i] : 0); if (pathStats == null) { DrawStringOnCurrPath(value[i].ToString(), font, new PointF(xPos, yPos), fontBaselineHeight, (rotations.Count > i ? rotations[i] : rotations.LastOrDefault())); } else { xPos = Math.Max(xPos, 0); halfWidth = charBounds[i - renderChar].Width / 2; if (pathStats.OffsetOnPath(xPos + halfWidth)) { pathStats.LocationAngleAtOffset(xPos + halfWidth, out pathPoint, out rotation); pathPoint = new PointF((float)(pathPoint.X - halfWidth * Math.Cos(rotation * Math.PI / 180) - (float)pathScale * yPos * Math.Sin(rotation * Math.PI / 180)), (float)(pathPoint.Y - halfWidth * Math.Sin(rotation * Math.PI / 180) + (float)pathScale * yPos * Math.Cos(rotation * Math.PI / 180))); DrawStringOnCurrPath(value[i].ToString(), font, pathPoint, fontBaselineHeight, rotation); } } } // Add the kerning to the next character if (lastIndividualChar < value.Length) { xPos += charBounds[charBounds.Count - 1].X - charBounds[charBounds.Count - 2].X; } else { xPos += charBounds.Last().Width; } } // Render the string normally if (lastIndividualChar < value.Length) { xPos += (xOffsets.Count > lastIndividualChar ? xOffsets[lastIndividualChar] : 0); yPos = (yAnchors.Count > lastIndividualChar ? yAnchors[lastIndividualChar] : yPos) + (yOffsets.Count > lastIndividualChar ? yOffsets[lastIndividualChar] : 0); DrawStringOnCurrPath(value.Substring(lastIndividualChar), font, new PointF(xPos, yPos), fontBaselineHeight, rotations.LastOrDefault()); var bounds = font.MeasureString(this.Renderer, value.Substring(lastIndividualChar)); xPos += bounds.Width; } NumChars += value.Length; // Undo any baseline shift. This is not persisted, unlike normal vertical offsets. this.Current = new PointF(xPos, yPos - baselineShift); } }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> public override GraphicsPath Path(ISvgRenderer renderer) { if (_path == null) { // Same size of rectangle can suffice to provide bounds of the image var rectangle = new RectangleF(Location.ToDeviceValue(renderer, this), SvgUnit.GetDeviceSize(Width, Height, renderer, this)); _path = new GraphicsPath(); _path.StartFigure(); _path.AddRectangle(rectangle); _path.CloseFigure(); } return(_path); }
/// <summary> /// Get the font information based on data stored with the text object or inherited from the parent. /// </summary> /// <returns></returns> internal IFontDefn GetFont(ISvgRenderer renderer) { // Get the font-size float fontSize; var fontSizeUnit = this.FontSize; if (fontSizeUnit == SvgUnit.None || fontSizeUnit == SvgUnit.Empty) { fontSize = new SvgUnit(SvgUnitType.Em, 1.0f); } else { fontSize = fontSizeUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); } var family = ValidateFontFamily(this.FontFamily, this.OwnerDocument); var sFaces = family as IEnumerable <SvgFontFace>; if (sFaces == null) { var fontStyle = System.Drawing.FontStyle.Regular; // Get the font-weight switch (this.FontWeight) { //Note: Bold is not listed because it is = W700. case SvgFontWeight.Bolder: case SvgFontWeight.W600: case SvgFontWeight.W700: case SvgFontWeight.W800: case SvgFontWeight.W900: fontStyle |= System.Drawing.FontStyle.Bold; break; } // Get the font-style switch (this.FontStyle) { case SvgFontStyle.Italic: case SvgFontStyle.Oblique: fontStyle |= System.Drawing.FontStyle.Italic; break; } // Get the text-decoration switch (this.TextDecoration) { case SvgTextDecoration.LineThrough: fontStyle |= System.Drawing.FontStyle.Strikeout; break; case SvgTextDecoration.Underline: fontStyle |= System.Drawing.FontStyle.Underline; break; } var ff = family as FontFamily; if (!ff.IsStyleAvailable(fontStyle)) { // Do Something } // Get the font-family return(new GdiFontDefn(new System.Drawing.Font(ff, fontSize, fontStyle, System.Drawing.GraphicsUnit.Pixel))); } else { var font = sFaces.First().Parent as SvgFont; if (font == null) { var uri = sFaces.First().Descendants().OfType <SvgFontFaceUri>().First().ReferencedElement; font = OwnerDocument.IdManager.GetElementById(uri) as SvgFont; } return(new SvgFontDefn(font, fontSize, OwnerDocument.Ppi)); } }