1
votes

I'm developing an application in C# with GTk. In this application I have to display boxes. Some are filled with color and others with an image. These boxes are resizable and movable. Boxes are displayed in a DrawingArea.

When I draw an image with Cairo context the image doesn't fill the box entirely if the image is larger than the box. I have tried some solutions like using ScaleSimple method on the Pixbuf every time the box is resized, but when the box is large the application become slow. And create a new Pixbuf instance everytime is not a good approach since performance is important for my application.

I have searched in the documentation and internet if there is a parameter to tell Cairo to fill the rectangle with the image but I had found nothing.

Here is my code to draw the image :

context.Translate(Bounds.X, Bounds.Y);
CairoHelper.SetSourcePixbuf(context, _source.Buffer, 0.0d, 0.0d);
context.Rectangle(0.0d, 0.0d, Bounds.Width, Bounds.Height);
context.Fill();

Bounds is a Gdk.Rectangle and _source.Buffer a Pixbuf instance.

Thanks for the help.

1
What exactly does 'fill a rectangle' mean to you? You want to scale the image so that it covers all pixels of your rectangle? You want to repeat the image multiple times so that everything is painted?Uli Schlachter
I want to scale the image to fill all pixels of my rectangle. Currently if I have a rectangle of 100x100 and an image of 1024x1024, the rectangle is filled with the top-left part of the image that correspond to 100x100. I have tried to use ScaleSimple method on my Pixbuf, work well but this solution slow down my application and it seems heavy to recreate a pixbuf. So I'm looking for a faster solution.Julien Pires
Uhm, so you want to cache your scaled surfaces? Perhaps if you have a 1024x1024 one, you could cache 512x512, 256x256 etc ones and use the closest one? Perhaps also cache the one that fits the current rectangle size. Scaling is slow, there isn't that much that can be done about it, so it should be avoidedUli Schlachter

1 Answers

1
votes

Finally found a solution.

Just need to scale before painting the image. Like that the image will always be of the same size of a defined rectangle.

float xScale = (float)rectangle.Width / (float)buffer.Width;
float yScale = (float)rectangle.Height / (float)buffer.Height;
context.Translate(rectangle.X, rectangle.Y);
context.Scale(xScale, yScale);

CairoHelper.SetSourcePixbuf(context, buffer, 0.0d, 0.0d);
context.Paint();

Variable named buffer is a Pixbuf instance. With this solution, no need to recreate the Pixbuf by using ScaleSimple and the application doesn't slow down.