📄 print.c
字号:
}static gboolean print_window_layout_render_idle(gpointer data){ PrintWindow *pw = data; print_job_close(pw, FALSE); print_job_start(pw, RENDER_FORMAT_PREVIEW, 0); pw->layout_idle_id = -1; return FALSE;}static void print_window_layout_render(PrintWindow *pw){ gdouble proof_w, proof_h; print_proof_size(pw, &proof_w, &proof_h); pw->proof_columns = (pw->layout_width - pw->margin_left - pw->margin_right) / proof_w; pw->proof_rows = (pw->layout_height - pw->margin_top - pw->margin_bottom) / proof_h; print_window_layout_status(pw); if (pw->layout_idle_id == -1) { pw->layout_idle_id = g_idle_add(print_window_layout_render_idle, pw); }}static void print_window_layout_size(PrintWindow *pw){ GdkPixbuf *pixbuf; gdouble width; gdouble height; gint sw, sh; if (!pw->layout_image) return; if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) { width = pw->paper_height; height = pw->paper_width; } else { width = pw->paper_width; height = pw->paper_height; } pw->layout_width = width; pw->layout_height = height; sw = print_preview_unit(width); sh = print_preview_unit(height); pixbuf = image_get_pixbuf(pw->layout_image); if (!pixbuf || gdk_pixbuf_get_width(pixbuf) != sw || gdk_pixbuf_get_height(pixbuf) != sh) { pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, sw, sh); image_change_pixbuf(pw->layout_image, pixbuf, 0.0); g_object_unref(pixbuf); } print_window_layout_render(pw); print_window_layout_status(pw);}static gint print_layout_page_count(PrintWindow *pw){ gint images; gint images_per_page; gint pages; if (pw->layout_width - pw->margin_left - pw->margin_right <= 0.0 || pw->layout_height - pw->margin_top - pw->margin_bottom <= 0.0) { return 0; } switch (pw->source) { case PRINT_SOURCE_ALL: images = g_list_length(pw->source_list); break; case PRINT_SOURCE_SELECTION: images = g_list_length(pw->source_selection); break; case PRINT_SOURCE_IMAGE: default: images = (pw->source_path) ? 1 : 0; break; } switch (pw->layout) { case PRINT_LAYOUT_PROOF: images_per_page = pw->proof_columns * pw->proof_rows; break; case PRINT_LAYOUT_IMAGE: default: images_per_page = 1; break; } if (images < 1 || images_per_page < 1) return 0; pages = images / images_per_page; if (pages * images_per_page < images) pages++; return pages;}static void print_layout_page_step(PrintWindow *pw, gint step){ gint max; gint page; max = print_layout_page_count(pw); page = pw->proof_page + step; if (page >= max) page = max - 1; if (page < 0) page = 0; if (page == pw->proof_page) return; pw->proof_page = page; print_window_layout_size(pw);}static void print_layout_page_back_cb(GtkWidget *widget, gpointer data){ PrintWindow *pw = data; print_layout_page_step(pw, -1);}static void print_layout_page_next_cb(GtkWidget *widget, gpointer data){ PrintWindow *pw = data; print_layout_page_step(pw, 1);}static void print_layout_zoom_in_cb(GtkWidget *widget, gpointer data){ PrintWindow *pw = data; image_zoom_adjust(pw->layout_image, 0.25);}static void print_layout_zoom_out_cb(GtkWidget *widget, gpointer data){ PrintWindow *pw = data; image_zoom_adjust(pw->layout_image, -0.25);}static void print_layout_zoom_original_cb(GtkWidget *widget, gpointer data){ PrintWindow *pw = data; gdouble zoom; zoom = image_zoom_get(pw->layout_image); image_zoom_set(pw->layout_image, (zoom == 1.0) ? 0.0 : 1.0);}static GtkWidget *print_window_layout_setup(PrintWindow *pw, GtkWidget *box){ GtkWidget *vbox; GtkWidget *hbox; GtkWidget *group; GtkWidget *button; vbox = pref_box_new(box, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); group = pref_frame_new(vbox, TRUE, _("Preview"), GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); pw->layout_idle_id = -1; pw->layout_image = image_new(FALSE); gtk_widget_set_size_request(pw->layout_image->widget, PRINT_DLG_PREVIEW_WIDTH, PRINT_DLG_PREVIEW_HEIGHT); gtk_box_pack_start(GTK_BOX(group), pw->layout_image->widget, TRUE, TRUE, 0); gtk_widget_show(pw->layout_image->widget); hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); pw->button_back = pref_button_new(hbox, GTK_STOCK_GO_BACK, NULL, TRUE, G_CALLBACK(print_layout_page_back_cb), pw); pw->button_next = pref_button_new(hbox, GTK_STOCK_GO_FORWARD, NULL, TRUE, G_CALLBACK(print_layout_page_next_cb), pw); pw->page_label = pref_label_new(hbox, ""); button = pref_button_new(NULL, GTK_STOCK_ZOOM_OUT, NULL, TRUE, G_CALLBACK(print_layout_zoom_out_cb), pw); gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show(button); button = pref_button_new(NULL, GTK_STOCK_ZOOM_IN, NULL, TRUE, G_CALLBACK(print_layout_zoom_in_cb), pw); gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show(button); button = pref_button_new(NULL, GTK_STOCK_ZOOM_100, NULL, TRUE, G_CALLBACK(print_layout_zoom_original_cb), pw); gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show(button); print_window_layout_size(pw); return vbox;}static void print_window_spin_set(GtkSpinButton *spin, gpointer block_data, gdouble value, gdouble min, gdouble max, gdouble step, gdouble page, gint digits){ if (block_data) g_signal_handlers_block_matched(G_OBJECT(spin), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, block_data); gtk_spin_button_set_digits(spin, digits); gtk_spin_button_set_increments(spin, step, page); gtk_spin_button_set_range(spin, min, max); gtk_spin_button_set_value(spin, value); if (block_data) g_signal_handlers_unblock_matched(G_OBJECT(spin), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, block_data);}static void print_window_layout_sync_layout(PrintWindow *pw){ gtk_widget_set_sensitive(pw->image_scale_spin, (pw->layout == PRINT_LAYOUT_IMAGE)); gtk_widget_set_sensitive(pw->proof_group, (pw->layout == PRINT_LAYOUT_PROOF));}static void print_window_layout_sync_paper(PrintWindow *pw){ gdouble width, height; gint digits; gdouble step; gdouble page; gtk_widget_set_sensitive(pw->paper_width_spin, (pw->paper_size == 0)); gtk_widget_set_sensitive(pw->paper_height_spin, (pw->paper_size == 0)); width = print_paper_size_convert_units((gdouble)pw->paper_width, PAPER_UNIT_POINTS, pw->paper_units); height = print_paper_size_convert_units((gdouble)pw->paper_height, PAPER_UNIT_POINTS, pw->paper_units); switch (pw->paper_units) { case PAPER_UNIT_MM: digits = 1; step = 1.0; page = 10.0; break; case PAPER_UNIT_CM: digits = 2; step = 0.5; page = 1.0; break; case PAPER_UNIT_INCH: digits = 3; step = 0.25; page = 1.0; break; case PAPER_UNIT_PICAS: digits = 2; step = 1.0; page = 6.0; break; case PAPER_UNIT_POINTS: default: digits = 1; step = 1.0; page = 10.0; break; } print_window_spin_set(GTK_SPIN_BUTTON(pw->paper_width_spin), pw, width, print_paper_size_convert_units(PRINT_MIN_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->paper_height_spin), pw, height, print_paper_size_convert_units(PRINT_MIN_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_left_spin), pw, print_paper_size_convert_units(pw->margin_left, PAPER_UNIT_POINTS, pw->paper_units), 0.0, print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_right_spin), pw, print_paper_size_convert_units(pw->margin_right, PAPER_UNIT_POINTS, pw->paper_units), 0.0, print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_top_spin), pw, print_paper_size_convert_units(pw->margin_top, PAPER_UNIT_POINTS, pw->paper_units), 0.0, print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_bottom_spin), pw, print_paper_size_convert_units(pw->margin_bottom, PAPER_UNIT_POINTS, pw->paper_units), 0.0, print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->proof_width_spin), pw, print_paper_size_convert_units(pw->proof_width, PAPER_UNIT_POINTS, pw->paper_units), print_paper_size_convert_units(PRINT_PROOF_MIN_SIZE, PAPER_UNIT_POINTS, pw->paper_units), print_paper_size_convert_units(PRINT_PROOF_MAX_SIZE, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits); print_window_spin_set(GTK_SPIN_BUTTON(pw->proof_height_spin), pw, print_paper_size_convert_units(pw->proof_height, PAPER_UNIT_POINTS, pw->paper_units), print_paper_size_convert_units(PRINT_PROOF_MIN_SIZE, PAPER_UNIT_POINTS, pw->paper_units), print_paper_size_convert_units(PRINT_PROOF_MAX_SIZE, PAPER_UNIT_POINTS, pw->paper_units), step, page, digits);}static void print_window_layout_set_size(PrintWindow *pw, gdouble width, gdouble height){ pw->paper_width = width; pw->paper_height = height; print_window_layout_sync_paper(pw); print_window_layout_size(pw);}static void print_window_layout_set_orientation(PrintWindow *pw, PaperOrientation o){ if (pw->paper_orientation == o) return; pw->paper_orientation = o; print_window_layout_size(pw);}/* *----------------------------------------------------------------------------- * list printers *----------------------------------------------------------------------------- */static GList *print_window_list_printers(void){ FILE *p; GList *list = NULL; gchar buffer[2048]; p = popen(PRINT_LPR_QUERY, "r"); if (!p) return NULL; while (fgets(buffer, sizeof(buffer), p) != NULL) { gchar *ptr; gchar *end; ptr = buffer; if (strncmp(ptr, "printer ", 8) != 0) continue; if (strstr(ptr, "enabled") == NULL) continue; ptr += 8; end = ptr; while (*end != '\0' && *end != '\n' && *end != ' ' && *end != '\t') end++; *end = '\0'; list = g_list_append(list, g_strdup(ptr)); if (debug) printf("adding printer: %s\n", ptr); } pclose(p); return list;}/* *----------------------------------------------------------------------------- * print ps *----------------------------------------------------------------------------- */typedef struct _PipeError PipeError;struct _PipeError { struct sigaction old_action; sig_atomic_t *error;};static sig_atomic_t pipe_handler_error = FALSE;static PipeError *pipe_handler_data = NULL;static void pipe_handler_sigpipe_cb(int fd){ pipe_handler_error = TRUE;}static PipeError *pipe_handler_new(void){ struct sigaction new_action; PipeError *pe; if (pipe_handler_data) { printf("warning SIGPIPE handler already in use\n"); return NULL; } pe = g_new0(PipeError, 1); pipe_handler_error = FALSE; pe->error = &pipe_handler_error; new_action.sa_handler = pipe_handler_sigpipe_cb; sigemptyset (&new_action.sa_mask); new_action.sa_flags = 0; /* setup our signal handler */ sigaction (SIGPIPE, &new_action, &pe->old_action); pipe_handler_data = pe; return pe;}static void pipe_handler_free(PipeError *pe){ if (!pe) return; if (pe != pipe_handler_data) printf("warning SIGPIPE handler not closing same data\n"); /* restore the original signal handler */ sigaction (SIGPIPE, &pe->old_action, NULL); pipe_handler_data = NULL; g_free(pe);}static gint pipe_handler_check(PipeError *pe){ if (!pe) return FALSE; return *pe->error;}static FILE *print_job_ps_fd(PrintWindow *pw){ if (pw->job_file) return pw->job_file; if (pw->job_pipe) return pw->job_pipe; return NULL;}static gint print_job_ps_init(PrintWindow *pw){ FILE *f; PipeError *pe; const gchar *cmd = NULL; const gchar *path = NULL; gchar *lc_pointer; gint ret; if (pw->job_file != NULL || pw->job_pipe != NULL) return FALSE; switch (pw->job_output) { case PRINT_OUTPUT_PS_LPR: cmd = PRINT_LPR_COMMAND; break; case PRINT_OUTPUT_PS_CUSTOM: cmd = pw->output_custom; break; case PRINT_OUTPUT_PS_FILE: path = pw->output_path; break; default: return FALSE; break; } if (cmd) { pw->job_pipe = popen(cmd, "w"); if (!pw->job_pipe) { gchar *buf; buf = g_strdup_printf(_("Unable to open pipe for writing.\n\"%s\""), cmd); print_job_throw_error(pw, buf); g_free(buf); return FALSE; } } else if (path) { gchar *pathl; if (isfile(path)) { gchar *buf; buf = g_strdup_printf(_("A file with name %s already exists."), path); print_job_throw_error(pw, buf); g_free(buf); return FALSE; } pathl = path_from_utf8(path); pw->job_file = fopen(pathl, "w"); g_free(pathl); if (!pw->job_file) { gchar *buf; buf = g_strdup_printf(_("Failure writing to file %s"), path); print_job_throw_error(pw, buf); g_free(buf); return FALSE; } g_free(pw->job_path); pw->job_path = g_strdup(path); } f = print_job_ps_fd(pw); if (!f) return FALSE; lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); pe = pipe_handler_new(); /* comments, etc. */ fprintf(f, "%%!PS-Adobe-3.0\n"); fprintf(f, "%%%%Creator: GQview Version %s\n", VERSION); fprintf(f, "%%%%CreationDate: \n"); fprintf(f, "%%%%LanguageLevel 2\n"); fprintf(f, "%%%%DocumentMedia: \n"); fprintf(f, "%%%%Orientation: %s\n", (pw->paper_orientation == PAPER_ORIENTATION_PORTRAIT) ? "Portrait" : "Landscape"); fprintf(f, "%%%%BoundingBox: %f %f %f %f\n", 0.0, 0.0, pw->paper_width, pw->paper_height); fprintf(f, "%%%%Pages: %d\n", print_layout_page_count(pw)); fprintf(f, "%%%%PageOrder: Ascend\n"); fprintf(f, "%%%%Title:\n"); /* setup page size, coordinates (do we really need this?) */#if 0 fprintf(f, "<<\n"); fprintf(f, "/PageSize [%f %f]\n", pw->layout_width, pw->layout_height); fprintf(f, "/ImagingBBox [%f %f %f %f]\n", /* l b r t */ pw->margin_left, pw->margin_bottom, pw->layout_width - pw->margin_right, pw->layout_height - pw->margin_top); fprintf(f, "/Orientation %d\n", (pw->paper_orientation == PAPER_ORIENTATION_PORTRAIT) ? 0 : 1); fprintf(f, ">> setpagedevice\n");#endif ret = !pipe_handler_check(pe); pipe_handler_free(pe); if (lc_pointer) { setlocale(LC_NUMERIC, lc_pointer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -