rustpdf 0.4.5-universal-darwin → 0.4.8-universal-darwin
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/README.md +13 -18
- data/lib/rustpdf/editable_doc.rb +157 -8
- data/lib/rustpdf/native.rb +17 -0
- data/lib/rustpdf.rb +49 -0
- data/vendor/universal-darwin/libpdf_ffi.dylib +0 -0
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '082524dbee70acfb9ee95fc16b1f5892159a7f63da57ab77061956dc365c19d3'
|
|
4
|
+
data.tar.gz: 7cd26d42a12ecacb24f1526da4b5a642556c887769f1d6243d43def4e7b914ea
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aaf0e097415445a9340e833906ae8165596cd417aceba6aff60bd7ae8508c1a825ef9015dc1811b00938c94130eb0fdef33f4b18b314a687b72de69bf17c2233
|
|
7
|
+
data.tar.gz: 43b7c488e1479a1b792da82337430eed855d032dbd5e3bb6a9db0102c5fc25874ffaaad4e80c9a7b54d82ebdca7a996378decea7f85adc338360bea448df699e
|
data/README.md
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* `lib/rustpdf.rb` — module functions (`version`, `activate_license`,
|
|
15
|
-
`extract_text`, `sign`, `timestamp`, `add_dss`), enums, error, helpers;
|
|
16
|
-
* `lib/rustpdf/native.rb` — the Fiddle signature table + loader;
|
|
17
|
-
* `lib/rustpdf/document.rb`, `editable_doc.rb` — the `Document` / `EditableDoc`
|
|
18
|
-
classes.
|
|
1
|
+
# RustPdf for Ruby
|
|
2
|
+
|
|
3
|
+
Generate, edit, sign and process PDFs from Ruby: vector graphics, embedded fonts and Unicode text, wrapping paragraphs, images, **PDF/A** (1b-4f), **tagged/accessible** output, attachments, **AcroForm** fields, page manipulation (merge/split/stamp), watermarks, true **redaction**, **AES-256** encryption, **digital signatures (PAdES)** with HSM/deferred signing, timestamps/LTV, text extraction and search, and page **rendering to PNG**. Pure Ruby gem (stdlib Fiddle), no native extension to compile.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- **Full API reference:** https://rustpdf.dev/docs/ruby
|
|
8
|
+
- **Interactive positioning guide** (coordinates, anchors, rotation): https://rustpdf.dev/positioning
|
|
9
|
+
- All product guides (PDF/A, signatures, encryption, redaction, rendering): https://rustpdf.dev/docs/
|
|
10
|
+
|
|
11
|
+
The public API is `RustPdf::Document` (create PDFs), `RustPdf::EditableDoc`
|
|
12
|
+
(load and edit existing PDFs) and module functions (`version`,
|
|
13
|
+
`activate_license`, `extract_text`, `sign`, `timestamp`, `add_dss`).
|
|
19
14
|
|
|
20
15
|
## Loading the native library
|
|
21
16
|
|
data/lib/rustpdf/editable_doc.rb
CHANGED
|
@@ -163,18 +163,149 @@ module RustPdf
|
|
|
163
163
|
found != 0
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
#
|
|
167
|
-
#
|
|
166
|
+
# Register a TrueType/OpenType font (from a file path) for text stamping;
|
|
167
|
+
# returns a font id usable with the +font_id+ keyword of #place_text /
|
|
168
|
+
# #masked_text / #place_paragraph. The font is embedded as a subset —
|
|
169
|
+
# stamped text renders with the real font's glyphs and metrics.
|
|
170
|
+
def add_font_file(path)
|
|
171
|
+
RustPdf.out_int { |buf| Native.call("pdf_editable_add_font_file", ptr, path, buf) }
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Register a stamping font from raw TrueType/OpenType bytes. See
|
|
175
|
+
# #add_font_file.
|
|
176
|
+
def add_font(data)
|
|
177
|
+
RustPdf.out_int { |buf| Native.call("pdf_editable_add_font", ptr, data, data.bytesize, buf) }
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Draw a line of positioned +text+ anchored at (+x+, +y+) on page
|
|
181
|
+
# +page_index+ (0-based), using standard Helvetica (or an embedded font —
|
|
182
|
+
# pass +font_id+ from #add_font_file / #add_font) at +size+ points in RGB
|
|
168
183
|
# +color+ (each 0..1, default black). +rotation_deg+ rotates the text
|
|
169
184
|
# counter-clockwise about its anchor (match the page rotation to follow a
|
|
170
|
-
# rotated page).
|
|
171
|
-
#
|
|
172
|
-
#
|
|
173
|
-
|
|
185
|
+
# rotated page). +align+ (RustPdf::Align, default LEFT) shifts the start
|
|
186
|
+
# point along the baseline direction by the text width for RIGHT/CENTER
|
|
187
|
+
# alignment. +anchor+ (RustPdf::VerticalAnchor) says what +y+ means:
|
|
188
|
+
# BASELINE (default, historical behavior), TOP (text hangs from +y+ —
|
|
189
|
+
# baseline lands ascent x size below it, legacy fixed-position layout), BOTTOM
|
|
190
|
+
# (descender line rests on +y+), or LINE_TOP / LINE_BOTTOM (legacy layout engines line
|
|
191
|
+
# box). Coordinates are in the page's VISIBLE space (origin lower-left,
|
|
192
|
+
# y up) unless #stamp_space= chose MEDIA. Returns whether the page (and
|
|
193
|
+
# font) existed.
|
|
194
|
+
def place_text(page_index, x, y, text, size = 12.0, color = [0.0, 0.0, 0.0], rotation_deg = 0.0,
|
|
195
|
+
align: Align::LEFT, font_id: -1, anchor: VerticalAnchor::BASELINE)
|
|
174
196
|
r, g, b = color
|
|
175
197
|
found = RustPdf.out_int do |buf|
|
|
176
|
-
Native.call("
|
|
177
|
-
size.to_f, r.to_f, g.to_f, b.to_f, rotation_deg.to_f, buf)
|
|
198
|
+
Native.call("pdf_editable_place_text_anchored", ptr, page_index, x.to_f, y.to_f, text,
|
|
199
|
+
size.to_f, r.to_f, g.to_f, b.to_f, rotation_deg.to_f, align, anchor, font_id, buf)
|
|
200
|
+
end
|
|
201
|
+
found != 0
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Choose the coordinate space of the positioned stamping primitives
|
|
205
|
+
# (#fill_rect, #place_text, #masked_text, #place_paragraph, #draw_image)
|
|
206
|
+
# for subsequent calls. StampSpace::VISIBLE (default) keeps the historical
|
|
207
|
+
# behavior — coordinates in the page's displayed space, compensating
|
|
208
|
+
# /Rotate. StampSpace::MEDIA interprets coordinates and +rotation_deg+ in
|
|
209
|
+
# the raw PDF user space (legacy layout semantics), never composing with the
|
|
210
|
+
# page's /Rotate — use it to reproduce legacy-engine placement on rotated/scanned
|
|
211
|
+
# pages. Watermarks and redaction are unaffected.
|
|
212
|
+
def stamp_space=(space)
|
|
213
|
+
RustPdf.check(Native.call("pdf_editable_set_stamp_space", ptr, space))
|
|
214
|
+
@stamp_space = space
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# The current stamping coordinate space (see #stamp_space=).
|
|
218
|
+
def stamp_space
|
|
219
|
+
@stamp_space || StampSpace::VISIBLE
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Chainable form of #stamp_space=.
|
|
223
|
+
def set_stamp_space(space)
|
|
224
|
+
self.stamp_space = space
|
|
225
|
+
self
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Stamp a paragraph with automatic word wrapping on page +page_index+:
|
|
229
|
+
# +text+ is broken into lines that fit +width+ points (greedy, by word;
|
|
230
|
+
# "\n" forces a break) and drawn downward from (+x+, +y+). +anchor+
|
|
231
|
+
# (RustPdf::VerticalAnchor) says what +y+ means for the block: TOP
|
|
232
|
+
# (default) — top of the box, first baseline ascent x size below +y+
|
|
233
|
+
# (legacy fixed-position layout); BASELINE — the first line's baseline; BOTTOM /
|
|
234
|
+
# LINE_BOTTOM — bottom-pinned: the block's bottom rests on +y+ and grows
|
|
235
|
+
# upward by its real content height. +align+ lays lines out inside
|
|
236
|
+
# +[x, x+width]+ (JUSTIFY stretches the word gaps of every line but the
|
|
237
|
+
# last of each paragraph). +max_height+ (points, nil = unlimited) truncates
|
|
238
|
+
# overflowing lines (a ceiling for the bottom-pinned anchors — the last
|
|
239
|
+
# lines stay pinned). +line_height+ scales the default 1.2 x size leading.
|
|
240
|
+
# Pass +font_id+ from #add_font_file / #add_font to wrap and draw with an
|
|
241
|
+
# embedded font (its real metrics drive the break points); -1 uses the
|
|
242
|
+
# built-in Helvetica. +rotation_deg+ rotates the laid-out block
|
|
243
|
+
# counter-clockwise about the anchor. Returns whether the page (and font)
|
|
244
|
+
# existed and the box was valid.
|
|
245
|
+
def place_paragraph(page_index, x, y, width, text, size: 12.0, color: [0.0, 0.0, 0.0],
|
|
246
|
+
align: Align::LEFT, font_id: -1, max_height: nil, line_height: 1.0,
|
|
247
|
+
anchor: VerticalAnchor::TOP, rotation_deg: 0.0)
|
|
248
|
+
found, = paragraph_anchored(page_index, x, y, width, text, size, color, align,
|
|
249
|
+
font_id, max_height, line_height, anchor, rotation_deg)
|
|
250
|
+
found
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Like #place_paragraph but returns a Hash with the number of +:lines+
|
|
254
|
+
# drawn and the consumed block +:height+ in points (top of the first drawn
|
|
255
|
+
# line's box to the bottom of the last one's; 0 when nothing fit) — stack
|
|
256
|
+
# blocks without re-measuring.
|
|
257
|
+
def place_paragraph_measured(page_index, x, y, width, text, size: 12.0, color: [0.0, 0.0, 0.0],
|
|
258
|
+
align: Align::LEFT, font_id: -1, max_height: nil, line_height: 1.0,
|
|
259
|
+
anchor: VerticalAnchor::TOP, rotation_deg: 0.0)
|
|
260
|
+
_, lines, height = paragraph_anchored(page_index, x, y, width, text, size, color, align,
|
|
261
|
+
font_id, max_height, line_height, anchor, rotation_deg)
|
|
262
|
+
{ lines: lines, height: height }
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# Mask a placeholder: fill an opaque background box +[x, y, x+width,
|
|
266
|
+
# y+height]+ in +bg_color+ (each 0..1, default white), then write +text+
|
|
267
|
+
# over it using standard Helvetica (or an embedded font — pass +font_id+
|
|
268
|
+
# from #add_font_file / #add_font) at +size+ points in +text_color+ (each
|
|
269
|
+
# 0..1, default black), horizontally aligned per +align+ (RustPdf::Align,
|
|
270
|
+
# default LEFT). +valign+ (RustPdf::VerticalAlign) controls the vertical
|
|
271
|
+
# alignment of the line inside the box: MIDDLE (default, historical
|
|
272
|
+
# cap-height centering), TOP (line hangs from the top edge — legacy PDF libraries
|
|
273
|
+
# top line-alignment semantics) or BOTTOM (descender line rests on the
|
|
274
|
+
# bottom edge). +padding+ is the horizontal edge inset (points) for
|
|
275
|
+
# LEFT/RIGHT alignment: text starts at +x + padding+ (or ends at
|
|
276
|
+
# +x + width - padding+); nil keeps the historical
|
|
277
|
+
# min(0.15 x size, width / 4), 0 starts flush with the box edge like
|
|
278
|
+
# rectangle-based DrawString APIs. Coordinates are in the page's VISIBLE space
|
|
279
|
+
# (origin lower-left, y up). Returns whether the page (and font) existed.
|
|
280
|
+
def masked_text(page_index, x, y, width, height, text, size = 12.0,
|
|
281
|
+
text_color = [0.0, 0.0, 0.0], bg_color = [1.0, 1.0, 1.0],
|
|
282
|
+
align: Align::LEFT, font_id: -1, valign: VerticalAlign::MIDDLE, padding: nil)
|
|
283
|
+
tr, tg, tb = text_color
|
|
284
|
+
br, bg, bb = bg_color
|
|
285
|
+
found = RustPdf.out_int do |buf|
|
|
286
|
+
Native.call("pdf_editable_masked_text_pad", ptr, page_index, x.to_f, y.to_f,
|
|
287
|
+
width.to_f, height.to_f, text, size.to_f,
|
|
288
|
+
tr.to_f, tg.to_f, tb.to_f, br.to_f, bg.to_f, bb.to_f, align, valign,
|
|
289
|
+
(padding || -1.0).to_f, font_id, buf)
|
|
290
|
+
end
|
|
291
|
+
found != 0
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Stamp an +image+ (PNG or JPEG bytes; the core dispatches on the signature)
|
|
295
|
+
# onto page +page_index+ (0-based), with its lower-left corner at (+x+, +y+),
|
|
296
|
+
# scaled to +width+ x +height+ points and rotated +rotation_deg+ degrees
|
|
297
|
+
# counter-clockwise. +anchor+ (RustPdf::ImageAnchor) controls how a rotated
|
|
298
|
+
# image is anchored: CORNER (default) rotates the image about its own
|
|
299
|
+
# lower-left corner at (x, y); BOUNDING_BOX lands the rotated image's
|
|
300
|
+
# bounding box with its lower-left at (x, y) (bounding-box layout semantics —
|
|
301
|
+
# e.g. a 90-degree image occupies [x, x+height] x [y, y+width]).
|
|
302
|
+
# Coordinates are in the page's VISIBLE space (origin lower-left, y up),
|
|
303
|
+
# regardless of the page's /Rotate. Returns whether the page existed.
|
|
304
|
+
def draw_image(page_index, image, x, y, width, height, rotation_deg = 0.0,
|
|
305
|
+
anchor: ImageAnchor::CORNER)
|
|
306
|
+
found = RustPdf.out_int do |buf|
|
|
307
|
+
Native.call("pdf_editable_draw_image_anchored", ptr, page_index, image, image.bytesize,
|
|
308
|
+
x.to_f, y.to_f, width.to_f, height.to_f, rotation_deg.to_f, anchor, buf)
|
|
178
309
|
end
|
|
179
310
|
found != 0
|
|
180
311
|
end
|
|
@@ -252,6 +383,24 @@ module RustPdf
|
|
|
252
383
|
|
|
253
384
|
private
|
|
254
385
|
|
|
386
|
+
# Shared core of #place_paragraph / #place_paragraph_measured. Returns
|
|
387
|
+
# [found (bool), lines (Integer), height (Float)].
|
|
388
|
+
def paragraph_anchored(page_index, x, y, width, text, size, color, align,
|
|
389
|
+
font_id, max_height, line_height, anchor, rotation_deg)
|
|
390
|
+
r, g, b = color
|
|
391
|
+
height_buf = Fiddle::Pointer.malloc(Fiddle::SIZEOF_DOUBLE, Fiddle::RUBY_FREE)
|
|
392
|
+
lines_buf = Fiddle::Pointer.malloc(Native::SIZEOF_INT, Fiddle::RUBY_FREE)
|
|
393
|
+
found_buf = Fiddle::Pointer.malloc(Native::SIZEOF_INT, Fiddle::RUBY_FREE)
|
|
394
|
+
RustPdf.check(Native.call("pdf_editable_place_paragraph_anchored", ptr, page_index,
|
|
395
|
+
x.to_f, y.to_f, width.to_f, text, size.to_f,
|
|
396
|
+
r.to_f, g.to_f, b.to_f, align, anchor, font_id,
|
|
397
|
+
(max_height || 0.0).to_f, line_height.to_f, rotation_deg.to_f,
|
|
398
|
+
height_buf, lines_buf, found_buf))
|
|
399
|
+
[found_buf[0, Native::SIZEOF_INT].unpack1("i!") != 0,
|
|
400
|
+
lines_buf[0, Native::SIZEOF_INT].unpack1("i!"),
|
|
401
|
+
height_buf[0, Fiddle::SIZEOF_DOUBLE].unpack1("d")]
|
|
402
|
+
end
|
|
403
|
+
|
|
255
404
|
def ptr
|
|
256
405
|
raise Error, "operation on a closed EditableDoc" if @ptr.nil? || @ptr.null?
|
|
257
406
|
|
data/lib/rustpdf/native.rb
CHANGED
|
@@ -78,6 +78,7 @@ module RustPdf
|
|
|
78
78
|
"pdf_editable_save" => [[VP, VP], I],
|
|
79
79
|
|
|
80
80
|
"pdf_extract_text" => [[VP, SZ, VP, VP], I],
|
|
81
|
+
"pdf_extract_page_text" => [[VP, SZ, SZ, VP, VP], I],
|
|
81
82
|
"pdf_extract_images_to_dir" => [[VP, SZ, VP, VP], I],
|
|
82
83
|
"pdf_render_page_to_png" => [[VP, SZ, SZ, D, VP, VP], I],
|
|
83
84
|
"pdf_page_count" => [[VP, SZ, VP], I],
|
|
@@ -129,6 +130,22 @@ module RustPdf
|
|
|
129
130
|
"pdf_inspect_json" => [[VP, SZ, VP, VP], I],
|
|
130
131
|
"pdf_editable_fill_rect" => [[VP, I, D, D, D, D, D, D, D, D, VP], I],
|
|
131
132
|
"pdf_editable_place_text" => [[VP, I, D, D, VP, D, D, D, D, D, VP], I],
|
|
133
|
+
"pdf_editable_place_text_aligned" => [[VP, I, D, D, VP, D, D, D, D, D, I, VP], I],
|
|
134
|
+
"pdf_editable_masked_text" => [[VP, I, D, D, D, D, VP, D, D, D, D, D, D, D, I, VP], I],
|
|
135
|
+
# Issue #50: stamp a PNG/JPEG image onto an existing page. The image bytes
|
|
136
|
+
# cross as the (uint8_t* data, uintptr_t len) pair, like pdf_editable_load.
|
|
137
|
+
"pdf_editable_draw_image" => [[VP, I, VP, SZ, D, D, D, D, D, VP], I],
|
|
138
|
+
|
|
139
|
+
# Stamping fonts + anchored stamping primitives. font_id -1 = built-in
|
|
140
|
+
# Helvetica; anchors/valign/space/image-anchor cross as small ints.
|
|
141
|
+
"pdf_editable_add_font_file" => [[VP, VP, VP], I],
|
|
142
|
+
"pdf_editable_add_font" => [[VP, VP, SZ, VP], I],
|
|
143
|
+
"pdf_editable_place_text_anchored" => [[VP, I, D, D, VP, D, D, D, D, D, I, I, I, VP], I],
|
|
144
|
+
"pdf_editable_masked_text_pad" => [[VP, I, D, D, D, D, VP, D, D, D, D, D, D, D, I, I, D, I, VP], I],
|
|
145
|
+
"pdf_editable_place_paragraph_anchored" =>
|
|
146
|
+
[[VP, I, D, D, D, VP, D, D, D, D, I, I, I, D, D, D, VP, VP, VP], I],
|
|
147
|
+
"pdf_editable_set_stamp_space" => [[VP, I], I],
|
|
148
|
+
"pdf_editable_draw_image_anchored" => [[VP, I, VP, SZ, D, D, D, D, D, I, VP], I],
|
|
132
149
|
}.freeze
|
|
133
150
|
|
|
134
151
|
def lib
|
data/lib/rustpdf.rb
CHANGED
|
@@ -40,6 +40,48 @@ module RustPdf
|
|
|
40
40
|
JUSTIFY = 3
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
# What +y+ means for stamped text (EditableDoc#place_text /
|
|
44
|
+
# #place_paragraph). BASELINE is the historical place_text behavior; TOP
|
|
45
|
+
# hangs the text from +y+ (baseline lands ascent x size below it, legacy layout engines
|
|
46
|
+
# fixed-position layout semantics); BOTTOM rests the descender line on +y+.
|
|
47
|
+
# LINE_TOP / LINE_BOTTOM anchor via the layout line box (its height is also
|
|
48
|
+
# the leading basis, so a single line and a wrapped block agree vertically).
|
|
49
|
+
module VerticalAnchor
|
|
50
|
+
BASELINE = 0
|
|
51
|
+
TOP = 1
|
|
52
|
+
BOTTOM = 2
|
|
53
|
+
LINE_TOP = 3
|
|
54
|
+
LINE_BOTTOM = 4
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Vertical alignment of the line inside a masked_text box. MIDDLE is the
|
|
58
|
+
# historical cap-height centering; TOP hangs the line from the top edge
|
|
59
|
+
# (top line-alignment in rectangle-based text APIs semantics); BOTTOM rests the descender
|
|
60
|
+
# line on the bottom edge.
|
|
61
|
+
module VerticalAlign
|
|
62
|
+
TOP = 0
|
|
63
|
+
MIDDLE = 1
|
|
64
|
+
BOTTOM = 2
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Coordinate space of the positioned stamping primitives (EditableDoc).
|
|
68
|
+
# VISIBLE (default) compensates the page /Rotate so coordinates match what
|
|
69
|
+
# a viewer displays; MEDIA is the raw PDF user space (legacy layout engines
|
|
70
|
+
# fixed-position layout/rotation semantics — no /Rotate composition).
|
|
71
|
+
module StampSpace
|
|
72
|
+
VISIBLE = 0
|
|
73
|
+
MEDIA = 1
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# How a rotated EditableDoc#draw_image is anchored. CORNER (default) rotates
|
|
77
|
+
# the image about its own lower-left corner at (x, y); BOUNDING_BOX lands
|
|
78
|
+
# the rotated image's bounding box with its lower-left at (x, y) (legacy layout engines
|
|
79
|
+
# layout semantics).
|
|
80
|
+
module ImageAnchor
|
|
81
|
+
CORNER = 0
|
|
82
|
+
BOUNDING_BOX = 1
|
|
83
|
+
end
|
|
84
|
+
|
|
43
85
|
# Embedded-file relationship (PDF/A-3).
|
|
44
86
|
module Relationship
|
|
45
87
|
SOURCE = 0
|
|
@@ -228,6 +270,13 @@ module RustPdf
|
|
|
228
270
|
.force_encoding(Encoding::UTF_8)
|
|
229
271
|
end
|
|
230
272
|
|
|
273
|
+
# Extract the text of a single 0-based +page_index+ (Unicode via ToUnicode),
|
|
274
|
+
# without building an intermediate one-page document.
|
|
275
|
+
def extract_page_text(pdf, page_index)
|
|
276
|
+
take_bytes { |pp, pn| Native.call("pdf_extract_page_text", pdf, pdf.bytesize, page_index, pp, pn) }
|
|
277
|
+
.force_encoding(Encoding::UTF_8)
|
|
278
|
+
end
|
|
279
|
+
|
|
231
280
|
# Extract every raster image into +dir+ (JPEG verbatim as .jpg, others as
|
|
232
281
|
# .png; files named page{N}_{name}.{ext}). Returns the number written.
|
|
233
282
|
def extract_images_to_dir(pdf, dir)
|
|
Binary file
|
metadata
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rustpdf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.8
|
|
5
5
|
platform: universal-darwin
|
|
6
6
|
authors:
|
|
7
7
|
- rust-pdf
|
|
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
|
-
description:
|
|
14
|
-
|
|
13
|
+
description: 'Generate, edit, sign and process PDFs in Ruby: PDF/A, AES-256 encryption,
|
|
14
|
+
digital signatures (PAdES), forms, stamping, redaction, text extraction and page
|
|
15
|
+
rendering. Docs: https://rustpdf.dev/docs/ruby'
|
|
15
16
|
email:
|
|
16
17
|
executables: []
|
|
17
18
|
extensions: []
|
|
@@ -45,6 +46,5 @@ requirements: []
|
|
|
45
46
|
rubygems_version: 3.5.22
|
|
46
47
|
signing_key:
|
|
47
48
|
specification_version: 4
|
|
48
|
-
summary:
|
|
49
|
-
PDFs).
|
|
49
|
+
summary: 'Generate, edit, sign and process PDFs in Ruby. Docs: https://rustpdf.dev/docs/ruby'
|
|
50
50
|
test_files: []
|