Implement per-page paper sizes.

2006-05-05  Alexander Larsson  <alexl@redhat.com>

	* gtk/gtkprintoperation-unix.c:
	Implement per-page paper sizes.

	* gtk/gtkprintoperation.c:
	Implement per-page paper sizes for pdf output.
	Make gtk_print_operation_set_pdf_target() work again

	* tests/Makefile.am:
	* tests/testprint.c:
	* tests/testprintfileoperation.[ch]:
	Add more test code for printing support.
	This tests per-page paper sizes & orientation and
	deriving from GtkPrintOperation.
This commit is contained in:
Alexander Larsson 2006-05-05 11:03:33 +00:00 committed by Alexander Larsson
parent f78961034b
commit 719050ed1f
8 changed files with 399 additions and 2 deletions

View File

@ -1,3 +1,19 @@
2006-05-05 Alexander Larsson <alexl@redhat.com>
* gtk/gtkprintoperation-unix.c:
Implement per-page paper sizes.
* gtk/gtkprintoperation.c:
Implement per-page paper sizes for pdf output.
Make gtk_print_operation_set_pdf_target() work again
* tests/Makefile.am:
* tests/testprint.c:
* tests/testprintfileoperation.[ch]:
Add more test code for printing support.
This tests per-page paper sizes & orientation and
deriving from GtkPrintOperation.
2006-05-04 Michael Emmel <mike.emmel@gmail.com>
* gdk/directfb/gdkkeys-directfb.c: DIKI_ALTGR to compile with

View File

@ -1,3 +1,19 @@
2006-05-05 Alexander Larsson <alexl@redhat.com>
* gtk/gtkprintoperation-unix.c:
Implement per-page paper sizes.
* gtk/gtkprintoperation.c:
Implement per-page paper sizes for pdf output.
Make gtk_print_operation_set_pdf_target() work again
* tests/Makefile.am:
* tests/testprint.c:
* tests/testprintfileoperation.[ch]:
Add more test code for printing support.
This tests per-page paper sizes & orientation and
deriving from GtkPrintOperation.
2006-05-04 Michael Emmel <mike.emmel@gmail.com>
* gdk/directfb/gdkkeys-directfb.c: DIKI_ALTGR to compile with

View File

@ -58,7 +58,21 @@ unix_start_page (GtkPrintOperation *op,
GtkPrintContext *print_context,
GtkPageSetup *page_setup)
{
GtkPaperSize *paper_size;
cairo_surface_type_t type;
double w, h;
paper_size = gtk_page_setup_get_paper_size (page_setup);
w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
type = cairo_surface_get_type (op->priv->surface);
if (type == CAIRO_SURFACE_TYPE_PS)
cairo_ps_surface_set_size (op->priv->surface, w, h);
else if (type == CAIRO_SURFACE_TYPE_PDF)
cairo_pdf_surface_set_size (op->priv->surface, w, h);
}
static void

View File

