PECL/Cairo 0.3.0 released!

As I'm sure you've all been longing to hear, we've finally got around to releasing a new version of PECL/Cairo! This version fixes some bugs, and adds support for some new features available since Cairo 1.10 — notably, support for subsurfaces, which are surfaces that draw onto a part of a larger surface, and for recording surfaces, which record all drawing operations and can then be used as the source for other drawing operations. Also, Mark Skilbeck has added support for Win32 fonts. Also, the FreeType font handling has been improved, and should now give more informative messages when errors occur.

Any questions, comments, bug reports, or contributed code are welcome. Drop us a line on the PECL mailing list, or try #php.pecl on EFNet.

FrOSCon 2011

I'm very pleased to be able to announce that I'll be giving two talks at this year's FrOSCon conference in St Augustin near Bonn in Germany, on the 20th and 21st of August. The first is on the PHP track, and is an overview of the PECL/Cairo extension for PHP.

The second talk is on the main track, and is about Making Software See, where I'll give an introduction to the OpenCV image processing library, including some examples in various popular programming languages.

I'm extremely happy to have been selected both by the main FrOSCon organisers and the PHP track, organised by the PHP Usergroup Dortmund. I hope to see some of you there!

Pango for PHP PECL channel

It occurs to me that though I wrote an introduction post about Pango for PHP, I forgot to mention that it's actually installable using the PECL installer.

 pecl channel-discover pecl.mgdm.net
pecl install channel://pecl.mgdm.net/Pango-0.1.0

Assuming you have the required development packages installed, it should go off and install it. You may still need to add the

extension=pango.so

line to your php.ini. Hope this helps someone give it a go! As ever, any feedback is welcome.

Using Pango for PHP: a taster

The PECL/Cairo library is pretty good at drawing vector graphics (in our opinion, as the developers, at least!), but one thing it's not able to do by itself is draw text with mildly advanced layout. It has the CairoContext::showText() function, but that doesn't really let you do anything GD can't. That's because the developers of the Cairo library decided to let another more specialised library handle the job of text layout. Much of the time, the library that gets used for this is Pango. It has several bindings already for most popular languages on Unix-like platforms. It's quite capable, and able to lay out text while taking care of things such as paragraph alignment, line breaking, bold/italic text, justification, and various other features. In this post, I intend to give a little tour of some of its features.

Quite a while ago now, I wrote an extension to wrap Pango for PHP. It's available on its Github repository. It's not available on PECL right now, but you can check it out from there and install it using the normal method. (Sorry Windows users, I've not had time to test it out on there, and likely won't any time soon. Patches are welcome, though...). It requires that the Pango headers are installed, and that PECL/Cairo is already installed into PHP.

Once installed, you can use it with Cairo. The best way to show it off is probably some example code:

  1.  
  2. <?php
  3. header("Content-Type: image/png");
  4. /* Make a 300x300px image surface */
  5. $s = new CairoImageSurface(CairoFormat::ARGB32, 300, 300);
  6. $c = new CairoContext($s);
  7.  
  8. /* Set the background to white */
  9. $c->setSourceRGB(1, 1, 1);
  10. $c->paint();
  11.  
  12. /* Let's draw using black 'ink' */
  13. $c->setSourceRGB(0, 0, 0);
  14.  
  15. /* Make a Pango layout, set the font, then set the layout size */
  16. $l = new PangoLayout($c);
  17. $desc = new PangoFontDescription("Bitstream Charter 28");
  18. $l->setFontDescription($desc);
  19. $l->setWidth(250 * PANGO_SCALE);
  20.  
  21. /* Here, we use Pango markup to make part of the text bold */
  22. $l->setMarkup("Hello <b>world!</b> Here is a rather long paragraph which should get wrapped");
  23.  
  24. /* Draw the layout on the surface */
  25. $l->showLayout($c);
  26.  
  27. /* Output the PNG to the browser */
  28. $s->writeToPng("php://output");
  29.  

If all goes to plan, you should see a PNG in your browser with the above text.

Going through each step, firstly we set up the Cairo surface to draw on, and the context we use to draw with. Once we have done that, we can create a PangoLayout object which lets us draw the text we require. The PangoLayout is passed a context, so it can invoke the drawing methods itself to draw the text. We pass the PangoLayout a PangoFontDescription object, which lets us choose from the fonts already installed on the machine. This means that we don't need to concern ourselves with the paths to actual TrueType font files, or similar - the fonts are resolved by Fontconfig or whatever system is available on your machine.

