diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2021-12-15 04:43:46 +0100 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2021-12-15 04:44:34 +0100 | 
| commit | c18404efee8d330cf30b1799fb1cefec722bf31d (patch) | |
| tree | 6a029436070cfd9003060eb76a2d3dcb2c4c3150 | |
| parent | bff2b92c9e9762dbd281b828fa0562e9992a9461 (diff) | |
| download | fiv-c18404efee8d330cf30b1799fb1cefec722bf31d.tar.gz fiv-c18404efee8d330cf30b1799fb1cefec722bf31d.tar.xz fiv-c18404efee8d330cf30b1799fb1cefec722bf31d.zip  | |
Add basic print functionality
| -rw-r--r-- | fastiv-view.c | 78 | 
1 files changed, 70 insertions, 8 deletions
diff --git a/fastiv-view.c b/fastiv-view.c index b2bc875..81e4add 100644 --- a/fastiv-view.c +++ b/fastiv-view.c @@ -569,18 +569,78 @@ show_error_dialog(GtkWindow *parent, GError *error)  	g_error_free(error);  } +static GtkWindow * +get_toplevel(GtkWidget *widget) +{ +	if (GTK_IS_WINDOW((widget = gtk_widget_get_toplevel(widget)))) +		return GTK_WINDOW(widget); +	return NULL; +} + +static void +on_draw_page(G_GNUC_UNUSED GtkPrintOperation *operation, +	GtkPrintContext *context, G_GNUC_UNUSED int page_nr, FastivView *self) +{ +	double surface_width_px = 0, surface_height_px = 0; +	get_surface_dimensions(self, &surface_width_px, &surface_height_px); + +	// Any DPI will be wrong, unless we import that information from the image. +	double scale = 1 / 96.; +	double w = surface_width_px * scale, h = surface_height_px * scale; + +	// Scale down to fit the print area, taking care to not divide by zero. +	double areaw = gtk_print_context_get_width(context); +	double areah = gtk_print_context_get_height(context); +	scale *= fmin((areaw < w) ? areaw / w : 1, (areah < h) ? areah / h : 1); + +	cairo_t *cr = gtk_print_context_get_cairo_context(context); +	cairo_scale(cr, scale, scale); +	cairo_set_source_surface(cr, self->frame, 0, 0); +	cairo_matrix_t matrix = get_orientation_matrix( +		self->orientation, surface_width_px, surface_height_px); +	cairo_pattern_set_matrix(cairo_get_source(cr), &matrix); +	cairo_paint(cr); +} + +static gboolean +print(FastivView *self) +{ +	GtkPrintOperation *print = gtk_print_operation_new(); +	gtk_print_operation_set_n_pages(print, 1); +	gtk_print_operation_set_embed_page_setup(print, TRUE); +	gtk_print_operation_set_unit(print, GTK_UNIT_INCH); +	gtk_print_operation_set_job_name(print, "Image"); +	g_signal_connect(print, "draw-page", G_CALLBACK(on_draw_page), self); + +	static GtkPrintSettings *settings = NULL; +	if (settings != NULL) +		gtk_print_operation_set_print_settings(print, settings); + +	GError *error = NULL; +	GtkWindow *window = get_toplevel(GTK_WIDGET(self)); +	GtkPrintOperationResult res = gtk_print_operation_run( +		print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, window, &error); +	if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { +		if (settings != NULL) +			g_object_unref(settings); +		settings = g_object_ref(gtk_print_operation_get_print_settings(print)); +	} +	if (error) +		show_error_dialog(window, error); + +	g_object_unref(print); +	return TRUE; +} +  static gboolean  save_as(FastivView *self, gboolean frame)  { -	GtkWindow *window = NULL; -	GtkWidget *widget = NULL; -	if (GTK_IS_WINDOW((widget = gtk_widget_get_toplevel(GTK_WIDGET(self))))) -		window = GTK_WINDOW(widget); +	GtkWindow *window = get_toplevel(GTK_WIDGET(self)); +	GtkWidget *dialog = gtk_file_chooser_dialog_new( +		frame ? "Save frame as" : "Save page as", +		window, GTK_FILE_CHOOSER_ACTION_SAVE, +		"_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); -	GtkWidget *dialog = -		gtk_file_chooser_dialog_new(frame ? "Save frame as" : "Save page as", -			window, GTK_FILE_CHOOSER_ACTION_SAVE, -			"_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL);  	GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);  	// TODO(p): Consider a hard dependency on libwebp, or clean this up. @@ -657,6 +717,8 @@ fastiv_view_key_press_event(GtkWidget *widget, GdkEventKey *event)  			return set_scale(self, self->scale * SCALE_STEP);  		case GDK_KEY_minus:  			return set_scale(self, self->scale / SCALE_STEP); +		case GDK_KEY_p: +			return print(self);  		case GDK_KEY_s:  			return save_as(self, FALSE);  		case GDK_KEY_S:  | 
