Schrenckii: cairo, rsvg, pixmap, pixbuf woes



Hello,

So I've been working away at integrating SVG themeable tiles into Schrenckii and have stumbled upon some problems when it comes to rsvg and cairo. I would appreciate any help anyone can offer to solve them. Sorry ahead of time about the length.

Essentially, there are three ways that I have found to draw the pieces. Each start with using rsvg to load the SVG handle:

1. Use cairo transformation matricies to resize the SVG before drawing every block on the screen, keeping no pixmap or pixbuf around.
     Pros: Block sizes can be of floating-point size, as cairo can take care of converting that to actual pixels on the screen.  Fancy game board backgrounds can be used, as cairo maintains the transparency of the SVG image.  SVG images are resized nicely both up and down (as vector art should, of course).
     Cons: Terribly slow, and not really usable in any way.  Performing a cairo SVG render for every block on the screen is really taxing on the CPU.

2. Use cairo transformation matrices to resize the SVG to the correct size and draw this to a pixmap each time the window is resized. (These pixmaps are then sprinkled on the game board accordingly)
      Pros: This is fast, and allows even "small" SVG files to be resized larger without problem, as cairo knows that the SVG is vector art when it does its transformation.
      Cons: Pixmaps do not support transparency, so when they are created we must know a background colour to paint before painting the SVG.  This eliminates the possibility of graphical backgrounds.  Also, pixmaps (therefore blocks) must be of integer size, so the height and width of the game area must be divisible by 20 and 10 respectively, or else we get a small border around the game board.

3. Use rsvg's get_pixbuf() function to get a pixbuf from the SVG file.  Re"get" and resize this pixbuf with each window resize.  These pixbufs, like the pixmaps are then sprinkled on the game board.
      Pros: This is also fast.  Pixbuf's support transparency, and this is properly respected by the get_pixbuf() method.  Therefore, graphical backgrounds can be used.
      Cons: A pixbuf is not a Drawable, so cairo cannot paint directly to it.  Therefore, we must use the pixbuf's resize method instead of cairo transformation matrices.  If the SVG file has a small default size, this results in a blurry up-size.  Like pixmaps, pixbufs are of integer size only. Changing the DPI from rsvg does not seem to help the situation.

In my opinion, option 3 is the best bet.  It allows proper transparency at usable speeds; resizes are only done when the window is resized.  Unfortunately, this requires the default size of the SVGs used for tiles to be larger than could be conceivably required on a screen to avoid any "upsizing".  The integer-size problem is not very important.  I am also going to be adding a strictly plain-block (like Gnometris) cairo-drawn option that doesn't require librsvg.

If anyone has any opinions on the matter (or any better solutions) please let me know :).

Thank you for reading all of that,
Steve

(I can post code of the 3 examples if anyone would like to get a better idea of the problem.)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]