summaryrefslogtreecommitdiff
path: root/render-symbolic.rb
blob: 9cb28dd4d5bfb19747fe3e20f6604e5bc9d7a674 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env ruby

require "rexml/document"
require "fileutils"
include REXML


INKSCAPE = 'flatpak run org.inkscape.Inkscape'
# INKSCAPE = '/usr/bin/inkscape'
SRC = "src/symbolic/gnome-stencils.svg"
PREFIX = "Adwaita/scalable"
PREFIX32 = "Adwaita/scalable-up-to-32" # dirty but it allows rendering those up-to icons

# SVGO is a Node.js SVG optimization tool install with 'sudo npm install -g svgo'
# script will skip if SVGO is not present
SVGO = '/usr/bin/svgo'
# SVGO = '/usr/local/bin/svgo' # it gets put here on some distros

def chopSVG(icon)
	FileUtils.mkdir_p(icon[:dir]) unless File.exists?(icon[:dir])
	unless (File.exists?(icon[:file]) && !icon[:forcerender])
		FileUtils.cp(SRC,icon[:file]) 
		puts " >> #{icon[:name]}"
		# extract the icon
		cmd = "#{INKSCAPE} -f #{icon[:file]} "
		cmd += "--select #{icon[:id]} --verb=FitCanvasToSelection --verb=EditInvertInAllLayers --verb=EditDelete " # delete everything but the icon
		cmd += "--verb=FileVacuum --verb=FileSave --verb=FileQuit > /dev/null 2>&1"
		system(cmd)
		# remove bounding rectangle
		svgcrop = Document.new(File.new(icon[:file], 'r'))
		svgcrop.root.each_element("//rect") do |rect| 
			w = ((rect.attributes["width"].to_f * 10).round / 10.0).to_i #get rid of 16 vs 15.99999 
			h = ((rect.attributes["width"].to_f * 10).round / 10.0).to_i #Inkscape bugs
			if w == 16 && h == 16
				rect.remove
			end
		end
		icon_f = File.new(icon[:file],'w+')
		icon_f.puts svgcrop
		icon_f.close
		# convert any strokes and objects to paths
		cmd = "#{INKSCAPE} -f #{icon[:file]} --verb=EditSelectAll --verb=SelectionUnGroup --verb=SelectionUnGroup --verb=SelectionUnGroup --verb=ObjectToPath --verb=StrokeToPath "
		cmd += "--verb=FileSave --verb=FileQuit > /dev/null 2>&1"
		system(cmd)
		# save as plain SVG
		cmd = "#{INKSCAPE} -f #{icon[:file]} -z --vacuum-defs --export-plain-svg=#{icon[:file]} > /dev/null 2>&1"
		system(cmd)
		# remove as many extraneous elements as possible with SVGO
		cmd = "#{SVGO} --pretty --disable=convertShapeToPath --disable=convertPathData --enable=removeStyleElement -i #{icon[:file]} -o  #{icon[:file]} > /dev/null 2>&1"
		system(cmd)
	else
		puts " -- #{icon[:name]} already exists"
	end
end #end of function

def get_output_filename(d,n)
	if (/rtl$/.match(n))
		outfile = "#{d}/#{n.chomp('-rtl')}-symbolic-rtl.svg"
	else
		outfile = "#{d}/#{n}-symbolic.svg"
	end
	return outfile
end

#main
# Open SVG file.
svg = Document.new(File.new(SRC, 'r'))

if (ARGV[0].nil?) #render all SVGs
	puts "Rendering from icons in #{SRC}"
	# Go through every layer.
	svg.root.each_element("/svg/g[@inkscape:groupmode='layer']") do |context| 
		context_name = context.attributes.get_attribute("inkscape:label").value  
		puts "Going through layer '" + context_name + "'"
		context.each_element("g") do |icon|
			#puts "DEBUG #{icon.attributes.get_attribute('id')}"
			dir = "#{PREFIX}/#{context_name}"
			icon_name = icon.attributes.get_attribute("inkscape:label").value
			# prevent rendering of icons ending in :
			if icon_name.end_with?("-alt", "-old", "-template", "-source", "-ltr", "-working")
				puts " ++ skipping icon '" + icon_name + "'"
			elsif icon_name =~ /\d$/
				puts " ++ skipping icon '" + icon_name + "'"
			else
				chopSVG({ :name => icon_name,
						:id => icon.attributes.get_attribute("id"),
						:dir => dir,
						:file => get_output_filename(dir, icon_name)})
			end
		end
	end
	puts "\nrendered all SVGs"
else #only render the icons passed
	icons = ARGV
	ARGV.each do |icon_name|
		icon = svg.root.elements["//g[@inkscape:label='#{icon_name}']"]
		if icon_name == "process-working"
			dir = "#{PREFIX32}/#{icon.parent.attributes['inkscape:label']}"
		else
			dir = "#{PREFIX}/#{icon.parent.attributes['inkscape:label']}"
		end
		chopSVG({	:name => icon_name,
					:id => icon.attributes["id"],
					:dir => dir,
					:file => get_output_filename(dir, icon_name),
					:forcerender => true})
	end
	puts "\nrendered #{ARGV.length} icons"
end