ea 0.6.140 → 0.6.142

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/config/themes/default.yml +7 -0
  3. data/lib/ea/cli/app.rb +10 -0
  4. data/lib/ea/cli/command/diagrams.rb +4 -1
  5. data/lib/ea/cli/command/render.rb +8 -1
  6. data/lib/ea/cli/command/spa.rb +2 -1
  7. data/lib/ea/cli/command/svg.rb +9 -6
  8. data/lib/ea/fonts/metrics.rb +44 -16
  9. data/lib/ea/model/diagram.rb +6 -0
  10. data/lib/ea/qea/services/database_loader.rb +4 -1
  11. data/lib/ea/sources/qea/diagram_builder/routing.rb +64 -22
  12. data/lib/ea/sources/qea/diagram_builder.rb +4 -1
  13. data/lib/ea/sources/xmi/adapter.rb +20 -0
  14. data/lib/ea/sources/xmi/connector_index.rb +30 -0
  15. data/lib/ea/sources/xmi/constraint_builder.rb +81 -0
  16. data/lib/ea/sources/xmi/diagram_builder.rb +22 -11
  17. data/lib/ea/sources/xmi/extension_style_parser.rb +1 -1
  18. data/lib/ea/sources/xmi/extension_types.rb +9 -2
  19. data/lib/ea/sources/xmi/relationship_builder.rb +17 -11
  20. data/lib/ea/sources/xmi/stored_route/reversed_routes.rb +10 -26
  21. data/lib/ea/sources/xmi.rb +2 -0
  22. data/lib/ea/spa/generator.rb +4 -2
  23. data/lib/ea/spa/projector.rb +4 -2
  24. data/lib/ea/svg/ea_emitter/bottom_margin.rb +16 -12
  25. data/lib/ea/svg/ea_emitter/bounds_calculator.rb +22 -14
  26. data/lib/ea/svg/ea_emitter/canvas.rb +43 -5
  27. data/lib/ea/svg/ea_emitter/canvas_anchor.rb +12 -4
  28. data/lib/ea/svg/ea_emitter/compartment/attributes.rb +5 -0
  29. data/lib/ea/svg/ea_emitter/compartment/constraints.rb +5 -0
  30. data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +5 -0
  31. data/lib/ea/svg/ea_emitter/compartment/header.rb +8 -1
  32. data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +6 -1
  33. data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +5 -0
  34. data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +6 -1
  35. data/lib/ea/svg/ea_emitter/compartment/marker.rb +5 -0
  36. data/lib/ea/svg/ea_emitter/compartment/note_body.rb +7 -2
  37. data/lib/ea/svg/ea_emitter/compartment/note_text.rb +5 -0
  38. data/lib/ea/svg/ea_emitter/compartment/operations.rb +5 -0
  39. data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +5 -0
  40. data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +12 -1
  41. data/lib/ea/svg/ea_emitter/compartment/shape.rb +14 -1
  42. data/lib/ea/svg/ea_emitter/compartment/stereotype_icon.rb +6 -0
  43. data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +5 -0
  44. data/lib/ea/svg/ea_emitter/compartment.rb +13 -0
  45. data/lib/ea/svg/ea_emitter/connector_bridges.rb +18 -4
  46. data/lib/ea/svg/ea_emitter/connector_redock.rb +13 -6
  47. data/lib/ea/svg/ea_emitter/content_extent.rb +11 -2
  48. data/lib/ea/svg/ea_emitter/diagram_frame.rb +7 -0
  49. data/lib/ea/svg/ea_emitter/document.rb +22 -6
  50. data/lib/ea/svg/ea_emitter/element/attribute_renderer.rb +6 -1
  51. data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +9 -0
  52. data/lib/ea/svg/ea_emitter/element/header_renderer.rb +7 -0
  53. data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +18 -14
  54. data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +1 -8
  55. data/lib/ea/svg/ea_emitter/elements.rb +36 -12
  56. data/lib/ea/svg/ea_emitter/font_resolver.rb +3 -1
  57. data/lib/ea/svg/ea_emitter/label/end_label.rb +113 -19
  58. data/lib/ea/svg/ea_emitter/label/midpoint_label.rb +66 -0
  59. data/lib/ea/svg/ea_emitter/label/plain_source_seat.rb +25 -2
  60. data/lib/ea/svg/ea_emitter/label/plain_target_seat.rb +64 -1
  61. data/lib/ea/svg/ea_emitter/labels.rb +64 -35
  62. data/lib/ea/svg/ea_emitter/layer_sequencer.rb +14 -7
  63. data/lib/ea/svg/ea_emitter/markers.rb +1 -1
  64. data/lib/ea/svg/ea_emitter/paint_order.rb +5 -4
  65. data/lib/ea/svg/ea_emitter/pen.rb +19 -0
  66. data/lib/ea/svg/ea_emitter/render_context.rb +1 -1
  67. data/lib/ea/svg/ea_emitter/text_renderer.rb +24 -8
  68. data/lib/ea/svg/ea_emitter.rb +1 -0
  69. data/lib/ea/svg/parity/source.rb +1 -1
  70. data/lib/ea/version.rb +1 -1
  71. metadata +5 -2