@ -1101,7 +1101,15 @@ pdf_start_page (GtkPrintOperation *op,
GtkPrintContext *print_context,
GtkPageSetup *page_setup)
{
/* TODO: Set up page size, not supported in cairo yet */
GtkPaperSize *paper_size;
double w, h;
paper_size = gtk_page_setup_get_paper_size (page_setup);
w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
cairo_pdf_surface_set_size (op->priv->surface, w, h);
}
static void
@ -1143,14 +1151,21 @@ run_pdf (GtkPrintOperation *op,
priv->surface = cairo_pdf_surface_create (priv->pdf_target,
width, height);
/* TODO: DPI from settings object? */
cairo_pdf_surface_set_dpi (priv->surface, 300, 300);
priv->dpi_x = 72;
priv->dpi_y = 72;
priv->print_pages = GTK_PRINT_PAGES_ALL;
priv->page_ranges = NULL;
priv->num_page_ranges = 0;
priv->manual_num_copies = 1;
priv->manual_collation = FALSE;
priv->manual_reverse = FALSE;
priv->manual_page_set = GTK_PAGE_SET_ALL;
priv->manual_scale = 1.0;
priv->manual_orientation = TRUE;
*do_print = TRUE;

View File

@ -54,6 +54,7 @@ noinst_PROGRAMS = \
testmultiscreen \
testnotebookdnd \
testnouiprint \
testprint \
testrgb \
testrecentchooser \
testselection \
@ -109,6 +110,7 @@ testmultidisplay_DEPENDENCIES = $(TEST_DEPS)
testmultiscreen_DEPENDENCIES = $(TEST_DEPS)
testnotebookdnd_DEPENDENCIES = $(TEST_DEPS)
testnouiprint_DEPENDENCIES = $(TEST_DEPS)
testprint_DEPENDENCIES = $(TEST_DEPS)
testrecentchooser_DEPENDENCIES = $(TEST_DEPS)
testrgb_DEPENDENCIES = $(TEST_DEPS)
testselection_DEPENDENCIES = $(TEST_DEPS)
@ -158,6 +160,7 @@ testmultidisplay_LDADD = $(LDADDS)
testmultiscreen_LDADD = $(LDADDS)
testnotebookdnd_LDADD = $(LDADDS)
testnouiprint_LDADD = $(LDADDS)
testprint_LDADD = $(LDADDS)
testrecentchooser_LDADD = $(LDADDS)
testrgb_LDADD = $(LDADDS)
testselection_LDADD = $(LDADDS)
@ -224,6 +227,10 @@ testtoolbar_SOURCES = \
testtoolbar.c \
prop-editor.c
testprint_SOURCES = \
testprint.c \
testprintfileoperation.c
testsocket_SOURCES = \
testsocket.c \
testsocket_common.c

123
tests/testprint.c Normal file
View File

@ -0,0 +1,123 @@
/* GTK - The GIMP Toolkit
* testprint.c: Print example
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <gtk/gtk.h>
#include <gtk/gtkprintoperation.h>
#include "testprintfileoperation.h"
static void
request_page_setup (GtkPrintOperation *operation,
GtkPrintContext *context,
int page_nr,
GtkPageSetup *setup)
{
/* Make the second page landscape mode a5 */
if (page_nr == 1)
{
GtkPaperSize *a5_size = gtk_paper_size_new ("iso_a5");
gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_LANDSCAPE);
gtk_page_setup_set_paper_size (setup, a5_size);
gtk_paper_size_free (a5_size);
}
}
static void
draw_page (GtkPrintOperation *operation,
GtkPrintContext *context,
int page_nr)
{
cairo_t *cr;
PangoLayout *layout;
PangoFontDescription *desc;
cr = gtk_print_context_get_cairo (context);
/* Draw a red rectangle, as wide as the paper (inside the margins) */
cairo_set_source_rgb (cr, 1.0, 0, 0);
cairo_rectangle (cr, 0, 0, gtk_print_context_get_width (context), 50);
cairo_fill (cr);
/* Draw some lines */
cairo_move_to (cr, 20, 10);
cairo_line_to (cr, 40, 20);
cairo_arc (cr, 60, 60, 20, 0, M_PI);
cairo_line_to (cr, 80, 20);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_set_line_width (cr, 5);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_stroke (cr);
/* Draw some text */
layout = gtk_print_context_create_layout (context);
pango_layout_set_text (layout, "Hello World! Printing is easy", -1);
desc = pango_font_description_from_string ("sans 28");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 30, 20);
pango_cairo_layout_path (cr, layout);
/* Font Outline */
cairo_set_source_rgb (cr, 0.93, 1.0, 0.47);
cairo_set_line_width (cr, 0.5);
cairo_stroke_preserve (cr);
/* Font Fill */
cairo_set_source_rgb (cr, 0, 0.0, 1.0);
cairo_fill (cr);
g_object_unref (layout);
}
int
main (int argc, char **argv)
{
GtkPrintOperation *print;
GtkPrintOperationResult res;
TestPrintFileOperation *print_file;
gtk_init (&argc, &argv);
/* Test some random drawing, with per-page paper settings */
print = gtk_print_operation_new ();
gtk_print_operation_set_nr_of_pages (print, 2);
gtk_print_operation_set_unit (print, GTK_UNIT_MM);
gtk_print_operation_set_pdf_target (print, "test.pdf");
g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), NULL);
g_signal_connect (print, "request_page_setup", G_CALLBACK (request_page_setup), NULL);
res = gtk_print_operation_run (print, NULL, NULL);
/* Test subclassing of GtkPrintOperation */
print_file = test_print_file_operation_new ("testprint.c");
test_print_file_operation_set_font_size (print_file, 12.0);
gtk_print_operation_set_pdf_target (GTK_PRINT_OPERATION (print_file), "test2.pdf");
res = gtk_print_operation_run (GTK_PRINT_OPERATION (print_file), NULL, NULL);
return 0;
}

View File

