idml 0.5.3 → 0.5.5
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.lock +2 -2
- data/TODO.pdf/89-deep-audit-idml-vs-indesign.md +20 -10
- data/TODO.pdf/92-xref-entry-byte-count.md +1 -1
- data/TODO.pdf/93-per-run-font-resolution.md +67 -0
- data/lib/idml/render.rb +10 -0
- data/lib/idml/version.rb +1 -1
- data/lib/idml.rb +1 -0
- metadata +2 -2
- data/TODO.pdf/90-per-run-font-resolution.md +0 -55
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce8ffd92b6fd96bc1b018ed0875a0344e4c96692b18a12f3ab7999db3bc0c257
|
|
4
|
+
data.tar.gz: b454cdc91f17dabacd2c35a8f1b808aacbb23b40a91b7b392eab68c7b109935c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d1c153af76705ddef5cdf58334d1f23010dd0a88c3559f9fd7da87cf94a52f2a48c386dddd6a443f2877c0df25e9ae618a3388e117d5c825b99814ee2d35973
|
|
7
|
+
data.tar.gz: 86eaa92d00b471cb085dc32f81e6c7618a856583ff340bd88f5b535378cfa8e46c73685d5fb6090a10be22e3c3425066b54859ce98be78cb31a2dcfc598a71b2
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
idml (0.5.
|
|
4
|
+
idml (0.5.5)
|
|
5
5
|
bigdecimal
|
|
6
6
|
lutaml-model (~> 0.8.18)
|
|
7
7
|
pdfrb
|
|
@@ -183,7 +183,7 @@ CHECKSUMS
|
|
|
183
183
|
ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496
|
|
184
184
|
ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
|
|
185
185
|
ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e
|
|
186
|
-
idml (0.5.
|
|
186
|
+
idml (0.5.5)
|
|
187
187
|
json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
|
|
188
188
|
language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
|
|
189
189
|
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
# TODO PDF 89: Deep audit — idml-generated PDF vs InDesign PDF
|
|
2
2
|
|
|
3
|
-
## Status:
|
|
3
|
+
## Status: COMPLETE — all fixable gaps closed; remaining gap is no-data-loss constraint
|
|
4
4
|
|
|
5
5
|
## TL;DR
|
|
6
6
|
|
|
7
|
-
**No** — the generated PDF is
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
**No** — the generated PDF is not byte-identical to InDesign's output.
|
|
8
|
+
This is by design: the user requirement is **no data loss**. InDesign's
|
|
9
|
+
100KB output downsamples the 1.94MB source image to ~12KB; we preserve
|
|
10
|
+
the image at full resolution. All other gaps (font selection, font
|
|
11
|
+
embedding type, subset prefix, xref compliance, Info dict, lossless
|
|
12
|
+
compression) are now closed.
|
|
13
|
+
|
|
14
|
+
Closed gaps (v0.5.0–v0.5.4):
|
|
15
|
+
1. Font selection — Regular weight preferred over first-in-family.
|
|
16
|
+
2. Font embedding via IO (not string path) — properly embeds as CFF.
|
|
17
|
+
3. Font type — Type1/CFF (not TrueType), matching InDesign.
|
|
18
|
+
4. Font subset prefix — 6-char uppercase tag (not FileFont-).
|
|
19
|
+
5. xref compliance — 20-byte entries (pdfrb 0.6.0 fix).
|
|
20
|
+
6. Info dict — no spurious /Type/Metadata.
|
|
21
|
+
7. Lossless FlateDecode compression — opt-in via --compress.
|
|
22
|
+
|
|
23
|
+
Remaining gap (cannot close without data loss):
|
|
24
|
+
- File size: 2.1MB vs 100KB. The 1.94MB embedded JPEG is preserved
|
|
25
|
+
at source resolution per the no-data-loss requirement.
|
|
16
26
|
object streams when `compress: true`. Saves ~96KB (4%) on the
|
|
17
27
|
sample-with-table-more fixture without any data loss.
|
|
18
28
|
3. **Image downsampling** — **not pursued**. The user requirement is
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# TODO PDF 93: Per-run font resolution from CharacterStyleRange
|
|
2
|
+
|
|
3
|
+
## Status: PLANNED (last major rendering fidelity gap)
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
All text in the rendered PDF uses the same font (the document's
|
|
8
|
+
default Regular weight). Real IDML documents specify per-run fonts
|
|
9
|
+
via `CharacterStyleRange#AppliedCharacterStyle` → `CharacterStyle`
|
|
10
|
+
→ `Properties/AppliedFont` (family name) + style attributes.
|
|
11
|
+
|
|
12
|
+
For the `sample-with-table-more` fixture, all text happens to use
|
|
13
|
+
`[No character style]` with `NormalParagraphStyle`, so the default
|
|
14
|
+
Regular weight is correct. But other IDML documents have bold,
|
|
15
|
+
italic, and mixed-family text that our renderer can't express.
|
|
16
|
+
|
|
17
|
+
## What needs to happen
|
|
18
|
+
|
|
19
|
+
1. **StyleResolver enhancement**: extract `applied_font` from each
|
|
20
|
+
CSR via its `AppliedCharacterStyle` reference. The chain is:
|
|
21
|
+
- CSR `AppliedCharacterStyle="CharacterStyle/$ID/bold_text"`
|
|
22
|
+
- → CharacterStyle `Self="CharacterStyle/$ID/bold_text"`
|
|
23
|
+
- → CharacterStyle `Properties/AppliedFont` → family name
|
|
24
|
+
- → CharacterStyle `FontStyle` → style (Bold, Italic, etc.)
|
|
25
|
+
- → Fonts.xml lookup → PostScriptName
|
|
26
|
+
- → Pdfrb::FontResolver → file path → pdfrb font resource
|
|
27
|
+
|
|
28
|
+
2. **Multi-font registration**: FontSetup registers each distinct
|
|
29
|
+
font used by any CSR, not just the document default. Returns a
|
|
30
|
+
map of `applied_font_ref → pdfrb_symbol`.
|
|
31
|
+
|
|
32
|
+
3. **StyledRun enhancement**: carries the resolved pdfrb font
|
|
33
|
+
resource Symbol (not just the PS name string).
|
|
34
|
+
|
|
35
|
+
4. **TextFrameRenderer**: uses `run.font_resource` for each
|
|
36
|
+
`canvas.text` / `canvas.text_rich` call instead of the single
|
|
37
|
+
`context.font_ps_name`.
|
|
38
|
+
|
|
39
|
+
5. **TableRenderer**: same — per-cell font resolution from the
|
|
40
|
+
cell's CSR.
|
|
41
|
+
|
|
42
|
+
## Scope
|
|
43
|
+
|
|
44
|
+
- For documents with uniform styling (like the test fixture), no
|
|
45
|
+
visible change — the default Regular font is already correct.
|
|
46
|
+
- For documents with bold/italic/mixed-family runs, text would
|
|
47
|
+
render in the correct font per run.
|
|
48
|
+
- Font subsetting becomes per-font: each registered font gets its
|
|
49
|
+
own used-codepoint set and subset.
|
|
50
|
+
|
|
51
|
+
## Dependencies
|
|
52
|
+
|
|
53
|
+
- pdfrb 0.6.0 with IO-based font loading (DONE, v0.5.3).
|
|
54
|
+
- CharacterStyle element model (exists — verify AppliedFont
|
|
55
|
+
extraction from Properties).
|
|
56
|
+
- FontReferenceResolver (exists — already builds family → PSName
|
|
57
|
+
lookup from Fonts.xml).
|
|
58
|
+
|
|
59
|
+
## Acceptance criteria
|
|
60
|
+
|
|
61
|
+
- [ ] StyledRun carries a resolved pdfrb font resource Symbol.
|
|
62
|
+
- [ ] CSR with `AppliedCharacterStyle` referencing a bold style
|
|
63
|
+
renders in bold font.
|
|
64
|
+
- [ ] CSR with no applied style renders in the document default.
|
|
65
|
+
- [ ] Multiple fonts embedded when document uses multiple families.
|
|
66
|
+
- [ ] Font subsetting works per-font (each font subsetted to its
|
|
67
|
+
own used codepoints).
|
data/lib/idml/render.rb
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
require "pdfrb"
|
|
4
4
|
|
|
5
|
+
# pdfrb 0.6.0 autoloads OptContentUsage from opt_content_ext.rb but
|
|
6
|
+
# that file doesn't define it, causing eager_load! to crash.
|
|
7
|
+
# Trigger the autoload (catching the failure) then define a stub.
|
|
8
|
+
begin
|
|
9
|
+
Pdfrb::Model::Type::OptContentUsage
|
|
10
|
+
rescue NameError
|
|
11
|
+
Pdfrb::Model::Type.const_set(:OptContentUsage,
|
|
12
|
+
Class.new(Pdfrb::Model::Cos::Dictionary))
|
|
13
|
+
end
|
|
14
|
+
|
|
5
15
|
module Idml
|
|
6
16
|
module Render
|
|
7
17
|
autoload :ColorHelper, "#{__dir__}/render/color_helper"
|
data/lib/idml/version.rb
CHANGED
data/lib/idml.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.5.
|
|
4
|
+
version: 0.5.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -215,9 +215,9 @@ files:
|
|
|
215
215
|
- TODO.pdf/86-caching-performance.md
|
|
216
216
|
- TODO.pdf/87-final-state-summary.md
|
|
217
217
|
- TODO.pdf/89-deep-audit-idml-vs-indesign.md
|
|
218
|
-
- TODO.pdf/90-per-run-font-resolution.md
|
|
219
218
|
- TODO.pdf/91-image-downsampling.md
|
|
220
219
|
- TODO.pdf/92-xref-entry-byte-count.md
|
|
220
|
+
- TODO.pdf/93-per-run-font-resolution.md
|
|
221
221
|
- TODO.pdf/README.md
|
|
222
222
|
- exe/idml
|
|
223
223
|
- idml.gemspec
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# TODO PDF 90: Per-run font resolution
|
|
2
|
-
|
|
3
|
-
## Status: PLANNED (TODO 89 audit follow-up)
|
|
4
|
-
|
|
5
|
-
## Problem
|
|
6
|
-
|
|
7
|
-
`Idml::Render::FontSetup#register` picks the first non-missing font
|
|
8
|
-
in the document's `font_family` collection. For the
|
|
9
|
-
`sample-with-table-more` fixture that's `MinionPro-BoldCn` — but
|
|
10
|
-
InDesign's reference PDF embeds `MinionPro-Regular` because each
|
|
11
|
-
text run's `CharacterStyleRange#AppliedFont` specifies a per-run font.
|
|
12
|
-
|
|
13
|
-
The current `Idml::Render::StyleResolver::StyledRun` carries font
|
|
14
|
-
metadata but not the resolved per-run font. All text renders with
|
|
15
|
-
the first-available font, which may not match what the CSR's
|
|
16
|
-
`AppliedFont` references.
|
|
17
|
-
|
|
18
|
-
## Plan
|
|
19
|
-
|
|
20
|
-
1. **Extract per-run font** — `StyleResolver` adds
|
|
21
|
-
`applied_font: <PSName>` to `StyledRun`, populated from
|
|
22
|
-
`csr.applied_font` (a `CharacterStyle` reference, not a font
|
|
23
|
-
directly).
|
|
24
|
-
|
|
25
|
-
2. **Resolve to font resource** — `FontSetup` exposes a
|
|
26
|
-
`font_for_ps_name(ps_name)` that returns a registered font
|
|
27
|
-
resource (Symbol) or nil. Pre-registers all non-missing fonts
|
|
28
|
-
in the document upfront so the lookup is constant-time.
|
|
29
|
-
|
|
30
|
-
3. **Pass per-run font through the renderer** — the render path
|
|
31
|
-
resolves `run.applied_font` → font resource once, registers if
|
|
32
|
-
needed, and uses that for the canvas.text / text_rich /
|
|
33
|
-
text_lines calls.
|
|
34
|
-
|
|
35
|
-
4. **Track font-by-font used codepoints** — each font tracks its
|
|
36
|
-
own set of used codepoints so `subset_fonts!` can produce
|
|
37
|
-
per-font subsets.
|
|
38
|
-
|
|
39
|
-
## Verification
|
|
40
|
-
|
|
41
|
-
After implementation:
|
|
42
|
-
- `Idml::Render::FontSetup#register_resolved(ps_name)` returns a
|
|
43
|
-
Symbol for each `ps_name` it knows about.
|
|
44
|
-
- `StyleResolver::StyledRun#applied_font` returns the PSName string
|
|
45
|
-
when set.
|
|
46
|
-
- TextFrameRenderer resolves `run.applied_font` once per run and
|
|
47
|
-
uses the returned Symbol for all canvas text ops.
|
|
48
|
-
- subset_fonts! produces a smaller output for sample-with-table-more.
|
|
49
|
-
|
|
50
|
-
## Acceptance criteria
|
|
51
|
-
|
|
52
|
-
- [ ] The idml render's embedded font for sample-with-table-more is
|
|
53
|
-
`MinionPro-Regular`, not `MinionPro-BoldCn`.
|
|
54
|
-
- [ ] Font stream size shrinks from 232KB to <50KB after subsetting.
|
|
55
|
-
- [ ] Spec asserts the correct font is selected per run.
|