1

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.

Julien Pires
  • 512
  • 7
  • 18
  • 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 Sep 01 '14 at 14:57
  • 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 Sep 02 '14 at 08:22
  • 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 avoided – Uli Schlachter Sep 03 '14 at 20:40

1 Answers1

3

Finally found a solution.

Just need to scale before painting the image. Like that, the image will always be the same size as 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();

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

Grandpa
  • 3,053
  • 1
  • 25
  • 35
Julien Pires
  • 512
  • 7
  • 18