@ -0,0 +1,163 @@
#include <pango/pangocairo.h>
#include <gtk/gtk.h>
#include <math.h>
#include "testprintfileoperation.h"
/* In points */
#define HEADER_HEIGHT (10*72/25.4)
#define HEADER_GAP (3*72/25.4)
G_DEFINE_TYPE (TestPrintFileOperation, test_print_file_operation, GTK_TYPE_PRINT_OPERATION)
static void
test_print_file_operation_finalize (GObject *object)
{
TestPrintFileOperation *op = TEST_PRINT_FILE_OPERATION (object);
g_free (op->filename);
G_OBJECT_CLASS (test_print_file_operation_parent_class)->finalize (object);
}
static void
test_print_file_operation_init (TestPrintFileOperation *operation)
{
gtk_print_operation_set_unit (GTK_PRINT_OPERATION (operation), GTK_UNIT_POINTS);
operation->font_size = 14.0;
}
TestPrintFileOperation *
test_print_file_operation_new (const char *filename)
{
TestPrintFileOperation *op;
op = g_object_new (TEST_TYPE_PRINT_FILE_OPERATION, NULL);
op->filename = g_strdup (filename);
return op;
}
void
test_print_file_operation_set_font_size (TestPrintFileOperation *op,
double points)
{
op->font_size = points;
}
static void
test_print_file_operation_begin_print (GtkPrintOperation *operation, GtkPrintContext *context)
{
TestPrintFileOperation *op = TEST_PRINT_FILE_OPERATION (operation);
char *contents;
int i;
double height;
height = gtk_print_context_get_height (context) - HEADER_HEIGHT - HEADER_GAP;
op->lines_per_page = floor (height / op->font_size);
g_file_get_contents (op->filename,
&contents,
NULL, NULL);
op->lines = g_strsplit (contents, "\n", 0);
g_free (contents);
i = 0;
while (op->lines[i] != NULL)
i++;
op->num_lines = i;
op->num_pages = (op->num_lines - 1) / op->lines_per_page + 1;
gtk_print_operation_set_nr_of_pages (operation, op->num_pages);
}
static void
test_print_file_operation_draw_page (GtkPrintOperation *operation,
GtkPrintContext *context,
int page_nr)
{
cairo_t *cr;
PangoLayout *layout;
TestPrintFileOperation *op = TEST_PRINT_FILE_OPERATION (operation);
double width, text_height;
int line, i, layout_height;
PangoFontDescription *desc;
char *page_str;
cr = gtk_print_context_get_cairo (context);
width = gtk_print_context_get_width (context);
cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);
cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_set_line_width (cr, 1);
cairo_stroke (cr);
layout = gtk_print_context_create_layout (context);
desc = pango_font_description_from_string ("sans 14");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
pango_layout_set_text (layout, op->filename, -1);
pango_layout_set_width (layout, width);
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
pango_layout_get_size (layout, NULL, &layout_height);
text_height = (double)layout_height / PANGO_SCALE;
cairo_move_to (cr, width / 2, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
page_str = g_strdup_printf ("%d/%d", page_nr + 1, op->num_pages);
pango_layout_set_text (layout, page_str, -1);
g_free (page_str);
pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
cairo_move_to (cr, width - 2, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
g_object_unref (layout);
layout = gtk_print_context_create_layout (context);
desc = pango_font_description_from_string ("mono");
pango_font_description_set_size (desc, op->font_size * PANGO_SCALE);
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP);
line = page_nr * op->lines_per_page;
for (i = 0; i < op->lines_per_page && line < op->num_lines; i++, line++) {
pango_layout_set_text (layout, op->lines[line], -1);
pango_cairo_show_layout (cr, layout);
cairo_rel_move_to (cr, 0, op->font_size);
}
g_object_unref (layout);
}
static void
test_print_file_operation_end_print (GtkPrintOperation *operation, GtkPrintContext *context)
{
TestPrintFileOperation *op = TEST_PRINT_FILE_OPERATION (operation);
g_strfreev (op->lines);
}
static void
test_print_file_operation_class_init (TestPrintFileOperationClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
GtkPrintOperationClass *print_class = (GtkPrintOperationClass *)class;
gobject_class->finalize = test_print_file_operation_finalize;
print_class->begin_print = test_print_file_operation_begin_print;
print_class->draw_page = test_print_file_operation_draw_page;
print_class->end_print = test_print_file_operation_end_print;
}

View File

@ -0,0 +1,43 @@
#ifndef __TEST_PRINT_FILE_OPERATION_H__
#define __TEST_PRINT_FILE_OPERATION_H__
#include <gtk/gtkprintoperation.h>
G_BEGIN_DECLS
#define TEST_TYPE_PRINT_FILE_OPERATION (test_print_file_operation_get_type ())
#define TEST_PRINT_FILE_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_PRINT_FILE_OPERATION, TestPrintFileOperation))
#define TEST_IS_PRINT_FILE_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_PRINT_FILE_OPERATION))
typedef struct _TestPrintFileOperationClass TestPrintFileOperationClass;
typedef struct _TestPrintFileOperationPrivate TestPrintFileOperationPrivate;
typedef struct _TestPrintFileOperation TestPrintFileOperation;
struct _TestPrintFileOperation
{
GtkPrintOperation parent_instance;
/* < private > */
char *filename;
double font_size;
int lines_per_page;
char **lines;
int num_lines;
int num_pages;
};
struct _TestPrintFileOperationClass
{
GtkPrintOperationClass parent_class;
};
GType test_print_file_operation_get_type (void);
TestPrintFileOperation *test_print_file_operation_new (const char *filename);
void test_print_file_operation_set_font_size (TestPrintFileOperation *op,
double points);
G_END_DECLS
#endif /* __TEST_PRINT_FILE_OPERATION_H__ */