Class: Emfsvg::Svg::Document

Inherits:
Object
  • Object
show all
Defined in:
lib/emfsvg/svg/document.rb

Overview

Root of a parsed SVG document. Carries the viewport geometry from the outer element plus the (lazily parsed) child element tree.

emfsvg's EMF→SVG renderer always wraps content in <g transform="translate(-bounds.left, -bounds.top)">. For byte-clean round-trip, the SVG→EMF side detects this "header translate group" and uses it to recover the EMF bounds origin instead of emitting a redundant SetWorldTransform.

Constant Summary collapse

IDENTITY_TOLERANCE =

A matrix equivalent to a pure translate: identity 2×2 portion (modulo floating-point rounding).

1e-9

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width:, height:, root_element:, view_box: nil) ⇒ Document

Returns a new instance of Document.



15
16
17
18
19
20
# File 'lib/emfsvg/svg/document.rb', line 15

def initialize(width:, height:, root_element:, view_box: nil)
  @width = width
  @height = height
  @view_box = view_box
  @root_element = root_element
end

Instance Attribute Details

#heightObject (readonly)

Returns the value of attribute height.



22
23
24
# File 'lib/emfsvg/svg/document.rb', line 22

def height
  @height
end

#root_elementObject (readonly)

Returns the value of attribute root_element.



22
23
24
# File 'lib/emfsvg/svg/document.rb', line 22

def root_element
  @root_element
end

#view_boxObject (readonly)

Returns the value of attribute view_box.



22
23
24
# File 'lib/emfsvg/svg/document.rb', line 22

def view_box
  @view_box
end

#widthObject (readonly)

Returns the value of attribute width.



22
23
24
# File 'lib/emfsvg/svg/document.rb', line 22

def width
  @width
end

Instance Method Details

#boundsObject

[min_x, min_y, w, h] for the EMF bounds.



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/emfsvg/svg/document.rb', line 51

def bounds
  return view_box if view_box

  group = header_translate_group
  if group
    matrix = group.transform_matrix
    return [-matrix.dx, -matrix.dy, width, height]
  end

  [0, 0, width, height]
end

#header_translate_groupObject

The Group that represents the emfsvg-emitted header translate, or nil if no such group is present. This group's contents are dispatched directly (without the wrapping translate); the translate feeds the EMF header bounds instead.



28
29
30
31
32
33
34
35
36
37
# File 'lib/emfsvg/svg/document.rb', line 28

def header_translate_group
  candidate = first_child
  return nil unless candidate.is_a?(Elements::Group)

  matrix = candidate.transform_matrix
  return nil unless matrix
  return nil unless translate_only?(matrix)

  candidate
end

#translate_only?(matrix) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
48
# File 'lib/emfsvg/svg/document.rb', line 43

def translate_only?(matrix)
  (matrix.m11 - 1.0).abs < IDENTITY_TOLERANCE &&
    (matrix.m22 - 1.0).abs < IDENTITY_TOLERANCE &&
    matrix.m12.abs < IDENTITY_TOLERANCE &&
    matrix.m21.abs < IDENTITY_TOLERANCE
end