/// <summary> /// Draw the background image of the given box in the given rectangle.<br/> /// Handle background-repeat and background-position values. /// </summary> /// <param name="g">the device to draw into</param> /// <param name="box">the box to draw its background image</param> /// <param name="imageLoadHandler">the handler that loads image to draw</param> /// <param name="rectangle">the rectangle to draw image in</param> public static void DrawBackgroundImage(Canvas g, CssBox box, ImageBinder imageBinder, RectangleF rectangle) { var image = imageBinder.Image; //temporary comment image scale code var imgSize = image.Size; //new Size(imageLoadHandler.Rectangle == Rectangle.Empty ? imageLoadHandler.Image.Width : imageLoadHandler.Rectangle.Width, // imageLoadHandler.Rectangle == Rectangle.Empty ? imageLoadHandler.Image.Height : imageLoadHandler.Rectangle.Height); // get the location by BackgroundPosition value var location = GetLocation(box.BackgroundPositionX, box.BackgroundPositionY, rectangle, imgSize); //var srcRect = imageLoadHandler.Rectangle == Rectangle.Empty // ? new Rectangle(0, 0, imgSize.Width, imgSize.Height) // : new Rectangle(imageLoadHandler.Rectangle.Left, imageLoadHandler.Rectangle.Top, imgSize.Width, imgSize.Height); var srcRect = new Rectangle(0, 0, image.Width, image.Height); // initial image destination rectangle var destRect = new Rectangle(location, imgSize); // need to clip so repeated image will be cut on rectangle var prevClip = g.CurrentClipRect; PixelFarm.Drawing.Rectangle copyRect = new PixelFarm.Drawing.Rectangle( (int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height); copyRect.Intersect(prevClip); g.SetClipRect(copyRect); switch (box.BackgroundRepeat) { case CssBackgroundRepeat.NoRepeat: g.DrawImage(image, new RectangleF(location, imgSize), new RectangleF(0, 0, image.Width, image.Height)); break; case CssBackgroundRepeat.RepeatX: DrawRepeatX(g, image, rectangle, srcRect, destRect, imgSize); break; case CssBackgroundRepeat.RepeatY: DrawRepeatY(g, image, rectangle, srcRect, destRect, imgSize); break; default: DrawRepeat(g, image, rectangle, srcRect, destRect, imgSize); break; } g.SetClipRect(prevClip); }
public void InvalidateGraphicArea(RenderElement fromElement, ref Rectangle elemClientRect) { //total bounds = total bounds at level if (this.IsInRenderPhase) { return; } //-------------------------------------- //bubble up ,find global rect coord //and then merge to accumulate rect //int globalX = 0; //int globalY = 0; Point globalPoint = new Point(); bool isBubbleUp = false; #if DEBUG int dbug_ncount = 0; dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, dbug_ncount, ">> :" + elemClientRect.ToString()); #endif do { if (!fromElement.Visible) { #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "EARLY-RET: "); #endif return; } else if (fromElement.BlockGraphicUpdateBubble) { #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "BLOCKED2: "); #endif return; } //--------------------------------------------------------------------- #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, dbug_ncount, ">> "); #endif globalPoint.Offset(fromElement.X, fromElement.Y); //globalX += fromElement.BubbleUpX; //globalY += fromElement.BubbleUpY; if (fromElement.MayHasViewport && isBubbleUp) { //elemClientRect.Offset(globalX, globalY); elemClientRect.Offset(globalPoint); if (fromElement.HasDoubleScrollableSurface) { //container.VisualScrollableSurface.WindowRootNotifyInvalidArea(elementClientRect); } Rectangle elementRect = fromElement.RectBounds; elementRect.Offset(fromElement.ViewportX, fromElement.ViewportY); elemClientRect.Intersect(elementRect); globalPoint.X = -fromElement.ViewportX; globalPoint.Y = -fromElement.ViewportY; //globalX = -fromElement.ViewportX; //globalY = -fromElement.ViewportY; } if (fromElement.IsTopWindow) { break; } else { #if DEBUG if (fromElement.dbugParentVisualElement == null) { dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "BLOCKED3: "); } #endif var parentLink = fromElement.MyParentLink; if (parentLink == null) { return; } parentLink.AdjustLocation(ref globalPoint); //move up fromElement = parentLink.ParentRenderElement;// fromElement.ParentRenderElement; if (fromElement == null) { return; } } isBubbleUp = true; } while (true); #if DEBUG var dbugMyroot = this; if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { while (dbug_ncount > 0) { dbugMyroot.dbugGraphicInvalidateTracer.PopElement(); dbug_ncount--; } } #endif //---------------------------------------- //elemClientRect.Offset(globalX, globalY); elemClientRect.Offset(globalPoint); if (elemClientRect.Top > this.Height || elemClientRect.Left > this.Width || elemClientRect.Bottom < 0 || elemClientRect.Right < 0) { //no intersect with #if DEBUG if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("ZERO-EEX"); dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("\r\n"); } #endif return; } //-------------------------------------------------------------------------------------------------- if (!hasAccumRect) { accumulateInvalidRect = elemClientRect; hasAccumRect = true; } else { accumulateInvalidRect = Rectangle.Union(accumulateInvalidRect, elemClientRect); } #if DEBUG if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { string state_str = "ACC: "; if (this.dbugNeedContentArrangement || this.dbugNeedReCalculateContentSize) { state_str = "!!" + state_str; } dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("ACC: " + accumulateInvalidRect.ToString()); dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("\r\n"); } #endif }
/// <summary> /// Intersect Method /// </summary> /// /// <remarks> /// Replaces the Rectangle with the intersection of itself /// and another Rectangle. /// </remarks> public void Intersect(Rectangle rect) { this = Rectangle.Intersect(this, rect); }