about summary refs log tree commit diff stats
path: root/drawing.lua
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2024-06-11 10:37:58 -0700
committerKartik K. Agaram <vc@akkartik.com>2024-06-11 10:37:58 -0700
commit69c88da98ca1bba3ab1c890639aa0228f125c467 (patch)
treeed5d0a06eeeb97d205a905efe73bd8730e79cd32 /drawing.lua
parentf2299cb422d0fc07a1b01f0c31f88e9ae5ab168f (diff)
downloadview.love-69c88da98ca1bba3ab1c890639aa0228f125c467.tar.gz
stop caching starty
This is quite useful because I used to have a long list of places in
which to invalidate the cache.
Diffstat (limited to 'drawing.lua')
-rw-r--r--drawing.lua107
1 files changed, 57 insertions, 50 deletions
diff --git a/drawing.lua b/drawing.lua
index 246c7ae..92e3d5f 100644
--- a/drawing.lua
+++ b/drawing.lua
@@ -6,16 +6,15 @@ require 'drawing_tests'
 -- into 256 parts.
 function Drawing.draw(State, line_index, y)
   local line = State.lines[line_index]
-  local line_cache = State.line_cache[line_index]
-  line_cache.starty = y
   local pmx,pmy = App.mouse_x(), App.mouse_y()
-  if pmx < State.right and pmy > line_cache.starty and pmy < line_cache.starty+Drawing.pixels(line.h, State.width) then
+  local starty = Text.starty(State, line_index)
+  if pmx < State.right and pmy > starty and pmy < starty+Drawing.pixels(line.h, State.width) then
     App.color(Icon_color)
-    love.graphics.rectangle('line', State.left,line_cache.starty, State.width,Drawing.pixels(line.h, State.width))
+    love.graphics.rectangle('line', State.left,starty, State.width,Drawing.pixels(line.h, State.width))
     if icon[State.current_drawing_mode] then
-      icon[State.current_drawing_mode](State.right-22, line_cache.starty+4)
+      icon[State.current_drawing_mode](State.right-22, starty+4)
     else
-      icon[State.previous_drawing_mode](State.right-22, line_cache.starty+4)
+      icon[State.previous_drawing_mode](State.right-22, starty+4)
     end
 
     if App.mouse_down(1) and love.keyboard.isDown('h') then
@@ -30,7 +29,7 @@ function Drawing.draw(State, line_index, y)
   end
 
   local mx = Drawing.coord(pmx-State.left, State.width)
-  local my = Drawing.coord(pmy-line_cache.starty, State.width)
+  local my = Drawing.coord(pmy-starty, State.width)
 
   for _,shape in ipairs(line.shapes) do
     if geom.on_shape(mx,my, line, shape) then
@@ -38,11 +37,11 @@ function Drawing.draw(State, line_index, y)
     else
       App.color(Stroke_color)
     end
-    Drawing.draw_shape(line, shape, line_cache.starty, State.left,State.right)
+    Drawing.draw_shape(line, shape, starty, State.left,State.right)
   end
 
   local function px(x) return Drawing.pixels(x, State.width)+State.left end
-  local function py(y) return Drawing.pixels(y, State.width)+line_cache.starty end
+  local function py(y) return Drawing.pixels(y, State.width)+starty end
   for i,p in ipairs(line.points) do
     if p.deleted == nil then
       if Drawing.near(p, mx,my, State.width) then
@@ -71,7 +70,7 @@ function Drawing.draw(State, line_index, y)
     end
   end
   App.color(Current_stroke_color)
-  Drawing.draw_pending_shape(line, line_cache.starty, State.left,State.right)
+  Drawing.draw_pending_shape(line, starty, State.left,State.right)
 end
 
 function Drawing.draw_shape(drawing, shape, top, left,right)
@@ -209,17 +208,24 @@ function Drawing.draw_pending_shape(drawing, top, left,right)
   end
 end
 
-function Drawing.in_drawing(drawing, line_cache, x,y, left,right)
-  if line_cache.starty == nil then return false end  -- outside current page
+function Drawing.in_current_drawing(State, x,y, left,right)
+  return Drawing.in_drawing(State, State.lines.current_drawing_index, x,y, left,right)
+end
+
+function Drawing.in_drawing(State, line_index, x,y, left,right)
+  assert(State.lines[line_index].mode == 'drawing')
+  local starty = Text.starty(State, line_index)
+  if starty == nil then return false end  -- outside current page
+  local drawing = State.lines[line_index]
   local width = right-left
