ea 0.6.94 → 0.6.95

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2c872554c2534df450bc335593fb39ed9363f3fe20053ef001b1621c5cdec6b
4
- data.tar.gz: 79cecbb5a25a07a38d5bac1df1aaf413ffbc471cdd39938cd64cdf8bca822ce7
3
+ metadata.gz: 87aea8f508b2ef7e8f98038519122caff0f87c967f3e59132838885124d0db84
4
+ data.tar.gz: 381aa0a30e5c9c3c60f0885f4fd2ca737d909f8fc620e36725e787db909898ab
5
5
  SHA512:
6
- metadata.gz: d24168a33acbf362b4feff14508abb00562139e6602caed154c7f4b5e8bfa2b0f773b045fd27585f0610946f8fb2e4e9e6dbf2b8667ab785fc1bd71f18e9aa83
7
- data.tar.gz: 1559678bc826ecdb82d710a72723709fa195907e8a11bb138eed728ba8b9804b30fcab7f75a024f27f8df34558ba52ec7f373e18bf1f46e6c7a89f07af8cf70b
6
+ metadata.gz: adba2730ddbc449a79ce0063273cb6f75c4fc88d219899e12e13bc4226d2d88d5ef438c062384d908296e62938d1b937c56b926043e89dc55b4d43a1d53c63c8
7
+ data.tar.gz: b677683c53a71f27f68c2c80f7b150517288751bdbf586d78ad0fbe986b014931b57659235587e4ba61b8753656de72f6949363291fd6f1ab2d6e1a0a70aa5d1
@@ -29,7 +29,9 @@ module Ea
29
29
  return false unless connector.connector_type == "Aggregation" && points.size == 4
30
30
 
31
31
  style = DiagramStyleParser.parse(link_row.style)
32
- return false unless style[:tree] == "V" && style[:lwidth] == "2"
32
+ return false unless style[:lwidth] == "2" || flush_width_zero_tree?(link_row)
33
+ return false unless style[:tree] == "V" ||
34
+ (style[:mode] == "3" && style[:tree].nil?)
33
35
 
34
36
  tree_bends_fit?(points[1], points[-2], src, tgt)
35
37
  end
@@ -78,6 +80,56 @@ module Ea
78
80
  end
79
81
  end
80
82
 
83
+ # A computed Mode 3 Generalization between horizontally disjoint
84
+ # boxes whose two explicit ports sit on the facing sides one pixel
85
+ # apart in y or less (edge-port integer rounding) is one horizontal line.
86
+ # Stored Path jogs and every other shape keep their route.
87
+ def collapse_computed_jog(model, link_row, diagram_row, geom)
88
+ return model unless computed_jog_candidate?(model, link_row, geom)
89
+
90
+ connection = database.find_connector(link_row.connectorid)
91
+ src, tgt = [connection.start_object_id, connection.end_object_id].map do |id|
92
+ placement = diagram_object_placement(diagram_row.diagram_id, id)
93
+ placement && bounds_from_rect(placement)
94
+ end
95
+ return model unless src && tgt && facing_jog_ports?(model.source_port, model.target_port, src, tgt)
96
+
97
+ ends = [[model.source_port.x, model.source_port.y],
98
+ [model.target_port.x, model.source_port.y]].map do |x, y|
99
+ Ea::Model::Point.new(x: x, y: y)
100
+ end
101
+ model.waypoints = ends.map { |point| Ea::Model::Waypoint.new(position: point) }
102
+ model.source_anchor = model.source_port = ends.first
103
+ model.target_anchor = model.target_port = ends.last
104
+ model
105
+ end
106
+
107
+ def computed_jog_candidate?(model, link_row, geom)
108
+ style = model.style.to_h
109
+ model.connector_type == "Generalization" && geom[:edge] == 2 &&
110
+ link_row.path.to_s.empty? && style[:mode] == "3" && style[:lwidth] == "2" &&
111
+ !style.key?(:tree) && model.source_port && model.target_port &&
112
+ model.waypoints.size == 3
113
+ end
114
+
115
+ def facing_jog_ports?(from, to, src, tgt)
116
+ return false unless (from.y - to.y).abs <= 1 && from.y.between?(tgt.y, tgt.y + tgt.height)
117
+
118
+ if src.x + src.width < tgt.x
119
+ from.x == src.x + src.width && to.x == tgt.x
120
+ elsif tgt.x + tgt.width < src.x
121
+ from.x == src.x && to.x == tgt.x + tgt.width
122
+ else
123
+ false
124
+ end
125
+ end
126
+
127
+ # Width-0 vertical trees dock on the box edges themselves (no outline).
128
+ def flush_width_zero_tree?(link_row)
129
+ style = DiagramStyleParser.parse(link_row.style)
130
+ style[:mode] == "3" && style[:tree] == "V" && style[:lwidth] == "0"
131
+ end
132
+
81
133
  def tree_bends_fit?(first, last, source, target)
82
134
  first[0] != last[0] && first[1] == last[1] &&
83
135
  within_vertical_gap?(first[1], source, target) &&
@@ -385,7 +385,7 @@ module Ea
385
385
  geom = parse_geometry_fields(link_row.geometry)
386
386
  context = ContextDiagramSupport.package_context(diagram_row) ||
387
387
  ContextDiagramSupport.element_regenerate?(diagram_row)
388
- Ea::Model::DiagramConnector.new(
388
+ collapse_computed_jog(Ea::Model::DiagramConnector.new(
389
389
  id: IdNormalizer.synthetic("dc", diagram_row.diagram_id,
390
390
  link_row.instance_id),
391
391
  diagram_id: IdNormalizer.from_guid(diagram_row.ea_guid),
@@ -409,7 +409,7 @@ module Ea
409
409
  ghost_labels: ghost_labels_for(connector, diagram_row, link_row),
410
410
  has_geometry_offsets: geometry_has_offsets?(link_row.geometry),
411
411
  is_substitutable: substitutable_connector?(connector)
412
- )
412
+ ), link_row, diagram_row, geom)
413
413
  end
414
414
 
415
415
  # Ray origin for one connector end: the element's center
@@ -653,14 +653,16 @@ module Ea
653
653
  points = tree_route
654
654
  elsif %w[Association Aggregation].include?(connector.connector_type) &&
655
655
  edge_out != 2
656
- unless preserve_stored_tree?(points, link_row, connector, src, tgt)
656
+ stored_tree = preserve_stored_tree?(points, link_row, connector, src, tgt)
657
+ unless stored_tree
657
658
  points = facing_edge_route(points, src, tgt)
658
659
  end
659
660
  # A width-2 Aggregation that keeps its stored bends is
660
661
  # docked like a Generalization one.
661
662
  if connector.connector_type == "Aggregation" &&
662
663
  intermediate.any? && points.size >= 4 &&
663
- generalization_outline_offset(link_row, points.size) == 1
664
+ (generalization_outline_offset(link_row, points.size) == 1 ||
665
+ (stored_tree && flush_width_zero_tree?(link_row)))
664
666
  redock_parent_above(points, link_row, source_placement,
665
667
  target_placement, strict: true)
666
668
  end
@@ -98,11 +98,30 @@ module Ea
98
98
 
99
99
  def stroke_outline?(connector, bounds)
100
100
  connector.style.to_h[:lwidth] == "2" &&
101
- %w[Generalization Aggregation].include?(connector.connector_type) &&
102
- bounds.all? { |box| box.width.positive? && box.height.positive? }
101
+ bounds.all? { |box| box.width.positive? && box.height.positive? } &&
102
+ outline_connector?(connector, bounds)
103
103
  end
104
104
  private_class_method :stroke_outline?
105
105
 
