pdf_oxide 0.3.68 → 0.3.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/pdf_oxide/ffi/bindings.rb +36 -0
- data/lib/pdf_oxide/pdf_document.rb +50 -4
- data/lib/pdf_oxide/version.rb +1 -1
- data/lib/pdf_oxide.rb +24 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69ee3975fd3514216f0145f91a2b53321b2837656900242f9292fdb4d31a3887
|
|
4
|
+
data.tar.gz: 2298ad2c2f64afd4eadedd408d1140e19436a3a5c5ee363295cc5053e789a61e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c845247d4fba11a9af23f7b17595de5f410d9750dfeec28020617f2a00633e0664969c3aab8d6505dcc1c01f009f0fbedbfe443b135975fcd88ac8506b02f740
|
|
7
|
+
data.tar.gz: 491b40c860d487d04af14a2a1aa5196d3d74114838239d2b7676a988dd7766f11c19a0932e0d2bb6c70e979cfa989aabc60ea16e15fc560835a94c2c37e68e1a
|
|
@@ -1465,6 +1465,9 @@ module PdfOxide
|
|
|
1465
1465
|
attach_function :pdf_oxide_word_get_bbox, %i[pointer pointer pointer pointer pointer pointer pointer pointer], :pointer, blocking: false
|
|
1466
1466
|
attach_function :pdf_oxide_word_get_font_name, %i[pointer pointer pointer pointer pointer pointer pointer pointer], :pointer, blocking: false
|
|
1467
1467
|
attach_function :pdf_oxide_word_get_font_size, %i[pointer pointer pointer pointer pointer pointer pointer pointer], :pointer, blocking: false
|
|
1468
|
+
# int64_t pdf_oxide_word_get_sequence(const void *words, int32_t index, int *error_code)
|
|
1469
|
+
# Content-stream emission order of the word's originating span; -1 on null/out-of-range.
|
|
1470
|
+
attach_function :pdf_oxide_word_get_sequence, %i[pointer int32 pointer], :int64, blocking: false
|
|
1468
1471
|
attach_function :pdf_oxide_word_get_text, %i[pointer pointer pointer pointer pointer pointer pointer pointer], :pointer, blocking: false
|
|
1469
1472
|
attach_function :pdf_oxide_word_is_bold, %i[pointer pointer pointer pointer pointer pointer pointer pointer], :pointer, blocking: false
|
|
1470
1473
|
attach_function :pdf_oxide_word_list_free, %i[pointer pointer pointer pointer pointer pointer pointer pointer], :pointer, blocking: false
|
|
@@ -1693,6 +1696,39 @@ module PdfOxide
|
|
|
1693
1696
|
%i[pointer size_t pointer], :int32
|
|
1694
1697
|
attach_function :document_editor_apply_all_redactions,
|
|
1695
1698
|
%i[pointer pointer], :int32
|
|
1699
|
+
|
|
1700
|
+
# ============================================================
|
|
1701
|
+
# PHASE 4 EXTEND: global tuning toggles + layer-filtered render.
|
|
1702
|
+
# Real ABI signatures from include/pdf_oxide_c/pdf_oxide.h.
|
|
1703
|
+
# ============================================================
|
|
1704
|
+
|
|
1705
|
+
# int64_t pdf_oxide_set_max_ops_per_stream(int64_t limit)
|
|
1706
|
+
# Process-global content-stream operator cap. `limit < 0` restores
|
|
1707
|
+
# the default (1,000,000); returns the previous cap (or -1 if the
|
|
1708
|
+
# default was active). No error channel.
|
|
1709
|
+
attach_function :pdf_oxide_set_max_ops_per_stream, [:int64], :int64
|
|
1710
|
+
|
|
1711
|
+
# int32_t pdf_oxide_set_preserve_unmapped_glyphs(int32_t preserve)
|
|
1712
|
+
# Toggle the global U+FFFD preservation flag. `1` = preserve,
|
|
1713
|
+
# `0` = filter. Returns the previous value (`0` or `1`). No error
|
|
1714
|
+
# channel.
|
|
1715
|
+
attach_function :pdf_oxide_set_preserve_unmapped_glyphs, [:int32], :int32
|
|
1716
|
+
|
|
1717
|
+
# FfiRenderedImage *pdf_render_page_with_options_ex(
|
|
1718
|
+
# PdfDocument *doc, int32_t page_index, int32_t dpi, int32_t format,
|
|
1719
|
+
# float bg_r, float bg_g, float bg_b, float bg_a,
|
|
1720
|
+
# int32_t transparent_background, int32_t render_annotations,
|
|
1721
|
+
# int32_t jpeg_quality,
|
|
1722
|
+
# const char *const *excluded_layers, uintptr_t excluded_layers_count,
|
|
1723
|
+
# int32_t *error_code)
|
|
1724
|
+
# Like pdf_render_page_with_options but with OCG layer filtering.
|
|
1725
|
+
attach_function :pdf_render_page_with_options_ex,
|
|
1726
|
+
%i[pointer int32 int32 int32
|
|
1727
|
+
float float float float
|
|
1728
|
+
int32 int32 int32
|
|
1729
|
+
pointer size_t
|
|
1730
|
+
pointer],
|
|
1731
|
+
:pointer
|
|
1696
1732
|
end
|
|
1697
1733
|
end
|
|
1698
1734
|
end
|
|
@@ -258,7 +258,50 @@ module PdfOxide
|
|
|
258
258
|
# path is the byte-buffer accessor introduced for v0.3.5x.
|
|
259
259
|
bytes = read_rendered_image_bytes(img_ptr)
|
|
260
260
|
Bindings.pdf_rendered_image_free(img_ptr) if Bindings.respond_to?(:pdf_rendered_image_free)
|
|
261
|
-
bytes.
|
|
261
|
+
bytes.b # binary-encoded copy (never mutates; read_* may return a frozen empty string)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# Render a single page with the full RenderOptions surface plus
|
|
265
|
+
# Optional-Content-Group (OCG) layer filtering.
|
|
266
|
+
#
|
|
267
|
+
# @param page_index [Integer]
|
|
268
|
+
# @param dpi [Integer] resolution (default 150).
|
|
269
|
+
# @param format [Integer] 0 = PNG, 1 = JPEG.
|
|
270
|
+
# @param background [Array(Float,Float,Float,Float)] RGBA, each 0.0..1.0.
|
|
271
|
+
# @param transparent [Boolean] drop the background fill entirely.
|
|
272
|
+
# @param render_annotations [Boolean] paint annotation appearances.
|
|
273
|
+
# @param jpeg_quality [Integer] 1..100 (only used when format == 1).
|
|
274
|
+
# @param excluded_layers [Array<String>] OCG `/Name`s to suppress.
|
|
275
|
+
# @return [String] encoded image bytes (BINARY).
|
|
276
|
+
def render_with_layers(page_index, dpi: 150, format: 0,
|
|
277
|
+
background: [1.0, 1.0, 1.0, 1.0], transparent: false,
|
|
278
|
+
render_annotations: true, jpeg_quality: 90,
|
|
279
|
+
excluded_layers: [])
|
|
280
|
+
validate_page_index(page_index)
|
|
281
|
+
bg_r, bg_g, bg_b, bg_a = background
|
|
282
|
+
names = Array(excluded_layers).map(&:to_s)
|
|
283
|
+
|
|
284
|
+
# Build a NULL-terminated-string array (char *const *).
|
|
285
|
+
names_ptr = ::FFI::Pointer::NULL
|
|
286
|
+
unless names.empty?
|
|
287
|
+
str_ptrs = names.map { |n| ::FFI::MemoryPointer.from_string(n) }
|
|
288
|
+
names_ptr = ::FFI::MemoryPointer.new(:pointer, str_ptrs.length)
|
|
289
|
+
names_ptr.write_array_of_pointer(str_ptrs)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
err = ::FFI::MemoryPointer.new(:int32)
|
|
293
|
+
img_ptr = Bindings.pdf_render_page_with_options_ex(
|
|
294
|
+
handle, page_index, dpi, format,
|
|
295
|
+
bg_r.to_f, bg_g.to_f, bg_b.to_f, bg_a.to_f,
|
|
296
|
+
transparent ? 1 : 0, render_annotations ? 1 : 0, jpeg_quality,
|
|
297
|
+
names_ptr, names.length, err
|
|
298
|
+
)
|
|
299
|
+
raise_for_code(err.read_int32, 'render_with_layers')
|
|
300
|
+
raise InternalError, 'render_with_layers returned null' if img_ptr.nil? || img_ptr.null?
|
|
301
|
+
|
|
302
|
+
bytes = read_rendered_image_bytes(img_ptr)
|
|
303
|
+
Bindings.pdf_rendered_image_free(img_ptr) if Bindings.respond_to?(:pdf_rendered_image_free)
|
|
304
|
+
bytes.b # binary-encoded copy (never mutates; read_* may return a frozen empty string)
|
|
262
305
|
end
|
|
263
306
|
|
|
264
307
|
# @return [PdfPage] a lightweight view of the page at `index`.
|
|
@@ -324,14 +367,17 @@ module PdfOxide
|
|
|
324
367
|
def open_native(source)
|
|
325
368
|
err = ::FFI::MemoryPointer.new(:int32)
|
|
326
369
|
handle, path =
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
370
|
+
# NB: detect in-memory bytes (%PDF…) BEFORE the path branch — binary PDF
|
|
371
|
+
# bytes contain null bytes, and File.exist? raises ArgumentError
|
|
372
|
+
# ("path name contains null byte") on those, so the bytes check must run first.
|
|
373
|
+
if source.is_a?(String) && source.start_with?('%PDF')
|
|
330
374
|
# in-memory PDF bytes
|
|
331
375
|
buf = source.dup.force_encoding(Encoding::BINARY)
|
|
332
376
|
mem = ::FFI::MemoryPointer.new(:uint8, buf.bytesize)
|
|
333
377
|
mem.write_bytes(buf, 0, buf.bytesize)
|
|
334
378
|
[Bindings.pdf_document_open_from_bytes(mem, buf.bytesize, err), '<in-memory>']
|
|
379
|
+
elsif source.is_a?(String) && File.exist?(source)
|
|
380
|
+
[Bindings.pdf_document_open(File.absolute_path(source), err), File.absolute_path(source)]
|
|
335
381
|
else
|
|
336
382
|
raise FileNotFoundError, "file not found: #{source}"
|
|
337
383
|
end
|
data/lib/pdf_oxide/version.rb
CHANGED
data/lib/pdf_oxide.rb
CHANGED
|
@@ -56,5 +56,29 @@ module PdfOxide
|
|
|
56
56
|
def version
|
|
57
57
|
VERSION
|
|
58
58
|
end
|
|
59
|
+
|
|
60
|
+
# Set the process-global content-stream operator cap.
|
|
61
|
+
#
|
|
62
|
+
# A negative `limit` restores the default (1,000,000); any
|
|
63
|
+
# non-negative value (including 0) becomes the explicit cap.
|
|
64
|
+
#
|
|
65
|
+
# @param limit [Integer]
|
|
66
|
+
# @return [Integer] the previous cap (or -1 if the default was active).
|
|
67
|
+
def set_max_ops_per_stream(limit)
|
|
68
|
+
Bindings.pdf_oxide_set_max_ops_per_stream(Integer(limit))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Toggle the process-global U+FFFD (unmapped-glyph) preservation flag
|
|
72
|
+
# used by the high-level text extraction accessors.
|
|
73
|
+
#
|
|
74
|
+
# @param preserve [Boolean, Integer] truthy / non-zero = preserve,
|
|
75
|
+
# falsey / 0 = filter (the v0.3.54 default).
|
|
76
|
+
# @return [Integer] the previous value (`0` or `1`).
|
|
77
|
+
def set_preserve_unmapped_glyphs(preserve)
|
|
78
|
+
# preserve may be Boolean or Integer; avoid numeric predicates that
|
|
79
|
+
# would raise on a Boolean (e.g. true.zero?). falsey / 0 = filter.
|
|
80
|
+
flag = [false, nil, 0].include?(preserve) ? 0 : 1
|
|
81
|
+
Bindings.pdf_oxide_set_preserve_unmapped_glyphs(flag)
|
|
82
|
+
end
|
|
59
83
|
end
|
|
60
84
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pdf_oxide
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.70
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- PDF Oxide Contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|