ea 0.6.54 → 0.6.55

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: 4b54f39e2dcdb482e55baad21977878ea11d4325ce84130b5a1be52d94461199
4
- data.tar.gz: e06fe1f966c7b82cd9a4ee5e0cef8482f5bb83050a74354d10e674b80e6b1317
3
+ metadata.gz: 7d4c834fa91906a0866bf29561214b7c9d140cb4b2a7106eb332f4ec029e56f1
4
+ data.tar.gz: e99cb2ff135675ec69d47397c102bd67f07925d8e59565bbabf6b96fb70cb60d
5
5
  SHA512:
6
- metadata.gz: a8c21021bb901b607f7e823bcd5caef4e10343177db98983f450a517c71d3ec929566c9ddc93dde15985bcc2fee88ffe469c164687589325d085bea94abf200d
7
- data.tar.gz: 538ea960c3033cb4b16fdedccdcc9a27be793e1d6615ad836cd340aec103bca7c86937720e74d925a1f06653939015a8a303ada6a7056a0e7209308fde308fb1
6
+ metadata.gz: 302544eb3d7bc17747114aac54f1aacb3b91c6f87340c699d4c35bb8eace2f76c9a4766fd675eb1d58d0c5faa039624124ee5d7dca75d36b7a2e6e109d9aef2c
7
+ data.tar.gz: e5a86d18db02e980a690a2653529f17cd87b431ba7d7aee03683abe6f1fc3de9d4881347817735365a53575e234a91e0cca36364552a39d24e9b725a06932017
@@ -44,6 +44,13 @@ module Ea
44
44
  # when the geometry string carries no offsets (auto-routed).
45
45
  attribute :source_port, Ea::Model::Point
46
46
  attribute :target_port, Ea::Model::Point
47
+ # Ray origins for the drawn line: element center translated by
48
+ # the stored Geometry SX/SY / EX/EY offsets. EA clips the
49
+ # segment between the two anchors at the DRAWN outlines
50
+ # (F851A657: anchors center+(-29,0)/center+(-29,0) clip to EA's
51
+ # (297,788)/(433,514) within 1.5px).
52
+ attribute :source_anchor, Ea::Model::Point
53
+ attribute :target_anchor, Ea::Model::Point
47
54
 
48
55
  json do
49
56
  map "id", to: :id
@@ -57,6 +64,8 @@ module Ea
57
64
  map "targetEdge", to: :target_edge
58
65
  map "sourcePort", to: :source_port
59
66
  map "targetPort", to: :target_port
67
+ map "sourceAnchor", to: :source_anchor
68
+ map "targetAnchor", to: :target_anchor
60
69
  map "connectorType", to: :connector_type
61
70
  map "direction", to: :direction
62
71
  map "sourceStereotype", to: :source_stereotype
@@ -373,6 +373,10 @@ module Ea
373
373
  target_stereotype: connector&.deststereotype,
374
374
  waypoints: context ? context_waypoints_for(connector, diagram_row) :
375
375
  waypoints_for_link(link_row, diagram_row),
376
+ source_anchor: port_anchor_for(connector, diagram_row,
377
+ geom, :source),
378
+ target_anchor: port_anchor_for(connector, diagram_row,
379
+ geom, :target),
376
380
  source_port: connection_port(diagram_row, connector, :source, geom),
377
381
  target_port: connection_port(diagram_row, connector, :target, geom),
378
382
  label_boxes: context ? {} : (geom[:label_boxes] || {}),
@@ -384,6 +388,26 @@ module Ea
384
388
  )
385
389
  end
386
390
 
391
+ # Ray origin for one connector end: the element's center
392
+ # translated by the stored SX/SY (source) or EX/EY (target)
393
+ # offset. EA clips the anchor-to-anchor segment at the drawn
394
+ # outlines.
395
+ def port_anchor_for(connector, diagram_row, geom, end_kind)
396
+ return nil unless connector
397
+
398
+ object_id = end_kind == :source ? connector.start_object_id :
399
+ connector.end_object_id
400
+ placement = diagram_object_placement(diagram_row.diagram_id,
401
+ object_id)
402
+ return nil unless placement
403
+
404
+ bounds = bounds_from_rect(placement)
405
+ dx = (end_kind == :source ? geom[:sx] : geom[:ex]).to_i
406
+ dy = (end_kind == :source ? geom[:sy] : geom[:ey]).to_i
407
+ Ea::Model::Point.new(x: bounds.x + bounds.width / 2 + dx,
408
+ y: bounds.y + bounds.height / 2 + dy)
409
+ end
410
+
387
411
  # Context diagrams re-route every drawn connector as a
