⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 print.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * GQview * (C) 2004 John Ellis * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */#include "gqview.h"#include "print.h"#include "filelist.h"#include "image.h"#include "image-load.h"#include "pixbuf_util.h"#include "thumb.h"#include "utilops.h"#include "ui_bookmark.h"#include "ui_menu.h"#include "ui_misc.h"#include "ui_utildlg.h"#include "ui_fileops.h"#include "ui_spinner.h"#include "ui_tabcomp.h"#include <locale.h>#include <signal.h>#define PRINT_LPR_COMMAND "lpr"#define PRINT_LPR_CUSTOM  "lpr -P %s"#define PRINT_LPR_QUERY   "lpstat -p"#define PRINT_DLG_WIDTH 600#define PRINT_DLG_HEIGHT 400#define PRINT_DLG_PREVIEW_WIDTH 270#define PRINT_DLG_PREVIEW_HEIGHT -1/* these are in point units */#define PRINT_MIN_WIDTH 100#define PRINT_MIN_HEIGHT 100#define PRINT_MAX_WIDTH 4000#define PRINT_MAX_HEIGHT 4000#define PRINT_MARGIN_DEFAULT 36#define PRINT_PROOF_MIN_SIZE 8#define PRINT_PROOF_MAX_SIZE 720#define PRINT_PROOF_DEFAULT_SIZE 144#define PRINT_PROOF_MARGIN 5/* default page size */#define PAGE_LAYOUT_WIDTH 850#define PAGE_LAYOUT_HEIGHT 1100/* preview uses 1 pixel = PRINT_PREVIEW_SCALE points */#define PRINT_PREVIEW_SCALE 4/* default dpi to use for printing ps image data */#define PRINT_PS_DPI_DEFAULT 300.0#define PRINT_PS_DPI_MIN 150.0/* method to use when scaling down image data */#define PRINT_PS_MAX_INTERP GDK_INTERP_BILINEAR/* padding between objects */#define PRINT_TEXT_PADDING 3.0/* locale for postscript portability */#define POSTSCRIPT_LOCALE "C"/* group and keys for saving prefs */#define PRINT_PREF_GROUP	"print_settings"#define PRINT_PREF_SAVE		"save_settings"#define PRINT_PREF_OUTPUT	"output"#define PRINT_PREF_FORMAT	"format"#define PRINT_PREF_DPI		"dpi"#define PRINT_PREF_UNITS	"units"#define PRINT_PREF_SIZE		"size"#define PRINT_PREF_ORIENTATION	"orientation"#define PRINT_PREF_CUSTOM_WIDTH		"custom_width"#define PRINT_PREF_CUSTOM_HEIGHT	"custom_height"#define PRINT_PREF_MARGIN_LEFT		"margin_left"#define PRINT_PREF_MARGIN_RIGHT		"margin_right"#define PRINT_PREF_MARGIN_TOP		"margin_top"#define PRINT_PREF_MARGIN_BOTTOM	"margin_bottom"#define PRINT_PREF_PROOF_WIDTH		"proof_width"#define PRINT_PREF_PROOF_HEIGHT		"proof_height"#define PRINT_PREF_PRINTERC	"custom_printer"typedef enum {	PRINT_SOURCE_IMAGE = 0,	PRINT_SOURCE_SELECTION,	PRINT_SOURCE_ALL,	PRINT_SOURCE_COUNT} PrintSource;const gchar *print_source_text[] = {	N_("Image"),	N_("Selection"),	N_("All"),	NULL};typedef enum {	PRINT_LAYOUT_IMAGE = 0,	PRINT_LAYOUT_PROOF,	PRINT_LAYOUT_COUNT} PrintLayout;const gchar *print_layout_text[] = {	N_("One image per page"),	N_("Proof sheet"),	NULL};typedef enum {	PRINT_OUTPUT_PS_LPR = 0,	PRINT_OUTPUT_PS_CUSTOM,	PRINT_OUTPUT_PS_FILE,	PRINT_OUTPUT_RGB_FILE,	PRINT_OUTPUT_COUNT} PrintOutput;const gchar *print_output_text[] = {	N_("Default printer"),	N_("Custom printer"),	N_("PostScript file"),	N_("Image file"),	NULL,	NULL};typedef enum {	PRINT_FILE_JPG_LOW = 0,	PRINT_FILE_JPG_NORMAL,	PRINT_FILE_JPG_HIGH,	PRINT_FILE_PNG,	PRINT_FILE_COUNT} PrintFileFormat;const gchar *print_file_format_text[] = {	N_("jpeg, low quality"),	N_("jpeg, normal quality"),	N_("jpeg, high quality"),	"png",	NULL};typedef enum {	RENDER_FORMAT_PREVIEW,	RENDER_FORMAT_RGB,	RENDER_FORMAT_PS} RenderFormat;typedef enum {	TEXT_INFO_FILENAME = 1 << 0,	TEXT_INFO_FILEDATE = 1 << 1,	TEXT_INFO_FILESIZE = 1 << 2,	TEXT_INFO_DIMENSIONS = 1 << 3} TextInfo;typedef struct _PrintWindow PrintWindow;struct _PrintWindow{	GenericDialog *dialog;	gchar *source_path;	GList *source_selection;	GList *source_list;	PrintSource source;	PrintLayout layout;	PrintOutput output;	gchar *output_path;	gchar *output_custom;	PrintFileFormat output_format;	gdouble max_dpi;	GtkWidget *notebook;	GtkWidget *path_entry;	GtkWidget *custom_entry;	GtkWidget *path_format_menu;	GtkWidget *max_dpi_menu;	ImageWindow *layout_image;	gdouble layout_width;	gdouble layout_height;	gint layout_idle_id;	gint image_scale;	GtkWidget *image_scale_spin;	gdouble proof_width;	gdouble proof_height;	gint proof_columns;	gint proof_rows;	GList *proof_point;	gint proof_position;	gint proof_page;	GtkWidget *proof_group;	GtkWidget *proof_width_spin;	GtkWidget *proof_height_spin;	GtkWidget *paper_menu;	GtkWidget *paper_width_spin;	GtkWidget *paper_height_spin;	GtkWidget *paper_units_menu;	GtkWidget *paper_orientation_menu;	GtkWidget *margin_left_spin;	GtkWidget *margin_right_spin;	GtkWidget *margin_top_spin;	GtkWidget *margin_bottom_spin;	gint paper_units;	gint paper_size;	gdouble paper_width;	gdouble paper_height;	gint paper_orientation;	gdouble margin_left;	gdouble margin_right;	gdouble margin_top;	gdouble margin_bottom;	GtkWidget *button_back;	GtkWidget *button_next;	GtkWidget *page_label;	GtkWidget *print_button;	gdouble single_scale;	gdouble single_x;	gdouble single_y;	GtkWidget *single_scale_spin;	TextInfo	text_fields;	gint		text_points;	guint8		text_r;	guint8		text_g;	guint8		text_b;	gint save_settings;	/* job printing */	GenericDialog	*job_dialog;	GtkWidget	*job_progress;	GtkWidget	*job_progress_label;	RenderFormat	 job_format;	PrintOutput	 job_output;	FILE		*job_file;	FILE 		*job_pipe;	gchar		*job_path;	GdkPixbuf	*job_pixbuf;	gint		 job_page;	ImageLoader	*job_loader;};static void print_job_throw_error(PrintWindow *pw, const gchar *message);static gint print_job_start(PrintWindow *pw, RenderFormat format, PrintOutput output);static void print_job_close(PrintWindow *pw, gint error);static void print_window_close(PrintWindow *pw);/* misc utils */static gint clip_region(gdouble x1, gdouble y1, gdouble w1, gdouble h1,			gdouble x2, gdouble y2, gdouble w2, gdouble h2,			gdouble *rx, gdouble *ry, gdouble *rw, gdouble *rh){	if (x2 + w2 <= x1 || x2 >= x1 + w1 ||	    y2 + h2 <= y1 || y2 >= y1 + h1)		{		return FALSE;		}	*rx = MAX(x1, x2);	*rw = MIN((x1 + w1), (x2 + w2)) - *rx;	*ry = MAX(y1, y2);	*rh = MIN((y1 + h1), (y2 + h2)) - *ry;	return TRUE;}static const gchar *print_output_name(PrintOutput output){	if (output < 0 || output >= PRINT_OUTPUT_COUNT) return "";	return _(print_output_text[output]);}/* *----------------------------------------------------------------------------- * data *----------------------------------------------------------------------------- */typedef enum {	PAPER_UNIT_POINTS = 0,	PAPER_UNIT_MM,	PAPER_UNIT_CM,	PAPER_UNIT_INCH,	PAPER_UNIT_PICAS,	PAPER_UNIT_COUNT} PaperUnits;typedef enum {	PAPER_ORIENTATION_PORTRAIT = 0,	PAPER_ORIENTATION_LANDSCAPE,	PAPER_ORIENTATION_COUNT} PaperOrientation;typedef struct _PaperSize PaperSize;struct _PaperSize {	gchar *description;	gint width;	gint height;	PaperOrientation orientation;};const gchar *print_paper_units[] = {	N_("points"),	N_("millimeters"),	N_("centimeters"),	N_("inches"),	N_("picas"),	NULL};const gchar *print_paper_orientation[] = {	N_("Portrait"),	N_("Landscape"),	NULL};PaperSize print_paper_sizes[] = {	{ N_("Custom"),		360,	720,	PAPER_ORIENTATION_PORTRAIT },	{ N_("Letter"),		612,	792,	PAPER_ORIENTATION_PORTRAIT },	/* in 8.5 x 11 */	{ N_("Legal"),		612,	1008,	PAPER_ORIENTATION_PORTRAIT },	/* in 8.5 x 14 */	{ N_("Executive"),	522,	756,	PAPER_ORIENTATION_PORTRAIT },	/* in 7.25x 10.5 */	{ "A0",			2384,	3370,	PAPER_ORIENTATION_PORTRAIT },	/* mm 841 x 1189 */	{ "A1",			1684,	2384,	PAPER_ORIENTATION_PORTRAIT },	/* mm 594 x 841 */	{ "A2",			1191,	1684,	PAPER_ORIENTATION_PORTRAIT },	/* mm 420 x 594 */	{ "A3",			842,	1191,	PAPER_ORIENTATION_PORTRAIT },	/* mm 297 x 420 */	{ "A4",			595,	842,	PAPER_ORIENTATION_PORTRAIT },	/* mm 210 x 297 */	{ "A5",			420,	595,	PAPER_ORIENTATION_PORTRAIT },	/* mm 148 x 210 */	{ "A6",			298,	420,	PAPER_ORIENTATION_PORTRAIT },	/* mm 105 x 148 */	{ "B3",			1001,	1417,	PAPER_ORIENTATION_PORTRAIT },	/* mm 353 x 500 */	{ "B4",			709,	1001,	PAPER_ORIENTATION_PORTRAIT },	/* mm 250 x 353 */	{ "B5",			499,	709,	PAPER_ORIENTATION_PORTRAIT },	/* mm 176 x 250 */	{ "B6",			354,	499,	PAPER_ORIENTATION_PORTRAIT },	/* mm 125 x 176 */	{ N_("Envelope #10"),	297,	684,	PAPER_ORIENTATION_LANDSCAPE },	/* in 4.125 x 9.5 */	{ N_("Envelope #9"),	279,	639,	PAPER_ORIENTATION_LANDSCAPE },	/* in 3.875 x 8.875 */	{ N_("Envelope C4"),	649,	918,	PAPER_ORIENTATION_LANDSCAPE },	/* mm 229 x 324 */	{ N_("Envelope C5"),	459,	649,	PAPER_ORIENTATION_LANDSCAPE },	/* mm 162 x 229 */	{ N_("Envelope C6"),	323,	459,	PAPER_ORIENTATION_LANDSCAPE },	/* mm 114 x 162 */	{ N_("Photo 6x4"),	432,	288,	PAPER_ORIENTATION_PORTRAIT },	/* in 6   x 4 */	{ N_("Photo 8x10"),	576,	720,	PAPER_ORIENTATION_PORTRAIT },	/* in 8   x 10 */	{ N_("Postcard"),	284,	419,	PAPER_ORIENTATION_LANDSCAPE },	/* mm 100 x 148 */	{ N_("Tabloid"),	792,	1224,	PAPER_ORIENTATION_PORTRAIT },	/* in 11  x 17 */	{ NULL, 0, 0, 0 }};static PaperSize *print_paper_size_nth(gint n){	PaperSize *ps = NULL;	gint i = 0;	while (i <= n && print_paper_sizes[i].description)		{		ps = &print_paper_sizes[i];		i++;		}	return ps;}static gint print_paper_size_lookup(gint n, gdouble *width, gdouble *height){	PaperSize *ps;	gdouble w, h;	ps = print_paper_size_nth(n);	if (!ps) return FALSE;	if (ps->orientation == PAPER_ORIENTATION_PORTRAIT)		{		w = ps->width;		h = ps->height;		}	else		{		h = ps->width;		w = ps->height;		}	if (width) *width = w;	if (height) *height = h;	return TRUE;}static gdouble print_paper_size_convert_units(gdouble value, PaperUnits src, PaperUnits dst){	gdouble ret;	if (src == dst) return value;	switch (src)		{		case PAPER_UNIT_MM:			ret = value / 25.4 * 72.0;			break;		case PAPER_UNIT_CM:			ret = value / 2.54 * 72.0;			break;		case PAPER_UNIT_INCH:			ret = value * 72.0;			break;		case PAPER_UNIT_PICAS:			ret = value * 12.0;			break;		case PAPER_UNIT_POINTS:		default:			ret = value;			break;		}	switch (dst)		{		case PAPER_UNIT_MM:			ret = ret / 72.0 * 25.4;			break;		case PAPER_UNIT_CM:			ret = ret / 72.0 * 2.54;			break;		case PAPER_UNIT_INCH:			ret = ret / 72.0;			break;		case PAPER_UNIT_PICAS:			ret = ret / 12.0;			break;		case PAPER_UNIT_POINTS:		default:			break;		}	return ret;}static PaperUnits paper_unit_default(void){	const char *result;#if 0	/* this is not used because it is not even slightly portable */	#include <langinfo.h>	result = nl_langinfo(_NL_MEASUREMENT_MEASUREMENT);	if (result[0] == '2') return PAPER_UNIT_INCH;#endif#ifdef LC_MEASUREMENT	result = setlocale(LC_MEASUREMENT, NULL);#else	result = setlocale(LC_ALL, NULL);#endif	if (result &&	    (strstr(result, "_US") || strstr(result, "_PR")) )		{		return PAPER_UNIT_INCH;		}	return PAPER_UNIT_CM;}/* *----------------------------------------------------------------------------- * the layout window *----------------------------------------------------------------------------- */static gint print_layout_page_count(PrintWindow *pw);static gint print_preview_unit(gdouble points){	return (int)(points / PRINT_PREVIEW_SCALE);}static void print_proof_size(PrintWindow *pw, gdouble *width, gdouble *height){	if (width) *width = pw->proof_width + PRINT_PROOF_MARGIN * 2;	if (height)		{		gdouble h;		h = pw->proof_height + PRINT_PROOF_MARGIN * 2;		if (pw->text_fields != 0) h += PRINT_TEXT_PADDING;		if (pw->text_fields & TEXT_INFO_FILENAME) h+= (gdouble)pw->text_points * 1.25;		if (pw->text_fields & TEXT_INFO_DIMENSIONS) h+= (gdouble)pw->text_points * 1.25;		if (pw->text_fields & TEXT_INFO_FILEDATE) h+= (gdouble)pw->text_points * 1.25;		if (pw->text_fields & TEXT_INFO_FILESIZE) h+= (gdouble)pw->text_points * 1.25;		*height = h;		}}static void print_window_layout_status(PrintWindow *pw){	gint total;	gchar *buf;	total = print_layout_page_count(pw);	pw->proof_page = CLAMP(pw->proof_page, 0, total - 1);	buf = g_strdup_printf(_("page %d of %d"), pw->proof_page + 1, (total > 0) ? total : 1);	gtk_label_set_text(GTK_LABEL(pw->page_label), buf);	g_free(buf);	gtk_widget_set_sensitive(pw->page_label, (total > 0));	gtk_widget_set_sensitive(pw->button_back, (pw->proof_page > 0));	gtk_widget_set_sensitive(pw->button_next, (pw->proof_page < total - 1));	gtk_widget_set_sensitive(pw->print_button, total > 0);}static void print_window_layout_render_stop(PrintWindow *pw){	if (pw->layout_idle_id != -1)		{		g_source_remove(pw->layout_idle_id);		pw->layout_idle_id = -1;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -