Skip to content

Commit b2ac03f

Browse files
committed
fix: prevent unnecessary rerenders and recrop previous images on new splits
1 parent 9cbe8ea commit b2ac03f

File tree

3 files changed

+51
-36
lines changed

3 files changed

+51
-36
lines changed

lua/image/backends/kitty/init.lua

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ backend.render = function(image, x, y, width, height)
143143
helpers.restore_cursor()
144144

145145
-- utils.debug("[kitty] rendered image", image.id, "(" .. image.internal_id .. ")")
146+
-- utils.debug("path:", image.cropped_path, display_payload)
146147
end
147148

148149
backend.clear = function(image_id, shallow)

lua/image/image.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ end
3030
function Image:render(geometry)
3131
if geometry then self.geometry = vim.tbl_deep_extend("force", self.geometry, geometry) end
3232

33-
-- utils.debug(("\n\n---------------- %s ----------------"):format(self.id))
33+
-- utils.debug(("---------------- %s ----------------"):format(self.id))
3434
local was_rendered = renderer.render(self)
3535

36-
-- utils.debug(("[image] render: %s, success: %s x: %s, y: %s, width: %s, height: %s"):format( self.id, was_rendered, self.geometry.x, self.geometry.y, self.geometry.width, self.geometry.height))
36+
-- utils.debug( ("[image] render: %s, success: %s x: %s, y: %s, width: %s, height: %s"):format( self.id, was_rendered, self.geometry.x, self.geometry.y, self.geometry.width, self.geometry.height))
3737

3838
-- clear if render was prevented
3939
if self.is_rendered and not was_rendered then self.global_state.backend.clear(self.id, true) end

lua/image/renderer.lua

+48-34
Original file line numberDiff line numberDiff line change
@@ -278,15 +278,6 @@ local render = function(image)
278278

279279
-- compute final geometry and prevent useless rerendering
280280
local rendered_geometry = { x = absolute_x, y = absolute_y, width = width, height = height }
281-
-- if
282-
-- image.is_rendered
283-
-- and image.rendered_geometry.x == rendered_geometry.x
284-
-- and image.rendered_geometry.y == rendered_geometry.y
285-
-- and image.rendered_geometry.width == rendered_geometry.width
286-
-- and image.rendered_geometry.height == rendered_geometry.height
287-
-- then
288-
-- return true
289-
-- end
290281

291282
-- handle crop/resize
292283
local pixel_width = width * term_size.cell_width
@@ -295,23 +286,23 @@ local render = function(image)
295286
local cropped_pixel_height = height * term_size.cell_height
296287
local needs_crop = false
297288
local needs_resize = false
289+
local initial_crop_hash = image.crop_hash
290+
local initial_resize_hash = image.resize_hash
298291

299292
-- compute crop top/bottom
300-
if not state.backend.features.crop then
301-
-- crop top
302-
if absolute_y < bounds.top then
303-
local visible_rows = height - (bounds.top - absolute_y)
304-
cropped_pixel_height = visible_rows * term_size.cell_height
305-
crop_offset_top = (bounds.top - absolute_y) * term_size.cell_height
306-
absolute_y = bounds.top
307-
needs_crop = true
308-
end
293+
-- crop top
294+
if absolute_y < bounds.top then
295+
local visible_rows = height - (bounds.top - absolute_y)
296+
cropped_pixel_height = visible_rows * term_size.cell_height
297+
crop_offset_top = (bounds.top - absolute_y) * term_size.cell_height
298+
if not state.backend.features.crop then absolute_y = bounds.top end
299+
needs_crop = true
300+
end
309301

310-
-- crop bottom
311-
if absolute_y + height > bounds.bottom then
312-
cropped_pixel_height = (bounds.bottom - absolute_y + 1) * term_size.cell_height
313-
needs_crop = true
314-
end
302+
-- crop bottom
303+
if absolute_y + height > bounds.bottom then
304+
cropped_pixel_height = (bounds.bottom - absolute_y + 1) * term_size.cell_height
305+
needs_crop = true
315306
end
316307

317308
-- compute resize
@@ -343,26 +334,49 @@ local render = function(image)
343334
end
344335

345336
-- crop
337+
local crop_hash = ("%d-%d-%d-%d"):format(0, crop_offset_top, pixel_width, cropped_pixel_height)
346338
if needs_crop then
347-
local crop_hash = ("%d-%d-%d-%d"):format(0, crop_offset_top, pixel_width, cropped_pixel_height)
348339
if (needs_resize and image.resize_hash ~= resize_hash) or image.crop_hash ~= crop_hash then
349-
local cropped_image = magick.load_image(image.resized_path or image.path)
350-
cropped_image:set_format("png")
351-
352-
-- utils.debug(("cropping image %s to %dx%d"):format(image.path, pixel_width, cropped_pixel_height))
353-
cropped_image:crop(pixel_width, cropped_pixel_height, 0, crop_offset_top)
354-
local tmp_path = state.tmp_dir .. "/" .. utils.base64.encode(image.id) .. "-cropped.png"
355-
cropped_image:write(tmp_path)
356-
cropped_image:destroy()
357-
358-
image.cropped_path = tmp_path
340+
if not state.backend.features.crop then
341+
local cropped_image = magick.load_image(image.resized_path or image.path)
342+
cropped_image:set_format("png")
343+
344+
-- utils.debug(("cropping image %s to %dx%d"):format(image.path, pixel_width, cropped_pixel_height))
345+
cropped_image:crop(pixel_width, cropped_pixel_height, 0, crop_offset_top)
346+
local tmp_path = state.tmp_dir .. "/" .. utils.base64.encode(image.id) .. "-cropped.png"
347+
cropped_image:write(tmp_path)
348+
cropped_image:destroy()
349+
image.cropped_path = tmp_path
350+
end
359351
image.crop_hash = crop_hash
360352
end
361353
else
362354
image.cropped_path = image.resized_path
363355
image.crop_hash = nil
364356
end
365357

358+
if
359+
image.is_rendered
360+
and image.rendered_geometry.x == rendered_geometry.x
361+
and image.rendered_geometry.y == rendered_geometry.y
362+
and image.rendered_geometry.width == rendered_geometry.width
363+
and image.rendered_geometry.height == rendered_geometry.height
364+
and image.crop_hash == initial_crop_hash
365+
and image.resize_hash == initial_resize_hash
366+
then
367+
-- utils.debug("skipping render", image.id)
368+
return true
369+
end
370+
371+
-- utils.debug("redering to backend", image.id, {
372+
-- x = absolute_x,
373+
-- y = absolute_y,
374+
-- width = width,
375+
-- height = height,
376+
-- resize_hash = image.resize_hash,
377+
-- crop_hash = image.crop_hash,
378+
-- })
379+
366380
image.bounds = bounds
367381
state.backend.render(image, absolute_x, absolute_y, width, height)
368382
image.rendered_geometry = rendered_geometry

0 commit comments

Comments
 (0)