idml 0.2.6 → 0.2.8
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/52-font-subsetting.md +43 -50
- data/TODO.pdf/63-replace-fontmetrics-with-pdfrb.md +39 -52
- data/TODO.pdf/65-pdfrb-019-integration.md +23 -13
- data/TODO.pdf/67-text-rich-multi-run.md +18 -15
- data/TODO.pdf/70-stroke-styling.md +23 -51
- data/TODO.pdf/71-shared-placement-module.md +41 -0
- data/TODO.pdf/72-stroke-styling.md +55 -0
- data/TODO.pdf/73-gradient-resolver-cleanup.md +48 -0
- data/TODO.pdf/74-renderer-spec-coverage.md +53 -0
- data/TODO.pdf/75-pdf-metadata-from-xmp.md +103 -0
- data/TODO.pdf/76-tagged-pdf-structure.md +92 -0
- data/TODO.pdf/77-pdfa-xmp-output-intent.md +74 -0
- data/lib/idml/cli.rb +3 -0
- data/lib/idml/elements/graphic_line.rb +8 -0
- data/lib/idml/elements/polygon.rb +8 -0
- data/lib/idml/elements/rectangle.rb +8 -0
- data/lib/idml/render/gradient_resolver.rb +10 -102
- data/lib/idml/render/pdfrb_writer.rb +22 -16
- data/lib/idml/render/pipeline.rb +3 -1
- data/lib/idml/render/placement.rb +31 -0
- data/lib/idml/render/renderers/graphic_line_renderer.rb +9 -7
- data/lib/idml/render/renderers/polygon_renderer.rb +8 -6
- data/lib/idml/render/renderers/rectangle_renderer.rb +8 -19
- data/lib/idml/render/renderers/table_renderer.rb +1 -1
- data/lib/idml/render/renderers/text_frame_renderer.rb +1 -9
- data/lib/idml/render/stroke_style.rb +97 -0
- data/lib/idml/render.rb +10 -3
- data/lib/idml/version.rb +1 -1
- metadata +10 -1
|
@@ -9,7 +9,7 @@ module Idml
|
|
|
9
9
|
rect = context.item
|
|
10
10
|
return if rect.visible == false
|
|
11
11
|
|
|
12
|
-
box =
|
|
12
|
+
box = Placement.box(rect, context.page_height)
|
|
13
13
|
return unless box
|
|
14
14
|
|
|
15
15
|
Blending.wrap(canvas, rect.transparency_setting) do
|
|
@@ -18,13 +18,6 @@ module Idml
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def self.placement_box(rect, page_height)
|
|
22
|
-
bounds = rect.geometric_bounds
|
|
23
|
-
return nil unless bounds
|
|
24
|
-
|
|
25
|
-
Geometry.placement_rect(bounds, rect.item_transform, page_height)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
21
|
def self.render_fill(canvas, rect, context, box)
|
|
29
22
|
return unless rect.fill_color
|
|
30
23
|
return if rect.fill_color == "Color/None"
|
|
@@ -101,23 +94,19 @@ module Idml
|
|
|
101
94
|
private_class_method :gradient_stops
|
|
102
95
|
|
|
103
96
|
def self.render_stroke(canvas, rect, context, box)
|
|
104
|
-
return unless strokeable?(rect)
|
|
97
|
+
return unless StrokeStyle.strokeable?(rect)
|
|
105
98
|
|
|
106
99
|
color = context.color_resolver&.resolve(rect.stroke_color)
|
|
107
100
|
return unless color
|
|
108
101
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
StrokeStyle.apply(canvas, rect) do
|
|
103
|
+
canvas.stroke_color(ColorHelper.to_canvas(color))
|
|
104
|
+
canvas.line_width = rect.stroke_weight
|
|
105
|
+
canvas.rectangle(box[:x], box[:y], box[:width], box[:height])
|
|
106
|
+
canvas.stroke
|
|
107
|
+
end
|
|
113
108
|
end
|
|
114
109
|
private_class_method :render_stroke
|
|
115
|
-
|
|
116
|
-
def self.strokeable?(rect)
|
|
117
|
-
rect.stroke_color &&
|
|
118
|
-
rect.stroke_color != "Color/None" &&
|
|
119
|
-
rect.stroke_weight&.positive?
|
|
120
|
-
end
|
|
121
110
|
end
|
|
122
111
|
end
|
|
123
112
|
end
|
|
@@ -9,7 +9,7 @@ module Idml
|
|
|
9
9
|
return if table.visible == false
|
|
10
10
|
return if table.table_row.empty?
|
|
11
11
|
|
|
12
|
-
box =
|
|
12
|
+
box = Placement.box(table, context.page_height)
|
|
13
13
|
return unless box
|
|
14
14
|
|
|
15
15
|
row_count = table.table_row.length
|
|
@@ -43,15 +43,7 @@ module Idml
|
|
|
43
43
|
private_class_method :chain_head?
|
|
44
44
|
|
|
45
45
|
def self.frame_box(frame, page_height)
|
|
46
|
-
|
|
47
|
-
unless bounds
|
|
48
|
-
return { x: 72.0, y: page_height - 72.0, width: 400.0,
|
|
49
|
-
height: 600.0 }
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
transform = Geometry.parse_transform(frame.item_transform)
|
|
53
|
-
transformed = Geometry.transform_bounds(bounds, transform)
|
|
54
|
-
Geometry.bounds_to_pdf_rect(transformed, page_height)
|
|
46
|
+
Placement.box(frame, page_height, fallback: true)
|
|
55
47
|
end
|
|
56
48
|
private_class_method :frame_box
|
|
57
49
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Idml
|
|
4
|
+
module Render
|
|
5
|
+
# Maps IDML stroke-style attributes on a page item to the four
|
|
6
|
+
# pdfrb Canvas setters that control PDF stroke rendering:
|
|
7
|
+
# `line_cap=`, `line_join=`, `miter_limit=`, `dash_pattern=`.
|
|
8
|
+
#
|
|
9
|
+
# IDML → PDF enum mapping per PDF 32000-1 §8.4.3:
|
|
10
|
+
#
|
|
11
|
+
# EndCap → LineCap
|
|
12
|
+
# ButtEndCap → 0
|
|
13
|
+
# RoundEndCap → 1
|
|
14
|
+
# ProjectingEndCap → 2
|
|
15
|
+
#
|
|
16
|
+
# EndJoin → LineJoin
|
|
17
|
+
# MiterEndJoin → 0
|
|
18
|
+
# RoundEndJoin → 1
|
|
19
|
+
# BevelEndJoin → 2
|
|
20
|
+
#
|
|
21
|
+
# `StrokeDashAndGap` is a flat list `[d1, g1, d2, g2, ...]` — pdfrb
|
|
22
|
+
# accepts the same shape as `dash_pattern=[array, phase]`.
|
|
23
|
+
module StrokeStyle
|
|
24
|
+
CAP_MAP = {
|
|
25
|
+
"ButtEndCap" => 0,
|
|
26
|
+
"RoundEndCap" => 1,
|
|
27
|
+
"ProjectingEndCap" => 2,
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
JOIN_MAP = {
|
|
31
|
+
"MiterEndJoin" => 0,
|
|
32
|
+
"RoundEndJoin" => 1,
|
|
33
|
+
"BevelEndJoin" => 2,
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
# True when the item has a renderable stroke: a non-None stroke
|
|
37
|
+
# color and a positive stroke weight.
|
|
38
|
+
def self.strokeable?(item)
|
|
39
|
+
!!(item.stroke_color &&
|
|
40
|
+
item.stroke_color != "Color/None" &&
|
|
41
|
+
item.stroke_weight&.positive?)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Apply stroke-style settings from `item` to `canvas` inside a
|
|
45
|
+
# saved graphics state, then yield so the caller can emit the
|
|
46
|
+
# path and call `canvas.stroke`. The save/restore ensures
|
|
47
|
+
# cap/join/miter/dash settings don't bleed into subsequent
|
|
48
|
+
# strokes on the same page.
|
|
49
|
+
def self.apply(canvas, item)
|
|
50
|
+
canvas.save_graphics_state do
|
|
51
|
+
set_cap(canvas, item.end_cap)
|
|
52
|
+
set_join(canvas, item.end_join)
|
|
53
|
+
set_miter(canvas, item.miter_limit)
|
|
54
|
+
set_dash(canvas, item.stroke_dash_and_gap)
|
|
55
|
+
yield
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.set_cap(canvas, raw)
|
|
60
|
+
code = CAP_MAP[raw]
|
|
61
|
+
canvas.line_cap = code if code
|
|
62
|
+
end
|
|
63
|
+
private_class_method :set_cap
|
|
64
|
+
|
|
65
|
+
def self.set_join(canvas, raw)
|
|
66
|
+
code = JOIN_MAP[raw]
|
|
67
|
+
canvas.line_join = code if code
|
|
68
|
+
end
|
|
69
|
+
private_class_method :set_join
|
|
70
|
+
|
|
71
|
+
def self.set_miter(canvas, raw)
|
|
72
|
+
return unless raw
|
|
73
|
+
|
|
74
|
+
value = raw.to_f
|
|
75
|
+
return unless value >= 1.0
|
|
76
|
+
|
|
77
|
+
canvas.miter_limit = value
|
|
78
|
+
end
|
|
79
|
+
private_class_method :set_miter
|
|
80
|
+
|
|
81
|
+
def self.set_dash(canvas, raw)
|
|
82
|
+
return unless raw
|
|
83
|
+
|
|
84
|
+
array = parse_dash_array(raw)
|
|
85
|
+
return unless array.length >= 2
|
|
86
|
+
|
|
87
|
+
canvas.dash_pattern = [array, 0]
|
|
88
|
+
end
|
|
89
|
+
private_class_method :set_dash
|
|
90
|
+
|
|
91
|
+
def self.parse_dash_array(raw)
|
|
92
|
+
raw.to_s.split(/\s+/).map(&:to_f)
|
|
93
|
+
end
|
|
94
|
+
private_class_method :parse_dash_array
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/idml/render.rb
CHANGED
|
@@ -12,7 +12,9 @@ module Idml
|
|
|
12
12
|
"#{__dir__}/render/font_reference_resolver"
|
|
13
13
|
autoload :GradientResolver, "#{__dir__}/render/gradient_resolver"
|
|
14
14
|
autoload :Blending, "#{__dir__}/render/blending"
|
|
15
|
+
autoload :StrokeStyle, "#{__dir__}/render/stroke_style"
|
|
15
16
|
autoload :LayerFilter, "#{__dir__}/render/layer_filter"
|
|
17
|
+
autoload :Placement, "#{__dir__}/render/placement"
|
|
16
18
|
autoload :StoryThreader, "#{__dir__}/render/story_threader"
|
|
17
19
|
autoload :PdfrbWriter, "#{__dir__}/render/pdfrb_writer"
|
|
18
20
|
autoload :SpreadRenderer, "#{__dir__}/render/spread_renderer"
|
|
@@ -23,11 +25,16 @@ module Idml
|
|
|
23
25
|
|
|
24
26
|
DEFAULT_FONT = "Helvetica"
|
|
25
27
|
|
|
28
|
+
# Render an IDML package to a PDF file. All options except
|
|
29
|
+
# `package:` and `to:` are keyword-only and optional.
|
|
30
|
+
# rubocop:disable Metrics/ParameterLists
|
|
26
31
|
def self.render(package:, to:, font_search_paths: nil, compliance: nil,
|
|
27
|
-
tagged: false)
|
|
28
|
-
Pipeline.new(package, to, font_search_paths,
|
|
29
|
-
|
|
32
|
+
tagged: false, subset_fonts: true)
|
|
33
|
+
Pipeline.new(package, to, font_search_paths,
|
|
34
|
+
compliance: compliance, tagged: tagged,
|
|
35
|
+
subset_fonts: subset_fonts).call
|
|
30
36
|
end
|
|
37
|
+
# rubocop:enable Metrics/ParameterLists
|
|
31
38
|
end
|
|
32
39
|
end
|
|
33
40
|
|
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.2.
|
|
4
|
+
version: 0.2.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -211,6 +211,13 @@ files:
|
|
|
211
211
|
- TODO.pdf/68-radial-gradient-shadings.md
|
|
212
212
|
- TODO.pdf/69-transparency-blend-modes.md
|
|
213
213
|
- TODO.pdf/70-stroke-styling.md
|
|
214
|
+
- TODO.pdf/71-shared-placement-module.md
|
|
215
|
+
- TODO.pdf/72-stroke-styling.md
|
|
216
|
+
- TODO.pdf/73-gradient-resolver-cleanup.md
|
|
217
|
+
- TODO.pdf/74-renderer-spec-coverage.md
|
|
218
|
+
- TODO.pdf/75-pdf-metadata-from-xmp.md
|
|
219
|
+
- TODO.pdf/76-tagged-pdf-structure.md
|
|
220
|
+
- TODO.pdf/77-pdfa-xmp-output-intent.md
|
|
214
221
|
- TODO.pdf/README.md
|
|
215
222
|
- exe/idml
|
|
216
223
|
- idml.gemspec
|
|
@@ -385,6 +392,7 @@ files:
|
|
|
385
392
|
- lib/idml/render/page_item_renderer.rb
|
|
386
393
|
- lib/idml/render/pdfrb_writer.rb
|
|
387
394
|
- lib/idml/render/pipeline.rb
|
|
395
|
+
- lib/idml/render/placement.rb
|
|
388
396
|
- lib/idml/render/render_context.rb
|
|
389
397
|
- lib/idml/render/renderers.rb
|
|
390
398
|
- lib/idml/render/renderers/graphic_line_renderer.rb
|
|
@@ -395,6 +403,7 @@ files:
|
|
|
395
403
|
- lib/idml/render/renderers/text_frame_renderer.rb
|
|
396
404
|
- lib/idml/render/spread_renderer.rb
|
|
397
405
|
- lib/idml/render/story_threader.rb
|
|
406
|
+
- lib/idml/render/stroke_style.rb
|
|
398
407
|
- lib/idml/render/style_resolver.rb
|
|
399
408
|
- lib/idml/text_engine.rb
|
|
400
409
|
- lib/idml/text_engine/cjk_layout.rb
|