public static void DrawText(this DrawingContext drawingContext, string text, Point point, Typeface typeface, double emSize, Color color, Color?haloColor = null, double?haloRadius = null, double angle = 0) { var formattedText = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize, new SolidColorBrush(color)); var width = formattedText.Width + haloRadius.GetValueOrDefault() * 2; var height = formattedText.Height + haloRadius.GetValueOrDefault() * 2; var rotate = new RotateTransform(angle); var newRect = rotate.TransformBounds(new Rect(new Point(0, 0), new Size(width, height))); drawingContext.PushTransform(new TranslateTransform(-newRect.Left, -newRect.Top)); drawingContext.PushTransform(rotate); if (haloColor.HasValue && haloRadius.HasValue && haloRadius.Value > 0) { var pen = new Pen(new SolidColorBrush(haloColor.Value), haloRadius.Value * 2); var textGeometry = formattedText.BuildGeometry(point); drawingContext.DrawGeometry(null, pen, textGeometry); } drawingContext.DrawText(formattedText, point); drawingContext.Pop(); drawingContext.Pop(); }
internal void RotateImage(double degrees) { ImageSource source = image.Source; // then copy the image to a format we can handle. double w = source.Width; double h = source.Height; RenderTargetBitmap copy = new RenderTargetBitmap((int)h, (int)w, 96, 96, PixelFormats.Pbgra32); Image img = new Image(); img.Source = source; img.Width = w; img.Height = h; // rotate the angle about 0,0 RotateTransform rotate = new RotateTransform(degrees, 0, 0); Rect bounds = new Rect(0, 0, w, h); // figure out where the bounds ends up with this rotation. Rect transformed = rotate.TransformBounds(bounds); // keep the bounds in non-negative territory by adjusting with a translate. TransformGroup group = new TransformGroup(); group.Children.Add(rotate); group.Children.Add(new TranslateTransform(transformed.X < 0 ? -transformed.X : 0, transformed.Y < 0 ? -transformed.Y : 0)); img.RenderTransform = group; img.Arrange(bounds); copy.Render(img); image.Source = copy; }
private void ComputeVideoBruchTransform() { if (this.captureDevice == null) { return; } var tmptransform = new RotateTransform { Angle = this.orientationAngle + this.captureDevice.SensorRotationInDegrees }; var previewSize = tmptransform.TransformBounds(new Rect(new Point(), new System.Windows.Size(this.captureDevice.PreviewResolution.Width, this.captureDevice.PreviewResolution.Height))); double s1 = this.viewfinderCanvas.ActualWidth / previewSize.Width; double s2 = this.viewfinderCanvas.ActualHeight / previewSize.Height; double scale = Math.Max(s1, s2); var t = new TransformGroup(); if (this.sensorLocation == CameraSensorLocation.Front) { t.Children.Add(new CompositeTransform { Rotation = -(this.orientationAngle + this.captureDevice.SensorRotationInDegrees), CenterX = this.viewfinderCanvas.ActualWidth / 2, CenterY = this.viewfinderCanvas.ActualHeight / 2, ScaleX = scale, ScaleY = scale }); t.Children.Add(new ScaleTransform { ScaleX = -1, CenterX = this.viewfinderCanvas.ActualWidth / 2, CenterY = this.viewfinderCanvas.ActualHeight / 2 }); } else { t.Children.Add( new CompositeTransform { Rotation = this.orientationAngle + this.captureDevice.SensorRotationInDegrees, CenterX = this.viewfinderCanvas.ActualWidth / 2, CenterY = this.viewfinderCanvas.ActualHeight / 2, ScaleX = scale, ScaleY = scale }); } this.viewfinderBrush.Transform = t; }
public void TransformBounds() { var rect = new Rect(-5, -5, 25, 10); var transform = new RotateTransform { Angle = 45 }; var result = transform.TransformBounds(rect); result.X.Should().BeInRange(-7.071068, -7.071067); result.Y.Should().BeInRange(-7.071068, -7.071067); result.Height.Should().BeInRange(24.748737, 24.748738); result.Width.Should().BeInRange(24.748737, 24.748738); }
public override bool ShapeAllInRect(Rectangle rect) { PreviewPoint p1 = PointToZoomPoint(new PreviewPoint(rect.X, rect.Y)); PreviewPoint p2 = PointToZoomPoint(new PreviewPoint(rect.X + rect.Width, rect.Y + rect.Height)); int X1 = Math.Min(p1.X, p2.X); int X2 = Math.Max(p1.X, p2.X); int Y1 = Math.Min(p1.Y, p2.Y); int Y2 = Math.Max(p1.Y, p2.Y); var rt = new RotateTransform(RotationAngle, _rotationCenter.X, _rotationCenter.Y); var b = rt.TransformBounds(Bounds); return(b.Top >= Y1 && b.Bottom <= Y2 && b.Left >= X1 && b.Right <= X2); }
/// <summary> /// This function calculates the smallest axis-aligned bounding box possible for the current ViewPort. /// This means that if the current Map has a Heading that is not a multiple of 90° /// this function will a bounding box that is bigger than the actual ViewPort. /// </summary> public virtual Rect GetViewportBounds() { double zoomFactor = ViewPortProjection.GetZoomFactor(ZoomLevel); double halfHeight = RenderSize.Height / (2 * zoomFactor); double halfWidth = RenderSize.Width / (2 * zoomFactor); Point topLeft = new Point(ViewPortCenter.X - halfWidth, ViewPortCenter.Y - halfHeight); Point bottomRight = new Point(ViewPortCenter.X + halfWidth, ViewPortCenter.Y + halfHeight); RotateTransform rotation = new RotateTransform { Angle = Heading, CenterY = ViewPortCenter.Y, CenterX = ViewPortCenter.X }; Rect rect = new Rect(topLeft, bottomRight); rect = rotation.TransformBounds(rect); return(rect); }
public WordDrawing(WordCloudEntry wordEntry, WordCloudTheme theme, DpiScale scale) { var text = new FormattedText(wordEntry.Word, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, theme.Typeface, 100, wordEntry.Brush, scale.PixelsPerDip); var textGeometry = text.BuildGeometry(new Point(0, 0)); _geo = textGeometry; WordCloudEntry = wordEntry; _bounds = textGeometry.Bounds; _geo.Transform = _transformGroup; var rotateTransform = new RotateTransform(WordCloudEntry.Angle, _bounds.Width / 2, _bounds.Height / 2); _transformGroup.Children.Add(rotateTransform); _bounds = rotateTransform.TransformBounds(_bounds); _transformGroup.Children.Add(_scaleTransformGroup); _initialPlacementTransform = new TranslateTransform(-_bounds.X, -_bounds.Y); _transformGroup.Children.Add(_initialPlacementTransform); _bounds.X = 0; _bounds.Y = 0; IntWidth = (int)Math.Ceiling(_bounds.Width); IntHeight = (int)Math.Ceiling(_bounds.Height); _transformGroup.Children.Add(_translateTransform); }
private static Point DrawLineArrowInternal(DrawingContext dc, double half, Pen pen, Brush brush, double x, double y, double angle, ArrowStyle style) { Point pt; bool doRectTransform = angle % 90.0 != 0.0; var rt = new RotateTransform(angle, x, y); double rx = style.RadiusX; double ry = style.RadiusY; double sx = 2.0 * rx; double sy = 2.0 * ry; switch (style.ArrowType) { default: case ArrowType.None: { pt = new Point(x, y); } break; case ArrowType.Rectangle: { pt = rt.Transform(new Point(x - sx, y)); var rect = new Rect(x - sx, y - ry, sx, sy); if (doRectTransform) { dc.PushTransform(rt); DrawRectangleInternal(dc, half, brush, pen, style.IsStroked, style.IsFilled, ref rect); dc.Pop(); } else { var bounds = rt.TransformBounds(rect); DrawRectangleInternal(dc, half, brush, pen, style.IsStroked, style.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt = rt.Transform(new Point(x - sx, y)); dc.PushTransform(rt); var c = new Point(x - rx, y); DrawEllipseInternal(dc, half, brush, pen, style.IsStroked, style.IsFilled, ref c, rx, ry); dc.Pop(); } break; case ArrowType.Arrow: { pt = rt.Transform(new Point(x, y)); var p11 = rt.Transform(new Point(x - sx, y + sy)); var p21 = rt.Transform(new Point(x, y)); var p12 = rt.Transform(new Point(x - sx, y - sy)); var p22 = rt.Transform(new Point(x, y)); DrawLineInternal(dc, half, pen, style.IsStroked, ref p11, ref p21); DrawLineInternal(dc, half, pen, style.IsStroked, ref p12, ref p22); } break; } return(pt); }
private void RotateTransform_Changed(object sender, EventArgs e) { Rect newRect = _rotateTransform.TransformBounds(_bounds); NotifyShapeChanged(ref _bounds, ref newRect); }
// Draw rotated text at the indicated location. public static void DrawRotatedString(this DrawingContext drawing_context, string text, double angle, string font_name, double em_size, Brush brush, Point origin, TextAlignment text_align, VertAlignment valign, TextAlignment halign) { Typeface typeface = new Typeface(font_name); FormattedText formatted_text = new FormattedText( text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeface, em_size, brush); formatted_text.TextAlignment = text_align; // Make a transformation to center the text. double width = formatted_text.Width - formatted_text.OverhangLeading; double height = formatted_text.Height; TranslateTransform translate1 = new TranslateTransform(); translate1.Y = -height / 2; if ((text_align == TextAlignment.Left) || (text_align == TextAlignment.Justify)) { translate1.X = -width / 2; } else if (text_align == TextAlignment.Right) { translate1.X = width / 2; } else { translate1.X = 0; } // Make a transformation to rotate the text. RotateTransform rotate = new RotateTransform(angle); // Get the text's bounding rectangle. Rect rect = new Rect(0, 0, width, height); if (text_align == TextAlignment.Center) { rect.X -= width / 2; } else if (text_align == TextAlignment.Right) { rect.X -= width; } // Get the rotated bounding rectangle. Rect rotated_rect = rotate.TransformBounds(rect); // Make a transformation to center the // bounding rectangle at the destination. TranslateTransform translate2 = new TranslateTransform(origin.X, origin.Y); // Adjust the translation for the desired alignment. if (halign == TextAlignment.Left) { translate2.X += rotated_rect.Width / 2; } else if (halign == TextAlignment.Right) { translate2.X -= rotated_rect.Width / 2; } if (valign == VertAlignment.Top) { translate2.Y += rotated_rect.Height / 2; } else if (valign == VertAlignment.Bottom) { translate2.Y -= rotated_rect.Height / 2; } // Push transformations in reverse order. drawing_context.PushTransform(translate2); drawing_context.PushTransform(rotate); drawing_context.PushTransform(translate1); // Draw. drawing_context.DrawText(formatted_text, new Point(0, 0)); // Draw a rectangle around the text. (For debugging.) drawing_context.DrawRectangle(null, new Pen(Brushes.Red, 1), rect); // Remove the transformations. drawing_context.Pop(); drawing_context.Pop(); drawing_context.Pop(); // Draw the rotated bounding rectangle. (For debugging.) Rect transformed_rect = translate2.TransformBounds( rotate.TransformBounds( translate1.TransformBounds(rect))); Pen custom_pen = new Pen(Brushes.Blue, 1); custom_pen.DashStyle = new DashStyle( new double[] { 5, 5 }, 0); drawing_context.DrawRectangle(null, custom_pen, transformed_rect); }
private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e) { ContentControl designerItem = DataContext as ContentControl; if (designerItem != null) { Point dragDelta = new Point(e.HorizontalChange, e.VerticalChange); RotateTransform rotateTransform = designerItem.RenderTransform as RotateTransform; if (rotateTransform != null) { dragDelta = rotateTransform.Transform(dragDelta); } Canvas parent_canvas = designerItem.Parent as Canvas; double left_canvas = Canvas.GetLeft(designerItem); double right_canvas = left_canvas + designerItem.ActualWidth; double top_canvas = Canvas.GetTop(designerItem); double bottom_canvas = top_canvas + designerItem.ActualHeight; Rect orig_bounds = new Rect(designerItem.RenderSize); Rect bounds = new Rect(designerItem.RenderSize); if (rotateTransform != null) { bounds = rotateTransform.TransformBounds(bounds); } if (rotateTransform != null) { left_canvas = left_canvas + (orig_bounds.Width - bounds.Width) / 2.0; top_canvas = top_canvas + (orig_bounds.Height - bounds.Height) / 2.0; Canvas.SetLeft(boundingBox, left_canvas); Canvas.SetTop(boundingBox, top_canvas); boundingBox.Width = bounds.Width; boundingBox.Height = bounds.Height; if (!added) { (designerItem.Parent as Canvas).Children.Add(boundingBox); added = true; } else { boundingBox.UpdateLayout(); } } //Horizontal Colision if (left_canvas + dragDelta.X < 0) { Canvas.SetLeft(designerItem, Canvas.GetLeft(designerItem)); } else if (left_canvas + Math.Abs(bounds.Width) + dragDelta.X > parent_canvas.ActualWidth) { Canvas.SetLeft(designerItem, Canvas.GetLeft(designerItem)); } else { Canvas.SetLeft(designerItem, Canvas.GetLeft(designerItem) + dragDelta.X); } //Vertical Collision if (top_canvas + dragDelta.Y < 0) { Canvas.SetTop(designerItem, Canvas.GetTop(designerItem)); } else if (top_canvas + Math.Abs(bounds.Height) + dragDelta.Y > parent_canvas.ActualHeight + 5) { Canvas.SetTop(designerItem, Canvas.GetTop(designerItem)); } else { Canvas.SetTop(designerItem, Canvas.GetTop(designerItem) + dragDelta.Y); } } }
private void RotateThumb_DragDelta(object sender, DragDeltaEventArgs e) { //Initialize the selected widgets' context when first rotate if (_infoItems.Count <= 0) { WidgetViewModBase wdg = designerItem.DataContext as WidgetViewModBase; if (wdg.IsGroup == false) { wdg.CreateNewPropertyMementos(); wdg.PropertyMementos.AddPropertyMemento(new PropertyMemento("RotateAngle", wdg.RotateAngle, wdg.RotateAngle)); _infoItems.Add(wdg); } else { foreach (WidgetViewModBase item in (wdg as GroupViewModel).WidgetChildren) { item.CreateNewPropertyMementos(); item.CreateNewPropertyMementos(); item.PropertyMementos.AddPropertyMemento(new PropertyMemento("RotateAngle", item.RotateAngle, item.RotateAngle)); item.PropertyMementos.AddPropertyMemento(new PropertyMemento("Left", item.Raw_Left, item.Raw_Left)); item.PropertyMementos.AddPropertyMemento(new PropertyMemento("Top", item.Raw_Top, item.Raw_Top)); _infoItems.Add(item); } } } //Rotate the current widget if (this.designerItem != null && this.canvas != null) { ContentPresenter wrapper = VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(designerItem)) as ContentPresenter; Point currentPoint = Mouse.GetPosition(this.canvas); Vector deltaVector = Point.Subtract(currentPoint, this.centerPoint); double angle = Vector.AngleBetween(this.startVector, deltaVector); RotateTransform rotateTransform = designerItem.RenderTransform as RotateTransform; angle = this.initialAngle + Math.Round(angle, 0); if (angle < 0) { angle += 360; } else if (angle >= 360) { angle -= 360; } wrapper.InvalidateMeasure(); if (this.designerItem.IsGroup == true) { GroupViewModel group = this.designerItem.DataContext as GroupViewModel; DesignerCanvas dc = canvas as DesignerCanvas; foreach (WidgetViewModBase item in group.WidgetChildren) { RotateTransform rt = new RotateTransform(); // bw.RenderTransform as RotateTransform; rt.Angle = angle - groupIntialAngle; rt.CenterX = groupCenterX; rt.CenterY = groupCenterY; double oldAngle = item.RotateAngle; item.RotateAngle = Convert.ToInt16(angle - groupIntialAngle); Rect rect1 = rt.TransformBounds(new Rect(item.Left, item.Top, item.ItemWidth, item.ItemHeight)); Rect rect2 = item.RevertBoundingRectangle(rect1); //item.IsActual = true; item.Raw_Left = rect2.Left; item.Raw_Top = rect2.Top; //only widget can rotate if (item is WidgetRotateViewModBase) { int newAngle = Convert.ToInt16(oldAngle + (angle - groupIntialAngle)) % 360; if (newAngle < 0) { newAngle += 360; } else if (angle >= 360) { newAngle -= 360; } item.RotateAngle = newAngle; } else { item.RotateAngle = 0; } } group.Refresh(); groupIntialAngle = angle; } else { rotateTransform.Angle = angle; } if (this.designerItem.ParentID != Guid.Empty) { IGroupOperation pageVM = canvas.DataContext as IGroupOperation; pageVM.UpdateGroup(this.designerItem.ParentID); } if (this.designerItem.IsGroup) { IGroupOperation pageVM = canvas.DataContext as IGroupOperation; pageVM.UpdateGroup((this.designerItem.DataContext as GroupViewModel).WidgetID); } } }
private void LifeTextDrawTransform(string s, DrawingContext drawingContext, Brush brush, Point p) { bool debug = false; FormattedText formattedText = new FormattedText( s, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface(new FontFamily("Chakra Petch"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal), 18, brush); formattedText.SetFontWeight(FontWeights.Bold); TextAlignment text_align = TextAlignment.Center; // Make a transformation to center the text. double width = formattedText.Width - formattedText.OverhangLeading; double height = formattedText.Height; TranslateTransform translate1 = new TranslateTransform { Y = -height / 2 }; if ((text_align == TextAlignment.Left) || (text_align == TextAlignment.Justify)) { translate1.X = -width / 2; } else if (text_align == TextAlignment.Right) { translate1.X = width / 2; } else { translate1.X = 0; } RotateTransform rotate = new RotateTransform(-35); // Get the text's bounding rectangle. Rect rect = new Rect(0, 0, width, height); if (text_align == TextAlignment.Center) { rect.X -= width / 2; } else if (text_align == TextAlignment.Right) { rect.X -= width; } // Get the rotated bounding rectangle. Rect rotated_rect = rotate.TransformBounds(rect); Point origin = new Point(p.X + 30, p.Y + 10); // Make a transformation to center the // bounding rectangle at the destination. TranslateTransform translate2 = new TranslateTransform(origin.X, origin.Y); TextAlignment halign = TextAlignment.Center; VerticalAlignment valign = VerticalAlignment.Top; // Adjust the translation for the desired alignment. if (halign == TextAlignment.Left) { translate2.X += rotated_rect.Width / 2; } else if (halign == TextAlignment.Right) { translate2.X -= rotated_rect.Width / 2; } if (valign == VerticalAlignment.Top) { translate2.Y += rotated_rect.Height / 2; } else if (valign == VerticalAlignment.Bottom) { translate2.Y -= rotated_rect.Height / 2; } // Push transformations in reverse order. (Thanks Microsoft!) drawingContext.PushTransform(translate2); drawingContext.PushTransform(rotate); drawingContext.PushTransform(translate1); // Draw. drawingContext.DrawText(formattedText, new Point(0, 0)); // Draw a rectangle around the text. (For debugging.) if (debug == true) { drawingContext.DrawRectangle(null, new Pen(Brushes.Red, 1), rect); } // Remove the transformations. drawingContext.Pop(); drawingContext.Pop(); drawingContext.Pop(); // Draw the rotated bounding rectangle. (For debugging.) if (debug == true) { Rect transformed_rect = translate2.TransformBounds(rotate.TransformBounds(translate1.TransformBounds(rect))); Pen custom_pen = new Pen(Brushes.Blue, 1) { DashStyle = new DashStyle(new double[] { 5, 5 }, 0) }; drawingContext.DrawRectangle(null, custom_pen, transformed_rect); } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="line"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XLine line, double dx, double dy, ImmutableArray <ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = line.Style; if (style == null) { return; } double zoom = _state.Zoom; double thicknessLine = style.Thickness / zoom; double halfLine = thicknessLine / 2.0; double thicknessStartArrow = style.StartArrowStyle.Thickness / zoom; double halfStartArrow = thicknessStartArrow / 2.0; double thicknessEndArrow = style.EndArrowStyle.Thickness / zoom; double halfEndArrow = thicknessEndArrow / 2.0; // line style Tuple <Brush, Pen> lineCache = null; Brush fillLine; Pen strokeLine; if (_enableStyleCache && _styleCache.TryGetValue(style, out lineCache)) { fillLine = lineCache.Item1; strokeLine = lineCache.Item2; } else { fillLine = CreateBrush(style.Fill); strokeLine = CreatePen(style, thicknessLine); if (_enableStyleCache) { _styleCache.Add(style, Tuple.Create(fillLine, strokeLine)); } } // start arrow style Tuple <Brush, Pen> startArrowCache = null; Brush fillStartArrow; Pen strokeStartArrow; if (_enableArrowStyleCache && _arrowStyleCache.TryGetValue(style.StartArrowStyle, out startArrowCache)) { fillStartArrow = startArrowCache.Item1; strokeStartArrow = startArrowCache.Item2; } else { fillStartArrow = CreateBrush(style.StartArrowStyle.Fill); strokeStartArrow = CreatePen(style.StartArrowStyle, thicknessStartArrow); if (_enableArrowStyleCache) { _arrowStyleCache.Add(style.StartArrowStyle, Tuple.Create(fillStartArrow, strokeStartArrow)); } } // end arrow style Tuple <Brush, Pen> endArrowCache = null; Brush fillEndArrow; Pen strokeEndArrow; if (_enableArrowStyleCache && _arrowStyleCache.TryGetValue(style.EndArrowStyle, out endArrowCache)) { fillEndArrow = endArrowCache.Item1; strokeEndArrow = endArrowCache.Item2; } else { fillEndArrow = CreateBrush(style.EndArrowStyle.Fill); strokeEndArrow = CreatePen(style.EndArrowStyle, thicknessEndArrow); if (_enableArrowStyleCache) { _arrowStyleCache.Add(style.EndArrowStyle, Tuple.Create(fillEndArrow, strokeEndArrow)); } } // line max length double x1 = line.Start.X + dx; double y1 = line.Start.Y + dy; double x2 = line.End.X + dx; double y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref x1, ref y1, ref x2, ref y2); // arrow transforms var sas = style.StartArrowStyle; var eas = style.EndArrowStyle; double a1 = Math.Atan2(y1 - y2, x1 - x2) * 180.0 / Math.PI; double a2 = Math.Atan2(y2 - y1, x2 - x1) * 180.0 / Math.PI; bool doRectTransform1 = a1 % 90.0 != 0.0; bool doRectTransform2 = a2 % 90.0 != 0.0; var t1 = new RotateTransform(a1, x1, y1); var t2 = new RotateTransform(a2, x2, y2); Point pt1; Point pt2; // draw start arrow double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new Point(x1, y1); } break; case ArrowType.Rectangle: { pt1 = t1.Transform(new Point(x1 - sizeX1, y1)); var rect = new Rect(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); if (doRectTransform1) { _dc.PushTransform(t1); DrawRectangleInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _dc.Pop(); } else { var bounds = t1.TransformBounds(rect); DrawRectangleInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt1 = t1.Transform(new Point(x1 - sizeX1, y1)); _dc.PushTransform(t1); var c = new Point(x1 - radiusX1, y1); DrawEllipseInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref c, radiusX1, radiusY1); _dc.Pop(); } break; case ArrowType.Arrow: { pt1 = t1.Transform(new Point(x1, y1)); var p11 = t1.Transform(new Point(x1 - sizeX1, y1 + sizeY1)); var p21 = t1.Transform(new Point(x1, y1)); var p12 = t1.Transform(new Point(x1 - sizeX1, y1 - sizeY1)); var p22 = t1.Transform(new Point(x1, y1)); DrawLineInternal(_dc, halfStartArrow, strokeStartArrow, sas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, halfStartArrow, strokeStartArrow, sas.IsStroked, ref p12, ref p22); } break; } // draw end arrow double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new Point(x2, y2); } break; case ArrowType.Rectangle: { pt2 = t2.Transform(new Point(x2 - sizeX2, y2)); var rect = new Rect(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); if (doRectTransform2) { _dc.PushTransform(t2); DrawRectangleInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _dc.Pop(); } else { var bounds = t2.TransformBounds(rect); DrawRectangleInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt2 = t2.Transform(new Point(x2 - sizeX2, y2)); _dc.PushTransform(t2); var c = new Point(x2 - radiusX2, y2); DrawEllipseInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref c, radiusX2, radiusY2); _dc.Pop(); } break; case ArrowType.Arrow: { pt2 = t2.Transform(new Point(x2, y2)); var p11 = t2.Transform(new Point(x2 - sizeX2, y2 + sizeY2)); var p21 = t2.Transform(new Point(x2, y2)); var p12 = t2.Transform(new Point(x2 - sizeX2, y2 - sizeY2)); var p22 = t2.Transform(new Point(x2, y2)); DrawLineInternal(_dc, halfEndArrow, strokeEndArrow, eas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, halfEndArrow, strokeEndArrow, eas.IsStroked, ref p12, ref p22); } break; } // draw line using points from arrow transforms DrawLineInternal(_dc, halfLine, strokeLine, line.IsStroked, ref pt1, ref pt2); }