idml 0.8.6 → 0.8.7
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/114-text-wrap-around-shapes.md +15 -7
- data/lib/idml/elements/graphic_line.rb +2 -0
- data/lib/idml/elements/oval.rb +2 -0
- data/lib/idml/elements/path.rb +2 -0
- data/lib/idml/elements/polygon.rb +2 -0
- data/lib/idml/render/render_context.rb +1 -0
- data/lib/idml/render/renderers/text_frame_renderer.rb +23 -0
- data/lib/idml/render/spread_renderer.rb +5 -0
- data/lib/idml/render/text_wrap_resolver.rb +22 -3
- data/lib/idml/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea725628da813f202ff5f6c8c9659e1de20b24d8eb9d92c6cd8cc43aad12948c
|
|
4
|
+
data.tar.gz: 3ae66c7b8c22ba9660da4a8bae4a8f2314cb13e90aa72f0c673350415ab77cfc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e6ec5c19fb106644c373ee8a3cd21526cfaff1ce88c7d56d7c65b6376fe508ba984203d2d7d7249d426fc9486d21f5d7dbc1f758c026dd6f60c923631e31a4d8
|
|
7
|
+
data.tar.gz: 82cd84ff102aafce7c0766e1bb3aea5393a20f4d959753273ad163f15a9b83ab22a323c8b369548b45a3cc6d3e0ec5857eac1663ccdb601e9adb093c7067121e
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# TODO PDF 114: Text wrap around shapes (TextWrapPreference)
|
|
2
2
|
|
|
3
|
-
## Status:
|
|
4
|
-
contours from page items declaring TextWrapPreference
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
## Status: DONE for BoundingBox mode — `Render::TextWrapResolver` computes
|
|
4
|
+
wrap contours from page items declaring TextWrapPreference with
|
|
5
|
+
TextWrapMode != "None". SpreadRenderer builds the resolver and passes
|
|
6
|
+
it via RenderContext. TextFrameRenderer's `text_wrap_overlap` queries
|
|
7
|
+
overlap at each run's y position and reduces the wrap width — text
|
|
8
|
+
flows around the shape instead of running over it.
|
|
9
|
+
|
|
10
|
+
Shape page items (Rectangle, Oval, Polygon, GraphicLine, Path) all
|
|
11
|
+
carry the TextWrapPreference child element. Non-shape items (Page,
|
|
12
|
+
Link) are filtered by WRAPPABLE_TYPES to avoid NoMethodError.
|
|
13
|
+
|
|
14
|
+
Per-run approximation: all lines in a run get the same reduced width.
|
|
15
|
+
True per-line adjustment (when a run spans the contour boundary)
|
|
16
|
+
requires line-count-aware layout. Shape mode (contour following) and
|
|
17
|
+
Inverse mode remain unsupported.
|
|
10
18
|
|
|
11
19
|
## Problem
|
|
12
20
|
|
|
@@ -18,6 +18,7 @@ module Idml
|
|
|
18
18
|
attribute :item_layer, :string
|
|
19
19
|
attribute :properties, Idml::Elements::Properties, collection: true
|
|
20
20
|
attribute :transparency_setting, Idml::Elements::TransparencySetting
|
|
21
|
+
attribute :text_wrap_preference, Idml::Elements::TextWrapPreference
|
|
21
22
|
|
|
22
23
|
xml do
|
|
23
24
|
root "GraphicLine"
|
|
@@ -34,6 +35,7 @@ module Idml
|
|
|
34
35
|
map_attribute "ItemLayer", to: :item_layer
|
|
35
36
|
map_element "Properties", to: :properties
|
|
36
37
|
map_element "TransparencySetting", to: :transparency_setting
|
|
38
|
+
map_element "TextWrapPreference", to: :text_wrap_preference
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def geometric_bounds
|
data/lib/idml/elements/oval.rb
CHANGED
|
@@ -29,6 +29,7 @@ module Idml
|
|
|
29
29
|
attribute :item_layer, :string
|
|
30
30
|
attribute :properties, Idml::Elements::Properties, collection: true
|
|
31
31
|
attribute :transparency_setting, Idml::Elements::TransparencySetting
|
|
32
|
+
attribute :text_wrap_preference, Idml::Elements::TextWrapPreference
|
|
32
33
|
attribute :image, Idml::Elements::Image, collection: true
|
|
33
34
|
|
|
34
35
|
xml do
|
|
@@ -50,6 +51,7 @@ module Idml
|
|
|
50
51
|
map_attribute "ItemLayer", to: :item_layer
|
|
51
52
|
map_element "Properties", to: :properties
|
|
52
53
|
map_element "TransparencySetting", to: :transparency_setting
|
|
54
|
+
map_element "TextWrapPreference", to: :text_wrap_preference
|
|
53
55
|
map_element "Image", to: :image
|
|
54
56
|
end
|
|
55
57
|
|
data/lib/idml/elements/path.rb
CHANGED
|
@@ -25,6 +25,7 @@ module Idml
|
|
|
25
25
|
attribute :item_layer, :string
|
|
26
26
|
attribute :properties, Idml::Elements::Properties, collection: true
|
|
27
27
|
attribute :transparency_setting, Idml::Elements::TransparencySetting
|
|
28
|
+
attribute :text_wrap_preference, Idml::Elements::TextWrapPreference
|
|
28
29
|
|
|
29
30
|
xml do
|
|
30
31
|
root "Path"
|
|
@@ -41,6 +42,7 @@ module Idml
|
|
|
41
42
|
map_attribute "ItemLayer", to: :item_layer
|
|
42
43
|
map_element "Properties", to: :properties
|
|
43
44
|
map_element "TransparencySetting", to: :transparency_setting
|
|
45
|
+
map_element "TextWrapPreference", to: :text_wrap_preference
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def geometric_bounds
|
|
@@ -20,6 +20,7 @@ module Idml
|
|
|
20
20
|
attribute :item_layer, :string
|
|
21
21
|
attribute :properties, Idml::Elements::Properties, collection: true
|
|
22
22
|
attribute :transparency_setting, Idml::Elements::TransparencySetting
|
|
23
|
+
attribute :text_wrap_preference, Idml::Elements::TextWrapPreference
|
|
23
24
|
attribute :image, Idml::Elements::Image, collection: true
|
|
24
25
|
|
|
25
26
|
xml do
|
|
@@ -39,6 +40,7 @@ module Idml
|
|
|
39
40
|
map_attribute "ItemLayer", to: :item_layer
|
|
40
41
|
map_element "Properties", to: :properties
|
|
41
42
|
map_element "TransparencySetting", to: :transparency_setting
|
|
43
|
+
map_element "TextWrapPreference", to: :text_wrap_preference
|
|
42
44
|
map_element "Image", to: :image
|
|
43
45
|
end
|
|
44
46
|
|
|
@@ -436,6 +436,8 @@ module Idml
|
|
|
436
436
|
rendered_count)
|
|
437
437
|
run_wrap = drop_cap_wrap_width(wrap_width, dc_width,
|
|
438
438
|
dc_lines, rendered_count)
|
|
439
|
+
run_wrap -= text_wrap_overlap(context, layout_frame, cursor_y,
|
|
440
|
+
run)
|
|
439
441
|
positioned, next_y = layout_run(
|
|
440
442
|
canvas, run, paragraph, context, layout_frame, font,
|
|
441
443
|
run_wrap, cursor_y, space_before,
|
|
@@ -450,6 +452,27 @@ module Idml
|
|
|
450
452
|
end
|
|
451
453
|
private_class_method :iterate_paragraph_runs
|
|
452
454
|
|
|
455
|
+
# Computes the text-wrap overlap for a run at its current y
|
|
456
|
+
# position. Uses the run's point_size as the line height
|
|
457
|
+
# approximation. Returns 0.0 when no resolver is wired or no
|
|
458
|
+
# contours overlap. Per-run approximation: all lines in the
|
|
459
|
+
# run get the same reduced width (correct when the run is
|
|
460
|
+
# fully inside or outside the contour; approximate when it
|
|
461
|
+
# spans the boundary).
|
|
462
|
+
def self.text_wrap_overlap(context, layout_frame, cursor_y, run)
|
|
463
|
+
resolver = context.text_wrap_resolver
|
|
464
|
+
return 0.0 unless resolver
|
|
465
|
+
|
|
466
|
+
size = run.point_size || DEFAULT_SIZE
|
|
467
|
+
frame_x = layout_frame.x + (layout_frame.inset_left || 0)
|
|
468
|
+
frame_right = layout_frame.x + layout_frame.width -
|
|
469
|
+
(layout_frame.inset_right || 0)
|
|
470
|
+
overlap = resolver.overlap_width(cursor_y, size,
|
|
471
|
+
frame_x, frame_right)
|
|
472
|
+
[overlap, 0.0].max
|
|
473
|
+
end
|
|
474
|
+
private_class_method :text_wrap_overlap
|
|
475
|
+
|
|
453
476
|
# Strips drop cap characters from the first run so they don't
|
|
454
477
|
# render twice (once as the enlarged drop cap, once as normal
|
|
455
478
|
# text). Returns a new run list with the first run's text
|
|
@@ -39,6 +39,7 @@ module Idml
|
|
|
39
39
|
chain_controller: StoryChainController.new,
|
|
40
40
|
condition_filter: @condition_filter,
|
|
41
41
|
style_lookup: @style_lookup,
|
|
42
|
+
text_wrap_resolver: build_text_wrap_resolver(spread, page_height),
|
|
42
43
|
}
|
|
43
44
|
images_by_parent = group_images_by_parent(image_refs)
|
|
44
45
|
|
|
@@ -144,6 +145,10 @@ module Idml
|
|
|
144
145
|
|
|
145
146
|
ColorResolver.new(@package.graphic)
|
|
146
147
|
end
|
|
148
|
+
|
|
149
|
+
def build_text_wrap_resolver(spread, page_height)
|
|
150
|
+
TextWrapResolver.build(spread, page_height: page_height)
|
|
151
|
+
end
|
|
147
152
|
end
|
|
148
153
|
end
|
|
149
154
|
end
|
|
@@ -66,16 +66,35 @@ module Idml
|
|
|
66
66
|
end
|
|
67
67
|
private_class_method :contour_for
|
|
68
68
|
|
|
69
|
+
# Page item types that can declare TextWrapPreference per the
|
|
70
|
+
# Spread schema. Used to guard the attribute read — querying
|
|
71
|
+
# non-shape items (Page, Link) would raise NoMethodError.
|
|
72
|
+
WRAPPABLE_TYPES = [
|
|
73
|
+
Idml::Elements::Rectangle,
|
|
74
|
+
Idml::Elements::Oval,
|
|
75
|
+
Idml::Elements::Polygon,
|
|
76
|
+
Idml::Elements::GraphicLine,
|
|
77
|
+
Idml::Elements::Path,
|
|
78
|
+
Idml::Elements::Group,
|
|
79
|
+
].freeze
|
|
80
|
+
|
|
69
81
|
def self.wrap_preference(item)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
return nil unless wrappable?(item)
|
|
83
|
+
|
|
84
|
+
pref = item.text_wrap_preference
|
|
85
|
+
return nil if pref.nil? ||
|
|
86
|
+
pref.text_wrap_mode.nil? ||
|
|
73
87
|
pref.text_wrap_mode == "None"
|
|
74
88
|
|
|
75
89
|
pref
|
|
76
90
|
end
|
|
77
91
|
private_class_method :wrap_preference
|
|
78
92
|
|
|
93
|
+
def self.wrappable?(item)
|
|
94
|
+
WRAPPABLE_TYPES.any? { |type| item.is_a?(type) }
|
|
95
|
+
end
|
|
96
|
+
private_class_method :wrappable?
|
|
97
|
+
|
|
79
98
|
def self.bounding_box_mode?(pref)
|
|
80
99
|
pref.text_wrap_mode == "BoundingBox"
|
|
81
100
|
end
|
data/lib/idml/version.rb
CHANGED