Prawn 0.3 saw a very quiet release a while ago, mainly because of the holiday crunch. However, as most people who have used it know, a bunch of glittering features were added by our contributors. The changes in 0.4 are a little less flashy, but not anything to shake a stick at. They pave the way for the transition from an experimental alpha-level library to a fairly solid beta, and this means you’ll have a lot to look forward to in the near future as a result of the work we’ve done on 0.4.
I’m going to start by giving a little background for those who haven’t had their ear to the ground, but the dedicated Prawn follower will find the key details about specific changes immediately after the following section. Feel free to skip the intro if you already know the score.
Previous to this release, Prawn’s font and text rendering system had grown to become fairly labyrinthine, and had included a fair bit of special casing that wasn’t pleasant to explain. We really should have seen the writing on the wall when documentation like this slipped into Prawn 0.3:
Thankfully, things like this have gone away in Prawn 0.4. The release includes a number of fixes that attack similar problems, with the intention of making Prawn a bit more predictable, consistent, and approachable for our users.
In addition to this comprehensive cleanup of the text rendering system, we started to think a bit more about the long term goals of the project. There are a lot of exciting ideas that are now coming into fruition, but we worried about the core of Prawn becoming bloated and shrouded in complexity if we continued to develop it as a monolithic package. For this reason, we’ve been working towards the idea of forming a tight, tiny core that other extensions can build on top of.
The support for tables and cells has been extracted out into a package called prawn-layout, which will serve as the official ‘layout’ extension for Prawn. All the new features that have been added to the developmental versions of Prawn’s table support have been included in this new extension. Though it sounds like a big move, you’ll see later on in the notes that the actual impact on users will be minimal, while the benefits will be substantial.
We’ve also decided that Jamis Buck’s ambitious inline styling engine for Prawn would introduce a lot of complexity if made part of the core. However, we have full intentions to support this great project as an extension, called prawn-format. Though Jamis wasn’t quite ready for a release by the time Prawn 0.4 hit RubyForge, it shouldn’t be long before he has this system out as a gem for public consumption. If you have complex formatting needs, you’ll definitely want to watch out for an announcement about this, or even head over to github and kick the tires while he stabilizes things.
So, barring the fact that we don’t have the details on Jamis’s prawn-format package yet, the key details are in what’s new or changed in the text system, and what to expect when you use prawn-layout. Keep in mind that these notes are not comprehensive, but they should be enough to get you going. Let me know if you feel they’re missing something by leaving a comment.
Although a lot of changes to the font system were mainly to give us better control over the internals, some things are sure to make at least a few people smile.
Previous to this release, Prawn was embedding entire font files in each document, no matter how simple your text was. For non-latin based character sets, this was producing massive PDFs, especially for many of our Asian friends. I’m delighted to say that Jamis has licked this issue, and Prawn now subsets your TTF files so that only the glyphs you use in your document are embedded. This means that a one page letter to Mom in Chinese will weigh in the kilobytes rather than megabytes, which is probably closer to what you’d expect. This change is implemented via our vendored library TTFunk, so those who are looking for a way to do this with TrueType fonts at the low level for purposes other than generating PDF are welcome to give this library a shot.
You don’t have to do anything at all in order to take advantage of this feature, aside from upgrade to Prawn 0.4.
It’s no secret how many folks are using OS X in the Ruby community. Now, you can take advantage of the full range of fonts on your system. The syntax is a little different than if you use an ordinary TTF, but it’s still relatively painless. Here’s a quick example of setting up a font family as well as loading a DFont file directly.
Prawn has had a rather strange ‘feature’ for a while, in that it has allowed each individual font to have its own current font size. We decided against this, and have settled on a single font size per document. Most people won’t notice this change, but what it means is that Prawn will work closer to what you might expect in other text processing systems
The current behavior is shown. If it’s what you’d expect, then you don’t need to worry about anything. If it is surprising to you however, you might need to re-think your code before upgrading to Prawn 0.4.
>> pdf.font "Courier", :size => 16 => Prawn::Font::AFM< Courier: 16 > >> pdf.font "Times-Roman", :size => 8 => Prawn::Font::AFM< Times-Roman: 8 > >> pdf.font "Courier" => Prawn::Font::AFM< Courier: 8 >
For this reason, we’ve also moved away from font.size back to font_size. his works as it did in Prawn 0.2, and makes a lot more sense now that we’ve changed our approach. Your document has one font size, and Document#font_size is how you’ll access and tweak it.
We’re now able to accurately determine the line_gap associated with a TTF file, which has enabled us to normalize our calculations in a lot of places. If you want to get a good sense of how font calculations work in Prawn, you’ll want to study the font calculations example distributed with the source. The underlying Prawn::Font class and its associated subclasses have also been overhauled, and though their documentation is a bit spare, you might investigate them if you have low level font calculation needs. These are certainly a little less scary than they have been in previous releases, but still depend on a fairly strong knowledge of how PDF fonts work.
Quite a bit has changed under the hood with fonts. You’ll want to review the commit logs and bug us when you run into problems. But at the user level these are the primary things of interest, unless I’ve missed something.
When you install the Prawn gem, it’ll go and pull down prawn-layout for you, but the one thing you’ll need to do is remember to add the following line after requiring Prawn itself:
require "prawn/layout"
Aside from the changes mentioned here, most of your code will still work as it did in 0.3, the overall changes to the Table API have been minimal.
Andrew Timberlake fixed a problem with our tables that in the past prevented someone from being able to use Prawn. While I’ve never personally minded whether a table sails off the edge of the page when it is too wide, there are definitely better ways to handle this. Andrew’s demonstration shows off the new behavior, which should make people happy. However, as a result of adding a :width option, the :widths option for column widths became a bit too ambiguous. This has been renamed to :column_widths, so be sure to update your code accordingly. To help you catch issues with this key change, turn on debugging via:
Prawn.debug = true
This will cause any place you used :widths instead of :column_widths to bubble up to the surface, making it easy for you to make the switch.
Prawn::Document::Table has become Prawn::Table. Prawn::Graphics::Cell and Prawn::Graphics::CellBlock have been renamed Prawn::Table::Cell and Prawn::Table::CellBlock. Most of you probably use these classes indirectly via Document, but if you’ve been doing some low level stuff, be sure to do a global find and replace on these constants.
You might find some other goodies in tables, by checking the API docs and looking at the examples distributed with prawn-layout‘s source. As the name suggests, this package will be the future home of other layout tools, which we’re still dreaming up now. But for now, keep in mind that this is the new home of our tables. The fewer ‘You broke tables!’ emails we get, the better. :)
You’ll notice that there are a few new projects on our Lighthouse main page now. It should be fairly self-explanatory, but please try to use the right tracker when you report an issue. Prawnto is for Prawn’s (unofficial) Rails plugin, prawn-format is for Jamis Buck’s yet-to-be-released formatting engine, prawn-layout is for tables and cells, and prawn-core is for everything else. If in doubt, file your ticket in prawn-core and we’ll help point you in the right direction.
Don’t let the shiny exterior fool you. Prawn is still dangerous, subject to change, might insult you or your mother’s sensibilities, and might have performance bottlenecks in places that make you curse me, Matz, and whoever your employer is. What’s more, if you approach us with the expectation that Prawn should already be production ready and fully suited to your needs, you’re likely to get an indifferent reply, if you get one at all. We might even fight you, if we’re especially cranky that day. You’ve been warned, you bastard!
Assuming the above paragraph has scared away those folks who aren’t familiar with how open source works and don’t want to learn, I’ll let you know it was mostly a joke. Prawn is getting more stable each day, but there is a lot left to be done. We hope to be able to call Prawn 0.5 a beta release, complete with a little manual that helps you get used to working with Prawn. We also hope that the core API gets more and more solidified, so that you can depend on it a little. But all of this takes time and energy, so it’ll happen when it happens.
To put it in a nutshell, Prawn is for folks who are willing to roll up their sleeves a bit. That doesn’t mean you’ll have to necessarily, I actually hear a lot of reports of people using Prawn with no issues without any help from us. However, if you find a feature missing, run into a bug, or want to see things go in a particular direction we’re not already pointing towards, be prepared to do the legwork. Until 1.0, there will be no user-level support for Prawn, only support for contributors. Luckily, asking a good question counts as contribution, so don’t be afraid! Which brings me to the final point of these notes.
We need testers on as many platforms as possible. We need people to share their experiences and if possible, their code, so we can see how Prawn is doing out in the wild. So don’t just sit around and ride the sea creature without us. Join the party by talking to us on IRC (#prawn on irc.freenode.net), catching up with us on the mailing list(http://groups.google.com/group/prawn-ruby), and otherwise getting involved.
Use blog posts, tweets, smoke signals, whatever you want. But tell us what you think now, don’t wait until 1.0 to tell us how much we suck (or rule). This is also serves as a friendly reminder to PDF::Writer users: Prawn is essentially your PDF::Writer 2.0, so get off your butt and tell us what changes you need to in order to migrate. Hell, if you’re using any PDF library in Ruby that isn’t Prawn, we want to know why. We can’t promise to please all of you, but I’m pretty sure we can cover most of the bases.
Enjoy the release!
Written by Gregory Brown on 2009.01.17 at 20:38 | Responses