From 8d5ac5da75b853e833c7ad5f18ce468eebc2aa0b Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 23 May 2022 22:31:36 -0700 Subject: keep one screen line of overlap on pagedown I'm now extracting the concern of computing line.screen_line_starting_pos out of Text.draw. Earlier I had to make sure I ran through the whole line to compute screen_line_starting_pos, but that had the side-effect of updating Screen_bottom1.pos as well with lines that had never been rendered. In this process I hit my first bug due to an accidental global. It doesn't show up in the patch because I accidentally deleted a local declaration. (I thought I didn't need screen_line_starting_pos anymore, deleted everywhere, then brought it back everywhere from the bottom of the function up, but forgot to put back the very first occurrence.) The amount of yoyoing this caused between App.draw and Text.draw, I very much have spaghetti on my hands. Accidental globals are _terrible_ in a program with tests. Cross test contamination X-( --- text.lua | 61 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 18 deletions(-) (limited to 'text.lua') diff --git a/text.lua b/text.lua index f765dd9..edb03d4 100644 --- a/text.lua +++ b/text.lua @@ -19,39 +19,32 @@ function Text.draw(line, line_width, line_index) if line.fragments == nil then Text.compute_fragments(line, line_width) end - line.screen_line_starting_pos = nil -- TODO: avoid recomputing on every repaint + if line.screen_line_starting_pos == nil then + Text.populate_screen_line_starting_pos(line_index) + end if Debug_new_render then print('--') end for _, f in ipairs(line.fragments) do local frag, frag_text = f.data, f.text -- render fragment local frag_width = math.floor(App.width(frag_text)*Zoom) local s=tostring ---? print('('..s(x)..','..s(y)..') '..frag..'('..s(frag_width)..' vs '..s(line_width)..') '..s(line_index)..' vs '..s(Screen_top1.line)..'; '..s(pos)..' vs '..s(Screen_top1.pos)) +--? print('('..s(x)..','..s(y)..') '..frag..'('..s(frag_width)..' vs '..s(line_width)..') '..s(line_index)..' vs '..s(Screen_top1.line)..'; '..s(pos)..' vs '..s(Screen_top1.pos)..'; bottom: '..s(Screen_bottom1.line)..'/'..s(Screen_bottom1.pos)) if x + frag_width > line_width then assert(x > 25) -- no overfull lines -- update y only after drawing the first screen line of screen top if line_index > Screen_top1.line or (line_index == Screen_top1.line and pos > Screen_top1.pos) then y = y + math.floor(15*Zoom) ---? print('text: new screen line', y, App.screen.height, screen_line_starting_pos) - screen_line_starting_pos = pos - if Debug_new_render then print('y', y) end - end - x = 25 - if line.screen_line_starting_pos == nil then - line.screen_line_starting_pos = {1, pos} - else - table.insert(line.screen_line_starting_pos, pos) - end - -- if we updated y, check if we're done with the screen - if line_index > Screen_top1.line or (line_index == Screen_top1.line and pos > Screen_top1.pos) then ---? print('a') if y + math.floor(15*Zoom) > App.screen.height then ---? print('b', y, App.screen.height) +--? print('b', y, App.screen.height, '=>', screen_line_starting_pos) return y, screen_line_starting_pos end + screen_line_starting_pos = pos +--? print('text: new screen line', y, App.screen.height, screen_line_starting_pos) + if Debug_new_render then print('y', y) end end + x = 25 end - if Debug_new_render then print('checking to draw', pos, Screen_top1.pos) end +--? print('checking to draw', pos, Screen_top1.pos) -- don't draw text above screen top if line_index > Screen_top1.line or (line_index == Screen_top1.line and pos >= Screen_top1.pos) then if Debug_new_render then print('drawing '..frag) end @@ -148,7 +141,6 @@ function test_pagedown_skips_drawings() Screen_bottom1 = {} Zoom = 1 local screen_top_margin = 15 -- pixels - local text height = 15 local drawing_height = 20 + App.screen.width / 2 -- default -- initially the screen displays the first line and the drawing -- 15px margin + 15px line1 + 10px margin + 25px drawing + 10px margin = 75px < screen height 80px @@ -164,6 +156,39 @@ function test_pagedown_skips_drawings() App.screen.check(y, 'def', 'F - test_pagedown_skips_drawings/screen:1') end +function test_pagedown_shows_one_screen_line_in_common() + io.write('\ntest_pagedown_shows_one_screen_line_in_common') + -- some lines of text with a drawing intermixed + App.screen.init{width=50, height=60} + Lines = load_array{'abc', 'def ghi jkl', 'mno'} + Line_width = App.screen.width + Cursor1 = {line=1, pos=1} + Screen_top1 = {line=1, pos=1} + Screen_bottom1 = {} + Zoom = 1 + local screen_top_margin = 15 -- pixels + local line_height = math.floor(15*Zoom) -- pixels + App.draw() + local y = screen_top_margin + App.screen.check(y, 'abc', 'F - test_pagedown_shows_one_screen_line_in_common/baseline/screen:1') + y = y + line_height + App.screen.check(y, 'def ', 'F - test_pagedown_shows_one_screen_line_in_common/baseline/screen:2') + y = y + line_height + App.screen.check(y, 'ghi ', 'F - test_pagedown_shows_one_screen_line_in_common/baseline/screen:3') + -- after pagedown the bottom screen line becomes the top + App.run_after_keychord('pagedown') + check_eq(Screen_top1.line, 2, 'F - test_pagedown_shows_one_screen_line_in_common/screen_top:line') + check_eq(Screen_top1.pos, 5, 'F - test_pagedown_shows_one_screen_line_in_common/screen_top:pos') + check_eq(Cursor1.line, 2, 'F - test_pagedown_shows_one_screen_line_in_common/cursor:line') + check_eq(Cursor1.pos, 5, 'F - test_pagedown_shows_one_screen_line_in_common/cursor:pos') + y = screen_top_margin + App.screen.check(y, 'ghi ', 'F - test_pagedown_shows_one_screen_line_in_common/screen:1') + y = y + line_height + App.screen.check(y, 'jkl', 'F - test_pagedown_shows_one_screen_line_in_common/screen:2') + y = y + line_height + App.screen.check(y, 'mn', 'F - test_pagedown_shows_one_screen_line_in_common/screen:3') +end + function test_down_arrow_moves_cursor() io.write('\ntest_down_arrow_moves_cursor') App.screen.init{width=120, height=60} -- cgit 1.4.1-2-gfad0