📄 print.c
字号:
255, 255, 255, 255); /* draw cm or inch grid */ if (TRUE) { gdouble i; gdouble grid; PaperUnits units; units = (pw->paper_units == PAPER_UNIT_MM || pw->paper_units == PAPER_UNIT_CM) ? PAPER_UNIT_CM : PAPER_UNIT_INCH; grid = print_paper_size_convert_units(1.0, units, PAPER_UNIT_POINTS); for (i = grid ; i < pw->layout_width; i += grid) { pixbuf_draw_rect_fill(pixbuf, print_preview_unit(i), 0, 1, h, 0, 0, 0, 16); } for (i = grid; i < pw->layout_height; i += grid) { pixbuf_draw_rect_fill(pixbuf, 0, print_preview_unit(i), w, 1, 0, 0, 0, 16); } } /* proof sheet grid */ if (pw->layout == PRINT_LAYOUT_PROOF) { gdouble i, j; gdouble proof_w, proof_h; gint uw, uh; print_proof_size(pw, &proof_w, &proof_h); uw = print_preview_unit(proof_w + PRINT_PREVIEW_SCALE - 0.1); uh = print_preview_unit(proof_h + PRINT_PREVIEW_SCALE - 0.1); for (i = 0; i < pw->proof_columns; i++) for (j = 0; j < pw->proof_rows; j++) { gint x, y; x = pw->margin_left + (pw->layout_width - pw->margin_left - pw->margin_right - (pw->proof_columns * proof_w)) / 2 + i * proof_w; y = pw->margin_top + j * proof_h; pixbuf_draw_rect(pixbuf, print_preview_unit(x), print_preview_unit(y), uw, uh, 255, 0, 0, 64, 1, 1, 1, 1); } } /* non-printable region (margins) */ pixbuf_draw_rect(pixbuf, 0, 0, w, h, 0, 0, 0, 16, l, r, t, b); /* margin lines */ pixbuf_draw_rect(pixbuf, l, 0, w - l - r, h, 0, 0, 255, 128, 1, 1, 0, 0); pixbuf_draw_rect(pixbuf, 0, t, w, h - t - b, 0, 0, 255, 128, 0, 0, 1, 1); /* border */ pixbuf_draw_rect(pixbuf, 0, 0, w, h, 0, 0, 0, 255, 1, 1, 1, 1); image_area_changed(pw->layout_image, 0, 0, w, h); return TRUE;}static gint print_job_preview_page_done(PrintWindow *pw){ return TRUE;}static gint print_job_preview_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, gdouble x, gdouble y, gdouble w, gdouble h, gdouble offx, gdouble offy){ gdouble sw, sh; gdouble dw, dh; gdouble rx, ry, rw, rh; if (!pw->job_pixbuf) return FALSE; if (!pixbuf) return TRUE; sw = (gdouble)gdk_pixbuf_get_width(pixbuf); sh = (gdouble)gdk_pixbuf_get_height(pixbuf); dw = (gdouble)gdk_pixbuf_get_width(pw->job_pixbuf); dh = (gdouble)gdk_pixbuf_get_height(pw->job_pixbuf); x = print_preview_unit(x); y = print_preview_unit(y); w = print_preview_unit(w); h = print_preview_unit(h); offx = print_preview_unit(offx); offy = print_preview_unit(offy); if (clip_region(x, y, w, h, 0.0, 0.0, dw, dh, &rx, &ry, &rw, &rh)) { gdk_pixbuf_composite(pixbuf, pw->job_pixbuf, rx, ry, rw, rh, x + offx, y + offy, w / sw, h / sh, (w / sw < 0.01 || h / sh < 0.01) ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR, 255); image_area_changed(pw->layout_image, rx, ry, rw, rh); } return TRUE;}static gint print_job_preview_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, gdouble x, gdouble y, gdouble width, guint8 r, guint8 g, guint8 b){ PangoLayout *layout; PangoFontDescription *desc; gint lw, lh; GdkPixbuf *pixbuf; if (!pw->job_pixbuf) return FALSE; layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); desc = pango_font_description_new(); pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &lw, &lh); x = x - (gdouble)lw / 2.0; pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, lw, lh); pixbuf_set_rect_fill(pixbuf, 0, 0, lw, lh, 0, 0, 0, 0); pixbuf_draw_layout(pixbuf, layout, pw->dialog->dialog, 0, 0, r, g, b, 255); g_object_unref(G_OBJECT(layout)); print_job_preview_page_image(pw, pixbuf, x, y, (gdouble)lw, (gdouble)lh, 0, 0); g_object_unref(pixbuf); return TRUE;}static gint print_job_preview_init(PrintWindow *pw){ if (pw->job_pixbuf) g_object_unref(pw->job_pixbuf); pw->job_pixbuf = image_get_pixbuf(pw->layout_image); g_object_ref(pw->job_pixbuf); return print_job_preview_page_new(pw, pw->job_page);}/* *----------------------------------------------------------------------------- * wrappers *----------------------------------------------------------------------------- */static gint print_job_page_new(PrintWindow *pw){ switch (pw->job_format) { case RENDER_FORMAT_RGB: return print_job_rgb_page_new(pw, pw->job_page); case RENDER_FORMAT_PS: return print_job_ps_page_new(pw, pw->job_page); case RENDER_FORMAT_PREVIEW: return print_job_preview_page_new(pw, pw->job_page); } return FALSE;}static gint print_job_page_done(PrintWindow *pw){ switch (pw->job_format) { case RENDER_FORMAT_RGB: return print_job_rgb_page_done(pw); case RENDER_FORMAT_PS: return print_job_ps_page_done(pw); case RENDER_FORMAT_PREVIEW: return print_job_preview_page_done(pw); } return FALSE;}static gint print_job_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, gdouble x, gdouble y, gdouble w, gdouble h, gdouble offx, gdouble offy){ gint success = FALSE; if (w <= 0.0 || h <= 0.0) return TRUE; switch (pw->job_format) { case RENDER_FORMAT_RGB: success = print_job_rgb_page_image(pw, pixbuf, x, y, w, h, offx, offy); break; case RENDER_FORMAT_PS: success = print_job_ps_page_image(pw, pixbuf, x, y, w, h, offx, offy); break; case RENDER_FORMAT_PREVIEW: success = print_job_preview_page_image(pw, pixbuf, x, y, w, h, offx, offy); break; } return success;}static gint print_job_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, gdouble x, gdouble y, gdouble width, guint8 r, guint8 g, guint8 b){ gint success = TRUE; if (!text) return TRUE; switch (pw->job_format) { case RENDER_FORMAT_RGB: success = print_job_rgb_page_text(pw, text, point_size, x, y, width, r, g, b); break; case RENDER_FORMAT_PS: success = print_job_ps_page_text(pw, text, point_size, x, y, width, r, g, b); break; case RENDER_FORMAT_PREVIEW: success = print_job_preview_page_text(pw, text, point_size, x, y, width, r, g, b); break; } return success;}/* *----------------------------------------------------------------------------- * print ? *----------------------------------------------------------------------------- */static gint print_job_render_image(PrintWindow *pw);static gint print_job_render_proof(PrintWindow *pw);static void print_job_status(PrintWindow *pw){ gdouble value; gint page; gint total; gchar *buf; if (!pw->job_progress) return; page = pw->job_page; total = print_layout_page_count(pw); if (pw->layout == PRINT_LAYOUT_PROOF && pw->proof_point) { GList *start; start = g_list_first(pw->proof_point); value = (gdouble)g_list_position(start, pw->proof_point) / g_list_length(start); } else { value = (total > 0) ? (gdouble)page / total : 0.0; } buf = g_strdup_printf(_("Page %d"), page + 1); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pw->job_progress), buf); g_free(buf); if (pw->job_path && pw->job_progress_label) { gtk_label_set_text(GTK_LABEL(pw->job_progress_label), pw->job_path); } gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pw->job_progress), value);}static void print_job_throw_error(PrintWindow *pw, const gchar *message){ GenericDialog *gd; GtkWidget *parent = NULL; GtkWidget *group; GtkWidget *label; gchar *buf; if (GTK_WIDGET_VISIBLE(pw->dialog->dialog)) parent = pw->dialog->dialog; gd = generic_dialog_new(_("Printing error"), "GQview", "print_warning", parent, TRUE, NULL, NULL); generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, NULL, TRUE); buf = g_strdup_printf(_("An error occured printing to %s."), print_output_name(pw->output)); generic_dialog_add_message(gd, GTK_STOCK_DIALOG_ERROR, _("Printing error"), buf); g_free(buf); group = pref_group_new(gd->vbox, FALSE, _("Details"), GTK_ORIENTATION_VERTICAL); label = pref_label_new(group, message); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_widget_show(gd->dialog);}static void print_job_done(PrintWindow *pw){ print_job_close(pw, FALSE);}static gint print_job_text_image(PrintWindow *pw, const gchar *path, gdouble x, gdouble y, gdouble width, gint sw, gint sh, gint proof){ GString *string; gint space = FALSE; gint newline = FALSE; gint ret; if (pw->text_fields == 0) return TRUE; string = g_string_new(""); path = pw->job_loader->path; if (pw->text_fields & TEXT_INFO_FILENAME) { g_string_append(string, filename_from_path(path)); newline = TRUE; } if (pw->text_fields & TEXT_INFO_DIMENSIONS) { if (newline) g_string_append(string, "\n"); g_string_append_printf(string, "%d x %d", (gint)sw, (gint)sh); newline = proof; space = !proof; } if (pw->text_fields & TEXT_INFO_FILEDATE) { if (newline) g_string_append(string, "\n"); if (space) g_string_append(string, " - "); g_string_append(string, text_from_time(filetime(pw->job_loader->path))); newline = proof; space = !proof; } if (pw->text_fields & TEXT_INFO_FILESIZE) { gchar *size; if (newline) g_string_append(string, "\n"); if (space) g_string_append(string, " - "); size = text_from_size_abrev(filesize(pw->job_loader->path)); g_string_append(string, size); g_free(size); } ret = print_job_page_text(pw, string->str, pw->text_points, x, y, width, pw->text_r, pw->text_g, pw->text_b); g_string_free(string, TRUE); return ret;}static void print_job_render_image_loader_done(ImageLoader *il, gpointer data){ PrintWindow *pw = data; GdkPixbuf *pixbuf; gint success = TRUE; pixbuf = image_loader_get_pixbuf(il); if (pixbuf) { gdouble sw, sh; gdouble dw, dh; gdouble x, y, w, h; gdouble scale; gdouble offx, offy; sw = (gdouble)gdk_pixbuf_get_width(pixbuf); sh = (gdouble)gdk_pixbuf_get_height(pixbuf); dw = pw->layout_width - pw->margin_left - pw->margin_right; dh = pw->layout_height - pw->margin_top - pw->margin_bottom; if (dw / sw < dh / sh) { w = dw; h = dw / sw * sh; scale = w / sw; } else { h = dh; w = dh / sh *sw; scale = h / sh; } if (pw->image_scale >= 5) { w = w * (gdouble)pw->image_scale / 100.0; h = h * (gdouble)pw->image_scale / 100.0; } x = pw->margin_left + (dw / 2) - (w / 2); y = pw->margin_top + (dh / 2) - (h / 2); offx = offy = 0; if (x < 0) { w += x; offx = x; x = 0; } if (x + w >= pw->layout_width) w = pw->layout_width - x; if (y < 0) { h += y; offy = y; y = 0; } if (y + h >= pw->layout_height) h = pw->layout_height - y; success = (success && print_job_page_image(pw, pixbuf, x, y, w, h, offx, offy)); x = x + w / 2; y = y + h + PRINT_TEXT_PADDING; success = (success && print_job_text_image(pw, pw->job_loader->path, x, y, dw, sw, sh, FALSE)); } image_loader_free(pw->job_loader); pw->job_loader = NULL; if (pw->job_format == RENDER_FORMAT_PREVIEW) { print_job_done(pw); return; } success = (success && print_job_page_done(pw)); if (!success) { print_job_close(pw, TRUE); return; } pw->job_page++; print_job_status(pw); if (print_job_render_image(pw)) { if (!print_job_page_new(pw)) print_job_close(pw, TRUE); } else { print_job_done(pw); }}static gint print_job_render_image(PrintWindow *pw){ gchar *path = NULL; switch (pw->source) { case PRINT_SOURCE_SELECTION: path = g_list_nth_data(pw->source_selection, pw->job_page); break; case PRINT_SOURCE_ALL: path = g_list_nth_data(pw->source_list, pw->job_page); break; case PRINT_SOURCE_IMAGE: default: if (pw->job_page == 0) path = pw->source_path; break; } image_loader_free(pw->job_loader); pw->job_loader = NULL; if (!path) return FALSE; pw->job_loader = image_loader_new(path); if (!image_loader_start(pw->job_loader, print_job_render_image_loader_done, pw)) { image_loader_free(pw->job_loader); pw->job_loader= NULL; } return TRUE;}static void print_job_render_proof_loader_done(ImageLoader *il, gpointer data){ PrintWindow *pw = data; GdkPixbuf *pixbuf; gdouble x, y; gdouble w, h; gdouble proof_w, proof_h; gdouble icon_w, icon_h; gdouble scale; gint success = TRUE; if (pw->proof_columns < 1 || pw->proof_rows < 1) { image_loader_free(pw->job_loader); pw->job_loader = NULL; print_job_done(pw); return; } pixbuf = image_loader_get_pixbuf(il); w = gdk_pixbuf_get_width(pixbuf); h = gdk_pixbuf_get_height(pixbuf); if (pw->proof_width / w < pw->proof_height / h) { icon_w = pw->proof_width; icon_h = pw->proof_width / w * h; scale = icon_w / w; } else { icon_h = pw->proof_height; icon_w = pw->proof_height / h * w; scale = icon_h / h; } y = pw->proof_position / pw->proof_columns; x = pw->proof_position - (y * pw->proof_columns); print_proof_size(pw, &proof_w, &proof_h); x *= proof_w; y *= proof_h; x += pw->margin_left + (pw->layout_width - pw->margin_left - pw->margin_right - (pw->proof_columns * proof_w)) / 2 + (proof_w - icon_w) / 2; y += pw->margin_top + PRINT_PROOF_MARGIN + (pw->proof_height - icon_h) / 2; success = (success && print_job_page_image(pw, pixbuf, x, y, icon_w, icon_h, 0, 0)); x = x + icon_w / 2; y = y + icon_h + (pw->proof_height - icon_h) / 2 + PRINT_TEXT_PADDING; success = (success && print_job_text_image(pw, pw->job_loader->path, x, y, icon_w + PRINT_PROOF_MARGIN * 2, w, h, TRUE));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -