Cache more SVG lookup data. Much faster!

This commit is contained in:
John Bintz 2014-09-30 08:56:59 -04:00
parent ff3d4ee51c
commit 9d78279d5e
2 changed files with 66 additions and 17 deletions

View File

@ -1,4 +1,5 @@
require 'nokogiri' require 'nokogiri'
require 'delegate'
module SVGGVS module SVGGVS
class File class File
@ -58,12 +59,42 @@ module SVGGVS
target.children.each(&:remove) target.children.each(&:remove)
end end
class SVGCache < SimpleDelegator
def initialize(doc)
@doc = doc
end
def __getobj__
@doc
end
def is_clone_dup_type(href)
@is_clone_dup_type ||= {}
return @is_clone_dup_type[href] if @is_clone_dup_type[href] != nil
if source = css(href).first
if source.name == 'flowRoot' || source.name == 'text'
@is_clone_dup_type[href] = source
end
end
@is_clone_dup_type[href] ||= false
@is_clone_dup_type[href]
end
end
def svg_cache
@svg_cache ||= SVGCache.new(source)
end
def with_new_target def with_new_target
new_target = source.dup new_target = source.dup
new_target[:id] = new_target[:id] + "_#{@instance}" new_target[:id] = new_target[:id] + "_#{@instance}"
new_target['inkscape:label'] = new_target['inkscape:label'] + "_#{@instance}" new_target['inkscape:label'] = new_target['inkscape:label'] + "_#{@instance}"
target_obj = Target.new(new_target) target_obj = Target.new(new_target, cache: svg_cache)
reset_defs! reset_defs!

View File

@ -4,8 +4,8 @@ module SVGGVS
class Target < SimpleDelegator class Target < SimpleDelegator
attr_reader :target attr_reader :target
def initialize(target) def initialize(target, options)
@target = target @target, @options = target, options
end end
def __getobj__ def __getobj__
@ -20,8 +20,16 @@ module SVGGVS
@injected_defs ||= {} @injected_defs ||= {}
end end
def file_layers
@file_layers ||= css("g[inkscape|groupmode='layer']")
end
def child_visible_layers
@child_visible_layers ||= file_layers.find_all { |layer| layer['inkscape:label'].include?('(child visible)') }
end
def inject! def inject!
css("g[inkscape|groupmode='layer']").each do |layer| file_layers.each do |layer|
if filename = layer['inkscape:label'][/inject (.*\.svg)/, 1] if filename = layer['inkscape:label'][/inject (.*\.svg)/, 1]
injected_sources[filename] ||= begin injected_sources[filename] ||= begin
data = Nokogiri::XML(::File.read(filename)) data = Nokogiri::XML(::File.read(filename))
@ -39,30 +47,36 @@ module SVGGVS
end end
def active_layers=(layers) def active_layers=(layers)
css("g[inkscape|groupmode='layer']").each do |layer| file_layers.each do |layer|
layer['style'] = if layer['inkscape:label'].include?('(visible)')
''
else
'display:none'
end
end
file_layers.each do |layer|
if layers.include?(layer['inkscape:label']) if layers.include?(layer['inkscape:label'])
layer['style'] = '' layer['style'] = ''
current_parent = layer.parent current_parent = layer.parent
while current_parent && current_parent.name == "g" while current_parent && current_parent.name == "g" && current_parent['style'] != ''
current_parent['style'] = '' current_parent['style'] = ''
current_parent = current_parent.parent current_parent = current_parent.parent
end end
else
layer['style'] = if layer['inkscape:label'].include?('(visible)') layers.delete(layer)
''
else
'display:none'
end
end end
break if layers.empty?
end end
loop do loop do
any_changed = false any_changed = false
css("g[inkscape|groupmode='layer']").each do |layer| child_visible_layers.each do |layer|
if layer['inkscape:label'].include?('(child visible)') && layer['style'] != '' && layer.parent['style'] == '' if layer['style'] != '' && layer.parent['style'] == ''
layer['style'] = '' layer['style'] = ''
any_changed = true any_changed = true
@ -106,11 +120,15 @@ module SVGGVS
end end
end end
def cache
@options[:cache]
end
# only uncloning text # only uncloning text
def unclone def unclone
css('svg|use').each do |clone| file_layers.find_all { |layer| layer['style'] == '' }.each do |layer|
if source = css(clone['xlink:href']).first layer.css('svg|use').each do |clone|
if source.name == 'flowRoot' || source.name == 'text' if source = cache.is_clone_dup_type(clone['xlink:href'])
new_group = clone.add_next_sibling("<g />").first new_group = clone.add_next_sibling("<g />").first
clone.attributes.each do |key, attribute| clone.attributes.each do |key, attribute|