-  return y >= line_cache.starty and y < line_cache.starty + Drawing.pixels(drawing.h, width) and x >= left and x < right
+  return y >= starty and y < starty + Drawing.pixels(drawing.h, width) and x >= left and x < right
 end
 
 function Drawing.mouse_press(State, drawing_index, x,y, mouse_button)
   local drawing = State.lines[drawing_index]
-  local line_cache = State.line_cache[drawing_index]
+  local starty = Text.starty(State, drawing_index)
   local cx = Drawing.coord(x-State.left, State.width)
-  local cy = Drawing.coord(y-line_cache.starty, State.width)
+  local cy = Drawing.coord(y-starty, State.width)
   if State.current_drawing_mode == 'freehand' then
     drawing.pending = {mode=State.current_drawing_mode, points={{x=cx, y=cy}}}
   elseif State.current_drawing_mode == 'line' or State.current_drawing_mode == 'manhattan' then
@@ -244,8 +250,8 @@ end
 function Drawing.update(State)
   if State.lines.current_drawing == nil then return end
   local drawing = State.lines.current_drawing
-  local line_cache = State.line_cache[State.lines.current_drawing_index]
-  if line_cache.starty == nil then
+  local starty = Text.starty(State, State.lines.current_drawing_index)
+  if starty == nil then
     -- some event cleared starty just this frame
     -- draw in this frame will soon set starty
     -- just skip this frame
@@ -254,9 +260,9 @@ function Drawing.update(State)
   assert(drawing.mode == 'drawing', 'Drawing.update: line is not a drawing')
   local pmx, pmy = App.mouse_x(), App.mouse_y()
   local mx = Drawing.coord(pmx-State.left, State.width)
-  local my = Drawing.coord(pmy-line_cache.starty, State.width)
+  local my = Drawing.coord(pmy-starty, State.width)
   if App.mouse_down(1) then
-    if Drawing.in_drawing(drawing, line_cache, pmx,pmy, State.left,State.right) then
+    if Drawing.in_current_drawing(State, pmx,pmy, State.left,State.right) then
       if drawing.pending.mode == 'freehand' then
         table.insert(drawing.pending.points, {x=mx, y=my})
       elseif drawing.pending.mode == 'move' then
@@ -266,7 +272,7 @@ function Drawing.update(State)
       end
     end
   elseif State.current_drawing_mode == 'move' then
-    if Drawing.in_drawing(drawing, line_cache, pmx, pmy, State.left,State.right) then
+    if Drawing.in_current_drawing(State, pmx, pmy, State.left,State.right) then
       drawing.pending.target_point.x = mx
       drawing.pending.target_point.y = my
       Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
@@ -304,7 +310,7 @@ function Drawing.mouse_release(State, x,y, mouse_button)
     end
   elseif State.lines.current_drawing then
     local drawing = State.lines.current_drawing
-    local line_cache = State.line_cache[State.lines.current_drawing_index]
+    local starty = Text.starty(State, State.lines.current_drawing_index)
     if drawing.pending then
       if drawing.pending.mode == nil then
         -- nothing pending
@@ -313,14 +319,14 @@ function Drawing.mouse_release(State, x,y, mouse_button)
         Drawing.smoothen(drawing.pending)
         table.insert(drawing.shapes, drawing.pending)
       elseif drawing.pending.mode == 'line' then
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           drawing.pending.p2 = Drawing.find_or_insert_point(drawing.points, mx,my, State.width)
           table.insert(drawing.shapes, drawing.pending)
         end
       elseif drawing.pending.mode == 'manhattan' then
         local p1 = drawing.points[drawing.pending.p1]
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           if math.abs(mx-p1.x) > math.abs(my-p1.y) then
             drawing.pending.p2 = Drawing.find_or_insert_point(drawing.points, mx, p1.y, State.width)
