Module: RustPdf
- Defined in:
- lib/rustpdf.rb,
lib/rustpdf/native.rb,
lib/rustpdf/document.rb,
lib/rustpdf/editable_doc.rb
Overview
Idiomatic Ruby binding for the rust-pdf core over its C ABI (libpdf_ffi), using the built-in Fiddle stdlib. Covers the whole product surface: vector graphics, fonts/text, paragraphs, images, PDF/A (1b-3a), tagged/accessible output, attachments, AcroForm fields, manipulation, text extraction, encryption and digital signatures, plus feature licensing.
Defined Under Namespace
Modules: Align, Cipher, FacturxProfile, Native, Pdfa, Relationship Classes: Bookmark, Document, EditableDoc, Error
Class Method Summary collapse
-
.activate_license(token) ⇒ Object
Activate a license token (unlocks PDF/A, signing, encryption, accessibility).
-
.add_dss(pdf, certs: [], crls: []) ⇒ Object
Append a Document Security Store (/DSS, PAdES-B-LT).
- .check(status) ⇒ Object
-
.extract_images_to_dir(pdf, dir) ⇒ Object
Extract every raster image into
dir(JPEG verbatim as .jpg, others as .png; files named pageN_name.ext). -
.extract_text(pdf) ⇒ Object
Extract a document's text (Unicode via ToUnicode).
-
.last_error ⇒ Object
---- internal helpers (used by Document/EditableDoc) ----------------------.
-
.out_int ⇒ Object
Run a producer { |out_int| status } and return the written int.
-
.page_count(pdf) ⇒ Object
Number of pages in
pdf(free — no license required). -
.render_page_to_png(pdf, page = 0, dpi = 150.0) ⇒ Object
Render page
page(0-based) ofpdfto a PNG image atdpidots-per-inch. -
.sign(pdf, key_der, cert_der, reason: nil, location: nil, name: nil, pades: false) ⇒ Object
Sign a PDF (PKCS#7 detached, incremental update).
-
.take_bytes ⇒ Object
Run an out-buffer producer { |out_ptr, out_len| status } and return the produced bytes, always freeing the native buffer.
-
.timestamp(pdf, tsa_key_der, tsa_cert_der, date: nil) ⇒ Object
Append a document timestamp (/DocTimeStamp, PAdES-B-LTA).
-
.verify_signatures(pdf) ⇒ Object
Validate every signature in
pdf. -
.version ⇒ Object
Native library version string.
Class Method Details
.activate_license(token) ⇒ Object
Activate a license token (unlocks PDF/A, signing, encryption, accessibility). Tokens may also be supplied via the RUSTPDF_LICENSE / RUSTPDF_LICENSE_FILE environment variables (auto-activated).
104 105 106 |
# File 'lib/rustpdf.rb', line 104 def activate_license(token) check(Native.call("pdf_activate_license", token)) end |
.add_dss(pdf, certs: [], crls: []) ⇒ Object
Append a Document Security Store (/DSS, PAdES-B-LT).
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/rustpdf.rb', line 163 def add_dss(pdf, certs: [], crls: []) cptrs = certs.map { |c| Fiddle::Pointer[c] } rptrs = crls.map { |c| Fiddle::Pointer[c] } cptr_buf = cptrs.map(&:to_i).pack("J*") clen_buf = certs.map(&:bytesize).pack("J*") rptr_buf = rptrs.map(&:to_i).pack("J*") rlen_buf = crls.map(&:bytesize).pack("J*") result = take_bytes do |pp, pn| Native.call("pdf_add_dss", pdf, pdf.bytesize, cptr_buf, clen_buf, certs.size, rptr_buf, rlen_buf, crls.size, pp, pn) end # keep the per-item pointers alive until the call has returned cptrs.clear rptrs.clear result end |
.check(status) ⇒ Object
187 188 189 |
# File 'lib/rustpdf.rb', line 187 def check(status) raise Error.new(last_error, status) unless status.zero? end |
.extract_images_to_dir(pdf, dir) ⇒ Object
Extract every raster image into dir (JPEG verbatim as .jpg, others as
.png; files named pageN_name.ext). Returns the number written.
116 117 118 119 120 |
# File 'lib/rustpdf.rb', line 116 def extract_images_to_dir(pdf, dir) count = Fiddle::Pointer.malloc(Native::SIZEOF_SZ, Fiddle::RUBY_FREE) check(Native.call("pdf_extract_images_to_dir", pdf, pdf.bytesize, dir, count)) count[0, Native::SIZEOF_SZ].unpack1("J") end |
.extract_text(pdf) ⇒ Object
Extract a document's text (Unicode via ToUnicode).
109 110 111 112 |
# File 'lib/rustpdf.rb', line 109 def extract_text(pdf) take_bytes { |pp, pn| Native.call("pdf_extract_text", pdf, pdf.bytesize, pp, pn) } .force_encoding(Encoding::UTF_8) end |
.last_error ⇒ Object
---- internal helpers (used by Document/EditableDoc) ----------------------
182 183 184 185 |
# File 'lib/rustpdf.rb', line 182 def last_error p = Native.call("pdf_last_error_message") p.null? ? "unknown error" : p.to_s end |
.out_int ⇒ Object
Run a producer { |out_int| status } and return the written int.
207 208 209 210 211 |
# File 'lib/rustpdf.rb', line 207 def out_int buf = Fiddle::Pointer.malloc(Native::SIZEOF_INT, Fiddle::RUBY_FREE) check(yield(buf)) buf[0, Native::SIZEOF_INT].unpack1("i!") end |
.page_count(pdf) ⇒ Object
Number of pages in pdf (free — no license required).
130 131 132 133 134 |
# File 'lib/rustpdf.rb', line 130 def page_count(pdf) count = Fiddle::Pointer.malloc(Native::SIZEOF_SZ, Fiddle::RUBY_FREE) check(Native.call("pdf_page_count", pdf, pdf.bytesize, count)) count[0, Native::SIZEOF_SZ].unpack1("J") end |
.render_page_to_png(pdf, page = 0, dpi = 150.0) ⇒ Object
Render page page (0-based) of pdf to a PNG image at dpi
dots-per-inch. Page rendering is a licensed Pro feature: raises unless a
license granting it is active.
125 126 127 |
# File 'lib/rustpdf.rb', line 125 def render_page_to_png(pdf, page = 0, dpi = 150.0) take_bytes { |pp, pn| Native.call("pdf_render_page_to_png", pdf, pdf.bytesize, page, dpi.to_f, pp, pn) } end |
.sign(pdf, key_der, cert_der, reason: nil, location: nil, name: nil, pades: false) ⇒ Object
Sign a PDF (PKCS#7 detached, incremental update). Requires a license.
147 148 149 150 151 152 |
# File 'lib/rustpdf.rb', line 147 def sign(pdf, key_der, cert_der, reason: nil, location: nil, name: nil, pades: false) take_bytes do |pp, pn| Native.call("pdf_sign", pdf, pdf.bytesize, key_der, key_der.bytesize, cert_der, cert_der.bytesize, reason, location, name, pades ? 1 : 0, pp, pn) end end |
.take_bytes ⇒ Object
Run an out-buffer producer { |out_ptr, out_len| status } and return the produced bytes, always freeing the native buffer.
193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/rustpdf.rb', line 193 def take_bytes pp = Fiddle::Pointer.malloc(Native::SIZEOF_SZ, Fiddle::RUBY_FREE) pn = Fiddle::Pointer.malloc(Native::SIZEOF_SZ, Fiddle::RUBY_FREE) check(yield(pp, pn)) len = pn[0, Native::SIZEOF_SZ].unpack1("J") return "".b if len.zero? dptr = pp.ptr bytes = dptr[0, len] Native.call("pdf_buffer_free", dptr, len) bytes end |
.timestamp(pdf, tsa_key_der, tsa_cert_der, date: nil) ⇒ Object
Append a document timestamp (/DocTimeStamp, PAdES-B-LTA).
155 156 157 158 159 160 |
# File 'lib/rustpdf.rb', line 155 def (pdf, tsa_key_der, tsa_cert_der, date: nil) take_bytes do |pp, pn| Native.call("pdf_timestamp", pdf, pdf.bytesize, tsa_key_der, tsa_key_der.bytesize, tsa_cert_der, tsa_cert_der.bytesize, date, pp, pn) end end |
.verify_signatures(pdf) ⇒ Object
Validate every signature in pdf. Returns one Hash per signature with keys
"field_name", "sub_filter", "signer", "covers_whole_document",
"digest_valid", "signature_valid", "is_valid" and "byte_range". An empty
array means the document is unsigned.
140 141 142 143 144 |
# File 'lib/rustpdf.rb', line 140 def verify_signatures(pdf) js = take_bytes { |pp, pn| Native.call("pdf_verify_signatures_json", pdf, pdf.bytesize, pp, pn) } .force_encoding(Encoding::UTF_8) js.empty? ? [] : JSON.parse(js) end |