idml 0.3.1 → 0.4.1

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.
@@ -58,8 +58,10 @@ module Idml
58
58
  end
59
59
  private_class_method :engine_render
60
60
 
61
- # Emits one `canvas.text_lines` call per run, after shaping
62
- # and line-breaking with real font metrics. Lines that fall
61
+ # Emits one `canvas.text` call per line, after shaping and
62
+ # line-breaking with real font metrics. Applies paragraph
63
+ # alignment via `Justifier` so each line is offset within
64
+ # the frame box per IDML `Justification`. Lines that fall
63
65
  # below the frame's bottom edge are clipped.
64
66
  def self.render_run_lines(canvas, run, context, box, font, baseline_y)
65
67
  size = run.point_size
@@ -69,26 +71,30 @@ module Idml
69
71
  lines = TextEngine::LineBreaker.break(
70
72
  glyphs: glyphs, frame_width: box[:width],
71
73
  )
72
-
73
- line_texts = []
74
- lines.each do |line|
75
- break if baseline_y < box[:y]
76
-
77
- line_texts << line.glyphs.map { |g| [g.codepoint].pack("U") }.join
78
- baseline_y -= size * LEADING_FACTOR
79
- end
80
-
81
- if line_texts.any?
82
- canvas.text_lines(line_texts,
83
- font: context.font_ps_name,
84
- size: size,
85
- at: [box[:x], box[:y] + box[:height] - size],
86
- leading: size * LEADING_FACTOR)
74
+ alignment = run.alignment || :left
75
+ start_y = box[:y] + box[:height] - size
76
+
77
+ lines.each_with_index do |line, idx|
78
+ line_y = start_y - (idx * size * LEADING_FACTOR)
79
+ break if line_y < box[:y]
80
+
81
+ TextEngine::Justifier.justify(line: line,
82
+ frame_width: box[:width],
83
+ alignment: alignment)
84
+ canvas.text(line_text(line),
85
+ at: [box[:x] + line.x_offset, line_y],
86
+ font: context.font_ps_name,
87
+ size: size)
87
88
  end
88
89
  baseline_y
89
90
  end
90
91
  private_class_method :render_run_lines
91
92
 
93
+ def self.line_text(line)
94
+ line.glyphs.map { |g| [g.codepoint].pack("U") }.join
95
+ end
96
+ private_class_method :line_text
97
+
92
98
  # Fallback when no metrics are available: emit all runs as
93
99
  # one `text_rich` block, letting pdfrb measure advance widths.
94
100
  # Uses pdfrb's measurement API directly (no Fontisan).
@@ -4,15 +4,30 @@ module Idml
4
4
  module Render
5
5
  # Extracts styled text runs from an IDML Story. Each run carries the
6
6
  # text content plus the CharacterStyleRange attributes that affect
7
- # rendering (font style, size, fill color, applied font reference).
7
+ # rendering (font style, size, fill color, applied font reference,
8
+ # paragraph alignment).
8
9
  class StyleResolver
9
10
  StyledRun = Struct.new(
10
11
  :text, :font_style, :point_size,
11
- :fill_color, :fill_tint, :applied_font, keyword_init: true
12
+ :fill_color, :fill_tint, :applied_font, :alignment,
13
+ keyword_init: true
12
14
  )
13
15
 
14
16
  DEFAULT_POINT_SIZE = 12.0
15
17
 
18
+ # IDML `Justification` enum → Justifier symbol. Full justify
19
+ # and binding-side variants defer to :left for now (TODO 80).
20
+ ALIGNMENT_MAP = {
21
+ "Left" => :left,
22
+ "Center" => :center,
23
+ "Right" => :right,
24
+ "LeftJustified" => :left,
25
+ "RightJustified" => :right,
26
+ "CenterJustified" => :center,
27
+ "FullyJustified" => :justified,
28
+ "ToBinding" => :left,
29
+ }.freeze
30
+
16
31
  def self.extract_runs(story)
17
32
  return [] unless story&.inner
18
33
 
@@ -33,11 +48,17 @@ module Idml
33
48
  fill_color: csr.fill_color,
34
49
  fill_tint: csr.fill_tint,
35
50
  applied_font: csr.applied_font,
51
+ alignment: alignment_for(csr),
36
52
  )
37
53
  end
38
54
  end
39
55
  private_class_method :csr_runs
40
56
 
