/// <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(IGraphics g, CssBox box, ImageLoadHandler imageLoadHandler, RectangleF rectangle) { // image size depends if specific rectangle given in image loader var imgSize = 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 Point location = GetLocation(box.BackgroundPosition, rectangle, imgSize); Rectangle 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); // initial image destination rectangle var destRect = new Rectangle(location, imgSize); // need to clip so repeated image will be cut on rectangle RectangleF prevClip = g.GetClip(); RectangleF lRectangle = rectangle; lRectangle.Intersect(prevClip); g.SetClip(lRectangle); switch (box.BackgroundRepeat) { case "no-repeat": g.DrawImage(imageLoadHandler.Image, destRect, srcRect); break; case "repeat-x": DrawRepeatX(g, imageLoadHandler, rectangle, srcRect, destRect, imgSize); break; case "repeat-y": DrawRepeatY(g, imageLoadHandler, rectangle, srcRect, destRect, imgSize); break; default: DrawRepeat(g, imageLoadHandler, rectangle, srcRect, destRect, imgSize); break; } g.SetClip(prevClip); }
/// <summary> /// Draw the background image at the required location repeating it over the Y axis.<br/> /// Adjust location to top if starting location doesn't include all the range (adjusted to center or bottom). /// </summary> private static void DrawRepeatY(IGraphics g, ImageLoadHandler imageLoadHandler, RectangleF rectangle, Rectangle srcRect, Rectangle destRect, Size imgSize) { while (destRect.Y > rectangle.Y) { destRect.Y -= imgSize.Height; } using (var brush = new TextureBrush(imageLoadHandler.Image, srcRect)) { brush.TranslateTransform(destRect.X, destRect.Y); g.FillRectangle(brush, destRect.X, rectangle.Y, srcRect.Width, rectangle.Height); } }