1
0
mirror of https://codeberg.org/vyivel/dulcepan/ synced 2025-03-12 18:59:15 +02:00

More scale changes :3

Surely this has no bugs in it
This commit is contained in:
Kirill Primak 2024-06-28 20:35:44 +03:00
parent 8794cbdeb2
commit bc97934371
6 changed files with 82 additions and 77 deletions

View File

@ -92,7 +92,7 @@ struct dp_seat {
// The output the pointer is on
struct dp_output *ptr_output;
// In buffer space
int ptr_x, ptr_y;
double ptr_x, ptr_y;
struct wl_list link;
};
@ -114,15 +114,15 @@ enum dp_resize_edges {
struct dp_selection {
struct dp_output *output; // May be NULL
int x, y, width, height;
double x, y, width, height;
enum dp_selection_action action;
bool action_active;
// Pointer offset to apply during movement
int ptr_off_x, ptr_off_y;
double ptr_off_x, ptr_off_y;
int resize_edges;
// Resize anchor
int resize_x, resize_y;
double resize_x, resize_y;
};
enum dp_file_format {
@ -213,12 +213,12 @@ void dp_output_hide_surface(struct dp_output *output);
void dp_seat_create(struct dp_state *state, uint32_t name, struct wl_seat *wl_seat);
void dp_seat_destroy(struct dp_seat *seat);
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, int x,
int y, bool modify_existing);
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, double x,
double y, bool modify_existing);
void dp_select_stop_interactive(struct dp_selection *selection);
void dp_select_notify_pointer_position(
struct dp_selection *selection, struct dp_output *output, int x, int y);
struct dp_selection *selection, struct dp_output *output, double x, double y);
void dp_select_whole(struct dp_selection *selection, struct dp_output *output);

View File

