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 // The output the pointer is on
struct dp_output *ptr_output; struct dp_output *ptr_output;
// In buffer space // In buffer space
int ptr_x, ptr_y; double ptr_x, ptr_y;
struct wl_list link; struct wl_list link;
}; };
@ -114,15 +114,15 @@ enum dp_resize_edges {
struct dp_selection { struct dp_selection {
struct dp_output *output; // May be NULL struct dp_output *output; // May be NULL
int x, y, width, height; double x, y, width, height;
enum dp_selection_action action; enum dp_selection_action action;
bool action_active; bool action_active;
// Pointer offset to apply during movement // Pointer offset to apply during movement
int ptr_off_x, ptr_off_y; double ptr_off_x, ptr_off_y;
int resize_edges; int resize_edges;
// Resize anchor // Resize anchor
int resize_x, resize_y; double resize_x, resize_y;
}; };
enum dp_file_format { 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_create(struct dp_state *state, uint32_t name, struct wl_seat *wl_seat);
void dp_seat_destroy(struct dp_seat *seat); void dp_seat_destroy(struct dp_seat *seat);
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, int x, void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, double x,
int y, bool modify_existing); double y, bool modify_existing);
void dp_select_stop_interactive(struct dp_selection *selection); void dp_select_stop_interactive(struct dp_selection *selection);
void dp_select_notify_pointer_position( 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); 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); return (uint32_t)(now.tv_sec * 1000 + now.tv_nsec / 1000000);
} }
static void setup_linear_gradient(cairo_t *cairo, struct dp_state *state) { static void setup_linear_gradient(
struct dp_selection *selection = &state->selection; cairo_t *cairo, struct dp_state *state, double x, double y, double width, double height) {
struct dp_config *config = &state->config; struct dp_config *config = &state->config;
cairo_matrix_t matrix; 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; matrix = state->precomputed_linear_matrix;
} }
cairo_matrix_scale(&matrix, 1.0 / selection->width, 1.0 / selection->height); cairo_matrix_scale(&matrix, 1.0 / width, 1.0 / height);
cairo_matrix_translate(&matrix, -selection->x, -selection->y); cairo_matrix_translate(&matrix, -x, -y);
cairo_pattern_set_matrix(state->border_pattern, &matrix); cairo_pattern_set_matrix(state->border_pattern, &matrix);
cairo_set_source(cairo, state->border_pattern); 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_selection *selection = &state->selection;
struct dp_config *config = &state->config; struct dp_config *config = &state->config;
double scale = state->loop_step_scale / selection->output->scale; double offset = (x + y + (width + height) / 2.0) * state->loop_step_scale;
double offset =
(selection->x + selection->y + (selection->width + selection->height) / 2.0) * scale;
if (config->animation_duration != 0) { 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_t matrix;
cairo_matrix_init(&matrix, scale, 0, 0, scale, fmod(offset, 2.0), 0); 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); cairo_paint(buffer->cairo);
if (output == selection->output) { 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; int border_size = config->border_size;
if (border_size != 0 && selection->width != 0 && selection->height != 0) { if (border_size != 0 && width != 0 && height != 0) {
double scaled_size = border_size * output->scale; double scaled_size = border_size * scale;
cairo_set_line_width(buffer->cairo, scaled_size); cairo_set_line_width(buffer->cairo, scaled_size);
double off = scaled_size / 2.0; double off = scaled_size / 2.0;
cairo_rectangle(buffer->cairo, selection->x - off, selection->y - off, cairo_rectangle(
selection->width + scaled_size, selection->height + scaled_size); buffer->cairo, x - off, y - off, width + scaled_size, height + scaled_size);
switch (config->border_gradient) { switch (config->border_gradient) {
case DP_BORDER_GRADIENT_NONE: case DP_BORDER_GRADIENT_NONE:
set_cairo_color(buffer->cairo, config->border_color); set_cairo_color(buffer->cairo, config->border_color);
break; break;
case DP_BORDER_GRADIENT_LINEAR: case DP_BORDER_GRADIENT_LINEAR:
setup_linear_gradient(buffer->cairo, state); setup_linear_gradient(buffer->cairo, state, x, y, width, height);
break; break;
case DP_BORDER_GRADIENT_LOOP: case DP_BORDER_GRADIENT_LOOP:
setup_loop_gradient(buffer->cairo, state); setup_loop_gradient(buffer->cairo, state, x, y, width, height);
break; break;
} }
cairo_stroke(buffer->cairo); cairo_stroke(buffer->cairo);
} }
cairo_rectangle( cairo_rectangle(buffer->cairo, x, y, width, height);
buffer->cairo, selection->x, selection->y, selection->width, selection->height);
set_cairo_color(buffer->cairo, config->selected_color); set_cairo_color(buffer->cairo, config->selected_color);
cairo_fill(buffer->cairo); cairo_fill(buffer->cairo);

View File

@ -28,7 +28,7 @@ void dp_persistent_load(struct dp_state *state) {
} }
char name[32]; char name[32];
int x, y, width, height; double x, y, width, height;
int n_read = 0; int n_read = 0;
fgets(name, sizeof(name), fp); fgets(name, sizeof(name), fp);
@ -36,7 +36,7 @@ void dp_persistent_load(struct dp_state *state) {
if (name[name_len - 1] == '\n') { if (name[name_len - 1] == '\n') {
name[--name_len] = '\0'; 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; bool ok = ferror(fp) == 0 && n_read == 4;
fclose(fp); fclose(fp);
@ -61,8 +61,8 @@ void dp_persistent_load(struct dp_state *state) {
return; return;
} }
if (x < 0 || y < 0 || x + width > selection_output->transformed_width || if (x < 0 || y < 0 || x + width > selection_output->effective_width ||
y + height > selection_output->transformed_height) { y + height > selection_output->effective_height) {
dp_log_error("Persistent state: invalid selection geometry", name); dp_log_error("Persistent state: invalid selection geometry", name);
return; return;
} }
@ -84,7 +84,7 @@ void dp_persistent_save(struct dp_state *state) {
} else { } else {
fprintf(fp, fprintf(fp,
"%s\n" "%s\n"
"%d %d %d %d\n", "%lf %lf %lf %lf\n",
selection->output->name, selection->x, selection->y, selection->width, selection->output->name, selection->x, selection->y, selection->width,
selection->height); selection->height);
fclose(fp); 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_set_transform(frame_image, &frame_transform);
pixman_image_t *out_image = double scale = output->scale;
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, int x = (int)round(selection->x * scale), y = (int)round(selection->y * scale);
selection->y, 0, 0, 0, 0, selection->width, selection->height); 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); pixman_image_unref(frame_image);
FILE *fp = NULL; FILE *fp = NULL;
@ -160,11 +165,10 @@ void dp_save(struct dp_state *state) {
case DP_FILE_UNKNOWN: case DP_FILE_UNKNOWN:
abort(); // Unreachable abort(); // Unreachable
case DP_FILE_PNG: case DP_FILE_PNG:
write_png( write_png(fp, out_image, width, height, state->config.png_compression);
fp, out_image, selection->width, selection->height, state->config.png_compression);
break; break;
case DP_FILE_PPM: case DP_FILE_PPM:
write_ppm(fp, out_image, selection->width, selection->height); write_ppm(fp, out_image, width, height);
break; break;
} }