Next, we set the width of the layout. We can also set a height, but I haven't bothered on this occasion. This lets Pango know where to wrap the text - if we don't set this, it won't bother, which may result in text falling off the edge of the image. You may note that the width is multiplied by the PANGO_SCALE - this is because Pango deals in units which are a tiny fraction (1/1024, in fact) of a pixel, in order to handle antialiasing properly. Because we're using a CairoImageSurface, this means that they layout will be 250 pixels wide.

Next up, we set the text to be drawn. There are two methods available to do this; PangoLayout::setText() is used when we just want to render text with no formatting instructions. In this case, I've opted for the PangoLayout::setMarkup() method, which lets me use Pango's markup language to make part of the text bold. Many other attributes can be changed using this markup, which has shortcuts that somewhat resemble HTML.

Finally, the call to showLayout() renders the layout onto the surface. You can also render just a path, using layoutPath(), which sets the path on the surface so you can then use more advanced effects with Cairo. The layout is drawn using whatever the current source is on the Cairo context, so you can render using flat colours, gradients, other source images, or whatever takes your fancy. Additionally, this means that any transformations you have set on the Cairo context also take effect, allowing you to rotate, scale, shear and otherwise distort the text.

It probably looks a little complex just to write some text on an image, but it is rather flexible. This flexibility is handy when you consider that Cairo can render more than just PNG images; PDFs, PostScript and SVG are also easy to create. I hope that this post may inspire someone else to give it a try. Feedback and reports of issues are always welcome.

Cairo talk feedback from DPC10

I noted a couple of comments after my talk on Cairo at DPC 10 yesterday, so I thought I'd respond to them here to clear up what's going on. It's always good to get some feedback about something I've been working on so I'd like to reply and keep the conversation going if I can.

First off, someone mentioned that the wrapper seems a bit beta and incomplete - and yes, that is true. The 0.2.0 release, which is the latest as I wrote this, is still marked as beta. The aim of me coming and talking about it is to try and get some more people interested in using it, so we can get some more information from real users about what works and what doesn't. I probably didn't help by mentioning that there are some features that we intend to implement that aren't there yet, which I'll list:

  • Support for reading and writing images that aren't PNGs The developers of the core Cairo API are not really interested in handling all the various graphics formats that exist, so they decided to implement one and one only which is useful for getting data in and out. This is the functionality that we use at present. We (the developers of the wrapper) would like to fix that and handle JPEG, GIF, TIFF, and whatever new format is cool this week, but we're not quite sure how to go about that yet. We could recycle the code used by GD or use ImageMagick or GraphicsMagick, but those would introduce dependencies that people might not have available. Once we work out a decent solution here, it will be put in.
  • Support for hyperlinks in PDFs and SVGs Again, this is something we'd quite like but it's not supported in the underlying library yet. There have been rumours about adding an API to do this, but there hasn't been a concensus about what's a good way to go about it. It's something I'd quite like to help fix, so I've been learning how Cairo itself is put together with the intention to add the support.

The other comments I saw suggested that the API is a bit fiddly, which I can't deny. It's not quite as simple to set up and get running as some of the other libraries in PHP already. This is nearly intentional - we're wrapping the underlying Cairo API as closely as we can, because we don't want to diverge too far from how other languages with Cairo wrappers work, so that developers who may be familiar with those already know roughly what is going on. It's for this reason that, for example, the API uses floating-point values from 0 to 1 to define the intensity of colours, rather than an integer value from 0-255 which most people are probably used to. This is because Cairo is designed not to make any assumptions about the surface you're going to be drawing to - some day we might get 16-bits-per-channel surfaces, and using float values means that we don't need to change the API or the values we're passing in to allow us to write to them. It'll just carry on working as it did before, just with better colour resolution.

However, if anyone has any ideas for how we could make things simpler, then we'd love to hear about it &emdash; drop us a line on the PECL developers mailing list (which you can find on the PECL mailing lists page), or find us on IRC on #php.pecl on EFnet.

There are a couple of things that I have worked on which sit on top of the Cairo extension, which can do some interesting things. If you're still at DPC I'll be demoing a couple of them on the uncon track at 2pm. It's only a 15 minute talk, so it shouldn't be too boring...!

 1 2 Next →

About

User