106
+ def outline_connector?(connector, bounds)
107
+ return true if %w[Generalization Aggregation].include?(connector.connector_type)
108
+
109
+ return false unless stored_association?(connector)
110
+
111
+ # Diagonal Association rounding and tree docks keep their existing rules.
112
+ pairs = clipped_pairs(bounds, [connector.source_anchor, connector.target_anchor])
113
+ pairs.first.zip(pairs.last).any? { |first, last| first == last }
114
+ end
115
+ private_class_method :outline_connector?
116
+
117
+ def stored_association?(connector)
118
+ style = connector.style.to_h
119
+ connector.connector_type == "Association" && connector.has_geometry_offsets &&
120
+ connector.source_port && connector.target_port &&
121
+ %w[1 3].include?(style[:mode]) && !style[:tree]
122
+ end
123
+ private_class_method :stored_association?
124
+
106
125
  def clipped_pairs(bounds, anchors)
107
126
  source, target = bounds
108
127
  source_anchor, target_anchor = anchors
@@ -22,15 +22,18 @@ module Ea
22
22
  DEFAULT_FAMILY = "Yu Gothic UI"
23
23
  DEFAULT_SIZE = 13
24
24
 
25
- attr_reader :diagram, :canvas, :model_index, :theme, :document
25
+ attr_reader :diagram, :canvas, :model_index, :theme, :document,
26
+ :drawn_bounds, :divider_y_by_ref
26
27
 
27
28
  def initialize(diagram, canvas: nil, model_index: nil, theme: nil,
28
- document: nil)
29
+ document: nil, drawn_bounds: nil, divider_y_by_ref: nil)
29
30
  @diagram = diagram
30
31
  @canvas = canvas
31
32
  @model_index = model_index
32
33
  @theme = theme || Ea::Theme::Registry.default
33
34
  @document = document
35
+ @drawn_bounds = drawn_bounds
36
+ @divider_y_by_ref = divider_y_by_ref
34
37
  end
35
38
 
36
39
  def render
@@ -51,7 +54,7 @@ module Ea
51
54
  # in t_connector.Name but renders only inside the Note box.
52
55
  return [] if connector.connector_type.to_s.casecmp("NoteLink").zero?
53
56
 
54
- points = waypoint_pairs(connector)
57
+ points = label_points(connector)
55
58
  return [] if points.size < 2
56
59
 
57
60
  texts = []
@@ -170,6 +173,19 @@ module Ea
170
173
  )
171
174
  end
172
175
 
176
+ # Two-point routes are clipped during emission, after their stored
177
+ # waypoints were parsed. End-label offsets follow the same final dock.
178
+ def label_points(connector)
179
+ points = waypoint_pairs(connector)
180
+ return points unless points.size == 2
181
+
182
+ points = ConnectorRedock.pairs_for(connector, diagram, model_index,
183
+ drawn_bounds) || points
184
+ ConnectorRedock.row_slot_adjust(points, connector, diagram,
185
+ model_index, drawn_bounds,
186
+ divider_y_by_ref) || points
187
+ end
188
+
173
189
  def waypoint_pairs(connector)
174
190
  (connector.waypoints || []).filter_map do |w|
175
191
  next unless w.position
@@ -83,7 +83,9 @@ module Ea
83
83
 
84
84
  def labels_layer
85
85
  Labels.new(diagram, canvas: canvas, model_index: model_index,
86
- theme: theme, document: document).render
86
+ theme: theme, document: document,
87
+ drawn_bounds: drawn_bounds,
88
+ divider_y_by_ref: divider_y_by_ref).render
87
89
  end
88
90
 
89
91
  def ghost_labels_layer
data/lib/ea/version.rb CHANGED
@@ -4,5 +4,5 @@ module Ea
4
4
  # Gem release version. Extracted to its own file so the
5
5
  # `gem-release` tool's `gem bump` can find and update it via the
6
6
  # standard `lib/<gem>/version.rb` convention.
7
- VERSION = "0.6.94"
7
+ VERSION = "0.6.95"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.94
4
+ version: 0.6.95
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.