aboutsummaryrefslogtreecommitdiff
path: root/gamemode/utility/svg/cl_svg.lua
blob: 7fa53d5e757475071640ad10b076edc247273b26 (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
--[[
    SVGModule v1.0 - Alexander "Apickx" Pickering
    Entered into the public domain Febuary 4, 2017
    You are not required to, but consider putting a link to the source in your file's comments!
]]

local svg = {}
local file_cache_max_size = 100
local file_cache_size = 0
local file_cache = {}

local function readsvg(path)
	if file_cache[path] == nil then
		if file_cache_size > file_cache_max_size then
			local k,_ = next(file_cache) --Random replacement
			file_cache[k] = nil
		end
		file_cache[path] = file.Read(path,"GAME")
	end
	return file_cache[path]
end

local function updatesvg(self)
	if self.path ~= self.svgpath then
		self.svgdata = readsvg(self.path)
		assert(self.svgdata ~= nil,"Could not open file:" .. self.path)
		self.svgpath = self.path
	end
	local bgf = ""
	local fgf = ""
	if self.bg ~= nil then
		bgf = string.format("svg{background:%s}",self.bg)
	end
	if self.fg ~= nil then
		fgf = string.format("svg path{fill:%s}",self.fg)
	end
	self.html:SetHTML(string.format([[
<style>%s%sbody{overflow:hidden}</style><body>%s</body>
]],bgf,fgf,self.svgdata))
end

local function updatesvgimg(self,newpath)
	self.path = newpath
	self:Update()
end

local function updatesvgfg(self,fore)
	self.fg = fore
	self:Update()
end

local function updatesvgbg(self,back)
	self.bg = back
	self:Update()
end

local toprocess = {}
function svg.MaterialFromSVG(spath,background,foreground)
	local html = vgui.Create("DHTML")
	local svgdata = readsvg(spath)
	local bgf = ""
	local fgf = ""
	if background ~= nil then
		bgf = string.format("svg{background:%s}",background)
	end
	if foreground ~= nil then
		fgf = string.format("svg path{fill:%s}",foreground)
	end
	html:SetHTML(string.format([[
<style>%s%sbody{overflow:hidden}</style><body>%s</body>
]],background and bgf or "",foreground and fgf or "",svgdata))
	local mat = {}
	toprocess[#toprocess + 1] = {mat,html}
	return mat
end

function svg.MaterialFromHTTP(spath,background,foreground)
	print("Drawing from http",spath)
	local html = vgui.Create("DHTML")
	http.Fetch(spath,
	function(body,size,headers,code)
		print("Got response!")
		html:SetHTML(string.format([[
	<style>%s%sbody{overflow:hidden}</style><body>%s</body>
	]],background and bgf or "",foreground and fgf or "",body))
	end,function(err)
		print("Failed to get file",spath,"err:",err)
	end,{})
	local mat = {}
	toprocess[#toprocess + 1] = {mat,html}
	return mat
end

hook.Add("Think","process_svg_materials",function()
	for k,v in ipairs(toprocess) do
		local hm = v[2]:GetHTMLMaterial()
		if hm then
			v[1].material = hm
		end
		for i = k,#toprocess do
			toprocess[i] = toprocess[i + 1]
		end
		if v[3] then
			v[3]()
		end
	end
end)

function svg.SetMaterialSVG(what,spath,background,foreground)
	local html = vgui.Create("DHTML")
	local svgdata = readsvg(spath)
	local bgf = ""
	local fgf = ""
	if background ~= nil then
		bgf = string.format("svg{background:%s}",background)
	end
	if foreground ~= nil then
		fgf = string.format("svg path{fill:%s}",foreground)
	end
	html:SetHTML(string.format([[
<style>%s%sbody{overflow:hidden}</style><body>%s</body>
]],background and bgf or "",foreground and fgf or "",svgdata))
	local mat = {}
	toprocess[#toprocess + 1] = {mat,html,function()
		what:SetMaterial(mat.material)
	end}
end

function svg.SvgOnDpanel(spath,background,foreground,dpanel)
	local ret = {}
	ret.html = vgui.Create("DHTML",dpanel)
	ret.path = spath
	ret.fg = foreground or Color(0,0,0,255)
	ret.bg = background or Color(255,255,255,0)
	ret.UpdateForeground = updatesvgfg
	ret.UpdateBackground = updatesvgbg
	ret.UpdateImage = updatesvgimg
	ret.Update = updatesvg
	ret:Update()
	return ret
end

return svg