📄 print.c
字号:
g_free(lc_pointer); } if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); return ret;}static gint print_job_ps_page_new(PrintWindow *pw, gint page){ FILE *f; PipeError *pe; gchar *lc_pointer; gint ret; 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(); fprintf(f, "%%%% page %d\n", page + 1); if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) { fprintf(f, "/pagelevel save def\n"); fprintf(f, "%d 0 translate 90 rotate\n", (gint)pw->layout_height); } ret = !pipe_handler_check(pe); pipe_handler_free(pe); if (lc_pointer) { setlocale(LC_NUMERIC, lc_pointer); g_free(lc_pointer); } if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); return ret;}static gint print_job_ps_page_done(PrintWindow *pw){ FILE *f; PipeError *pe; gchar *lc_pointer; gint ret; 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(); if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) { fprintf(f, "pagelevel restore\n"); } fprintf(f, "showpage\n"); ret = !pipe_handler_check(pe); pipe_handler_free(pe); if (lc_pointer) { setlocale(LC_NUMERIC, lc_pointer); g_free(lc_pointer); } if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); return ret;}static void print_job_ps_page_image_pixel(FILE *f, guchar *pix){ static gchar hex_digits[] = "0123456789abcdef"; gchar text[8]; gint i; for (i = 0; i < 3; i++) { text[i*2] = hex_digits[pix[i] >> 4]; text[i*2+1] = hex_digits[pix[i] & 0xf]; } text[6] = '\0'; fprintf(f, text);} static gint print_job_ps_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, gdouble x, gdouble y, gdouble w, gdouble h, gdouble offx, gdouble offy){ FILE *f; PipeError *pe; gchar *lc_pointer; gint sw, sh; gint bps; gint rowstride; guchar *pix; gint i, j; gint c; guchar *p; gint ret; if (!pixbuf) return TRUE; f = print_job_ps_fd(pw); if (!f) return FALSE; sw = gdk_pixbuf_get_width(pixbuf); sh = gdk_pixbuf_get_height(pixbuf); if (pw->max_dpi >= PRINT_PS_DPI_MIN && sw / pw->max_dpi > w / 72.0) { pixbuf = gdk_pixbuf_scale_simple(pixbuf, (gint)(w / 72.0 * pw->max_dpi), (gint)(h / 72.0 * pw->max_dpi), PRINT_PS_MAX_INTERP); sw = gdk_pixbuf_get_width(pixbuf); sh = gdk_pixbuf_get_height(pixbuf); } else { g_object_ref(G_OBJECT(pixbuf)); } bps = (gdk_pixbuf_get_has_alpha(pixbuf)) ? 4 : 3; rowstride = gdk_pixbuf_get_rowstride(pixbuf); pix = gdk_pixbuf_get_pixels(pixbuf); lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); pe = pipe_handler_new(); fprintf(f, "gsave\n"); fprintf(f, "[%f 0 0 %f %f %f] concat\n", w, h, x, pw->layout_height - h - y); fprintf(f, "/buf %d string def\n", sw * 3); fprintf(f, "%d %d %d\n", sw, sh, 8); fprintf(f, "[%d 0 0 -%d 0 %d]\n", sw, sh, sh); fprintf(f, "{ currentfile buf readhexstring pop }\n"); fprintf(f, "false %d colorimage\n", 3); c = 0; for (j = 0; j < sh; j++) { p = pix + j * rowstride; for (i = 0; i < sw; i++) { print_job_ps_page_image_pixel(f, p); p+=bps; c++; if (c > 11) { fprintf(f, "\n"); c = 0; } } } if (c > 0) fprintf(f, "\n"); fprintf(f, "grestore\n"); ret = !pipe_handler_check(pe); pipe_handler_free(pe); if (lc_pointer) { setlocale(LC_NUMERIC, lc_pointer); g_free(lc_pointer); } g_object_unref(G_OBJECT(pixbuf)); if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); return ret;}static const gchar *ps_text_to_hex_array(FILE *f, const gchar *text, gdouble x, gdouble y){ static gchar hex_digits[] = "0123456789abcdef"; const gchar *p; if (!text) return NULL; fprintf(f, "%f %f moveto\n", x, y); fprintf(f, "<"); /* fixme: convert utf8 to ascii or proper locale string.. */ p = text; while (*p != '\0' && *p != '\n') { gchar text[3]; text[0] = hex_digits[*p >> 4]; text[1] = hex_digits[*p & 0xf]; text[2] = '\0'; fprintf(f, text); p++; } fprintf(f, ">\n"); fprintf(f, "dup stringwidth pop 2 div neg 0 rmoveto show\n"); return p;}static void ps_text_parse(FILE *f, const gchar *text, gdouble x, gdouble y, gdouble point_size){ const gchar *p; if (!text) return; fprintf(f, "newpath\n"); p = text; while (p && *p != '\0') { p = ps_text_to_hex_array(f, p, x, y); if (p && *p == '\n') p++; y -= point_size; } fprintf(f, "closepath\n");}static gint print_job_ps_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, gdouble x, gdouble y, gdouble width, guint8 r, guint8 g, guint8 b){ FILE *f; PipeError *pe; gchar *lc_pointer; gint ret; if (!text) return TRUE; 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(); fprintf(f, "/Sans findfont\n"); fprintf(f, "%f scalefont\n", point_size); fprintf(f, "setfont\n"); fprintf(f, "%f %f %f setrgbcolor\n", (gdouble)r / 255.0, (gdouble)g / 255.0, (gdouble)b / 255.0); ps_text_parse(f, text, x, pw->layout_height - y - point_size, point_size); ret = !pipe_handler_check(pe); pipe_handler_free(pe); if (lc_pointer) { setlocale(LC_NUMERIC, lc_pointer); g_free(lc_pointer); } if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); return ret;}static gint print_job_ps_end(PrintWindow *pw){ FILE *f; PipeError *pe; gchar *lc_pointer; gint ret; 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(); fprintf(f, "%%%%EOF\n"); ret = !pipe_handler_check(pe); pipe_handler_free(pe); if (lc_pointer) { setlocale(LC_NUMERIC, lc_pointer); g_free(lc_pointer); } if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); return ret;}/* *----------------------------------------------------------------------------- * print rgb *----------------------------------------------------------------------------- */static gint print_job_rgb_page_new(PrintWindow *pw, gint page){ gint total; if (pw->job_pixbuf) { pixbuf_set_rect_fill(pw->job_pixbuf, 0, 0, gdk_pixbuf_get_width(pw->job_pixbuf), gdk_pixbuf_get_height(pw->job_pixbuf), 255, 255, 255, 255); } g_free(pw->job_path); pw->job_path = NULL; total = print_layout_page_count(pw); if (!pw->output_path || page < 0 || page >= total) return FALSE; if (total > 1) { const gchar *ext; gchar *base; ext = extension_from_path(pw->output_path); if (ext) { base = g_strndup(pw->output_path, ext - pw->output_path); } else { base = g_strdup(pw->output_path); ext = ""; } pw->job_path = g_strdup_printf("%s_%03d%s", base, page + 1, ext); g_free(base); } else { pw->job_path = g_strdup(pw->output_path); } if (isfile(pw->job_path)) { gchar *buf; buf = g_strdup_printf(_("A file with name %s already exists."), pw->job_path); print_job_throw_error(pw, buf); g_free(buf); g_free(pw->job_path); pw->job_path = NULL; } return (pw->job_path != NULL);}static gint print_job_rgb_page_done(PrintWindow *pw){ gchar *pathl; gint ret = FALSE; if (!pw->job_pixbuf) return FALSE; pathl = path_from_utf8(pw->job_path); if (pw->output_format == PRINT_FILE_PNG) { ret = pixbuf_to_file_as_png(pw->job_pixbuf, pathl); } else { gint quality = 0; switch (pw->output_format) { case PRINT_FILE_JPG_LOW: quality = 65; break; case PRINT_FILE_JPG_NORMAL: quality = 80; break; case PRINT_FILE_JPG_HIGH: quality = 95; break; default: break; } if (quality > 0) { ret = pixbuf_to_file_as_jpg(pw->job_pixbuf, pathl, quality); } } g_free(pathl); if (!ret) { gchar *buf; buf = g_strdup_printf(_("Failure writing to file %s"), pw->job_path); print_job_throw_error(pw, buf); g_free(buf); } return ret;}static gint print_job_rgb_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); 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); } return TRUE;}static gdouble convert_pango_dpi(gdouble points){ static gdouble dpi = 0.0; if (dpi == 0.0) { GtkSettings *settings; GObjectClass *klass; settings = gtk_settings_get_default(); klass = G_OBJECT_CLASS(GTK_SETTINGS_GET_CLASS(settings)); if (g_object_class_find_property(klass, "gtk-xft-dpi")) { int int_dpi; g_object_get(settings, "gtk-xft-dpi", &int_dpi, NULL); dpi = (gdouble)int_dpi / PANGO_SCALE; } if (dpi < 25.0) { static gint warned = FALSE; gdouble fallback_dpi = 96.0; if (!warned) { if (dpi == 0.0) { printf("pango dpi unknown, assuming %.0f\n", fallback_dpi); } else { printf("pango dpi reported as %.0f ignored, assuming %.0f\n", dpi, fallback_dpi); } warned = TRUE; } dpi = fallback_dpi; } } if (dpi == 0) return points; return points * 72.0 / dpi;}static gint print_job_rgb_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; 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_draw_layout(pw->job_pixbuf, layout, pw->dialog->dialog, x, y, r, g, b, 255); g_object_unref(G_OBJECT(layout)); return TRUE;}static gint print_job_rgb_init(PrintWindow *pw){ if (pw->job_pixbuf) g_object_unref(pw->job_pixbuf); pw->job_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, (gint)pw->layout_width, (gint)pw->layout_height); return print_job_rgb_page_new(pw, pw->job_page);}/* *----------------------------------------------------------------------------- * print preview *----------------------------------------------------------------------------- */static gint print_job_preview_page_new(PrintWindow *pw, gint page){ GdkPixbuf *pixbuf; gint w, h; gint l, r, t, b; pixbuf = pw->job_pixbuf; if (!pixbuf) return FALSE; w = print_preview_unit(pw->layout_width); h = print_preview_unit(pw->layout_height); l = print_preview_unit(pw->margin_left); r = print_preview_unit(pw->margin_right); t = print_preview_unit(pw->margin_top); b = print_preview_unit(pw->margin_bottom); /* fill background */ pixbuf_set_rect_fill(pixbuf, 0, 0, w, h,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -