Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/prawn/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ def initialize(options = {}, &block)

@background = options[:background]
@background_scale = options[:background_scale] || 1
@font = nil
@font_size = 12

@bounding_box = nil
Expand Down
56 changes: 54 additions & 2 deletions lib/prawn/font.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ class Document
# font files.
# See font_families for more information.
#
def font(name = nil, options = DEFAULT_OPTS)
return((defined?(@font) && @font) || font('Helvetica')) if name.nil?
def font(name = nil, options = nil)
return @font || font('Helvetica') if name.nil? && options.nil?

if state.pages.empty? && !state.page.in_stamp_stream?
raise Prawn::Errors::NotOnPage
end

name ||= font_family
options ||= DEFAULT_OPTS

new_font = find_font(name.to_s, options)

if block_given?
Expand All @@ -68,6 +71,51 @@ def font(name = nil, options = DEFAULT_OPTS)
@font
end

def font_family
@font ? @font.family : 'Helvetica'
end

# @method font_style(points=nil)
#
# When called with no argument, returns the current font style.
#
# When called with a single argument but no block, sets the current font
# style. When a block is used, the font style is applied transactionally and
# is rolled back when the block exits. You may still change the font style
# within a transactional block for individual text segments, or nested calls
# to font_style.
#
# Prawn::Document.generate("font_style.pdf") do
# font_style :bold
# text "Bold text"
#
# font_style(:italic) do
# text "Italic text"
# text "Bold text", :style => :bold
# text "Italic text"
# end
#
# text "Bold text"
# end
#
# Font styles are not additive, i.e. if the current style is :bold, setting
# the style to :italic results in italic, not bold-italic text. Use
# :bold_italic instead.
#
# When called without an argument, this method returns the current font
# style.
#
def font_style(style = nil, &block)
return @font ? @font.style : :normal if style.nil?

font(font.name, style: style, &block)
end

# Sets the font style
def font_style=(style = nil)
font_style(style)
end

# @method font_size(points=nil)
#
# When called with no argument, returns the current font size.
Expand Down Expand Up @@ -299,6 +347,9 @@ class Font
# The current font family
attr_reader :family

# The current font style
attr_reader :style

# The options hash used to initialize the font
attr_reader :options

Expand Down Expand Up @@ -334,6 +385,7 @@ def initialize(document, name, options = {}) #:nodoc:
@options = options

@family = options[:family]
@style = options[:style] || :normal

@identifier = generate_unique_id

Expand Down
1 change: 1 addition & 0 deletions lib/prawn/fonts/afm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def initialize(document, name, options = {}) #:nodoc:
@kern_pair_table = font_data[:kern_pair_table]
@attributes = font_data[:attributes]

@family ||= @attributes['familyname']
@ascender = @attributes['ascender'].to_i
@descender = @attributes['descender'].to_i
@line_gap = Float(bbox[3] - bbox[1]) - (@ascender - @descender)
Expand Down
1 change: 1 addition & 0 deletions lib/prawn/fonts/ttf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def initialize(document, name, options = {})
super

@ttf = read_ttf_file
@family ||= @ttf.name.font_family.first
@subsets = TTFunk::SubsetCollection.new(@ttf)
@italic_angle = nil

Expand Down
15 changes: 11 additions & 4 deletions manual/text/font.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
# If we don't pass it any arguments it will return the current font being used
# to render text.
#
# If we just pass it a font name it will use that font for rendering text
# through the rest of the document.
# If we just pass it a font name and an options hash, it will use that font for
# rendering text through the rest of the document. Both the font name and
# the options can be omitted. Valid option keys are :style and :size.
#
# It can also be used by passing a font name and a block. In this case the
# specified font will only be used to render text inside the block.
# It can also be used by passing a font name, an options hash and a block. In this
# case the specified font will only be used to render text inside the block.
#
# The default font is Helvetica.

Expand All @@ -18,6 +19,7 @@
filename = File.basename(__FILE__).gsub('.rb', '.pdf')
Prawn::ManualBuilder::Example.generate(filename) do
text "Let's see which font we are using: #{font.inspect}"
text "Family is #{font_family}, style is #{font_style}, and size is #{font_size}"

move_down 20
font 'Times-Roman'
Expand All @@ -31,6 +33,11 @@
move_down 20
text 'Written in Times again as we left the previous block.'

move_down 20
font nil, size: 16, style: :bold do
text 'Written in 16pt bold, still Times.'
end

move_down 20
text "Let's see which font we are using again: #{font.inspect}"

Expand Down
18 changes: 14 additions & 4 deletions manual/text/font_style.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# frozen_string_literal: true

# The <code>font_style</code> method works just like the <code>font</code>
# method.
#
# In fact we can even use <code>font</code> with the <code>:style</code> option
# to declare which size we want.
#
# Another way to change the font size is by supplying the <code>:style</code>
# option to the text methods.
#
# Most font families come with some styles other than normal. Most common are
# <code>bold</code>, <code>italic</code> and <code>bold_italic</code>.
#
# The style can be set the using the <code>:style</code> option, with either the
# <code>font</code> method which will set the font and style for rest of the
# document, or with the inline text methods.

