+ first_draw = self._previous_area.x1 == self._previous_area.x2
+ hidden = self._hidden_tilegrid or self._hidden_by_parent
+ if not first_draw and hidden:
+ self._previous_area.x2 = self._previous_area.x1
+ elif self._moved or first_draw:
+ self._current_area.copy_into(self._previous_area)
+
+ self._moved = False
+ self._full_change = False
+ self._partial_change = False
+ if isinstance(self._pixel_shader, (Palette, ColorConverter)):
+ self._pixel_shader._finish_refresh() # pylint: disable=protected-access
+ if isinstance(self._bitmap, (Bitmap, Shape)):
+ self._bitmap._finish_refresh() # pylint: disable=protected-access
+
+ def _get_refresh_areas(self, areas: list[Area]) -> None:
+ # pylint: disable=invalid-name, too-many-branches, too-many-statements
+ first_draw = self._previous_area.x1 == self._previous_area.x2
+ hidden = self._hidden_tilegrid or self._hidden_by_parent
+
+ # Check hidden first because it trumps all other changes
+ if hidden:
+ self._rendered_hidden = True
+ if not first_draw:
+ areas.append(self._previous_area)
+ return
+ if self._moved and not first_draw:
+ self._previous_area.union(self._current_area, self._dirty_area)
+ if self._dirty_area.size() < 2 * self._pixel_width * self._pixel_height:
+ areas.append(self._dirty_area)
+ return
+ areas.append(self._current_area)
+ areas.append(self._previous_area)
+ return
+
+ tail = areas[-1]
+ # If we have an in-memory bitmap, then check it for modifications
+ if isinstance(self._bitmap, Bitmap):
+ self._bitmap._get_refresh_areas(areas) # pylint: disable=protected-access
+ if tail != areas[-1]:
+ # Special case a TileGrid that shows a full bitmap and use its
+ # dirty area. Copy it to ours so we can transform it.
+ if self._tiles_in_bitmap == 1:
+ areas[-1].copy_into(self._dirty_area)
+ self._partial_change = True
+ else:
+ self._full_change = True
+ elif isinstance(self._bitmap, Shape):
+ self._bitmap._get_refresh_areas(areas) # pylint: disable=protected-access
+ if areas[-1] != tail:
+ areas[-1].copy_into(self._dirty_area)
+ self._partial_change = True
+
+ self._full_change = self._full_change or (
+ isinstance(self._pixel_shader, (Palette, ColorConverter))
+ and self._pixel_shader._needs_refresh # pylint: disable=protected-access
+ )
+ if self._full_change or first_draw:
+ areas.append(self._current_area)
+ return
+
+ if self._partial_change:
+ x = self._x
+ y = self._y
+ if self._absolute_transform.transpose_xy:
+ x, y = y, x
+ x1 = self._dirty_area.x1
+ x2 = self._dirty_area.x2
+ if self._flip_x:
+ x1 = self._pixel_width - x1
+ x2 = self._pixel_width - x2
+ y1 = self._dirty_area.y1
+ y2 = self._dirty_area.y2
+ if self._flip_y:
+ y1 = self._pixel_height - y1
+ y2 = self._pixel_height - y2
+ if self._transpose_xy != self._absolute_transform.transpose_xy:
+ x1, y1 = y1, x1
+ x2, y2 = y2, x2
+ self._dirty_area.x1 = (
+ self._absolute_transform.x + self._absolute_transform.dx * (x + x1)
+ )
+ self._dirty_area.y1 = (
+ self._absolute_transform.y + self._absolute_transform.dy * (y + y1)
+ )
+ self._dirty_area.x2 = (
+ self._absolute_transform.x + self._absolute_transform.dx * (x + x2)
+ )
+ self._dirty_area.y2 = (
+ self._absolute_transform.y + self._absolute_transform.dy * (y + y2)
+ )
+ if self._dirty_area.y2 < self._dirty_area.y1:
+ self._dirty_area.y1, self._dirty_area.y2 = (
+ self._dirty_area.y2,
+ self._dirty_area.y1,
+ )
+ if self._dirty_area.x2 < self._dirty_area.x1:
+ self._dirty_area.x1, self._dirty_area.x2 = (
+ self._dirty_area.x2,
+ self._dirty_area.x1,
+ )
+ areas.append(self._dirty_area)