summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/font_pango.c36
-rw-r--r--gtk/font_pango.h9
-rw-r--r--gtk/gtk_bitmap.c8
-rw-r--r--gtk/gtk_plotters.c10
-rw-r--r--gtk/gtk_plotters.h1
-rw-r--r--gtk/gtk_print.c573
-rw-r--r--gtk/gtk_print.h48
-rw-r--r--gtk/gtk_scaffolding.c91
-rw-r--r--gtk/res/netsurf.glade19
9 files changed, 778 insertions, 17 deletions
diff --git a/gtk/font_pango.c b/gtk/font_pango.c
index c6ddae102..e1ec7b6fe 100644
--- a/gtk/font_pango.c
+++ b/gtk/font_pango.c
@@ -37,8 +37,26 @@
/* Until we can consider the descenders etc, we need to not render using cairo */
#undef CAIRO_VERSION
-static PangoFontDescription *nsfont_style_to_description(
- const struct css_style *style);
+static bool nsfont_width(const struct css_style *style,
+ const char *string, size_t length,
+ int *width);
+
+static bool nsfont_position_in_string(const struct css_style *style,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x);
+
+static bool nsfont_split(const struct css_style *style,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x);
+
+const struct font_functions nsfont = {
+ nsfont_width,
+ nsfont_position_in_string,
+ nsfont_split
+};
+
+
+
/**
@@ -203,11 +221,11 @@ bool nsfont_paint(const struct css_style *style,
{
PangoFontDescription *desc;
PangoLayout *layout;
+ PangoLayoutLine *line;
gint size;
#ifdef CAIRO_VERSION
int width, height;
-#else
- PangoLayoutLine *line;
+#else
PangoContext *context;
GdkColor colour = { 0,
((c & 0xff) << 8) | (c & 0xff),
@@ -234,14 +252,13 @@ bool nsfont_paint(const struct css_style *style,
pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, string, length);
-
+ line = pango_layout_get_line(layout, 0);
+
#ifdef CAIRO_VERSION
- pango_layout_get_pixel_size(layout, &width, &height);
- cairo_move_to(current_cr, x, y - height);
+ cairo_move_to(current_cr, x, y);
nsgtk_set_colour(c);
- pango_cairo_show_layout(current_cr, layout);
+ pango_cairo_show_layout_line(current_cr, layout, line);
#else
- line = pango_layout_get_line(layout, 0);
gdk_draw_layout_line_with_colors(current_drawable, current_gc,
x, y, line, &colour, 0);
@@ -350,3 +367,4 @@ PangoFontDescription *nsfont_style_to_description(
return desc;
}
+
diff --git a/gtk/font_pango.h b/gtk/font_pango.h
index b3b08b95a..cbae6b2a7 100644
--- a/gtk/font_pango.h
+++ b/gtk/font_pango.h
@@ -20,6 +20,9 @@
* Font handling (GTK interface).
*/
+#ifndef _NETSURF_GTK_FONT_PANGO_H_
+#define _NETSURF_GTK_FONT_PANGO_H_
+
#include <stdbool.h>
@@ -28,3 +31,9 @@ struct css_style;
bool nsfont_paint(const struct css_style *style,
const char *string, size_t length,
int x, int y, colour c);
+
+PangoFontDescription *nsfont_style_to_description(
+ const struct css_style *style);
+
+
+#endif
diff --git a/gtk/gtk_bitmap.c b/gtk/gtk_bitmap.c
index 2f4e1085c..bf36a94e6 100644
--- a/gtk/gtk_bitmap.c
+++ b/gtk/gtk_bitmap.c
@@ -211,6 +211,14 @@ void bitmap_set_suspendable(struct bitmap *bitmap, void *private_word,
void (*invalidate)(struct bitmap *bitmap, void *private_word)) {
}
+int bitmap_get_width(struct bitmap *bitmap){
+ return gdk_pixbuf_get_width(bitmap->primary);
+}
+
+int bitmap_get_height(struct bitmap *bitmap){
+ return gdk_pixbuf_get_height(bitmap->primary);
+}
+
static GdkPixbuf *
gtk_bitmap_generate_pretile(GdkPixbuf *primary, int repeat_x, int repeat_y)
{
diff --git a/gtk/gtk_plotters.c b/gtk/gtk_plotters.c
index 62d31539e..7a696e84a 100644
--- a/gtk/gtk_plotters.c
+++ b/gtk/gtk_plotters.c
@@ -65,10 +65,10 @@ static bool nsgtk_plot_disc(int x, int y, int radius, colour c, bool filled);
static bool nsgtk_plot_arc(int x, int y, int radius, int angle1, int angle2,
colour c);
static bool nsgtk_plot_bitmap(int x, int y, int width, int height,
- struct bitmap *bitmap, colour bg);
+ struct bitmap *bitmap, colour bg, struct content *content);
static bool nsgtk_plot_bitmap_tile(int x, int y, int width, int height,
struct bitmap *bitmap, colour bg,
- bool repeat_x, bool repeat_y);
+ bool repeat_x, bool repeat_y, struct content *content);
static void nsgtk_set_solid(void); /**< Set for drawing solid lines */
static void nsgtk_set_dotted(void); /**< Set for drawing dotted lines */
static void nsgtk_set_dashed(void); /**< Set for drawing dashed lines */
@@ -281,7 +281,7 @@ static bool nsgtk_plot_pixbuf(int x, int y, int width, int height,
}
bool nsgtk_plot_bitmap(int x, int y, int width, int height,
- struct bitmap *bitmap, colour bg)
+ struct bitmap *bitmap, colour bg, struct content *content)
{
GdkPixbuf *pixbuf = gtk_bitmap_get_primary(bitmap);
return nsgtk_plot_pixbuf(x, y, width, height, pixbuf, bg);
@@ -289,7 +289,7 @@ bool nsgtk_plot_bitmap(int x, int y, int width, int height,
bool nsgtk_plot_bitmap_tile(int x, int y, int width, int height,
struct bitmap *bitmap, colour bg,
- bool repeat_x, bool repeat_y)
+ bool repeat_x, bool repeat_y, struct content *content)
{
int doneheight = 0, donewidth = 0;
GdkPixbuf *primary;
@@ -297,7 +297,7 @@ bool nsgtk_plot_bitmap_tile(int x, int y, int width, int height,
if (!(repeat_x || repeat_y)) {
/* Not repeating at all, so just pass it on */
- return nsgtk_plot_bitmap(x,y,width,height,bitmap,bg);
+ return nsgtk_plot_bitmap(x,y,width,height,bitmap,bg,content);
}
if (repeat_x && !repeat_y)
diff --git a/gtk/gtk_plotters.h b/gtk/gtk_plotters.h
index 2fb940904..33e1a9484 100644
--- a/gtk/gtk_plotters.h
+++ b/gtk/gtk_plotters.h
@@ -42,3 +42,4 @@ void nsgtk_set_colour(colour c);
void nsgtk_plot_caret(int x, int y, int h);
#endif /* NETSURF_GTK_PLOTTERS_H */
+
diff --git a/gtk/gtk_print.c b/gtk/gtk_print.c
new file mode 100644
index 000000000..6056eec61
--- /dev/null
+++ b/gtk/gtk_print.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright 2006 Rob Kendrick <rjek@rjek.com>
+ * Copyright 2005 James Bursa <bursa@users.sourceforge.net>
+ * Copyright 2008 Adam Blokus <adamblokus@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+ /** \file
+ * GTK printing (implementation).
+ * All the functions and structures necessary for printing( signal handlers,
+ * plotters, printer) are here.
+ * Most of the plotters have been copied from the gtk_plotters.c file.
+ */
+
+
+#include <math.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include "desktop/plotters.h"
+#include "gtk/font_pango.h"
+#include "gtk/gtk_scaffolding.h"
+#include "render/font.h"
+#include "utils/log.h"
+#include "desktop/options.h"
+#include "gtk/options.h"
+#include "gtk/gtk_bitmap.h"
+
+#include "desktop/print.h"
+#include "desktop/printer.h"
+#include "content/content.h"
+#include "gtk_print.h"
+#include "utils/utils.h"
+
+cairo_t *gtk_print_current_cr;
+static struct print_settings* settings;
+struct content *content_to_print;
+
+static bool nsgtk_print_plot_clg(colour c);
+static bool nsgtk_print_plot_rectangle(int x0, int y0, int width, int height,
+ int line_width, colour c, bool dotted, bool dashed);
+static bool nsgtk_print_plot_line(int x0, int y0, int x1, int y1, int width,
+ colour c, bool dotted, bool dashed);
+static bool nsgtk_print_plot_polygon(int *p, unsigned int n, colour fill);
+static bool nsgtk_print_plot_path(float *p, unsigned int n, colour fill, float width,
+ colour c, float *transform);
+static bool nsgtk_print_plot_fill(int x0, int y0, int x1, int y1, colour c);
+static bool nsgtk_print_plot_clip(int clip_x0, int clip_y0,
+ int clip_x1, int clip_y1);
+static bool nsgtk_print_plot_text(int x, int y, const struct css_style *style,
+ const char *text, size_t length, colour bg, colour c);
+static bool nsgtk_print_plot_disc(int x, int y, int radius, colour c, bool filled);
+static bool nsgtk_print_plot_arc(int x, int y, int radius, int angle1, int angle2,
+ colour c);
+static bool nsgtk_print_plot_bitmap(int x, int y, int width, int height,
+ struct bitmap *bitmap, colour bg, struct content *content);
+static bool nsgtk_print_plot_bitmap_tile(int x, int y, int width, int height,
+ struct bitmap *bitmap, colour bg,
+ bool repeat_x, bool repeat_y, struct content *content);
+
+static void nsgtk_print_set_solid(void); /**< Set for drawing solid lines */
+static void nsgtk_print_set_dotted(void); /**< Set for drawing dotted lines */
+static void nsgtk_print_set_dashed(void); /**< Set for drawing dashed lines */
+
+
+static void nsgtk_print_set_colour(colour c);
+static void nsgtk_print_plot_caret(int x, int y, int h);
+
+
+static bool gtk_print_font_paint(const struct css_style *style,
+ const char *string, size_t length,
+ int x, int y, colour c);
+
+
+static bool gtk_print_begin(struct print_settings* settings);
+static bool gtk_print_next_page(void);
+static void gtk_print_end(void);
+
+
+static GdkRectangle cliprect;
+
+struct plotter_table plot;
+
+static const struct plotter_table nsgtk_print_plotters = {
+ nsgtk_print_plot_clg,
+ nsgtk_print_plot_rectangle,
+ nsgtk_print_plot_line,
+ nsgtk_print_plot_polygon,
+ nsgtk_print_plot_fill,
+ nsgtk_print_plot_clip,
+ nsgtk_print_plot_text,
+ nsgtk_print_plot_disc,
+ nsgtk_print_plot_arc,
+ nsgtk_print_plot_bitmap,
+ nsgtk_print_plot_bitmap_tile,
+ NULL,
+ NULL,
+ NULL,
+ nsgtk_print_plot_path
+};
+
+static const struct printer gtk_printer= {
+ &nsgtk_print_plotters,
+ gtk_print_begin,
+ gtk_print_next_page,
+ gtk_print_end
+};
+
+bool nsgtk_print_plot_clg(colour c)
+{
+ return true;
+}
+
+bool nsgtk_print_plot_rectangle(int x0, int y0, int width, int height,
+ int line_width, colour c, bool dotted, bool dashed)
+{
+ LOG(("Plotting rectangle. width: %i ; height: %i", width, height));
+ nsgtk_print_set_colour(c);
+ if (dotted)
+ nsgtk_print_set_dotted();
+ else if (dashed)
+ nsgtk_print_set_dashed();
+ else
+ nsgtk_print_set_solid();
+
+
+ if (line_width == 0)
+ line_width = 1;
+
+ cairo_set_line_width(gtk_print_current_cr, line_width);
+ cairo_rectangle(gtk_print_current_cr, x0, y0, width, height);
+ cairo_stroke(gtk_print_current_cr);
+
+ return true;
+}
+
+
+bool nsgtk_print_plot_line(int x0, int y0, int x1, int y1, int width,
+ colour c, bool dotted, bool dashed)
+{
+ nsgtk_print_set_colour(c);
+ if (dotted)
+ nsgtk_print_set_dotted();
+ else if (dashed)
+ nsgtk_print_set_dashed();
+ else
+ nsgtk_print_set_solid();
+
+
+ if (width == 0)
+ width = 1;
+
+ cairo_set_line_width(gtk_print_current_cr, width);
+ cairo_move_to(gtk_print_current_cr, x0, y0 - 0.5);
+ cairo_line_to(gtk_print_current_cr, x1, y1 - 0.5);
+ cairo_stroke(gtk_print_current_cr);
+
+ return true;
+}
+
+
+bool nsgtk_print_plot_polygon(int *p, unsigned int n, colour fill)
+{
+
+ LOG(("Plotting polygon."));
+ unsigned int i;
+
+ nsgtk_print_set_colour(fill);
+ nsgtk_print_set_solid();
+
+
+ cairo_set_line_width(gtk_print_current_cr, 0);
+ cairo_move_to(gtk_print_current_cr, p[0], p[1]);
+ LOG(("Starting line at: %i\t%i",p[0],p[1]));
+ for (i = 1; i != n; i++) {
+ cairo_line_to(gtk_print_current_cr, p[i * 2], p[i * 2 + 1]);
+ LOG(("Drawing line to: %i\t%i",p[i * 2], p[i * 2 + 1]));
+ }
+ cairo_fill(gtk_print_current_cr);
+ cairo_stroke(gtk_print_current_cr);
+
+ return true;
+}
+
+
+bool nsgtk_print_plot_fill(int x0, int y0, int x1, int y1, colour c)
+{
+ LOG(("Plotting fill. x0: %i ;\t y0: %i ;\t x1: %i ;\t y1: %i", x0,y0,x1,y1));
+ nsgtk_print_set_colour(c);
+ nsgtk_print_set_solid();
+
+ /*Normalize boundaries of the area - to prevent overflows.
+ See comment in pdf_plot_fill.
+ */
+ x0 = min(max(x0, 0), settings->page_width);
+ y0 = min(max(y0, 0), settings->page_height);
+ x1 = min(max(x1, 0), settings->page_width);
+ y1 = min(max(y1, 0), settings->page_height);
+
+ cairo_set_line_width(gtk_print_current_cr, 0);
+ cairo_rectangle(gtk_print_current_cr, x0, y0, x1 - x0, y1 - y0);
+ cairo_fill(gtk_print_current_cr);
+ cairo_stroke(gtk_print_current_cr);
+
+ return true;
+}
+
+
+bool nsgtk_print_plot_clip(int clip_x0, int clip_y0,
+ int clip_x1, int clip_y1)
+{
+ LOG(("Clipping. x0: %i ;\t y0: %i ;\t x1: %i ;\t y1: %i",
+ clip_x0,clip_y0,clip_x1,clip_y1));
+
+ /*Normalize cllipping area - to prevent overflows.
+ See comment in pdf_plot_fill.
+ */
+ clip_x0 = min(max(clip_x0, 0), settings->page_width);
+ clip_y0 = min(max(clip_y0, 0), settings->page_height);
+ clip_x1 = min(max(clip_x1, 0), settings->page_width);
+ clip_y1 = min(max(clip_y1, 0), settings->page_height);
+
+
+ cairo_reset_clip(gtk_print_current_cr);
+ cairo_rectangle(gtk_print_current_cr, clip_x0, clip_y0,
+ clip_x1 - clip_x0, clip_y1 - clip_y0);
+ cairo_clip(gtk_print_current_cr);
+
+ cliprect.x = clip_x0;
+ cliprect.y = clip_y0;
+ cliprect.width = clip_x1 - clip_x0;
+ cliprect.height = clip_y1 - clip_y0;
+// gdk_gc_set_clip_rectangle(gtk_print_current_gc, &cliprect);
+ return true;
+
+}
+
+
+bool nsgtk_print_plot_text(int x, int y, const struct css_style *style,
+ const char *text, size_t length, colour bg, colour c)
+{
+ return gtk_print_font_paint(style, text, length, x, y, c);
+}
+
+
+bool nsgtk_print_plot_disc(int x, int y, int radius, colour c, bool filled)
+{
+ nsgtk_print_set_colour(c);
+ nsgtk_print_set_solid();
+
+ if (filled)
+ cairo_set_line_width(gtk_print_current_cr, 0);
+ else
+ cairo_set_line_width(gtk_print_current_cr, 1);
+
+ cairo_arc(gtk_print_current_cr, x, y, radius, 0, M_PI * 2);
+
+ if (filled)
+ cairo_fill(gtk_print_current_cr);
+
+ cairo_stroke(gtk_print_current_cr);
+
+
+ return true;
+}
+
+bool nsgtk_print_plot_arc(int x, int y, int radius, int angle1, int angle2, colour c)
+{
+ nsgtk_print_set_colour(c);
+ nsgtk_print_set_solid();
+
+ cairo_set_line_width(gtk_print_current_cr, 1);
+ cairo_arc(gtk_print_current_cr, x, y, radius,
+ (angle1 + 90) * (M_PI / 180),
+ (angle2 + 90) * (M_PI / 180));
+ cairo_stroke(gtk_print_current_cr);
+
+
+ return true;
+}
+
+static bool nsgtk_print_plot_pixbuf(int x, int y, int width, int height,
+ GdkPixbuf *pixbuf, colour bg)
+{
+ /* XXX: This currently ignores the background colour supplied.
+ * Does this matter?
+ */
+
+ if (width == 0 || height == 0)
+ return true;
+
+ if (gdk_pixbuf_get_width(pixbuf) == width &&
+ gdk_pixbuf_get_height(pixbuf) == height) {
+ gdk_cairo_set_source_pixbuf(gtk_print_current_cr, pixbuf, x, y);
+ cairo_paint(gtk_print_current_cr);
+
+ } else {
+ GdkPixbuf *scaled;
+ scaled = gdk_pixbuf_scale_simple(pixbuf,
+ width, height,
+ /* plotting for the printer doesn't have to be fast
+ * so we can use always the interp_style
+ * that gives better quality
+ */
+ GDK_INTERP_BILINEAR
+ );
+ if (!scaled)
+ return false;
+ gdk_cairo_set_source_pixbuf(gtk_print_current_cr, scaled, x, y);
+ cairo_paint(gtk_print_current_cr);
+
+ g_object_unref(scaled);
+ }
+
+ return true;
+}
+
+bool nsgtk_print_plot_bitmap(int x, int y, int width, int height,
+ struct bitmap *bitmap, colour bg, struct content *content)
+{
+ GdkPixbuf *pixbuf = gtk_bitmap_get_primary(bitmap);
+ return nsgtk_print_plot_pixbuf(x, y, width, height, pixbuf, bg);
+}
+
+bool nsgtk_print_plot_bitmap_tile(int x, int y, int width, int height,
+ struct bitmap *bitmap, colour bg,
+ bool repeat_x, bool repeat_y, struct content *content)
+{
+ int doneheight = 0, donewidth = 0;
+ GdkPixbuf *primary;
+ GdkPixbuf *pretiled;
+
+ if (!(repeat_x || repeat_y)) {
+ /* Not repeating at all, so just pass it on */
+ return nsgtk_print_plot_bitmap(x,y,width,height,bitmap,bg,content);
+ }
+
+ if (repeat_x && !repeat_y)
+ pretiled = gtk_bitmap_get_pretile_x(bitmap);
+ if (repeat_x && repeat_y)
+ pretiled = gtk_bitmap_get_pretile_xy(bitmap);
+ if (!repeat_x && repeat_y)
+ pretiled = gtk_bitmap_get_pretile_y(bitmap);
+ primary = gtk_bitmap_get_primary(bitmap);
+ /* use the primary and pretiled widths to scale the w/h provided */
+ width *= gdk_pixbuf_get_width(pretiled);
+ width /= gdk_pixbuf_get_width(primary);
+ height *= gdk_pixbuf_get_height(pretiled);
+ height /= gdk_pixbuf_get_height(primary);
+
+ if (y > cliprect.y)
+ doneheight = (cliprect.y - height) + ((y - cliprect.y) % height);
+ else
+ doneheight = y;
+
+ while (doneheight < (cliprect.y + cliprect.height)) {
+ if (x > cliprect.x)
+ donewidth = (cliprect.x - width) + ((x - cliprect.x) % width);
+ else
+ donewidth = x;
+ while (donewidth < (cliprect.x + cliprect.width)) {
+ nsgtk_print_plot_pixbuf(donewidth, doneheight,
+ width, height, pretiled, bg);
+ donewidth += width;
+ if (!repeat_x) break;
+ }
+ doneheight += height;
+ if (!repeat_y) break;
+ }
+
+
+ return true;
+}
+
+bool nsgtk_print_plot_path(float *p, unsigned int n, colour fill, float width,
+ colour c, float *transform)
+{
+ /* Only the internal SVG renderer uses this plot call currently,
+ * and the GTK version uses librsvg. Thus, we ignore this complexity,
+ * and just return true obliviously.
+ */
+
+ return true;
+}
+
+void nsgtk_print_set_colour(colour c)
+{
+ int r, g, b;
+ GdkColor colour;
+
+ r = c & 0xff;
+ g = (c & 0xff00) >> 8;
+ b = (c & 0xff0000) >> 16;
+
+ colour.red = r | (r << 8);
+ colour.green = g | (g << 8);
+ colour.blue = b | (b << 8);
+ colour.pixel = (r << 16) | (g << 8) | b;
+
+ gdk_color_alloc(gdk_colormap_get_system(),
+ &colour);
+// gdk_gc_set_foreground(gtk_print_current_gc, &colour);
+
+ cairo_set_source_rgba(gtk_print_current_cr, r / 255.0,
+ g / 255.0, b / 255.0, 1.0);
+
+}
+
+
+void nsgtk_print_set_solid()
+{
+
+ double dashes = 0;
+
+ cairo_set_dash(gtk_print_current_cr, &dashes, 0, 0);
+
+}
+
+void nsgtk_print_set_dotted()
+{
+ double cdashes = 1;
+ gint8 dashes[] = { 1, 1 };
+
+ cairo_set_dash(gtk_print_current_cr, &cdashes, 1, 0);
+
+}
+
+void nsgtk_print_set_dashed()
+{
+ double cdashes = 3;
+ gint8 dashes[] = { 3, 3 };
+
+ cairo_set_dash(gtk_print_current_cr, &cdashes, 1, 0);
+}
+
+bool gtk_print_font_paint(const struct css_style *style,
+ const char *string, size_t length,
+ int x, int y, colour c)
+{
+ PangoFontDescription *desc;
+ PangoLayout *layout;
+ gint size;
+ PangoLayoutLine *line;
+
+ int width, height;
+
+
+ if (length == 0)
+ return true;
+
+ desc = nsfont_style_to_description(style);
+ size = (gint)((double)pango_font_description_get_size(desc) * settings->scale);
+ if (pango_font_description_get_size_is_absolute(desc))
+ pango_font_description_set_absolute_size(desc, size);
+ else
+ pango_font_description_set_size(desc, size);
+
+
+ layout = pango_cairo_create_layout(gtk_print_current_cr);
+
+ pango_layout_set_font_description(layout, desc);
+ pango_layout_set_text(layout, string, length);
+
+ line = pango_layout_get_line(layout, 0);
+
+ cairo_move_to(gtk_print_current_cr, x, y);
+ nsgtk_print_set_colour(c);
+ pango_cairo_show_layout_line(gtk_print_current_cr, line);
+
+
+ g_object_unref(layout);
+ pango_font_description_free(desc);
+
+ return true;
+}
+
+
+
+static bool gtk_print_begin(struct print_settings* settings)
+{
+ return true;
+}
+static bool gtk_print_next_page()
+{
+ return true;
+}
+static void gtk_print_end()
+{
+}
+
+/** Handle the begin_print signal from the GtkPrintOperation
+ * \param operation the operation which emited the signal
+ * \param context the print context used to set up the pages
+ * \param user_data nothing in here
+ */
+
+void gtk_print_signal_begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gpointer user_data)
+{
+
+ int page_number;
+ double height_on_page, height_to_print;
+
+ LOG(("Begin print"));
+
+
+ settings = print_make_settings(DEFAULT);
+
+ settings->margins[MARGINTEXT] = 0;
+ settings->margins[MARGINTOP] = 0;
+ settings->margins[MARGINLEFT] = 0;
+ settings->margins[MARGINBOTTOM] = 0;
+ settings->margins[MARGINRIGHT] = 0;
+ settings->page_width = gtk_print_context_get_width(context);
+ settings->page_height = gtk_print_context_get_height(context);
+ settings->scale = 0.7;
+ settings->font_func = &nsfont;
+
+ print_set_up(content_to_print, &gtk_printer, settings, &height_to_print);
+
+ LOG(("page_width: %f ;page_height: %f; content height: %lf",settings->page_width,
+ settings->page_height, height_to_print));
+
+ height_on_page = settings->page_height;
+ height_on_page = height_on_page - settings->margins[MARGINTOP]
+ - settings->margins[MARGINBOTTOM];
+ height_to_print *= settings->scale;
+
+ page_number = height_to_print / height_on_page;
+ if (height_to_print - page_number * height_on_page > 0)
+ page_number += 1;
+
+
+ gtk_print_operation_set_n_pages(operation, page_number);
+}
+
+/** Handle the draw_page signal from the GtkPrintOperation.
+ * This function changes only the cairo context to print on.
+ */
+
+void gtk_print_signal_draw_page(GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ gpointer user_data)
+{
+ LOG(("Draw Page"));
+ gtk_print_current_cr = gtk_print_context_get_cairo_context(context);
+ print_draw_next_page(&gtk_printer, settings);
+}
+
+/** Handle the end_print signal from the GtkPrintOperation.
+ * This functions calls only the print_cleanup function from the print interface
+ */
+
+void gtk_print_signal_end_print(GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gpointer user_data)
+{
+ LOG(("End print"));
+ print_cleanup(content_to_print, &gtk_printer);
+}
diff --git a/gtk/gtk_print.h b/gtk/gtk_print.h
new file mode 100644
index 000000000..b232920de
--- /dev/null
+++ b/gtk/gtk_print.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Adam Blokus <adamblokus@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /** \file
+ * GTK printing (interface).
+ */
+
+#ifndef NETSURF_GTK_PRINT_PLOTTERS_H
+#define NETSURF_GTK_PRINT_PLOTTERS_H
+
+
+#include <gtk/gtk.h>
+
+extern cairo_t *gtk_print_current_cr;
+
+extern struct content *content_to_print;
+
+
+/*handlers for signals from the GTK print operation*/
+void gtk_print_signal_begin_print(GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gpointer user_data);
+
+void gtk_print_signal_draw_page(GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ gpointer user_data);
+
+void gtk_print_signal_end_print(GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gpointer user_data);
+
+#endif
diff --git a/gtk/gtk_scaffolding.c b/gtk/gtk_scaffolding.c
index c13acbad5..1165d785a 100644
--- a/gtk/gtk_scaffolding.c
+++ b/gtk/gtk_scaffolding.c
@@ -49,6 +49,11 @@
#include "render/html.h"
#include "utils/messages.h"
#include "utils/utils.h"
+
+#include "pdf/pdf_plotters.h"
+#include "desktop/print.h"
+#include "gtk/gtk_print.h"
+
#undef NDEBUG
#include "utils/log.h"
@@ -138,6 +143,9 @@ void nsgtk_openfile_open(char *filename);
MENUPROTO(new_window);
MENUPROTO(open_location);
MENUPROTO(open_file);
+MENUPROTO(export_pdf);
+MENUPROTO(print);
+MENUPROTO(print_preview);
MENUPROTO(close_window);
MENUPROTO(quit);
@@ -181,6 +189,9 @@ static struct menu_events menu_events[] = {
MENUEVENT(new_window),
MENUEVENT(open_location),
MENUEVENT(open_file),
+ MENUEVENT(export_pdf),
+ MENUEVENT(print),
+ MENUEVENT(print_preview),
MENUEVENT(close_window),
MENUEVENT(quit),
@@ -467,6 +478,86 @@ MENUHANDLER(open_file)
return TRUE;
}
+MENUHANDLER(export_pdf){
+
+ GtkWidget *save_dialog;
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+ struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level);
+ struct print_settings* settings;
+
+ LOG(("Print preview (generating PDF) started."));
+
+ settings = print_make_settings(DEFAULT);
+
+ save_dialog = gtk_file_chooser_dialog_new("Export to PDF", gw->window,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog),
+ getenv("HOME") ? getenv("HOME") : "/");
+
+ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog),
+ "out.pdf");
+
+ if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) {
+ settings->output = gtk_file_chooser_get_filename(
+ GTK_FILE_CHOOSER(save_dialog));
+ }
+
+ gtk_widget_destroy(save_dialog);
+
+ print_basic_run(bw->current_content, &pdf_printer, settings);
+
+ return TRUE;
+}
+
+MENUHANDLER(print){
+
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+ struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level);
+
+ GtkPrintOperation* print_op;
+ GtkPageSetup* page_setup;
+ struct print_settings* settings;
+
+ settings = print_make_settings(DEFAULT);
+
+ print_op = gtk_print_operation_new();
+ page_setup = gtk_page_setup_new();
+
+ content_to_print = bw->current_content;
+
+ page_setup = gtk_print_run_page_setup_dialog(gw->window, page_setup, NULL);
+ gtk_print_operation_set_default_page_setup (print_op, page_setup);
+
+ g_signal_connect(print_op, "begin_print", G_CALLBACK (gtk_print_signal_begin_print), NULL);
+ g_signal_connect(print_op, "draw_page", G_CALLBACK (gtk_print_signal_draw_page), NULL);
+ g_signal_connect(print_op, "end_print", G_CALLBACK (gtk_print_signal_end_print), NULL);
+
+
+ gtk_print_operation_run(print_op,
+ GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ gw->window,
+ NULL);
+
+
+ return TRUE;
+}
+
+MENUHANDLER(print_preview){
+
+ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
+ struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level);
+
+ LOG(("Print preview (generating PDF) started."));
+
+ print_basic_run(bw->current_content, &pdf_printer, NULL);
+
+ return TRUE;
+}
+
MENUHANDLER(close_window)
{
struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g;
diff --git a/gtk/res/netsurf.glade b/gtk/res/netsurf.glade
index 09af6fea9..9f9e036f4 100644
--- a/gtk/res/netsurf.glade
+++ b/gtk/res/netsurf.glade
@@ -91,7 +91,7 @@
<child>
<widget class="GtkMenuItem" id="export">
<property name="visible">True</property>
- <property name="sensitive">False</property>
+ <property name="sensitive">True</property>
<property name="tooltip" translatable="yes">Export the page to a different format.</property>
<property name="label" translatable="yes">Export</property>
<property name="use_underline">True</property>
@@ -100,6 +100,7 @@
<child>
<widget class="GtkMenuItem" id="export_plain_text">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="tooltip" translatable="yes">Plain ASCII text, readable in text editors and views.</property>
<property name="label" translatable="yes">Plain text...</property>
<property name="use_underline">True</property>
@@ -108,6 +109,7 @@
<child>
<widget class="GtkMenuItem" id="export_drawfile">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="tooltip" translatable="yes">RISC OS Drawfile vector graphic.</property>
<property name="label" translatable="yes">Drawfile...</property>
<property name="use_underline">True</property>
@@ -116,11 +118,21 @@
<child>
<widget class="GtkMenuItem" id="export_postscript">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="tooltip" translatable="yes">PostScript for printing and converting to PDFs.</property>
<property name="label" translatable="yes">PostScript...</property>
<property name="use_underline">True</property>
</widget>
</child>
+ <child>
+ <widget class="GtkMenuItem" id="export_pdf">
+ <property name="visible">True</property>
+ <property name="sensitive">True</property>
+ <property name="tooltip" translatable="yes">Portable Document Format.</property>
+ <property name="label" translatable="yes">PDF...</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
</widget>
</child>
</widget>
@@ -133,10 +145,11 @@
<child>
<widget class="GtkImageMenuItem" id="print_preview">
<property name="visible">True</property>
- <property name="sensitive">False</property>
+ <property name="sensitive">True</property>
<property name="tooltip" translatable="yes">Show how a print out might look like.</property>
<property name="label" translatable="yes">Print preview...</property>
<property name="use_underline">True</property>
+ <accelerator key="P" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image558">
<property name="visible">True</property>
@@ -149,7 +162,7 @@
<child>
<widget class="GtkImageMenuItem" id="print">
<property name="visible">True</property>
- <property name="sensitive">False</property>
+ <property name="sensitive">True</property>
<property name="tooltip" translatable="yes">Produce a hardcopy on your printer.</property>
<property name="label" translatable="yes">Print...</property>
<property name="use_underline">True</property>