Union() public static method

public static Union ( Rect rect, Point point ) : Rect
rect Rect
point Point
return Rect
Example #1
0
 /// <summary>
 /// Sets the item's position according to its tikzitem's value
 /// </summary>
 public override bool AdjustPosition(double Resolution)
 {
     Rect r = new Rect(0, 0, 0, 0);
     bool hasone = false;
     foreach (OverlayShape o in children)
     {
         o.AdjustPosition(Resolution);
         Rect rr = o.View.GetBB();
         if (hasone)
             r.Union(rr);
         else
         {
             r = rr;
             hasone = true;
         }
     }
     if (hasone)
     {
         r.Inflate(20, 20);
         //r = new Rect(10, 10, 100, 100);
         View.SetSize( r.Width, r.Height);
         View.SetPosition(r.X, r.Y);
         return true;
     }
     else return false;
 }
Example #2
0
 protected Rect GetBoundsFromChildren()
 {
     Rect bounds = new Rect(new Size(10, 10)); // default if there are no children.
     Plot2DItem child;
     for (int i = 0; i < plotItems.Count; ++i)
     {
         child = plotItems[i];
         if (i == 0) bounds = child.PaddedBounds;
         else bounds.Union(child.PaddedBounds);
     }
     return bounds;
 }
Example #3
0
		public override Rect TransformBounds (Rect rect)
		{
			Point p1 = new Point (rect.Left, rect.Top);
			Point p2 = new Point (rect.Right, rect.Top);
			Point p3 = new Point (rect.Left, rect.Bottom);
			Point p4 = new Point (rect.Right, rect.Bottom);
			
			Rect r1 = new Rect (Transform (p1), Transform (p2));
			Rect r2 = new Rect (Transform (p3), Transform (p4));

			r1.Union (r2);

			return r1;
		}
Example #4
0
        protected override Size MeasureOverride(Size availableSize)
        {
            var bounds = new Rect();
            var midPoint = new Point(0, 0);
            var arc = new Arc(midPoint, this.MinAngle, this.MaxAngle, this.ReservedSpace, this.IsDirectionReversed);
            for (int i = 0; i < this.AllTicks.Count; i++)
            {
                var tick = this.AllTicks[i];
                var text = this.AllTexts[i];
                var angle = TickHelper.ToAngle(tick, this.Minimum, this.Maximum, arc);
                var point = arc.GetPoint(angle);
                var textPosition = new TextPosition(text, new TextPositionOptions(this.TextOrientation, angle), point, angle);
                bounds.Union(textPosition.TransformedBounds);
            }
            var points = new[] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft };

            this.TextSpace = 2 * points.Max(p => (p - midPoint).Length);
            return bounds.Size;
        }
 private void setupSelectionAdorner()
 {
     var selectedBound = new Rect();
     bool firstShape = true;
     foreach (Stroke stroke in referencedStrokes)
     {
         addStylingToStroke(stroke);
         var bounds = stroke.GetBounds();
         if (firstShape)
         {
             selectedBound.X = bounds.Left - 5;
             selectedBound.Y = bounds.Top - 5;
             firstShape = false;
         }
         var points = new Point[] { new Point(bounds.Left, bounds.Top), new Point(bounds.Right, bounds.Bottom) };
         foreach (Point point in points)
             selectedBound.Union(point);
     }
     this.Width = selectedBound.Width + 10;
     this.Height = selectedBound.Height + 10;
     Canvas.SetLeft(this, selectedBound.X);
     Canvas.SetTop(this, selectedBound.Y);
 }
Example #6
0
        private Rect AddToRegion(KeyValuePair<DrawingVisual, uint> entry, Rect region)
        {
            Rect compRect = entry.Key.ContentBounds;

            if (compRect == Rect.Empty)
                return region;

            TranslateTransform transform = entry.Key.Transform as TranslateTransform;
            if (transform != null)
            {
                double x = transform.X;
                double y = transform.Y;
                compRect.Offset(new Vector(x, y));
            }

            if (region.Width == 0)
                return compRect;
            else
            {
                region.Union(compRect);
                return region;
            }
        }
Example #7
0
		public void Union()
		{
			Rect r;
			
			// fully contained
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(10, 10, 10, 10));
			Assert.AreEqual(new Rect(0, 0, 50, 50), r);

			// crosses top side
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(5, -5, 10, 10));
			Assert.AreEqual(new Rect(0, -5, 50, 55), r);

			// crosses right side
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(5, 5, 50, 10));
			Assert.AreEqual(new Rect(0, 0, 55, 50), r);

			// crosses bottom side
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(5, 5, 10, 50));
			Assert.AreEqual(new Rect(0, 0, 50, 55), r);

			// crosses left side
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(-5, 5, 10, 10));
			Assert.AreEqual(new Rect(-5, 0, 55, 50), r);

			// completely outside (top)
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(5, -5, 1, 1));
			Assert.AreEqual(new Rect(0, -5, 50, 55), r);

			// completely outside (right)
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(75, 5, 1, 1));
			Assert.AreEqual(new Rect(0, 0, 76, 50), r);

			// completely outside (bottom)
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(5, 75, 1, 1));
			Assert.AreEqual(new Rect(0,0, 50, 76), r);

			// completely outside (left)
			r = new Rect(0, 0, 50, 50);
			r.Union(new Rect(-25, 5, 1, 1));
			Assert.AreEqual(new Rect(-25, 0, 75, 50), r);
		}
Example #8
0
    /// <summary>
    /// Determine the size of the union of the bounds of the positioned and rotated child elements.
    /// </summary>
    /// <param name="availableSize"></param>
    /// <returns></returns>
    protected override Size MeasureOverride(Size availableSize) {
      Part part = Diagram.FindAncestor<Part>(this);
      if (part == null) return new Size();

      if (!part.IsMeasuringArranging) return new Size();

      Link link = part as Link;
      if (link == null) {
        Adornment ad = part as Adornment;
        if (ad != null) link = ad.AdornedPart as Link;
        if (link == null) return new Size();
      }

      //Diagram.Debug(" LinkPanelM- " + (link.Data != null ? link.Data.ToString() : ""));

      Shape stroke = this.Path;  // may be null
      link.Path = stroke;  // the Link caches what the Path really is

      Route route = link.Route;
      Rect routeBounds = route.RouteBounds;  // in model coordinates
      Rect linkBounds = new Rect(0, 0, routeBounds.Width, routeBounds.Height);  // will include all decorations
      childrenBounds = new List<Rect>();  // in local coordinates
      if (stroke != null) {
        stroke.Measure(Geo.Unlimited);
        Size sz = stroke.DesiredSize;
        double thick = stroke.StrokeThickness;
        linkBounds.Union(new Rect(-thick/2, -thick/2, sz.Width, sz.Height));  // local coordinates
        childrenBounds.Add(new Rect(0, 0, linkBounds.Width, linkBounds.Height));
      }

      IList<Point> pts = (List<Point>)route.Points;
      int nPoints = pts.Count;
      foreach (UIElement e in this.Children) {
        if (e == stroke) continue;  // already measured the stroke, above

        Path otherpath = e as Path;
        if (otherpath != null && !GetIsLinkShape(e)) otherpath = null;
        if (otherpath != null) {  // IsLinkShape="True"
          otherpath.Data = Adornment.Copy(route.DefiningGeometry);
        }






        e.Measure(Geo.Unlimited);
        //if (e.GetType().Name.Contains("Expander")) Diagram.Debug(e.ToString() + " measured: " + Diagram.Str(e.DesiredSize));
        if (nPoints < 2) continue;
        Size sz = e.DesiredSize;
        int index = GetIndex(e);
        double frac = ComputeFraction(GetFraction(e));
        Spot align = GetAlignment(e);
        if (align.IsNoSpot) align = Spot.Center;
        LabelOrientation orient = GetOrientation(e);
        Point eltpt;  // local coordinates
        if (index < -nPoints || index >= nPoints) {  // beyond range? assume at the MidPoint, with the MidAngle
          Point mid = route.MidPoint;
          if (this.Implementation == LinkPanelImplementation.Stretch) {
            Point p0 = pts[0];
            Point pn = pts[nPoints-1];
            sz.Width = Math.Sqrt(Geo.DistanceSquared(pn, p0));
          }
          double segangle = route.MidAngle;
          // maybe rotate the label
          double labelangle = 0;
          if (orient != LabelOrientation.None) {
            labelangle = ComputeAngle(e, orient, segangle);
            link.SetAngle(e, labelangle, align);
          }
          // maybe the alignment point is away from the line
          eltpt = new Point(mid.X - routeBounds.X, mid.Y - routeBounds.Y);  // local coordinates
          Point offset = ComputeOffset(e, index, segangle, sz, labelangle);
          eltpt = Geo.Add(eltpt, offset);
        } else {  // on a particular segment, given by Index, at a point given by Fraction
          // negative index means start from last point, going "backwards"
          Point a, b;
          if (index >= 0) {
            a = pts[index];
            b = (index < nPoints-1) ? pts[index+1] : a;
          } else {
            int i = nPoints + index;  // remember that index is negative here
            a = pts[i];
            b = (i > 0) ? pts[i-1] : a;
          }
          // compute the fractional point along the line, in local coordinates
          eltpt = new Point(a.X + (b.X-a.X)*frac - routeBounds.X, a.Y + (b.Y-a.Y)*frac - routeBounds.Y);
          double segangle = (index >= 0 ? Geo.GetAngle(a, b) : Geo.GetAngle(b, a));
          // maybe rotate the label
          double labelangle = 0;
          if (orient != LabelOrientation.None) {
            labelangle = ComputeAngle(e, orient, segangle);
            Arrowhead toArrow = GetToArrow(e);
            Arrowhead fromArrow = GetFromArrow(e);
            if (toArrow == Arrowhead.None && fromArrow == Arrowhead.None) {
              link.SetAngle(e, labelangle, align);
            } else {
              double arrowScale = 0.0;
              if (toArrow != Arrowhead.None)
                arrowScale = GetToArrowScale(e);
              else
                arrowScale = GetFromArrowScale(e);
              link.SetAngleAndScale(e, labelangle, align, new Size(arrowScale, arrowScale));
            }
          }
          // maybe the alignment point is away from the line
          Point offset = ComputeOffset(e, index, segangle, sz, labelangle);
          eltpt = Geo.Add(eltpt, offset);
        }
        if (otherpath != null) {  // IsLinkShape="True"
          double thick = otherpath.StrokeThickness;
          linkBounds.Union(new Rect(-thick/2, -thick/2, sz.Width, sz.Height));  // local coordinates
          childrenBounds.Add(new Rect(0, 0, linkBounds.Width, linkBounds.Height));
        } else {
          Rect cb = align.RectForPoint(eltpt, sz);
          childrenBounds.Add(cb);  // local coordinates
          linkBounds.Union(new Rect(cb.X, cb.Y, cb.Width, cb.Height));  // local coordinates
        }
      }

      // if this panel is the "whole" link, update the link's Bounds
      if (link.VisualElement == this) {
        link.Bounds = new Rect(routeBounds.X, routeBounds.Y, linkBounds.Width, linkBounds.Height);  // convert to model coordinates
      }

      //Diagram.Debug(" LinkPanelM+ " + (link.Data != null ? link.Data.ToString() : "") + " " + Diagram.Str(routeBounds) + Diagram.Str(linkBounds));
      return new Size(routeBounds.Width, routeBounds.Height);
    }
