snapshot: wrapping long lines at word boundaries

[?]
May 20, 2022, 12:29 AM
H2DPLWMVRFYTO2CQTG54FMT2LF3B6UKLXH32CUA22DNQJVP5XBNQC

Dependencies

  • [2] 4C375P53 this is a bit clearer
  • [3] UWNHC4AA redo y computations
  • [4] YJGADSGK delete unused arg
  • [5] XNFTJHC4 split keyboard handling between Text and Drawing
  • [6] BULPIBEG beginnings of a module for the text editor
  • [7] DLQMM265 scroll past first page
  • [8] B3IWYWSR delete another arg that can be deduced
  • [*] OTIBCAUJ love2d scaffold

Change contents

  • replacement in text.lua at line 6
    [3.44][3.1:63]()
    function Text.draw(line, line_index, cursor_line, cursor_pos)
    [3.44]
    [3.109]
    function Text.compute_fragments(line, line_width)
    line.fragments = {}
    local x = 25
    -- try to wrap at word boundaries
    for frag in line.data:gmatch('%S*%s*') do
    local frag_text = love.graphics.newText(love.graphics.getFont(), frag)
    local frag_width = math.floor(frag_text:getWidth()*Zoom)
    --? print('x: '..tostring(x)..'; '..tostring(line_width-x)..'px to go')
    --? print('frag: ^'..frag..'$ is '..tostring(frag_width)..'px wide')
    if x + frag_width > line_width then
    while x + frag_width > line_width do
    if x < 0.8*line_width then
    -- long word; chop it at some letter
    -- We're not going to reimplement TeX here.
    local b = Text.nearest_cursor_pos(frag, line_width - x)
    --? print('space for '..tostring(b)..' graphemes')
    local frag1 = string.sub(frag, 1, b)
    local frag1_text = love.graphics.newText(love.graphics.getFont(), frag1)
    local frag1_width = math.floor(frag1_text:getWidth()*Zoom)
    --? print('inserting '..frag1..' of width '..tostring(frag1_width)..'px')
    table.insert(line.fragments, {data=frag1, text=frag1_text})
    frag = string.sub(frag, b+1)
    frag_text = love.graphics.newText(love.graphics.getFont(), frag)
    frag_width = math.floor(frag_text:getWidth()*Zoom)
    end
    x = 25 -- new line
    end
    end
    if #frag > 0 then
    --? print('inserting '..frag..' of width '..tostring(frag_width)..'px')
    table.insert(line.fragments, {data=frag, text=frag_text})
    end
    end
    end
    function Text.draw(line, line_width, line_index, cursor_line, cursor_pos)
    love.graphics.setColor(0.75,0.75,0.75)
    love.graphics.line(line_width, 0, line_width, Screen_height)
  • replacement in text.lua at line 45
    [3.141][3.141:219](),[3.219][3.64:116](),[3.116][3.266:316](),[3.266][3.266:316](),[3.316][3.117:264]()
    local love_text = love.graphics.newText(love.graphics.getFont(), line.data)
    love.graphics.draw(love_text, 25,line.y, 0, Zoom)
    if line_index == cursor_line then
    -- cursor
    love.graphics.print('_', Text.cursor_x(line.data, cursor_pos), line.y+6) -- drop the cursor down a bit to account for the increased font size
    [3.141]
    [3.31]
    -- wrap long lines
    local x = 25
    local y = line.y
    local pos = 1
    if line.fragments == nil then
    Text.compute_fragments(line, line_width)
    end
    for _, f in ipairs(line.fragments) do
    local frag, frag_text = f.data, f.text
    -- render fragment
    local frag_width = math.floor(frag_text:getWidth()*Zoom)
    if x + frag_width > line_width then
    assert(x > 25) -- no overfull lines
    y = y + math.floor(15*Zoom)
    x = 25
    end
    love.graphics.draw(frag_text, x,y, 0, Zoom)
    -- render cursor if necessary
    local frag_len = utf8.len(frag)
    if line_index == cursor_line then
    if pos <= cursor_pos and pos + frag_len > cursor_pos then
    -- cursor
    love.graphics.print('_', x+Text.cursor_x2(frag, cursor_pos-pos+1), y+6) -- drop the cursor down a bit to account for the increased font size
    end
    end
    x = x + frag_width
    pos = pos + frag_len
  • edit in text.lua at line 73
    [3.37]
    [3.37]
    return y
  • edit in text.lua at line 75
    [3.41]
    [3.41]
    -- manual tests:
    -- draw with small line_width of 100
    -- short words break on spaces
    -- long words break when they must
  • edit in text.lua at line 95
    [3.453]
    [3.453]
    Lines[Cursor_line].fragments = nil
  • edit in text.lua at line 105
    [3.921]
    [3.921]
    Lines[Cursor_line].fragments = nil
  • edit in text.lua at line 162
    [3.2556]
    [3.2556]
    Lines[Cursor_line].fragments = nil
  • edit in text.lua at line 172
    [3.2907]
    [3.2907]
    Lines[Cursor_line-1].fragments = nil
  • edit in text.lua at line 188
    [3.3565]
    [3.3565]
    Lines[Cursor_line].fragments = nil
  • edit in text.lua at line 197
    [3.3861]
    [3.3861]
    Lines[Cursor_line].fragments = nil
  • edit in text.lua at line 322
    [3.1438]
    [3.1438]
    function Text.cursor_x2(s, cursor_pos)
    local s_before_cursor = s:sub(1, cursor_pos-1)
    local text_before_cursor = love.graphics.newText(love.graphics.getFont(), s_before_cursor)
    return math.floor(text_before_cursor:getWidth()*Zoom)
    end
  • replacement in main.lua at line 136
    [3.213][3.267:328](),[3.1510][3.267:328]()
    Text.draw(line, line_index, Cursor_line, Cursor_pos)
    [3.213]
    [2.56]
    y = Text.draw(line, 100, line_index, Cursor_line, Cursor_pos)
    --? y = Text.draw(line, Drawing_width, line_index, Cursor_line, Cursor_pos)
  • edit in main.lua at line 142
    [10.416]
    [10.416]
    --? os.exit(1)