-- primitives for editing drawings Drawing = {} geom = require 'geom' function Drawing.draw(line, y) local pmx,pmy = love.mouse.getX(), love.mouse.getY() if pmx < 16+Drawing_width and pmy > line.y and pmy < line.y+Drawing.pixels(line.h) then love.graphics.setColor(0.75,0.75,0.75) love.graphics.rectangle('line', 16,line.y, Drawing_width,Drawing.pixels(line.h)) if icon[Current_drawing_mode] then icon[Current_drawing_mode](16+Drawing_width-20, line.y+4) else icon[Previous_drawing_mode](16+Drawing_width-20, line.y+4) end if love.mouse.isDown('1') and love.keyboard.isDown('h') then draw_help_with_mouse_pressed(line) return end end if line.show_help then draw_help_without_mouse_pressed(line) return end local mx,my = Drawing.coord(pmx-16), Drawing.coord(pmy-line.y) for _,shape in ipairs(line.shapes) do assert(shape) if geom.on_shape(mx,my, line, shape) then love.graphics.setColor(1,0,0) else love.graphics.setColor(0,0,0) end Drawing.draw_shape(16,line.y, line, shape) end for _,p in ipairs(line.points) do if p.deleted == nil then if Drawing.near(p, mx,my) then love.graphics.setColor(1,0,0) love.graphics.circle('line', Drawing.pixels(p.x)+16,Drawing.pixels(p.y)+line.y, 4) else love.graphics.setColor(0,0,0) love.graphics.circle('fill', Drawing.pixels(p.x)+16,Drawing.pixels(p.y)+line.y, 2) end end end love.graphics.setColor(0.75,0.75,0.75) Drawing.draw_pending_shape(16,line.y, line) end function Drawing.draw_shape(left,top, drawing, shape) if shape.mode == 'freehand' then local prev = nil for _,point in ipairs(shape.points) do if prev then love.graphics.line(Drawing.pixels(prev.x)+left,Drawing.pixels(prev.y)+top, Drawing.pixels(point.x)+left,Drawing.pixels(point.y)+top) end prev = point end elseif shape.mode == 'line' or shape.mode == 'manhattan' then local p1 = drawing.points[shape.p1] local p2 = drawing.points[shape.p2] love.graphics.line(Drawing.pixels(p1.x)+left,Drawing.pixels(p1.y)+top, Drawing.pixels(p2.x)+left,Drawing.pixels(p2.y)+top) elseif shape.mode == 'polygon' or shape.mode == 'rectangle' or shape.mode == 'square' then local prev = nil for _,point in ipairs(shape.vertices) do local curr = drawing.points[point] if prev then love.graphics.line(Drawing.pixels(prev.x)+left,Drawing.pixels(prev.y)+top, Drawing.pixels(curr.x)+left,Drawing.pixels(curr.y)+top) end prev = curr end -- close the loop local curr = drawing.points[shape.vertices[1]] love.graphics.line(Drawing.pixels(prev.x)+left,Drawing.pixels(prev.y)+top, Drawing.pixels(curr.x)+left,Drawing.pixels(curr.y)+top) elseif shape.mode == 'circle' then local center = drawing.points[shape.center] love.graphics.circle('line', Drawing.pixels(center.x)+left,Drawing.pixels(center.y)+top, Drawing.pixels(shape.radius)) elseif shape.mode == 'arc' then local center = drawing.points[shape.center] love.graphics.arc('line', 'open', Drawing.pixels(center.x)+left,Drawing.pixels(center.y)+top, Drawing.pixels(shape.radius), shape.start_angle, shape.end_angle, 360) elseif shape.mode == 'deleted' then -- ignore else print(shape.mode) assert(false) end end function Drawing.draw_pending_shape(left,top, drawing) local shape = drawing.pending if shape.mode == nil then -- nothing pending elseif shape.mode == 'freehand' then Drawing.draw_shape(left,top, drawing, shape) elseif shape.mode == 'line' then local mx,my = Drawing.coord(love.mouse.getX()-left), Drawing.coord(love.mouse.getY()-top) if mx < 0 or mx >= 256 or my < 0 or my >= drawing.h then return end local p1 = drawing.points[shape.p1] love.graphics.line(Drawing.pixels(p1.x)+left,Drawing.pixels(p1.y)+top, Drawing.pixels(mx)+left,Drawing.pixels(my)+top) elseif shape.mode == 'manhattan' then local mx,my = Drawing.coord(love.mouse.getX()-left), Drawing.coord(love.mouse.getY()-top) if mx < 0 or mx >= 256 or my < 0 or my >= drawing.h then return end local p1 = drawing.points[shape.p1] if math.abs(mx-p1.x) > math.abs(my-p1.y) then love.graphics.line(Drawing.pixels(p1.x)+left,Drawing.pixels(p1.y)+top, Drawing.pixels(mx)+left,Drawing.pixels(p1.y)+top) else love.graphics.line(Drawing.pixels(p1.x)+left,Drawing.pixels(p1.y)+top, Drawing.pixels(p1.x)+left,Drawing.pixels(my)+top) end elseif shape.mode == 'polygon' then -- don't close the loop on a pending polygon local prev = nil for _,point in ipairs(shape.vertices) do local curr = drawing.points[point] if prev then love.graphics.line(Drawing.pixels(prev.x)+left,Drawing.pixels(prev.y)+top, Drawing.pixels(curr.x)+left,Drawing.pixels(curr.y)+top) end prev = curr end love.graphics.line(Drawing.pixels(prev.x)+left,Drawing.pixels(prev.y)+top, love.mouse.getX(),love.mouse.getY()) elseif shape.mode == 'rectangle' then local pmx,pmy = love.mouse.getX(), love.mouse.getY() local first = drawing.points[shape.vertices[1]] if #shape.vertices == 1 then love.graphics.line(Drawing.pixels(first.x)+left,Drawing.pixels(first.y)+top, pmx,pmy) return end local second = drawing.points[shape.vertices[2]] local mx,my = Drawing.coord(pmx-left), Drawing.coord(pmy-top) local thirdx,thirdy, fourthx,fourthy = Drawing.complete_rectangle(first.x,first.y, second.x,second.y, mx,my) love.graphics.line(Drawing.pixels(first.x)+left,Drawing.pixels(first.y)+top, Drawing.pixels(second.x)+left,Drawing.pixels(second.y)+top) love.graphics.line(Drawing.pixels(second.x)+left,Drawing.pixels(second.y)+top, Drawing
c{0: 0 (((1 string-address)) <- ((new)) ) -- nil
c{0: 1 (((2 string-address)) <- ((new)) abc) -- nil
c{0: 2 (((3 boolean)) <- ((match-at)) ((1 string-address)) ((2 string-address)) ((0 literal))) -- nil
c{1: 0 ✓ (((1 string-address)) <- ((new)) )
c{1: 1 ✓ (((2 string-address)) <- ((new)) abc)
c{1: 2 ✓ (((3 boolean)) <- ((match-at)) ((1 string-address)) ((2 string-address)) ((0 literal)))
cn0: convert-names in main
cn0: (((1 string-address)) <- ((new)) ) nil nil
cn0: checking arg
cn0: checking oarg ((1 string-address))
maybe-add: ((1 string-address))
cn0: (((2 string-address)) <- ((new)) abc) nil nil
cn0: checking arg abc
cn0: checking oarg ((2 string-address))
maybe-add: ((2 string-address))
cn0: (((3 boolean)) <- ((match-at)) ((1 string-address)) ((2 string-address)) ((0 literal))) nil nil
cn0: checking arg ((1 string-address))
maybe-add: ((1 string-address))
cn0: checking arg ((2 string-address))
maybe-add: ((2 string-address))
cn0: checking arg ((0 literal))
cn0: checking oarg ((3 boolean))
maybe-add: ((3 boolean))
cn1: (((1 string-address)) <- ((new)) )
cn1: (((2 string-address)) <- ((new)) abc)
cn1: (((3 boolean)) <- ((match-at)) ((1 string-address)) ((2 string-address)) ((0 literal)))
schedule: main
run: main 0: (((1 string-address)) <- ((new)) )
run: main 0: 1000 => ((1 string-address))
mem: ((1 string-address)): 1 <= 1000
run: main 1: (((2 string-address)) <- ((new)) abc)
run: main 1: 1001 => ((2 string-address))
mem: ((2 string-address)): 2 <= 1001
run: main 2: (((3 boolean)) <- ((match-at)) ((1 string-address)) ((2 string-address)) ((0 literal)))
mem: ((1 string-address)) => 1000
mem: ((2 string-address)) => 1001
run: match-at/main 0: (((default-space space-address)) <- ((new)) ((space literal)) ((30 literal)))
run: match-at/main 0: 1005 => ((default-space space-address))
run: match-at/main 1: (((1 string-address)) <- ((next-input)))
arg: nil 0 (1000 1001 0)
run: match-at/main 1: 1000 => ((1 string-address))
mem: ((1 string-address)): 1007 <= 1000
run: match-at/main 2: (((2 string-address)) <- ((next-input)))
arg: nil 1 (1000 1001 0)
run: match-at/main 2: 1001 => ((2 string-address))
mem: ((2 string-address)): 1008 <= 1001
run: match-at/main 3: (((3 integer)) <- ((next-input)))
arg: nil 2 (1000 1001 0)
run: match-at/main 3: 0 => ((3 integer))
mem: ((3 integer)): 1009 <= 0
run: match-at/main 4: (((4 integer)) <- ((length)) ((2 string-address) (deref)))
array-len: ((2 string-address) (deref))
mem: ((1001 integer) (raw)) => 3
run: match-at/main 4: 3 => ((4 integer))
mem: ((4 integer)): 1010 <= 3
run: match-at/main 5: (((5 integer)) <- ((length)) ((1 string-address) (deref)))
array-len: ((1 string-address) (deref))
mem: ((1000 integer) (raw)) => 0
run: match-at/main 5: 0 => ((5 integer))
mem: ((5 integer)): 1011 <= 0
run: match-at/main 6: (((5 integer)) <- ((subtract)) ((5 integer)) ((4 integer)))
mem: ((5 integer)) => 0
mem: ((4 integer)) => 3
run: match-at/main 6: -3 => ((5 integer))
mem: ((5 integer)): 1011 <= -3
run: match-at/main 7: (((6 boolean)) <- ((lesser-or-equal)) ((3 integer)) ((5 integer)))
mem: ((3 integer)) => 0
mem: ((5 integer)) => -3
run: match-at/main 7: nil => ((6 boolean))
mem: ((6 boolean)): 1012 <= nil
run: match-at/main 8: (((jump-if)) ((6 boolean)) ((1 offset)))
mem: ((6 boolean)) => nil
run: match-at/main 9: (((reply)) ((nil literal)))
run: main 2: nil => ((3 boolean))
mem: ((3 boolean)): 3 <= nil
schedule: done with routine nil