renderer: cleanup, reduce nesting, more comments

This commit is contained in:
Qwerasd
2024-10-09 15:53:02 -04:00
parent b65ccd4598
commit 0bb176d22c
2 changed files with 132 additions and 112 deletions

View File

@ -2255,7 +2255,7 @@ fn rebuildCells(
}, },
} }
// Iterator of of runs for shaping. // Iterator of runs for shaping.
var run_iter = self.font_shaper.runIterator( var run_iter = self.font_shaper.runIterator(
self.font_grid, self.font_grid,
screen, screen,
@ -2272,55 +2272,62 @@ fn rebuildCells(
for (row_cells, 0..) |*cell, x| { for (row_cells, 0..) |*cell, x| {
// If this cell falls within our preedit range then we // If this cell falls within our preedit range then we
// skip this because preedits are setup separately. // skip this because preedits are setup separately.
if (preedit_range) |range| { if (preedit_range) |range| preedit: {
if (range.y == y) { // We're not on the preedit line, no actions necessary.
if (x >= range.x[0] and if (range.y != y) break :preedit;
x <= range.x[1]) // We're before the preedit range, no actions necessary.
{ if (x < range.x[0]) break :preedit;
continue; // We're in the preedit range, skip this cell.
} if (x <= range.x[1]) continue;
// After exiting the preedit range we need to catch
// the run position up because of the missed cells.
// In all other cases, no action is necessary.
if (x != range.x[1] + 1) break :preedit;
// After exiting the preedit range we need to catch // Step the run iterator until we find a run that ends
// the run position up because of the missed cells. // after the current cell, which will be the soonest run
if (x == range.x[1] + 1) { // that might contain glyphs for our cell.
while (shaper_run) |run| { while (shaper_run) |run| {
if (run.offset + run.cells > x) break; if (run.offset + run.cells > x) break;
shaper_run = try run_iter.next(self.alloc); shaper_run = try run_iter.next(self.alloc);
shaper_cells = null; shaper_cells = null;
shaper_cells_i = 0; shaper_cells_i = 0;
} }
if (shaper_run) |run| {
// Try to read the cells from the shaping cache if we can.
shaper_cells = self.font_shaper_cache.get(run) orelse cache: {
// Otherwise we have to shape them.
const cells = try self.font_shaper.shape(run);
// Try to cache them. If caching fails for any reason we const run = shaper_run orelse break :preedit;
// continue because it is just a performance optimization,
// not a correctness issue.
self.font_shaper_cache.put(
self.alloc,
run,
cells,
) catch |err| {
log.warn(
"error caching font shaping results err={}",
.{err},
);
};
// The cells we get from direct shaping are always owned // If we haven't shaped this run, do so now.
// by the shaper and valid until the next shaping call so shaper_cells = shaper_cells orelse
// we can safely use them. // Try to read the cells from the shaping cache if we can.
break :cache cells; self.font_shaper_cache.get(run) orelse
}; cache: {
} // Otherwise we have to shape them.
if (shaper_cells) |cells| { const cells = try self.font_shaper.shape(run);
while (cells[shaper_cells_i].x < x) {
shaper_cells_i += 1; // Try to cache them. If caching fails for any reason we
} // continue because it is just a performance optimization,
} // not a correctness issue.
} self.font_shaper_cache.put(
self.alloc,
run,
cells,
) catch |err| {
log.warn(
"error caching font shaping results err={}",
.{err},
);
};
// The cells we get from direct shaping are always owned
// by the shaper and valid until the next shaping call so
// we can safely use them.
break :cache cells;
};
// Advance our index until we reach or pass
// our current x position in the shaper cells.
while (shaper_cells.?[shaper_cells_i].x < x) {
shaper_cells_i += 1;
} }
} }
@ -2493,10 +2500,12 @@ fn rebuildCells(
shaper_cells_i = 0; shaper_cells_i = 0;
} }
// If we haven't shaped this run yet, do so. if (shaper_run) |run| glyphs: {
if (shaper_cells == null) if (shaper_run) |run| { // If we haven't shaped this run yet, do so.
// Try to read the cells from the shaping cache if we can. shaper_cells = shaper_cells orelse
shaper_cells = self.font_shaper_cache.get(run) orelse cache: { // Try to read the cells from the shaping cache if we can.
self.font_shaper_cache.get(run) orelse
cache: {
// Otherwise we have to shape them. // Otherwise we have to shape them.
const cells = try self.font_shaper.shape(run); const cells = try self.font_shaper.shape(run);
@ -2519,12 +2528,9 @@ fn rebuildCells(
// we can safely use them. // we can safely use them.
break :cache cells; break :cache cells;
}; };
};
// NOTE: An assumption is made here that a single cell will never const cells = shaper_cells orelse break :glyphs;
// be present in more than one shaper run. If that assumption is
// violated, this logic breaks.
if (shaper_cells) |cells| glyphs: {
// If there are no shaper cells for this run, ignore it. // If there are no shaper cells for this run, ignore it.
// This can occur for runs of empty cells, and is fine. // This can occur for runs of empty cells, and is fine.
if (cells.len == 0) break :glyphs; if (cells.len == 0) break :glyphs;
@ -2534,6 +2540,10 @@ fn rebuildCells(
// position monotonically increasing. // position monotonically increasing.
assert(cells[shaper_cells_i].x >= x); assert(cells[shaper_cells_i].x >= x);
// NOTE: An assumption is made here that a single cell will never
// be present in more than one shaper run. If that assumption is
// violated, this logic breaks.
while (shaper_cells_i < cells.len and cells[shaper_cells_i].x == x) : ({ while (shaper_cells_i < cells.len and cells[shaper_cells_i].x == x) : ({
shaper_cells_i += 1; shaper_cells_i += 1;
}) { }) {

View File

@ -1322,7 +1322,7 @@ pub fn rebuildCells(
}, },
} }
// Iterator of of runs for shaping. // Iterator of runs for shaping.
var run_iter = self.font_shaper.runIterator( var run_iter = self.font_shaper.runIterator(
self.font_grid, self.font_grid,
screen, screen,
@ -1339,55 +1339,62 @@ pub fn rebuildCells(
for (row_cells, 0..) |*cell, x| { for (row_cells, 0..) |*cell, x| {
// If this cell falls within our preedit range then we // If this cell falls within our preedit range then we
// skip this because preedits are setup separately. // skip this because preedits are setup separately.
if (preedit_range) |range| { if (preedit_range) |range| preedit: {
if (range.y == y) { // We're not on the preedit line, no actions necessary.
if (x >= range.x[0] and if (range.y != y) break :preedit;
x <= range.x[1]) // We're before the preedit range, no actions necessary.
{ if (x < range.x[0]) break :preedit;
continue; // We're in the preedit range, skip this cell.
} if (x <= range.x[1]) continue;
// After exiting the preedit range we need to catch
// the run position up because of the missed cells.
// In all other cases, no action is necessary.
if (x != range.x[1] + 1) break :preedit;
// After exiting the preedit range we need to catch // Step the run iterator until we find a run that ends
// the run position up because of the missed cells. // after the current cell, which will be the soonest run
if (x == range.x[1] + 1) { // that might contain glyphs for our cell.
while (shaper_run) |run| { while (shaper_run) |run| {
if (run.offset + run.cells > x) break; if (run.offset + run.cells > x) break;
shaper_run = try run_iter.next(self.alloc); shaper_run = try run_iter.next(self.alloc);
shaper_cells = null; shaper_cells = null;
shaper_cells_i = 0; shaper_cells_i = 0;
} }
if (shaper_run) |run| {
// Try to read the cells from the shaping cache if we can.
shaper_cells = self.font_shaper_cache.get(run) orelse cache: {
// Otherwise we have to shape them.
const cells = try self.font_shaper.shape(run);
// Try to cache them. If caching fails for any reason we const run = shaper_run orelse break :preedit;
// continue because it is just a performance optimization,
// not a correctness issue.
self.font_shaper_cache.put(
self.alloc,
run,
cells,
) catch |err| {
log.warn(
"error caching font shaping results err={}",
.{err},
);
};
// The cells we get from direct shaping are always owned // If we haven't shaped this run, do so now.
// by the shaper and valid until the next shaping call so shaper_cells = shaper_cells orelse
// we can safely use them. // Try to read the cells from the shaping cache if we can.
break :cache cells; self.font_shaper_cache.get(run) orelse
}; cache: {
} // Otherwise we have to shape them.
if (shaper_cells) |cells| { const cells = try self.font_shaper.shape(run);
while (cells[shaper_cells_i].x < x) {
shaper_cells_i += 1; // Try to cache them. If caching fails for any reason we
} // continue because it is just a performance optimization,
} // not a correctness issue.
} self.font_shaper_cache.put(
self.alloc,
run,
cells,
) catch |err| {
log.warn(
"error caching font shaping results err={}",
.{err},
);
};
// The cells we get from direct shaping are always owned
// by the shaper and valid until the next shaping call so
// we can safely use them.
break :cache cells;
};
// Advance our index until we reach or pass
// our current x position in the shaper cells.
while (shaper_cells.?[shaper_cells_i].x < x) {
shaper_cells_i += 1;
} }
} }
@ -1587,10 +1594,12 @@ pub fn rebuildCells(
shaper_cells_i = 0; shaper_cells_i = 0;
} }
// If we haven't shaped this run yet, do so. if (shaper_run) |run| glyphs: {
if (shaper_cells == null) if (shaper_run) |run| { // If we haven't shaped this run yet, do so.
// Try to read the cells from the shaping cache if we can. shaper_cells = shaper_cells orelse
shaper_cells = self.font_shaper_cache.get(run) orelse cache: { // Try to read the cells from the shaping cache if we can.
self.font_shaper_cache.get(run) orelse
cache: {
// Otherwise we have to shape them. // Otherwise we have to shape them.
const cells = try self.font_shaper.shape(run); const cells = try self.font_shaper.shape(run);
@ -1613,12 +1622,9 @@ pub fn rebuildCells(
// we can safely use them. // we can safely use them.
break :cache cells; break :cache cells;
}; };
};
// NOTE: An assumption is made here that a single cell will never const cells = shaper_cells orelse break :glyphs;
// be present in more than one shaper run. If that assumption is
// violated, this logic breaks.
if (shaper_cells) |cells| glyphs: {
// If there are no shaper cells for this run, ignore it. // If there are no shaper cells for this run, ignore it.
// This can occur for runs of empty cells, and is fine. // This can occur for runs of empty cells, and is fine.
if (cells.len == 0) break :glyphs; if (cells.len == 0) break :glyphs;
@ -1628,6 +1634,10 @@ pub fn rebuildCells(
// position monotonically increasing. // position monotonically increasing.
assert(cells[shaper_cells_i].x >= x); assert(cells[shaper_cells_i].x >= x);
// NOTE: An assumption is made here that a single cell will never
// be present in more than one shaper run. If that assumption is
// violated, this logic breaks.
while (shaper_cells_i < cells.len and cells[shaper_cells_i].x == x) : ({ while (shaper_cells_i < cells.len and cells[shaper_cells_i].x == x) : ({
shaper_cells_i += 1; shaper_cells_i += 1;
}) { }) {