ea 0.6.31 → 0.6.33

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: da25cfb5a4f0690b2b73df2d3c12fe3cd042c96fe6aab67d07e2c8871868feaf
4
- data.tar.gz: 8be40d4bb501b904f1ba2609446d332ea260f3d04a831528d213d6747e352dfa
3
+ metadata.gz: e63b36fde438e5d088ee091f1a7e9612eb93d379d066d3abaebca6e3495b3d16
4
+ data.tar.gz: fbe7073cfddcd4bb861cb7ea238ea436a7f3f5bab5d661e928b2df596bdde92a
5
5
  SHA512:
6
- metadata.gz: 271180e45139ae7e67a63a66a9fd78c8311edd379ee73f3a5ab9241f7b43d1be737bffca276e0585473f0294f1f557d3ff46fb254cdd105b8b6526ffb052fd36
7
- data.tar.gz: 63856efa026109bf92d89468c10e6325f9a2f411e4f49217335667b590842d1b5f8f0f860f17c3527bb57236a3d096729ae411a9c3166c4f4efbb169db30eea0
6
+ metadata.gz: e1a3392ff7069a1c9287e94997c9d516ac5ee358fb66f76bf27a310615bcaad6e4daeffb135bbda464976e6cccf24e9d40999fabbec64c2f3a863e0bb5b60b3d
7
+ data.tar.gz: 55d8d38d9bc7d613f0673863b6f6ace24bad435d1e59b9662fada852bc38248abcacb5f211f466566b668abfcb7a368c129a57e34b58b389d6621a8b5fa13cde
@@ -165,8 +165,8 @@ module Ea
165
165
  target = diagram_object_placement(diagram_row.diagram_id, target_id)
166
166
  return nil unless source && target
167
167
 
168
- source_bounds = bounds_from_rect(source)
169
- target_bounds = bounds_from_rect(target)
168
+ source_bounds = drawn_bounds_for(source)
169
+ target_bounds = drawn_bounds_for(target)
170
170
  waypoints = if source_id == target_id
171
171
  self_loop_waypoints(source_bounds)
172
172
  else
@@ -182,7 +182,12 @@ module Ea
182
182
  target_stereotype: conn.deststereotype,
183
183
  waypoints: waypoints,
184
184
  label_boxes: {},
185
- style: { direct: true },
185
+ # Only the Dependency family carries EA's double-back
186
+ # "M t L s M t" byte form; regenerated generalizations
187
+ # and associations draw as plain source-first lines
188
+ # (0CABA7D7's gen "M 125 130 L 125 99"; 568CDFC9's
189
+ # regenerated assocs).
190
+ style: conn.connector_type == "Dependency" ? { direct: true } : {},
186
191
  hidden: false,
187
192
  has_geometry_offsets: false
188
193
  )
@@ -224,8 +229,8 @@ module Ea
224
229
  target_placement = diagram_object_placement(diagram_row.diagram_id, target_id)
225
230
  return nil unless source_placement && target_placement
226
231
 
227
- source_bounds = bounds_from_rect(source_placement)
228
- target_bounds = bounds_from_rect(target_placement)
232
+ source_bounds = drawn_bounds_for(source_placement)
233
+ target_bounds = drawn_bounds_for(target_placement)
229
234
  waypoints = direct_waypoints(source_bounds, target_bounds)
230
235
  Ea::Model::DiagramConnector.new(
231
236
  id: IdNormalizer.synthetic("xc", diagram_row.diagram_id, object_id),
@@ -383,7 +388,33 @@ module Ea
383
388
  connector.end_object_id)
384
389
  return [] unless source && target
385
390
 
386
- direct_waypoints(bounds_from_rect(source), bounds_from_rect(target))
391
+ direct_waypoints(drawn_bounds_for(source),
392
+ drawn_bounds_for(target))
393
+ end
394
+
395
+ # The outline EA clips connector rays against: the DRAWN
396
+ # autosized box, not the stored logical rect. Packages draw
397
+ # narrower than their stored rect (body = autosized tab +
398
+ # 15), so their docks land on the drawn edges (E58034A3:
399
+ # supplier right-edge dock 155 drawn vs 121 stored). All
400
+ # other element kinds draw at the stored rect.
401
+ PACKAGE_BODY_EXTRA = 15
402
+
403
+ def drawn_bounds_for(placement)
404
+ logical = bounds_from_rect(placement)
405
+ obj = database.find_object(placement.ea_object_id.to_i)
406
+ return logical unless obj && obj.object_type == "Package"
407
+
408
+ tab = ::Ea::Svg::EaEmitter::Element::PackageShapeRenderer
409
+ .autosized_tab_width(label: obj.name.to_s,
410
+ stereotype: obj.stereotype.to_s,
411
+ size: 7)
412
+ Ea::Model::Bounds.new(
413
+ x: logical.x,
414
+ y: logical.y,
415
+ width: tab + PACKAGE_BODY_EXTRA,
416
+ height: logical.height
417
+ )
387
418
  end
388
419
 
389
420
  # Straight-line waypoints between the two box-outline
@@ -58,17 +58,23 @@ module Ea
58
58
  pts = waypoints_for(connector)
