ea 0.6.139 → 0.6.141
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/lib/ea/cli/app.rb +10 -0
- data/lib/ea/cli/command/diagrams.rb +4 -1
- data/lib/ea/cli/command/render.rb +8 -1
- data/lib/ea/cli/command/spa.rb +2 -1
- data/lib/ea/cli/command/svg.rb +9 -6
- data/lib/ea/fonts/metrics.rb +54 -6
- data/lib/ea/model/note.rb +2 -0
- data/lib/ea/sources/qea/diagram_builder/routing.rb +188 -8
- data/lib/ea/sources/qea/diagram_builder.rb +14 -1
- data/lib/ea/sources/qea/note_builder.rb +7 -1
- data/lib/ea/sources/xmi/diagram_builder/element_borders.rb +27 -0
- data/lib/ea/sources/xmi/diagram_builder.rb +58 -15
- data/lib/ea/sources/xmi/extension_style_parser.rb +1 -1
- data/lib/ea/sources/xmi/note_builder.rb +2 -1
- data/lib/ea/sources/xmi/stored_route/reversed_routes.rb +78 -0
- data/lib/ea/sources/xmi/stored_route.rb +83 -6
- data/lib/ea/spa/generator.rb +4 -2
- data/lib/ea/spa/projector.rb +4 -2
- data/lib/ea/svg/ea_emitter/bottom_margin.rb +104 -0
- data/lib/ea/svg/ea_emitter/bounds_calculator.rb +25 -15
- data/lib/ea/svg/ea_emitter/canvas.rb +80 -14
- data/lib/ea/svg/ea_emitter/canvas_anchor.rb +132 -0
- data/lib/ea/svg/ea_emitter/compartment/attributes.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/constraints.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/header.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/marker.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/note_body.rb +11 -2
- data/lib/ea/svg/ea_emitter/compartment/note_text.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/operations.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +34 -4
- data/lib/ea/svg/ea_emitter/compartment/shape.rb +30 -5
- data/lib/ea/svg/ea_emitter/compartment/stereotype_icon.rb +6 -0
- data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +5 -0
- data/lib/ea/svg/ea_emitter/compartment.rb +13 -0
- data/lib/ea/svg/ea_emitter/connector_bridges.rb +117 -29
- data/lib/ea/svg/ea_emitter/connectors.rb +67 -17
- data/lib/ea/svg/ea_emitter/content_extent.rb +104 -0
- data/lib/ea/svg/ea_emitter/diagram_frame.rb +7 -0
- data/lib/ea/svg/ea_emitter/document.rb +76 -31
- data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +22 -10
- data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +57 -32
- data/lib/ea/svg/ea_emitter/elements.rb +24 -5
- data/lib/ea/svg/ea_emitter/font_resolver.rb +3 -1
- data/lib/ea/svg/ea_emitter/label/end_label.rb +134 -14
- data/lib/ea/svg/ea_emitter/labels.rb +16 -3
- data/lib/ea/svg/ea_emitter/layer_sequencer.rb +54 -33
- data/lib/ea/svg/ea_emitter/markers.rb +22 -10
- data/lib/ea/svg/ea_emitter/paint_order.rb +30 -0
- data/lib/ea/svg/ea_emitter/pen.rb +19 -0
- data/lib/ea/svg/ea_emitter/render_context.rb +14 -3
- data/lib/ea/svg/ea_emitter/text_renderer.rb +24 -8
- data/lib/ea/svg/ea_emitter.rb +5 -0
- data/lib/ea/svg/parity/source.rb +1 -1
- data/lib/ea/version.rb +1 -1
- metadata +9 -2
|
@@ -52,17 +52,28 @@ module Ea
|
|
|
52
52
|
entries = visible_connectors.flat_map { |c| entries_for(c) }
|
|
53
53
|
|
|
54
54
|
if grouped
|
|
55
|
-
entries.group_by { |e| [e.style_key, e.stroke_width] }.map do |(key, width), grouped_entries|
|
|
55
|
+
entries.group_by { |e| [e.style_key, e.stroke_width, e.stroke_color] }.map do |(key, width, color), grouped_entries|
|
|
56
56
|
# EA emits ONE marker per connector regardless of
|
|
57
57
|
# anchor overlap. Verified against plateau Bridge
|
|
58
58
|
# diagram: 9 generalizations fanning from the same
|
|
59
59
|
# parent anchor produce 9 distinct triangle polygons
|
|
60
60
|
# at the same coordinates. The earlier "dedup by
|
|
61
61
|
# anchor" hypothesis is disproven by reference SVGs.
|
|
62
|
-
marker_layer(key, width, grouped_entries.map(&:body).join("\n "))
|
|
62
|
+
marker_layer(key, width, color, grouped_entries.map(&:body).join("\n "))
|
|
63
63
|
end
|
|
64
64
|
else
|
|
65
|
-
entries.map { |e| marker_layer(e.style_key, e.stroke_width, e.body) }
|
|
65
|
+
entries.map { |e| marker_layer(e.style_key, e.stroke_width, e.stroke_color, e.body) }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# One `[connector, Layer]` pair per marker, in diagram link
|
|
70
|
+
# order, so the sequencer can paint each connector's heads right
|
|
71
|
+
# after its line like EA does.
|
|
72
|
+
def connector_layers
|
|
73
|
+
visible_connectors.flat_map do |connector|
|
|
74
|
+
entries_for(connector).map do |e|
|
|
75
|
+
[connector, marker_layer(e.style_key, e.stroke_width, e.stroke_color, e.body)]
|
|
76
|
+
end
|
|
66
77
|
end
|
|
67
78
|
end
|
|
68
79
|
|
|
@@ -86,7 +97,7 @@ module Ea
|
|
|
86
97
|
# drives dedup — EA emits one marker per connector.
|
|
87
98
|
Entry = Struct.new(:style_key, :body, :anchor,
|
|
88
99
|
:connector_waypoint_count, :stroke_width,
|
|
89
|
-
keyword_init: true) do
|
|
100
|
+
:stroke_color, keyword_init: true) do
|
|
90
101
|
def hash
|
|
91
102
|
anchor.hash
|
|
92
103
|
end
|
|
@@ -140,18 +151,18 @@ module Ea
|
|
|
140
151
|
connector_line: { fill: "#000000", opacity: "0.00" }
|
|
141
152
|
}.freeze
|
|
142
153
|
|
|
143
|
-
def marker_layer(key, width, body)
|
|
144
|
-
Layer.new(style_key: Connectors.layer_key(key, width, stroke_width),
|
|
145
|
-
style: style_for(key, width), body: body)
|
|
154
|
+
def marker_layer(key, width, color, body)
|
|
155
|
+
Layer.new(style_key: Connectors.layer_key(key, width, stroke_width, color),
|
|
156
|
+
style: style_for(key, width, color), body: body)
|
|
146
157
|
end
|
|
147
158
|
|
|
148
|
-
def style_for(key, width = stroke_width)
|
|
159
|
+
def style_for(key, width = stroke_width, color = Connectors::DEFAULT_STROKE)
|
|
149
160
|
spec = STYLE_MAP[key]
|
|
150
161
|
return nil unless spec
|
|
151
162
|
|
|
152
163
|
"stroke-width:#{width};stroke-linecap:round;stroke-linejoin:bevel; " \
|
|
153
164
|
"fill:#{spec[:fill]};fill-opacity:#{spec[:opacity]}; " \
|
|
154
|
-
"stroke:#
|
|
165
|
+
"stroke:#{color}; stroke-opacity:1.00"
|
|
155
166
|
end
|
|
156
167
|
|
|
157
168
|
def visible_connectors
|
|
@@ -171,7 +182,8 @@ module Ea
|
|
|
171
182
|
body: body,
|
|
172
183
|
anchor: anchor_for(spec),
|
|
173
184
|
connector_waypoint_count: waypoint_count,
|
|
174
|
-
stroke_width: Connectors.stroke_width_for(connector, stroke_width)
|
|
185
|
+
stroke_width: Connectors.stroke_width_for(connector, stroke_width),
|
|
186
|
+
stroke_color: Connectors.stroke_color_for(connector))
|
|
175
187
|
end
|
|
176
188
|
end
|
|
177
189
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
module EaEmitter
|
|
6
|
+
# EA paints connectors (each line followed by its heads) ordered by the
|
|
7
|
+
# start element's placement row, then the connector id: the
|
|
8
|
+
# `paint_order` key the diagram builders store. Verified without a
|
|
9
|
+
# single inversion over 12785 connector pairs of the QEA corpus.
|
|
10
|
+
# Connectors with an unresolvable key (empty, or with a nil part)
|
|
11
|
+
# follow the keyed ones, and phantoms (no stored key) come last, each
|
|
12
|
+
# in link order.
|
|
13
|
+
module PaintOrder
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def connectors(diagram)
|
|
17
|
+
(diagram.connectors || []).each_with_index.sort_by do |connector, index|
|
|
18
|
+
order = connector.paint_order
|
|
19
|
+
rank = if order.nil?
|
|
20
|
+
2
|
|
21
|
+
else
|
|
22
|
+
order.empty? || order.any?(&:nil?) ? 1 : 0
|
|
23
|
+
end
|
|
24
|
+
[rank, rank.zero? ? order : [], index]
|
|
25
|
+
end.map(&:first)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ea
|
|
4
|
+
module Svg
|
|
5
|
+
module EaEmitter
|
|
6
|
+
# The [cap, join] stroke pen a drawing leaves behind. EA never sets a
|
|
7
|
+
# pen on notes and legends: they take whatever the previous drawing
|
|
8
|
+
# left, so the emitter threads the pen from one element to the next.
|
|
9
|
+
module Pen
|
|
10
|
+
ROUND_BEVEL = %w[round bevel].freeze
|
|
11
|
+
SQUARE_BEVEL = %w[square bevel].freeze
|
|
12
|
+
SQUARE_MITER = %w[square miter].freeze
|
|
13
|
+
|
|
14
|
+
# The pen in force when nothing has been drawn yet.
|
|
15
|
+
INITIAL = SQUARE_MITER
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -19,7 +19,7 @@ module Ea
|
|
|
19
19
|
:enum_literals, :tagged_values, :constraints, :marker_lines,
|
|
20
20
|
:package_content_lines,
|
|
21
21
|
:geometry, :theme, :canvas, :diagram, :model_index,
|
|
22
|
-
:off_canvas_parent_name,
|
|
22
|
+
:off_canvas_parent_name, :previous_pen,
|
|
23
23
|
keyword_init: true
|
|
24
24
|
)
|
|
25
25
|
def note_body
|
|
@@ -57,11 +57,22 @@ module Ea
|
|
|
57
57
|
# roles; the XMI reads them as ownedAttribute), so a class whose
|
|
58
58
|
# only properties are association ends has no feature compartment
|
|
59
59
|
# and no divider (A59065AF urf::Administration).
|
|
60
|
+
#
|
|
61
|
+
# A diagram that suppresses a whole feature kind (Style
|
|
62
|
+
# HideAtts=1 / HideOps=1) has no such compartment to draw, so
|
|
63
|
+
# that kind never earns a divider: 4881CEEE (HideAtts=1 and
|
|
64
|
+
# HideOps=1) draws none over classes that own attributes,
|
|
65
|
+
# 8FD488EF likewise. Per-attribute visibility toggles are a
|
|
66
|
+
# different mechanism and keep the divider (10E3E08A).
|
|
60
67
|
def hidden_features_present?
|
|
61
68
|
return false unless classifier.respond_to?(:properties)
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
config = diagram&.display_config
|
|
71
|
+
shows_attributes = config.nil? || config.show_attributes?
|
|
72
|
+
shows_operations = config.nil? || config.show_operations?
|
|
73
|
+
|
|
74
|
+
(shows_attributes && classifier.properties.any? { |property| !property.association_id }) ||
|
|
75
|
+
(shows_operations && classifier.operations.any?)
|
|
65
76
|
end
|
|
66
77
|
end
|
|
67
78
|
end
|
|
@@ -24,14 +24,15 @@ module Ea
|
|
|
24
24
|
|
|
25
25
|
attr_reader :content, :x, :y, :family, :size, :weight, :style,
|
|
26
26
|
:fill, :text_length, :rotation, :size_unit,
|
|
27
|
-
:stroke_in_text, :width_factor, :logical_height
|
|
27
|
+
:stroke_in_text, :width_factor, :logical_height, :legend_title
|
|
28
28
|
|
|
29
29
|
def initialize(content:, x:, y:, family:, size:, weight: 400,
|
|
30
30
|
style: "normal", fill: DEFAULT_FILL,
|
|
31
31
|
text_length: nil, rotation: DEFAULT_ROTATION,
|
|
32
32
|
size_unit: "px", logical_height: nil,
|
|
33
33
|
stroke_in_text: DEFAULT_STROKE_IN_TEXT,
|
|
34
|
-
width_factor: DEFAULT_WIDTH_FACTOR)
|
|
34
|
+
width_factor: DEFAULT_WIDTH_FACTOR, legend_title: false)
|
|
35
|
+
@legend_title = legend_title
|
|
35
36
|
@content = content.to_s
|
|
36
37
|
@x = x
|
|
37
38
|
@y = y
|
|
@@ -155,23 +156,38 @@ module Ea
|
|
|
155
156
|
GLYPH_FALLBACK = 0.61
|
|
156
157
|
|
|
157
158
|
def self.estimate_width(text, size, _width_factor = nil, family: nil,
|
|
158
|
-
weight: nil, style: nil, logical_height: nil
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
weight: nil, style: nil, logical_height: nil,
|
|
160
|
+
legend_title: false)
|
|
161
|
+
opts = { family: family, weight: weight, style: style,
|
|
162
|
+
logical_height: logical_height, legend_title: legend_title }
|
|
163
|
+
real = Ea::Fonts::Metrics.text_length(text, size, **opts)
|
|
162
164
|
return real if real
|
|
165
|
+
return piecewise_width(text, size, opts) if Ea::Fonts::Metrics.piecewise_family?(family, size)
|
|
163
166
|
|
|
167
|
+
text.to_s.each_char.sum { |ch| glyph_estimate(ch, size) }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# A Cambria run outside 7pt that is not wholly in the measured
|
|
171
|
+
# table: table characters are exact, the rest are estimated one
|
|
172
|
+
# at a time with the glyph fallback, so the
|
|
173
|
+
# width never shrinks when a character is appended.
|
|
174
|
+
def self.piecewise_width(text, size, opts)
|
|
164
175
|
text.to_s.each_char.sum do |ch|
|
|
165
|
-
(
|
|
176
|
+
Ea::Fonts::Metrics.text_length(ch, size, **opts) || glyph_estimate(ch, size)
|
|
166
177
|
end
|
|
167
178
|
end
|
|
168
179
|
|
|
180
|
+
def self.glyph_estimate(char, size)
|
|
181
|
+
(GLYPH_WIDTHS[char] || GLYPH_FALLBACK) * size.to_f
|
|
182
|
+
end
|
|
183
|
+
|
|
169
184
|
def formatted_text_length
|
|
170
185
|
return text_length.to_i.to_s if text_length
|
|
171
186
|
|
|
172
187
|
width = self.class.estimate_width(content, size, width_factor,
|
|
173
188
|
family: family, weight: weight,
|
|
174
|
-
style: style, logical_height: logical_height
|
|
189
|
+
style: style, logical_height: logical_height,
|
|
190
|
+
legend_title: legend_title)
|
|
175
191
|
width.round.to_s
|
|
176
192
|
end
|
|
177
193
|
|
data/lib/ea/svg/ea_emitter.rb
CHANGED
|
@@ -26,10 +26,15 @@ module Ea
|
|
|
26
26
|
#
|
|
27
27
|
module EaEmitter
|
|
28
28
|
autoload :Canvas, "ea/svg/ea_emitter/canvas"
|
|
29
|
+
autoload :CanvasAnchor, "ea/svg/ea_emitter/canvas_anchor"
|
|
30
|
+
autoload :BottomMargin, "ea/svg/ea_emitter/bottom_margin"
|
|
31
|
+
autoload :ContentExtent, "ea/svg/ea_emitter/content_extent"
|
|
29
32
|
autoload :Background, "ea/svg/ea_emitter/background"
|
|
30
33
|
autoload :BoundsCalculator, "ea/svg/ea_emitter/bounds_calculator"
|
|
31
34
|
autoload :Style, "ea/svg/ea_emitter/style"
|
|
35
|
+
autoload :Pen, "ea/svg/ea_emitter/pen"
|
|
32
36
|
autoload :Elements, "ea/svg/ea_emitter/elements"
|
|
37
|
+
autoload :PaintOrder, "ea/svg/ea_emitter/paint_order"
|
|
33
38
|
autoload :Connectors, "ea/svg/ea_emitter/connectors"
|
|
34
39
|
autoload :ConnectorBridges, "ea/svg/ea_emitter/connector_bridges"
|
|
35
40
|
private_constant :ConnectorBridges
|
data/lib/ea/svg/parity/source.rb
CHANGED
data/lib/ea/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ea
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.141
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
@@ -854,6 +854,7 @@ files:
|
|
|
854
854
|
- lib/ea/sources/xmi/diagram_builder.rb
|
|
855
855
|
- lib/ea/sources/xmi/diagram_builder/association_class_metadata.rb
|
|
856
856
|
- lib/ea/sources/xmi/diagram_builder/connector_metadata.rb
|
|
857
|
+
- lib/ea/sources/xmi/diagram_builder/element_borders.rb
|
|
857
858
|
- lib/ea/sources/xmi/diagram_builder/font_settings.rb
|
|
858
859
|
- lib/ea/sources/xmi/diagram_builder/stereotype_profiles.rb
|
|
859
860
|
- lib/ea/sources/xmi/diagram_builder/umldi_edges.rb
|
|
@@ -875,6 +876,7 @@ files:
|
|
|
875
876
|
- lib/ea/sources/xmi/relationship_type_map.rb
|
|
876
877
|
- lib/ea/sources/xmi/stereotype_builder.rb
|
|
877
878
|
- lib/ea/sources/xmi/stored_route.rb
|
|
879
|
+
- lib/ea/sources/xmi/stored_route/reversed_routes.rb
|
|
878
880
|
- lib/ea/sources/xmi/tag_builder.rb
|
|
879
881
|
- lib/ea/sources/xmi/type_classifier_map.rb
|
|
880
882
|
- lib/ea/sources/xmi/umldi_keyword_extractor.rb
|
|
@@ -898,8 +900,10 @@ files:
|
|
|
898
900
|
- lib/ea/svg/connector_router.rb
|
|
899
901
|
- lib/ea/svg/ea_emitter.rb
|
|
900
902
|
- lib/ea/svg/ea_emitter/background.rb
|
|
903
|
+
- lib/ea/svg/ea_emitter/bottom_margin.rb
|
|
901
904
|
- lib/ea/svg/ea_emitter/bounds_calculator.rb
|
|
902
905
|
- lib/ea/svg/ea_emitter/canvas.rb
|
|
906
|
+
- lib/ea/svg/ea_emitter/canvas_anchor.rb
|
|
903
907
|
- lib/ea/svg/ea_emitter/color_resolver.rb
|
|
904
908
|
- lib/ea/svg/ea_emitter/compartment.rb
|
|
905
909
|
- lib/ea/svg/ea_emitter/compartment/attributes.rb
|
|
@@ -922,6 +926,7 @@ files:
|
|
|
922
926
|
- lib/ea/svg/ea_emitter/connector_bridges.rb
|
|
923
927
|
- lib/ea/svg/ea_emitter/connector_redock.rb
|
|
924
928
|
- lib/ea/svg/ea_emitter/connectors.rb
|
|
929
|
+
- lib/ea/svg/ea_emitter/content_extent.rb
|
|
925
930
|
- lib/ea/svg/ea_emitter/diagram_frame.rb
|
|
926
931
|
- lib/ea/svg/ea_emitter/document.rb
|
|
927
932
|
- lib/ea/svg/ea_emitter/element.rb
|
|
@@ -976,6 +981,8 @@ files:
|
|
|
976
981
|
- lib/ea/svg/ea_emitter/marker/registry.rb
|
|
977
982
|
- lib/ea/svg/ea_emitter/markers.rb
|
|
978
983
|
- lib/ea/svg/ea_emitter/orthogonal_ray.rb
|
|
984
|
+
- lib/ea/svg/ea_emitter/paint_order.rb
|
|
985
|
+
- lib/ea/svg/ea_emitter/pen.rb
|
|
979
986
|
- lib/ea/svg/ea_emitter/render_context.rb
|
|
980
987
|
- lib/ea/svg/ea_emitter/segment_geometry.rb
|
|
981
988
|
- lib/ea/svg/ea_emitter/style.rb
|