class Object

Public Class Methods

new(image_blob) click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn-gmagick.rb, line 9
def initialize image_blob
  super
  # apply patch for https://github.com/packetmonkey/prawn-gmagick/issues/19
  if bits != 8 && (GMagick::Image.format image_blob) == 'PNG'
    (io = StringIO.new image_blob).read 8
    chunk_size = io.read 4
    self.bits = ((io.read chunk_size.unpack1 'N').unpack 'NNC')[-1] if (io.read 4) == 'IHDR'
  end
end

Public Instance Methods

absolute_path(path, dir = nil) click to toggle source

NOTE: see github.com/jruby/jruby/issues/7750

Calls superclass method
# File lib/asciidoctor/pdf/ext/core/file.rb, line 5
def absolute_path path, dir = nil
  return super unless dir && !(absolute_path? path)
  super File.join dir, path
end
absolute_path?(path) click to toggle source

NOTE: JRuby < 9.4 doesn’t implement this method; JRuby 9.4 implements it incorrectly

# File lib/asciidoctor/pdf/ext/core/file.rb, line 11
def absolute_path? path
  (Pathname.new path).absolute? && !(%r/\A[[:alpha:]][[:alnum:]\-+]*:\/\/\S/.match? path)
end
add_fragment_to_line(fragment) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/line_wrap.rb, line 4
def add_fragment_to_line fragment
  case fragment
  when ''
    true
  when ?\n
    @newline_encountered = true
    false
  else
    if (joined_string = @arranger.preview_joined_string)
      joined_string_width = @document.width_of (tokenize joined_string)[0], kerning: @kerning
    else
      joined_string_width = 0
    end
    last_idx = (segments = tokenize fragment).length - 1
    segments.each_with_index do |segment, idx|
      if segment == (zero_width_space segment.encoding)
        segment_width = effective_segment_width = 0
      else
        segment_width = effective_segment_width = @document.width_of segment, kerning: @kerning
        effective_segment_width += joined_string_width if idx === last_idx
      end
      if @accumulated_width + effective_segment_width <= @width
        @accumulated_width += segment_width
        if segment[-1] == (shy = soft_hyphen segment.encoding)
          @accumulated_width -= (@document.width_of shy, kerning: @kerning)
        end
        @fragment_output += segment
      else
        @line_contains_more_than_one_word = false if @accumulated_width == 0 && @line_contains_more_than_one_word
        end_of_the_line_reached segment
        fragment_finished fragment
        return false
      end
    end
    fragment_finished fragment
    true
  end
end
analyze_glyphs_for_fallback_font_support(fragment_hash) click to toggle source

help Prawn correctly resolve which font to analyze, including the font style also instruct Prawn to ignore fragment for inline image since the text is just a placeholder

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb, line 37
def analyze_glyphs_for_fallback_font_support fragment_hash
  return [fragment_hash] if fragment_hash[:image_obj]
  fragment_font = fragment_hash[:font] || (original_font = @document.font.family)
  effective_font_styles = @document.font_styles
  fragment_font_opts = {}
  if (fragment_font_styles = fragment_hash[:styles])
    effective_font_styles.merge fragment_font_styles
    if effective_font_styles.include? :bold
      fragment_font_opts[:style] = (effective_font_styles.include? :italic) ? :bold_italic : :bold
    elsif effective_font_styles.include? :italic
      fragment_font_opts[:style] = :italic
    end
  elsif !effective_font_styles.empty?
    fragment_font_opts[:style] = @document.resolve_font_style effective_font_styles
  end
  fallback_fonts = @fallback_fonts.drop 0
  font_glyph_pairs = []
  @document.save_font do
    fragment_hash[:text].each_char do |char|
      font_glyph_pairs << [(find_font_for_this_glyph char, fragment_font, fragment_font_opts, (fallback_fonts.drop 0)), char]
    end
  end
  # NOTE: don't add a :font to fragment if it wasn't there originally
  font_glyph_pairs.each {|pair| pair[0] = nil if pair[0] == original_font } if original_font
  form_fragments_from_like_font_glyph_pairs font_glyph_pairs, fragment_hash