59
59
  return nil if pts.size < 2
60
60
 
61
- d = pts.each_with_index.map do |p, idx|
62
- x, y = translate_point(p)
63
- "#{idx.zero? ? 'M' : 'L'} #{Canvas.coord(x)} #{Canvas.coord(y)}"
64
- end.join(" ")
65
- # EA writes a trailing zero-length "M <start>" repeat for
66
- # DIRECT (auto-routed straight) connectors — verified on
67
- # context diagrams where every line carries it (B6847577,
68
- # E58034A3, 8CF27BE8).
61
+ # DIRECT (auto-routed straight) connectors: EA writes the
62
+ # segment TARGET-FIRST with a trailing zero-length repeat —
63
+ # "M target L source M target" (B6847577, E58034A3,
64
+ # 8CF27BE8). Same pixels as source-first; only the byte
65
+ # order differs, so reversal lives here at the emitter and
66
+ # the marker anchoring (source = first waypoint) is
67
+ # untouched.
69
68
  if pts.size == 2 && direct?(connector)
70
- x, y = translate_point(pts.first)
71
- d = "#{d} M #{Canvas.coord(x)} #{Canvas.coord(y)}"
69
+ x1, y1 = translate_point(pts.first)
70
+ x2, y2 = translate_point(pts.last)
71
+ d = "M #{Canvas.coord(x2)} #{Canvas.coord(y2)} L #{Canvas.coord(x1)} #{Canvas.coord(y1)} " \
72
+ "M #{Canvas.coord(x2)} #{Canvas.coord(y2)}"
73
+ else
74
+ d = pts.each_with_index.map do |p, idx|
75
+ x, y = translate_point(p)
76
+ "#{idx.zero? ? 'M' : 'L'} #{Canvas.coord(x)} #{Canvas.coord(y)}"
77
+ end.join(" ")
72
78
  end
73
79
  %(<path d="#{d}" shape-rendering="auto"/>)
74
80
  end
@@ -101,7 +101,13 @@ module Ea
101
101
  # baseline + text descent (~4px) against the box bottom:
102
102
  # TK_PositionType keeps 7 rows ending 6px above the bottom,
103
103
  # while a 13px-tighter box loses them all.
104
+ # The drop applies only to association-derived property
105
+ # rows (AOS/CityFurniture). When the element has REAL
106
+ # attributes EA instead GROWS the drawn box past the
107
+ # stored height and shows every row (0CABA7D7: parent at
108
+ # stored h44 draws at h59 with +minimumOccurs visible).
104
109
  if attr_lines.any? &&
110
+ !classifier.properties.to_a.any? { |p| !p.association_id } &&
105
111
  geometry.attr_bottom_y.to_i > bounds.y + bounds.height
106
112
  attr_lines = []
107
113
  geometry = compartment_geometry(bounds, size, attr_lines, op_lines,
@@ -123,6 +129,24 @@ module Ea
123
129
  marker_count: marker_lines_for(classifier).size,
124
130
  enum_literals_count: enum_row_count_for(classifier))
125
131
  end
132
+ # Real attributes grow the DRAWN box past the stored
133
+ # height instead of being dropped (0CABA7D7: stored h44
134
+ # draws at h59). Grown height = last row baseline + EA's
135
+ # ~8px bottom padding. Render-local: the diagram-level
136
+ # canvas still derives from stored bounds.
137
+ # content_bottom_y is nil when no compartment has rows;
138
+ # op_bottom_y is NOT a sentinel (it reports the op-divider
139
+ # position even with zero operations), so it must stay out
140
+ # of the max.
141
+ grown_bottom = geometry.content_bottom_y.to_i
142
+ if attr_lines.any? && grown_bottom.positive? &&
143
+ grown_bottom + 8 > bounds.y + bounds.height
144
+ bounds = Ea::Model::Bounds.new(
145
+ x: bounds.x, y: bounds.y,
146
+ width: bounds.width,
147
+ height: grown_bottom + 8 - bounds.y
148
+ )
149
+ end
126
150
  RenderContext.new(
127
151
  element: element,
128
152
  bounds: bounds,
@@ -44,7 +44,19 @@ module Ea
44
44
  !attr_lines.empty? || !op_lines.empty? ||
45
45
  enum_literals.any? || tagged_values.any? ||
46
46
  (constraints&.any?) ||
47
- (!package_content_lines.nil? && !package_content_lines.empty?)
47
+ (!package_content_lines.nil? && !package_content_lines.empty?) ||
48
+ hidden_features_present?
49
+ end
50
+
51
+ # EA draws the header divider whenever the element HAS a
52
+ # feature compartment — even one whose rows are all hidden
53
+ # by visibility flags (10E3E08A: CodeList with 3 attributes
54
+ # toggled off still renders the divider over an empty body;
55
+ # only feature-less elements omit it).
56
+ def hidden_features_present?
57
+ return false unless classifier.respond_to?(:properties)
58
+
59
+ classifier.properties.any? || classifier.operations.any?
48
60
  end
49
61
  end
50
62
  end
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.31"
7
+ VERSION = "0.6.33"
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.31
4
+ version: 0.6.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.