diff --git a/ChangeLog b/ChangeLog index 9b7bee3a8f..1c307d817b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-05-05 Alexander Larsson + + * 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 * gdk/directfb/gdkkeys-directfb.c: DIKI_ALTGR to compile with diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9b7bee3a8f..1c307d817b 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,19 @@ +2006-05-05 Alexander Larsson + + * 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 * gdk/directfb/gdkkeys-directfb.c: DIKI_ALTGR to compile with diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c index 3b6f5561f5..a411445462 100644 --- a/gtk/gtkprintoperation-unix.c +++ b/gtk/gtkprintoperation-unix.c @@ -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 diff --git a/gtk/gtkprintoperation.c b/gtk/gtkprintoperation.c index 998717d753..26397dda9c 100644 --- a/gtk/gtkprintoperation.c +++ b/gtk/gtkprintoperation.c @@ -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; diff --git a/tests/Makefile.am b/tests/Makefile.am index c5d269ec42..23b5c224d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 diff --git a/tests/testprint.c b/tests/testprint.c new file mode 100644 index 0000000000..4294fd02f3 --- /dev/null +++ b/tests/testprint.c @@ -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 +#include +#include +#include +#include +#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; +} diff --git a/tests/testprintfileoperation.c b/tests/testprintfileoperation.c new file mode 100644 index 0000000000..e1c4b5a7d8 --- /dev/null +++ b/tests/testprintfileoperation.c @@ -0,0 +1,163 @@ +#include +#include +#include +#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; + +} diff --git a/tests/testprintfileoperation.h b/tests/testprintfileoperation.h new file mode 100644 index 0000000000..653abbf802 --- /dev/null +++ b/tests/testprintfileoperation.h @@ -0,0 +1,43 @@ +#ifndef __TEST_PRINT_FILE_OPERATION_H__ +#define __TEST_PRINT_FILE_OPERATION_H__ + +#include + +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__ */