Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I change font in Prawn

What I'm trying to do is generate a PDF using Prawn, while having some language specific characters.

And as a result I'm getting the following error:

raise Prawn::Errors::IncompatibleStringEncoding,
   "Your document includes text that's not compatible with the  Windows-1252 character set.\n" \
   "If you need full UTF-8 support, use TTF fonts instead of PDF's built-in fonts\n."

So I tried changing the font by doing this:

# app/models/prawn/change_font_decorator.rb

Prawn::Document.generate("output.pdf") do
  font_families.update("Arial" => {
    :normal => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold_italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf")
  })
  font "Arial"
end

Yet, I'm getting the same error when trying to generate a PDF file.

Any ideas on how to solve this?

like image 406
Catalin Avatar asked Nov 17 '16 09:11

Catalin


Video Answer


2 Answers

The prawn manual is an excellent reference, and includes sections on font usage. The "External Fonts" section is particularly relevant to your issue.

Here's a basic case that should work, although it doesn't support bold and italic:

Prawn::Document.generate("output.pdf") do
  font Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf")
  text "Euro €"
end

To also use bold and italic, it's best to register a font family that doesn't conflict with one of the standard PDF fonts:

Prawn::Document.generate("output.pdf") do
  font_families.update("OpenSans" => {
    :normal => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf"),
    :bold_italic => Rails.root.join("app/assets/fonts/OpenSans-Regular.ttf")
  })
  font "OpenSans"
  text "Euro €"
end

Where do I put the above code?

If you are inheriting from Prawn::Document you can try out the following:

class SpreeInvoicePdf < Prawn::Document
  require 'prawn'

  def initialize(quote, line_items)
    self.font_families.update("OpenSans" => {
                                :normal => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-Regular.ttf"),
                                :italic => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-Italic.ttf"),
                                :bold => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-Bold.ttf"),
                                :bold_italic => Rails.root.join("vendor/assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf")
    })

    font "OpenSans"

  # etc.

You will of course need to go to Google fonts and download the fonts and place it in the vendor/assets/fonts/Open_Sans/ directory.

like image 143
James Healy Avatar answered Sep 20 '22 05:09

James Healy


If you're building your PDF using initialize, you can simply update your font families in the initialize method and then set the desired font.

class InvoicePdf < Prawn::Document

  def initialize()
    super()
    self.font_families.update("DejaVuSans" => {:normal => "#{Rails.root}/public/DejaVuSans.ttf"})
    font "DejaVuSans"
    business_logo
    invoice_items
    footer
  end

  def business_logo
    ##stuff here
  end

end
like image 20
Patrick Jones Avatar answered Sep 22 '22 05:09

Patrick Jones