idml 0.5.1 → 0.5.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4b32bcaed6562461191096ac7bbcd0ff8a14c151056bdbf122c439a711dc869
4
- data.tar.gz: 30cff3491f9588716cfb676b00509f728c7c2af21b0efe9cb5a6ac4f2b77fe0b
3
+ metadata.gz: b61e00a5f26f6e7266f1f512362e22453623b09ea06dd002d5e0a79ba23b52d0
4
+ data.tar.gz: 2177e3e9371f985bd06fe889d02db20a03c90f31fdbcaa162709d2494f37fd24
5
5
  SHA512:
6
- metadata.gz: a97de15a173bca917a1e10aa4fc32eb553b2ee2bd88fc33f49953437513e923b90acdaa02a734b74bc3d51493ba464aadbfbb51f86ede65369c0cf2a7a779911
7
- data.tar.gz: 55448f8fb8d465fe0fbc2d078b4530ef80843721055856717788d7a77f6984f5e20a44dcaa41a8e2741a66b17b616b174f322ed0a770b3236c8617b6545054c4
6
+ metadata.gz: a85eed35528a6da8709a6f54c7b7a01f42334646f110adc5ff6fff572b250c26a011a3744682da3216476973f97a45cf9e9850b1bf398df7985fd85ec013eb0b
7
+ data.tar.gz: 405859c6e2efe2e62ae56ea3079799e0d5a822e3c7c0b15d04a904969408d7f2cd0aa76fa20faf5bb1dd7640c7c4b98fcfe0185e9f18d0c041168e7b55af5e9c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- idml (0.5.1)
4
+ idml (0.5.2)
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.1)
186
+ idml (0.5.2)
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
@@ -65,16 +65,82 @@ non-image streams.
65
65
  - **Font subsetting to fewer glyphs than used** (lossless subsetting
66
66
  IS done by pdfrb — removes only unused glyphs).
67
67
 
68
- ## Future audit work
69
-
70
- - **Stream-by-stream comparison** with `qpdf --qdf` to decompose both
71
- PDFs into canonical form and diff.
72
- - **Font subsetting investigation** pdfrb's `subset_fonts!` is
73
- called but the font stream is still 232KB. The likely cause is
74
- that no codepoints are recorded as "used" for the registered font
75
- (the renderer uses a default font that doesn't get text drawn
76
- through it). Future fix: register the font actually used to draw
77
- text, so `used_codepoints` populates correctly.
68
+ ## Additional findings (stream-level audit via `mutool`)
69
+
70
+ ### xref byte-count bug (TODO 92)
71
+
72
+ pdfrb emits 21-byte xref entries (extra space before `\r\n`). PDF
73
+ spec §7.5.4 requires exactly 20. `mutool` reports:
74
+ ```
75
+ format error: expected trailer marker
76
+ warning: trying to repair broken xref
77
+ ```
78
+ **Workaround**: use `compress: true` — switches to XRef stream,
79
+ bypassing the traditional xref table entirely.
80
+
81
+ ### Font naming
82
+
83
+ - InDesign: `OZNMOQ+MinionPro-Regular` (5-char subset prefix per
84
+ PDF spec convention for subsetted fonts).
85
+ - Ours: `FileFont-MinionPro-Regular` (non-standard prefix).
86
+
87
+ pdfrb should use the `[A-Z]{6}+` prefix convention for subsetted
88
+ fonts.
89
+
90
+ ### Font type
91
+
92
+ - InDesign: `/Subtype /Type1` with `/FontFile3` (CFF/Type1C).
93
+ InDesign converts OTF → CFF subset.
94
+ - Ours: `/Subtype /TrueType` with `/FontFile2`. We embed the raw
95
+ TTF/OTF bytes as-is.
96
+
97
+ Both are valid PDF but Type1/CFF is typically more compact.
98
+
99
+ ### Page Resources
100
+
101
+ - InDesign page 1 Resources: `/ColorSpace` (ICCBased),
102
+ `/ExtGState` (graphics states for transparency),
103
+ `/Font` (T1_0), `/ProcSet`, `/XObject` (Form XObjects for master
104
+ items + Images).
105
+ - Our page 1 Resources: `/Font` only. No ColorSpace, no ExtGState,
106
+ no XObject/Form.
107
+
108
+ Missing: ICC color space, extended graphics states, Form XObjects
109
+ for master-spread content.
110
+
111
+ ### Image count
112
+
113
+ - InDesign: 3 images per page (downsampled to 300ppi, with ICC
114
+ profiles).
115
+ - Ours: 1 image total (full-resolution GenAI JPEG, no ICC).
116
+
117
+ The difference is because InDesign renders the same source asset
118
+ on multiple pages via Form XObject reference, while we embed it
119
+ once globally.
120
+
121
+ ### Info dictionary
122
+
123
+ - InDesign Info: clean key/value pairs.
124
+ - Ours: includes `/Type/Metadata` — incorrect. Info dictionaries
125
+ should not have a `/Type` key. This is a pdfrb issue.
126
+
127
+ ## Summary of all differences
128
+
129
+ | Category | InDesign | Ours | Status |
130
+ |---|---|---|---|
131
+ | File size | 100KB | 2.1MB | Cannot close without data loss (image) |
132
+ | PDF version | 1.7 | 1.4 | Minor |
133
+ | Font selection | MinionPro-Regular | MinionPro-Regular | **Closed** (v0.5.0) |
134
+ | Font subtype | Type1/CFF | TrueType | pdfrb upstream |
135
+ | Font subset prefix | `OZNMOQ+` | `FileFont-` | pdfrb upstream |
136
+ | FlateDecode | 24 streams | 8 streams | **Closed** (v0.5.1, opt-in) |
137
+ | xref compliance | valid | 21-byte entries | **Workaround**: `compress: true` |
138
+ | ICC color space | embedded | absent | TODO |
139
+ | ExtGState | per-page | absent | TODO |
140
+ | Form XObjects | master items | absent | TODO |
141
+ | Image count | 3/page (downsampled) | 1 total (full-res) | Cannot close without data loss |
142
+ | Info dict | clean | has spurious /Type/Metadata | pdfrb upstream |
143
+ | Object count | 215 | 17 | InDesign richer structure |
78
144
 
