idml 0.9.5 → 0.9.6
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/TODO.pdf/122-vertical-latin-ruby.md +29 -0
- data/lib/idml/render/renderers/text_frame_renderer.rb +70 -9
- data/lib/idml/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76ef12540a7d7d1805189664f88fc0c5b400b8d1240fbc495239ddb35f64822c
|
|
4
|
+
data.tar.gz: 941893920b3e23a32c196de4286a64f10edb0e377bb716a5287ba110bc3052bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 95da409c1987bac0a36ab73793c02e349d3060f313f3f4fc2670f22efffd89bd2d5f0bcfba4096dab595cf39a7843134ee0fc4f06f9e4136d477c65f44870586
|
|
7
|
+
data.tar.gz: a74c7d9a0a1ccd22e57308890a0f6b257e9ec2d3aab7d3d8a407c23b4b52f466cd2c39f86be48d4b89e912e26fcd3a582dbdf27455d8db49a405219ede022357
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# TODO PDF 122: Vertical mode completion — Latin rotation, vertical ruby
|
|
2
|
+
|
|
3
|
+
## Status: COMPLETE — implemented 2026-08-20
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
The vertical writing path (TODO 13, 2026-08-19) stacked every glyph
|
|
8
|
+
upright: Latin letters and digits rendered sideways-wrong (rotated
|
|
9
|
+
in appearance relative to convention), and ruby annotations were
|
|
10
|
+
not emitted at all in vertical mode.
|
|
11
|
+
|
|
12
|
+
## What was done
|
|
13
|
+
|
|
14
|
+
- Latin rotation: non-CJK glyphs in vertical text render rotated
|
|
15
|
+
90° clockwise (the vertical-writing convention for Latin runs),
|
|
16
|
+
via a graphics-state transform (q → translate → rotate −90° →
|
|
17
|
+
text at origin → Q). CJK glyphs stay upright.
|
|
18
|
+
- Vertical ruby: runs carrying RubyString emit the annotation
|
|
19
|
+
stacked vertically alongside the base glyphs — to the right of
|
|
20
|
+
the column by default, to the left for RubyPosition values
|
|
21
|
+
containing "Below" (mirroring the horizontal above/below
|
|
22
|
+
convention under rotation). RubyFontSize defaults to half the
|
|
23
|
+
base size.
|
|
24
|
+
|
|
25
|
+
## Known limitations
|
|
26
|
+
|
|
27
|
+
- Tate-chu-yoko (horizontal digit groups inside vertical text) and
|
|
28
|
+
mojikumi spacing classes remain documented stretch goals
|
|
29
|
+
(TODO 13).
|
|
@@ -232,6 +232,8 @@ module Idml
|
|
|
232
232
|
positioned.each do |glyph|
|
|
233
233
|
emit_vertical_glyph(canvas, glyph, run, context, size)
|
|
234
234
|
end
|
|
235
|
+
emit_vertical_ruby(canvas, run, positioned, layout_frame,
|
|
236
|
+
size, context)
|
|
235
237
|
end
|
|
236
238
|
[]
|
|
237
239
|
end
|
|
@@ -246,21 +248,80 @@ module Idml
|
|
|
246
248
|
|
|
247
249
|
# Emits one upright glyph at its vertical position with the
|
|
248
250
|
# run's character styling.
|
|
251
|
+
# Emits one glyph in vertical mode: CJK upright; Latin
|
|
252
|
+
# (non-CJK) rotated 90° clockwise per the vertical-writing
|
|
253
|
+
# convention, via a graphics-state transform.
|
|
249
254
|
def self.emit_vertical_glyph(canvas, positioned, run, context,
|
|
250
255
|
size)
|
|
251
256
|
text = [positioned.codepoint].pack("U")
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
257
|
+
if TextEngine::CjkLayout.cjk?(positioned.codepoint)
|
|
258
|
+
text_kwargs = CharacterStyle.text_kwargs(
|
|
259
|
+
run,
|
|
260
|
+
{
|
|
261
|
+
at: [positioned.x, positioned.y],
|
|
262
|
+
font: font_for_run(run, context),
|
|
263
|
+
size: size,
|
|
264
|
+
},
|
|
265
|
+
)
|
|
266
|
+
canvas.text(text, **text_kwargs)
|
|
267
|
+
else
|
|
268
|
+
canvas.save_graphics_state do
|
|
269
|
+
# 90° clockwise: exact matrix (rotate would emit
|
|
270
|
+
# cos/sin float noise like 6.1e-17).
|
|
271
|
+
canvas.concat(0, -1, 1, 0, positioned.x, positioned.y)
|
|
272
|
+
text_kwargs = CharacterStyle.text_kwargs(
|
|
273
|
+
run,
|
|
274
|
+
{
|
|
275
|
+
at: [0, 0],
|
|
276
|
+
font: font_for_run(run, context),
|
|
277
|
+
size: size,
|
|
278
|
+
},
|
|
279
|
+
)
|
|
280
|
+
canvas.text(text, **text_kwargs)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
261
283
|
end
|
|
262
284
|
private_class_method :emit_vertical_glyph
|
|
263
285
|
|
|
286
|
+
# Emits the run's ruby alongside its vertical glyphs:
|
|
287
|
+
# stacked top-to-bottom beside the column — right side by
|
|
288
|
+
# default, left for Below* RubyPosition values (the
|
|
289
|
+
# horizontal above/below convention mirrored under
|
|
290
|
+
# rotation).
|
|
291
|
+
def self.emit_vertical_ruby(canvas, run, positioned, frame,
|
|
292
|
+
base_size, context)
|
|
293
|
+
ruby_text = run.ruby_string
|
|
294
|
+
return if ruby_text.nil? || ruby_text.empty?
|
|
295
|
+
|
|
296
|
+
ruby_size = run.ruby_font_size ||
|
|
297
|
+
(base_size * RUBY_SIZE_FACTOR)
|
|
298
|
+
x = ruby_vertical_x(positioned.first, run, base_size)
|
|
299
|
+
y = frame.y + frame.height - (frame.inset_top || 0)
|
|
300
|
+
ruby_text.each_codepoint do |codepoint|
|
|
301
|
+
text_kwargs = CharacterStyle.text_kwargs(
|
|
302
|
+
run,
|
|
303
|
+
{
|
|
304
|
+
at: [x, y - ruby_size],
|
|
305
|
+
font: font_for_run(run, context),
|
|
306
|
+
size: ruby_size,
|
|
307
|
+
},
|
|
308
|
+
)
|
|
309
|
+
canvas.text([codepoint].pack("U"), **text_kwargs)
|
|
310
|
+
y -= ruby_size
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
private_class_method :emit_vertical_ruby
|
|
314
|
+
|
|
315
|
+
def self.ruby_vertical_x(positioned, run, base_size)
|
|
316
|
+
offset = base_size * 0.9
|
|
317
|
+
if run.ruby_position.to_s.include?("Below")
|
|
318
|
+
positioned.x - offset
|
|
319
|
+
else
|
|
320
|
+
positioned.x + offset
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
private_class_method :ruby_vertical_x
|
|
324
|
+
|
|
264
325
|
def self.chain_head?(frame)
|
|
265
326
|
frame.previous_text_frame.nil? || frame.previous_text_frame == "n"
|
|
266
327
|
end
|
data/lib/idml/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: idml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bigdecimal
|
|
@@ -180,6 +180,7 @@ files:
|
|
|
180
180
|
- TODO.pdf/12-idml-to-pdf-pipeline.md
|
|
181
181
|
- TODO.pdf/120-start-paragraph-breaks.md
|
|
182
182
|
- TODO.pdf/121-cell-edge-strokes.md
|
|
183
|
+
- TODO.pdf/122-vertical-latin-ruby.md
|
|
183
184
|
- TODO.pdf/13-cjk-text-layout.md
|
|
184
185
|
- TODO.pdf/14-page-item-element-models.md
|
|
185
186
|
- TODO.pdf/15-wire-spread-children.md
|