public void DrawImage(Pixbuf image, RectangleD layout, RectangleD imagePart, SizeMode sizeMode = SizeMode.Fit) { double x = layout.X * drawingScaleX; double y = layout.Y * drawingScaleY; double width = layout.Width * drawingScaleX; double height = layout.Height * drawingScaleY; if (width.IsZero() || height.IsZero()) { return; } double scaleX = width / imagePart.Width; double scaleY = height / imagePart.Height; using (Pixbuf pbCropped = new Pixbuf(Colorspace.Rgb, true, 8, (int)imagePart.Width, (int)imagePart.Height)) { image.CopyArea((int)imagePart.X, (int)imagePart.Y, (int)imagePart.Width, (int)imagePart.Height, pbCropped, 0, 0); using (Pixbuf pbScaled = new Pixbuf(Colorspace.Rgb, true, 8, (int)width, (int)height)) { pbCropped.Scale(pbScaled, 0, 0, pbScaled.Width, pbScaled.Height, 0, 0, scaleX, scaleY, InterpType.Hyper); CairoHelper.SetSourcePixbuf(cairoContext, pbScaled, x, y); cairoContext.Paint(); } } }
/// <summary> /// Called when the widget is exposed or drawn. /// </summary> /// <param name="e">The e.</param> /// <returns></returns> protected override bool OnExposeEvent(EventExpose e) { // Figure out the area we are rendering into. Gdk.Rectangle area = e.Region.Clipbox; var cairoArea = new Rectangle(area.X, area.Y, area.Width, area.Height); using (Context cairoContext = CairoHelper.Create(e.Window)) { // Create a render context. var renderContext = new RenderContext(cairoContext); renderContext.RenderRegion = cairoArea; // If we don't have a buffer at this point, don't render anything. if (Renderer == null || LineBuffer == null) { return(true); } // Paint the background color of the window. RegionBlockStyle backgroundStyle = Theme.RegionStyles[Theme.BackgroundRegionStyleName]; DrawingUtility.DrawLayout(this, renderContext, cairoArea, backgroundStyle); // Reset the layout and its properties. Renderer.Width = area.Width - margins.Width; // Figure out the viewport area we'll be drawing. int offsetY = 0; if (verticalAdjustment != null) { offsetY += (int)verticalAdjustment.Value; } var viewArea = new Rectangle( area.X, area.Y + offsetY, area.Width, area.Height); // Determine the line range visible in the given area. int startLine, endLine; Renderer.GetLineLayoutRange(viewArea, out startLine, out endLine); // Determine where the first line actually starts. int startLineY = 0; if (startLine > 0) { startLineY = Renderer.GetLineLayoutHeight(0, startLine - 1); } // Go through the lines and draw each one in the correct position. double currentY = startLineY - offsetY; for (int lineIndex = startLine; lineIndex <= endLine; lineIndex++) { // Figure out if we are on the current line. var lineContexts = LineContexts.None; bool currentLine = false; if (lineIndex == caret.Position.LinePosition) { // Add the curent line to the context. lineContexts |= LineContexts.CurrentLine; currentLine = true; } // Pull out the layout and style since we'll use it. Layout layout = Renderer.GetLineLayout(lineIndex, lineContexts); LineBlockStyle style = Renderer.GetLineStyle(lineIndex, lineContexts); // Get the extents for that line. int layoutWidth, layoutHeight; layout.GetPixelSize(out layoutWidth, out layoutHeight); // Figure out the height of the line including padding. double height = layoutHeight + style.Height; if (currentLine) { // If we have a full-line background color, display it. RegionBlockStyle currentLineStyle = Theme.RegionStyles[Theme.CurrentLineRegionStyleName]; if (currentLineStyle != null) { var lineArea = new Rectangle(TextX, currentY, TextWidth, height); DrawingUtility.DrawLayout( this, renderContext, lineArea, currentLineStyle); } // If we have a wrapped line background color, draw it. RegionBlockStyle currentWrappedLineStyle = Theme.RegionStyles[Theme.CurrentWrappedLineRegionStyleName]; if (currentWrappedLineStyle != null) { // Get the wrapped line for the caret's position. LayoutLine wrappedLine = caret.Position.GetWrappedLine(this); Pango.Rectangle wrappedLineExtents; wrappedLine.GetPixelExtents(out wrappedLineExtents); // Draw the current wrapped line index. var wrappedLineArea = new Rectangle( TextX, currentY + wrappedLineExtents.Y + style.Top, TextWidth, wrappedLineExtents.Height); DrawingUtility.DrawLayout( this, renderContext, wrappedLineArea, currentWrappedLineStyle); } } // Draw the current line along with wrapping and padding. DrawingUtility.DrawLayout( this, renderContext, new Rectangle(TextX, currentY, TextWidth, height), layout, style); // Render out the margin renderers. margins.Draw( this, renderContext, lineIndex, new PointD(0, currentY), height, style); // Move down a line. currentY += height; } // Draw the caret on the screen, but only if we have focus. if (IsFocus) { caret.Draw(renderContext); } // Show the scroll region, if requested. if (editorViewSettings.ShowScrollPadding) { cairoContext.Color = new Color(1, 0.5, 0.5); cairoContext.Rectangle(scrollPaddingRegion); cairoContext.Stroke(); } } return(true); }