refactor: improve code readability by formatting and restructuring function parameters and logic
mandatory-regression-gate / deterministic-tests (push) Waiting to run
mandatory-regression-gate / protected-performance-path (push) Waiting to run

This commit is contained in:
Your Name
2026-07-25 16:56:28 +03:00
parent 45a231a456
commit 683dac06ec
4 changed files with 127 additions and 59 deletions
+31 -8
View File
@@ -117,17 +117,25 @@ impl Engine {
if mask.len() != full_size {
let mut full_mask = vec![layer.mask_default_color; full_size];
if let Some(mb) = layer.mask_bounds {
let (m_top, m_left, m_bottom, m_right) =
(mb[0].max(0) as u32, mb[1].max(0) as u32, mb[2].max(0) as u32, mb[3].max(0) as u32);
let (m_top, m_left, m_bottom, m_right) = (
mb[0].max(0) as u32,
mb[1].max(0) as u32,
mb[2].max(0) as u32,
mb[3].max(0) as u32,
);
let mw = (m_right - m_left) as usize;
let mh = (m_bottom - m_top) as usize;
if mw > 0 && mh > 0 && mask.len() == mw * mh {
for y in 0..mh {
let gy = m_top as usize + y;
if gy >= ch as usize { break; }
if gy >= ch as usize {
break;
}
for x in 0..mw {
let gx = m_left as usize + x;
if gx >= cw as usize { break; }
if gx >= cw as usize {
break;
}
full_mask[gy * cw as usize + gx] = mask[y * mw + x];
}
}
@@ -181,7 +189,9 @@ impl Engine {
let cw = self.document.canvas_width as usize;
let ch = self.document.canvas_height as usize;
let mask_len = cw * ch;
if mask_len == 0 { return; }
if mask_len == 0 {
return;
}
if let Some(layer) = self.document.get_layer_by_id_mut(layer_id) {
if layer.mask_pixels.is_none() {
@@ -294,7 +304,13 @@ impl Engine {
self.draw_target_pixels_or_mask(
layer_id,
|pixels, lw, lh, mask_ref, active_stroke_mask, stroke_before_buf, sketch_history| {
|pixels,
lw,
lh,
mask_ref,
active_stroke_mask,
stroke_before_buf,
sketch_history| {
let sketch_hist = if tip.style == BrushStyle::Sketch {
sketch_history
} else {
@@ -361,8 +377,15 @@ impl Engine {
if self.editing_mask {
self.draw_target_pixels_or_mask(
layer_id,
|pixels, lw, lh, mask_ref, active_stroke_mask, stroke_before_buf, _sketch_history| {
let mut temp_layer = hcie_protocol::Layer::from_rgba("temp", lw, lh, pixels.to_vec());
|pixels,
lw,
lh,
mask_ref,
active_stroke_mask,
stroke_before_buf,
_sketch_history| {
let mut temp_layer =
hcie_protocol::Layer::from_rgba("temp", lw, lh, pixels.to_vec());
draw_brush_stroke(
&mut temp_layer,
&[(x, y, pressure)],
+27 -28
View File
@@ -2901,11 +2901,14 @@ impl HcieIcedApp {
let paint_tool =
matches!(tool, Tool::Pen | Tool::Brush | Tool::Eraser | Tool::Spray);
if paint_tool && (self.modifiers.control() || self.modifiers.logo()) {
let cx = canvas_x as u32;
let cy = canvas_y as u32;
let width = self.documents[self.active_doc].engine.canvas_width();
if cx < width && cy < self.documents[self.active_doc].engine.canvas_height() {
let index = ((cy * width + cx) * 4) as usize;
let height = self.documents[self.active_doc].engine.canvas_height();
if canvas_x >= 0.0
&& canvas_y >= 0.0
&& (canvas_x as u32) < width
&& (canvas_y as u32) < height
{
let index = ((canvas_y as u32 * width + canvas_x as u32) * 4) as usize;
if index + 3 < self.documents[self.active_doc].composite_raw.len() {
let pixels = &self.documents[self.active_doc].composite_raw;
let color = [
@@ -3247,13 +3250,11 @@ impl HcieIcedApp {
let is_ctrl = self.modifiers.control() || self.modifiers.logo();
if is_ctrl {
// Pick color
let cx = x as u32;
let cy = y as u32;
let w = self.documents[self.active_doc].engine.canvas_width();
let h = self.documents[self.active_doc].engine.canvas_height();
if cx < w && cy < h {
if x >= 0.0 && y >= 0.0 && (x as u32) < w && (y as u32) < h {
let pixels = &self.documents[self.active_doc].composite_raw;
let idx = ((cy * w + cx) * 4) as usize;
let idx = ((y as u32 * w + x as u32) * 4) as usize;
if idx + 3 < pixels.len() {
let color = [
pixels[idx],
@@ -3719,7 +3720,9 @@ impl HcieIcedApp {
}
Message::LayerSetEditMask(editing) => {
self.documents[self.active_doc].engine.set_editing_mask(editing);
self.documents[self.active_doc]
.engine
.set_editing_mask(editing);
self.documents[self.active_doc].cached_layers =
self.documents[self.active_doc].engine.layer_infos();
}
@@ -6711,10 +6714,8 @@ impl HcieIcedApp {
self.settings.tool_settings.vector_angle = angle.to_degrees();
// Track snap state for visual overlay feedback
let is_rotate = matches!(
session.handle,
hcie_engine_api::VectorEditHandle::Rotate
);
let is_rotate =
matches!(session.handle, hcie_engine_api::VectorEditHandle::Rotate);
let is_resize = matches!(
session.handle,
hcie_engine_api::VectorEditHandle::TopLeft
@@ -7784,7 +7785,8 @@ impl HcieIcedApp {
}
Message::PasteImage => {
// Check internal clipboard first
if let Some(transform) = self.documents[self.active_doc].internal_clipboard.clone() {
if let Some(transform) = self.documents[self.active_doc].internal_clipboard.clone()
{
// Enter transform mode with the clipboard content
let mut placed = transform;
placed.pos.x += 10.0;
@@ -8481,12 +8483,10 @@ impl HcieIcedApp {
return self.update(Message::OpenFileRfd);
}
Message::FileOpened(Ok(path)) => {
match self.open_path_in_new_tab(path, true) {
Ok(_) => return Task::perform(async {}, |_| Message::CompositeRefresh),
Err(error) => log::error!("Failed to open file: {error}"),
}
}
Message::FileOpened(Ok(path)) => match self.open_path_in_new_tab(path, true) {
Ok(_) => return Task::perform(async {}, |_| Message::CompositeRefresh),
Err(error) => log::error!("Failed to open file: {error}"),
},
Message::FileOpened(Err(e)) => {
log::error!("Failed to open file: {}", e);
@@ -9153,9 +9153,7 @@ impl HcieIcedApp {
| crate::theme::ThemePreset::ProDark
| crate::theme::ThemePreset::Amoled => crate::theme::ThemePreset::ProLight,
crate::theme::ThemePreset::PhotoshopLight
| crate::theme::ThemePreset::ProLight => {
crate::theme::ThemePreset::Photopea
}
| crate::theme::ThemePreset::ProLight => crate::theme::ThemePreset::Photopea,
};
self.theme_state.set_preset(new_preset);
self.settings.theme_preset = new_preset;
@@ -10308,10 +10306,8 @@ mod cycle_one_ux_tests {
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let path = std::env::temp_dir().join(format!(
"hcie-open-tab-{}-{unique}.png",
std::process::id()
));
let path =
std::env::temp_dir().join(format!("hcie-open-tab-{}-{unique}.png", std::process::id()));
image::save_buffer(
&path,
&[255, 0, 0, 255, 0, 255, 0, 255],
@@ -10328,7 +10324,10 @@ mod cycle_one_ux_tests {
assert_eq!(app.active_doc, 1);
assert_eq!(app.documents[0].name, original_name);
assert!(app.documents[0].source_path.is_none());
assert_eq!(app.documents[1].source_path.as_deref(), Some(path.as_path()));
assert_eq!(
app.documents[1].source_path.as_deref(),
Some(path.as_path())
);
assert_eq!(app.documents[1].engine.canvas_width(), 2);
assert_eq!(app.documents[1].engine.canvas_height(), 1);
@@ -985,8 +985,7 @@ fn should_publish_cursor_status(
current: (u32, u32),
elapsed: Option<std::time::Duration>,
) -> bool {
previous != Some(current)
&& elapsed.map_or(true, |duration| duration >= CURSOR_STATUS_INTERVAL)
previous != Some(current) && elapsed.map_or(true, |duration| duration >= CURSOR_STATUS_INTERVAL)
}
/// Canvas shader program — implements `iced::widget::shader::Program`.
@@ -110,23 +110,44 @@ impl Program<Message> for CanvasViewportProgram {
let mut frame = Frame::new(bounds.size());
// Draw checkerboard background (tiled to cover display area)
let checker_pattern = canvas::Pattern::new(&cfg.checker_handle).mode(canvas::PatternMode::Repeat);
let checker_path = Path::rectangle(Point::new(origin_x, origin_y), Size::new(display_w, display_h));
let checker_pattern =
canvas::Pattern::new(&cfg.checker_handle).mode(canvas::PatternMode::Repeat);
let checker_path = Path::rectangle(
Point::new(origin_x, origin_y),
Size::new(display_w, display_h),
);
frame.fill(&checker_path, checker_pattern);
// Draw composite texture
let composite_image = canvas::Image::new(&cfg.composite_handle)
.destination_rectangle(Rectangle::new(Point::new(origin_x, origin_y), Size::new(display_w, display_h)));
let composite_image =
canvas::Image::new(&cfg.composite_handle).destination_rectangle(Rectangle::new(
Point::new(origin_x, origin_y),
Size::new(display_w, display_h),
));
frame.draw_image(composite_image);
// Draw canvas border
let border_path = Path::rectangle(Point::new(origin_x, origin_y), Size::new(display_w, display_h));
frame.stroke(&border_path, Stroke::default().with_color(Color::from_rgb(0.35, 0.35, 0.35)).with_width(1.0));
let border_path = Path::rectangle(
Point::new(origin_x, origin_y),
Size::new(display_w, display_h),
);
frame.stroke(
&border_path,
Stroke::default()
.with_color(Color::from_rgb(0.35, 0.35, 0.35))
.with_width(1.0),
);
vec![frame.into_geometry()]
}
fn update(&self, state: &mut (), event: iced::Event, bounds: Rectangle, cursor: Cursor) -> (iced::widget::canvas::Status, Option<Message>) {
fn update(
&self,
state: &mut (),
event: iced::Event,
bounds: Rectangle,
cursor: Cursor,
) -> (iced::widget::canvas::Status, Option<Message>) {
let mut program_state = self.state.lock().unwrap();
match event {
@@ -140,17 +161,22 @@ impl Program<Message> for CanvasViewportProgram {
iced::mouse::Event::ButtonPressed(iced::mouse::Button::Left) => {
if let Some(pos) = program_state.last_cursor {
if bounds.contains(pos) {
let (cx, cy) = viewport_to_canvas(pos, bounds, &program_state.config);
let (cx, cy) =
viewport_to_canvas(pos, bounds, &program_state.config);
if let Some((cx, cy)) = (cx, cy) {
return (iced::widget::canvas::Status::Captured, Some(Message::CanvasPointerPressed { x: cx, y: cy }));
return (
iced::widget::canvas::Status::Captured,
Some(Message::CanvasPointerPressed { x: cx, y: cy }),
);
}
}
}
(iced::widget::canvas::Status::Captured, None)
}
iced::mouse::Event::ButtonReleased(iced::mouse::Button::Left) => {
(iced::widget::canvas::Status::Captured, Some(Message::CanvasPointerReleased))
}
iced::mouse::Event::ButtonReleased(iced::mouse::Button::Left) => (
iced::widget::canvas::Status::Captured,
Some(Message::CanvasPointerReleased),
),
iced::mouse::Event::Scrolled { delta } => {
if program_state.is_hovered {
let scroll_delta = match delta {
@@ -164,8 +190,13 @@ impl Program<Message> for CanvasViewportProgram {
let new_zoom = (old_zoom * factor).clamp(0.1, 10.0);
if let Some(cursor_pos) = program_state.last_cursor {
let (canvas_x, canvas_y) = viewport_to_canvas(cursor_pos, bounds, &program_state.config).unwrap_or((0.0, 0.0));
let (canvas_x, canvas_y) = viewport_to_canvas(
cursor_pos,
bounds,
&program_state.config,
)
.unwrap_or((0.0, 0.0));
// Calculate new pan_offset to keep cursor over same canvas point
let display_w = program_state.config.engine_w as f32 * new_zoom;
let display_h = program_state.config.engine_h as f32 * new_zoom;
@@ -173,12 +204,19 @@ impl Program<Message> for CanvasViewportProgram {
let new_origin_y = cursor_pos.y - canvas_y * new_zoom;
let new_default_origin_x = (bounds.width - display_w) / 2.0;
let new_default_origin_y = (bounds.height - display_h) / 2.0;
program_state.config.pan_offset.x = new_origin_x - new_default_origin_x;
program_state.config.pan_offset.y = new_origin_y - new_default_origin_y;
program_state.config.pan_offset.x =
new_origin_x - new_default_origin_x;
program_state.config.pan_offset.y =
new_origin_y - new_default_origin_y;
}
program_state.config.zoom = new_zoom;
return (iced::widget::canvas::Status::Captured, Some(Message::CanvasZoom { delta: scroll_delta }));
return (
iced::widget::canvas::Status::Captured,
Some(Message::CanvasZoom {
delta: scroll_delta,
}),
);
}
}
(iced::widget::canvas::Status::Ignored, None)
@@ -190,7 +228,12 @@ impl Program<Message> for CanvasViewportProgram {
}
}
fn mouse_interaction(&self, _state: &(), bounds: Rectangle, cursor: Cursor) -> iced::mouse::Interaction {
fn mouse_interaction(
&self,
_state: &(),
bounds: Rectangle,
cursor: Cursor,
) -> iced::mouse::Interaction {
if cursor.is_over(bounds) {
iced::mouse::Interaction::Crosshair
} else {
@@ -203,7 +246,11 @@ impl Program<Message> for CanvasViewportProgram {
///
/// Returns signed canvas coordinates even when the cursor is outside the canvas
/// image so brush strokes can start or continue beyond the visible edges.
fn viewport_to_canvas(viewport_pos: Point, bounds: Rectangle, config: &CanvasViewportConfig) -> Option<(f32, f32)> {
fn viewport_to_canvas(
viewport_pos: Point,
bounds: Rectangle,
config: &CanvasViewportConfig,
) -> Option<(f32, f32)> {
let display_w = config.engine_w as f32 * config.zoom;
let display_h = config.engine_h as f32 * config.zoom;
@@ -234,4 +281,4 @@ pub fn canvas_viewport<'a>(
..Default::default()
})
.into()
}
}