Skip to content

Commit

Permalink
Correctly handle "use"ing symbols
Browse files Browse the repository at this point in the history
The svg spec says to treat "use"d symbols as svg elements, and to
transfer the width and height from the use element to the cloned svg
element.  This fixes a rendering problem reported in issue #157.
  • Loading branch information
mogest committed Jan 27, 2024
1 parent 4460059 commit 93d1af3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
32 changes: 20 additions & 12 deletions lib/prawn/svg/elements/use.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
class Prawn::SVG::Elements::Use < Prawn::SVG::Elements::Base
attr_reader :referenced_element_class
attr_reader :referenced_element_source
attr_reader :referenced_element_class, :referenced_element_source

def parse
href = href_attribute
if href.nil?
raise SkipElementError, "use tag must have an href or xlink:href"
end
raise SkipElementError, 'use tag must have an href or xlink:href' if href.nil?

if href[0..0] != '#'
raise SkipElementError, "use tag has an href that is not a reference to an id; this is not supported"
raise SkipElementError, 'use tag has an href that is not a reference to an id; this is not supported'
end

id = href[1..-1]
Expand All @@ -29,14 +26,18 @@ def parse
end
end

if referenced_element_class.nil?
raise SkipElementError, "no tag with ID '#{id}' was found, referenced by use tag"
raise SkipElementError, "no tag with ID '#{id}' was found, referenced by use tag" if referenced_element_class.nil?

if referenced_element_source.name == 'symbol'
@referenced_element_class = Prawn::SVG::Elements::Viewport
end

state.inside_use = true

@x = attributes['x']
@y = attributes['y']
@width = attributes['width']
@height = attributes['height']
end

def container?
Expand All @@ -45,16 +46,23 @@ def container?

def apply
if @x || @y
add_call_and_enter "translate", x_pixels(@x || 0), -y_pixels(@y || 0)
add_call_and_enter 'translate', x_pixels(@x || 0), -y_pixels(@y || 0)
end
end

def process_child_elements
add_call "save"
add_call 'save'

source = referenced_element_source.dup

if referenced_element_class == Prawn::SVG::Elements::Viewport
source.attributes['width'] = @width || '100%'
source.attributes['height'] = @height || '100%'
end

child = referenced_element_class.new(document, referenced_element_source, calls, state.dup)
child = referenced_element_class.new(document, source, calls, state.dup)
child.process

add_call "restore"
add_call 'restore'
end
end
12 changes: 12 additions & 0 deletions spec/sample_svg/symbol.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 93d1af3

Please sign in to comment.