View File

@ -111,9 +111,10 @@ static enum wp_cursor_shape_device_v1_shape get_cursor_shape(struct dp_selection
} }
break; break;
case DP_SELECTION_ACTION_MOVING: case DP_SELECTION_ACTION_MOVING:
// XXX: this might have rounding issues but whatever
if (selection->x == 0 && selection->y == 0 && if (selection->x == 0 && selection->y == 0 &&
selection->width == selection->output->width && selection->width == selection->output->effective_width &&
selection->height == selection->output->height) { selection->height == selection->output->effective_height) {
// Moving is impossible // Moving is impossible
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT; 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) { 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; struct dp_output *output = seat->ptr_output;
seat->ptr_x = seat->ptr_x = wl_fixed_to_double(x);
(int)(wl_fixed_to_double(x) * output->transformed_width / output->effective_width); seat->ptr_y = wl_fixed_to_double(y);
seat->ptr_y =
(int)(wl_fixed_to_double(y) * output->transformed_height / output->effective_height);
dp_select_notify_pointer_position(&seat->state->selection, output, seat->ptr_x, seat->ptr_y); dp_select_notify_pointer_position(&seat->state->selection, output, seat->ptr_x, seat->ptr_y);
update_cursor(seat, serial); 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) { if (output == selection->output) {
int sx = x - selection->x; double sx = x - selection->x;
int sy = y - selection->y; double sy = y - selection->y;
int inner = (int)ceil(RESIZE_INNER_SIZE * output->scale); if (sx >= RESIZE_INNER_SIZE && sy >= RESIZE_INNER_SIZE &&
int outer = (int)ceil(RESIZE_OUTER_SIZE * output->scale); sx < selection->width - RESIZE_INNER_SIZE &&
int threshold = (int)ceil(RESIZE_THRESHOLD * output->scale); sy <= selection->height - RESIZE_INNER_SIZE) {
if (sx >= inner && sy >= inner && sx < selection->width - inner &&
sy <= selection->height - inner) {
selection->action = DP_SELECTION_ACTION_MOVING; selection->action = DP_SELECTION_ACTION_MOVING;
return; return;
} else if (sx >= -outer && sy >= -outer && sx < selection->width + outer && } else if (sx >= -RESIZE_OUTER_SIZE && sy >= -RESIZE_OUTER_SIZE &&
sy < selection->height + outer) { sx < selection->width + RESIZE_OUTER_SIZE &&
sy < selection->height + RESIZE_OUTER_SIZE) {
int edges = DP_EDGE_NONE; 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; edges |= DP_EDGE_RIGHT;
} else if (sx < threshold) { } else if (sx < RESIZE_THRESHOLD) {
edges |= DP_EDGE_LEFT; 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; edges |= DP_EDGE_BOTTOM;
} else if (sy < threshold) { } else if (sy < RESIZE_THRESHOLD) {
edges |= DP_EDGE_TOP; 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; selection->action = DP_SELECTION_ACTION_NONE;
} }
static void do_resize(struct dp_selection *selection, int x, int y) { static void do_resize(struct dp_selection *selection, double x, double y) {
int ptr_x = x - selection->ptr_off_x, ptr_y = y - selection->ptr_off_y; double ptr_x = x - selection->ptr_off_x, ptr_y = y - selection->ptr_off_y;
if (ptr_x < 0) { if (ptr_x < 0) {
ptr_x = 0; ptr_x = 0;
} else if (ptr_x > selection->output->transformed_width) { } else if (ptr_x > selection->output->effective_width) {
ptr_x = selection->output->transformed_width; ptr_x = selection->output->effective_width;
} }
if (ptr_y < 0) { if (ptr_y < 0) {
ptr_y = 0; ptr_y = 0;
} else if (ptr_y > selection->output->transformed_height) { } else if (ptr_y > selection->output->effective_height) {
ptr_y = selection->output->transformed_height; ptr_y = selection->output->effective_height;
} }
int width = selection->width, height = selection->height; double width = selection->width, height = selection->height;
retry_horiz: retry_horiz:
if ((selection->resize_edges & DP_EDGE_LEFT) != 0) { if ((selection->resize_edges & DP_EDGE_LEFT) != 0) {
@ -117,18 +116,18 @@ retry_verti:
dp_output_redraw(selection->output); dp_output_redraw(selection->output);
} }
static void do_move(struct dp_selection *selection, int x, int y) { static void do_move(struct dp_selection *selection, double x, double y) {
int new_x = x - selection->ptr_off_x, new_y = y - selection->ptr_off_y; double new_x = x - selection->ptr_off_x, new_y = y - selection->ptr_off_y;
if (new_x < 0) { if (new_x < 0) {
new_x = 0; new_x = 0;
} else if (new_x > selection->output->transformed_width - selection->width) { } else if (new_x > selection->output->effective_width - selection->width) {
new_x = selection->output->transformed_width - selection->width; new_x = selection->output->effective_width - selection->width;
} }
if (new_y < 0) { if (new_y < 0) {
new_y = 0; new_y = 0;
} else if (new_y > selection->output->transformed_height - selection->height) { } else if (new_y > selection->output->effective_height - selection->height) {
new_y = selection->output->transformed_height - selection->height; new_y = selection->output->effective_height - selection->height;
} }
if (new_x == selection->x && new_y == selection->y) { 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); 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) { if ((selection->resize_edges & DP_EDGE_RIGHT) != 0) {
selection->ptr_off_x = x - selection->x - selection->width; selection->ptr_off_x = x - selection->x - selection->width;
selection->resize_x = selection->x; 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, void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, double x,
int y, bool modify_existing) { double y, bool modify_existing) {
update_action(selection, output, x, y); update_action(selection, output, x, y);
selection->action_active = true; selection->action_active = true;
@ -195,7 +194,7 @@ void dp_select_stop_interactive(struct dp_selection *selection) {
} }
void dp_select_notify_pointer_position( 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) { if (selection->action_active) {
switch (selection->action) { switch (selection->action) {
case DP_SELECTION_ACTION_NONE: 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->x = 0;
selection->y = 0; selection->y = 0;
selection->width = output->transformed_width; selection->width = output->effective_width;
selection->height = output->transformed_height; selection->height = output->effective_height;
dp_output_redraw(output); dp_output_redraw(output);
} }