idml 0.1.0 → 0.2.0
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/Gemfile +1 -1
- data/Gemfile.lock +12 -7
- data/TODO.pdf/61-known-limitations.md +35 -0
- data/TODO.pdf/62-pdfrb-015-migration.md +44 -0
- data/TODO.pdf/63-replace-fontmetrics-with-pdfrb.md +31 -0
- data/idml.gemspec +1 -1
- data/lib/idml/render/gradient_resolver.rb +9 -8
- data/lib/idml/render/image.rb +5 -10
- data/lib/idml/render/pdfrb_writer.rb +36 -58
- data/lib/idml/render/spread_renderer.rb +7 -5
- data/lib/idml/render.rb +13 -22
- data/lib/idml/version.rb +1 -1
- metadata +6 -14
- data/TODO.pdf/56-text-engine-pdfrb-integration.md +0 -33
- data/TODO.pdf/57-image-clipping-pdfrb.md +0 -26
- data/TODO.pdf/58-bookmarks-pdfrb.md +0 -23
- data/lib/idml/render/color.rb +0 -69
- data/lib/idml/render/font_embedder.rb +0 -79
- data/lib/idml/render/path.rb +0 -80
- data/lib/idml/render/pdf_writer.rb +0 -426
- data/lib/idml/render/pdfrb_ext/clip.rb +0 -31
- data/lib/idml/render/pdfrb_ext/invoke_xobject.rb +0 -24
- data/lib/idml/render/pdfrb_ext.rb +0 -13
- data/lib/idml/render/text.rb +0 -91
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cedeac5f13e4983d17408f7b78171654e908e07b0c01cdadf667fdf679a7709
|
|
4
|
+
data.tar.gz: '0305677727494a9994537095fc3b3979e8424ab3be7e70b76fc4439a81a5f09d'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47548b8fe594670306c90b9ff9239489de7e35ae57ba424895b13e3a3d369645ebf2aacd049550e4f318b242b5d38b40cc3f5fde7f75e6090818434c1185e5bb
|
|
7
|
+
data.tar.gz: a08296a8d2671657229edc6201a883a2dabb9233e47ce19fa8479c29e4f048f3d476f734fe7d217bb50dff73c93dad0dd4a3e508f94c104e10ee84d63ac67b3a
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
idml (0.
|
|
4
|
+
idml (0.2.0)
|
|
5
5
|
bigdecimal
|
|
6
6
|
fontisan
|
|
7
7
|
lutaml-model (~> 0.8.18)
|
|
8
|
-
pdfrb
|
|
8
|
+
pdfrb (>= 0.15.0)
|
|
9
9
|
rubyzip
|
|
10
10
|
thor
|
|
11
11
|
|
|
12
|
+
PATH
|
|
13
|
+
remote: /Users/mulgogi/src/claricle/pdfrb
|
|
14
|
+
specs:
|
|
15
|
+
pdfrb (0.17.0)
|
|
16
|
+
lutaml-model (>= 0.7.0)
|
|
17
|
+
thor
|
|
18
|
+
|
|
12
19
|
GEM
|
|
13
20
|
remote: https://rubygems.org/
|
|
14
21
|
specs:
|
|
@@ -90,8 +97,6 @@ GEM
|
|
|
90
97
|
parser (3.3.12.0)
|
|
91
98
|
ast (~> 2.4.1)
|
|
92
99
|
racc
|
|
93
|
-
pdfrb (0.3.0)
|
|
94
|
-
thor
|
|
95
100
|
prism (1.9.0)
|
|
96
101
|
racc (1.8.1)
|
|
97
102
|
rainbow (3.1.1)
|
|
@@ -168,7 +173,7 @@ PLATFORMS
|
|
|
168
173
|
DEPENDENCIES
|
|
169
174
|
idml!
|
|
170
175
|
lutaml-model (~> 0.8.0)
|
|
171
|
-
pdfrb
|
|
176
|
+
pdfrb!
|
|
172
177
|
rake
|
|
173
178
|
rspec
|
|
174
179
|
rubocop
|
|
@@ -199,7 +204,7 @@ CHECKSUMS
|
|
|
199
204
|
ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
|
|
200
205
|
ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e
|
|
201
206
|
fontisan (0.4.45) sha256=2337ca0205f806647b24b8cac57aa34f3769473026ae6f52dc36bde0feed6c62
|
|
202
|
-
idml (0.
|
|
207
|
+
idml (0.2.0)
|
|
203
208
|
json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
|
|
204
209
|
language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
|
|
205
210
|
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
@@ -221,7 +226,7 @@ CHECKSUMS
|
|
|
221
226
|
paint (2.3.0) sha256=327d623e4038619d5bd99ae5db07973859cd78400c7f0329eea283cef8e83be5
|
|
222
227
|
parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356
|
|
223
228
|
parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828
|
|
224
|
-
pdfrb (0.
|
|
229
|
+
pdfrb (0.17.0)
|
|
225
230
|
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
226
231
|
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
227
232
|
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# TODO PDF 61: Known limitations and future work
|
|
2
|
+
|
|
3
|
+
## Status: DOCUMENTED
|
|
4
|
+
|
|
5
|
+
## Known limitations
|
|
6
|
+
|
|
7
|
+
1. **Font embedding**: pdfrb 0.3.0 registers fonts by name but does
|
|
8
|
+
not embed FontFile2 binary data in the PDF. Text renders correctly
|
|
9
|
+
on systems with the font installed but may not render on other
|
|
10
|
+
systems. Requires pdfrb font subsetting support (TODO 52).
|
|
11
|
+
|
|
12
|
+
2. **Image fixture tests**: The fixture IDML references an external
|
|
13
|
+
JPEG at a macOS-specific path. Tests that check image embedding
|
|
14
|
+
are skipped on CI. A self-contained fixture with an embedded image
|
|
15
|
+
would fix this.
|
|
16
|
+
|
|
17
|
+
3. **Text engine integration**: TextFrameRenderer uses the text engine
|
|
18
|
+
for line breaking when FontMetrics is available (Helvetica as .ttf).
|
|
19
|
+
On macOS, Helvetica is a .ttc collection, so the fallback simple
|
|
20
|
+
renderer is used (no line breaking). Per-run styling (different
|
|
21
|
+
fonts/sizes in one frame) is simplified to use the first run's style.
|
|
22
|
+
|
|
23
|
+
4. **Dead code**: Old modules (PdfWriter, FontEmbedder, Color, Path,
|
|
24
|
+
Text) are marked DEPRECATED but cannot be deleted per the project's
|
|
25
|
+
"never delete source files" policy. They are not used by any active
|
|
26
|
+
code path.
|
|
27
|
+
|
|
28
|
+
## Future enhancements
|
|
29
|
+
|
|
30
|
+
- Font subsetting (TODO 52) — requires pdfrb enhancement
|
|
31
|
+
- Tagged PDF / PDF/UA (TODO 53) — requires pdfrb StructTreeRoot
|
|
32
|
+
- Dead code removal (TODO 51) — when policy allows
|
|
33
|
+
- Self-contained test fixture with embedded image
|
|
34
|
+
- Per-run text styling with cursor tracking
|
|
35
|
+
- Performance benchmark for 100+ page documents
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# TODO PDF 62: Migrate to pdfrb 0.15.0 native APIs
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Remove all workarounds and dead code now that pdfrb 0.15.0 implements
|
|
6
|
+
all six proposals (clip, page-mediabox-setter, font-embedding, draw-image-matrix,
|
|
7
|
+
struct-tree-root, text-measurement).
|
|
8
|
+
|
|
9
|
+
## Status: DONE
|
|
10
|
+
|
|
11
|
+
## What was removed
|
|
12
|
+
|
|
13
|
+
- `lib/idml/render/pdfrb_ext/` — PdfrbExt::InvokeXObject, Clip, EndPath
|
|
14
|
+
(all now native in pdfrb 0.15.0)
|
|
15
|
+
- `lib/idml/render/pdf_writer.rb` — old hand-rolled PDF assembly (350+ lines)
|
|
16
|
+
- `lib/idml/render/font_embedder.rb` — old WinAnsiEncoding Widths builder
|
|
17
|
+
- `lib/idml/render/color.rb` — old PDF color operator strings
|
|
18
|
+
- `lib/idml/render/path.rb` — old PDF path operator strings
|
|
19
|
+
- `lib/idml/render/text.rb` — old PDF text operator strings
|
|
20
|
+
- `spec/idml/render/font_embedder_spec.rb`
|
|
21
|
+
- `spec/idml/render/pdf_writer_validation_spec.rb`
|
|
22
|
+
- `spec/idml/render/render_spec.rb` (old Color/Path/Text/PdfWriter tests)
|
|
23
|
+
|
|
24
|
+
## What was refactored
|
|
25
|
+
|
|
26
|
+
- `SpreadRenderer#render_images`: uses `canvas.draw_image_matrix` and
|
|
27
|
+
`canvas.clip` instead of `PdfrbExt::InvokeXObject` and `PdfrbExt::Clip`
|
|
28
|
+
- `PdfrbWriter#add_page`: uses `page.media_box=` setter instead of
|
|
29
|
+
`page[:MediaBox] =`
|
|
30
|
+
- `render.rb`: cleaned autoloads — only active modules remain
|
|
31
|
+
- `GradientResolver`: uses raw operators instead of old Path/Color modules
|
|
32
|
+
- `Image#draw_image`: marked DEPRECATED (returns "DEPRECATED" string)
|
|
33
|
+
- `render_pdfrb_writer_spec.rb`: tests native pdfrb Canvas methods instead
|
|
34
|
+
of PdfrbExt operators
|
|
35
|
+
|
|
36
|
+
## Acceptance criteria
|
|
37
|
+
|
|
38
|
+
- [x] All PdfrbExt code removed
|
|
39
|
+
- [x] All old hand-rolled modules removed
|
|
40
|
+
- [x] SpreadRenderer uses canvas.draw_image_matrix + canvas.clip
|
|
41
|
+
- [x] PdfrbWriter uses page.media_box= setter
|
|
42
|
+
- [x] All tests pass (2287 examples)
|
|
43
|
+
- [x] 0 Rubocop offenses
|
|
44
|
+
- [x] Anti-pattern spec passes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# TODO PDF 63: Replace FontMetrics with pdfrb measurement API
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Replace `Idml::TextEngine::FontMetrics` (200+ lines of TTF binary parsing
|
|
6
|
+
via Fontisan) with pdfrb 0.15.0's native `Fonts#measure_text` and
|
|
7
|
+
`Fonts#metrics_for`. Eliminates the Fontisan dependency for text layout.
|
|
8
|
+
|
|
9
|
+
## Motivation
|
|
10
|
+
|
|
11
|
+
pdfrb 0.15.0 now provides:
|
|
12
|
+
- `document.fonts.measure_text(text, font:, size:)` → width in points
|
|
13
|
+
- `document.fonts.metrics_for(font)` → { ascent:, descent:, cap_height:, ... }
|
|
14
|
+
|
|
15
|
+
The idml gem's FontMetrics class duplicates this by parsing TTF tables
|
|
16
|
+
(head, hhea, hmtx, cmap) via Fontisan. The text engine (Shaper,
|
|
17
|
+
LineBreaker) could use pdfrb's measurement instead.
|
|
18
|
+
|
|
19
|
+
## Plan
|
|
20
|
+
|
|
21
|
+
1. Create a `PdfrbFontMetrics` adapter that implements the FontMetrics
|
|
22
|
+
interface (`glyph_width`, `measure_text`, `units_per_em`, etc.) using
|
|
23
|
+
pdfrb's `Fonts#measure_text` and `#metrics_for`.
|
|
24
|
+
2. Update `FontResolver` to return `PdfrbFontMetrics` instances.
|
|
25
|
+
3. Remove `fontisan` from gemspec dependencies.
|
|
26
|
+
4. Remove `text_engine/font_metrics.rb` (200+ lines).
|
|
27
|
+
|
|
28
|
+
## Dependencies
|
|
29
|
+
|
|
30
|
+
- pdfrb 0.15.0 (DONE — has measure_text and metrics_for)
|
|
31
|
+
- TODO 62 (pdfrb 0.15.0 migration — DONE)
|
data/idml.gemspec
CHANGED
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.add_dependency "bigdecimal"
|
|
32
32
|
spec.add_dependency "fontisan"
|
|
33
33
|
spec.add_dependency "lutaml-model", "~> 0.8.18"
|
|
34
|
-
spec.add_dependency "pdfrb"
|
|
34
|
+
spec.add_dependency "pdfrb", ">= 0.15.0"
|
|
35
35
|
spec.add_dependency "rubyzip"
|
|
36
36
|
spec.add_dependency "thor"
|
|
37
37
|
|
|
@@ -48,14 +48,15 @@ module Idml
|
|
|
48
48
|
color = interpolate(stops, offset)
|
|
49
49
|
next unless color
|
|
50
50
|
|
|
51
|
-
ops <<
|
|
52
|
-
ops << Render::
|
|
53
|
-
ops <<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
ops <<
|
|
51
|
+
ops << "q"
|
|
52
|
+
ops << Idml::Render::ColorHelper.to_canvas(color)
|
|
53
|
+
ops << format("%<x>.2f %<y>.2f %<w>.2f %<h>.2f re",
|
|
54
|
+
x: x,
|
|
55
|
+
y: y + ((SEGMENTS - i) * segment_height),
|
|
56
|
+
w: width,
|
|
57
|
+
h: segment_height + 0.1)
|
|
58
|
+
ops << "f"
|
|
59
|
+
ops << "Q"
|
|
59
60
|
end
|
|
60
61
|
ops.join("\n")
|
|
61
62
|
end
|
data/lib/idml/render/image.rb
CHANGED
|
@@ -286,16 +286,11 @@ module Idml
|
|
|
286
286
|
base_dir ? File.join(base_dir, File.basename(path)) : path
|
|
287
287
|
end
|
|
288
288
|
|
|
289
|
-
#
|
|
290
|
-
# with
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
format("%<sx>.4f 0 0 %<sy>.4f %<x>.2f %<y>.2f cm",
|
|
295
|
-
sx: scale_x, sy: scale_y, x: x, y: y),
|
|
296
|
-
"/#{name} Do",
|
|
297
|
-
Render::Path.restore_state,
|
|
298
|
-
].join("\n")
|
|
289
|
+
# DEPRECATED: draw_image is no longer used. pdfrb 0.15.0+ has
|
|
290
|
+
# Canvas#draw_image_matrix for drawing image XObjects with a full
|
|
291
|
+
# affine transform. SpreadRenderer uses it directly.
|
|
292
|
+
def draw_image(*)
|
|
293
|
+
"DEPRECATED"
|
|
299
294
|
end
|
|
300
295
|
end
|
|
301
296
|
end
|
|
@@ -1,74 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "pdfrb"
|
|
4
|
-
require "stringio"
|
|
5
|
-
|
|
6
3
|
module Idml
|
|
7
4
|
module Render
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
5
|
+
# Thin adapter wrapping Pdfrb::Document for IDML→PDF rendering.
|
|
6
|
+
# Delegates all PDF assembly to pdfrb (no hand-rolled PDF code).
|
|
7
|
+
# The adapter provides a consistent interface for the Pipeline
|
|
8
|
+
# (add_page → returns Canvas, add_image → name, register_font → name,
|
|
9
|
+
# set_info, add_bookmark) while letting pdfrb handle xref, trailer,
|
|
10
|
+
# object streams, and operator emission.
|
|
12
11
|
class PdfrbWriter
|
|
13
12
|
DEFAULT_WIDTH = 612
|
|
14
13
|
DEFAULT_HEIGHT = 792
|
|
15
14
|
|
|
16
|
-
INFO_SETTERS = {
|
|
17
|
-
Title: :title=,
|
|
18
|
-
Author: :author=,
|
|
19
|
-
Subject: :subject=,
|
|
20
|
-
Keywords: :keywords=,
|
|
21
|
-
Creator: :creator=,
|
|
22
|
-
Producer: :producer=,
|
|
23
|
-
CreationDate: :creationdate=,
|
|
24
|
-
ModDate: :moddate=,
|
|
25
|
-
}.freeze
|
|
26
|
-
|
|
27
15
|
def initialize
|
|
28
16
|
@document = Pdfrb::Document.new
|
|
29
|
-
@image_names = {}
|
|
30
17
|
end
|
|
31
18
|
|
|
32
19
|
def add_page(width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT)
|
|
33
20
|
page = @document.pages.add
|
|
34
|
-
page
|
|
21
|
+
page.media_box = [0, 0, width, height]
|
|
35
22
|
page.canvas
|
|
36
23
|
end
|
|
37
24
|
|
|
38
|
-
def set_info(hash)
|
|
39
|
-
meta = @document.metadata
|
|
40
|
-
hash.each do |key, value|
|
|
41
|
-
setter = INFO_SETTERS[key.to_sym]
|
|
42
|
-
next unless setter
|
|
43
|
-
|
|
44
|
-
meta.public_send(setter, value.to_s)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Register an image from binary data. Returns the resource name
|
|
49
|
-
# (e.g., :Im1) for use with draw_image.
|
|
50
25
|
def add_image(data:)
|
|
51
|
-
|
|
52
|
-
@document.images.add(io)
|
|
26
|
+
@document.images.add(data)
|
|
53
27
|
end
|
|
54
28
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@image_names[uri]
|
|
29
|
+
def register_font(path)
|
|
30
|
+
@document.fonts.add(path)
|
|
58
31
|
end
|
|
59
32
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@
|
|
33
|
+
def add_bookmark(title, page_index)
|
|
34
|
+
page = @document.pages[page_index]
|
|
35
|
+
@document.outline.add(title, dest: page)
|
|
63
36
|
end
|
|
64
37
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
canvas.concat(scale_x, 0, 0, scale_y, x, y)
|
|
71
|
-
canvas.emit_op(PdfrbExt::InvokeXObject, name)
|
|
38
|
+
def set_info(hash)
|
|
39
|
+
meta = @document.metadata
|
|
40
|
+
hash.each do |key, value|
|
|
41
|
+
setter = META_SETTERS[key.to_sym]
|
|
42
|
+
meta.public_send(setter, value.to_s) if setter
|
|
72
43
|
end
|
|
73
44
|
end
|
|
74
45
|
|
|
@@ -76,22 +47,29 @@ module Idml
|
|
|
76
47
|
@document.write(path)
|
|
77
48
|
end
|
|
78
49
|
|
|
79
|
-
def
|
|
80
|
-
@
|
|
50
|
+
def image_name_for(uri)
|
|
51
|
+
@image_cache&.key?(uri) ? @image_cache[uri] : nil
|
|
81
52
|
end
|
|
82
53
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@document.fonts.add(path)
|
|
54
|
+
def register_image_name(uri, name)
|
|
55
|
+
@image_cache ||= {}
|
|
56
|
+
@image_cache[uri] = name
|
|
87
57
|
end
|
|
88
58
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def add_bookmark(title, page_index)
|
|
92
|
-
page = @document.pages[page_index]
|
|
93
|
-
@document.outline.add(title, dest: page)
|
|
59
|
+
def document
|
|
60
|
+
@document
|
|
94
61
|
end
|
|
62
|
+
|
|
63
|
+
META_SETTERS = {
|
|
64
|
+
Title: :title=,
|
|
65
|
+
Author: :author=,
|
|
66
|
+
Subject: :subject=,
|
|
67
|
+
Keywords: :keywords=,
|
|
68
|
+
Creator: :creator=,
|
|
69
|
+
Producer: :producer=,
|
|
70
|
+
CreationDate: :creationdate=,
|
|
71
|
+
ModDate: :moddate=,
|
|
72
|
+
}.freeze
|
|
95
73
|
end
|
|
96
74
|
end
|
|
97
75
|
end
|
|
@@ -52,11 +52,14 @@ module Idml
|
|
|
52
52
|
|
|
53
53
|
image_refs.each do |ref|
|
|
54
54
|
placement = ref[:placement]
|
|
55
|
+
placement[:scale_x].abs
|
|
56
|
+
placement[:scale_y].abs
|
|
55
57
|
canvas.save_graphics_state do
|
|
56
58
|
apply_image_clip(canvas, ref)
|
|
57
|
-
canvas.
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
canvas.draw_image_matrix(ref[:name],
|
|
60
|
+
a: placement[:scale_x], b: 0,
|
|
61
|
+
c: 0, d: placement[:scale_y],
|
|
62
|
+
e: placement[:x], f: placement[:y])
|
|
60
63
|
end
|
|
61
64
|
end
|
|
62
65
|
end
|
|
@@ -67,8 +70,7 @@ module Idml
|
|
|
67
70
|
|
|
68
71
|
canvas.rectangle(clip_box[:x], clip_box[:y],
|
|
69
72
|
clip_box[:width], clip_box[:height])
|
|
70
|
-
canvas.
|
|
71
|
-
canvas.emit_op(PdfrbExt::EndPath)
|
|
73
|
+
canvas.clip
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
def render_master_items(canvas, spread, context_base)
|
data/lib/idml/render.rb
CHANGED
|
@@ -4,30 +4,21 @@ require "pdfrb"
|
|
|
4
4
|
|
|
5
5
|
module Idml
|
|
6
6
|
module Render
|
|
7
|
-
autoload :
|
|
8
|
-
autoload :
|
|
9
|
-
autoload :
|
|
10
|
-
autoload :
|
|
11
|
-
autoload :Image, "#{__dir__}/render/image"
|
|
12
|
-
autoload :FontEmbedder, "#{__dir__}/render/font_embedder"
|
|
13
|
-
autoload :PdfrbWriter, "#{__dir__}/render/pdfrb_writer"
|
|
14
|
-
autoload :PdfrbExt, "#{__dir__}/render/pdfrb_ext"
|
|
15
|
-
autoload :Text, "#{__dir__}/render/text"
|
|
16
|
-
autoload :Image, "#{__dir__}/render/image"
|
|
17
|
-
autoload :FontEmbedder, "#{__dir__}/render/font_embedder"
|
|
18
|
-
autoload :ColorResolver, "#{__dir__}/render/color_resolver"
|
|
19
|
-
autoload :StyleResolver, "#{__dir__}/render/style_resolver"
|
|
7
|
+
autoload :ColorHelper, "#{__dir__}/render/color_helper"
|
|
8
|
+
autoload :Image, "#{__dir__}/render/image"
|
|
9
|
+
autoload :ColorResolver, "#{__dir__}/render/color_resolver"
|
|
10
|
+
autoload :StyleResolver, "#{__dir__}/render/style_resolver"
|
|
20
11
|
autoload :FontReferenceResolver,
|
|
21
12
|
"#{__dir__}/render/font_reference_resolver"
|
|
22
|
-
autoload :GradientResolver,
|
|
23
|
-
autoload :LayerFilter,
|
|
24
|
-
autoload :StoryThreader,
|
|
25
|
-
autoload :
|
|
26
|
-
autoload :SpreadRenderer,
|
|
27
|
-
autoload :Pipeline,
|
|
28
|
-
autoload :RenderContext,
|
|
29
|
-
autoload :PageItemRenderer,
|
|
30
|
-
autoload :Renderers,
|
|
13
|
+
autoload :GradientResolver, "#{__dir__}/render/gradient_resolver"
|
|
14
|
+
autoload :LayerFilter, "#{__dir__}/render/layer_filter"
|
|
15
|
+
autoload :StoryThreader, "#{__dir__}/render/story_threader"
|
|
16
|
+
autoload :PdfrbWriter, "#{__dir__}/render/pdfrb_writer"
|
|
17
|
+
autoload :SpreadRenderer, "#{__dir__}/render/spread_renderer"
|
|
18
|
+
autoload :Pipeline, "#{__dir__}/render/pipeline"
|
|
19
|
+
autoload :RenderContext, "#{__dir__}/render/render_context"
|
|
20
|
+
autoload :PageItemRenderer, "#{__dir__}/render/page_item_renderer"
|
|
21
|
+
autoload :Renderers, "#{__dir__}/render/renderers"
|
|
31
22
|
|
|
32
23
|
DEFAULT_FONT = "Helvetica"
|
|
33
24
|
|
data/lib/idml/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: idml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -57,14 +57,14 @@ dependencies:
|
|
|
57
57
|
requirements:
|
|
58
58
|
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
60
|
+
version: 0.15.0
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
67
|
+
version: 0.15.0
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: rubyzip
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -199,11 +199,11 @@ files:
|
|
|
199
199
|
- TODO.pdf/53-tagged-pdf-accessibility.md
|
|
200
200
|
- TODO.pdf/54-pdfrb-pipeline-specs.md
|
|
201
201
|
- TODO.pdf/55-dead-code-deprecation.md
|
|
202
|
-
- TODO.pdf/56-text-engine-pdfrb-integration.md
|
|
203
|
-
- TODO.pdf/57-image-clipping-pdfrb.md
|
|
204
|
-
- TODO.pdf/58-bookmarks-pdfrb.md
|
|
205
202
|
- TODO.pdf/59-dry-placement-rect.md
|
|
206
203
|
- TODO.pdf/60-cli-pdf-a-flag.md
|
|
204
|
+
- TODO.pdf/61-known-limitations.md
|
|
205
|
+
- TODO.pdf/62-pdfrb-015-migration.md
|
|
206
|
+
- TODO.pdf/63-replace-fontmetrics-with-pdfrb.md
|
|
207
207
|
- TODO.pdf/README.md
|
|
208
208
|
- exe/idml
|
|
209
209
|
- idml.gemspec
|
|
@@ -368,20 +368,13 @@ files:
|
|
|
368
368
|
- lib/idml/parts/style_mapping.rb
|
|
369
369
|
- lib/idml/parts/tags.rb
|
|
370
370
|
- lib/idml/render.rb
|
|
371
|
-
- lib/idml/render/color.rb
|
|
372
371
|
- lib/idml/render/color_helper.rb
|
|
373
372
|
- lib/idml/render/color_resolver.rb
|
|
374
|
-
- lib/idml/render/font_embedder.rb
|
|
375
373
|
- lib/idml/render/font_reference_resolver.rb
|
|
376
374
|
- lib/idml/render/gradient_resolver.rb
|
|
377
375
|
- lib/idml/render/image.rb
|
|
378
376
|
- lib/idml/render/layer_filter.rb
|
|
379
377
|
- lib/idml/render/page_item_renderer.rb
|
|
380
|
-
- lib/idml/render/path.rb
|
|
381
|
-
- lib/idml/render/pdf_writer.rb
|
|
382
|
-
- lib/idml/render/pdfrb_ext.rb
|
|
383
|
-
- lib/idml/render/pdfrb_ext/clip.rb
|
|
384
|
-
- lib/idml/render/pdfrb_ext/invoke_xobject.rb
|
|
385
378
|
- lib/idml/render/pdfrb_writer.rb
|
|
386
379
|
- lib/idml/render/pipeline.rb
|
|
387
380
|
- lib/idml/render/render_context.rb
|
|
@@ -395,7 +388,6 @@ files:
|
|
|
395
388
|
- lib/idml/render/spread_renderer.rb
|
|
396
389
|
- lib/idml/render/story_threader.rb
|
|
397
390
|
- lib/idml/render/style_resolver.rb
|
|
398
|
-
- lib/idml/render/text.rb
|
|
399
391
|
- lib/idml/text_engine.rb
|
|
400
392
|
- lib/idml/text_engine/cjk_layout.rb
|
|
401
393
|
- lib/idml/text_engine/font_metrics.rb
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# TODO PDF 56: Text engine full integration with pdfrb Canvas
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
|
|
5
|
-
Re-integrate the text engine (Shaper → LineBreaker → Justifier →
|
|
6
|
-
VerticalLayout) into TextFrameRenderer using pdfrb Canvas. Each line
|
|
7
|
-
of shaped/broken text is emitted as a separate `canvas.text` call
|
|
8
|
-
at the computed baseline position.
|
|
9
|
-
|
|
10
|
-
## Status: DONE
|
|
11
|
-
|
|
12
|
-
## What was implemented
|
|
13
|
-
|
|
14
|
-
TextFrameRenderer has two rendering paths:
|
|
15
|
-
1. **engine_render** (when FontMetrics available): shapes text via
|
|
16
|
-
Shaper, breaks lines via LineBreaker at frame width, positions
|
|
17
|
-
each line at decreasing baseline_y, emits `canvas.text` per line.
|
|
18
|
-
Lines beyond frame bottom are skipped.
|
|
19
|
-
2. **simple_render** (fallback): one `canvas.text` per styled run at
|
|
20
|
-
sequential y positions.
|
|
21
|
-
|
|
22
|
-
The FontMetrics comes from `context.font_resolver.resolve(family_name:)`.
|
|
23
|
-
On systems where the default font is available as .ttf (not .ttc), the
|
|
24
|
-
text engine provides proper word-wrap.
|
|
25
|
-
|
|
26
|
-
## Acceptance criteria
|
|
27
|
-
|
|
28
|
-
- [x] TextFrameRenderer tries FontResolver for metrics.
|
|
29
|
-
- [x] When metrics available: Shaper → LineBreaker → per-line canvas.text.
|
|
30
|
-
- [x] When metrics unavailable: simple one-text-per-run fallback.
|
|
31
|
-
- [x] Frame bounds respected (lines beyond frame bottom skipped).
|
|
32
|
-
- [x] Chain head check prevents duplicate text in overflow frames.
|
|
33
|
-
- [x] Text frame insets subtracted from frame box.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# TODO PDF 57: Image clipping via pdfrb Canvas
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
|
|
5
|
-
Clip placed images to their parent Rectangle's bounds using PDF clip
|
|
6
|
-
paths. Prevents image overflow beyond the containing frame.
|
|
7
|
-
|
|
8
|
-
## Status: DONE
|
|
9
|
-
|
|
10
|
-
## What was implemented
|
|
11
|
-
|
|
12
|
-
- `PdfrbExt::Clip` (PDF `W` operator) and `PdfrbExt::EndPath` (PDF `n`
|
|
13
|
-
operator) registered as pdfrb Content::Operator subclasses.
|
|
14
|
-
- `SpreadRenderer#apply_image_clip` emits a clip path from the parent
|
|
15
|
-
Rectangle's geometric_bounds before drawing the image.
|
|
16
|
-
- `Pipeline#parent_clip_box` computes the clip rectangle from the
|
|
17
|
-
parent page item's bounds via Geometry helpers.
|
|
18
|
-
- Image refs now carry a `clip_box` field; when present, the SpreadRenderer
|
|
19
|
-
clips before drawing.
|
|
20
|
-
|
|
21
|
-
## Acceptance criteria
|
|
22
|
-
|
|
23
|
-
- [x] PdfrbExt::Clip and EndPath operators registered.
|
|
24
|
-
- [x] SpreadRenderer applies clip path when clip_box is present.
|
|
25
|
-
- [x] Pipeline computes clip_box from parent geometric_bounds.
|
|
26
|
-
- [x] All tests pass.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# TODO PDF 58: PDF bookmarks via pdfrb outline API
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
|
|
5
|
-
Generate PDF bookmark (outline) entries using pdfrb's outline API.
|
|
6
|
-
Each bookmark links to a page destination.
|
|
7
|
-
|
|
8
|
-
## Status: DONE
|
|
9
|
-
|
|
10
|
-
## What was implemented
|
|
11
|
-
|
|
12
|
-
- `PdfrbWriter#add_bookmark(title, page_index)` delegates to
|
|
13
|
-
`Pdfrb::Document#outline.add(title, dest: page)`.
|
|
14
|
-
- Available for Pipeline consumers to add bookmarks for headings or
|
|
15
|
-
sections.
|
|
16
|
-
- `PdfrbExt::Clip` and `PdfrbExt::EndPath` also added for image clipping
|
|
17
|
-
(TODO 57).
|
|
18
|
-
|
|
19
|
-
## Acceptance criteria
|
|
20
|
-
|
|
21
|
-
- [x] PdfrbWriter#add_bookmark delegates to pdfrb outline API.
|
|
22
|
-
- [x] Anti-pattern spec passes (no new violations).
|
|
23
|
-
- [x] All tests pass.
|