Several weeks ago I wrote about the first development checkpoint for Prawn, the PDF library currently being developed for the Ruby Mendicant project. I’ve finally reached the second checkpoint, which involves basic text rendering operations, and this post describes these new features, the problems I have run into, and the plans for the coming weeks. If you’re following the project, please read on.
What’s new in Archaean Prawn?
Before I go into the messy details about the hurdles I’ve run into, it makes sense to show some shiny new stuff. So here’s a quick screenshot showing some of the new stuff:
As you can see, we’re doing fancy stuff like word wrapping, bounding text within columns, and doing automated page advancing. Here’s the code that generates the document:
Prawn::Document.generate("flow.pdf") do |pdf| pdf.font "Times-Roman" pdf.stroke_line [pdf.bounds.left, pdf.bounds.top], [pdf.bounds.right, pdf.bounds.top] pdf.text content, :size => 10 pdf.bounding_box([100,600], :width => 200, :height => 500) do pdf.stroke_line [pdf.bounds.left, pdf.bounds.top], [pdf.bounds.right, pdf.bounds.top] pdf.text poem, :size => 12 end pdf.bounding_box([325,600], :width => 200, :height => 500) do pdf.stroke_line [pdf.bounds.left, pdf.bounds.top], [pdf.bounds.right, pdf.bounds.top] pdf.text poem.reverse, :size => 12 end pdf.text overflow * 10, :size => 14 pdf.text "Hooray! We've conquered the evil PDF gods", :size => 36 end
Though this is pretty basic stuff, it is already accomplishing quite a bit with not so much code. This is largely in thanks to these nifty bounding box primitives.
A bounding box is simply a rectangular drawing / text flowing area. It allows you to work with a subsection of your page, and simplifies things by removing the need for explicit coordinate math. What you are looking at here is mostly going to be Prawn’s underbelly, you can expect higher level functions in the future. Nevertheless, I hope they are interesting to prospective users / contributors after seeing a glimpse of them in action.
So what’s the bad news?
Archaean Prawn delivers what it promised, primitive text drawing operations and basic text flow functionality. The bad news is that this all took me much longer than expected, I severely underestimated the complexity of implementing text rendering in PDF. This means that rather than having working font embedding and some inroads towards ensuring UTF8 input friendliness, I’m still in the planning stages for those things.
This essentially means that for now, Prawn only supports the 14 built-in fonts specified by Adobe. This of course needs to be fixed, and I do have some sense (after ruining my afternoon today digging through various open source PDF packages and the PDF spec) of to how to implement font embedding. It just simply isn’t ready yet. JEG2 and I ported Text::AFM from Perl, which will help with font embedding for sure, it’s mostly a matter of tying all the things I’ve learned together and actually putting in the coding time.
Once I get font embedding in there, I can begin working on internationalization, but if I learned anything over the last several weeks, it’s that I know very little about character encoding or i18n. This means I need your help, which reminds me…
I need your help!
I really could use some expert help from the community to help make things go smoother. I can dredge through the spec and reverse-engineer PDFs generated from other libraries and study source code, but any shortcuts I can take along the way in the form of advice from smart people will help make things go a lot smoother.
For this reason, I’ve created a Prawn mailing list, which I hope will attract folks who have some experience with PDF, internationalization, or anything else that might be helpful. I will start posting some of my open questions and concerns there in hopes that some kind soul will help me out. This may be a good way to contribute to an open source Ruby project even if you don’t have much Ruby experience, I’m mostly going to gain from PDF domain experts here…
Also, as Prawn starts to get past the primitive stages, I need to get a sense of where it needs to go in order to best serve the community. I am mostly working on extracting feature ideas from my own work, from the features needed to integrate Prawn with Ruport, and from sample PDFs others have donated. I will probably have people vote for futures in the next few weeks, so if you have ideas, please speak up on the new mailing list, or as a response to this post.
Until Next Time…
I’ll be back again with another update within the next couple weeks, once I do some cleanup and work on getting past some of the sticking points such as font embedding. Until then, please watch Prawn on Github, especially since interesting forks are already popping up. Consider joining the Prawn mailing list, and if you have meta-commentary about the Ruby Mendicant project, there is a mailing list for that too.
Enjoy the new changes and don’t hesitate to get in touch about all things Prawn!