summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
Diffstat (limited to 'riscos')
-rw-r--r--riscos/gui.c2
-rw-r--r--riscos/print.c458
2 files changed, 250 insertions, 210 deletions
diff --git a/riscos/gui.c b/riscos/gui.c
index 0aefc6a00..af3b3c263 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -1344,7 +1344,7 @@ char *ro_gui_url_file_parse(const char *file_name)
void ro_msg_datasave_ack(wimp_message *message)
{
#ifdef WITH_PRINT
- if (print_current_window && print_ack(message))
+ if (print_ack(message))
return;
#endif
diff --git a/riscos/print.c b/riscos/print.c
index ed77d0c97..59999cf2b 100644
--- a/riscos/print.c
+++ b/riscos/print.c
@@ -17,6 +17,7 @@
#include "netsurf/utils/config.h"
#include "netsurf/content/content.h"
+#include "netsurf/desktop/plotters.h"
#include "netsurf/render/box.h"
#include "netsurf/render/font.h"
#include "netsurf/render/html.h"
@@ -25,6 +26,7 @@
#include "netsurf/riscos/print.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
+#include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h"
/** \todo landscape format pages
@@ -40,7 +42,7 @@ bool print_active = false;
#ifdef WITH_PRINT
-/* 1 millipoint == 1/400 OS unit = 1/800 browser units */
+/* 1 millipoint == 1/400 OS unit == 1/800 browser units */
/* static globals */
static int print_prev_message = 0;
@@ -50,17 +52,19 @@ static int print_num_copies = 1;
static bool print_bg_images = false;
static int print_max_sheets = -1;
-/* array of fonts in document - max 255 */
+/* a font in a document */
struct print_font {
font_f handle;
- void *fontName;
+ void *font_name;
};
static void print_update_sheets_shaded_state(bool on);
static void print_send_printsave(struct content *c);
static bool print_send_printtypeknown(wimp_message *m);
-static void print_document(struct gui_window *g, const char *filename);
-static bool print_find_fonts(struct box *box, struct print_font **print_fonts, int *numFonts);
+static bool print_document(struct gui_window *g, const char *filename);
+static const char *print_declare_fonts(struct box *box);
+static bool print_find_fonts(struct box *box, struct print_font **print_fonts,
+ int *font_count);
/**
* Open the print dialog
@@ -362,80 +366,80 @@ void print_type_odd(wimp_message *m)
}
+
/**
- * Handle message_DATASAVE_ACK for the printing protocol
+ * Handle message_DATASAVE_ACK for the printing protocol.
*
- * \param m the message to handle
+ * \param m the message to handle
* \return true if message successfully handled, false otherwise
+ *
+ * We cheat here and, instead of giving Printers what it asked for (a copy of
+ * the file so it can poke us later via a broadcast of PrintTypeOdd), we give
+ * it a file that it can print itself without having to bother us further. For
+ * PostScript printers (type 0) we give it a PostScript file. Otherwise, we give
+ * it a PrintOut file.
+ *
+ * This method has a couple of advantages:
+ * - we can reuse this code for background printing (we simply ignore the
+ * PrintTypeOdd reply)
+ * - there's no need to ensure all components of a page queued to be printed
+ * still exist when it reaches the top of the queue. (which reduces complexity
+ * a fair bit)
*/
+
bool print_ack(wimp_message *m)
{
- int type;
- os_error *e;
+ pdriver_info_type info_type;
+ pdriver_type type;
+ os_error *error;
- if (m->your_ref == 0 || m->your_ref != print_prev_message) {
- LOG(("message ignored"));
+ if (m->your_ref == 0 || m->your_ref != print_prev_message ||
+ !print_current_window)
return false;
+
+ /* read printer driver type */
+ error = xpdriver_info(&info_type, 0, 0, 0, 0, 0, 0, 0);
+ if (error) {
+ LOG(("xpdriver_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
+ print_cleanup();
+ return true;
}
+ type = info_type >> 16;
- /* Read Printer Driver Type */
- e = xpdriver_info(&type, 0, 0, 0, 0, 0, 0, 0);
- if (e) {
- LOG(("%s", e->errmess));
+ /* print to file */
+ if (!print_document(print_current_window,
+ m->data.data_xfer.file_name)) {
print_cleanup();
return true;
}
- type &= 0xFFFF0000; /* we don't care about the version no */
+ /* send dataload */
+ m->your_ref = m->my_ref;
+ m->action = message_DATA_LOAD;
- if (print_current_window) {
- print_document(print_current_window,
- (const char*)m->data.data_xfer.file_name);
-
- /* send dataload */
- m->your_ref = m->my_ref;
- m->action = message_DATA_LOAD;
-
- /* We cheat here and, instead of giving Printers what
- * it asked for (a copy of the file so it can poke us
- * later via a broadcast of PrintTypeOdd), we give
- * it a file that it can print itself without having
- * to bother us further. For PostScript printers
- * (type 0) we give it a PostScript file. Otherwise,
- * we give it a PrintOut file.
- *
- * This method has a couple of advantages:
- * - we can reuse this code for background printing
- * (we simply ignore the PrintTypeOdd reply)
- * - there's no need to ensure all components of a
- * page queued to be printed still exist when it
- * reaches the top of the queue. (which reduces
- * complexity a fair bit)
- */
- if (type == 0)
- /* postscript */
- m->data.data_xfer.file_type = 0xff5;
- else
- /* printout */
- m->data.data_xfer.file_type = 0xff4;
-
- e = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, m,
- m->sender);
- if (e) {
- LOG(("xwimp_send_message: 0x%x: %s",
- e->errnum, e->errmess));
- warn_user("WimpError", e->errmess);
- /* and delete temporary file */
- xosfile_delete(m->data.data_xfer.file_name,
- 0, 0, 0, 0, 0);
- print_cleanup();
- }
- print_prev_message = m->my_ref;
+ if (type == pdriver_TYPE_PS)
+ m->data.data_xfer.file_type = osfile_TYPE_POSTSCRIPT;
+ else
+ m->data.data_xfer.file_type = osfile_TYPE_PRINTOUT;
+
+ error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, m, m->sender);
+ if (error) {
+ LOG(("xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ /* and delete temporary file */
+ xosfile_delete(m->data.data_xfer.file_name,
+ 0, 0, 0, 0, 0);
}
+ print_prev_message = m->my_ref;
+ print_cleanup();
return true;
}
+
/**
* Handle a bounced dataload message
*
@@ -466,188 +470,152 @@ void print_cleanup(void)
ro_gui_dialog_close(dialog_print);
}
+
/**
- * Print a document
+ * Print a document.
*
- * \param g gui_window containing the document to print
- * \param filename name of file to print to
+ * \param g gui_window containing the document to print
+ * \param filename name of file to print to
+ * \return true on success, false on error and error reported
*/
-void print_document(struct gui_window *g, const char *filename)
+
+bool print_document(struct gui_window *g, const char *filename)
{
+ int left, right, top, bottom, width, height;
+ int saved_width;
+ int yscroll = 0, sheets = print_max_sheets;
+ struct box *box = 0;
struct content *c = g->bw->current_content;
- struct box *box = NULL;
- int temp;
- os_error *e;
+ const char *error_message;
pdriver_features features;
- int left, right, top, bottom, width, height;
os_fw fhandle, old_job = 0;
- int yscroll = 0, sheets = print_max_sheets;
+ os_error *error;
/* no point printing a blank page */
- if (!c)
- return;
-
- LOG(("Printing page (%d)", print_max_sheets));
+ if (!c) {
+ warn_user("PrintError", "nothing to print");
+ return false;
+ }
if (c->type == CONTENT_HTML)
box = c->data.html.layout;
- /* Read Printer Driver Features */
- e = xpdriver_info(0, 0, 0, &features, 0, 0, 0, 0);
- if (e) {
- LOG(("%s", e->errmess));
- return;
+ /* read printer driver features */
+ error = xpdriver_info(0, 0, 0, &features, 0, 0, 0, 0);
+ if (error) {
+ LOG(("xpdriver_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
+ return false;
}
- LOG(("read features"));
-
- /* Acquire page size */
- e = xpdriver_page_size(&width, &height, &left, &bottom, &right, &top);
- if (e) {
- LOG(("%s", e->errmess));
- return;
+ /* read page size */
+ error = xpdriver_page_size(0, 0, &left, &bottom, &right, &top);
+ if (error) {
+ LOG(("xpdriver_page_size: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
+ return false;
}
- LOG(("page size: %d x %d", width/800, height/800));
-
width = (right - left) / 800;
height = (top - bottom) / 800;
- LOG(("printable area: [(%d, %d), (%d, %d)] = %d x %d",
- left, bottom, right, top, width, height));
-
-
- temp = c->width;
-
/* layout the document to the correct width */
+ saved_width = c->width;
if (c->type == CONTENT_HTML)
layout_document(box, width, c->data.html.box_pool);
- /* open printer */
- e = xosfind_openoutw(0xf, filename, 0, &fhandle);
- if (e) {
- LOG(("%s", e->errmess));
- return;
+ /* open printer file */
+ error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR |
+ osfind_ERROR_IF_ABSENT, filename, 0, &fhandle);
+ if (error) {
+ LOG(("xosfind_openoutw: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
+ return false;
}
- LOG(("opened %s", filename));
-
/* select print job */
- e = xpdriver_select_jobw(fhandle, "NetSurf", &old_job);
- if (e) {
- LOG(("%s", e->errmess));
+ error = xpdriver_select_jobw(fhandle, "NetSurf", &old_job);
+ if (error) {
+ LOG(("xpdriver_select_jobw: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
xosfind_closew(fhandle);
- return;
+ return false;
}
- LOG(("selected job - polling the wimp now does bad things(TM)"));
-
/* declare fonts, if necessary */
if (features & pdriver_FEATURE_DECLARE_FONT &&
c->type == CONTENT_HTML) {
- struct print_font *print_fonts =
- calloc(255, sizeof(*print_fonts));
- int numFonts = 0;
- int i;
-
- if (!print_fonts) {
- LOG(("malloc failed"));
- goto error;
- }
-
- if(!print_find_fonts(box, &print_fonts, &numFonts)) {
- LOG(("print_find_fonts_failed"));
- for (i = 0; i != numFonts; ++i) {
- free((print_fonts[i]).fontName);
- }
- free(print_fonts);
- goto error;
- }
- LOG(("%d", numFonts));
-
- for (i = 0; i != numFonts; ++i) {
- LOG(("0x%x: %s", (print_fonts[i]).handle, (char*)(print_fonts[i]).fontName));
- e = xpdriver_declare_font((font_f)(print_fonts[i]).handle, (print_fonts[i]).fontName, 0);
- if (e) {
- for (i = 0; i != numFonts; ++i) {
- free((print_fonts[i]).fontName);
- }
- free(print_fonts);
- LOG(("%s", e->errmess));
- goto error;
- }
- }
-
- for (i = 0; i != numFonts; ++i) {
- free((print_fonts[i]).fontName);
- }
- free(print_fonts);
-
- e = xpdriver_declare_font(0, 0, 0);
- if (e) {
- LOG(("%s", e->errmess));
+ if ((error_message = print_declare_fonts(box)))
goto error;
- }
-
- LOG(("declared fonts"));
}
+ plot = ro_plotters;
+ ro_plot_set_scale(print_scale);
+ ro_gui_current_redraw_gui = g;
+
/* print is now active */
print_active = true;
do {
- os_box b = {left/400 - 2, bottom/400 - 2,
- right/400 + 2, top/400 + 2};
- os_hom_trfm t = { { { 65536, 0}, {0, 65536} } };
+ int clip_x0, clip_y0, clip_x1, clip_y1;
+ os_box b = {left / 400 - 2, bottom / 400 - 2,
+ right / 400 + 2, top / 400 + 2};
+ os_hom_trfm t = { { {65536, 0}, {0, 65536} } };
os_coord p = {left, bottom};
+ osbool more;
- e = xhourglass_percentage((int)(yscroll*100/c->height));
- if (e) {
- LOG(("%s", e->errmess));
- /* the hourglass failing to be updated
- * shouldn't stop the printjob
- */
- }
+ xhourglass_percentage((int) (yscroll * 100 / c->height));
- /* Give page rectangle */
- e = xpdriver_give_rectangle(0, &b, &t, &p, os_COLOUR_WHITE);
- if (e) {
- LOG(("%s", e->errmess));
+ /* give page rectangle */
+ error = xpdriver_give_rectangle(0, &b, &t, &p, os_COLOUR_WHITE);
+ if (error) {
+ LOG(("xpdriver_give_rectangle: 0x%x: %s",
+ error->errnum, error->errmess));
+ error_message = error->errmess;
goto error;
}
- LOG(("given rectangle: [(%d, %d), (%d, %d)]", b.x0, b.y0, b.x1, b.y1));
+ LOG(("given rectangle: [(%d, %d), (%d, %d)]",
+ b.x0, b.y0, b.x1, b.y1));
/* and redraw the document */
- osbool more;
- e = xpdriver_draw_page(print_num_copies, &b, 0, 0, &more, 0);
- if (e) {
- LOG(("%s", e->errmess));
+ error = xpdriver_draw_page(print_num_copies, &b, 0, 0,
+ &more, 0);
+ if (error) {
+ LOG(("xpdriver_draw_page: 0x%x: %s",
+ error->errnum, error->errmess));
+ error_message = error->errmess;
goto error;
}
- LOG(("done draw_page"));
-
- ro_gui_current_redraw_gui = g;
+ ro_plot_origin_x = left / 400;
+ ro_plot_origin_y = top / 400 + yscroll * 2;
while (more) {
- LOG(("redrawing area: [(%d, %d), (%d, %d)]", b.x0, b.y0, b.x1, b.y1));
- if (c) {
- if (!content_redraw(c, left/400,
- top/400 + (yscroll*2),
- c->width * 2, c->height * 2,
- b.x0, b.y0,
- b.x1-1, b.y1-1,
- print_scale, 0xFFFFFF)) {
- ro_gui_current_redraw_gui = NULL;
- goto error;
- }
+ LOG(("redrawing area: [(%d, %d), (%d, %d)]",
+ b.x0, b.y0, b.x1, b.y1));
+ clip_x0 = (b.x0 - ro_plot_origin_x) / 2;
+ clip_y0 = (ro_plot_origin_y - b.y1) / 2;
+ clip_x1 = (b.x1 - ro_plot_origin_x) / 2;
+ clip_y1 = (ro_plot_origin_y - b.y0) / 2;
+ if (!content_redraw(c, 0, 0,
+ c->width, c->height,
+ clip_x0, clip_y0, clip_x1, clip_y1,
+ print_scale,
+ 0xFFFFFF)) {
+ error_message = "redraw error";
+ goto error;
}
- e = xpdriver_get_rectangle(&b, &more, 0);
- if (e) {
- LOG(("%s", e->errmess));
- ro_gui_current_redraw_gui = NULL;
+ error = xpdriver_get_rectangle(&b, &more, 0);
+ if (error) {
+ LOG(("xpdriver_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess));
+ error_message = error->errmess;
goto error;
}
}
@@ -657,47 +625,119 @@ void print_document(struct gui_window *g, const char *filename)
/* make print inactive */
print_active = false;
-
- ro_gui_current_redraw_gui = NULL;
- LOG(("finished redraw"));
+ ro_gui_current_redraw_gui = 0;
/* clean up */
- e = xpdriver_end_jobw(fhandle);
- if (e) {
- LOG(("%s", e->errmess));
+ error = xpdriver_end_jobw(fhandle);
+ if (error) {
+ LOG(("xpdriver_end_jobw: 0x%x: %s",
+ error->errnum, error->errmess));
+ error_message = error->errmess;
goto error;
}
- xosfind_close(fhandle);
- if (old_job) xpdriver_select_jobw(old_job, 0, 0);
- LOG(("done job"));
+ error = xosfind_closew(fhandle);
+ if (error) {
+ LOG(("xosfind_closew: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
+ return false;
+ }
+
+ if (old_job) {
+ error = xpdriver_select_jobw(old_job, 0, 0);
+ if (error) {
+ LOG(("xpdriver_select_jobw: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("PrintError", error->errmess);
+ /* the printing succeeded anyway */
+ return true;
+ }
+ }
/* restore document layout */
if (c->type == CONTENT_HTML)
- layout_document(box, temp, c->data.html.box_pool);
+ layout_document(box, saved_width, c->data.html.box_pool);
- return;
+ return true;
error:
xpdriver_abort_job(fhandle);
- xosfind_close(fhandle);
- if (old_job) xpdriver_select_jobw(old_job, 0, 0);
+ xosfind_closew(fhandle);
+ if (old_job)
+ xpdriver_select_jobw(old_job, 0, 0);
print_active = false;
+ ro_gui_current_redraw_gui = 0;
+
+ warn_user("PrintError", error_message);
/* restore document layout */
if (c->type == CONTENT_HTML)
- layout_document(box, temp, c->data.html.box_pool);
+ layout_document(box, saved_width, c->data.html.box_pool);
+
+ return false;
}
+
+/**
+ * Declare fonts to the printer driver.
+ *
+ * \param box box tree being printed
+ * \return 0 on success, error message on error
+ */
+
+const char *print_declare_fonts(struct box *box)
+{
+ struct print_font *print_fonts = calloc(255, sizeof (*print_fonts));
+ unsigned int font_count = 0, i;
+ const char *error_message = 0;
+ os_error *error;
+
+ if (!print_fonts)
+ return messages_get("NoMemory");
+
+ if (!print_find_fonts(box, &print_fonts, &font_count)) {
+ LOG(("print_find_fonts() failed"));
+ error_message = "print_find_fonts() failed";
+ goto end;
+ }
+
+ for (i = 0; i != font_count; ++i) {
+ error = xpdriver_declare_font(print_fonts[i].handle,
+ print_fonts[i].font_name, 0);
+ if (error) {
+ LOG(("xpdriver_declare_font: 0x%x: %s",
+ error->errnum, error->errmess));
+ error_message = error->errmess;
+ goto end;
+ }
+ }
+ error = xpdriver_declare_font(0, 0, 0);
+ if (error) {
+ LOG(("xpdriver_declare_font: 0x%x: %s",
+ error->errnum, error->errmess));
+ error_message = error->errmess;
+ goto end;
+ }
+
+end:
+ for (i = 0; i != font_count; i++)
+ free(print_fonts[i].font_name);
+ free(print_fonts);
+
+ return error_message;
+}
+
+
/**
* Find all fonts in a document
*
* \param box Root of box tree
* \param print_fonts pointer to array of fonts in document
- * \paran numFonts number of fonts declared
+ * \paran font_count number of fonts declared
* \return true on success, false otherwise
*/
-bool print_find_fonts(struct box *box, struct print_font **print_fonts, int *numFonts)
+bool print_find_fonts(struct box *box, struct print_font **print_fonts, int *font_count)
{
struct box *a;
const char *txt;
@@ -728,27 +768,27 @@ bool print_find_fonts(struct box *box, struct print_font **print_fonts, int *num
return false;
}
- for (i = 0; i != *numFonts; ++i) {
- if (!strcmp(((*print_fonts)[i]).fontName, rofontname))
+ for (i = 0; i != *font_count; ++i) {
+ if (!strcmp(((*print_fonts)[i]).font_name, rofontname))
break;
}
- if (i == *numFonts) {
+ if (i == *font_count) {
/* max 255 fonts (as per draw) */
- if (*numFonts == 255)
+ if (*font_count == 255)
return false;
- if ((((*print_fonts)[*numFonts]).fontName = strdup(rofontname)) == NULL) {
+ if ((((*print_fonts)[*font_count]).font_name = strdup(rofontname)) == NULL) {
LOG(("failed to strdup (%s)", rofontname));
return false;
}
- ((*print_fonts)[(*numFonts)++]).handle = (font_f)box->font->handle;
+ ((*print_fonts)[(*font_count)++]).handle = (font_f)box->font->handle;
}
free((void*)rotext);
}
for (a = box->children; a; a = a->next) {
- if (!print_find_fonts(a, print_fonts, numFonts))
+ if (!print_find_fonts(a, print_fonts, font_count))
return false;
}