/// <summary> /// Calculates the element's rendered size. /// </summary> /// <param name="element">The element to measure.</param> /// <returns>The rendered size.</returns> public static Size GetRenderedSize(FrameworkElement element) { if (element == null) { throw new ArgumentNullException("element"); } double width = element.ActualWidth; double height = element.ActualHeight; MatrixTransform t = GetGlobalTransformation(element); Point upperLeft = t.Transform(new Point(0, 0)); Point upperRight = t.Transform(new Point(width, 0)); Point lowerLeft = t.Transform(new Point(0, height)); Point lowerRight = t.Transform(new Point(width, height)); List <Point> allBoundingPoints = new List <Point>() { upperLeft, upperRight, lowerLeft, lowerRight }; var minBoundingX = allBoundingPoints.Min(point => point.X); var minBoundingY = allBoundingPoints.Min(point => point.Y); var maxBoundingX = allBoundingPoints.Max(point => point.X); var maxBoundingY = allBoundingPoints.Max(point => point.Y); Size s = new Size(maxBoundingX - minBoundingX, maxBoundingY - minBoundingY); return(s); }
private Point GetScaledValue(DataValue d) { double availableHeight = this.ActualHeight - 1; Point point = scaleTransform.Transform(new Point(d.X, d.Y)); return(new Point(point.X, availableHeight - point.Y)); }
/// <summary> /// Gets the resolution in DPI of the target device of a visual. /// </summary> static public Point GetResolution(Visual visual) { Point dpi = new Point(120, 120); PresentationSource source = PresentationSource.FromVisual(visual); if (source == null) { return(dpi); } CompositionTarget target = source.CompositionTarget; Matrix m = target.TransformToDevice; MatrixTransform t = new MatrixTransform(m); Point pt1 = new Point(0, 0); pt1 = t.Transform(pt1); Point pt2 = new Point(96, 96); pt2 = t.Transform(pt2); dpi.X = pt2.X - pt1.X; dpi.Y = pt2.Y - pt1.Y; return(dpi); }
void Manipulation(ManipulationDeltaEventArgs e) { var mt = new MatrixTransform(ShapeUtils.GetTransform(e)); var Point1 = mt.Transform(new Point(line.X1, line.Y1)); var Point2 = mt.Transform(new Point(line.X2, line.Y2)); line.X1 = Point1.X; line.Y1 = Point1.Y; line.X2 = Point2.X; line.Y2 = Point2.Y; }
private void Manipulation(ManipulationDeltaEventArgs e) { var mt = new MatrixTransform(ShapeUtils.GetTransform(e)); var newTopLeft = mt.Transform(getBadgePos()); setBadgePos(newTopLeft.X, newTopLeft.Y); }
internal override void BeforeArrange() { graphToCanvas.Matrix = new Matrix(xAxis.Scale, 0, 0, -yAxis.Scale, -xAxis.Offset - xAxis.AxisPadding.Lower, yAxis.Offset + yAxis.AxisTotalLength - yAxis.AxisPadding.Upper); canvasToGraph = (MatrixTransform)(graphToCanvas.Inverse); Curve.FilterMinMax(canvasToGraph, new Rect(new Point(xAxis.Min, yAxis.Min), new Point(xAxis.Max, yAxis.Max))); if (host.UseDirect2D == true && !host.direct2DControl.InitializationFailed) { lineD2D.Geometry = curve.ToDirect2DPathGeometry(lineD2D.Factory, graphToCanvas); markersD2D.SetGeometry((MarkersType)GetValue(MarkersTypeProperty), (double)GetValue(MarkersSizeProperty)); //host.direct2DControl.RequestRender(); } else { line.Data = LineGeometries.PathGeometryFromCurve(curve, graphToCanvas); markers.Data = MarkerGeometries.MarkersAsGeometry(Curve, graphToCanvas, (MarkersType)GetValue(MarkersTypeProperty), (double)GetValue(MarkersSizeProperty)); } Point annotationPoint = graphToCanvas.Transform(new Point(curve.xTransformed[0], curve.yTransformed[0])); annotation.SetValue(Canvas.TopProperty, annotationPoint.Y); annotation.SetValue(Canvas.LeftProperty, annotationPoint.X); }
private void AddScaledValues(PathFigure figure, int start, int end) { double height = this.ActualHeight - 1; double availableHeight = height; double width = this.ActualWidth; int len = series.Values.Count; double offset = Canvas.GetLeft(Graph); bool started = (figure.Segments.Count > 0); for (int i = start; i < end; i++) { DataValue d = series.Values[i]; // add graph segment Point point = scaleTransform.Transform(new Point(d.X, d.Y)); point = zoomTransform.Transform(point); double y = availableHeight - point.Y; double x = point.X; double rx = x + offset; if (rx > 0) { Point pt = new Point(x, y); if (!started) { figure.StartPoint = pt; started = true; } else { figure.Segments.Add(new LineSegment() { Point = pt }); } } } }
protected override void OnRender(DrawingContext dc) { // Draw background dc.DrawRectangle(Brushes.White, null, new Rect(RenderSize)); Transform t = new MatrixTransform(TheModel.GetTikzToScreenTransform().ToWpfMatrix()); t.Freeze(); Pen pen = new Pen(Brushes.WhiteSmoke, 1); pen.Freeze(); TheModel.DrawRaster( (p1, p2) => dc.DrawLine(pen, t.Transform(p1), t.Transform(p2)), (r1, r2) => { EllipseGeometry eg = new EllipseGeometry(new Point(0, 0), r1, r2); eg.Transform = t; eg.Freeze(); dc.DrawGeometry(null, pen, eg); }); }
public Point GetPlacementTargetOffset() { Point offset = new Point(); FrameworkElement target = ExtensionSurface.GetPlacementTarget(this); if (null != target) { FrameworkElement commonRoot = target.FindCommonVisualAncestor(this) as FrameworkElement; MatrixTransform transform = (MatrixTransform)target.TransformToAncestor(commonRoot); Point targetPosition = transform.Transform(new Point()); Point windowPosition = ExtensionSurface.GetPosition(this); offset.X = targetPosition.X - windowPosition.X; offset.Y = targetPosition.Y - windowPosition.Y; } return(offset); }
public static List <Point> Generate(int n = 1000, double width = 1.0, double height = 1.0) { // Probabilities double[] p = { 0.85, .92, .99, 1.00 }; // Transformations var a1 = new MatrixTransform(new System.Windows.Media.Matrix(0.85, -0.04, 0.04, 0.85, 0, 1.6)); var a2 = new MatrixTransform(new System.Windows.Media.Matrix(0.20, 0.23, -0.26, 0.22, 0, 1.6)); var a3 = new MatrixTransform(new System.Windows.Media.Matrix(-0.15, 0.26, 0.28, 0.24, 0, 0.44)); var a4 = new MatrixTransform(new System.Windows.Media.Matrix(0, 0, 0, 0.16, 0, 0)); var random = new Random(17); var point = new Point(0.5, 0.5); var points = new List <Point>(); // Transformation for [-3,3,0,10] => output coordinates var T = new MatrixTransform(new System.Windows.Media.Matrix(width / 6.0, 0, 0, -height / 10.1, width / 2.0, height)); for (int i = 0; i < n; i++) { var r = random.NextDouble(); if (r < p[0]) { point = a1.Transform(point); } else if (r < p[1]) { point = a2.Transform(point); } else if (r < p[2]) { point = a3.Transform(point); } else { point = a4.Transform(point); } points.Add(T.Transform(point)); } return(points); }
private void viewport_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e) { if (e.PinchManipulation != null) { double newWidth, newHieght; if (m_Width < m_Height) // box new size between image size and viewport actual size { newHieght = m_Height * m_Zoom * e.PinchManipulation.CumulativeScale; newHieght = Math.Max(viewport.ActualHeight, newHieght); newHieght = Math.Min(newHieght, m_Height); newWidth = newHieght * m_Width / m_Height; } else { newWidth = m_Width * m_Zoom * e.PinchManipulation.CumulativeScale; newWidth = Math.Max(viewport.ActualWidth, newWidth); newWidth = Math.Min(newWidth, m_Width); newHieght = newWidth * m_Height / m_Width; } if (newWidth < m_Width && newHieght < m_Height) { // Tells image positione in viewport (offset) MatrixTransform transform = image.TransformToVisual(viewport) as MatrixTransform; // Calculate center of pinch gesture on image (not screen) Point pinchCenterOnImage = transform.Transform(e.PinchManipulation.Original.Center); // Calculate relative point (0-1) of pinch center in image Point relativeCenter = new Point(e.PinchManipulation.Original.Center.X / image.Width, e.PinchManipulation.Original.Center.Y / image.Height); // Calculate and set new origin point of viewport Point newOriginPoint = new Point(relativeCenter.X * newWidth - pinchCenterOnImage.X, relativeCenter.Y * newHieght - pinchCenterOnImage.Y); viewport.SetViewportOrigin(newOriginPoint); } image.Width = newWidth; image.Height = newHieght; // Set new view port bound viewport.Bounds = new Rect(0, 0, newWidth, newHieght); } }
private void ViewportControl_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e) { if (e.PinchManipulation != null) { double newWidth, newHieght; if (m_Width < m_Height) { newHieght = m_Height * m_Zoom * e.PinchManipulation.CumulativeScale; newHieght = Math.Max(viewport.ActualHeight, newHieght); newHieght = Math.Min(newHieght, m_Height); newWidth = newHieght * m_Width / m_Height; } else { newWidth = m_Width * m_Zoom * e.PinchManipulation.CumulativeScale; newWidth = Math.Max(viewport.ActualWidth, newWidth); newWidth = Math.Min(newWidth, m_Width); newHieght = newWidth * m_Height / m_Width; } if (newWidth < m_Width && newHieght < m_Height) { MatrixTransform transform = map.TransformToVisual(viewport) as MatrixTransform; Point pinchCenterOnImage = transform.Transform(e.PinchManipulation.Original.Center); Point relativeCenter = new Point(e.PinchManipulation.Original.Center.X / map.Width, e.PinchManipulation.Original.Center.Y / map.Height); Point newOriginPoint = new Point(relativeCenter.X * newWidth - pinchCenterOnImage.X, relativeCenter.Y * newHieght - pinchCenterOnImage.Y); viewport.SetViewportOrigin(newOriginPoint); } _mapTransform.ScaleX = map.Width / m_Width; _mapTransform.ScaleY = map.Width / m_Width; map.Width = newWidth; map.Height = newHieght; viewport.Bounds = new Rect(0, 0, newWidth, newHieght); e.Handled = true; } }
internal int CurveIndexFromCanvasPoint(Point canvasPoint) { Point graphPoint = canvasToGraph.Transform(canvasPoint); double value = curve.SortedValues == SortedValues.X ? graphPoint.X : graphPoint.Y; int index = Curve.GetInterpolatedIndex(curve.TransformedSorted, value); if (index == (curve.xTransformed.Length - 1)) { return(curve.SortedToUnsorted[curve.xTransformed.Length - 1]); } // otherwise return nearest: if ((curve.TransformedSorted[index + 1] - value) < (value - curve.TransformedSorted[index])) { return(curve.SortedToUnsorted[index + 1]); } else { return(curve.SortedToUnsorted[index]); } }
public static Pt[] GetOutline(FrameworkElement elt, FrameworkElement parent) { if (parent == null) { return(new Pt[0]); } elt.UpdateLayout(); GeneralTransform trans = new MatrixTransform(Mat.Identity); try { trans = elt.TransformToAncestor(parent); } catch (System.InvalidOperationException ex) { } Pt[] bounds = new Pt[] { new Pt(), new Pt(elt.ActualWidth, 0), new Pt(elt.ActualWidth, elt.ActualHeight), new Pt(0, elt.ActualHeight) }; for (int i = 0; i < bounds.Length; i++) { bounds[i] = trans.Transform(bounds[i]); } return(bounds); }
void PlaceWindow(ExtensionWindow window) { if (null != window) { FrameworkElement target = ExtensionSurface.GetPlacementTarget(window); PositionAlignment alignment = ExtensionSurface.GetAlignment(window); PlacementMode mode = ExtensionSurface.GetMode(window); Point position = ExtensionSurface.GetPosition(window); Point calculatedPosition = new Point(); FrameworkElement commonRoot = null; MatrixTransform transform = null; switch (mode) { case PlacementMode.Relative: if (null != target) { commonRoot = target.FindCommonVisualAncestor(this) as FrameworkElement; if (null == commonRoot) { return; } transform = (MatrixTransform)target.TransformToAncestor(commonRoot); } else { if (!DesignerProperties.GetIsInDesignMode(this)) { Fx.Assert(string.Format(CultureInfo.InvariantCulture, "PlacementTarget must be set in RelativeMode on ExtensionSurface '{0}'", this.Name)); } } break; case PlacementMode.Absolute: calculatedPosition = position; break; default: Fx.Assert(string.Format(CultureInfo.CurrentCulture, "ExtensionWindowPlacement.Mode {0} specified in ExtensionWindow '{1}' is not supported for ExtensionSurface", mode, window.Name)); return; } if (PlacementMode.Relative == mode) { if (null != target) { double x; double y; switch (alignment) { case PositionAlignment.LeftTop: calculatedPosition = transform.Transform(calculatedPosition); break; case PositionAlignment.LeftBottom: calculatedPosition = transform.Transform(new Point(0.0, target.ActualHeight)); break; case PositionAlignment.RightTop: calculatedPosition = transform.Transform(new Point(target.ActualWidth, 0.0)); break; case PositionAlignment.RightBottom: calculatedPosition = transform.Transform(new Point(target.ActualWidth, target.ActualHeight)); break; case PositionAlignment.Center: calculatedPosition = transform.Transform(calculatedPosition); x = ((target.ActualWidth * transform.Matrix.M11) - window.Width) / 2.0; y = ((target.ActualHeight * transform.Matrix.M22) - window.Height) / 2.0; calculatedPosition.Offset(x, y); break; case PositionAlignment.CenterHorizontal: calculatedPosition = transform.Transform(calculatedPosition); x = ((target.ActualWidth * transform.Matrix.M11) - window.Width) / 2.0; calculatedPosition.Offset(x, 0.0); break; case PositionAlignment.CenterVertical: calculatedPosition = transform.Transform(calculatedPosition); y = ((target.ActualHeight * transform.Matrix.M22) - window.Height) / 2.0; calculatedPosition.Offset(0.0, y); break; default: Fx.Assert(string.Format(CultureInfo.CurrentCulture, "ExtensionWindowPlacement.Position = '{0}' is not supported", alignment)); return; } } } SetWindowPosition(window, calculatedPosition); } }
/// <summary> /// Transforms a geographic location to a viewport coordinates point. /// </summary> public Point LocationToViewportPoint(Location location) { return(viewportTransform.Transform(mapTransform.Transform(location))); }
protected override void OnDragDelta(object sender, DragDeltaEventArgs e) { double deltaVertical = 0, deltaHorizontal = 0; Point dragDelta = new Point(e.HorizontalChange, e.VerticalChange); dragDelta = GridManager.AdjustPointToGrid(dragDelta); Matrix m = ((Transform)this.TransformToVisual(_controlledItem)).Value; m.OffsetX = 0; m.OffsetY = 0; System.Windows.Media.Transform t = new MatrixTransform(m); dragDelta = t.Transform(dragDelta); Rect r = new Rect(Canvas.GetLeft(_controlledItem), Canvas.GetTop(_controlledItem), _controlledItem.Width, _controlledItem.Height); //r = GridManager.AdjustRectToGrid(r); switch (base.VerticalAlignment) { case System.Windows.VerticalAlignment.Bottom: deltaVertical = Math.Min(-dragDelta.Y, _controlledItem.ActualHeight - Height); r.Height -= deltaVertical; break; case System.Windows.VerticalAlignment.Top: deltaVertical = Math.Min(dragDelta.Y, _controlledItem.ActualHeight - Height); Point p = _controlledItem.RenderTransform.Transform(new Point(0, deltaVertical)); r.Y += p.Y; r.X += p.X; r.Height -= deltaVertical; break; default: break; } switch (base.HorizontalAlignment) { case System.Windows.HorizontalAlignment.Left: deltaHorizontal = Math.Min(dragDelta.X, _controlledItem.ActualWidth - Width); Point p = _controlledItem.RenderTransform.Transform(new Point(deltaHorizontal, 0)); r.Y += p.Y; r.X += p.X; r.Width -= deltaHorizontal; break; case System.Windows.HorizontalAlignment.Right: deltaHorizontal = Math.Min(-dragDelta.X, _controlledItem.ActualWidth - Width); r.Width -= deltaHorizontal; break; default: break; } Point sizeDelta = new Point(deltaHorizontal, deltaVertical); Point sizeDeltaTrans = _controlledItem.RenderTransform.Transform(sizeDelta); Vector v = sizeDelta - sizeDeltaTrans; r.X = r.X + v.X * _controlledItem.RenderTransformOrigin.X; r.Y = r.Y + v.Y * _controlledItem.RenderTransformOrigin.Y; EditorHelper.SetDependencyProperty(_controlledItem, Canvas.LeftProperty, r.X); EditorHelper.SetDependencyProperty(_controlledItem, Canvas.TopProperty, r.Y); EditorHelper.SetDependencyProperty(_controlledItem, FrameworkElement.WidthProperty, r.Width); EditorHelper.SetDependencyProperty(_controlledItem, FrameworkElement.HeightProperty, r.Height); }
/// <summary> /// Draws a mouse cursor on the adorened element /// </summary> /// <param name="drawingContext"></param> protected override void OnRender(DrawingContext drawingContext) { GeneralTransform inverse = elementTransform.Inverse; if (inverse == null) { return; } Brush blackBrush = new SolidColorBrush(Colors.Black); float radius = 15; if (locked) { // Draw the little circle around the lock point Point point = elementTransform.Transform(lockPoint); drawingContext.DrawEllipse(null, new Pen(blackBrush, 3), point, 2.5, 2.5); drawingContext.DrawEllipse(null, new Pen(new SolidColorBrush(Colors.White), 2), point, 2.5, 2.5); // Draw the big yellow circle var yellowPen = new Pen(new SolidColorBrush(Colors.Yellow), 2); var blackPen = new Pen(blackBrush, 3); drawingContext.DrawEllipse(null, blackPen, mousePoint, radius, radius); drawingContext.DrawEllipse(null, yellowPen, mousePoint, radius, radius); } else { // Draw the target symbol var blackPen = new Pen(blackBrush, .7); drawingContext.DrawEllipse(null, blackPen, mousePoint, radius, radius); drawingContext.DrawLine(blackPen, new Point(mousePoint.X - radius * 1.6, mousePoint.Y), new Point(mousePoint.X - 2, mousePoint.Y)); drawingContext.DrawLine(blackPen, new Point(mousePoint.X + radius * 1.6, mousePoint.Y), new Point(mousePoint.X + 2, mousePoint.Y)); drawingContext.DrawLine(blackPen, new Point(mousePoint.X, mousePoint.Y - radius * 1.6), new Point(mousePoint.X, mousePoint.Y - 2)); drawingContext.DrawLine(blackPen, new Point(mousePoint.X, mousePoint.Y + radius * 1.6), new Point(mousePoint.X, mousePoint.Y + 2)); } // Draw the coordinate text // Works out the number of decimal places required to show the difference between // 2 pixels. E.g if pixels are .1 apart then use 2 places etc Rect rect = inverse.TransformBounds(new Rect(0, 0, 1, 1)); int xFigures = Math.Max(1, (int)(Math.Ceiling(-Math.Log10(rect.Width)) + .1)); int yFigures = Math.Max(1, (int)(Math.Ceiling(-Math.Log10(rect.Height)) + .1)); // Number of significant figures for the x coordinate string xFormat = "#0." + new string('#', xFigures); /// Number of significant figures for the y coordinate string yFormat = "#0." + new string('#', yFigures); Point coordinate = locked ? lockPoint : inverse.Transform(mousePoint); string coordinateText = coordinate.X.ToString(xFormat) + "," + coordinate.Y.ToString(yFormat); if (flipYAxis) { drawingContext.PushTransform(new ScaleTransform(1, 1)); } else { drawingContext.PushTransform(new ScaleTransform(1, -1)); } var formattedText = new FormattedText(coordinateText, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Arial"), 10, blackBrush); var textBoxPen = new Pen(new SolidColorBrush(Color.FromArgb(127, 255, 255, 255)), 1); Rect textBoxRect = flipYAxis ? new Rect(new Point(mousePoint.X + radius * .7, mousePoint.Y + radius * .7), new Size(formattedText.Width, formattedText.Height)) : new Rect(new Point(mousePoint.X + radius * .7, -mousePoint.Y + radius * .7), new Size(formattedText.Width, formattedText.Height)); double diff = textBoxRect.Right + 3 - ((FrameworkElement)AdornedElement).ActualWidth; if (diff > 0) { textBoxRect.Location = new Point(textBoxRect.Left - diff, textBoxRect.Top); } drawingContext.DrawRectangle(textBoxPen.Brush, textBoxPen, textBoxRect); drawingContext.DrawText(formattedText, textBoxRect.Location); drawingContext.Pop(); }
/// <summary> /// Renders a bitmap using any affine transformation and transparency into this bitmap /// Unlike Silverlight's Render() method, this one uses 2-3 times less memory, and is the same or better quality /// The algorithm is simple dx/dy (bresenham-like) step by step painting, optimized with fixed point and fast bilinear filtering /// It's used in Fantasia Painter for drawing stickers and 3D objects on screen /// </summary> /// <param name="bmp">Destination bitmap.</param> /// <param name="source">The source WriteableBitmap.</param> /// <param name="shouldClear">If true, the the destination bitmap will be set to all clear (0) before rendering.</param> /// <param name="opacity">opacity of the source bitmap to render, between 0 and 1 inclusive</param> /// <param name="transform">Transformation to apply</param> public static void BlitRender(this BitmapBuffer bmp, BitmapBuffer source, bool shouldClear = true, float opacity = 1f, GeneralTransform transform = null) { const int PRECISION_SHIFT = 10; const int PRECISION_VALUE = (1 << PRECISION_SHIFT); const int PRECISION_MASK = PRECISION_VALUE - 1; using (BitmapContext destContext = bmp.GetBitmapContext()) { if (transform == null) { transform = new MatrixTransform(Affine.IdentityMatrix); } int[] destPixels = destContext.Pixels; int destWidth = destContext.Width; int destHeight = destContext.Height; MatrixTransform inverse = transform.Inverse; if (shouldClear) { destContext.Clear(); } using (BitmapContext sourceContext = source.GetBitmapContext(ReadWriteMode.ReadOnly)) { var sourcePixels = sourceContext.Pixels; int sourceWidth = sourceContext.Width; int sourceHeight = sourceContext.Height; RectD sourceRect = new RectD(0, 0, sourceWidth, sourceHeight); RectD destRect = new RectD(0, 0, destWidth, destHeight); RectD bounds = transform.TransformBounds(sourceRect); bounds.Intersect(destRect); int startX = (int)bounds.Left; int startY = (int)bounds.Top; int endX = (int)bounds.Right; int endY = (int)bounds.Bottom; #if NETFX_CORE Point zeroZero = inverse.TransformPoint(new Point(startX, startY)); Point oneZero = inverse.TransformPoint(new Point(startX + 1, startY)); Point zeroOne = inverse.TransformPoint(new Point(startX, startY + 1)); #else PointD zeroZero = inverse.Transform(new PointD(startX, startY)); PointD oneZero = inverse.Transform(new PointD(startX + 1, startY)); PointD zeroOne = inverse.Transform(new PointD(startX, startY + 1)); #endif float sourceXf = ((float)zeroZero.X); float sourceYf = ((float)zeroZero.Y); int dxDx = (int)((((float)oneZero.X) - sourceXf) * PRECISION_VALUE); // for 1 unit in X coord, how much does X change in source texture? int dxDy = (int)((((float)oneZero.Y) - sourceYf) * PRECISION_VALUE); // for 1 unit in X coord, how much does Y change in source texture? int dyDx = (int)((((float)zeroOne.X) - sourceXf) * PRECISION_VALUE); // for 1 unit in Y coord, how much does X change in source texture? int dyDy = (int)((((float)zeroOne.Y) - sourceYf) * PRECISION_VALUE); // for 1 unit in Y coord, how much does Y change in source texture? int sourceX = (int)(((float)zeroZero.X) * PRECISION_VALUE); int sourceY = (int)(((float)zeroZero.Y) * PRECISION_VALUE); int sourceWidthFixed = sourceWidth << PRECISION_SHIFT; int sourceHeightFixed = sourceHeight << PRECISION_SHIFT; int opacityInt = (int)(opacity * 255); int index = 0; for (int destY = startY; destY < endY; destY++) { index = destY * destWidth + startX; int savedSourceX = sourceX; int savedSourceY = sourceY; for (int destX = startX; destX < endX; destX++) { if ((sourceX >= 0) && (sourceX < sourceWidthFixed) && (sourceY >= 0) && (sourceY < sourceHeightFixed)) { // bilinear filtering int xFloor = sourceX >> PRECISION_SHIFT; int yFloor = sourceY >> PRECISION_SHIFT; if (xFloor < 0) { xFloor = 0; } if (yFloor < 0) { yFloor = 0; } int xCeil = xFloor + 1; int yCeil = yFloor + 1; if (xCeil >= sourceWidth) { xFloor = sourceWidth - 1; xCeil = 0; } else { xCeil = 1; } if (yCeil >= sourceHeight) { yFloor = sourceHeight - 1; yCeil = 0; } else { yCeil = sourceWidth; } int i1 = yFloor * sourceWidth + xFloor; int p1 = sourcePixels[i1]; int p2 = sourcePixels[i1 + xCeil]; int p3 = sourcePixels[i1 + yCeil]; int p4 = sourcePixels[i1 + yCeil + xCeil]; int xFrac = sourceX & PRECISION_MASK; int yFrac = sourceY & PRECISION_MASK; // alpha byte a1 = (byte)(p1 >> 24); byte a2 = (byte)(p2 >> 24); byte a3 = (byte)(p3 >> 24); byte a4 = (byte)(p4 >> 24); int comp1, comp2; byte a; if ((a1 == a2) && (a1 == a3) && (a1 == a4)) { if (a1 == 0) { destPixels[index] = 0; sourceX += dxDx; sourceY += dxDy; index++; continue; } a = a1; } else { comp1 = a1 + ((xFrac * (a2 - a1)) >> PRECISION_SHIFT); comp2 = a3 + ((xFrac * (a4 - a3)) >> PRECISION_SHIFT); a = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); } // red comp1 = ((byte)(p1 >> 16)) + ((xFrac * (((byte)(p2 >> 16)) - ((byte)(p1 >> 16)))) >> PRECISION_SHIFT); comp2 = ((byte)(p3 >> 16)) + ((xFrac * (((byte)(p4 >> 16)) - ((byte)(p3 >> 16)))) >> PRECISION_SHIFT); byte r = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); // green comp1 = ((byte)(p1 >> 8)) + ((xFrac * (((byte)(p2 >> 8)) - ((byte)(p1 >> 8)))) >> PRECISION_SHIFT); comp2 = ((byte)(p3 >> 8)) + ((xFrac * (((byte)(p4 >> 8)) - ((byte)(p3 >> 8)))) >> PRECISION_SHIFT); byte g = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); // blue comp1 = ((byte)p1) + ((xFrac * (((byte)p2) - ((byte)p1))) >> PRECISION_SHIFT); comp2 = ((byte)p3) + ((xFrac * (((byte)p4) - ((byte)p3))) >> PRECISION_SHIFT); byte b = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT)); // save updated pixel if (opacityInt != 255) { a = (byte)((a * opacityInt) >> 8); r = (byte)((r * opacityInt) >> 8); g = (byte)((g * opacityInt) >> 8); b = (byte)((b * opacityInt) >> 8); } destPixels[index] = (a << 24) | (r << 16) | (g << 8) | b; } sourceX += dxDx; sourceY += dxDy; index++; } sourceX = savedSourceX + dyDx; sourceY = savedSourceY + dyDy; } } } }
private void LoadSampleLinesData(double lineThickness, Rect targetRect) { // Read many lines from a custom bin file format. // The bin file was created from a metafile (wmf) file that was read by Ab2d.ReaderWmf, // then the lines were grouped by color and saved to a custom bin file. Rect bounds; var lines = ReadLineDataFromBin(AppDomain.CurrentDomain.BaseDirectory + @"Resources\palazz_sport.bin", out bounds); Point targetCenter = new Point(targetRect.X + targetRect.Width * 0.5, targetRect.Y + targetRect.Height * 0.5); double xScale = targetRect.Width / bounds.Width; double yScale = targetRect.Height / bounds.Height; double scale = Math.Min(xScale, yScale); // Preserve aspect ratio - so use the minimal scale double xOffset = targetCenter.X - bounds.Width * scale * 0.5; double yOffset = targetCenter.Y + bounds.Height * scale * 0.5; // targetCenter.Y - bounds.Height * scale * 0.5 + bounds.Height * scale // because we flipped y we need to offset by height var matrixTransform = new MatrixTransform(scale, 0, 0, -scale, // We also need to flip y axis because here y axis is pointing up xOffset, yOffset); for (var i = 0; i < lines.Count; i++) { var oneLineData = lines[i]; var positions = oneLineData.Positions; var point3DCollection = new Point3DCollection(positions.Count); for (var j = 0; j < positions.Count; j++) { var p = new Point(positions[j].X, positions[j].Y); p = matrixTransform.Transform(p); point3DCollection.Add(new Point3D(p.X, p.Y, 0)); } if (oneLineData.IsLineStrip) { var polyLineVisual3D = new PolyLineVisual3D() { Positions = point3DCollection, LineColor = oneLineData.LineColor, LineThickness = lineThickness < 0 ? oneLineData.LineThickness : lineThickness }; RootLinesVisual3D.Children.Add(polyLineVisual3D); } else { var multiLineVisual3D = new MultiLineVisual3D() { Positions = point3DCollection, LineColor = oneLineData.LineColor, LineThickness = lineThickness < 0 ? oneLineData.LineThickness : lineThickness }; RootLinesVisual3D.Children.Add(multiLineVisual3D); } } }