Example #9
0
 /// <summary>
 /// Union - Return the result of the union of rect and point.
 /// </summary>
 public static Rect Union(Rect rect, Point point)
 {
     rect.Union(new Rect(point, point));
     return(rect);
 }
Example #10
0
 protected override Size MeasureOverride(Size availableSize)
 {
     var rect = new Rect();
     var arc = new Arc(new Point(0, 0), this.MinAngle, this.MaxAngle, this.ReservedSpace / 2 + this.TickLength, this.IsDirectionReversed);
     rect.Union(arc.GetPoint(arc.Start));
     var a = TickHelper.ToAngle(this.Value, this.Minimum, this.Maximum, arc);
     rect.Union(arc.GetPoint(a));
     foreach (var p in arc.GetQuadrants(arc.Start, a))
     {
         rect.Union(p);
     }
     return rect.Size;
 }
Example #11
0
    protected override Size MeasureOverride( Size availableSize )
    {
      DateTime calcBeginDate = DateTime.MaxValue;
      DateTime calcEndDate = DateTime.MinValue;

      foreach( UIElement child in InternalChildren )
      {
        DateTime date = GetDate( child );
        DateTime dateEnd = GetDateEnd( child );

        if( date < calcBeginDate )
        {
          calcBeginDate = date;
        }

        if( date > calcEndDate )
        {
          calcEndDate = date;
        }

        if( dateEnd > calcEndDate )
        {
          calcEndDate = dateEnd;
        }
      }

      if( BeginDate == DateTime.MinValue )
      {
        BeginDate = calcBeginDate;
      }

      if( EndDate == DateTime.MinValue )
      {
        EndDate = calcEndDate;
      }

      foreach( UIElement child in InternalChildren )
      {
        DateTime date = GetDate( child );
        DateTime dateEnd = GetDateEnd( child );

        Size childSize = availableSize;

        if( dateEnd > DateTime.MinValue && dateEnd > date )
        {
          if( Orientation == Orientation.Horizontal )
          {
            if( UnitTimeSpan != TimeSpan.Zero && UnitSize > 0 )
            {
              double size = ( double )( dateEnd.Ticks - date.Ticks ) / ( double )UnitTimeSpan.Ticks;

              childSize.Width = size * UnitSize;
            }
            else if( !double.IsPositiveInfinity( availableSize.Width ) )
            {
              // width is DateEnd - Date
              childSize.Width = CalculateTimelineOffset( dateEnd, availableSize.Width ) - CalculateTimelineOffset( date, availableSize.Width );
            }
          }
          else
          {
            if( UnitTimeSpan != TimeSpan.Zero && UnitSize > 0 )
            {
              double size = ( double )( dateEnd.Ticks - date.Ticks ) / ( double )UnitTimeSpan.Ticks;

              childSize.Height = size * UnitSize;
            }
            else if( !double.IsPositiveInfinity( availableSize.Height ) )
            {
              // height is DateEnd - Date
              childSize.Height = CalculateTimelineOffset( dateEnd, availableSize.Height ) - CalculateTimelineOffset( date, availableSize.Height );
            }
          }
        }

        child.Measure( childSize );
      }

      Size newAvailableSize = new Size( availableSize.Width, availableSize.Height );

      if( UnitTimeSpan != TimeSpan.Zero && UnitSize > 0 )
      {
        double size = ( double )( EndDate.Ticks - BeginDate.Ticks ) / ( double )UnitTimeSpan.Ticks;

        if( Orientation == Orientation.Horizontal )
        {
          newAvailableSize.Width = size * UnitSize;
        }
        else
        {
          newAvailableSize.Height = size * UnitSize;
        }
      }

      Size desiredSize = new Size();

      if( ( Orientation == Orientation.Vertical && double.IsPositiveInfinity( newAvailableSize.Height ) ) ||
          ( Orientation == Orientation.Horizontal && double.IsPositiveInfinity( newAvailableSize.Width ) ) )
      {
        // Our panel cannot layout items when we have positive infinity in the layout direction
        // so defer to arrange pass.
        _visibleElements = null;
      }
      else
      {
        LayoutItems( InternalChildren, newAvailableSize );

        Rect desiredRect = new Rect();

        foreach( DateElement child in _visibleElements )
        {
          desiredRect.Union( child.PlacementRectangle );
        }

        if( Orientation == Orientation.Horizontal )
        {
          desiredSize.Width = newAvailableSize.Width;
          desiredSize.Height = desiredRect.Size.Height;
        }
        else
        {
          desiredSize.Width = desiredRect.Size.Width;
          desiredSize.Height = newAvailableSize.Height;
        }
      }

      if( IsScrolling )
      {
        Size viewport = new Size( availableSize.Width, availableSize.Height );
        Size extent = new Size( desiredSize.Width, desiredSize.Height );
        Vector offset = new Vector( Math.Max( 0, Math.Min( _offset.X, extent.Width - viewport.Width ) ),
                                    Math.Max( 0, Math.Min( _offset.Y, extent.Height - viewport.Height ) ) );

        SetScrollingData( viewport, extent, offset );

        desiredSize.Width = Math.Min( desiredSize.Width, availableSize.Width );
        desiredSize.Height = Math.Min( desiredSize.Height, availableSize.Height );

        _physicalViewport = availableSize;
      }

      return desiredSize;
    }
        internal void SaveWorkspaceAsImage(string path)
        {
            var initialized = false;
            var bounds = new Rect();

            double minX = 0.0, minY = 0.0;
            var dragCanvas = WpfUtilities.ChildOfType<DragCanvas>(this);
            var childrenCount = VisualTreeHelper.GetChildrenCount(dragCanvas);
            for (int index = 0; index < childrenCount; ++index)
            {
                var child = VisualTreeHelper.GetChild(dragCanvas, index);
                var firstChild = VisualTreeHelper.GetChild(child, 0);

                switch (firstChild.GetType().Name)
                {
                    case "NodeView":
                    case "NoteView":
                    case "AnnotationView":
                        break;

                    // Until we completely removed InfoBubbleView (or fixed its broken 
                    // size calculation), we will not be including it in our size 
                    // calculation here. This means that the info bubble, if any, will 
                    // still go beyond the boundaries of the final PNG file. I would 
                    // prefer not to add this hack here as it introduces multiple issues 
                    // (including NaN for Grid inside the view and the fix would be too 
                    // ugly to type in). Suffice to say that InfoBubbleView is not 
                    // included in the size calculation for screen capture (work-around 
                    // should be obvious).
                    // 
                    // case "InfoBubbleView":
                    //     child = WpfUtilities.ChildOfType<Grid>(child);
                    //     break;

                    // We do not take anything other than those above 
                    // into consideration when the canvas size is measured.
                    default:
                        continue;
                }

                // Determine the smallest corner of all given visual elements on the 
                // graph. This smallest top-left corner value will be useful in making 
                // the offset later on.
                // 
                var childBounds = VisualTreeHelper.GetDescendantBounds(child as Visual);
                minX = childBounds.X < minX ? childBounds.X : minX;
                minY = childBounds.Y < minY ? childBounds.Y : minY;
                childBounds.X = (double)(child as Visual).GetValue(Canvas.LeftProperty);
                childBounds.Y = (double)(child as Visual).GetValue(Canvas.TopProperty);

                if (initialized)
                {
                    bounds.Union(childBounds);
                }
                else
                {
                    initialized = true;
                    bounds = childBounds;
                }
            }

            // Nothing found in the canvas, bail out.
            if (!initialized) return;

            // Add padding to the edge and make them multiples of two (pad 10px on each side).
            bounds.Width = 20 + ((((int)Math.Ceiling(bounds.Width)) + 1) & ~0x01);
            bounds.Height = 20 + ((((int)Math.Ceiling(bounds.Height)) + 1) & ~0x01);

            var currentTransformGroup = WorkspaceElements.RenderTransform as TransformGroup;
            WorkspaceElements.RenderTransform = new TranslateTransform(10.0 - bounds.X - minX, 10.0 - bounds.Y - minY);
            WorkspaceElements.UpdateLayout();

            var rtb = new RenderTargetBitmap(((int)bounds.Width),
                ((int)bounds.Height), 96, 96, PixelFormats.Default);

            rtb.Render(WorkspaceElements);
            WorkspaceElements.RenderTransform = currentTransformGroup;

            try
            {
                using (var stm = System.IO.File.Create(path))
                {
                    // Encode as PNG format
                    var pngEncoder = new PngBitmapEncoder();
                    pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
                    pngEncoder.Save(stm);
                }
            }
            catch (Exception)
            {
            }
        }
        /// <summary>
        /// Expand the content area to fit the diagram-elements.
        /// </summary>
        private void ExpandContent()
        {
            double smallestX = 0;
            double smallestY = 0;
            var contentRect = new Rect(0, 0, 0, 0);
            foreach (DiagramElement diagramElement in Controller.DiagramElements)
            {
                if (diagramElement.TopLeft.X < smallestX)
                {
                    smallestX = diagramElement.TopLeft.X;
                }

                if (diagramElement.TopLeft.Y < smallestY)
                {
                    smallestY = diagramElement.TopLeft.Y;
                }

                contentRect.Union(new Rect(diagramElement.TopLeft.X, diagramElement.TopLeft.Y, diagramElement.Width, diagramElement.Height));
            }

            // Translate all diagram-elements so they are in positive space.
            smallestX = Math.Abs(smallestX);
            smallestY = Math.Abs(smallestY);

            if (smallestX > 0.01 || smallestY > 0.01)
            {
                Controller.DiagramElements.ToList().ForEach(element => element.AdjustCoordinatesAfterCanvasExpansion(smallestX, smallestY));
            }

            Diagram.ContentWidth = contentRect.Width;
            Diagram.ContentHeight = contentRect.Height;
        }
        /// <summary>
        /// Arranges the content of a <see cref="StiZoomableCanvas"/> element.
        /// </summary>
        /// <param name="finalSize">The size that this <see cref="StiZoomableCanvas"/> element should use to arrange its child elements.</param>
        /// <returns>A <see cref="Size"/> that represents the arranged size of this <see cref="StiZoomableCanvas"/> element and its descendants.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            bool applyTransform = ApplyTransform;
            Point offset = applyTransform ? new Point() : Offset;
            double scale = applyTransform ? 1.0 : Scale;

            ChildrenExtent = Rect.Empty;

            foreach (UIElement child in InternalChildren)
            {
                if (child != null)
                {
                    // Get bounds information from the element.
                    Rect bounds = new Rect(Canvas.GetLeft(child).GetValueOrDefault(), Canvas.GetTop(child).GetValueOrDefault(), child.DesiredSize.Width / scale, child.DesiredSize.Height / scale);

                    // If we are maintaining our own spatial wrapper then update its bounds.
                    if (PrivateIndex != null)
                    {
                        int index = IndexFromContainer(child); //TODO
                        Rect oldBounds = PrivateIndex[index];
                        const double tolerance = .0001; // The exact values during arrange can vary slightly.
                        if (Math.Abs(oldBounds.Top - bounds.Top) > tolerance ||
                            Math.Abs(oldBounds.Left - bounds.Left) > tolerance ||
                            Math.Abs(oldBounds.Width - bounds.Width) > tolerance ||
                            Math.Abs(oldBounds.Height - bounds.Height) > tolerance)
                        {
                            PrivateIndex[index] = bounds;
                        }
                    }

                    // Update the children extent for scrolling.
                    ChildrenExtent.Union(bounds);

                    // So far everything has been in canvas coordinates.  Here we adjust the result for the final call to Arrange.
                    bounds.X *= scale;
                    bounds.X -= offset.X;
                    bounds.Y *= scale;
                    bounds.Y -= offset.Y;
                    bounds.Width  = Math.Ceiling(bounds.Width*scale);
                    bounds.Height = Math.Ceiling(bounds.Height*scale);

                    // WPF Arrange will crash if the values are too large.
                    bounds.X = bounds.X.AtLeast(Single.MinValue / 2);
                    bounds.Y = bounds.Y.AtLeast(Single.MinValue / 2);
                    bounds.Width = bounds.Width.AtMost(Single.MaxValue);
                    bounds.Height = bounds.Height.AtMost(Single.MaxValue);

                    child.Arrange(bounds);
                }
            }

            InvalidateExtent();

            return finalSize;
        }
