This is quite useful because I used to have a long list of places in which to invalidate the cache.
2TCIWW6ZC73FHPZLO5QOBUFZCIL74U2MBYTPNXFYYFJ7IH4YAGUQC FNJF2FMQJPQDVLHDZTVMUX5R3LGRKLGSNUPTHUT2WZY3RKVSNRIQC YRJFJNUDVPX2OAK7OKRYCVYDGMJI4XL4JASN4JJ7QGIPCVQI22TAC ZS5IYZH5EXXPSVIFWS7XW5POEVRRCK6XV6PB36D3EJXJRT22LKOQC P6SYWBLBN2KAYQ6VJBPYZQNCD2WQHOZGC6XOKWW4SLAMFFGH3ZYQC LXTTOB33N2HCUZFIUDRQGGBVHK2HODRG4NBLH6RXRQZDCHF27BSAC LF7BWEG4DKQI7NMXMZC4LC2BE5PB42HK5PD6OYBNIDMAZBJASOKQC IFTYOERMW7P3I24WISZN35X3GWJ5MSMRYDRBK3L52GCZTPP3CWZQC WAR3HXHTN7JZVV6TFMU2F3QYAG6NDH7DN7KKPTM2ICEHRNQYP6PAC 6RYLD5ONDIQFWU5CNL4NGHJQ2LNAZZFGTPXQJDNJGLNYAUOTUI7QC ZLJGZYQGQ2S4UFWTVF4PQDSGMP6A4IS4GDHCMBAAA5SK2N2NWR3QC RMKMPFT5L67WIFWIO4GTC6XESX6UPKNL4GPNQLOBC5CXSUZABEHQC TGHAJBESCIEGWUE2D3FGLNOIAYT4D2IRGZKRXRMTUFW7QZETC7OAC ILOA5BYFTQKBSHLFMMZUVPQ2JXBFJD62ERQFBTDK2WSRXUN525VQC BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC MXA3RZYKUI4UF2ISY7JEF6VKX6NOPZMZH5SLLCZHRJKFIXXXDPSAC ODLKHO7BO2AODYO2OEQ6D4NSNBT5GR3CKLUXWMDLRYXL7DJOI7BAC HYEAFRZ2UEKDYTAE2GDQLHEJBPQASP2NDLMXB7F6MTVK2BKOXKEAC G3DLS5OUO77V4MC6754KTETRCTVUBYBHMGR7MTV52IYYM7QA3ROQC BOFNXP5GZDCUMQG3LQVTSSFEQP7REQ4RIRJLDLETFSAGFTVDVEKAC KOTNETIMJP2G753SAAQHR5LNOIC7LWLTFSY3QXA276L3TUN63UHQC KKMFQDR43ZWVCDRHQLWWX3FCWCFA3ZSXYOBRJNPHUQZR2XPKWULAC KMSL74GAMFNTAKGDKZFP2AMQXUMOC3XH373BO4IABZWBEP3YAXKAC 5SM6DRHKPLFWQPCZDTVM4ENVENWBYBQ3Q2KYKSWLWYUTOSEPCRLAC G54H3YG2NEZPW2F6OYT5JPV7KSKVMNW5D3QT3FBCXTJHAQYTV5UAC OI4FPFINEROK6GNDEMOBTGSPYIULCLRGGT5W3H7VLM7VFH22GMWQC JYB3RFWHD6IXYGHJ77BEILJ5QNRPPH77DITIH4PKZM4D4OZSHRVQC KYNGDE2CKNOKUC2XMAS5MEU6YT2C3IW5SIZLOJE64G3ERT7BSWFAC 6XCJX4DZB6UEAXEXXUGVVPBCF5SNDYOJGU3Q6BPB4ZMI5DZH4MYQC VHQCNMARPMNBSIUFLJG7HVK4QGDNPCGNVFLHS3I4IGNVSV5MRLYQC 4KC7I3E2DIKLIP7LQRKB5WFA2Z5XZXAU46RFHNFQU5BVEJPDX6UQC UHB4GARJI5AB5UCDCZRFSCJNXGJSLU5DYGUGX5ITYEXI7Q43Z4CAC 2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC QAMVLUK22RP5RBDTDV5XVPQCSJUWDWESV4TRCUTNUM46E26BH2AQC 3OTESDW65UJ2W5RIXA6FNKRSD7TBCZTCCCEAYOQMEVGYZ6RCU34QC LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC ORRSP7FVCHI2TF5GXBRGQYYJAA3JFYXZBM3T663BKSBV22FCZVCAC K2X6G75Z6XBC4DVIRWC5HC7XA3A2SKOM3MWSQTCFEYWIJL7LME2QC BLWAYPKV3MLDZ4ALXLUJ25AIR6PCIL4RFYNRYLB26GFVC2KQBYBAC JFFUF5ALUWPDM7IEDEZVAYG2SVXO334STONRGKVB3QKY2TT5QGBQC 7JH2ZT3FCW4WX52IJFSLGRVZWQQVYJXULSQM2BM4BJUZWG3IVGKAC R3XGABERHYD7X42VXYENLVRSNFUXO5JAO4HCX3N4CMHZCHWEIW6AC FZCKGO2IA5ZMX7TD4HL3WBUR6NPOYYMT4RGVWF7KFQBFV2V3RZBAC AH744RFRNNEQ7THYLBD52BKUGPJJL36G5YLQY6NVU442UICAXUXQC NYQ7HD4D5L44UORK52TH7CAEXYN5CE4ZUVLCWMY6XXPYHXVBTGHAC KTZQ57HVZU4XGWRPXBA27G4GXZFV74YYKJRXCJCE7UKDS7NGJVBAC QFC3WRDZEZJM3UICG2R7YZL35JJNWKAML4KLHCDX2ZDKREWV44GQC DLQAEAC76KLM3KZXQ2C5DASP4IBS64GR6L7QYEP67CNXJ6LRL7LQC PJEQCTBL2ZX5Q7NJQ3KCWSHHBV2QWGYS5NVMRDNK5LOOIIRRIPHAC 4PHGNJN64ELUEU4SJH6KG36WNTATT3QSZYTY4I5R3XGRZHZPAQ4QC BXJMGTV2FMXDI5ML3OATRJ6O35L3T64S4TW4UYM37V3K3DICSC4AC DRFE3B3ZKRG4RY2R5Q3SDFD3LH4EXUX3CZCDFBNAXVI2SLDS57PAC RT6EV6OPUYCXYZOX2PHFXJ7KT77KHNEVINEGQXIQLHQVKPGTN6VQC QXVD2RIFQPTO3H6J3IJHRHRDRBW6C6MLUWMCEDQ6Z75SW2TMRBIQC SRVDX4I5QKWAH3Y5DX25PG34U7NY55H46ZYG2APH47BUZT3EJ2HAC 23MA4T3GWPOLM5S6JCNQJU2SRT7VQGYZ2JZJN26KA5MKI4LOCC4QC XNFTJHC4QSHNSIWNN7K6QZEZ37GTQYKHS4EPNSVPQCUSWREROGIQC BYG5CEMVXANDTBI2ORNVMEY6K3EBRIHZHS4QBK27VONJC5537COQC 3QNOKBFMKBGXBVJIRHR2444JRRMBTABHE4674NR3DT67RRM2X6GAC CUFW4EJL75OAA5BS5EXGTM5RMRNJOBBPAXUJADGZ3VLP2ZMKFOTAC end-- return the top y coordinate of a given line_index,-- or nil if no part of it is on screenfunction Text.starty(State, line_index)-- duplicate some logic from love.draw-- does not modify State (except to populate line_cache)if line_index < State.screen_top1.line then return endlocal loc2 = Text.to2(State, State.screen_top1)local y = State.topwhile true doif State.lines[loc2.line].mode == 'drawing' theny = y + Drawing_padding_topendif loc2.line == line_index then return y endif State.lines[loc2.line].mode == 'text' theny = y + State.line_heightelseif State.lines[loc2.line].mode == 'drawing' theny = y + Drawing.pixels(State.lines[loc2.line].h, State.width) + Drawing_padding_bottomendif y + State.line_height > App.screen.height then break endlocal next_loc2 = Text.next_screen_line(State, loc2)if Text.eq2(next_loc2, loc2) then break end -- end of fileloc2 = next_loc2end
if line_cache.starty == nil then return false end -- outside current pageif y < line_cache.starty then return false end
local starty = Text.starty(State, line_index)if starty == nil then return false end -- outside current pageif y < starty then return false end
return y < line_cache.starty + State.line_height*(#line_cache.screen_line_starting_pos - Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos) + 1)
return y < starty + State.line_height*(#line_cache.screen_line_starting_pos - Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos) + 1)
-- return the top y coordinate of a given line_index,-- or nil if no part of it is on screenfunction Text.starty(State, line_index)-- duplicate some logic from love.draw-- does not modify State (except to populate line_cache)if line_index < State.screen_top1.line then return endlocal loc2 = Text.to2(State, State.screen_top1)local y = State.topwhile true doif loc2.line == line_index then return y endif State.lines[loc2.line].mode == 'text' theny = y + State.line_heightelseif State.lines[loc2.line].mode == 'drawing' theny = y + Drawing_padding_height + Drawing.pixels(State.lines[loc2.line].h, State.width)endif y + State.line_height > App.screen.height then break endlocal next_loc2 = Text.next_screen_line(State, loc2)if Text.eq2(next_loc2, loc2) then break end -- end of fileloc2 = next_loc2endend
if line_cache.starty == nil then return false end -- outside current pageif y < line_cache.starty then return false end
local starty = Text.starty(State, line_index)if starty == nil then return false end -- outside current pageif y < starty then return false end
return y < line_cache.starty + State.line_height*(#line_cache.screen_line_starting_pos - Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos) + 1)
return y < starty + State.line_height*(#line_cache.screen_line_starting_pos - Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos) + 1)
love.graphics.rectangle('fill', State.left,line_cache.starty, State.width, math.max(Drawing.pixels(drawing.h, State.width),y-line_cache.starty))
love.graphics.rectangle('fill', State.left,starty, State.width, math.max(Drawing.pixels(drawing.h, State.width),y-starty))
love.graphics.rectangle('fill', State.left,line_cache.starty, State.width, math.max(Drawing.pixels(drawing.h, State.width),y-line_cache.starty))
love.graphics.rectangle('fill', State.left,starty, State.width, math.max(Drawing.pixels(drawing.h, State.width),y-starty))
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
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)endfunction 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 pagelocal drawing = State.lines[line_index]
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 _,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 line_cache = State.line_cache[drawing_index]if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) thenreturn drawing_index,drawing,line_cache
if Drawing.in_drawing(State, drawing_index, x,y, State.left,State.right) thenreturn drawing_index,drawing
local line_cache = State.line_cache[drawing_index]if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) thenlocal 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) thenlocal mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)
local line_cache = State.line_cache[drawing_index]if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) thenlocal 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) thenlocal mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-starty, State.width)