Module: PDF::Core::Text

Defined in:
lib/pdf/core/text.rb

Overview

Low-level text rendering.

Defined Under Namespace

Classes: BadFontFamily

Constant Summary collapse

VALID_OPTIONS =

Valid options of text drawing. These should be used as a base. Extensions may build on this list

%i[kerning size style].freeze
MODES =

text rendering modes

{
  fill: 0,
  stroke: 1,
  fill_stroke: 2,
  invisible: 3,
  fill_clip: 4,
  stroke_clip: 5,
  fill_stroke_clip: 6,
  clip: 7,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#skip_encodingObject (readonly)

Deprecated.


37
38
39
# File 'lib/pdf/core/text.rb', line 37

def skip_encoding
  @skip_encoding
end

Instance Method Details

#add_text_content(text, x, y, options) ⇒ Object

Add a text object to content stream.

Parameters:

  • text (String)
  • x (Numeric)

    horizontal position of the text origin on the page

  • y (Numeric)

    vertical position of the text origin on the page

  • options (Hash)

Options Hash (options):

  • :rotate (Numeric)

    text rotation angle in degrees

  • :kerning (Boolean)


332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/pdf/core/text.rb', line 332

def add_text_content(text, x, y, options)
  chunks = font.encode_text(text, options)

  add_content("\nBT")

  if options[:rotate]
    rad = Float(options[:rotate]) * Math::PI / 180
    array = [
      Math.cos(rad),
      Math.sin(rad),
      -Math.sin(rad),
      Math.cos(rad),
      x, y,
    ]
    add_content("#{PDF::Core.real_params(array)} Tm")
  else
    add_content("#{PDF::Core.real(x)} #{PDF::Core.real(y)} Td")
  end

  chunks.each do |(subset, string)|
    font.add_to_current_page(subset)
    add_content(
      [
        PDF::Core.pdf_object(font.identifier_for(subset), true),
        PDF::Core.pdf_object(font_size, true),
        'Tf',
      ].join(' '),
    )

    operation = options[:kerning] && string.is_a?(Array) ? 'TJ' : 'Tj'
    add_content("#{PDF::Core.pdf_object(string, true)} #{operation}")
  end

  add_content("ET\n")
end

#character_spacing(amount = nil) { ... } ⇒ Numeric, void

Increases or decreases the space between characters. For horizontal text, a positive value will increase the space. For vertical text, a positive value will decrease the space.

Call with no arguments to retrieve current character spacing.

Parameters:

  • amount (Numeric) (defaults to: nil)

Yields:

  • Temporarily set character spacing

Returns:

  • (Numeric)

    if called without amount

  • (void)

    otherwise



254
255
256
257
258
259
260
261
262
263
264
# File 'lib/pdf/core/text.rb', line 254

def character_spacing(amount = nil, &block)
  if amount.nil?
    return (defined?(@character_spacing) && @character_spacing) || 0
  end

  if character_spacing == amount
    yield
  else
    wrap_and_restore_character_spacing(amount, &block)
  end
end

#default_kerning(value) ⇒ void Also known as: default_kerning=

This method returns an undefined value.

Call with a boolean to set the document-wide kerning setting. This can be overridden using the :kerning text option when drawing text or a text box.

Examples:

pdf.default_kerning = false
pdf.text('hello world')                # text is not kerned
pdf.text('hello world', kerning: true) # text is kerned

Parameters:

  • value (Boolean)


84
85
86
# File 'lib/pdf/core/text.rb', line 84

def default_kerning(value)
  @default_kerning = value
end

#default_kerning?Boolean

Retrieve the current default kerning setting.

Defaults to ‘true`.

Returns:

  • (Boolean)


67
68
69
70
71
# File 'lib/pdf/core/text.rb', line 67

def default_kerning?
  return true unless defined?(@default_kerning)

  @default_kerning
end

#default_leading(number = nil) ⇒ Numeric Also known as: default_leading=

Call with no argument to retrieve the current default leading.

Call with a number to set the document-wide text leading. This can be overridden using the :leading text option when drawing text or a text box.

Defaults to 0.

Examples:

pdf.default_leading = 7
pdf.text('hello world')             # a leading of 7 is used
pdf.text('hello world', leading: 0) # a leading of 0 is used

Parameters:

  • number (Numeric) (defaults to: nil)

Returns:

  • (Numeric)


105
106
107
108
109
110
111
# File 'lib/pdf/core/text.rb', line 105

def default_leading(number = nil)
  if number.nil?
    (defined?(@default_leading) && @default_leading) || 0
  else
    @default_leading = number
  end
end

#fallback_fonts(fallback_fonts = nil) ⇒ Array<String> Also known as: fallback_fonts=

Call with no argument to retrieve the current fallback fonts.

Call with an array of font names. Each name must be the name of an AFM font or the name that was used to register a family of TTF fonts (see Prawn::Document#font_families). If present, then each glyph will be rendered using the first font that includes the glyph, starting with the current font and then moving through :fallback_fonts from left to right.

Call with an empty array to turn off fallback fonts.

Side effects:

  • Increased overhead when fallback fonts are declared as each glyph is checked to see whether it exists in the current font

Examples:

file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
font_families['Kai'] = {
  normal: { file: file, font: 'Kai' }
}
file = "#{Prawn::DATADIR}/fonts/Action Man.dfont"
font_families['Action Man'] = {
  normal: { file: file, font: 'ActionMan' },
}
fallback_fonts ['Times-Roman', 'Kai']
font 'Action Man'
text 'hello ƒ 你好'
# hello prints in Action Man
# ƒ prints in Times-Roman
# 你好 prints in Kai

fallback_fonts [] # clears document-wide fallback fonts

Parameters:

  • fallback_fonts (Array<String>) (defaults to: nil)

Returns:

  • (Array<String>)


184
185
186
187
188
189
190
# File 'lib/pdf/core/text.rb', line 184

def fallback_fonts(fallback_fonts = nil)
  if fallback_fonts.nil?
    (defined?(@fallback_fonts) && @fallback_fonts) || []
  else
    @fallback_fonts = fallback_fonts
  end
end

#forget_text_rendering_mode!void

This method returns an undefined value.

Forget previously set text rendering mode.



240
241
242
# File 'lib/pdf/core/text.rb', line 240

def forget_text_rendering_mode!
  @text_rendering_mode = :unknown
end

#horizontal_text_scaling(amount = nil) { ... } ⇒ Numeric, void

Set the horizontal scaling.

Parameters:

  • amount (Numeric) (defaults to: nil)

    the percentage of the normal width.

Yields:

  • Temporarili set text scaling

Returns:

  • (Numeric)

    if called with no arguments

  • (void)

    otherwise



292
293
294
295
296
297
298
299
300
301
302
# File 'lib/pdf/core/text.rb', line 292

def horizontal_text_scaling(amount = nil, &block)
  if amount.nil?
    return (defined?(@horizontal_text_scaling) && @horizontal_text_scaling) || 100
  end

  if horizontal_text_scaling == amount
    yield
  else
    wrap_and_restore_horizontal_text_scaling(amount, &block)
  end
end

#process_text_options(options) ⇒ void

This method returns an undefined value.

Low level call to set the current font style and extract text options from an options hash. Should be called from within a save_font block

Parameters:

  • options (Hash)

Options Hash (options):

  • :style (Symbol, String)
  • :kerning (Boolean)
  • :size (Numeric)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/pdf/core/text.rb', line 47

def process_text_options(options)
  if options[:style]
    raise BadFontFamily unless font.family

    font(font.family, style: options[:style])
  end

  # must compare against false to keep kerning on as default
  unless options[:kerning] == false
    options[:kerning] = font.has_kerning_data?
  end

  options[:size] ||= font_size
end

#rise(amount = nil) { ... } ⇒ Numeric, void

Move the baseline up or down from its default location. Positive values move the baseline up, negative values move it down, and a zero value resets the baseline to its default location.

Parameters:

  • amount (Numeric) (defaults to: nil)

Yields:

  • Temporarily set text rise

Returns:

  • (Numeric)

    if called with no arguments

  • (void)

    otherwise



312
313
314
315
316
317
318
319
320
321
322
# File 'lib/pdf/core/text.rb', line 312

def rise(amount = nil, &block)
  if amount.nil?
    return (defined?(@rise) && @rise) || 0
  end

  if rise == amount
    yield
  else
    wrap_and_restore_rise(amount, &block)
  end
end

#text_direction(direction = nil) ⇒ :ltr, :rtl Also known as: text_direction=

Call with no argument to retrieve the current text direction.

Call with a symbol to set the document-wide text direction. This can be overridden using the :direction text option when drawing text or a text box.

Valid directions are:

  • ‘:ltr` – left-to-right (default)

  • ‘:rtl` – right-to-left

Side effects:

  • When printing left-to-right, the default text alignment is ‘:left`

  • When printing right-to-left, the default text alignment is ‘:right`

Examples:

pdf.text_direction = :rtl
pdf.text('hello world')                  # prints 'dlrow olleh'
pdf.text('hello world', direction: :ltr) # prints 'hello world'

Parameters:

  • direction (:ltr, :rtl) (defaults to: nil)

Returns:

  • (:ltr)
  • (:rtl)


139
140
141
142
143
144
145
# File 'lib/pdf/core/text.rb', line 139

def text_direction(direction = nil)
  if direction.nil?
    (defined?(@text_direction) && @text_direction) || :ltr
  else
    @text_direction = direction
  end
end

#text_rendering_mode(mode = nil) { ... } ⇒ Symbol, void

Call with no argument to retrieve the current text rendering mode.

Call with a symbol and block to temporarily change the current text rendering mode.

Valid modes are:

  • ‘:fill` - fill text (default)

  • ‘:stroke` - stroke text

  • ‘:fill_stroke` - fill, then stroke text

  • ‘:invisible` - invisible text

  • ‘:fill_clip` - fill text then add to path for clipping

  • ‘:stroke_clip` - stroke text then add to path for clipping

  • ‘:fill_stroke_clip` - fill then stroke text, then add to path for

    clipping
    
  • ‘:clip` - add text to path for clipping

Examples:

pdf.text_rendering_mode(:stroke) do
  pdf.text('Outlined Text')
end

Parameters:

  • mode (Symbol) (defaults to: nil)

Yields:

  • Temporariliy set text rendering mode

Returns:

  • (Symbol)

    if called withouth mode

  • (void)

    otherwise



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/pdf/core/text.rb', line 220

def text_rendering_mode(mode = nil, &block)
  if mode.nil?
    return (defined?(@text_rendering_mode) && @text_rendering_mode) || :fill
  end

  unless MODES.key?(mode)
    raise ArgumentError,
      "mode must be between one of #{MODES.keys.join(', ')} (#{mode})"
  end

  if text_rendering_mode == mode
    yield
  else
    wrap_and_restore_text_rendering_mode(mode, &block)
  end
end

#word_spacing(amount = nil) { ... } ⇒ Numeric, void

Increases or decreases the space between words. For horizontal text, a positive value will increase the space. For vertical text, a positive value will decrease the space.

Call with no arguments to retrieve current word spacing.

Parameters:

  • amount (Numeric) (defaults to: nil)

Yields:

  • Temporarily set word spacing

Returns:

  • (Numeric)

    if called without amount

  • (void)

    otherwise



276
277
278
279
280
281
282
283
284
# File 'lib/pdf/core/text.rb', line 276

def word_spacing(amount = nil, &block)
  return (defined?(@word_spacing) && @word_spacing) || 0 if amount.nil?

  if word_spacing == amount
    yield
  else
    wrap_and_restore_word_spacing(amount, &block)
  end
end