require_relative '../example_helper'

Expand All @@ -20,6 +25,11 @@
styles.each do |style|
font example_font, style: style
text "I'm writing in #{example_font} (#{style})"

font_style style
text "This is also #{style}"

text "And this is also #{style}", style: style
end
end
end
133 changes: 102 additions & 31 deletions spec/prawn/font_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,109 @@
end
end

describe '#font' do
it 'allows setting of size directly when font is created' do
pdf.font 'Courier', size: 16
expect(pdf.font_size).to eq(16)
end

it 'allows temporary setting of a new font using a transaction' do
pdf.font 'Helvetica', size: 12

pdf.font 'Courier', size: 16, style: :bold do
expect(pdf.font_family).to eq('Courier')
expect(pdf.font_size).to eq(16)
expect(pdf.font_style).to eq(:bold)
end

expect(pdf.font.name).to eq('Helvetica')
expect(pdf.font_size).to eq(12)
expect(pdf.font_style).to eq(:normal)
end

it 'masks font size when using a transacation' do
pdf.font 'Courier', size: 16 do
expect(pdf.font_size).to eq(16)
end

pdf.font 'Times-Roman'
pdf.font 'Courier'

expect(pdf.font_size).to eq(12)
end
end

describe '#font_size' do
it 'returns default font size' do
expect(pdf.font_size).to eq(12)
end

it 'allows setting font size in DSL style' do
pdf.font_size 20
expect(pdf.font_size).to eq(20)
end

it 'allows setting font size in DSL style using a transaction' do
pdf.font_size 20 do
expect(pdf.font_size).to eq(20)
end

expect(pdf.font_size).to eq(12)
end

it 'allows setting font size as assignment' do
pdf.font_size = 20
expect(pdf.font_size).to eq(20)
end
end

describe '#font_style' do
it 'returns default font style' do
expect(pdf.font_style).to eq(:normal)
end

it 'allows setting font style in DSL style' do
expect(pdf.font_style).to eq(:normal)
pdf.font_style :bold
expect(pdf.font_style).to eq(:bold)
expect(pdf.font.name).to eq('Helvetica-Bold')
end

it 'allows setting font style in DSL style using a transaction' do
pdf.font_style :bold do
expect(pdf.font_style).to eq(:bold)
expect(pdf.font.name).to eq('Helvetica-Bold')
end

expect(pdf.font_style).to eq(:normal)
expect(pdf.font.name).to eq('Helvetica')
end

it 'allows setting font style as assignment' do
pdf.font_style = :bold
expect(pdf.font_style).to eq(:bold)
end
end

describe '#font_family' do
it 'returns default font family' do
expect(pdf.font_family).to eq('Helvetica')
end

it 'returns font family' do
pdf.font 'Courier', style: :bold
expect(pdf.font_family).to eq('Courier')
end

it 'returns font family for AFM font' do
pdf.font 'ZapfDingbats'
expect(pdf.font_family).to eq('ZapfDingbats')
end

it 'returns font family for TTF font' do
pdf.font "#{Prawn::DATADIR}/fonts/DejaVuSans-Bold.ttf"
expect(pdf.font_family).to eq('DejaVu Sans')
end
end

describe 'font style support' do
Expand All @@ -142,11 +240,14 @@
pdf.font 'Helvetica'
pdf.text 'In Normal Helvetica'

pdf.font nil, style: :bold
pdf.text 'In Bold Helvetica'

text = PDF::Inspector::Text.analyze(pdf.render)
expect(text.font_settings.map { |e| e[:name] }).to eq(
%i[
Courier-Bold Courier-BoldOblique Courier-Oblique
Courier Helvetica
Courier Helvetica Helvetica-Bold
]
)
end
Expand Down Expand Up @@ -233,36 +334,6 @@
end
end

describe 'Transactional font handling' do
it 'allows setting of size directly when font is created' do
pdf.font 'Courier', size: 16
expect(pdf.font_size).to eq(16)
end

it 'allows temporary setting of a new font using a transaction' do
pdf.font 'Helvetica', size: 12

pdf.font 'Courier', size: 16 do
expect(pdf.font.name).to eq('Courier')
expect(pdf.font_size).to eq(16)
end

expect(pdf.font.name).to eq('Helvetica')
expect(pdf.font_size).to eq(12)
end

it 'masks font size when using a transacation' do
pdf.font 'Courier', size: 16 do
expect(pdf.font_size).to eq(16)
end

pdf.font 'Times-Roman'
pdf.font 'Courier'

expect(pdf.font_size).to eq(12)
end
end

describe 'Document#page_fonts' do
it 'registers fonts properly by page' do
pdf.font 'Courier'
Expand Down