Example #15
0
 public Bars(Plot2D plot2D, ILArray<double> barStart, ILArray<double> barEnd, ILArray<double> barPosition, ILArray<double> barThickness, BarType barType)
 {
     this.plot2D = plot2D;
     int n = barStart.Length;
     rectangles = new List<Path>();
     Geometry geometry;
     Path rectangle;
     Rect bounds = new Rect();
     Rect rectangleBounds = new Rect();
     for (int i = 0; i < n; ++i)
     {
         rectangle = new Path();
         rectangles.Add(rectangle);
         if (barType == BarType.Horizontal)
         {
             rectangleBounds = new Rect(new Point(barStart.GetValue(i), barPosition.GetValue(i) + barThickness.GetValue(i) / 2),
                 new Point(barEnd.GetValue(i), barPosition.GetValue(i) - barThickness.GetValue(i) / 2));
         }
         else
         {
             rectangleBounds = new Rect(new Point(barPosition.GetValue(i) + barThickness.GetValue(i) / 2, barStart.GetValue(i)),
                 new Point(barPosition.GetValue(i) - barThickness.GetValue(i) / 2, barEnd.GetValue(i)));
         }
         geometry = new RectangleGeometry(rectangleBounds);
         rectangle.Data = geometry;
         geometry.Transform = plot2D.GraphToCanvas;
         rectangle.Fill = (Brush)(this.GetValue(FillProperty));
         rectangle.StrokeThickness = (double)(this.GetValue(StrokeThicknessProperty));
         rectangle.Stroke = (Brush)(this.GetValue(StrokeProperty));
         if (i == 0) bounds = rectangleBounds;
         else
         {
             bounds.Union(rectangleBounds);
         }
     }
     Bounds = bounds;
     SetBindings();
 }
Example #16
0
        protected override Size MeasureOverride(Size availableSize)
        {
            if (Children == null || Children.Count < 1)
             {
            return new Size (0, 0);
             }

             var resultingRect = new Rect ();

             object accumulatedState = null;
             try
             {
            var count = Children.Count;
            for (var iter = 0; iter < count; ++iter)
            {
               var child = Children[iter];
               child.Measure (availableSize);
               var desiredSize = child.DesiredSize;
               var args = new LayoutItemEventArgs
               {
                  LayoutItemState = LayoutItemState.IsMeasuring,
                  UiElement = child,
                  AccumulateState = accumulatedState,
                  State = GetUIElementState (child),
                  AvailableSize = availableSize,
                  DesiredSize = desiredSize,
                  Count = count,
                  Index = iter,
                  Transform = child.RenderTransform,
               };

               OnItemLayout (args);

               accumulatedState = args.AccumulateState;
               var childRect = (args.Transform ?? s_identityTransform).TransformBounds (new Rect (0, 0, desiredSize.Width, desiredSize.Height));
               resultingRect.Union (childRect);
            }

            return availableSize.Merge (resultingRect.ToSize ());
             }
             finally
             {
            Common.Dispose (accumulatedState);
             }
        }