57
+ def self.alignment_for(csr)
58
+ ALIGNMENT_MAP[csr.justification] || :left
59
+ end
60
+ private_class_method :alignment_for
61
+
41
62
  # Concatenate runs into a single block. Used when the renderer
42
63
  # can't handle per-run styling (e.g., no font metrics available).
43
64
  def self.concatenate(runs)
data/lib/idml/render.rb CHANGED
@@ -19,6 +19,11 @@ module Idml
19
19
  autoload :StructureTracker, "#{__dir__}/render/structure_tracker"
20
20
  autoload :StructureMapper, "#{__dir__}/render/structure_mapper"
21
21
  autoload :PdfaPacket, "#{__dir__}/render/pdfa_packet"
22
+ autoload :IccProfile, "#{__dir__}/render/icc_profile"
23
+ autoload :BookmarkResolver, "#{__dir__}/render/bookmark_resolver"
24
+ autoload :HyperlinkResolver, "#{__dir__}/render/hyperlink_resolver"
25
+ autoload :HyperlinkEmitter, "#{__dir__}/render/hyperlink_emitter"
26
+ autoload :MetadataBuilder, "#{__dir__}/render/metadata_builder"
22
27
  autoload :StoryThreader, "#{__dir__}/render/story_threader"
23
28
  autoload :PdfrbWriter, "#{__dir__}/render/pdfrb_writer"
24
29
  autoload :SpreadRenderer, "#{__dir__}/render/spread_renderer"
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.3.1"
4
+ VERSION = "0.4.1"
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.3.1
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
@@ -206,6 +206,10 @@ files:
206
206
  - TODO.pdf/77-pdfa-xmp-output-intent.md
207
207
  - TODO.pdf/78-hyperlinks.md
208
208
  - TODO.pdf/79-bookmarks-outline.md
209
+ - TODO.pdf/80-paragraph-alignment.md
210
+ - TODO.pdf/81-pdfa-icc-output-intent.md
211
+ - TODO.pdf/82-table-cell-text.md
212
+ - TODO.pdf/83-pipeline-decomposition.md
209
213
  - TODO.pdf/README.md
210
214
  - exe/idml
211
215
  - idml.gemspec
@@ -223,6 +227,7 @@ files:
223
227
  - lib/idml/elements/baseline_frame_grid_option.rb
224
228
  - lib/idml/elements/bevel_and_emboss_setting.rb
225
229
  - lib/idml/elements/blending_setting.rb
230
+ - lib/idml/elements/bookmark.rb
226
231
  - lib/idml/elements/cell_style.rb
227
232
  - lib/idml/elements/cell_style_group.rb
228
233
  - lib/idml/elements/character_style.rb
@@ -249,6 +254,10 @@ files:
249
254
  - lib/idml/elements/gradient_stop.rb
250
255
  - lib/idml/elements/graphic_line.rb
251
256
  - lib/idml/elements/group.rb
257
+ - lib/idml/elements/hyperlink.rb
258
+ - lib/idml/elements/hyperlink_page_destination.rb
259
+ - lib/idml/elements/hyperlink_text_source.rb
260
+ - lib/idml/elements/hyperlink_url_destination.rb
252
261
  - lib/idml/elements/image.rb
253
262
  - lib/idml/elements/ink.rb
254
263
  - lib/idml/elements/inner_glow_setting.rb
@@ -372,13 +381,18 @@ files:
372
381
  - lib/idml/parts/xmp.rb
373
382
  - lib/idml/render.rb
374
383
  - lib/idml/render/blending.rb
384
+ - lib/idml/render/bookmark_resolver.rb
375
385
  - lib/idml/render/color_helper.rb
376
386
  - lib/idml/render/color_resolver.rb
377
387
  - lib/idml/render/font_reference_resolver.rb
378
388
  - lib/idml/render/gradient_resolver.rb
389
+ - lib/idml/render/hyperlink_emitter.rb
390
+ - lib/idml/render/hyperlink_resolver.rb
391
+ - lib/idml/render/icc_profile.rb
379
392
  - lib/idml/render/image.rb
380
393
  - lib/idml/render/image_collector.rb
381
394
  - lib/idml/render/layer_filter.rb
395
+ - lib/idml/render/metadata_builder.rb
382
396
  - lib/idml/render/page_item_renderer.rb
383
397
  - lib/idml/render/pdfa_packet.rb
384
398
  - lib/idml/render/pdfrb_writer.rb