118 lines
3.9 KiB
Lua
118 lines
3.9 KiB
Lua
base64 = require('base64')
|
|
|
|
function export(filename)
|
|
local outfile = io.open(filename, 'w')
|
|
if outfile == nil then
|
|
error('failed to create "'..filename)
|
|
end
|
|
for _,line in ipairs(Editor_state.lines) do
|
|
if line.mode == 'drawing' then
|
|
local svg_contents = export_drawing(line)
|
|
outfile:write('<img src="data:image/svg+xml;base64,'..base64.encode(svg_contents)..'"/>')
|
|
else
|
|
outfile:write(line.data)
|
|
end
|
|
outfile:write('<br/>\n')
|
|
end
|
|
outfile:close()
|
|
end
|
|
|
|
function export_drawing(drawing)
|
|
local out = {}
|
|
table.insert(out, '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="128">\n')
|
|
for _,shape in ipairs(drawing.shapes) do
|
|
if shape.mode == 'freehand' then
|
|
export_freehand(shape, out)
|
|
elseif shape.mode == 'line' or shape.mode == 'manhattan' then
|
|
export_line(drawing, shape, out)
|
|
elseif shape.mode == 'polygon' or shape.mode == 'rectangle' or shape.mode == 'square' then
|
|
export_polygon(drawing, shape, out)
|
|
elseif shape.mode == 'circle' then
|
|
export_circle(drawing, shape, out)
|
|
elseif shape.mode == 'arc' then
|
|
export_circle_arc(drawing, shape, out)
|
|
elseif shape.mode == 'deleted' then
|
|
-- ignore
|
|
else
|
|
assert(false, ('unknown drawing mode %s'):format(shape.mode))
|
|
end
|
|
table.insert(out, '\n')
|
|
end
|
|
table.insert(out, '</svg>\n')
|
|
return table.concat(out)
|
|
end
|
|
|
|
function file_exists(filename)
|
|
local f = io.open(filename)
|
|
if f then
|
|
f:close()
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function export_freehand(shape, out)
|
|
table.insert(out, ('<path stroke="black" fill="none" d="M %d %d L'):format(shape.points[1].x, shape.points[1].y))
|
|
for i=2,#shape.points do
|
|
table.insert(out, (' %d %d'):format(shape.points[i].x, shape.points[i].y))
|
|
end
|
|
table.insert(out, '"/>\n')
|
|
end
|
|
|
|
function export_line(drawing, shape, out)
|
|
local p1 = drawing.points[shape.p1]
|
|
local p2 = drawing.points[shape.p2]
|
|
table.insert(out, ('<line stroke="black" x1="%d" y1="%d" x2="%d" y2="%d"/>\n'):format(p1.x, p1.y, p2.x, p2.y))
|
|
export_point(p1, out)
|
|
export_point(p2, out)
|
|
end
|
|
|
|
function export_polygon(drawing, shape, out)
|
|
table.insert(out, '<polygon stroke="black" fill="none" points="')
|
|
for _,p in ipairs(shape.vertices) do
|
|
local vertex = drawing.points[p]
|
|
table.insert(out, ('%d,%d, '):format(vertex.x, vertex.y))
|
|
end
|
|
table.insert(out, '"/>\n')
|
|
for _,p in ipairs(shape.vertices) do
|
|
export_point(drawing.points[p], out)
|
|
end
|
|
end
|
|
|
|
function export_circle(drawing, shape, out)
|
|
local center = drawing.points[shape.center]
|
|
table.insert(out, ('<circle stroke="black" fill="none" cx="%d" cy="%d" r="%d"/>\n'):format(center.x, center.y, shape.radius))
|
|
export_point(center, out)
|
|
end
|
|
|
|
function export_circle_arc(drawing, shape, out)
|
|
local center = drawing.points[shape.center]
|
|
local cx,cy = center.x, center.y
|
|
-- angle 0
|
|
local zx,zy = cx+shape.radius, cy
|
|
local sx,sy = geom.rotate(cx,cy, zx,zy, shape.start_angle)
|
|
local ex,ey = geom.rotate(cx,cy, zx,zy, shape.end_angle)
|
|
local sweep_flag = 0
|
|
if shape.start_angle < shape.end_angle then
|
|
sweep_flag = 1
|
|
end
|
|
table.insert(out, ('<path stroke="black" fill="none" d="M %d %d A %d,%d 0 0 %d %d,%d"/>'):format(sx,sy, shape.radius,shape.radius, sweep_flag, ex,ey))
|
|
export_point(center, out)
|
|
end
|
|
|
|
function export_point(p, out)
|
|
table.insert(out, ('<circle cx="%d" cy="%d" r="1"/>\n'):format(p.x, p.y))
|
|
if p.name then
|
|
-- couple of adjustments:
|
|
-- * lines.love text coordinate starts at top left, but SVG starts at baseline.
|
|
--
|
|
-- * lines.love renders labels at x,y both offset by 5px on the screen.
|
|
-- While rendering SVG, however, we don't have pixels, only viewport coordinates. Seems to work well to just drop the increment.
|
|
table.insert(out, ('<text fill="black" x="%d" y="%d">%s</text>\n'):format(p.x, p.y+Drawing_text_baseline_height, p.name))
|
|
end
|
|
end
|
|
|
|
function basename(s)
|
|
return string.gsub(s, "(.*/)(.*)", "%2")
|
|
end
|