Example #17
0
		private Rect CoerceVisible(Rect newVisible)
		{
			if (Plotter == null)
			{
				return newVisible;
			}

			bool isDefaultValue = newVisible == (Rect)VisibleProperty.DefaultMetadata.DefaultValue;
			if (isDefaultValue)
			{
				newVisible = Rect.Empty;
			}

			if (isDefaultValue && IsFittedToView)
			{
				Rect bounds = Rect.Empty;
				foreach (var g in Plotter.Children)
				{
					var graph = g as DependencyObject;
					if (graph != null)
					{
						var uiElement = g as UIElement;
						if (uiElement == null || (uiElement != null && uiElement.Visibility == Visibility.Visible))
						{
							bounds.Union((Rect)graph.GetValue(ViewportElement2D.ContentBoundsProperty));
						}
					}
				}
				Rect viewportBounds = bounds;
				if (!bounds.IsEmpty)
				{
					bounds = bounds.DataToViewport(transform);
				}

				//Rect defaultRect = (Rect)VisibleProperty.DefaultMetadata.DefaultValue;
				//if (bounds.Width.IsInfinite())
				//    bounds.Width = defaultRect.Width;
				//if (bounds.Height.IsInfinite())
				//    bounds.Height = defaultRect.Height;
				//if (bounds.X.IsInfinite())
				//    bounds.X = defaultRect.X;
				//if (bounds.Y.IsInfinite())
				//    bounds.Y = defaultRect.Y;

				if (!bounds.IsEmpty)
				{
					bounds = CoordinateUtilities.RectZoom(bounds, bounds.GetCenter(), clipToBoundsFactor);
				}
				else
				{
					bounds = (Rect)VisibleProperty.DefaultMetadata.DefaultValue;
				}
				newVisible.Union(bounds);
			}

			if (newVisible.IsEmpty)
			{
				newVisible = (Rect)VisibleProperty.DefaultMetadata.DefaultValue;
			}
			else if (newVisible.Width == 0 || newVisible.Height == 0)
			{
				Rect defRect = (Rect)VisibleProperty.DefaultMetadata.DefaultValue;
				Size size = newVisible.Size;
				Point loc = newVisible.Location;

				if (newVisible.Width == 0)
				{
					size.Width = defRect.Width;
					loc.X -= size.Width / 2;
				}
				if (newVisible.Height == 0)
				{
					size.Height = defRect.Height;
					loc.Y -= size.Height / 2;
				}

				newVisible = new Rect(loc, size);
			}

			newVisible = ApplyRestrictions(Visible, newVisible);

			// applying transform's data domain restriction
			if (!transform.DataTransform.DataDomain.IsEmpty)
			{
				var newDataRect = newVisible.ViewportToData(transform);
				newDataRect = Rect.Intersect(newDataRect, transform.DataTransform.DataDomain);
				newVisible = newDataRect.DataToViewport(transform);
			}

			if (newVisible.IsEmpty) return new Rect(0, 0, 1, 1);

			return newVisible;
		}
        /// <summary>
        /// When overridden in a derived class, participates in rendering operations that are directed by the layout system. 
        /// In this case the rendering draws additional line between info box and its origin vertex control, when
        /// the mouse is over either vertex control or its info box.
        /// </summary>
        /// <param name="drawingContext">The drawing instructions for a specific element. This context is provided to the layout system.</param>
        protected override void OnRender(DrawingContext drawingContext)
        {
            var element = OriginElement as FrameworkElement;

            if (element != null && (IsMouseOver || element.IsMouseOver))
            {
                var mainWindow = this.GetParent<DockableGraph>(null);
                
                var gt = element.TransformToVisual(this);
                var elementCenter = gt.Transform(new Point(element.ActualWidth / 2, element.ActualHeight / 2));
                var elementSize = new Size(element.ActualWidth, element.ActualHeight);
                var elementRect = new Rect(gt.Transform(new Point(0, 0)), elementSize);

                var thisCenter = new Point(ActualWidth / 2, ActualHeight / 2);

                // The total area we'll be drawing in.
                var totalRect = new Rect(elementRect.Location, elementRect.Size);
                totalRect.Union(new Rect(new Point(0, 0), new Size(ActualWidth, ActualHeight)));

                // Create geometry objects to work with.
                var elementRectangleGeometry = new RectangleGeometry(elementRect);
                var totalRectangleGeometry = new RectangleGeometry(totalRect);

                // We'll now remove the element's rectangle from where we're drawing, so that we 
                // don't draw on top of it, but will draw on top of everything else.
                CombinedGeometry clipGeometry = new CombinedGeometry(GeometryCombineMode.Exclude, totalRectangleGeometry, elementRectangleGeometry);

                drawingContext.PushClip(clipGeometry);

                //var node = OriginElement.Vertex as TraceLab.Core.Experiments.ExperimentNode;
                //Point vertexCenter = new Point(node.Data.X, node.Data.Y);

                Pen solidPen = new Pen(System.Windows.Media.Brushes.LightCoral, 1.0);
                drawingContext.DrawLine(solidPen, elementCenter, thisCenter);

                // Pop off the RectangleGeometry
                drawingContext.Pop();
            }

            base.OnRender(drawingContext);
        }
        /// <summary>
        /// Create Gant TimeLine ranges.
        /// </summary>
        protected override Size _CreateVisualChildren(Size dimension, double rangeWidth, int rangeStepInHour)
        {
            Rect boundingRect = new Rect();

            // Calculate range boundbox.
            Size itemSize = new Size(rangeWidth, dimension.Height);
            Rect itemRect = new Rect(new Point(0, 0), itemSize);

            DateTime currentHour;

            // Define start hour: "0" if _startDate in MaxValue
            if (_startHour.Date == DateTime.MaxValue.Date)
                currentHour = DateTime.MinValue;
            else
                currentHour = _startHour;

            int current = 0;
            while (current < (int)_duration)
            {
                // Create TimeLine range.
                DrawingVisual visualItem = _CreateVisualItem(currentHour, rangeStepInHour, itemRect);
                _children.Add(visualItem);

                boundingRect.Union(visualItem.ContentBounds);

                // Relocate for next element.
                itemRect.Offset(rangeWidth, 0);

                currentHour = currentHour.AddHours(rangeStepInHour);
                current += rangeStepInHour;
            }

            return boundingRect.Size;
        }