79
145
  ## Verification
80
146
 
@@ -0,0 +1,74 @@
1
+ # TODO PDF 92: XRef entry byte-count compliance (21 vs 20 bytes)
2
+
3
+ ## Status: IDENTIFIED — pdfrb upstream bug
4
+
5
+ ## Problem
6
+
7
+ PDF spec §7.5.4 requires each cross-reference entry to be exactly
8
+ **20 bytes** including the 2-character end-of-line marker. Three
9
+ valid EOL formats:
10
+
11
+ - `nnnnnnnnnn ggggg n\r\n` (CRLF)
12
+ - `nnnnnnnnnn ggggg n \n` (space + LF)
13
+ - `nnnnnnnnnn ggggg n \r` (space + CR)
14
+
15
+ pdfrb's xref writer emits `nnnnnnnnnn ggggg n \r\n` — **21 bytes**
16
+ because of the extra space between the status character and the
17
+ `\r\n`. Strict PDF readers (MuPDF, `mutool`) reject this:
18
+
19
+ ```
20
+ format error: expected trailer marker
21
+ warning: trying to repair broken xref
22
+ warning: repairing PDF document
23
+ ```
24
+
25
+ Lenient readers (`pdftk`, Apple Preview, Chrome) tolerate it.
26
+
27
+ ## Verification
28
+
29
+ ```python
30
+ # In a generated PDF:
31
+ entry = b'0000000015 00000 n \r\n' # 21 bytes
32
+ assert len(entry) == 21 # BUG: should be 20
33
+ ```
34
+
35
+ Compare with InDesign's output (compliant):
36
+ ```python
37
+ entry = b'0000000015 00000 n \r\n' # should be 20 bytes
38
+ # InDesign uses object streams + xref stream, so no traditional
39
+ # xref table in the test fixture's pages.pdf
40
+ ```
41
+
42
+ ## Fix
43
+
44
+ In pdfrb's writer, remove the space before `\r\n` in each xref
45
+ entry. The format should be:
46
+ ```ruby
47
+ "%010d %05d %s\r\n" % [offset, generation, status]
48
+ ```
49
+ Not:
50
+ ```ruby
51
+ "%010d %05d %s \r\n" % [offset, generation, status]
52
+ ```
53
+
54
+ ## Impact
55
+
56
+ Without the fix, strict validators flag our PDFs as broken. The
57
+ PDFs still open in most readers because the xref can be rebuilt
58
+ from the object scan, but:
59
+
60
+ - `mutool` prints repair warnings.
61
+ - veraPDF may reject the file.
62
+ - PDF/A validators may flag non-compliance.
63
+
64
+ ## Workaround
65
+
66
+ Use `compress: true` — pdfrb then uses an XRef stream
67
+ (`writer.use_xref_stream: true`) instead of a traditional xref
68
+ table, bypassing the byte-counting issue entirely.
69
+
70
+ ## Acceptance criteria
71
+
72
+ - [ ] pdfrb xref writer emits 20-byte entries.
73
+ - [ ] `mutool info` reports no repair warnings.
74
+ - [ ] PDF/A validators accept the output without xref warnings.
data/lib/idml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Idml
4
- VERSION = "0.5.1"
4
+ VERSION = "0.5.2"
5
5
  end
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.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
@@ -217,6 +217,7 @@ files:
217
217
  - TODO.pdf/89-deep-audit-idml-vs-indesign.md
218
218
  - TODO.pdf/90-per-run-font-resolution.md
219
219
  - TODO.pdf/91-image-downsampling.md
220
+ - TODO.pdf/92-xref-entry-byte-count.md
220
221
  - TODO.pdf/README.md
221
222
  - exe/idml
222
223
  - idml.gemspec