-- text editor, particularly text drawing, horizontal wrap, vertical scrolling Text = {} local utf8 = require 'utf8' require 'search' require 'select' require 'undo' require 'text_tests' -- return values: -- y coordinate drawn until in px -- position of start of final screen line drawn function Text.draw(line, line_width, line_index) --? print('text.draw') love.graphics.setColor(0,0,0) -- wrap long lines local x = 25 local y = line.y local pos = 1 local screen_line_starting_pos = 1 if line.fragments == nil then Text.compute_fragments(line, line_width) end if line.screen_line_starting_pos == nil then Text.populate_screen_line_starting_pos(line_index) end --? print('--') for _, f in ipairs(line.fragments) do local frag, frag_text = f.data, f.text -- render fragment local frag_width = App.width(frag_text) local frag_len = utf8.len(frag) --? 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)..'; 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 Text.lt1(Screen_top1, {line=line_index, pos=pos}) then y = y + Line_height if y + Line_height > App.screen.height then --? 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) end x = 25 end --? print('checking to draw', pos, Screen_top1.pos) -- don't draw text above screen top if Text.le1(Screen_top1, {line=line_index, pos=pos}) then if Selection1.line then local lo, hi = Text.clip_selection(line_index, pos, pos+frag_len) Text.draw_highlight(line, x,y, pos, lo,hi) end --? print('drawing '..frag) App.screen.draw(frag_text, x,y) end -- render cursor if necessary if line_index == Cursor1.line then if pos <= Cursor1.pos and pos + frag_len > Cursor1.pos then if Search_term then if Lines[Cursor1.line].data:sub(Cursor1.pos, Cursor1.pos+utf8.len(Search_term)-1) == Search_term then local lo_px = Text.draw_highlight(line, x,y, pos, Cursor1.pos, Cursor1.pos+utf8.len(Search_term)) love.graphics.setColor(0,0,0) love.graphics.print(Search_term, x+lo_px,y) end else Text.draw_cursor(x+Text.x(frag, Cursor1.pos-pos+1), y) end end end x = x + frag_width pos = pos + frag_len end if Search_term == nil then if line_index == Cursor1.line and Cursor1.pos == pos then Text.draw_cursor(x, y) end end return y, screen_line_starting_pos end -- manual tests: -- draw with small line_width of 100 function Text.draw_cursor(x, y) love.graphics.setColor(1,0,0) love.graphics.circle('fill', x,y+Line_height, 3) love.graphics.setColor(0,0,0) Cursor_x = x Cursor_y = y+Line_height end function Text.compute_fragments(line, line_width) --? print('compute_fragments', 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 = App.newText(love.graphics.getFont(), frag) local frag_width = App.width(frag_text) --? 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 --?
// "a type" "needed java_imports"