about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--text.lua17
-rw-r--r--text_tests.lua22
2 files changed, 38 insertions, 1 deletions
diff --git a/text.lua b/text.lua
index 5e9e724..22e7349 100644
--- a/text.lua
+++ b/text.lua
@@ -683,7 +683,7 @@ function Text.to_pos_on_line(line, mx, my)
       -- On all wrapped screen lines but the final one, clicks past end of
       -- line position cursor on final character of screen line.
       -- (The final screen line positions past end of screen line as always.)
-      if screen_line_index < #line.screen_line_starting_pos and mx > Line_width then
+      if screen_line_index < #line.screen_line_starting_pos and mx > Text.screen_line_width(line, screen_line_index) then
 --?         print('past end of non-final line; return')
         return line.screen_line_starting_pos[screen_line_index+1]-1
       end
@@ -710,6 +710,21 @@ end
 --  nearest_cursor_pos('gh', mx) = 2
 --  Cursor1.pos = 7 + 2 - 1 = 8
 
+function Text.screen_line_width(line, i)
+  local start_pos = line.screen_line_starting_pos[i]
+  local start_offset = Text.offset(line.data, start_pos)
+  local screen_line
+  if i < #line.screen_line_starting_pos then
+    local past_end_pos = line.screen_line_starting_pos[i+1]
+    local past_end_offset = Text.offset(line.data, past_end_pos)
+    screen_line = string.sub(line.data, start_offset, past_end_offset-1)
+  else
+    screen_line = string.sub(line.data, start_pos)
+  end
+  local screen_line_text = App.newText(love.graphics.getFont(), screen_line)
+  return App.width(screen_line_text)
+end
+
 function Text.nearest_cursor_pos(line, x)  -- x includes left margin
   if x == 0 then
     return 1
diff --git a/text_tests.lua b/text_tests.lua
index dca9062..af36c82 100644
--- a/text_tests.lua
+++ b/text_tests.lua
@@ -235,6 +235,28 @@ function test_click_on_wrapping_line_containing_non_ascii()
   check_eq(Cursor1.pos, 15, 'F - test_click_on_wrapping_line_containing_non_ascii/cursor')  -- one more than the number of UTF-8 code-points
 end
 
+function test_click_past_end_of_word_wrapping_line()
+  io.write('\ntest_click_past_end_of_word_wrapping_line')
+  -- display a long line wrapping at a word boundary on a screen of more realistic length
+  App.screen.init{width=200, height=80}
+                   -- 0        1         2
+                   -- 123456789012345678901
+  Lines = load_array{'the quick brown fox jumped over the lazy dog'}
+  Line_width = 160
+  Cursor1 = {line=1, pos=1}
+  Screen_top1 = {line=1, pos=1}
+  Screen_bottom1 = {}
+  App.draw()
+  local y = Margin_top
+  App.screen.check(y, 'the quick brown fox ', 'F - test_click_past_end_of_word_wrapping_line/baseline/screen:1')
+  y = y + Line_height
+  -- click past the end of the screen line but within Line_width
+  App.draw()
+  App.run_after_mouse_click(Line_width-2,y-2, 1)
+  -- cursor moves to end of screen line
+  check_eq(Cursor1.pos, 20, 'F - test_click_past_end_of_word_wrapping_line/cursor')
+end
+
 function test_select_text()
   io.write('\ntest_select_text')
   -- display a line of text