@ -272,8 +272,8 @@ static inline uint32_t get_time_msec(void) {
return (uint32_t)(now.tv_sec * 1000 + now.tv_nsec / 1000000);
}
static void setup_linear_gradient(cairo_t *cairo, struct dp_state *state) {
struct dp_selection *selection = &state->selection;
static void setup_linear_gradient(
cairo_t *cairo, struct dp_state *state, double x, double y, double width, double height) {
struct dp_config *config = &state->config;
cairo_matrix_t matrix;
@ -285,25 +285,25 @@ static void setup_linear_gradient(cairo_t *cairo, struct dp_state *state) {
matrix = state->precomputed_linear_matrix;
}
cairo_matrix_scale(&matrix, 1.0 / selection->width, 1.0 / selection->height);
cairo_matrix_translate(&matrix, -selection->x, -selection->y);
cairo_matrix_scale(&matrix, 1.0 / width, 1.0 / height);
cairo_matrix_translate(&matrix, -x, -y);
cairo_pattern_set_matrix(state->border_pattern, &matrix);
cairo_set_source(cairo, state->border_pattern);
}
static void setup_loop_gradient(cairo_t *cairo, struct dp_state *state) {
static void setup_loop_gradient(
cairo_t *cairo, struct dp_state *state, double x, double y, double width, double height) {
struct dp_selection *selection = &state->selection;
struct dp_config *config = &state->config;
double scale = state->loop_step_scale / selection->output->scale;
double offset =
(selection->x + selection->y + (selection->width + selection->height) / 2.0) * scale;
double offset = (x + y + (width + height) / 2.0) * state->loop_step_scale;
if (config->animation_duration != 0) {
offset += (double)get_time_msec() * state->time_multiplier / selection->output->scale;
offset += (double)get_time_msec() * state->time_multiplier;
}
double scale = state->loop_step_scale / selection->output->scale;
cairo_matrix_t matrix;
cairo_matrix_init(&matrix, scale, 0, 0, scale, fmod(offset, 2.0), 0);
@ -345,31 +345,34 @@ static void redraw(struct dp_output *output) {
cairo_paint(buffer->cairo);
if (output == selection->output) {
double scale = output->scale;
double x = selection->x * scale, y = selection->y * scale;
double width = selection->width * scale, height = selection->height * scale;
int border_size = config->border_size;
if (border_size != 0 && selection->width != 0 && selection->height != 0) {
double scaled_size = border_size * output->scale;
if (border_size != 0 && width != 0 && height != 0) {
double scaled_size = border_size * scale;
cairo_set_line_width(buffer->cairo, scaled_size);
double off = scaled_size / 2.0;
cairo_rectangle(buffer->cairo, selection->x - off, selection->y - off,
selection->width + scaled_size, selection->height + scaled_size);
cairo_rectangle(
buffer->cairo, x - off, y - off, width + scaled_size, height + scaled_size);
switch (config->border_gradient) {
case DP_BORDER_GRADIENT_NONE:
set_cairo_color(buffer->cairo, config->border_color);
break;
case DP_BORDER_GRADIENT_LINEAR:
setup_linear_gradient(buffer->cairo, state);
setup_linear_gradient(buffer->cairo, state, x, y, width, height);
break;
case DP_BORDER_GRADIENT_LOOP:
setup_loop_gradient(buffer->cairo, state);
setup_loop_gradient(buffer->cairo, state, x, y, width, height);
break;
}
cairo_stroke(buffer->cairo);
}
cairo_rectangle(
buffer->cairo, selection->x, selection->y, selection->width, selection->height);
cairo_rectangle(buffer->cairo, x, y, width, height);
set_cairo_color(buffer->cairo, config->selected_color);
cairo_fill(buffer->cairo);

View File

@ -28,7 +28,7 @@ void dp_persistent_load(struct dp_state *state) {
}
char name[32];
int x, y, width, height;
double x, y, width, height;
int n_read = 0;
fgets(name, sizeof(name), fp);
@ -36,7 +36,7 @@ void dp_persistent_load(struct dp_state *state) {
if (name[name_len - 1] == '\n') {
name[--name_len] = '\0';
}
n_read += fscanf(fp, "%d %d %d %d", &x, &y, &width, &height);
n_read += fscanf(fp, "%lf %lf %lf %lf", &x, &y, &width, &height);
bool ok = ferror(fp) == 0 && n_read == 4;
fclose(fp);
@ -61,8 +61,8 @@ void dp_persistent_load(struct dp_state *state) {
return;
}
if (x < 0 || y < 0 || x + width > selection_output->transformed_width ||
y + height > selection_output->transformed_height) {
if (x < 0 || y < 0 || x + width > selection_output->effective_width ||
y + height > selection_output->effective_height) {
dp_log_error("Persistent state: invalid selection geometry", name);
return;
}
@ -84,7 +84,7 @@ void dp_persistent_save(struct dp_state *state) {
} else {
fprintf(fp,
"%s\n"
"%d %d %d %d\n",
"%lf %lf %lf %lf\n",
selection->output->name, selection->x, selection->y, selection->width,
selection->height);
fclose(fp);

View File

@ -140,10 +140,15 @@ void dp_save(struct dp_state *state) {
pixman_image_set_transform(frame_image, &frame_transform);
pixman_image_t *out_image =
pixman_image_create_bits(PIXMAN_a8b8g8r8, selection->width, selection->height, NULL, 0);
pixman_image_composite32(PIXMAN_OP_SRC, frame_image, NULL, out_image, selection->x,
selection->y, 0, 0, 0, 0, selection->width, selection->height);
double scale = output->scale;
int x = (int)round(selection->x * scale), y = (int)round(selection->y * scale);
int width = (int)round(selection->width * scale),
height = (int)round(selection->height * scale);
pixman_image_t *out_image = pixman_image_create_bits(PIXMAN_a8b8g8r8, width, height, NULL, 0);
pixman_image_composite32(
PIXMAN_OP_SRC, frame_image, NULL, out_image, x, y, 0, 0, 0, 0, width, height);
pixman_image_unref(frame_image);
FILE *fp = NULL;
@ -160,11 +165,10 @@ void dp_save(struct dp_state *state) {
case DP_FILE_UNKNOWN:
abort(); // Unreachable
case DP_FILE_PNG:
write_png(
fp, out_image, selection->width, selection->height, state->config.png_compression);
write_png(fp, out_image, width, height, state->config.png_compression);
break;
case DP_FILE_PPM:
write_ppm(fp, out_image, selection->width, selection->height);
write_ppm(fp, out_image, width, height);
break;
}

View File

@ -111,9 +111,10 @@ static enum wp_cursor_shape_device_v1_shape get_cursor_shape(struct dp_selection
}
break;
case DP_SELECTION_ACTION_MOVING:
// XXX: this might have rounding issues but whatever
if (selection->x == 0 && selection->y == 0 &&
selection->width == selection->output->width &&
selection->height == selection->output->height) {
selection->width == selection->output->effective_width &&
selection->height == selection->output->effective_height) {
// Moving is impossible
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT;
}
@ -129,10 +130,8 @@ static void update_cursor(struct dp_seat *seat, uint32_t serial) {
static void process_position(struct dp_seat *seat, wl_fixed_t x, wl_fixed_t y, uint32_t serial) {
struct dp_output *output = seat->ptr_output;
seat->ptr_x =
(int)(wl_fixed_to_double(x) * output->transformed_width / output->effective_width);
seat->ptr_y =
(int)(wl_fixed_to_double(y) * output->transformed_height / output->effective_height);
seat->ptr_x = wl_fixed_to_double(x);
seat->ptr_y = wl_fixed_to_double(y);
dp_select_notify_pointer_position(&seat->state->selection, output, seat->ptr_x, seat->ptr_y);
update_cursor(seat, serial);
}

View File

@ -20,31 +20,30 @@ static void set_selected_output(struct dp_selection *selection, struct dp_output
}
}
static void update_action(struct dp_selection *selection, struct dp_output *output, int x, int y) {
static void update_action(
struct dp_selection *selection, struct dp_output *output, double x, double y) {
if (output == selection->output) {
int sx = x - selection->x;
int sy = y - selection->y;
double sx = x - selection->x;
double sy = y - selection->y;
int inner = (int)ceil(RESIZE_INNER_SIZE * output->scale);
int outer = (int)ceil(RESIZE_OUTER_SIZE * output->scale);
int threshold = (int)ceil(RESIZE_THRESHOLD * output->scale);
if (sx >= inner && sy >= inner && sx < selection->width - inner &&
sy <= selection->height - inner) {
if (sx >= RESIZE_INNER_SIZE && sy >= RESIZE_INNER_SIZE &&
sx < selection->width - RESIZE_INNER_SIZE &&
sy <= selection->height - RESIZE_INNER_SIZE) {
selection->action = DP_SELECTION_ACTION_MOVING;
return;
} else if (sx >= -outer && sy >= -outer && sx < selection->width + outer &&
sy < selection->height + outer) {
} else if (sx >= -RESIZE_OUTER_SIZE && sy >= -RESIZE_OUTER_SIZE &&
sx < selection->width + RESIZE_OUTER_SIZE &&
sy < selection->height + RESIZE_OUTER_SIZE) {
int edges = DP_EDGE_NONE;
if (sx >= selection->width - threshold && sx >= selection->width / 2) {
if (sx >= selection->width - RESIZE_THRESHOLD && sx >= selection->width / 2) {
edges |= DP_EDGE_RIGHT;
} else if (sx < threshold) {
} else if (sx < RESIZE_THRESHOLD) {
edges |= DP_EDGE_LEFT;
}
if (sy >= selection->height - threshold && sy >= selection->height / 2) {
if (sy >= selection->height - RESIZE_THRESHOLD && sy >= selection->height / 2) {
edges |= DP_EDGE_BOTTOM;
} else if (sy < threshold) {
} else if (sy < RESIZE_THRESHOLD) {
edges |= DP_EDGE_TOP;
}
@ -59,20 +58,20 @@ static void update_action(struct dp_selection *selection, struct dp_output *outp
selection->action = DP_SELECTION_ACTION_NONE;
}
static void do_resize(struct dp_selection *selection, int x, int y) {
int ptr_x = x - selection->ptr_off_x, ptr_y = y - selection->ptr_off_y;
static void do_resize(struct dp_selection *selection, double x, double y) {
double ptr_x = x - selection->ptr_off_x, ptr_y = y - selection->ptr_off_y;
if (ptr_x < 0) {
ptr_x = 0;
} else if (ptr_x > selection->output->transformed_width) {
ptr_x = selection->output->transformed_width;
} else if (ptr_x > selection->output->effective_width) {
ptr_x = selection->output->effective_width;
}
if (ptr_y < 0) {
ptr_y = 0;
} else if (ptr_y > selection->output->transformed_height) {
ptr_y = selection->output->transformed_height;
} else if (ptr_y > selection->output->effective_height) {
ptr_y = selection->output->effective_height;
}
int width = selection->width, height = selection->height;
double width = selection->width, height = selection->height;
retry_horiz:
if ((selection->resize_edges & DP_EDGE_LEFT) != 0) {
@ -117,18 +116,18 @@ retry_verti:
dp_output_redraw(selection->output);
}
static void do_move(struct dp_selection *selection, int x, int y) {
int new_x = x - selection->ptr_off_x, new_y = y - selection->ptr_off_y;
static void do_move(struct dp_selection *selection, double x, double y) {
double new_x = x - selection->ptr_off_x, new_y = y - selection->ptr_off_y;
if (new_x < 0) {
new_x = 0;
} else if (new_x > selection->output->transformed_width - selection->width) {
new_x = selection->output->transformed_width - selection->width;
} else if (new_x > selection->output->effective_width - selection->width) {
new_x = selection->output->effective_width - selection->width;
}
if (new_y < 0) {
new_y = 0;
} else if (new_y > selection->output->transformed_height - selection->height) {
new_y = selection->output->transformed_height - selection->height;
} else if (new_y > selection->output->effective_height - selection->height) {
new_y = selection->output->effective_height - selection->height;
}
if (new_x == selection->x && new_y == selection->y) {
@ -140,7 +139,7 @@ static void do_move(struct dp_selection *selection, int x, int y) {
dp_output_redraw(selection->output);
}
static void init_resize(struct dp_selection *selection, int x, int y) {
static void init_resize(struct dp_selection *selection, double x, double y) {
if ((selection->resize_edges & DP_EDGE_RIGHT) != 0) {
selection->ptr_off_x = x - selection->x - selection->width;
selection->resize_x = selection->x;
@ -157,8 +156,8 @@ static void init_resize(struct dp_selection *selection, int x, int y) {
}
}
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, int x,
int y, bool modify_existing) {
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, double x,
double y, bool modify_existing) {
update_action(selection, output, x, y);
selection->action_active = true;
@ -195,7 +194,7 @@ void dp_select_stop_interactive(struct dp_selection *selection) {
}
void dp_select_notify_pointer_position(
struct dp_selection *selection, struct dp_output *output, int x, int y) {
struct dp_selection *selection, struct dp_output *output, double x, double y) {
if (selection->action_active) {
switch (selection->action) {
case DP_SELECTION_ACTION_NONE:
@ -217,8 +216,8 @@ void dp_select_whole(struct dp_selection *selection, struct dp_output *output) {
selection->x = 0;
selection->y = 0;
selection->width = output->transformed_width;
selection->height = output->transformed_height;
selection->width = output->effective_width;
selection->height = output->effective_height;
dp_output_redraw(output);
}