388
412
  # direct line at draw time: the center-to-center ray clipped
389
413
  # at both box outlines. The stored SX/SY/EDGE geometry is
@@ -19,11 +19,12 @@ module Ea
19
19
  # self-loop, or no drawn bounds for either end).
20
20
  def pairs_for(connector, diagram, model_index, bounds_map)
21
21
  return nil unless bounds_map
22
- return nil unless direct?(connector)
22
+ return nil unless direct?(connector) || two_point?(connector)
23
23
 
24
24
  points = waypoint_pairs(connector)
25
25
  return nil unless points.size == 2
26
26
 
27
+
27
28
  rel = relationship_for(connector, model_index)
28
29
  return nil unless rel
29
30
 
@@ -35,8 +36,45 @@ module Ea
35
36
  return nil unless source_bounds && target_bounds
36
37
  return nil if source_ref == target_ref
37
38
 
38
- [edge_point(source_bounds, target_bounds),
39
- edge_point(target_bounds, source_bounds)]
39
+ sa = connector.source_anchor
40
+ ta = connector.target_anchor
41
+ if sa && ta
42
+ [anchor_exit(sa, source_bounds, ta),
43
+ anchor_exit(ta, target_bounds, sa)]
44
+ else
45
+ [edge_point(source_bounds, target_bounds),
46
+ edge_point(target_bounds, source_bounds)]
47
+ end
48
+ end
49
+
50
+ # Exit point of the anchor-to-anchor segment through a box's
51
+ # outline: smallest positive t whose crossing lies on the
52
+ # rectangle perimeter.
53
+ def anchor_exit(anchor, bounds, other)
54
+ ax, ay = anchor.x.to_f, anchor.y.to_f
55
+ ox, oy = other.x.to_f, other.y.to_f
56
+ dx, dy = ox - ax, oy - ay
57
+ candidates = []
58
+ if dx != 0
59
+ [bounds.x, bounds.x + bounds.width].each do |x|
60
+ t = (x - ax) / dx
61
+ candidates << [t, x, ay + t * dy] if t.positive?
62
+ end
63
+ end
64
+ if dy != 0
65
+ [bounds.y, bounds.y + bounds.height].each do |y|
66
+ t = (y - ay) / dy
67
+ candidates << [t, ax + t * dx, y] if t.positive?
68
+ end
69
+ end
70
+ on_perimeter = candidates.select do |_t, x, y|
71
+ x >= bounds.x - 0.01 && x <= bounds.x + bounds.width + 0.01 &&
72
+ y >= bounds.y - 0.01 && y <= bounds.y + bounds.height + 0.01
73
+ end
74
+ best = on_perimeter.min_by(&:first)
75
+ # EA floors the dock coordinates (F851A657: 297.75 -> 297,
76
+ # 433.7 -> 433) - a rounded-up dock is a visible miss.
77
+ best ? [best[1].floor, best[2].floor] : [ax.floor, ay.floor]
40
78
  end
41
79
 
42
80
  # EA never docks a horizontal connector line at the header
@@ -85,6 +123,12 @@ module Ea
85
123
  %w[direct regenerated].any? { |k| style.key?(k) }
86
124
  end
87
125
 
126
+ # EXPERIMENT: every auto-laid 2-waypoint connector re-docks
127
+ # as the center-to-center ray clipped at the drawn outlines.
128
+ def two_point?(connector)
129
+ (connector.waypoints || []).size == 2
130
+ end
131
+
88
132
  def waypoint_pairs(connector)
89
133
  (connector.waypoints || []).filter_map do |wp|
90
134
  next unless wp.position
@@ -126,11 +170,11 @@ module Ea
126
170
  if dx.abs * bounds.height > dy.abs * bounds.width
127
171
  x = dx.positive? ? bounds.x + bounds.width : bounds.x
128
172
  y = safe_y(cx, cy, dx, dy, x)
129
- [x, y]
173
+ [x, y.floor]
130
174
  else
131
175
  y = dy.positive? ? bounds.y + bounds.height : bounds.y
132
176
  x = safe_x(cx, cy, dx, dy, y)
133
- [x, y]
177
+ [x.floor, y]
134
178
  end
135
179
  end
136
180
 
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.54"
7
+ VERSION = "0.6.55"
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.54
4
+ version: 0.6.55
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.