/// <summary> /// Applies the specified old data rect. /// </summary> /// <param name="oldDataRect">The old data rect.</param> /// <param name="newDataRect">The new data rect.</param> /// <param name="viewport">The viewport.</param> /// <returns></returns> /// public override Rect Apply(Rect oldDataRect, Rect newDataRect, Viewport2D viewport) { DataRect res = domain; if (domain.IsEmpty) { res = newDataRect; } else if (newDataRect.IntersectsWith(domain)) { res = newDataRect; if (newDataRect.Size == oldDataRect.Size) { if (res.XMin < domain.XMin) res.XMin = domain.XMin; if (res.YMin < domain.YMin) res.YMin = domain.YMin; if (res.XMax > domain.XMax) res.XMin += domain.XMax - res.XMax; if (res.YMax > domain.YMax) res.YMin += domain.YMax - res.YMax; } else { newDataRect.Intersect(domain); res = newDataRect; } } return res; }
internal static Point GetCoordinatesInView(this FrameworkElement element, UIElement visualRoot) { var point = element.TransformToVisual(visualRoot).Transform(new Point(0, 0)); var center = new Point(point.X + (int)(element.ActualWidth / 2), point.Y + (int)(element.ActualHeight / 2)); var bounds = new Rect(point, new Size(element.ActualWidth, element.ActualHeight)); var boundsInView = new Rect(new Point(0, 0), visualRoot.RenderSize); boundsInView.Intersect(bounds); return boundsInView.IsEmpty ? center : new Point(boundsInView.X + (int)(boundsInView.Width / 2), boundsInView.Y + (int)(boundsInView.Height / 2)); }
internal static bool IsUserVisible(this FrameworkElement element, UIElement visualRoot) { var zero = new Point(0, 0); var elementSize = new Size(element.ActualWidth, element.ActualHeight); // Check if element is of zero size if (!(elementSize.Width > 0 && elementSize.Height > 0)) { return false; } var rect = new Rect(zero, elementSize); var bound = element.TransformToVisual(visualRoot).TransformBounds(rect); var rootRect = new Rect(zero, visualRoot.RenderSize); rootRect.Intersect(bound); // Check if element is offscreen if (rootRect.IsEmpty) { return false; } while (true) { if (element.Visibility != Visibility.Visible || !element.IsHitTestVisible || !(element.Opacity > 0)) { return false; } var container = VisualTreeHelper.GetParent(element) as FrameworkElement; if (container == null) { return true; } element = container; } }
public bool collidesWith(Entity entity) { int x1 = this.PosX; int y1 = this.PosY; int w1 = this.Width; int h1 = this.Height; Rect box1 = new Rect(x1, y1, w1, h1); int x2 = entity.PosX; int y2 = entity.PosY; int w2 = entity.Width; int h2 = entity.Height; Rect box2 = new Rect(x2, y2, w2, h2); box1.Intersect(box2); if (box1 == Rect.Empty) { return false; } else { return true; } }
// Returns the visible tiles inside a rectangle on any level private IEnumerable<Tile> VisibleTiles(Rect rectangle, int level) { rectangle.Intersect(new Rect(ImageSize)); var top = Math.Floor(rectangle.Top / TileSize); var left = Math.Floor(rectangle.Left / TileSize); var right = Math.Ceiling(rectangle.Right / TileSize); var bottom = Math.Ceiling(rectangle.Bottom / TileSize); right = right.AtMost(ColumnsAtLevel(level)); bottom = bottom.AtMost(RowsAtLevel(level)); var width = (right - left).AtLeast(0); var height = (bottom - top).AtLeast(0); if (top == 0.0 && left == 0.0 && width == 1.0 && height == 1.0) // This level only has one tile yield return new Tile(level, 0, 0); else { foreach (var pt in Quadivide(new Rect(left, top, width, height))) yield return new Tile(level, (int)pt.X, (int)pt.Y); } }
public void Intersect () { Rect r; // fully contained r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (10, 10, 10, 10)); Assert.AreEqual (new Rect (10, 10, 10, 10), r); // crosses top side r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (5, -5, 10, 10)); Assert.AreEqual (new Rect (5, 0, 10, 5), r); // crosses right side r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (5, 5, 50, 10)); Assert.AreEqual (new Rect (5, 5, 45, 10), r); // crosses bottom side r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (5, 5, 10, 50)); // crosses left side r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (-5, 5, 10, 10)); // completely outside (top) r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (5, -5, 1, 1)); Assert.AreEqual (Rect.Empty, r); // completely outside (right) r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (75, 5, 1, 1)); Assert.AreEqual (Rect.Empty, r); // completely outside (bottom) r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (5, 75, 1, 1)); Assert.AreEqual (Rect.Empty, r); // completely outside (left) r = new Rect (0, 0, 50, 50); r.Intersect (new Rect (-25, 5, 1, 1)); Assert.AreEqual (Rect.Empty, r); }
/// <summary> /// Computes the bounds of the render scope area visible through all nested scroll areas. /// </summary> private Rect GetVisibleRectangle(ITextView textView) { Rect visibleRect = new Rect(textView.RenderScope.RenderSize); Visual visual = VisualTreeHelper.GetParent(textView.RenderScope) as Visual; while (visual != null && visibleRect != Rect.Empty) { if (VisualTreeHelper.GetClip(visual) != null) { GeneralTransform transform = textView.RenderScope.TransformToAncestor(visual).Inverse; // Safer version of transform to descendent (doing the inverse ourself), // we want the rect inside of our space. (Which is always rectangular and much nicer to work with). if (transform != null) { Rect rectBounds = VisualTreeHelper.GetClip(visual).Bounds; rectBounds = transform.TransformBounds(rectBounds); visibleRect.Intersect(rectBounds); } else { // No visibility if non-invertable transform exists. visibleRect = Rect.Empty; } } visual = VisualTreeHelper.GetParent(visual) as Visual; } return visibleRect; }
private Point FitMouse() { double x = this.placementRect.Left; double y = this.placementRect.Top; if (this.IsRightToLeft) { x = this.viewPortRect.Width - x; } y += 20.0 + this.offset.Y; x += this.offset.X; y = Math.Max(2.0, y); x = Math.Max(2.0, x); Rect rect = new Rect(x, y, this.popupSize.Width, this.popupSize.Height); Rect rect2 = new Rect(0.0, 0.0, this.viewPortRect.Width, this.viewPortRect.Height); rect2.Intersect(rect); if ((Math.Abs(rect2.Width - rect.Width) < 2.0) && (Math.Abs(rect2.Height - rect.Height) < 2.0)) { if (this.IsRightToLeft) { x = this.viewPortRect.Width - x; } } else { if ((y + rect.Height) > this.viewPortRect.Height) { y = (this.viewPortRect.Height - rect.Height) - 2.0; } if (y < 0.0) { y = 0.0; } if ((x + rect.Width) > this.viewPortRect.Width) { x = (this.viewPortRect.Width - rect.Width) - 2.0; } if (x < 0.0) { x = 0.0; } if (this.IsRightToLeft) { x = this.viewPortRect.Width - x; } } return new Point(x, y); }
/// <summary> /// RibbonGalleryCategoriesPanel implementation of <seealso cref="IScrollInfo.MakeVisible" />. /// </summary> /// <param name="visual">The Visual that should become visible</param> /// <param name="rectangle">A rectangle representing in the visual's coordinate space to make visible.</param> /// <returns> /// A rectangle in the IScrollInfo's coordinate space that has been made visible. /// Other ancestors to in turn make this new rectangle visible. /// The rectangle should generally be a transformed version of the input rectangle. In some cases, like /// when the input rectangle cannot entirely fit in the viewport, the return value might be smaller. /// </returns> public Rect MakeVisible(Visual visual, Rect rectangle) { // We can only work on visuals that are us or children. // An empty rect has no size or position. We can't meaningfully use it. if (rectangle.IsEmpty || visual == null || visual == (Visual)this || !this.IsAncestorOf(visual)) { return Rect.Empty; } #pragma warning disable 1634, 1691 #pragma warning disable 56506 // Compute the child's rect relative to (0,0) in our coordinate space. // This is a false positive by PreSharp. visual cannot be null because of the 'if' check above GeneralTransform childTransform = visual.TransformToAncestor(this); #pragma warning restore 56506 #pragma warning restore 1634, 1691 rectangle = childTransform.TransformBounds(rectangle); // We can't do any work unless we're scrolling. if (!IsScrolling) { return rectangle; } // Initialize the viewport Rect viewport = new Rect(HorizontalOffset, VerticalOffset, ViewportWidth, ViewportHeight); rectangle.X += viewport.X; rectangle.Y += viewport.Y; // Compute the offsets required to minimally scroll the child maximally into view. double minX = ComputeScrollOffsetWithMinimalScroll(viewport.Left, viewport.Right, rectangle.Left, rectangle.Right); double minY = ComputeScrollOffsetWithMinimalScroll(viewport.Top, viewport.Bottom, rectangle.Top, rectangle.Bottom); // We have computed the scrolling offsets; scroll to them. SetHorizontalOffset(minX); SetVerticalOffset(minY); // Compute the visible rectangle of the child relative to the viewport. viewport.X = minX; viewport.Y = minY; rectangle.Intersect(viewport); if (!rectangle.IsEmpty) { rectangle.X -= viewport.X; rectangle.Y -= viewport.Y; } // Return the rectangle return rectangle; }
///<summary> /// This eliminates the part of bounding rectangle if it is at all being overlapped/clipped by any of the visual ancestor up in the parent chain ///</summary> internal static Rect CalculateVisibleBoundingRect(UIElement uiElement) { Rect boundingRect = Rect.Empty; boundingRect = new Rect(uiElement.RenderSize); // Compute visible portion of the rectangle. Visual visual = VisualTreeHelper.GetParent(uiElement) as Visual; while (visual != null && boundingRect != Rect.Empty && boundingRect.Height != 0 && boundingRect.Width != 0) { Geometry clipGeometry = VisualTreeHelper.GetClip(visual); if (clipGeometry != null) { GeneralTransform transform = uiElement.TransformToAncestor(visual).Inverse; // Safer version of transform to descendent (doing the inverse ourself and saves us changing the co-ordinate space of the owner's bounding rectangle), // we want the rect inside of our space. (Which is always rectangular and much nicer to work with) if (transform != null) { Rect clipBounds = clipGeometry.Bounds; clipBounds = transform.TransformBounds(clipBounds); boundingRect.Intersect(clipBounds); } else { // No visibility if non-invertable transform exists. boundingRect = Rect.Empty; } } visual = VisualTreeHelper.GetParent(visual) as Visual; } return boundingRect; }
public Rect MakeVisible(Visual visual, Rect rectangle) { if (rectangle.IsEmpty || visual == null || visual == this || !IsAncestorOf(visual)) { return Rect.Empty; } rectangle = visual.TransformToAncestor(this).TransformBounds(rectangle); var viewRect = new Rect(HorizontalOffset, VerticalOffset, ViewportWidth, ViewportHeight); rectangle.X += viewRect.X; rectangle.Y += viewRect.Y; viewRect.X = CalculateNewScrollOffset(viewRect.Left, viewRect.Right, rectangle.Left, rectangle.Right); viewRect.Y = CalculateNewScrollOffset(viewRect.Top, viewRect.Bottom, rectangle.Top, rectangle.Bottom); SetHorizontalOffset(viewRect.X); SetVerticalOffset(viewRect.Y); rectangle.Intersect(viewRect); rectangle.X -= viewRect.X; rectangle.Y -= viewRect.Y; return rectangle; }
// helper function to accumulate a list of bounding rectangles for a potentially mult-line range private ArrayList GetMultilineBoundingRectangles(string text, Point mapClientToScreen, Rect clippingRectangle) { // remember the line height int height = Math.Abs(_provider.GetLogfont().lfHeight);; // get the starting and ending lines for the range. int start = Start; int end = End; int startLine = _provider.LineFromChar(start); int endLine = _provider.LineFromChar(end - 1); // adjust the start based on the first visible line int firstVisibleLine = _provider.GetFirstVisibleLine(); if (firstVisibleLine > startLine) { startLine = firstVisibleLine; start = _provider.LineIndex(startLine); } // adjust the end based on the last visible line int lastVisibleLine = firstVisibleLine + _provider.LinesPerPage() - 1; if (lastVisibleLine < endLine) { endLine = lastVisibleLine; end = _provider.LineIndex(endLine) - 1; } // adding a rectangle for each line ArrayList rects = new ArrayList(Math.Max(endLine - startLine + 1, 0)); int nextLineIndex = _provider.LineIndex(startLine); for (int i = startLine; i <= endLine; i++) { // determine the starting coordinate on this line Point startPoint; if (i == startLine) { startPoint = _provider.PosFromChar(start); } else { startPoint = _provider.PosFromChar(nextLineIndex); } // determine the ending coordinate on this line Point endPoint; if (i == endLine) { endPoint = _provider.PosFromCharUR(end-1, text); } else { nextLineIndex = _provider.LineIndex(i + 1); endPoint = _provider.PosFromChar(nextLineIndex - 1); } // add a bounding rectangle for this line if it is nonempty Rect rect = new Rect(startPoint.X, startPoint.Y, endPoint.X - startPoint.X, height); rect.Intersect(clippingRectangle); if (rect.Width > 0 && rect.Height > 0) // r.Empty is true only if both width & height are zero. Duh! { rect.Offset(mapClientToScreen.X, mapClientToScreen.Y); rects.Add(rect); } } return rects; }
double[] ITextRangeProvider.GetBoundingRectangles() { // Return zero rectangles for a degenerate range. We don't return an empty, // but properly positioned, rectangle for degenerate ranges because // there is ambiguity at line breaks and some international scenarios. if (IsDegenerate) { return new double[0]; } // we'll need to have the text eventually (so we can measure characters) so get it up // front so we can check the endpoints before proceeding. string text = _provider.GetText(); ValidateEndpoints(); // get the mapping from client coordinates to screen coordinates NativeMethods.Win32Point w32point; w32point.x = 0; w32point.y = 0; if (!Misc.MapWindowPoints(_provider.WindowHandle, IntPtr.Zero, ref w32point, 1)) { return new double[0]; } Point mapClientToScreen = new Point(w32point.x, w32point.y); // clip the rectangles to the edit control's formatting rectangle Rect clippingRectangle = _provider.GetRect(); // we accumulate rectangles onto a list ArrayList rects; if (_provider.IsMultiline) { rects = GetMultilineBoundingRectangles(text, mapClientToScreen, clippingRectangle); } else { // single line edit control rects = new ArrayList(1); // figure out the rectangle for this one line Point startPoint = _provider.PosFromChar(Start); Point endPoint = _provider.PosFromCharUR(End - 1, text); Rect rect = new Rect(startPoint.X, startPoint.Y, endPoint.X - startPoint.X, clippingRectangle.Height); rect.Intersect(clippingRectangle); // use the rectangle if it is non-empty. if (rect.Width > 0 && rect.Height > 0) // r.Empty is true only if both width & height are zero. Duh! { rect.Offset(mapClientToScreen.X, mapClientToScreen.Y); rects.Add(rect); } } // convert the list of rectangles into an array for returning Rect[] rectArray = new Rect[rects.Count]; rects.CopyTo(rectArray); return Misc.RectArrayToDoubleArray(rectArray); }
///<summary> /// This eliminates the part of bounding rectangle if it is at all being overlapped/clipped by any of the visual ancestor up in the parent chain ///</summary> internal static Rect CalculateVisibleBoundingRect(UIElement owner) { Rect boundingRect = new Rect(owner.RenderSize); // Compute visible portion of the rectangle. DependencyObject parent = VisualTreeHelper.GetParent(owner); while (parent != null && !DoubleUtil.AreClose(boundingRect, Rect.Empty) && !DoubleUtil.AreClose(boundingRect.Height, 0) && !DoubleUtil.AreClose(boundingRect.Width, 0)) { Visual visualParent = parent as Visual; if (visualParent != null) { Geometry clipGeometry = VisualTreeHelper.GetClip(visualParent); if (clipGeometry != null) { GeneralTransform transform = owner.TransformToAncestor(visualParent).Inverse; // Safer version of transform to descendent (doing the inverse ourself and saves us changing the co-ordinate space of the owner's bounding rectangle), // we want the rect inside of our space. (Which is always rectangular and much nicer to work with) if (transform != null) { Rect clipBounds = clipGeometry.Bounds; clipBounds = transform.TransformBounds(clipBounds); boundingRect.Intersect(clipBounds); } else { // No visibility if non-invertable transform exists. boundingRect = Rect.Empty; } } } parent = VisualTreeHelper.GetParent(parent); } return boundingRect; }
/// <summary> /// <see cref="IScrollInfo.MakeVisible"/> /// </summary> internal Rect MakeVisible(UIElement owner, Visual visual, Rect rectangle) { // We can only work on visuals that are us or children. // An empty rect has no size or position. We can't meaningfully use it. if (rectangle.IsEmpty || visual == null || (visual != owner && !owner.IsAncestorOf(visual))) { return Rect.Empty; } // Compute the child's rect relative to (0,0) in our coordinate space. GeneralTransform childTransform = visual.TransformToAncestor(owner); rectangle = childTransform.TransformBounds(rectangle); // Initialize the viewport Rect viewport = new Rect(_offset.X, _offset.Y, _viewport.Width, _viewport.Height); rectangle.X += viewport.X; rectangle.Y += viewport.Y; // Compute the offsets required to minimally scroll the child maximally into view. double minX = ComputeScrollOffset(viewport.Left, viewport.Right, rectangle.Left, rectangle.Right); double minY = ComputeScrollOffset(viewport.Top, viewport.Bottom, rectangle.Top, rectangle.Bottom); // We have computed the scrolling offsets; scroll to them. SetHorizontalOffset(owner, minX); SetVerticalOffset(owner, minY); // Compute the visible rectangle of the child relative to the viewport. if (this.CanHorizontallyScroll) { viewport.X = minX; } else { // munge the intersection rectangle.X = viewport.X; } if (this.CanVerticallyScroll) { viewport.Y = minY; } else { // munge the intersection rectangle.Y = viewport.Y; } rectangle.Intersect(viewport); if (!rectangle.IsEmpty) { rectangle.X -= viewport.X; rectangle.Y -= viewport.Y; } // Return the rectangle return rectangle; }
public static Rect Intersect(Rect rect1, Rect rect2) { rect1.Intersect(rect2); return(rect1); }
/// <summary> /// Override of <seealso cref="UIElement.GetLayoutClip"/>. /// </summary> /// <returns>Geometry to use as additional clip in case when element is larger then available space</returns> protected override Geometry GetLayoutClip(Size layoutSlotSize) { bool useLayoutRounding = this.UseLayoutRounding; if (useLayoutRounding) { if (!CheckFlagsAnd(VisualFlags.UseLayoutRounding)) { SetFlags(true, VisualFlags.UseLayoutRounding); } } if (NeedsClipBounds || ClipToBounds) { // see if MaxWidth/MaxHeight limit the element MinMax mm = new MinMax(this); //this is in element's local rendering coord system Size inkSize = this.RenderSize; double maxWidthClip = (Double.IsPositiveInfinity(mm.maxWidth) ? inkSize.Width : mm.maxWidth); double maxHeightClip = (Double.IsPositiveInfinity(mm.maxHeight) ? inkSize.Height : mm.maxHeight); //need to clip because the computed sizes exceed MaxWidth/MaxHeight/Width/Height bool needToClipLocally = ClipToBounds //need to clip at bounds even if inkSize is less then maxSize || (DoubleUtil.LessThan(maxWidthClip, inkSize.Width) || DoubleUtil.LessThan(maxHeightClip, inkSize.Height)); //now lets say we already clipped by MaxWidth/MaxHeight, lets see if further clipping is needed inkSize.Width = Math.Min(inkSize.Width, mm.maxWidth); inkSize.Height = Math.Min(inkSize.Height, mm.maxHeight); //if LayoutTransform is set, convert RenderSize to "outer bounds" LayoutTransformData ltd = LayoutTransformDataField.GetValue(this); Rect inkRectTransformed = new Rect(); if (ltd != null) { inkRectTransformed = Rect.Transform(new Rect(0, 0, inkSize.Width, inkSize.Height), ltd.Transform.Value); inkSize.Width = inkRectTransformed.Width; inkSize.Height = inkRectTransformed.Height; } //now see if layout slot should clip the element Thickness margin = Margin; double marginWidth = margin.Left + margin.Right; double marginHeight = margin.Top + margin.Bottom; Size clippingSize = new Size(Math.Max(0, layoutSlotSize.Width - marginWidth), Math.Max(0, layoutSlotSize.Height - marginHeight)); bool needToClipSlot = ( ClipToBounds //forces clip at layout slot bounds even if reported sizes are ok || DoubleUtil.LessThan(clippingSize.Width, inkSize.Width) || DoubleUtil.LessThan(clippingSize.Height, inkSize.Height)); Transform rtlMirror = GetFlowDirectionTransform(); if (needToClipLocally && !needToClipSlot) { Rect clipRect = new Rect(0, 0, maxWidthClip, maxHeightClip); if (useLayoutRounding) { clipRect = UIElement.RoundLayoutRect(clipRect, DpiScaleX, DpiScaleY); } RectangleGeometry localClip = new RectangleGeometry(clipRect); if (rtlMirror != null) localClip.Transform = rtlMirror; return localClip; } if (needToClipSlot) { Vector offset = ComputeAlignmentOffset(clippingSize, inkSize); if (ltd != null) { Rect slotClipRect = new Rect(-offset.X + inkRectTransformed.X, -offset.Y + inkRectTransformed.Y, clippingSize.Width, clippingSize.Height); if (useLayoutRounding) { slotClipRect = UIElement.RoundLayoutRect(slotClipRect, DpiScaleX, DpiScaleY); } RectangleGeometry slotClip = new RectangleGeometry(slotClipRect); Matrix m = ltd.Transform.Value; if (m.HasInverse) { m.Invert(); slotClip.Transform = new MatrixTransform(m); } if (needToClipLocally) { Rect localClipRect = new Rect(0, 0, maxWidthClip, maxHeightClip); if (useLayoutRounding) { localClipRect = UIElement.RoundLayoutRect(localClipRect, DpiScaleX, DpiScaleY); } RectangleGeometry localClip = new RectangleGeometry(localClipRect); PathGeometry combinedClip = Geometry.Combine(localClip, slotClip, GeometryCombineMode.Intersect, null); if (rtlMirror != null) combinedClip.Transform = rtlMirror; return combinedClip; } else { if (rtlMirror != null) { if (slotClip.Transform != null) slotClip.Transform = new MatrixTransform(slotClip.Transform.Value * rtlMirror.Value); else slotClip.Transform = rtlMirror; } return slotClip; } } else //no layout transform, intersect axis-aligned rects { Rect slotRect = new Rect(-offset.X + inkRectTransformed.X, -offset.Y + inkRectTransformed.Y, clippingSize.Width, clippingSize.Height); if (useLayoutRounding) { slotRect = UIElement.RoundLayoutRect(slotRect, DpiScaleX, DpiScaleY); } if (needToClipLocally) //intersect 2 rects { Rect localRect = new Rect(0, 0, maxWidthClip, maxHeightClip); if (useLayoutRounding) { localRect = UIElement.RoundLayoutRect(localRect, DpiScaleX, DpiScaleY); } slotRect.Intersect(localRect); } RectangleGeometry combinedClip = new RectangleGeometry(slotRect); if (rtlMirror != null) combinedClip.Transform = rtlMirror; return combinedClip; } } return null; } return base.GetLayoutClip(layoutSlotSize); }
/// <summary> /// Deterines if the PathBase objects shares an overlap with a specified extent /// </summary> /// <param name="bounds"></param> /// <returns></returns> public override bool Intersects(Rect bounds) { var intersect = new Rect(bounds.X, bounds.Y, bounds.Width, bounds.Height); intersect.Intersect(_Extent); return (intersect.Width > 0 || intersect.Height > 0); }
/// <summary> /// Arrange children cards in this stack. /// </summary> /// <remarks> /// Assumes that all cards have the same width. /// </remarks> public void RearrangeCards(IList<CardView> cards, double transitionInSeconds) { lock (_rearrangeLock) { int numCards = cards.Count(); if (_cardInteraction == CardInteraction.Drag && cards.Contains(_interactingCard)) { numCards--; } if (numCards == 0) return; Trace.Assert(ParentCanvas != null); double cardHeight = (from c in cards select c.Height).Max(); double cardWidth = (from c in cards select c.Width).Max(); if (KeepHorizontalOrder) { cards = new List<CardView>(cards.OrderBy(c => c.Position.X)); } int zindex = 0; double totalWidth = this.ActualWidth; // Do not continue if the layout has not been updated yet. if (totalWidth == 0) return; double extraSpace = Math.Min(MaxCardSpacing - (totalWidth - cardWidth) / (numCards - 1), _extraSpaceForHighlightedCard); int highlightIndex = (_interactingCard == null) ? -1 : cards.IndexOf(_interactingCard); bool doHighlight = (_cardInteraction != CardInteraction.None && highlightIndex >= 0 && highlightIndex != _cards.Count - 1); double maxWidth = doHighlight ? Math.Max(0, totalWidth - extraSpace) : totalWidth; double step = Math.Max(0, Math.Min(MaxCardSpacing, (maxWidth - cardWidth) / (numCards - 1))); if (step == MaxCardSpacing) doHighlight = false; Point topLeft = this.TranslatePoint(new Point(0,0), ParentCanvas); double startX = topLeft.X; if (CardAlignment == HorizontalAlignment.Center) { startX += totalWidth / 2 - step * ((numCards - 1) / 2.0) - cardWidth / 2; if (doHighlight) startX -= _extraSpaceForHighlightedCard / 2; } else if (CardAlignment == HorizontalAlignment.Right) { startX += maxWidth - step * numCards; } int i = 0; double lastX = startX - step; foreach (CardView card in cards) { if (card == _interactingCard && _cardInteraction == CardInteraction.Drag) { i++; Rect lastCardRect = new Rect(lastX, topLeft.Y + ActualHeight / 2 - cardHeight / 2, step, cardHeight); Rect cardRect = new Rect(card.Position, new Size(cardWidth, cardHeight)); lastCardRect.Intersect(cardRect); double overlapX = lastCardRect.Size.Width; double overlapY = lastCardRect.Size.Height; if (overlapX < 0) { continue; } else if (overlapX < cardWidth / 2) { lastX += overlapX * overlapY / cardHeight; } else { lastX = Math.Max(startX - step, card.Position.X); } continue; } double newX = lastX + step; if (doHighlight && i == highlightIndex + 1) { newX = Math.Min(newX + _extraSpaceForHighlightedCard, lastX + MaxCardSpacing); } lastX = newX; if (!ParentCanvas.Children.Contains(card)) { ParentCanvas.Children.Add(card); } card.Position = new Point(newX, topLeft.Y + ActualHeight / 2 - cardHeight / 2); card.SetValue(Canvas.ZIndexProperty, zindex++); card.Rebase(transitionInSeconds); i++; } } }
private void btnSave_Click(object sender, RoutedEventArgs e) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "JPEGファイル (*.jpg)|*.jpg|PNGファイル (*.png)|*.png|ビットマップファイル (*.bmp)|*.bmp"; if (sfd.ShowDialog() == true) { IImageEncoder enc; string fn = sfd.SafeFileName.ToLower(); if(fn.EndsWith(".jpg")) { enc = new JpegEncoder(); } else if (fn.EndsWith(".png")) { enc = new PngEncoder(); } else if (fn.EndsWith(".bmp")) { enc = new BmpEncoder(); } else { MessageBox.Show("エラー"); return; } double scaledWidth = (cropImage.Width * zoom); double scaledHeight = (cropImage.Height * zoom); double scaledLeft = (imageWidth - scaledWidth) / 2; double scaledTop = (imageHeight - scaledHeight) / 2; Rect r = new Rect((double)cropCanvas.GetValue(Canvas.LeftProperty), (double)cropCanvas.GetValue(Canvas.TopProperty), cropCanvas.Width, cropCanvas.Height); Rect r2 = new Rect(scaledLeft, scaledTop, scaledWidth , scaledHeight); r.Intersect(r2); double clipedLeft = r.Left - scaledLeft; double clipedTop = r.Top - scaledTop; r.X = clipedLeft; r.Y = clipedTop; ScaleTransform st = new ScaleTransform(); st.ScaleX = zoom; st.ScaleY = zoom; WriteableBitmap wb = new WriteableBitmap(cropImage, st); WriteableBitmap outputWb = new WriteableBitmap((int)r.Width, (int)r.Height); outputWb.Blit(new Rect(0, 0, r.Width, r.Height), wb, new Rect(r.Left, r.Top, r.Width, r.Height)); ImageTools.Image img = ToImage(outputWb); using (Stream stream = sfd.OpenFile()) { enc.Encode(img, stream); } } }
public static unsafe void Blit(this WriteableBitmap bmp, Rect destRect, WriteableBitmap source, Rect sourceRect, Color color, WriteableBitmapExtensions.BlendMode blendMode) { if ((int)color.A == 0) return; bool flag1 = source.Format == PixelFormats.Pbgra32 || source.Format == PixelFormats.Prgba64 || source.Format == PixelFormats.Prgba128Float; int num1 = (int)destRect.Width; int num2 = (int)destRect.Height; using (BitmapContext bitmapContext1 = WriteableBitmapContextExtensions.GetBitmapContext(source, ReadWriteMode.ReadOnly)) { using (BitmapContext bitmapContext2 = WriteableBitmapContextExtensions.GetBitmapContext(bmp)) { int width1 = bitmapContext1.Width; int width2 = bitmapContext2.Width; int height = bitmapContext2.Height; Rect rect = new Rect(0.0, 0.0, (double)width2, (double)height); rect.Intersect(destRect); if (rect.IsEmpty) return; int* pixels1 = bitmapContext1.Pixels; int* pixels2 = bitmapContext2.Pixels; int length = bitmapContext1.Length; int num3 = (int)destRect.X; int num4 = (int)destRect.Y; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = (int)color.A; int num10 = (int)color.R; int num11 = (int)color.G; int num12 = (int)color.B; bool flag2 = color != Colors.White; int num13 = (int)sourceRect.Width; double num14 = sourceRect.Width / destRect.Width; double num15 = sourceRect.Height / destRect.Height; int num16 = (int)sourceRect.X; int num17 = (int)sourceRect.Y; int num18 = -1; int num19 = -1; double num20 = (double)num17; int num21 = num4; for (int index1 = 0; index1 < num2; ++index1) { if (num21 >= 0 && num21 < height) { double num22 = (double)num16; int index2 = num3 + num21 * width2; int num23 = num3; int num24 = *pixels1; if (blendMode == WriteableBitmapExtensions.BlendMode.None && !flag2) { int num25 = (int)num22 + (int)num20 * width1; int num26 = num23 < 0 ? -num23 : 0; int num27 = num23 + num26; int num28 = width1 - num26; int num29 = num27 + num28 < width2 ? num28 : width2 - num27; if (num29 > num13) num29 = num13; if (num29 > num1) num29 = num1; BitmapContext.BlockCopy(bitmapContext1, (num25 + num26) * 4, bitmapContext2, (index2 + num26) * 4, num29 * 4); } else { for (int index3 = 0; index3 < num1; ++index3) { if (num23 >= 0 && num23 < width2) { if ((int)num22 != num18 || (int)num20 != num19) { int index4 = (int)num22 + (int)num20 * width1; if (index4 >= 0 && index4 < length) { num24 = pixels1[index4]; num8 = num24 >> 24 & (int)Byte.MaxValue; num5 = num24 >> 16 & (int)Byte.MaxValue; num6 = num24 >> 8 & (int)Byte.MaxValue; num7 = num24 & (int)Byte.MaxValue; if (flag2 && num8 != 0) { num8 = num8 * num9 * 32897 >> 23; num5 = (num5 * num10 * 32897 >> 23) * num9 * 32897 >> 23; num6 = (num6 * num11 * 32897 >> 23) * num9 * 32897 >> 23; num7 = (num7 * num12 * 32897 >> 23) * num9 * 32897 >> 23; num24 = num8 << 24 | num5 << 16 | num6 << 8 | num7; } } else num8 = 0; } if (blendMode == WriteableBitmapExtensions.BlendMode.None) pixels2[index2] = num24; else if (blendMode == WriteableBitmapExtensions.BlendMode.ColorKeying) { num5 = num24 >> 16 & (int)Byte.MaxValue; num6 = num24 >> 8 & (int)Byte.MaxValue; num7 = num24 & (int)Byte.MaxValue; if (num5 != (int)color.R || num6 != (int)color.G || num7 != (int)color.B) pixels2[index2] = num24; } else if (blendMode == WriteableBitmapExtensions.BlendMode.Mask) { int num25 = pixels2[index2]; int num26 = num25 >> 24 & (int)Byte.MaxValue; int num27 = num25 >> 16 & (int)Byte.MaxValue; int num28 = num25 >> 8 & (int)Byte.MaxValue; int num29 = num25 & (int)Byte.MaxValue; int num30 = num26 * num8 * 32897 >> 23 << 24 | num27 * num8 * 32897 >> 23 << 16 | num28 * num8 * 32897 >> 23 << 8 | num29 * num8 * 32897 >> 23; pixels2[index2] = num30; } else if (num8 > 0) { int num25 = pixels2[index2]; int num26 = num25 >> 24 & (int)Byte.MaxValue; if ((num8 == (int)Byte.MaxValue || num26 == 0) && (blendMode != WriteableBitmapExtensions.BlendMode.Additive && blendMode != WriteableBitmapExtensions.BlendMode.Subtractive) && blendMode != WriteableBitmapExtensions.BlendMode.Multiply) { pixels2[index2] = num24; } else { int num27 = num25 >> 16 & (int)Byte.MaxValue; int num28 = num25 >> 8 & (int)Byte.MaxValue; int num29 = num25 & (int)Byte.MaxValue; if (blendMode == WriteableBitmapExtensions.BlendMode.Alpha) { int num30 = (int)Byte.MaxValue - num8; num25 = !flag1 ? (num26 & (int)Byte.MaxValue) << 24 | (num5 * num8 + num30 * num27 >> 8 & (int)Byte.MaxValue) << 16 | (num6 * num8 + num30 * num28 >> 8 & (int)Byte.MaxValue) << 8 | num7 * num8 + num30 * num29 >> 8 & (int)Byte.MaxValue : (num26 & (int)Byte.MaxValue) << 24 | ((num5 << 8) + num30 * num27 >> 8 & (int)Byte.MaxValue) << 16 | ((num6 << 8) + num30 * num28 >> 8 & (int)Byte.MaxValue) << 8 | (num7 << 8) + num30 * num29 >> 8 & (int)Byte.MaxValue; } else if (blendMode == WriteableBitmapExtensions.BlendMode.Additive) { int num30 = (int)Byte.MaxValue <= num8 + num26 ? (int)Byte.MaxValue : num8 + num26; num25 = num30 << 24 | (num30 <= num5 + num27 ? num30 : num5 + num27) << 16 | (num30 <= num6 + num28 ? num30 : num6 + num28) << 8 | (num30 <= num7 + num29 ? num30 : num7 + num29); } else if (blendMode == WriteableBitmapExtensions.BlendMode.Subtractive) num25 = num26 << 24 | (num5 >= num27 ? 0 : num5 - num27) << 16 | (num6 >= num28 ? 0 : num6 - num28) << 8 | (num7 >= num29 ? 0 : num7 - num29); else if (blendMode == WriteableBitmapExtensions.BlendMode.Multiply) { int num30 = num8 * num26 + 128; int num31 = num5 * num27 + 128; int num32 = num6 * num28 + 128; int num33 = num7 * num29 + 128; int num34 = (num30 >> 8) + num30 >> 8; int num35 = (num31 >> 8) + num31 >> 8; int num36 = (num32 >> 8) + num32 >> 8; int num37 = (num33 >> 8) + num33 >> 8; num25 = num34 << 24 | (num34 <= num35 ? num34 : num35) << 16 | (num34 <= num36 ? num34 : num36) << 8 | (num34 <= num37 ? num34 : num37); } pixels2[index2] = num25; } } } ++num23; ++index2; num22 += num14; } } } num20 += num15; ++num21; } } } }
private Rect MakeRectVisible(Rect rectangle) { double desiredWidth = CanHorizontallyScroll ? Math.Min(rectangle.Width*1.6, _viewport.Width) : rectangle.Width; double desiredHeight = CanVerticallyScroll ? Math.Min(rectangle.Height*1.6, _viewport.Height) : rectangle.Height; rectangle.Inflate(Math.Max(desiredWidth - rectangle.Width, 0)*0.5, Math.Max(desiredHeight - rectangle.Height, 0)*0.5); if (ExtentWidth - rectangle.Right <= EndScrollPadding + 1) { rectangle.Width += EndScrollPadding; } var viewRect = new Rect(HorizontalOffset, VerticalOffset, ViewportWidth, ViewportHeight); viewRect.X = CalculateNewScrollOffset(viewRect.Left, viewRect.Right, rectangle.Left, rectangle.Right); viewRect.Y = CalculateNewScrollOffset(viewRect.Top, viewRect.Bottom, rectangle.Top, rectangle.Bottom); SetHorizontalOffset(viewRect.X); SetVerticalOffset(viewRect.Y); rectangle.Intersect(viewRect); rectangle.X -= viewRect.X; rectangle.Y -= viewRect.Y; return rectangle; }
private static bool RectsOverlap(Rect r1, Rect r2) { r1.Intersect(r2); if (r1.Width > 0 || r1.Height > 0) { return true; } else { return false; } }
public void Init(Syscalls syscalls, Core core, Runtime runtime) { PhoneApplicationFrame frame = (PhoneApplicationFrame)Application.Current.RootVisual; double screenWidth = System.Windows.Application.Current.Host.Content.ActualWidth; double screenHeight = System.Windows.Application.Current.Host.Content.ActualHeight; if ((int)screenHeight == 0) throw new Exception("screenHeight"); PhoneApplicationPage mainPage = (PhoneApplicationPage)frame.Content; Image mainImage = new Image(); mainPage.Width = screenWidth; mainPage.Height = screenHeight; mainImage.Width = screenWidth; mainImage.Height = screenHeight; mainPage.Content = mainImage; // no apparent effect on memory leaks. runtime.RegisterCleaner(delegate() { MoSync.Util.RunActionOnMainThreadSync(() => { mainPage.Content = null; }); }); mBackBuffer = new WriteableBitmap( (int)screenWidth, (int)screenHeight); mFrontBuffer = new WriteableBitmap( (int)screenWidth, (int)screenHeight); mainImage.Source = mFrontBuffer; mCurrentDrawTarget = mBackBuffer; mCurrentWindowsColor = System.Windows.Media.Color.FromArgb(0xff, (byte)(mCurrentColor >> 16), (byte)(mCurrentColor >> 8), (byte)(mCurrentColor)); syscalls.maSetColor = delegate(int rgb) { int oldColor = (int)mCurrentColor; mCurrentColor = 0xff000000 | (uint)(rgb & 0xffffff); mCurrentWindowsColor = System.Windows.Media.Color.FromArgb(0xff, (byte)(mCurrentColor >> 16), (byte)(mCurrentColor >> 8), (byte)(mCurrentColor)); return oldColor & 0xffffff; }; syscalls.maSetClipRect = delegate(int x, int y, int w, int h) { }; syscalls.maGetClipRect = delegate(int cliprect) { }; syscalls.maPlot = delegate(int x, int y) { mCurrentDrawTarget.SetPixel(x, y, (int)mCurrentColor); }; syscalls.maUpdateScreen = delegate() { System.Array.Copy(mBackBuffer.Pixels, mFrontBuffer.Pixels, mFrontBuffer.PixelWidth * mFrontBuffer.PixelHeight); InvalidateWriteableBitmapOnMainThread(mFrontBuffer); }; syscalls.maFillRect = delegate(int x, int y, int w, int h) { mCurrentDrawTarget.FillRectangle(x, y, x + w, y + h, (int)mCurrentColor); }; syscalls.maLine = delegate(int x1, int y1, int x2, int y2) { mCurrentDrawTarget.DrawLine(x1, y1, x2, y2, (int)mCurrentColor); }; TextBlock textBlock = new TextBlock(); textBlock.FontSize = mCurrentFontSize; syscalls.maDrawText = delegate(int left, int top, int str) { String text = core.GetDataMemory().ReadStringAtAddress(str); if (text.Length == 0) return; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textBlock.Foreground = new SolidColorBrush(mCurrentWindowsColor); WriteableBitmap b = new WriteableBitmap(textBlock, null); mCurrentDrawTarget.Blit(new Rect(left, top, b.PixelWidth, b.PixelHeight), b, new Rect(0, 0, b.PixelWidth, b.PixelHeight)); }); }; syscalls.maGetTextSize = delegate(int str) { String text = core.GetDataMemory().ReadStringAtAddress(str); int textWidth = 0; int textHeight = 0; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textWidth = (int)textBlock.ActualWidth; textHeight = (int)textBlock.ActualHeight; }); return MoSync.Util.CreateExtent(textWidth, textHeight); }; syscalls.maDrawTextW = delegate(int left, int top, int str) { String text = core.GetDataMemory().ReadWStringAtAddress(str); if (text.Length == 0) return; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textBlock.Foreground = new SolidColorBrush(mCurrentWindowsColor); WriteableBitmap b = new WriteableBitmap(textBlock, null); Rect dstRect = new Rect(left, top, b.PixelWidth, b.PixelHeight); Rect srcRect = new Rect(0, 0, b.PixelWidth, b.PixelHeight); // cliprect.. Rect clipRect = new Rect(0, 0, mBackBuffer.PixelWidth, mBackBuffer.PixelHeight); clipRect.Intersect(dstRect); if (clipRect.IsEmpty == true) { return; } mCurrentDrawTarget.Blit(dstRect, b, srcRect); }); }; syscalls.maGetTextSizeW = delegate(int str) { String text = core.GetDataMemory().ReadWStringAtAddress(str); int textWidth = 0; int textHeight = 0; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textWidth = (int)textBlock.ActualWidth; textHeight = (int)textBlock.ActualHeight; }); return MoSync.Util.CreateExtent(textWidth, textHeight); }; syscalls.maFillTriangleFan = delegate(int points, int count) { int[] newPoints = new int[count * 2 + 2]; for (int i = 0; i < count; i++) { newPoints[i * 2 + 0] = core.GetDataMemory().ReadInt32(points + i * 8); newPoints[i * 2 + 1] = core.GetDataMemory().ReadInt32(points + i * 8 + 4); } newPoints[count * 2 + 0] = core.GetDataMemory().ReadInt32(points + 0); newPoints[count * 2 + 1] = core.GetDataMemory().ReadInt32(points + 4); mCurrentDrawTarget.FillPolygon(newPoints, (int)mCurrentColor); }; syscalls.maFillTriangleStrip = delegate(int points, int count) { int[] xcoords = new int[count]; int[] ycoords = new int[count]; for (int i = 0; i < count; i++) { xcoords[i] = core.GetDataMemory().ReadInt32(points + i * 8); ycoords[i] = core.GetDataMemory().ReadInt32(points + i * 8 + 4); } for (int i = 2; i < count; i++) { mCurrentDrawTarget.FillTriangle( xcoords[i - 2], ycoords[i - 2], xcoords[i - 1], ycoords[i - 1], xcoords[i - 0], ycoords[i - 0], (int)mCurrentColor); } }; syscalls.maSetDrawTarget = delegate(int drawTarget) { int oldDrawTarget = mCurrentDrawTargetIndex; if (drawTarget == mCurrentDrawTargetIndex) return oldDrawTarget; if (drawTarget == MoSync.Constants.HANDLE_SCREEN) { mCurrentDrawTarget = mBackBuffer; mCurrentDrawTargetIndex = drawTarget; return oldDrawTarget; } Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, drawTarget); mCurrentDrawTarget = (WriteableBitmap)res.GetInternalObject(); mCurrentDrawTargetIndex = drawTarget; return oldDrawTarget; }; syscalls.maGetScrSize = delegate() { return MoSync.Util.CreateExtent(mBackBuffer.PixelWidth, mBackBuffer.PixelHeight); }; syscalls.maGetImageSize = delegate(int handle) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, handle); BitmapSource src = (BitmapSource)res.GetInternalObject(); int w = 0, h = 0; MoSync.Util.RunActionOnMainThreadSync(() => { w = src.PixelWidth; h = src.PixelHeight; }); return MoSync.Util.CreateExtent(w, h); }; syscalls.maDrawImage = delegate(int image, int left, int top) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Rect srcRect = new Rect(0, 0, src.PixelWidth, src.PixelHeight); Rect dstRect = new Rect(left, top, src.PixelWidth, src.PixelHeight); mCurrentDrawTarget.Blit(dstRect, src, srcRect, WriteableBitmapExtensions.BlendMode.Alpha); }; syscalls.maDrawImageRegion = delegate(int image, int srcRectPtr, int dstPointPtr, int transformMode) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Memory dataMemory = core.GetDataMemory(); int srcRectX = dataMemory.ReadInt32(srcRectPtr + 0); int srcRectY = dataMemory.ReadInt32(srcRectPtr + 4); int srcRectW = dataMemory.ReadInt32(srcRectPtr + 8); int srcRectH = dataMemory.ReadInt32(srcRectPtr + 12); int dstPointX = dataMemory.ReadInt32(dstPointPtr + 0); int dstPointY = dataMemory.ReadInt32(dstPointPtr + 4); Rect srcRect = new Rect(srcRectX, srcRectY, srcRectW, srcRectH); Rect dstRect = new Rect(dstPointX, dstPointY, srcRectW, srcRectH); // mCurrentDrawTarget.Blit(dstRect, src, srcRect, WriteableBitmapExtensions.BlendMode.Alpha); DrawImageRegion(mCurrentDrawTarget, dstPointX, dstPointY, srcRect, src, transformMode); }; syscalls.maCreateDrawableImage = delegate(int placeholder, int width, int height) { Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, placeholder); res.SetResourceType(MoSync.Constants.RT_IMAGE); WriteableBitmap bitmap = null; MoSync.Util.RunActionOnMainThreadSync(() => { bitmap = new WriteableBitmap(width, height); }); if (bitmap == null) return MoSync.Constants.RES_OUT_OF_MEMORY; res.SetInternalObject(bitmap); return MoSync.Constants.RES_OK; }; syscalls.maCreateImageRaw = delegate(int _placeholder, int _src, int _size, int _alpha) { int width = MoSync.Util.ExtentX(_size); int height = MoSync.Util.ExtentY(_size); WriteableBitmap bitmap = null; MoSync.Util.RunActionOnMainThreadSync(() => { bitmap = new WriteableBitmap(width, height); }); //core.GetDataMemory().ReadIntegers(bitmap.Pixels, _src, width * height); bitmap.FromByteArray(core.GetDataMemory().GetData(), _src, width * height * 4); if (_alpha == 0) { int[] pixels = bitmap.Pixels; int numPixels = width * height; for (int i = 0; i < numPixels; i++) { pixels[i] = (int)((uint)pixels[i] | 0xff000000); } } runtime.SetResource(_placeholder, new Resource( bitmap, MoSync.Constants.RT_IMAGE ) ); return MoSync.Constants.RES_OK; }; syscalls.maDrawRGB = delegate(int _dstPoint, int _src, int _srcRect, int _scanlength) { Memory dataMemory = core.GetDataMemory(); int dstX = dataMemory.ReadInt32(_dstPoint + 0); int dstY = dataMemory.ReadInt32(_dstPoint + 4); int srcRectX = dataMemory.ReadInt32(_srcRect + 0); int srcRectY = dataMemory.ReadInt32(_srcRect + 4); int srcRectW = dataMemory.ReadInt32(_srcRect + 8); int srcRectH = dataMemory.ReadInt32(_srcRect + 12); int[] pixels = mCurrentDrawTarget.Pixels; // todo: clipRect _scanlength *= 4; // sizeof(int) for (int h = 0; h < srcRectH; h++) { int pixelIndex = dstY * mCurrentDrawTarget.PixelWidth + dstX; int address = _src + (srcRectY + h) * _scanlength; for (int w = 0; w < srcRectW; w++) { uint srcPixel = dataMemory.ReadUInt32(address); uint dstPixel = (uint)pixels[pixelIndex]; uint srcPixelR = (srcPixel & 0x00ff0000) >> 16; uint srcPixelG = (srcPixel & 0x0000ff00) >> 8; uint srcPixelB = (srcPixel & 0x000000ff) >> 0; uint srcPixelA = (srcPixel & 0xff000000) >> 24; uint dstPixelR = (dstPixel & 0x00ff0000) >> 16; uint dstPixelG = (dstPixel & 0x0000ff00) >> 8; uint dstPixelB = (dstPixel & 0x000000ff) >> 0; uint dstPixelA = (dstPixel & 0xff000000) >> 24; dstPixelR += ((srcPixelR - dstPixelR) * srcPixelA) / 255; dstPixelG += ((srcPixelG - dstPixelG) * srcPixelA) / 255; dstPixelB += ((srcPixelB - dstPixelB) * srcPixelA) / 255; dstPixel = (dstPixelA << 24) | (dstPixelR << 16) | (dstPixelG << 8) | (dstPixelB); pixels[pixelIndex] = (int)dstPixel; address += 4; pixelIndex++; } dstY++; } }; syscalls.maGetImageData = delegate(int _image, int _dst, int _srcRect, int _scanlength) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, _image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Memory dataMemory = core.GetDataMemory(); int srcRectX = dataMemory.ReadInt32(_srcRect + 0); int srcRectY = dataMemory.ReadInt32(_srcRect + 4); int srcRectW = dataMemory.ReadInt32(_srcRect + 8); int srcRectH = dataMemory.ReadInt32(_srcRect + 12); int lineDst = _dst; byte[] data = src.ToByteArray(srcRectY * src.PixelWidth, srcRectH * src.PixelWidth); byte[] coreArray = dataMemory.GetData(); for (int y = 0; y < srcRectH; y++) { System.Array.Copy(data, y * src.PixelWidth * 4, coreArray, lineDst, src.PixelWidth * 4); lineDst += _scanlength * 4; } }; syscalls.maCreateImageFromData = delegate(int _placeholder, int _data, int _offset, int _size) { Resource res = runtime.GetResource(MoSync.Constants.RT_BINARY, _data); Memory mem = (Memory)res.GetInternalObject(); Stream s = mem.GetStream(_offset, _size); WriteableBitmap bitmap = MoSync.Util.CreateWriteableBitmapFromStream(s); s.Close(); runtime.SetResource( _placeholder, new Resource( bitmap, MoSync.Constants.RT_IMAGE ) ); return MoSync.Constants.RES_OK; }; }
/// <summary> /// Forces content to scroll until the coordinate space of a System.Windows.Media.Visual object is visible. /// This is optimized for horizontal scrolling only /// </summary> /// <param name="visual">A System.Windows.Media.Visual that becomes visible.</param> /// <param name="rectangle">A bounding rectangle that identifies the coordinate space to make visible.</param> /// <returns>A System.Windows.Rect that is visible.</returns> public Rect MakeVisible(Visual visual, Rect rectangle) { // We can only work on visuals that are us or children. // An empty rect has no size or position. We can't meaningfully use it. if (rectangle.IsEmpty || visual == null || ReferenceEquals(visual, this) || !this.IsAncestorOf(visual)) { return Rect.Empty; } // Compute the child's rect relative to (0,0) in our coordinate space. GeneralTransform childTransform = visual.TransformToAncestor(this); rectangle = childTransform.TransformBounds(rectangle); // Initialize the viewport Rect viewport = new Rect(HorizontalOffset, rectangle.Top, ViewportWidth, rectangle.Height); rectangle.X += viewport.X; // Compute the offsets required to minimally scroll the child maximally into view. double minX = ComputeScrollOffsetWithMinimalScroll(viewport.Left, viewport.Right, rectangle.Left, rectangle.Right); // We have computed the scrolling offsets; scroll to them. SetHorizontalOffset(minX); // Compute the visible rectangle of the child relative to the viewport. viewport.X = minX; rectangle.Intersect(viewport); rectangle.X -= viewport.X; // Return the rectangle return rectangle; }
static bool WindowBoundsValidAnyScreen(PresentationSource source, Rect bounds) { foreach (var screen in System.Windows.Forms.Screen.AllScreens) { var wa = screen.WorkingArea; var i = new Rect(wa.X, wa.Y, wa.Width, wa.Height); i.Transform(source.CompositionTarget.TransformFromDevice); i.Intersect(bounds); if (i.Width > 10 && i.Height > 10) return true; } return false; }
protected override Geometry GetLayoutClip(Size layoutSlotSize) { bool useLayoutRounding = this.UseLayoutRounding; if (useLayoutRounding && !this.CheckFlagsAnd(VisualFlags.UseLayoutRounding)) this.SetFlags(true, VisualFlags.UseLayoutRounding); if (!this.NeedsClipBounds && !this.ClipToBounds) return base.GetLayoutClip(layoutSlotSize); FrameworkElement.MinMax minMax = new FrameworkElement.MinMax(this); Size renderSize = this.RenderSize; double width = double.IsPositiveInfinity(minMax.maxWidth) ? renderSize.Width : minMax.maxWidth; double height = double.IsPositiveInfinity(minMax.maxHeight) ? renderSize.Height : minMax.maxHeight; bool flag1 = this.ClipToBounds || (DoubleUtil.LessThan(width, renderSize.Width) || DoubleUtil.LessThan(height, renderSize.Height)); renderSize.Width = Math.Min(renderSize.Width, minMax.maxWidth); renderSize.Height = Math.Min(renderSize.Height, minMax.maxHeight); FrameworkElement.LayoutTransformData layoutTransformData = FrameworkElement.LayoutTransformDataField.GetValue((DependencyObject) this); Rect rect1 = new Rect(); if (layoutTransformData != null) { rect1 = Rect.Transform(new Rect(0.0, 0.0, renderSize.Width, renderSize.Height), layoutTransformData.Transform.Value); renderSize.Width = rect1.Width; renderSize.Height = rect1.Height; } Thickness margin = this.Margin; double num1 = margin.Left + margin.Right; double num2 = margin.Top + margin.Bottom; Size clientSize = new Size(Math.Max(0.0, layoutSlotSize.Width - num1), Math.Max(0.0, layoutSlotSize.Height - num2)); bool flag2 = this.ClipToBounds || DoubleUtil.LessThan(clientSize.Width, renderSize.Width) || DoubleUtil.LessThan(clientSize.Height, renderSize.Height); Transform directionTransform = this.GetFlowDirectionTransform(); if (flag1 && !flag2) { Rect rect2 = new Rect(0.0, 0.0, width, height); if (useLayoutRounding) rect2 = UIElement.RoundLayoutRect(rect2, FrameworkElement.DpiScaleX, FrameworkElement.DpiScaleY); RectangleGeometry rectangleGeometry = new RectangleGeometry(rect2); if (directionTransform != null) rectangleGeometry.Transform = directionTransform; return (Geometry) rectangleGeometry; } else { if (!flag2) return (Geometry) null; Vector alignmentOffset = this.ComputeAlignmentOffset(clientSize, renderSize); if (layoutTransformData != null) { Rect rect2 = new Rect(-alignmentOffset.X + rect1.X, -alignmentOffset.Y + rect1.Y, clientSize.Width, clientSize.Height); if (useLayoutRounding) rect2 = UIElement.RoundLayoutRect(rect2, FrameworkElement.DpiScaleX, FrameworkElement.DpiScaleY); RectangleGeometry rectangleGeometry = new RectangleGeometry(rect2); Matrix matrix = layoutTransformData.Transform.Value; if (matrix.HasInverse) { matrix.Invert(); rectangleGeometry.Transform = (Transform) new MatrixTransform(matrix); } if (flag1) { Rect rect3 = new Rect(0.0, 0.0, width, height); if (useLayoutRounding) rect3 = UIElement.RoundLayoutRect(rect3, FrameworkElement.DpiScaleX, FrameworkElement.DpiScaleY); PathGeometry pathGeometry = Geometry.Combine((Geometry) new RectangleGeometry(rect3), (Geometry) rectangleGeometry, GeometryCombineMode.Intersect, (Transform) null); if (directionTransform != null) pathGeometry.Transform = directionTransform; return (Geometry) pathGeometry; } else { if (directionTransform != null) { if (rectangleGeometry.Transform != null) rectangleGeometry.Transform = (Transform) new MatrixTransform(rectangleGeometry.Transform.Value * directionTransform.Value); else rectangleGeometry.Transform = directionTransform; } return (Geometry) rectangleGeometry; } } else { Rect rect2 = new Rect(-alignmentOffset.X + rect1.X, -alignmentOffset.Y + rect1.Y, clientSize.Width, clientSize.Height); if (useLayoutRounding) rect2 = UIElement.RoundLayoutRect(rect2, FrameworkElement.DpiScaleX, FrameworkElement.DpiScaleY); if (flag1) { Rect rect3 = new Rect(0.0, 0.0, width, height); if (useLayoutRounding) rect3 = UIElement.RoundLayoutRect(rect3, FrameworkElement.DpiScaleX, FrameworkElement.DpiScaleY); rect2.Intersect(rect3); } RectangleGeometry rectangleGeometry = new RectangleGeometry(rect2); if (directionTransform != null) rectangleGeometry.Transform = directionTransform; return (Geometry) rectangleGeometry; } } }
/// <summary> /// Calculates visible rectangle taking into account all clips and transforms /// in the visual ancestors chain. /// </summary> /// <param name="visibleRect">Original rectangle relative to 'visual'.</param> /// <param name="originalVisual">Originating visual element.</param> internal static Rect CalculateVisibleRect(Rect visibleRect, Visual originalVisual) { Visual visual = VisualTreeHelper.GetParent(originalVisual) as Visual; while (visual != null && visibleRect != Rect.Empty) { if (VisualTreeHelper.GetClip(visual) != null) { GeneralTransform transform = originalVisual.TransformToAncestor(visual).Inverse; // Safer version of transform to descendent (doing the inverse ourself), // we want the rect inside of our space. (Which is always rectangular and much nicer to work with) if (transform != null) { Rect rectBounds = VisualTreeHelper.GetClip(visual).Bounds; rectBounds = transform.TransformBounds(rectBounds); visibleRect.Intersect(rectBounds); } else { // No visibility if non-invertable transform exists. visibleRect = Rect.Empty; } } visual = VisualTreeHelper.GetParent(visual) as Visual; } return visibleRect; }
/// <summary> /// Clips the host. /// </summary> /// <param name="clipRect">The clip rect.</param> /// <param name="zoom">The zoom value.</param> public override void ClipHost(Rect clipRect, double zoom) { // Compute right level of detail uint levelOfDetail = 0; int tmpZoom = 1; while (tmpZoom <= zoom) { levelOfDetail++; tmpZoom = tmpZoom << 1; } tmpZoom = tmpZoom >> 1; if (levelOfDetail < 1) { levelOfDetail = 1; tmpZoom = 1; } // Perform clipping Rect visibleRect = new Rect(0, 0, Width, Height); visibleRect.Intersect(clipRect); // tmpGuid is used to Tag visible tiles Guid tmpGuid = Guid.NewGuid(); double mapSize = this.MapProjection.MapSize(levelOfDetail); // Convert baseClipping in new level of detail Rect visibleRect2 = new Rect(); if (!visibleRect.IsEmpty) { visibleRect2 = new Rect(visibleRect.Left * tmpZoom, visibleRect.Top * tmpZoom, visibleRect.Width * tmpZoom, visibleRect.Height * tmpZoom); // Get tileindex based points Point tilePt1 = this.MapProjection.PixelXYToTileXY(new Point(visibleRect2.Left, visibleRect2.Top), levelOfDetail); Point tilePt2 = this.MapProjection.PixelXYToTileXY(new Point(visibleRect2.Right, visibleRect2.Bottom), levelOfDetail); for (double x = Math.Floor(tilePt1.X); x <= Math.Ceiling(tilePt2.X); x++) { for (double y = Math.Floor(tilePt1.Y); y <= Math.Ceiling(tilePt2.Y); y++) { this.UpdateOrCreateTile(new Point(x, y), tmpGuid, levelOfDetail); } } } // Remove tiles not tagged List<int> idxToRemove = new List<int>(); for (int i = 0; i < this.tileDataList.Count; i++) { if (!tmpGuid.Equals(this.tileDataList[i].Tag)) { idxToRemove.Add(i); } } for (int i = idxToRemove.Count - 1; i >= 0; i--) { this.tileDataList.RemoveAt(idxToRemove[i]); } }
/// <summary> /// Intersects the specified source. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <returns>The computed intersection</returns> private static Rect Intersect(Rect source, Rect target) { source.Intersect(target); return source; }
/// <summary> /// Transform the rect bounds into the smallest axis alligned bounding box that /// contains all the point in the original bounds. /// </summary> /// <param name="rect"></param> /// <returns></returns> public override Rect TransformBounds(Rect rect) { List<HitTestEdge> edges = null; // intersect the rect given to us with the bounds of the visual brush to guarantee the rect we are // searching for is within the visual brush rect.Intersect(_visualBrushBounds); // get the texture coordinate values for the rect's corners Point[] texCoordsOfInterest = new Point[4]; texCoordsOfInterest[0] = Viewport2DVisual3D.VisualCoordsToTextureCoords(rect.TopLeft, _visualBrushBounds); texCoordsOfInterest[1] = Viewport2DVisual3D.VisualCoordsToTextureCoords(rect.TopRight, _visualBrushBounds); texCoordsOfInterest[2] = Viewport2DVisual3D.VisualCoordsToTextureCoords(rect.BottomRight, _visualBrushBounds); texCoordsOfInterest[3] = Viewport2DVisual3D.VisualCoordsToTextureCoords(rect.BottomLeft, _visualBrushBounds); // get the edges that map to the given rect edges = GrabValidEdges(texCoordsOfInterest); Rect result = Rect.Empty; if (edges != null) { for (int i = 0, count = edges.Count; i < count; i++) { result.Union(edges[i]._p1Transformed); result.Union(edges[i]._p2Transformed); } } return result; }