Example #20
0
        private ValidSetOfPointsCollection IsValid(List<TouchPoint2> points)
        {
            bool result = true;

            ValidSetOfPointsCollection sets = new ValidSetOfPointsCollection();

            if (points.Count > 0)
            {
                //double minX = int.MinValue, minY = int.MinValue, maxX = int.MaxValue, maxY = int.MaxValue;

                Rect area = new Rect(points[0].Position, new Size(0, 0));

                // Calculate the bounding box that covers all points
                foreach (var point in points)
                {
                    if (_data.HistoryLevel > 0)
                    {
                        Rect location = RuleValidationHelper.GetBoundingBox(point);
                        List<TouchPoint2> selectedPoints = new List<TouchPoint2>();
                        result = RuleValidationHelper.HasPreviousTouchPoints(location, point, _data.HistoryLevel, point.StartTime.AddSeconds(-_data.HistoryTimeLine), selectedPoints);

                        if (result) // Has required number of previous touch points in selected location
                        {
                            foreach (var p in selectedPoints)
                            {
                                area.Union(p.Position);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    area.Union(point.Position);
                }

                // TODO: We need to implement circular area too

                if (result && area.Height <= _data.Height && area.Width <= _data.Width)
                {
                    sets.Add(new ValidSetOfTouchPoints(points));
                }

            }
            return sets;
        }
        private void RebuildMap()
        {
            Rect canvRect = new Rect(
                new Point(cam.MapToScreen(new Vector3(baseMap.width + 1, 0, 0)).X, cam.MapToScreen(new Vector3(0, 0, 0)).Y),
                new Point(cam.MapToScreen(new Vector3(0, baseMap.height + 1, 0)).X, cam.MapToScreen(new Vector3(baseMap.width + 1, baseMap.height + 1, 0)).Y));
            Tiles.Children.Clear();

            int maxHeight = 0;
            for (int i = 0; i < baseMap.tiles.Count; i++)
            {
                for (int j = 0; j < baseMap.tiles[i].Count; j++)
                {
                    int height = 0;
                    foreach (Map.TileReference tref in baseMap.tiles[i][j])
                    {
                        Tile tile = baseMap.GetTile(tref);

                        Point loc = cam.MapToScreen(new Vector3(j, i, height));
                        Rect tRect = new Rect(loc.X - (64 * (tile.OriginX - tile.LeftX) + 32), loc.Y - (64 * (tile.OriginY - tile.TopY) + 32),
                            64 * (tile.RightX - tile.LeftX + 1), 64 * (tile.BottomY - tile.TopY + 1));

                        Rectangle rec = new Rectangle();
                        Canvas.SetLeft(rec, tRect.Left); Canvas.SetTop(rec, tRect.Top);
                        Panel.SetZIndex(rec, i + j + height);
                        rec.Width = tRect.Width; rec.Height = tRect.Height;
                        rec.Fill = ((TileSets.Items[tref.TileSetIndex] as TabItem).Content as TileSetEditor).getTileBrush(tile);
                        rec.Opacity = (height > clipZ || (height == clipZ && !tile.IsFloor)) ? .5*Math.Pow(.7,height-clipZ) : 1;

                        Tiles.Children.Add(rec);

                        canvRect.Union(tRect);

                        if (tile.IsBlock) height++;
                    }
                    if (height > maxHeight) maxHeight = height;
                }
            }
            canvRect.Union(cam.MapToScreen(new Vector3(0, 0, clipZ)));
            canvas.Width = canvRect.Width;
            canvas.Height = canvRect.Height;
            Canvas.SetLeft(Origin, -canvRect.Left);
            Canvas.SetTop(Origin, -canvRect.Top);

            PointCollection mapBorder = new PointCollection();
            mapBorder.Add(cam.MapToScreen(new Vector3(0, 0, clipZ))); mapBorder.Add(cam.MapToScreen(new Vector3(baseMap.width, 0, clipZ)));
            mapBorder.Add(cam.MapToScreen(new Vector3(baseMap.width, baseMap.height, clipZ))); mapBorder.Add(cam.MapToScreen(new Vector3(0, baseMap.height, clipZ)));
            MapEdge.Points = mapBorder;

            ZClip.Maximum = maxHeight+1;

            PreviewPaint();
        }
Example #22
0
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var r = new Rect();
            ScreenHelper.AllScreens.Select(x => x.Bounds).ToList().ForEach(x => r.Union(x));
            Left = r.Left;
            Top = r.Top;
            Width = r.Width;
            Height = r.Height;

            _m.IsHooked = true;
            _m.MouseMove += m_MouseMove;
            _m.MouseUp += m_MouseUp;
            _m.MouseDown += m_MouseDown;

            _k.IsHooked = true;
            _k.KeyDown += (s, ev) =>
            {
                if (ev.Key == Key.System || ev.Key == Key.LeftAlt || ev.Key == Key.RightAlt)
                {
                    IsAltDown = true;
                    e.Handled = true;
                }
            };
            _k.KeyUp += (s, ev) =>
            {
                if (ev.Key == Key.System || ev.Key == Key.LeftAlt || ev.Key == Key.RightAlt)
                {
                    IsAltDown = false;
                    e.Handled = true;
                }
            };
        }
Example #23
0
        protected virtual Rect CoerceVisible(Rect newVisible)
        {
            PerformanceCounter.startStopwatch("Coercing visible");
            if (Plotter == null)
            {
                return newVisible;
            }

            bool isDefaultValue = (newVisible == defaultRect);
            if (isDefaultValue)
            {
                newVisible = Rect.Empty;
            }

            //if (isDefaultValue && IsFittedToView)
            if(isDefaultValue)
            {
                Rect bounds = Rect.Empty;
                foreach (var g in Plotter.Children)
                {
                    var graph = g as DependencyObject;
                    if (graph != null)
                    {
                        var uiElement = g as UIElement;
                          if (uiElement == null || (uiElement != null && uiElement.Visibility == Visibility.Visible))
                          {
                            bounds.Union((Rect)graph.GetValue(ViewportElement2D.ContentBoundsProperty));
                          }
                    }
                }
                Rect viewportBounds = bounds;

                if (!bounds.IsEmpty)
                {
                    bounds = CoordinateUtilities.RectZoom(bounds, bounds.GetCenter(), clipToBoundsFactor);
                }
                else
                {
                    bounds = defaultRect;
                }
                newVisible.Union(bounds);
            }

            if (newVisible.IsEmpty)
            {
                newVisible = defaultRect;
            }
            else if (newVisible.Width == 0 || newVisible.Height == 0)
            {
                Rect defRect = defaultRect;
                Size size = new Size(newVisible.Width,newVisible.Height);
                Point loc = new Point(newVisible.X,newVisible.Y);

                if (newVisible.Width == 0)
                {
                    size.Width = defRect.Width;
                    loc.X -= size.Width / 2;
                }
                if (newVisible.Height == 0)
                {
                    size.Height = defRect.Height;
                    loc.Y -= size.Height / 2;
                }

                newVisible = new Rect(loc, size);
            }

            newVisible = ApplyRestrictions(Visible, newVisible);

            // applying transform's data domain restriction
            if (!transform.DataTransform.DataDomain.IsEmpty)
            {
                var newDataRect = newVisible.ViewportToData(transform);
                newDataRect = RectExt.Intersect(newDataRect, transform.DataTransform.DataDomain);
                newVisible = newDataRect.DataToViewport(transform);
            }

            if (newVisible.IsEmpty) return new Rect(0, 0, 1, 1);

            //RaisePropertyChangedEvent();
            PerformanceCounter.stopStopwatch("Coercing visible");
            return newVisible;
        }
Example #24
0
 /// <summary>
 /// Returns an estimate for the Bounding Box of the container.
 /// In fact, it simply returns the smallest rectangle around all occuring coordinates in children.
 /// </summary>
 /// <param name="r">Will hold the rectangle upon return.</param>
 /// <returns></returns>
 public override bool GetBB(out Rect r)
 {
     bool hasone = false;
     r = new Rect(0, 0, 0, 0);
     foreach (TikzParseItem tpi in Children)
     {
         Rect rr;
         if (tpi.GetBB(out rr))
         {
             if (!hasone)
             {
                 r = rr;
                 hasone = true;
             }
             else
                 r.Union(rr);
         }
     }
     return hasone;
 }
Example #25
0
        /// <summary>
        /// Expand the content area to fit the rectangles.
        /// </summary>
        private void ExpandContent()
        {
            double xOffset = 0;
            double yOffset = 0;
            Rect contentRect = new Rect(0, 0, 0, 0);
            foreach (BoardObject rectangleData in DataModel.Instance.BoardObjects)
            {
                if (rectangleData.X < xOffset)
                {
                    xOffset = rectangleData.X;
                }

                if (rectangleData.Y < yOffset)
                {
                    yOffset = rectangleData.Y;
                }

                contentRect.Union(new Rect(rectangleData.X, rectangleData.Y, rectangleData.Width, rectangleData.Height));
            }

            //
            // Translate all rectangles so they are in positive space.
            //
            xOffset = Math.Abs(xOffset);
            yOffset = Math.Abs(yOffset);

            foreach (BoardObject rectangleData in DataModel.Instance.BoardObjects)
            {
                rectangleData.X += xOffset;
                rectangleData.Y += yOffset;
            }

            DataModel.Instance.ContentWidth = contentRect.Width;
            DataModel.Instance.ContentHeight = contentRect.Height;
        }
Example #26
0
 /// <summary>
 /// Sets the item's position according to its tikzitem's value
 /// </summary>
 public override bool AdjustPosition(Func<Point, Point> TikzToScreen)
 {
     Rect r = new Rect(0, 0, 0, 0);
     bool hasone = false;
     foreach (OverlayShapeVM o in children)
     {
         o.AdjustPosition(TikzToScreen);
         Rect rr = o.BB;
         if (hasone)
             r.Union(rr);
         else
         {
             r = rr;
             hasone = true;
         }
     }
     if (hasone)
     {
         r.Inflate(20, 20);
         //r = new Rect(10, 10, 100, 100);
         //ScopeView.SetSize(r.Width, r.Height);
         //ScopeView.SetPosition(r.X, r.Y);
         BB = r;
         return true;
     }
     else return false;
 }
Example #27
0
 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     var r = new Rect();
     ScreenHelper.AllScreens.Select(x => x.Bounds).ToList().ForEach(x => r.Union(x));
     Left = r.Left;
     Top = r.Top;
     Width = r.Width;
     Height = r.Height;
     _m.IsHooked = true;
     _m.MouseMove += m_MouseMove;
     _m.MouseUp += m_MouseUp;
     _m.MouseDown += m_MouseDown;
 }
Example #28
0
        internal static void CalcGeometryAndBounds(StrokeNodeIterator iterator,
                                                   DrawingAttributes drawingAttributes,
#if DEBUG_RENDERING_FEEDBACK
                                                   DrawingContext debugDC,
                                                   double feedbackSize,
                                                   bool showFeedback,
#endif
                                                   bool calculateBounds,
                                                   out Geometry geometry,
                                                   out Rect bounds)
        {

            Debug.Assert(iterator != null && drawingAttributes != null);

            //we can use our new algorithm for identity only.
            Matrix stylusTipTransform = drawingAttributes.StylusTipTransform;
            if (stylusTipTransform != Matrix.Identity && stylusTipTransform._type != MatrixTypes.TRANSFORM_IS_SCALING)
            {
                //second best optimization
                CalcGeometryAndBoundsWithTransform(iterator, drawingAttributes, stylusTipTransform._type, calculateBounds, out geometry, out bounds);
            }
            else
            {

                StreamGeometry streamGeometry = new StreamGeometry();
                streamGeometry.FillRule = FillRule.Nonzero;

                StreamGeometryContext context = streamGeometry.Open();
                geometry = streamGeometry;
                Rect empty = Rect.Empty;
                bounds = empty;
                try
                {
                    //
                    // We keep track of three StrokeNodes as we iterate across
                    // the Stroke. Since these are structs, the default ctor will
                    // be called and .IsValid will be false until we initialize them
                    //
                    StrokeNode emptyStrokeNode = new StrokeNode();
                    StrokeNode prevPrevStrokeNode = new StrokeNode();
                    StrokeNode prevStrokeNode = new StrokeNode();
                    StrokeNode strokeNode = new StrokeNode();

                    Rect prevPrevStrokeNodeBounds = empty;
                    Rect prevStrokeNodeBounds = empty;
                    Rect strokeNodeBounds = empty;

                    //percentIntersect is a function of drawingAttributes height / width
                    double percentIntersect = 95d;
                    double maxExtent = Math.Max(drawingAttributes.Height, drawingAttributes.Width);
                    percentIntersect += Math.Min(4.99999d, ((maxExtent / 20d) * 5d));

                    double prevAngle = double.MinValue;
                    bool isStartOfSegment = true;
                    bool isEllipse = drawingAttributes.StylusTip == StylusTip.Ellipse;
                    bool ignorePressure = drawingAttributes.IgnorePressure;
                    //
                    // Two List<Point>'s that get reused for adding figures
                    // to the streamgeometry.
                    //
                    List<Point> pathFigureABSide = new List<Point>();//don't prealloc.  It causes Gen2 collections to rise and doesn't help execution time
                    List<Point> pathFigureDCSide = new List<Point>();
                    List<Point> polyLinePoints =  new List<Point>(4);

                    int iteratorCount = iterator.Count;
                    for (int index = 0, previousIndex = -1; index < iteratorCount; )
                    {
                        if (!prevPrevStrokeNode.IsValid)
                        {
                            if (prevStrokeNode.IsValid)
                            {
                                //we're sliding our pointers forward
                                prevPrevStrokeNode = prevStrokeNode;
                                prevPrevStrokeNodeBounds = prevStrokeNodeBounds;
                                prevStrokeNode = emptyStrokeNode;
                            }
                            else
                            {
                                prevPrevStrokeNode = iterator[index++, previousIndex++];
                                prevPrevStrokeNodeBounds = prevPrevStrokeNode.GetBounds();
                                continue; //so we always check if index < iterator.Count
                            }
                        }

                        //we know prevPrevStrokeNode is valid
                        if (!prevStrokeNode.IsValid)
                        {
                            if (strokeNode.IsValid)
                            {
                                //we're sliding our pointers forward
                                prevStrokeNode = strokeNode;
                                prevStrokeNodeBounds = strokeNodeBounds;
                                strokeNode = emptyStrokeNode;
                            }
                            else
                            {
                                //get the next strokeNode, but don't automatically update previousIndex
                                prevStrokeNode = iterator[index++, previousIndex];
                                prevStrokeNodeBounds = prevStrokeNode.GetBounds();

                                RectCompareResult result = 
                                    FuzzyContains(  prevStrokeNodeBounds, 
                                                    prevPrevStrokeNodeBounds,
                                                    isStartOfSegment ? 99.99999d : percentIntersect);

                                if (result == RectCompareResult.Rect1ContainsRect2)
                                {
                                    // this node already contains the prevPrevStrokeNodeBounds (PP):
                                    //
                                    //  |------------|
                                    //  | |----|     |
                                    //  | | PP |  P  |                            
                                    //  | |----|     |
                                    //  |------------|
                                    //
                                    prevPrevStrokeNode = iterator[index - 1, prevPrevStrokeNode.Index - 1]; ;
                                    prevPrevStrokeNodeBounds = Rect.Union(prevStrokeNodeBounds, prevPrevStrokeNodeBounds);

                                    // at this point prevPrevStrokeNodeBounds already contains this node
                                    // we can just ignore this node
                                    prevStrokeNode = emptyStrokeNode;

                                    // update previousIndex to point to this node
                                    previousIndex = index - 1;

                                    // go back to our main loop
                                    continue;
                                }
                                else if (result == RectCompareResult.Rect2ContainsRect1)
                                {
                                    // this prevPrevStrokeNodeBounds (PP) already contains this node:
                                    //
                                    //  |------------|
                                    //  |      |----||
                                    //  |  PP  | P  ||                            
                                    //  |      |----||
                                    //  |------------|
                                    //

                                    //prevPrevStrokeNodeBounds already contains this node
                                    //we can just ignore this node
                                    prevStrokeNode = emptyStrokeNode;

                                    // go back to our main loop, but do not update previousIndex
                                    // because it should continue to point to previousPrevious
                                    continue;
                                }

                                Debug.Assert(!prevStrokeNode.GetConnectingQuad().IsEmpty, "prevStrokeNode.GetConnectingQuad() is Empty!");
                                
                                // if neither was true, we now have two of our three nodes required to 
                                // start our computation, we need to update previousIndex to point
                                // to our current, valid prevStrokeNode
                                previousIndex = index - 1;
                                continue; //so we always check if index < iterator.Count
                            }
                        }

                        //we know prevPrevStrokeNode and prevStrokeNode are both valid 
                        if (!strokeNode.IsValid)
                        {
                            strokeNode = iterator[index++, previousIndex];
                            strokeNodeBounds = strokeNode.GetBounds();

                            RectCompareResult result =
                                    FuzzyContains(  strokeNodeBounds,
                                                    prevStrokeNodeBounds,
                                                    isStartOfSegment ? 99.99999 : percentIntersect);

                            RectCompareResult result2 =
                                    FuzzyContains(  strokeNodeBounds,
                                                    prevPrevStrokeNodeBounds,
                                                    isStartOfSegment ? 99.99999 : percentIntersect);

                            if ( isStartOfSegment &&
                                 result == RectCompareResult.Rect1ContainsRect2 &&
                                 result2 == RectCompareResult.Rect1ContainsRect2)
                            {
                                if (pathFigureABSide.Count > 0)
                                {
                                    //we've started a stroke, we need to end it before resetting
                                    //prevPrev
#if DEBUG_RENDERING_FEEDBACK
                                    prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide, debugDC, feedbackSize, showFeedback);
#else
                                    prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide);
#endif
                                    //render
                                    ReverseDCPointsRenderAndClear(context, pathFigureABSide, pathFigureDCSide, polyLinePoints, isEllipse, true/*clear the point collections*/);
                                }
                                //we're resetting
                                //prevPrevStrokeNode.  We need to gen one
                                //without a connecting quad
                                prevPrevStrokeNode = iterator[index - 1, prevPrevStrokeNode.Index - 1];
                                prevPrevStrokeNodeBounds = prevPrevStrokeNode.GetBounds();
                                prevStrokeNode = emptyStrokeNode;
                                strokeNode = emptyStrokeNode;

                                // increment previousIndex to to point to this node
                                previousIndex = index - 1;
                                continue;

                            }
                            else if (result == RectCompareResult.Rect1ContainsRect2)
                            {
                                // this node (C) already contains the prevStrokeNodeBounds (P):
                                //
                                //          |------------|
                                //  |----|  | |----|     |
                                //  | PP |  | | P  |  C  |                            
                                //  |----|  | |----|     |
                                //          |------------|
                                //
                                //we have to generate a new stroke node that points
                                //to pp since the connecting quad from C to P could be empty
                                //if they have the same point
                                strokeNode = iterator[index - 1, prevStrokeNode.Index - 1];
                                if (!strokeNode.GetConnectingQuad().IsEmpty)
                                {
                                    //only update prevStrokeNode if we have a valid connecting quad
                                    prevStrokeNode = strokeNode;
                                    prevStrokeNodeBounds = Rect.Union(strokeNodeBounds, prevStrokeNodeBounds);

                                    // update previousIndex, since it should point to this node now
                                    previousIndex = index - 1;
                                }

                                // at this point we can just ignore this node
                                strokeNode = emptyStrokeNode;
                                //strokeNodeBounds = empty;

                                prevAngle = double.MinValue; //invalidate
                                
                                // go back to our main loop
                                continue;
                            }
                            else if (result == RectCompareResult.Rect2ContainsRect1)
                            {
                                // this prevStrokeNodeBounds (P) already contains this node (C):
                                //
                                //          |------------|
                                // |----|   |      |----||
                                // | PP |   |  P   | C  ||                            
                                // |----|   |      |----||
                                //          |------------|
                                //
                                //prevStrokeNodeBounds already contains this node
                                //we can just ignore this node
                                strokeNode = emptyStrokeNode;

                                // go back to our main loop, but do not update previousIndex
                                // because it should continue to point to previous
                                continue;
                            }

                            Debug.Assert(!strokeNode.GetConnectingQuad().IsEmpty, "strokeNode.GetConnectingQuad was empty, this is unexpected");

                            //
                            // NOTE: we do not check if C contains PP, or PP contains C because
                            // that indicates a change in direction, which we handle below
                            //
                            // if neither was true P and C are separate, 
                            // we now have all three nodes required to 
                            // start our computation, we need to update previousIndex to point
                            // to our current, valid prevStrokeNode
                            previousIndex = index - 1;
                        }


                        // see if we have an overlap between the first and third node
                        bool overlap = prevPrevStrokeNodeBounds.IntersectsWith(strokeNodeBounds);

                        // prevPrevStrokeNode, prevStrokeNode and strokeNode are all 
                        // valid nodes now.  Now we need to figure out what do add to our 
                        // PathFigure.  First calc bounds on the strokeNode we know we need to render
                        if (calculateBounds)
                        {
                            bounds.Union(prevStrokeNodeBounds);
                        }

                        // determine what points to add to pathFigureABSide and pathFigureDCSide
                        // from prevPrevStrokeNode
                        if (pathFigureABSide.Count == 0)
                        {
                            Debug.Assert(pathFigureDCSide.Count == 0);
                            if (calculateBounds)
                            {
                                bounds.Union(prevPrevStrokeNodeBounds);
                            }

                            if (isStartOfSegment && overlap)
                            {
                                //render a complete first stroke node or we can get artifacts
                                prevPrevStrokeNode.GetContourPoints(polyLinePoints);
                                AddFigureToStreamGeometryContext(context, polyLinePoints, prevPrevStrokeNode.IsEllipse/*isBezierFigure*/);
                                polyLinePoints.Clear();
                            }

                            // we're starting a new pathfigure
                            // we need to add parts of the prevPrevStrokeNode contour
                            // to pathFigureABSide and pathFigureDCSide
#if DEBUG_RENDERING_FEEDBACK
                            prevStrokeNode.GetPointsAtStartOfSegment(pathFigureABSide, pathFigureDCSide, debugDC, feedbackSize, showFeedback);
#else
                            prevStrokeNode.GetPointsAtStartOfSegment(pathFigureABSide, pathFigureDCSide);
#endif

                            //set our marker, we're no longer at the start of the stroke
                            isStartOfSegment = false;
                        }

                        

                        if (prevAngle == double.MinValue)
                        {
                            //prevAngle is no longer valid
                            prevAngle = GetAngleBetween(prevPrevStrokeNode.Position, prevStrokeNode.Position);
                        }
                        double delta = GetAngleDeltaFromLast(prevStrokeNode.Position, strokeNode.Position, ref prevAngle);
                        bool directionChangedOverAbsoluteThreshold = Math.Abs(delta) > 90d && Math.Abs(delta) < (360d - 90d);
                        bool directionChangedOverOverlapThreshold = overlap && !(ignorePressure || strokeNode.PressureFactor == 1f) && Math.Abs(delta) > 30d && Math.Abs(delta) < (360d - 30d);

                        double prevArea = prevStrokeNodeBounds.Height * prevStrokeNodeBounds.Width;
                        double currArea = strokeNodeBounds.Height * strokeNodeBounds.Width;

                        bool areaChanged = !(prevArea == currArea && prevArea == (prevPrevStrokeNodeBounds.Height * prevPrevStrokeNodeBounds.Width));
                        bool areaChangeOverThreshold = false;
                        if (overlap && areaChanged)
                        {
                            if ((Math.Min(prevArea, currArea) / Math.Max(prevArea, currArea)) <= 0.90d)
                            {
                                //the min area is < 70% of the max area
                                areaChangeOverThreshold = true;
                            }
                        }

                        if (areaChanged || delta != 0.0d || index >= iteratorCount)
                        {
                            //the area changed between the three nodes OR there was an angle delta OR we're at the end 
                            //of the stroke...  either way, this is a significant node.  If not, we're going to drop it.
                            if ((overlap && (directionChangedOverOverlapThreshold || areaChangeOverThreshold)) ||
                                directionChangedOverAbsoluteThreshold)
                            {
                                //
                                // we need to stop the pathfigure at P
                                // and render the pathfigure
                                //
                                //  |--|      |--|    |--||--|   |------|
                                //  |PP|------|P |    |PP||P |   |PP P C| 
                                //  |--|      |--|    |--||--|   |------|
                                //           /           |C |          
                                //      |--|             |--|         
                                //      |C |               
                                //      |--|               


#if DEBUG_RENDERING_FEEDBACK
                                prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide, debugDC, feedbackSize, showFeedback);
#else
                                //end the figure
                                prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide);
#endif
                                //render
                                ReverseDCPointsRenderAndClear(context, pathFigureABSide, pathFigureDCSide, polyLinePoints, isEllipse, true/*clear the point collections*/);

                                if (areaChangeOverThreshold)
                                {
                                    //render a complete stroke node or we can get artifacts
                                    prevStrokeNode.GetContourPoints(polyLinePoints);
                                    AddFigureToStreamGeometryContext(context, polyLinePoints, prevStrokeNode.IsEllipse/*isBezierFigure*/);
                                    polyLinePoints.Clear();
                                }
                            }
                            else
                            {
                                //
                                // direction didn't change over the threshold, add the midpoint data
                                //  |--|      |--|
                                //  |PP|------|P | 
                                //  |--|      |--|
                                //                \
                                //                  |--| 
                                //                  |C | 
                                //                  |--| 
                                bool endSegment; //flag that tell us if we missed an intersection
#if DEBUG_RENDERING_FEEDBACK
                                strokeNode.GetPointsAtMiddleSegment(prevStrokeNode, delta, pathFigureABSide, pathFigureDCSide, out endSegment, debugDC, feedbackSize, showFeedback);
#else
                                strokeNode.GetPointsAtMiddleSegment(prevStrokeNode, delta, pathFigureABSide, pathFigureDCSide, out endSegment);
#endif
                                if (endSegment)
                                {
                                    //we have a missing intersection, we need to end the 
                                    //segment at P
#if DEBUG_RENDERING_FEEDBACK
                                    prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide, debugDC, feedbackSize, showFeedback);
#else
                                    //end the figure
                                    prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide);
#endif
                                    //render
                                    ReverseDCPointsRenderAndClear(context, pathFigureABSide, pathFigureDCSide, polyLinePoints, isEllipse, true/*clear the point collections*/);
                                }
                             }
                        }

                        //
                        // either way... slide our pointers forward, to do this, we simply mark 
                        // our first pointer as 'empty'
                        //
                        prevPrevStrokeNode = emptyStrokeNode;
                        prevPrevStrokeNodeBounds = empty;

                        
                    }

                    //
                    // anything left to render?
                    //
                    if (prevPrevStrokeNode.IsValid)
                    {
                        if (prevStrokeNode.IsValid)
                        {
                            if (calculateBounds)
                            {
                                bounds.Union(prevPrevStrokeNodeBounds);
                                bounds.Union(prevStrokeNodeBounds);
                            }
                            Debug.Assert(!strokeNode.IsValid);
                            //
                            // we never made it to strokeNode, render two points, OR 
                            // strokeNode was a dupe
                            //
                            if (pathFigureABSide.Count > 0)
                            {
#if DEBUG_RENDERING_FEEDBACK
                                prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide, debugDC, feedbackSize, showFeedback);
#else
                                //
                                // strokeNode was a dupe, we just need to render the end of the stroke
                                // which is at prevStrokeNode
                                //
                                prevStrokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide);
#endif
                                //render
                                ReverseDCPointsRenderAndClear(context, pathFigureABSide, pathFigureDCSide, polyLinePoints, isEllipse, false/*clear the point collections*/);
                            }
                            else
                            {
                                // we've only seen two points to render
                                Debug.Assert(pathFigureDCSide.Count == 0);
                                //contains all the logic to render two stroke nodes
                                RenderTwoStrokeNodes(   context,
                                                        prevPrevStrokeNode,
                                                        prevPrevStrokeNodeBounds,
                                                        prevStrokeNode,
                                                        prevStrokeNodeBounds,
                                                        pathFigureABSide,
                                                        pathFigureDCSide,
                                                        polyLinePoints
#if DEBUG_RENDERING_FEEDBACK
                                                       ,debugDC,
                                                       feedbackSize,
                                                       showFeedback
#endif
                                                    );

                            }
                        }
                        else
                        {
                            if (calculateBounds)
                            {
                                bounds.Union(prevPrevStrokeNodeBounds);
                            }

                            // we only have a single point to render
                            Debug.Assert(pathFigureABSide.Count == 0);
                            prevPrevStrokeNode.GetContourPoints(pathFigureABSide);
                            AddFigureToStreamGeometryContext(context, pathFigureABSide, prevPrevStrokeNode.IsEllipse/*isBezierFigure*/);

                        }
                    }
                    else if (prevStrokeNode.IsValid && strokeNode.IsValid)
                    {
                        if (calculateBounds)
                        {
                            bounds.Union(prevStrokeNodeBounds);
                            bounds.Union(strokeNodeBounds);
                        }

                        // typical case, we hit the end of the stroke
                        // see if we need to start a stroke, or just end one
                        if (pathFigureABSide.Count > 0)
                        {
#if DEBUG_RENDERING_FEEDBACK
                            strokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide, debugDC, feedbackSize, showFeedback);
#else
                            strokeNode.GetPointsAtEndOfSegment(pathFigureABSide, pathFigureDCSide);
#endif

                            //render
                            ReverseDCPointsRenderAndClear(context, pathFigureABSide, pathFigureDCSide, polyLinePoints, isEllipse, false/*clear the point collections*/);

                            if (FuzzyContains(strokeNodeBounds, prevStrokeNodeBounds, 70d) != RectCompareResult.NoItersection)
                            {
                                //render a complete stroke node or we can get artifacts
                                strokeNode.GetContourPoints(polyLinePoints);
                                AddFigureToStreamGeometryContext(context, polyLinePoints, strokeNode.IsEllipse/*isBezierFigure*/);
                            }
                        }
                        else
                        {
                            Debug.Assert(pathFigureDCSide.Count == 0);
                            //contains all the logic to render two stroke nodes
                            RenderTwoStrokeNodes(   context,
                                                    prevStrokeNode,
                                                    prevStrokeNodeBounds,
                                                    strokeNode,
                                                    strokeNodeBounds,
                                                    pathFigureABSide,
                                                    pathFigureDCSide,
                                                    polyLinePoints
#if DEBUG_RENDERING_FEEDBACK
                                                   ,debugDC,
                                                   feedbackSize,
                                                   showFeedback
#endif
                                                );

                        } 
                    }
                }
                finally
                {
                    context.Close();
                    geometry.Freeze();
                }
            }
        }
