Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
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.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def verify_options(accepted, actual)
require_relative 'prawn/images/image'
require_relative 'prawn/images/jpg'
require_relative 'prawn/images/png'
require_relative 'prawn/embedded_files'
require_relative 'prawn/stamp'
require_relative 'prawn/soft_mask'
require_relative 'prawn/security'
Expand Down
1 change: 1 addition & 0 deletions lib/prawn/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Document
include Prawn::Text
include Prawn::Graphics
include Prawn::Images
include Prawn::EmbeddedFiles
include Prawn::Stamp
include Prawn::SoftMask
include Prawn::TransformationStack
Expand Down
45 changes: 45 additions & 0 deletions lib/prawn/embedded_files.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module Prawn
module EmbeddedFiles
# include PDF::Core::EmbeddedFiles
# Link to PR (https://github.com/prawnpdf/pdf-core/pull/47)

def file(src, options = {})
path = Pathname.new(src)

if path.directory?
raise ArgumentError, 'Data source can\'t be a directory'
elsif path.file?
data = path.read
options[:name] ||= src
options[:creation_date] ||= path.birthtime
options[:modification_date] ||= path.mtime
else
data = src
end

@file_registry ||= {}

file = EmbeddedFile.new(data, options)
file_obj = @file_registry[file.chksum]

if file_obj.nil?
file_obj = file.build_pdf_object(self)
@file_registry[file.chksum] = file_obj
end

filespec = Filespec.new(file_obj, options)
filespec_obj = filespec.build_pdf_object(self)

unless filespec.hidden?
# Wait for pdf-core PR

# attach_file(filespec.file_name, filespec_obj)
end
end
end
end

require_relative 'embedded_files/embedded_file'
require_relative 'embedded_files/filespec'
42 changes: 42 additions & 0 deletions lib/prawn/embedded_files/embedded_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'digest/md5'

module Prawn
module EmbeddedFiles
class EmbeddedFile
attr_reader :chksum

def initialize(data, options = {})
@creation_date = options[:creation_date]
unless @creation_date.instance_of?(Time)
@creation_date = Time.now.utc
end

@mod_date = options[:modification_date]
unless @mod_date.instance_of?(Time)
@mod_date = Time.now.utc
end

@chksum = Digest::MD5.hexdigest(data)
@data = data.dup
end

def build_pdf_object(document)
obj = document.ref!(
Type: :EmbeddedFile,
Params: {
CreationDate: @creation_date,
ModDate: @mod_date,
CheckSum: PDF::Core::LiteralString.new(@chksum),
Size: @data.length
}
)

obj << @data
obj.stream.compress!
obj
end
end
end
end
39 changes: 39 additions & 0 deletions lib/prawn/embedded_files/filespec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

module Prawn
module EmbeddedFiles
class Filespec
attr_reader :file_name

def initialize(file, options = {})
name = options[:name] || file.chksum

@file_name = PDF::Core::LiteralString.new(name)

if options[:description]
desc_str = options[:description].to_s
@description = PDF::Core::LiteralString.new(desc_str)
end

@hidden = options[:hidden] == true
@file = file
end

def hidden?
@hidden
end

def build_pdf_object(document)
obj = document.ref!(
Type: :Filespec,
F: @file_name,
EF: { F: @file },
UF: @file_name
)

obj[:Desc] = @description if @description
obj
end
end
end
end