end
apply_font_size(size, styles) { || ... } click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb, line 40
def apply_font_size size, styles
  if (subscript? styles) || (superscript? styles)
    size ||= @document.font_size
    if String === size
      units = (size.end_with? 'em', '%') ? ((size.end_with? '%') ? '%' : 'em') : ''
      size = %(#{size.to_f * @sub_and_sup_relative_size}#{units})
    else
      size *= @sub_and_sup_relative_size
    end
    @document.font_size(size) { yield }
  elsif size
    @document.font_size(size) { yield }
  else
    yield
  end
end
ascender=(val) click to toggle source

Modify the built-in ascender write method to allow an override value to be specified using the format_state hash.

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb, line 29
def ascender= val
  @ascender = (format_state.key? :ascender) ? format_state[:ascender] : val
end
assert_valid_path!(path) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn-svg/loaders/file.rb, line 17
def assert_valid_path! path
  if jail_path && !(path.start_with? %(#{jail_path}#{File::SEPARATOR}))
    raise Prawn::SVG::UrlLoader::Error, %(file path points to location outside of jail #{jail_path})
  end
end
border_color=(color) click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn-table/cell.rb, line 6
def border_color= color
  color = [color, color] if Asciidoctor::PDF::ThemeLoader::CMYKColorValue === color
  super
end
conceal(force_width_to_zero = false) click to toggle source

Prevent fragment from being written by discarding the text, optionally forcing the width to 0

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb, line 7
def conceal force_width_to_zero = false
  if force_width_to_zero
    @width = 0
    @text = ''
  else
    @text = ' ' * space_count # preserve space_count so width is still computed correctly
  end
end
descender=(val) click to toggle source

Modify the built-in ascender write method to allow an override value to be specified using the format_state hash.

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb, line 35
def descender= val
  @descender = (format_state.key? :descender) ? format_state[:descender] : val
end
draw_borders(pt) click to toggle source

Draws borders around the cell. Borders are centered on the bounds of the cell outside of any padding, so the caller is responsible for setting appropriate padding to ensure the border does not overlap with cell content.

Adds support for transparent border color.

# File lib/asciidoctor/pdf/ext/prawn-table/cell.rb, line 18
def draw_borders pt
  x, y = pt

  @pdf.mask :line_width, :stroke_color do
    @borders.each do |border|
      idx = { top: 0, right: 1, bottom: 2, left: 3 }[border]
      border_color = @border_colors[idx]
      border_width = @border_widths[idx]
      border_line  = @border_lines[idx]

      next unless border_width > 0

      # Left and right borders are drawn one-half border beyond the center
      # of the corner, so that the corners end up square.
      case border
      when :top
        from, to = [[x, y], [x + width, y]]
      when :bottom
        from, to = [[x, y - height], [x + width, y - height]]
      when :left
        from, to = [[x, y + (border_top_width / 2.0)], [x, y - height - (border_bottom_width / 2.0)]]
      else # :right
        from, to = [[x + width, y + (border_top_width / 2.0)], [x + width, y - height - (border_bottom_width / 2.0)]]
      end

      case border_line
      when :dashed
        @pdf.dash border_width * 4
      when :dotted
        @pdf.dash border_width
      when :solid
        # normal line style
      else
        raise ArgumentError, 'border_line must be :solid, :dotted or :dashed'
      end

      @pdf.line_width = border_width
      if border_color == 'transparent'
        @pdf.stroke_color = '000000'
        @pdf.transparent 0 do
          @pdf.stroke_line from, to
        end
      else
        @pdf.stroke_color = border_color
        @pdf.stroke_line from, to
      end
      @pdf.undash
    end
  end
end
draw_fragment_overlay_styles(fragment) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb, line 21
def draw_fragment_overlay_styles fragment
  if (underline = (styles = fragment.styles).include? :underline) || (styles.include? :strikethrough)
    (doc = fragment.document).save_graphics_state do
      if (text_decoration_width = (fs = fragment.format_state)[:text_decoration_width] || doc.text_decoration_width)
        doc.line_width = text_decoration_width
      end
      if (text_decoration_color = fs[:text_decoration_color])
        doc.stroke_color = text_decoration_color
      end
      underline ? (doc.stroke_line fragment.underline_points) : (doc.stroke_line fragment.strikethrough_points)
    end
  end
end
empty?() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 4
def empty?
  blocks.empty?
end
finalize_line() click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb, line 20
def finalize_line
  @consumed.unshift text: Prawn::Text::ZWSP if @normalize_line_height
  super
end
find_font_for_this_glyph(char, current_font, current_font_opts = {}) click to toggle source

TODO: remove once Prawn 2.5 is released

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb, line 65
def find_font_for_this_glyph char, current_font, current_font_opts = {}, fallback_fonts_to_check = [], original_font = current_font
  (doc = @document).font current_font, current_font_opts
  if doc.font.glyph_present? char
    current_font
  elsif fallback_fonts_to_check.empty?
    if logger.info? && !doc.scratch?
      fonts_checked = [original_font].concat @fallback_fonts
      missing_chars = (doc.instance_variable_defined? :@missing_chars) ?
          (doc.instance_variable_get :@missing_chars) : (doc.instance_variable_set :@missing_chars, {})
      previous_fonts_checked = (missing_chars[char] ||= [])
      if previous_fonts_checked.empty? && !(previous_fonts_checked.include? fonts_checked)
        logger.warn %(Could not locate the character `#{char}' (#{char.unpack('U*').map {|it| "\\u#{(it.to_s 16).rjust 4, '0'}" }.join}) in the following fonts: #{fonts_checked.join ', '})
        previous_fonts_checked << fonts_checked
      end
    end
    original_font
  else
    find_font_for_this_glyph char, fallback_fonts_to_check.shift, current_font_opts, fallback_fonts_to_check, original_font
  end
end
find_image_handler(data) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn-svg/elements/image.rb, line 12
def find_image_handler data
  Prawn.image_handler.find data rescue nil
end
first_child() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 8
def first_child
  blocks[0]
end
first_child?() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 16
def first_child?
  self == parent.blocks[0]
end
format_array=(array) click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb, line 15
def format_array= array
  @normalize_line_height = !array.empty? && (array[0].delete :normalize_line_height)
  super
end
from_url(url) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn-svg/loaders/web.rb, line 8
def from_url url
  (url.to_s.start_with? 'http://', 'https://') ? (load_open_uri.open_uri url, 'rb', &:read) : nil
rescue
  raise Prawn::SVG::UrlLoader::Error, $!.message
end
image_dimensions(data) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn-svg/elements/image.rb, line 4
def image_dimensions data
  unless (handler = find_image_handler data)
    raise Prawn::SVG::Elements::Base::SkipElementError, 'Unsupported image type supplied to image tag'
  end
  image = handler.new data
  [image.width.to_f, image.height.to_f]
end
include_trailing_white_space!() click to toggle source

Don’t strip soft hyphens when repacking unretrieved fragments

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb, line 17
def include_trailing_white_space!
  @format_state.delete :normalized_soft_hyphen
  super
end
initial_row_on_initial_page() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn-table.rb, line 6
def initial_row_on_initial_page
  return 0 if fits_on_page? @pdf.bounds.height
  height_required = (row (0..number_of_header_rows)).height_with_span
  return -1 if fits_on_page? height_required, true
  @pdf.bounds.move_past_bottom
  0
end
last_child() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 12
def last_child
  blocks[-1]
end
last_child?() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 20
def last_child?
  self == parent.blocks[-1]
end
last_column() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/document/column_box.rb, line 6
def last_column
  @columns - 1
end
load_open_uri() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn-svg/loaders/web.rb, line 14
def load_open_uri
  if @open_uri_loader
    @open_uri_loader.call
  else
    require 'open-uri' unless defined? OpenURI
    OpenURI
  end
end
move_past_bottom() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/document/column_box.rb, line 10
def move_past_bottom
  (doc = @document).y = @y
  return if (@current_column = (@current_column + 1) % @columns) > 0
  parent_ = @parent
  reset_top parent_ if (reflow_at = @reflow_margins) && (reflow_at == true || reflow_at > doc.page_number)
  initial_margins = doc.page.margins
  parent_.move_past_bottom
  if doc.page.margins != initial_margins
    doc.bounds = bounds = self.class.new doc, parent_, [(margin_box = doc.margin_box).absolute_left, @y],
      columns: @columns, reflow_margins: @reflow_margins, spacer: @spacer, width: margin_box.width, height: @height
    # ensure indentation is preserved across page break
    bounds.add_left_padding @total_left_padding if @total_left_padding > 0
    bounds.add_right_padding @total_right_padding if @total_right_padding > 0
  end
  nil
end
next_sibling() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 24
def next_sibling
  (siblings = parent.blocks)[(siblings.index self) + 1]
end
next_string() click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb, line 25
def next_string
  (string = super) == @dummy_text ? (string.extend Prawn::Text::NoopLstripBang) : string
end
parse() click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn-svg/elements/use.rb, line 5
def parse
  result = super
  if @referenced_element_source.name == 'symbol' && !(@referenced_element_source.attributes.key? 'viewBox')
    @referenced_element_class = Prawn::SVG::Elements::Container
  end
  result
end
preview_joined_string() click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb, line 29
def preview_joined_string
  if (next_unconsumed = @unconsumed[0] || {})[:wj] && !(@consumed[-1] || [])[:wj]
    idx = 0
    str = '' if (str = next_unconsumed[:text]) == @dummy_text
    while (next_unconsumed = @unconsumed[idx += 1] || {})[:wj] && (next_string = next_unconsumed[:text])
      str += next_string unless next_string == @dummy_text
    end
    str unless str == ''
  end
end
previous_sibling() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 28
def previous_sibling
  (self_idx = (siblings = parent.blocks).index self) > 0 ? siblings[self_idx - 1] : nil
end
process_vertical_alignment(text) click to toggle source

Override method in super class to provide support for a tuple consisting of alignment and offset

Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb, line 96
def process_vertical_alignment text
  return super if Symbol === (valign = @vertical_align)

  return if defined? @vertical_alignment_processed
  @vertical_alignment_processed = true

  valign, offset = valign

  case valign
  when :center
    wrap text
    @at[1] -= (@height - (rendered_height = height) + @descender) * 0.5 + offset
    @height = rendered_height
  when :bottom
    wrap text
    @at[1] -= (@height - (rendered_height = height)) + offset
    @height = rendered_height
  else # :top
    @at[1] -= offset
  end

  nil
end
remove() click to toggle source
# File lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb, line 32
def remove
  parent.blocks.delete self
end
reset_top(parent_ = @parent) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/document/column_box.rb, line 27
def reset_top parent_ = @parent
  @current_column = 0
  @height = parent_.height unless stretchy?
  @y = parent_.absolute_top
end
run() click to toggle source
# File lib/asciidoctor/pdf/optimizer.rb, line 18
def run
  RGhost::Config.config_platform unless File.exist? RGhost::Config::GS[:path].to_s
  (cmd = @params.slice 1, @params.length).unshift RGhost::Config::GS[:path].to_s
  #puts cmd if @debug
  _out, err, status = Open3.capture3(*cmd)
  unless (lines = err.lines.each_with_object([]) {|l, accum| (l.include? '-dNEWPDF=') ? accum.pop : (accum << l) }).empty?
    $stderr.write(*lines)
  end
  status.success?
end
shellescape(str) click to toggle source
# File lib/asciidoctor/pdf/optimizer.rb, line 31
def shellescape str
  str
end
single_file() click to toggle source

Rearranges the column box into a single column, where the original columns are in a single file. Used for the purpose of computing the extent of content in a scratch document.

# File lib/asciidoctor/pdf/ext/prawn/document/column_box.rb, line 35
def single_file
  if @reflow_margins && @parent.absolute_top > @y && @columns > @current_column + 1
    # defer reflow margins until all columns on current page have been exhausted
    @reflow_margins = @document.page_number + (@columns - @current_column)
  end
  @width = bare_column_width
  @columns = 1
  @current_column = 0
  nil
end
strip_zero_width_spaces(string) click to toggle source

Use .tr instead of .gsub to remove zero-width spaces

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb, line 23
def strip_zero_width_spaces string
  string.encoding == Encoding::UTF_8 ? (string.tr Prawn::Text::ZWSP, '') : string
end
to_pdf_object() click to toggle source

Convert the object to a serialized PDF object.

# File lib/asciidoctor/pdf/ext/core/object.rb, line 5
def to_pdf_object
  ::PDF::Core.pdf_object self
end
warning(*_args;) click to toggle source
# File lib/asciidoctor/pdf/ext/prawn/extensions.rb, line 7
def warning *_args; end
width() click to toggle source
Calls superclass method
# File lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb, line 39
def width
  if (val = format_state[:width])
    val = (val.end_with? 'em') ? val.to_f * @document.font_size : (@document.str_to_pt val) if String === val
  else
    val = super
  end
  if (border_offset = format_state[:border_offset])
    val += border_offset * 2
  end
  val
end
word_spacing_for_this_line() click to toggle source

Override method to force text justification when :force_justify option is set (typically for rendering a single line)

# File lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb, line 87
def word_spacing_for_this_line
  if @align == :justify && (@force_justify || (@line_wrap.space_count > 0 && !@line_wrap.paragraph_finished?))
    (available_width - @line_wrap.width) / @line_wrap.space_count
  else
    0
  end
end