Example #29
0
    protected override Size ArrangeOverride( Size finalSize )
    {
      Rect finalRect = new Rect();

      if( _visibleElements == null )
      {
        LayoutItems( InternalChildren, finalSize );
      }

      foreach( DateElement child in _visibleElements )
      {
        if( IsScrolling )
        {
          Rect placement = new Rect( child.PlacementRectangle.Location, child.PlacementRectangle.Size );
          placement.Offset( -_offset );

          child.Element.Arrange( placement );
        }
        else
        {
          child.Element.Arrange( child.PlacementRectangle );
        }

        finalRect.Union( child.PlacementRectangle );
      }

      Size renderSize;

      if( Orientation == Orientation.Horizontal )
      {
        renderSize = new Size( finalSize.Width, finalRect.Size.Height );
      }
      else
      {
        renderSize = new Size( finalRect.Size.Width, finalSize.Height );
      }

      return renderSize;
    }
Example #30
0
        /// <summary>
        /// Calculate the StreamGeometry for the StrokeNodes.
        /// This method is one of our most sensitive perf paths.  It has been optimized to 
        /// create the minimum path figures in the StreamGeometry.  There are two structures
        /// we create for each point in a stroke, the strokenode and the connecting quad.  Adding
        /// strokenodes is very expensive later when MIL renders it, so this method has been optimized
        /// to only add strokenodes when either pressure changes, or the angle of the stroke changes.
        /// </summary>
        internal static void CalcGeometryAndBoundsWithTransform(StrokeNodeIterator iterator,
                                                               DrawingAttributes drawingAttributes,
                                                               MatrixTypes stylusTipMatrixType,
                                                               bool calculateBounds,
                                                               out Geometry geometry,
                                                               out Rect bounds)
        {
            Debug.Assert(iterator != null);
            Debug.Assert(drawingAttributes != null);

            StreamGeometry streamGeometry = new StreamGeometry();
            streamGeometry.FillRule = FillRule.Nonzero;

            StreamGeometryContext context = streamGeometry.Open();
            geometry = streamGeometry;
            bounds = Rect.Empty;
            try
            {
                List<Point> connectingQuadPoints = new List<Point>(iterator.Count * 4);

                //the index that the cb quad points are copied to
                int cdIndex = iterator.Count * 2;
                //the index that the ab quad points are copied to
                int abIndex = 0;
                for (int x = 0; x < cdIndex; x++)
                {
                    //initialize so we can start copying to cdIndex later
                    connectingQuadPoints.Add(new Point(0d, 0d));
                }

                List<Point> strokeNodePoints = new List<Point>();
                double lastAngle = 0.0d;
                bool previousPreviousNodeRendered = false;

                Rect lastRect = new Rect(0, 0, 0, 0);

                for (int index = 0; index < iterator.Count; index++)
                {
                    StrokeNode strokeNode = iterator[index];
                    System.Diagnostics.Debug.Assert(true == strokeNode.IsValid);

                    //the only code that calls this with !calculateBounds
                    //is dynamic rendering, which already draws enough strokeNodes
                    //to hide any visual artifacts.
                    //static rendering calculatesBounds, and we use those
                    //bounds below to figure out what angle to lay strokeNodes down for.
                    Rect strokeNodeBounds = strokeNode.GetBounds();
                    if (calculateBounds)
                    {
                        bounds.Union(strokeNodeBounds);
                    }

                    //if the angle between this and the last position has changed
                    //too much relative to the angle between the last+1 position and the last position
                    //we need to lay down stroke node
                    double delta = Math.Abs(GetAngleDeltaFromLast(strokeNode.PreviousPosition, strokeNode.Position, ref lastAngle));

                    double angleTolerance = 45d;
                    if (stylusTipMatrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN)
                    {
                        //probably a skew is thrown in, we need to fall back to being very conservative 
                        //about how many strokeNodes we prune
                        angleTolerance = 10d;
                    }
                    else if (strokeNodeBounds.Height > 40d || strokeNodeBounds.Width > 40d)
                    {
                        //if the strokeNode gets above a certain size, we need to lay down more strokeNodes
                        //to prevent visual artifacts
                        angleTolerance = 20d;
                    }
                    bool directionChanged = delta > angleTolerance && delta < (360d - angleTolerance);

                    double prevArea = lastRect.Height * lastRect.Width;
                    double currArea = strokeNodeBounds.Height * strokeNodeBounds.Width;
                    bool areaChangedOverThreshold = false;
                    if ((Math.Min(prevArea, currArea) / Math.Max(prevArea, currArea)) <= 0.70d)
                    {
                        //the min area is < 70% of the max area
                        areaChangedOverThreshold = true;
                    }

                    lastRect = strokeNodeBounds;

                    //render the stroke node for the first two nodes and last two nodes always
                    if (index <= 1 || index >= iterator.Count - 2 || directionChanged || areaChangedOverThreshold)
                    {
                        //special case... the direction has changed and we need to 
                        //insert a stroke node in the StreamGeometry before we render the current one
                        if (directionChanged && !previousPreviousNodeRendered && index > 1 && index < iterator.Count - 1)
                        {
                            //insert a stroke node for the previous node
                            strokeNodePoints.Clear();
                            strokeNode.GetPreviousContourPoints(strokeNodePoints);
                            AddFigureToStreamGeometryContext(context, strokeNodePoints, strokeNode.IsEllipse/*isBezierFigure*/);

                            previousPreviousNodeRendered = true;
                        }

                        //render the stroke node
                        strokeNodePoints.Clear();
                        strokeNode.GetContourPoints(strokeNodePoints);
                        AddFigureToStreamGeometryContext(context, strokeNodePoints, strokeNode.IsEllipse/*isBezierFigure*/);
                    }

                    if (!directionChanged)
                    {
                        previousPreviousNodeRendered = false;
                    }

                    //add the end points of the connecting quad
                    Quad quad = strokeNode.GetConnectingQuad();
                    if (!quad.IsEmpty)
                    {
                        connectingQuadPoints[abIndex++] = quad.A;
                        connectingQuadPoints[abIndex++] = quad.B;
                        connectingQuadPoints.Add(quad.D);
                        connectingQuadPoints.Add(quad.C);
                    }

                    if (strokeNode.IsLastNode)
                    {
                        Debug.Assert(index == iterator.Count - 1);
                        if (abIndex > 0)
                        {
                            //we added something to the connecting quad points.
                            //now we need to do three things
                            //1) Shift the dc points down to the ab points
                            int cbStartIndex = iterator.Count * 2;
                            int cbEndIndex = connectingQuadPoints.Count - 1;
                            for (int i = abIndex, j = cbStartIndex; j <= cbEndIndex; i++, j++)
                            {
                                connectingQuadPoints[i] = connectingQuadPoints[j];
                            }

                            //2) trim the exess off the end of the array
                            int countToRemove = cbStartIndex - abIndex;
                            connectingQuadPoints.RemoveRange((cbEndIndex - countToRemove) + 1, countToRemove);

                            //3) reverse the dc points to make them cd points
                            for (int i = abIndex, j = connectingQuadPoints.Count - 1; i < j; i++, j--)
                            {
                                Point temp = connectingQuadPoints[i];
                                connectingQuadPoints[i] = connectingQuadPoints[j];
                                connectingQuadPoints[j] = temp;
                            }

                            //now render away!
                            AddFigureToStreamGeometryContext(context, connectingQuadPoints, false/*isBezierFigure*/);
                        }
                    }
                }
            }
            finally
            {
                context.Close();
                geometry.Freeze();
            }
        }
