Skip to content

Commit 2cd01fe

Browse files
jtheooflelgenio
authored and
lelgenio
committed
fix(ui): compute window sizes and buffers properly
Compute maximum width and height of area container based on monitor size and fix image ratio based on appropriate values. Note that this will lower the resolution of the final image. Closes jtheoof#56
1 parent 000bb6d commit 2cd01fe

File tree

7 files changed

+93
-130
lines changed

7 files changed

+93
-130
lines changed

include/buffer.h

-7
This file was deleted.

include/pixbuf.h

+3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
#include "swappy.h"
44

5+
GdkPixbuf *pixbuf_init_from_file(struct swappy_state *state);
56
GdkPixbuf *pixbuf_get_from_state(struct swappy_state *state);
67
void pixbuf_save_state_to_folder(GdkPixbuf *pixbuf, char *folder,
78
char *filename_format);
89
void pixbuf_save_to_file(GdkPixbuf *pixbuf, char *file);
910
void pixbuf_save_to_stdout(GdkPixbuf *pixbuf);
11+
void pixbuf_scale_surface_from_widget(struct swappy_state *state,
12+
GtkWidget *widget);

include/swappy.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ struct swappy_state {
148148
struct swappy_state_ui *ui;
149149
struct swappy_config *config;
150150

151+
GdkPixbuf *original_image;
151152
cairo_surface_t *original_image_surface;
152153
cairo_surface_t *scaled_image_surface;
153154
cairo_surface_t *rendered_surface;
@@ -165,8 +166,6 @@ struct swappy_state {
165166
struct swappy_box *window;
166167
struct swappy_box *geometry;
167168

168-
cairo_rectangle_int_t *drawing_area_rect;
169-
170169
GList *paints;
171170
GList *redo_paints;
172171
struct swappy_paint *temp_paint;

meson.build

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ executable(
5959
'src/main.c',
6060
'src/algebra.c',
6161
'src/application.c',
62-
'src/buffer.c',
6362
'src/box.c',
6463
'src/config.c',
6564
'src/clipboard.c',

src/application.c

+34-26
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <stdio.h>
66
#include <time.h>
77

8-
#include "buffer.h"
98
#include "clipboard.h"
109
#include "config.h"
1110
#include "file.h"
@@ -231,8 +230,6 @@ void blur_clicked_handler(GtkWidget *widget, struct swappy_state *state) {
231230

232231
void application_finish(struct swappy_state *state) {
233232
paint_free_all(state);
234-
buffer_free_all(state);
235-
g_free(state->drawing_area_rect);
236233
cairo_surface_destroy(state->rendered_surface);
237234
cairo_surface_destroy(state->original_image_surface);
238235
cairo_surface_destroy(state->scaled_image_surface);
@@ -247,6 +244,7 @@ void application_finish(struct swappy_state *state) {
247244
g_free(state->geometry);
248245
g_free(state->window);
249246
g_free(state->ui);
247+
g_object_unref(state->original_image);
250248
g_object_unref(state->app);
251249

252250
config_free(state);
@@ -394,27 +392,21 @@ gboolean draw_area_handler(GtkWidget *widget, cairo_t *cr,
394392
gboolean draw_area_configure_handler(GtkWidget *widget,
395393
GdkEventConfigure *event,
396394
struct swappy_state *state) {
397-
g_debug("received configure_event handler");
395+
g_debug("received configure_event callback");
398396
cairo_surface_destroy(state->rendered_surface);
399-
g_free(state->drawing_area_rect);
400397

401398
cairo_surface_t *surface = gdk_window_create_similar_surface(
402399
gtk_widget_get_window(widget), CAIRO_CONTENT_COLOR_ALPHA,
403400
gtk_widget_get_allocated_width(widget),
404401
gtk_widget_get_allocated_height(widget));
405402

406-
state->rendered_surface = surface;
403+
g_info("size of drawing area surface: %ux%u",
404+
cairo_image_surface_get_width(surface),
405+
cairo_image_surface_get_height(surface));
407406

408-
GtkAllocation *alloc = g_new(GtkAllocation, 1);
409-
gtk_widget_get_allocation(widget, alloc);
410-
state->drawing_area_rect = alloc;
411-
buffer_resize_patterns(state);
407+
state->rendered_surface = surface;
412408

413-
g_info("size of cairo_surface: %ux%u with type: %d",
414-
cairo_image_surface_get_width(surface),
415-
cairo_image_surface_get_height(surface),
416-
cairo_image_surface_get_format(surface));
417-
g_info("size of area to render: %ux%u", alloc->width, alloc->height);
409+
pixbuf_scale_surface_from_widget(state, widget);
418410

419411
render_state(state);
420412

@@ -562,18 +554,34 @@ static void compute_window_size(struct swappy_state *state) {
562554
state->window->y = workarea.y;
563555

564556
double threshold = 0.75;
565-
double scaling = 1.0;
566557

567-
if (state->geometry->width > workarea.width * threshold) {
568-
scaling = workarea.width * threshold / state->geometry->width;
569-
} else if (state->geometry->height > workarea.height * threshold) {
570-
scaling = workarea.height * threshold / state->geometry->height;
571-
}
558+
int image_width = gdk_pixbuf_get_width(state->original_image);
559+
int image_height = gdk_pixbuf_get_height(state->original_image);
572560

573-
state->window->width = state->geometry->width * scaling;
574-
state->window->height = state->geometry->height * scaling;
561+
int max_width = workarea.width * threshold;
562+
int max_height = workarea.height * threshold;
575563

564+
g_info("size of image: %ux%u", image_width, image_height);
576565
g_info("size of monitor at window: %ux%u", workarea.width, workarea.height);
566+
g_info("maxium size allowed for window: %ux%u", max_width, max_height);
567+
568+
int scaled_width = image_width;
569+
int scaled_height = image_height;
570+
571+
double scaling_factor_width = (double)max_width / image_width;
572+
double scaling_factor_height = (double)max_height / image_height;
573+
574+
if (scaling_factor_height < 1.0 || scaling_factor_width < 1.0) {
575+
double scaling_factor = MIN(scaling_factor_width, scaling_factor_height);
576+
scaled_width = image_width * scaling_factor;
577+
scaled_height = image_height * scaling_factor;
578+
g_info("rendering area will be scaled by a factor of: %.2lf",
579+
scaling_factor);
580+
}
581+
582+
state->window->width = scaled_width;
583+
state->window->height = scaled_height;
584+
577585
g_info("size of window to render: %ux%u", state->window->width,
578586
state->window->height);
579587
}
@@ -675,8 +683,8 @@ static bool load_layout(struct swappy_state *state) {
675683
}
676684

677685
static bool init_gtk_window(struct swappy_state *state) {
678-
if (!state->geometry) {
679-
g_critical("no geometry found, did you use -f option?");
686+
if (!state->original_image) {
687+
g_critical("original image not loaded");
680688
return false;
681689
}
682690

@@ -725,7 +733,7 @@ static gint command_line_handler(GtkApplication *app,
725733
state->temp_file_str = temp_file_str;
726734
}
727735

728-
if (!buffer_init_from_file(state)) {
736+
if (!pixbuf_init_from_file(state)) {
729737
return EXIT_FAILURE;
730738
}
731739
}

src/buffer.c

-94
This file was deleted.

src/pixbuf.c

+55
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,65 @@ void pixbuf_save_to_stdout(GdkPixbuf *pixbuf) {
6363
g_object_unref(out);
6464
}
6565

66+
GdkPixbuf *pixbuf_init_from_file(struct swappy_state *state) {
67+
GError *error = NULL;
68+
char *file =
69+
state->temp_file_str != NULL ? state->temp_file_str : state->file_str;
70+
GdkPixbuf *image = gdk_pixbuf_new_from_file(file, &error);
71+
72+
if (error != NULL) {
73+
g_error("unable to load file: %s - reason: %s", file, error->message);
74+
return NULL;
75+
}
76+
77+
state->original_image = image;
78+
return image;
79+
}
80+
6681
void pixbuf_save_to_file(GdkPixbuf *pixbuf, char *file) {
6782
if (g_strcmp0(file, "-") == 0) {
6883
pixbuf_save_to_stdout(pixbuf);
6984
} else {
7085
write_file(pixbuf, file);
7186
}
7287
}
88+
89+
void pixbuf_scale_surface_from_widget(struct swappy_state *state,
90+
GtkWidget *widget) {
91+
GtkAllocation *alloc = g_new(GtkAllocation, 1);
92+
GdkPixbuf *image = state->original_image;
93+
gtk_widget_get_allocation(widget, alloc);
94+
95+
gboolean has_alpha = gdk_pixbuf_get_has_alpha(image);
96+
cairo_format_t format = has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
97+
gint image_width = gdk_pixbuf_get_width(image);
98+
gint image_height = gdk_pixbuf_get_height(image);
99+
cairo_surface_t *surface =
100+
cairo_image_surface_create(format, image_width, image_height);
101+
102+
if (!surface) {
103+
g_error("unable to create cairo surface from pixbuf");
104+
goto cleanup;
105+
} else {
106+
cairo_t *cr;
107+
cr = cairo_create(surface);
108+
double scale_x = (double)alloc->width / image_width;
109+
double scale_y = (double)alloc->height / image_height;
110+
g_info("image scaled on x,y: %.2lf,%.2lf", scale_x, scale_y);
111+
cairo_scale(cr, scale_x, scale_y);
112+
gdk_cairo_set_source_pixbuf(cr, image, 0, 0);
113+
cairo_paint(cr);
114+
cairo_destroy(cr);
115+
}
116+
117+
g_info("size of area to render: %ux%u", alloc->width, alloc->height);
118+
119+
if (state->scaled_image_surface) {
120+
cairo_surface_destroy(state->scaled_image_surface);
121+
state->scaled_image_surface = NULL;
122+
}
123+
state->scaled_image_surface = surface;
124+
125+
cleanup:
126+
g_free(alloc);
127+
}

0 commit comments

Comments
 (0)