@@ -7,8 +7,9 @@ module Ea
7
7
  # start element's placement row, then the connector id: the
8
8
  # `paint_order` key the diagram builders store. Verified without a
9
9
  # single inversion over 12785 connector pairs of the QEA corpus.
10
- # Connectors with an unresolvable key follow the keyed ones, and
11
- # phantoms (no stored key) come last, each in link order.
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.
12
13
  module PaintOrder
13
14
  module_function
14
15
 
@@ -18,9 +19,9 @@ module Ea
18
19
  rank = if order.nil?
19
20
  2
20
21
  else
21
- order.empty? ? 1 : 0
22
+ order.empty? || order.any?(&:nil?) ? 1 : 0
22
23
  end
23
- [rank, order || [], index]
24
+ [rank, rank.zero? ? order : [], index]
24
25
  end.map(&:first)
25
26
  end
26
27
  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, :first_painted, :previous_pen,
22
+ :off_canvas_parent_name, :previous_pen,
23
23
  keyword_init: true
24
24
  )
25
25
  def note_body
@@ -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
- real = Ea::Fonts::Metrics.text_length(text, size, family: family,
160
- weight: weight,
161
- style: style, logical_height: logical_height)
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
- (GLYPH_WIDTHS[ch] || GLYPH_FALLBACK) * size.to_f
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
 
@@ -32,6 +32,7 @@ module Ea
32
32
  autoload :Background, "ea/svg/ea_emitter/background"
33
33
  autoload :BoundsCalculator, "ea/svg/ea_emitter/bounds_calculator"
34
34
  autoload :Style, "ea/svg/ea_emitter/style"
35
+ autoload :Pen, "ea/svg/ea_emitter/pen"
35
36
  autoload :Elements, "ea/svg/ea_emitter/elements"
36
37
  autoload :PaintOrder, "ea/svg/ea_emitter/paint_order"
37
38
  autoload :Connectors, "ea/svg/ea_emitter/connectors"
@@ -44,7 +44,7 @@ module Ea
44
44
  private
45
45
 
46
46
  def load_qea
47
- raise NotImplementedError, "QEA Document loading not yet wired into bench"
47
+ Ea::Sources::Qea::Adapter.from_path(path)
48
48
  end
49
49
 
50
50
  def load_xmi
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.140"
7
+ VERSION = "0.6.142"
8
8
  end
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.140
4
+ version: 0.6.142
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-21 00:00:00.000000000 Z
11
+ date: 2026-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -851,6 +851,8 @@ files:
851
851
  - lib/ea/sources/xmi/adapter.rb
852
852
  - lib/ea/sources/xmi/annotation_builder.rb
853
853
  - lib/ea/sources/xmi/classifier_builder.rb
854
+ - lib/ea/sources/xmi/connector_index.rb
855
+ - lib/ea/sources/xmi/constraint_builder.rb
854
856
  - lib/ea/sources/xmi/diagram_builder.rb
855
857
  - lib/ea/sources/xmi/diagram_builder/association_class_metadata.rb
856
858
  - lib/ea/sources/xmi/diagram_builder/connector_metadata.rb
@@ -982,6 +984,7 @@ files:
982
984
  - lib/ea/svg/ea_emitter/markers.rb
983
985
  - lib/ea/svg/ea_emitter/orthogonal_ray.rb
984
986
  - lib/ea/svg/ea_emitter/paint_order.rb
987
+ - lib/ea/svg/ea_emitter/pen.rb
985
988
  - lib/ea/svg/ea_emitter/render_context.rb
986
989
  - lib/ea/svg/ea_emitter/segment_geometry.rb
987
990
  - lib/ea/svg/ea_emitter/style.rb