Example #31
0
        void DynamoViewModelRequestSaveImage(object sender, ImageSaveEventArgs e)
        {
            if (string.IsNullOrEmpty(e.Path))
                return;

            var workspace = dynamoViewModel.Model.CurrentWorkspace;
            if (workspace == null)
                return;

            if (!workspace.Nodes.Any() && (!workspace.Notes.Any()))
                return; // An empty graph.

            var initialized = false;
            var bounds = new Rect();

            var dragCanvas = WpfUtilities.ChildOfType<DragCanvas>(this);
            var childrenCount = VisualTreeHelper.GetChildrenCount(dragCanvas);
            for (int index = 0; index < childrenCount; ++index)
            {
                var child = VisualTreeHelper.GetChild(dragCanvas, index);
                var firstChild = VisualTreeHelper.GetChild(child, 0);
                if ((!(firstChild is NodeView)) && (!(firstChild is NoteView)))
                    continue;

                var childBounds = VisualTreeHelper.GetDescendantBounds(child as Visual);
                childBounds.X = (double)(child as Visual).GetValue(Canvas.LeftProperty);
                childBounds.Y = (double)(child as Visual).GetValue(Canvas.TopProperty);

                if (initialized)
                    bounds.Union(childBounds);
                else
                {
                    initialized = true;
                    bounds = childBounds;
                }
            }

            // Add padding to the edge and make them multiples of two.
            bounds.Width = (((int)Math.Ceiling(bounds.Width)) + 1) & ~0x01;
            bounds.Height = (((int)Math.Ceiling(bounds.Height)) + 1) & ~0x01;

            var drawingVisual = new DrawingVisual();
            using (var drawingContext = drawingVisual.RenderOpen())
            {
                var targetRect = new Rect(0, 0, bounds.Width, bounds.Height);
                var visualBrush = new VisualBrush(dragCanvas);
                drawingContext.DrawRectangle(visualBrush, null, targetRect);

                // drawingContext.DrawRectangle(null, new Pen(Brushes.Blue, 1.0), childBounds);
            }

            // var m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
            // region.Scale(m.M11, m.M22);

            var rtb = new RenderTargetBitmap(((int)bounds.Width),
                ((int)bounds.Height), 96, 96, PixelFormats.Default);

            rtb.Render(drawingVisual);

            //endcode as PNG
            var pngEncoder = new PngBitmapEncoder();
            pngEncoder.Frames.Add(BitmapFrame.Create(rtb));

            try
            {
                using (var stm = File.Create(e.Path))
                {
                    pngEncoder.Save(stm);
                }
            }
            catch
            {
                dynamoViewModel.Model.Logger.Log(Wpf.Properties.Resources.MessageFailedToSaveAsImage);
            }
        }
Example #32
0
 /// <summary>
 /// Union - Return the result of the union of rect1 and rect2.
 /// </summary>
 public static Rect Union(Rect rect1, Rect rect2)
 {
     rect1.Union(rect2);
     return(rect1);
 }