@@ -328,11 +334,11 @@ function Drawing.mouse_release(State, x,y, mouse_button)
             drawing.pending.p2 = Drawing.find_or_insert_point(drawing.points, p1.x, my, State.width)
           end
           local p2 = drawing.points[drawing.pending.p2]
-          App.mouse_move(State.left+Drawing.pixels(p2.x, State.width), line_cache.starty+Drawing.pixels(p2.y, State.width))
+          App.mouse_move(State.left+Drawing.pixels(p2.x, State.width), starty+Drawing.pixels(p2.y, State.width))
           table.insert(drawing.shapes, drawing.pending)
         end
       elseif drawing.pending.mode == 'polygon' then
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           table.insert(drawing.pending.vertices, Drawing.find_or_insert_point(drawing.points, mx,my, State.width))
           table.insert(drawing.shapes, drawing.pending)
@@ -340,7 +346,7 @@ function Drawing.mouse_release(State, x,y, mouse_button)
       elseif drawing.pending.mode == 'rectangle' then
         assert(#drawing.pending.vertices <= 2, 'Drawing.mouse_release: rectangle has too many pending vertices')
         if #drawing.pending.vertices == 2 then
-          local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+          local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
           if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
             local first = drawing.points[drawing.pending.vertices[1]]
             local second = drawing.points[drawing.pending.vertices[2]]
@@ -355,7 +361,7 @@ function Drawing.mouse_release(State, x,y, mouse_button)
       elseif drawing.pending.mode == 'square' then
         assert(#drawing.pending.vertices <= 2, 'Drawing.mouse_release: square has too many pending vertices')
         if #drawing.pending.vertices == 2 then
-          local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+          local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
           if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
             local first = drawing.points[drawing.pending.vertices[1]]
             local second = drawing.points[drawing.pending.vertices[2]]
@@ -366,14 +372,14 @@ function Drawing.mouse_release(State, x,y, mouse_button)
           end
         end
       elseif drawing.pending.mode == 'circle' then
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           local center = drawing.points[drawing.pending.center]
           drawing.pending.radius = round(geom.dist(center.x,center.y, mx,my))
           table.insert(drawing.shapes, drawing.pending)
         end
       elseif drawing.pending.mode == 'arc' then
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
           local center = drawing.points[drawing.pending.center]
           drawing.pending.end_angle = geom.angle_with_hint(center.x,center.y, mx,my, drawing.pending.end_angle)
@@ -477,13 +483,15 @@ function Drawing.keychord_press(State, chord)
     end
     drawing.pending.mode = 'square'
   elseif App.mouse_down(1) and chord == 'p' and State.current_drawing_mode == 'polygon' then
-    local _,drawing,line_cache = Drawing.current_drawing(State)
-    local mx,my = Drawing.coord(App.mouse_x()-State.left, State.width), Drawing.coord(App.mouse_y()-line_cache.starty, State.width)
+    local drawing_index,drawing = Drawing.current_drawing(State)
+    local starty = Text.starty(State, drawing_index)
+    local mx,my = Drawing.coord(App.mouse_x()-State.left, State.width), Drawing.coord(App.mouse_y()-starty, State.width)
     local j = Drawing.find_or_insert_point(drawing.points, mx,my, State.width)
     table.insert(drawing.pending.vertices, j)
   elseif App.mouse_down(1) and chord == 'p' and (State.current_drawing_mode == 'rectangle' or State.current_drawing_mode == 'square') then
-    local _,drawing,line_cache = Drawing.current_drawing(State)
-    local mx,my = Drawing.coord(App.mouse_x()-State.left, State.width), Drawing.coord(App.mouse_y()-line_cache.starty, State.width)
+    local drawing_index,drawing = Drawing.current_drawing(State)
+    local starty = Text.starty(State, drawing_index)
+    local mx,my = Drawing.coord(App.mouse_x()-State.left, State.width), Drawing.coord(App.mouse_y()-starty, State.width)
     local j = Drawing.find_or_insert_point(drawing.points, mx,my, State.width)
     while #drawing.pending.vertices >= 2 do
       table.remove(drawing.pending.vertices)
@@ -492,9 +500,10 @@ function Drawing.keychord_press(State, chord)
   elseif chord == 'C-o' and not App.mouse_down(1) then
     State.current_drawing_mode = 'circle'
   elseif App.mouse_down(1) and chord == 'a' and State.current_drawing_mode == 'circle' then
-    local _,drawing,line_cache = Drawing.current_drawing(State)
+    local drawing_index,drawing = Drawing.current_drawing(State)
+    local starty = Text.starty(State, drawing_index)
     drawing.pending.mode = 'arc'
-    local mx,my = Drawing.coord(App.mouse_x()-State.left, State.width), Drawing.coord(App.mouse_y()-line_cache.starty, State.width)
+    local mx,my = Drawing.coord(App.mouse_x()-State.left, State.width), Drawing.coord(App.mouse_y()-starty, State.width)
     local center = drawing.points[drawing.pending.center]
     drawing.pending.radius = round(geom.dist(center.x,center.y, mx,my))
     drawing.pending.start_angle = geom.angle(center.x,center.y, mx,my)
@@ -510,7 +519,7 @@ function Drawing.keychord_press(State, chord)
     end
     drawing.pending.mode = 'circle'
   elseif chord == 'C-u' and not App.mouse_down(1) then
-    local drawing_index,drawing,line_cache,i,p = Drawing.select_point_at_mouse(State)
+    local drawing_index,drawing,_,i,p = Drawing.select_point_at_mouse(State)
     if drawing then
       if State.previous_drawing_mode == nil then
         State.previous_drawing_mode = State.current_drawing_mode
@@ -521,7 +530,7 @@ function Drawing.keychord_press(State, chord)
       State.lines.current_drawing = drawing
     end
   elseif chord == 'C-n' and not App.mouse_down(1) then
-    local drawing_index,drawing,line_cache,point_index,p = Drawing.select_point_at_mouse(State)
+    local drawing_index,drawing,_,point_index,p = Drawing.select_point_at_mouse(State)
     if drawing then
       if State.previous_drawing_mode == nil then
         -- don't clobber
@@ -619,9 +628,8 @@ function Drawing.current_drawing(State)
   local x, y = App.mouse_x(), App.mouse_y()
   for drawing_index,drawing in ipairs(State.lines) do
     if drawing.mode == 'drawing' then
-      local line_cache = State.line_cache[drawing_index]
-      if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) then
-        return drawing_index,drawing,line_cache
+      if Drawing.in_drawing(State, drawing_index, x,y, State.left,State.right) then
+        return drawing_index,drawing
       end
     end
   end
@@ -632,12 +640,12 @@ function Drawing.select_shape_at_mouse(State)
   for drawing_index,drawing in ipairs(State.lines) do
     if drawing.mode == 'drawing' then
       local x, y = App.mouse_x(), App.mouse_y()
-      local line_cache = State.line_cache[drawing_index]
-      if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) then
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+      local starty = Text.starty(State, drawing_index)
+      if Drawing.in_drawing(State, drawing_index, x,y, State.left,State.right) then
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         for i,shape in ipairs(drawing.shapes) do
           if geom.on_shape(mx,my, drawing, shape) then
-            return drawing,line_cache,i,shape
+            return drawing,starty,i,shape
           end
         end
       end
@@ -649,12 +657,12 @@ function Drawing.select_point_at_mouse(State)
   for drawing_index,drawing in ipairs(State.lines) do
     if drawing.mode == 'drawing' then
       local x, y = App.mouse_x(), App.mouse_y()
-      local line_cache = State.line_cache[drawing_index]
-      if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) then
-        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width)
+      local starty = Text.starty(State, drawing_index)
+      if Drawing.in_drawing(State, drawing_index, x,y, State.left,State.right) then
+        local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
         for i,point in ipairs(drawing.points) do
           if Drawing.near(point, mx,my, State.width) then
-            return drawing_index,drawing,line_cache,i,point
+            return drawing_index,drawing,starty,i,point
           end
         end
       end
@@ -666,8 +674,7 @@ function Drawing.select_drawing_at_mouse(State)
   for drawing_index,drawing in ipairs(State.lines) do
     if drawing.mode == 'drawing' then
       local x, y = App.mouse_x(), App.mouse_y()
-      local line_cache = State.line_cache[drawing_index]
-      if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) then
+      if Drawing.in_drawing(State, drawing_index, x,y, State.left,State.right) then
         return drawing
       end
     end