diff options
author | John Tytgat <joty@netsurf-browser.org> | 2008-08-14 20:32:10 +0000 |
---|---|---|
committer | John Tytgat <joty@netsurf-browser.org> | 2008-08-14 20:32:10 +0000 |
commit | e063a2a59d698dd96123b68a44b09f0623f80cab (patch) | |
tree | 1bd06130de988cb0f6da239800229387f189d21c | |
parent | 44856d86d4efb12e08c8ef7560f39233107dfa8a (diff) | |
download | netsurf-e063a2a59d698dd96123b68a44b09f0623f80cab.tar.gz netsurf-e063a2a59d698dd96123b68a44b09f0623f80cab.tar.bz2 |
Second merge of Adam Blokus' GSoC work from his branch 'branches/adamblokus/netsurf'.
Merged revisions 4195-4211,4216,4219-4220,4222-4234,4236-4250,4252-4262,4264-4266,4268-4326,4329-4335,4338-4342,4344-4411,4413-4420,4422-4436,4438-4491,4494-4506,4508-4514,4516,4518-4552,4554,4556-4564,4567-4568,4570-4574,4576-4686,4689-4692,4694,4698-4709,4715-4723,4725-4755,4757-4769,4771-4919,4921-4996,4998-5110,5112-5117 via svnmerge from
svn://svn.netsurf-browser.org/branches/adamblokus/netsurf
........
r4736 | adamblokus | 2008-07-26 13:46:54 +0200 (Sat, 26 Jul 2008) | 2 lines
Sorting out some problems with svn.
........
r4737 | adamblokus | 2008-07-26 13:54:36 +0200 (Sat, 26 Jul 2008) | 4 lines
Added export tab to the options dialog.
Added the possibility of changing some print options.
........
r4897 | adamblokus | 2008-08-04 17:59:05 +0200 (Mon, 04 Aug 2008) | 5 lines
Added checking of horizontal clipping.
Added better table loosening.
Changed some minor bugs.
Applied changes in the Export options tab according to the review from tlsa.
........
r4905 | adamblokus | 2008-08-05 01:53:34 +0200 (Tue, 05 Aug 2008) | 2 lines
Fixed bug which made it impossible to export pdf's.
........
r4919 | adamblokus | 2008-08-05 16:39:33 +0200 (Tue, 05 Aug 2008) | 2 lines
Fixed some memory leaks which caused Netsurf to break.
........
r4927 | adamblokus | 2008-08-06 02:26:30 +0200 (Wed, 06 Aug 2008) | 4 lines
Fixed bug with filenames which crashed Netsurf.
Turned anti aliasing off for printing.
Fixed some scaling issues.
........
r4928 | adamblokus | 2008-08-06 17:52:44 +0200 (Wed, 06 Aug 2008) | 5 lines
Added new export/print options:
- suppressing images
- turning off backgrounds
- toggled loosening
........
r4950 | adamblokus | 2008-08-07 21:15:21 +0200 (Thu, 07 Aug 2008) | 5 lines
Added new options to PDF export:
- document compression
- document encryption
Added PDF password dialog
........
r4954 | adamblokus | 2008-08-07 22:11:31 +0200 (Thu, 07 Aug 2008) | 2 lines
Added saving print settings.
........
r4956 | adamblokus | 2008-08-07 22:44:48 +0200 (Thu, 07 Aug 2008) | 2 lines
Fixes to PDF encryption
........
r4970 | adamblokus | 2008-08-09 15:26:24 +0200 (Sat, 09 Aug 2008) | 3 lines
Fixed bug in plotting tiled bitmaps.
Fixed bug with too long text decorations.
........
r4977 | adamblokus | 2008-08-09 19:18:56 +0200 (Sat, 09 Aug 2008) | 2 lines
Fixed JPG embedding bug.
........
r4988 | adamblokus | 2008-08-10 16:59:51 +0200 (Sun, 10 Aug 2008) | 3 lines
Added clip checking to pdf plotters. No more "blank" clips.
Made PDF compression a default setting.
........
r4995 | adamblokus | 2008-08-10 20:03:00 +0200 (Sun, 10 Aug 2008) | 2 lines
Fixed Haru crash on font-size==0.
........
r4996 | adamblokus | 2008-08-10 21:04:43 +0200 (Sun, 10 Aug 2008) | 2 lines
Added changing text mode only if necessary.
........
r5045 | adamblokus | 2008-08-11 21:26:26 +0200 (Mon, 11 Aug 2008) | 3 lines
Removing gtk stuff from core code.
Little fix in options.
........
r5048 | adamblokus | 2008-08-11 21:57:45 +0200 (Mon, 11 Aug 2008) | 2 lines
Better font size checking in PDF export.
........
r5050 | adamblokus | 2008-08-11 22:19:56 +0200 (Mon, 11 Aug 2008) | 2 lines
Fixed riscos text scale bug.
........
r5073 | adamblokus | 2008-08-12 17:40:57 +0200 (Tue, 12 Aug 2008) | 2 lines
Added missing tooltips
........
r5092 | adamblokus | 2008-08-13 17:09:25 +0200 (Wed, 13 Aug 2008) | 2 lines
Moved /pdf folder to desktop/save_pdf
........
r5110 | adamblokus | 2008-08-13 22:44:50 +0200 (Wed, 13 Aug 2008) | 2 lines
Added comments.
........
r5113 | adamblokus | 2008-08-13 23:07:35 +0200 (Wed, 13 Aug 2008) | 2 lines
Cosmetic changes
........
r5116 | adamblokus | 2008-08-14 16:10:18 +0200 (Thu, 14 Aug 2008) | 2 lines
Fixed bug with BOX_INLINE_END in tree duplication.
........
r5117 | joty | 2008-08-14 21:47:46 +0200 (Thu, 14 Aug 2008) | 1 line
Improvement for r5116: use local vars when possible; rename global last to box_duplicate_last; check on box_duplicate_main_tree failure.
........
svn path=/trunk/netsurf/; revision=5118
-rw-r--r-- | Makefile.sources | 2 | ||||
-rw-r--r-- | desktop/options.c | 30 | ||||
-rw-r--r-- | desktop/options.h | 19 | ||||
-rw-r--r-- | desktop/print.c | 141 | ||||
-rw-r--r-- | desktop/print.h | 23 | ||||
-rw-r--r-- | desktop/save_pdf/TODO (renamed from pdf/TODO) | 0 | ||||
-rw-r--r-- | desktop/save_pdf/font_haru.c (renamed from pdf/font_haru.c) | 23 | ||||
-rw-r--r-- | desktop/save_pdf/font_haru.h (renamed from pdf/font_haru.h) | 2 | ||||
-rw-r--r-- | desktop/save_pdf/pdf_plotters.c (renamed from pdf/pdf_plotters.c) | 232 | ||||
-rw-r--r-- | desktop/save_pdf/pdf_plotters.h (renamed from pdf/pdf_plotters.h) | 4 | ||||
-rw-r--r-- | gtk/dialogs/gtk_about.c | 7 | ||||
-rw-r--r-- | gtk/dialogs/gtk_options.c | 78 | ||||
-rw-r--r-- | gtk/gtk_gui.c | 112 | ||||
-rw-r--r-- | gtk/gtk_gui.h | 1 | ||||
-rw-r--r-- | gtk/gtk_print.c | 17 | ||||
-rw-r--r-- | gtk/gtk_print.h | 14 | ||||
-rw-r--r-- | gtk/gtk_scaffolding.c | 73 | ||||
-rw-r--r-- | gtk/res/netsurf.glade | 275 | ||||
-rw-r--r-- | gtk/res/options.glade | 429 | ||||
-rw-r--r-- | pdf/pdf_printer.h | 36 | ||||
-rw-r--r-- | render/box.c | 78 | ||||
-rw-r--r-- | render/box.h | 2 | ||||
-rw-r--r-- | render/html_redraw.c | 160 | ||||
-rw-r--r-- | render/layout.c | 2 | ||||
-rw-r--r-- | render/layout.h | 3 | ||||
-rw-r--r-- | render/loosen.c | 103 | ||||
-rw-r--r-- | riscos/gui.c | 6 | ||||
-rw-r--r-- | riscos/save_pdf.c | 7 | ||||
-rw-r--r-- | testres/jpeg.jpeg | bin | 6170 -> 0 bytes | |||
-rw-r--r-- | testres/png.png | bin | 4922 -> 0 bytes | |||
-rw-r--r-- | testres/text.html | 68 | ||||
-rw-r--r-- | testres/text2.html | 29 | ||||
-rw-r--r-- | utils/utils.h | 1 |
33 files changed, 1557 insertions, 420 deletions
diff --git a/Makefile.sources b/Makefile.sources index 10038b5be..f499c9e89 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -31,7 +31,7 @@ S_IMAGE := $(addprefix image/,$(S_IMAGE)) S_PDF := pdf_plotters.c font_haru.c S_PRINT := print.c S_LOOSE := loosen.c -S_PDF := $(addprefix pdf/,$(S_PDF)) $(addprefix desktop/,$(S_PRINT)) \ +S_PDF := $(addprefix desktop/save_pdf/,$(S_PDF)) $(addprefix desktop/,$(S_PRINT)) \ $(addprefix render/,$(S_LOOSE)) # S_BROWSER are sources related to full browsers but are common diff --git a/desktop/options.c b/desktop/options.c index c289cb0b6..197399aa1 100644 --- a/desktop/options.c +++ b/desktop/options.c @@ -139,6 +139,26 @@ unsigned int option_min_reflow_period = 100; /* time in cs */ #else unsigned int option_min_reflow_period = 25; /* time in cs */ #endif +/** top margin of exported page*/ +int option_margin_top = DEFAULT_MARGIN_TOP_MM; +/** bottom margin of exported page*/ +int option_margin_bottom = DEFAULT_MARGIN_BOTTOM_MM; +/** left margin of exported page*/ +int option_margin_left = DEFAULT_MARGIN_LEFT_MM; +/** right margin of exported page*/ +int option_margin_right = DEFAULT_MARGIN_RIGHT_MM; +/** scale of exported content*/ +int option_export_scale = DEFAULT_EXPORT_SCALE * 100; +/**suppressing images in printed content*/ +bool option_suppress_images = false; +/**turning off all backgrounds for printed content*/ +bool option_remove_backgrounds = false; +/**turning on content loosening for printed content*/ +bool option_enable_loosening = true; +/**compression of PDF documents*/ +bool option_enable_PDF_compression = true; +/**setting a password and encoding PDF documents*/ +bool option_enable_PDF_password = false; /* Fetcher configuration */ /** Maximum simultaneous active fetchers */ @@ -218,6 +238,16 @@ struct { { "suppress_curl_debug", OPTION_BOOL, &option_suppress_curl_debug }, { "target_blank", OPTION_BOOL, &option_target_blank }, + { "margin_top", OPTION_INTEGER, &option_margin_top}, + { "margin_bottom", OPTION_INTEGER, &option_margin_bottom}, + { "margin_left", OPTION_INTEGER, &option_margin_left}, + { "margin_right", OPTION_INTEGER, &option_margin_right}, + { "export_scale", OPTION_INTEGER, &option_export_scale}, + { "suppress_images", OPTION_BOOL, &option_suppress_images}, + { "remove_backgrounds", OPTION_BOOL, &option_remove_backgrounds}, + { "enable_loosening", OPTION_BOOL, &option_enable_loosening}, + { "enable_PDF_compression", OPTION_BOOL, &option_enable_PDF_compression}, + { "enable_PDF_password", OPTION_BOOL, &option_enable_PDF_password}, EXTRA_OPTION_TABLE }; diff --git a/desktop/options.h b/desktop/options.h index 89e99969b..cb238b93a 100644 --- a/desktop/options.h +++ b/desktop/options.h @@ -83,6 +83,25 @@ extern int option_scale; extern bool option_incremental_reflow; extern unsigned int option_min_reflow_period; +extern int option_margin_top; +extern int option_margin_bottom; +extern int option_margin_left; +extern int option_margin_right; +extern int option_export_scale; +extern bool option_suppress_images; +extern bool option_remove_backgrounds; +extern bool option_enable_loosening; +extern bool option_enable_PDF_compression; +extern bool option_enable_PDF_password; +#define DEFAULT_PAGE_WIDTH 595 +#define DEFAULT_PAGE_HEIGHT 840 +#define DEFAULT_MARGIN_TOP_MM 10 +#define DEFAULT_MARGIN_BOTTOM_MM 10 +#define DEFAULT_MARGIN_LEFT_MM 10 +#define DEFAULT_MARGIN_RIGHT_MM 10 +#define DEFAULT_EXPORT_SCALE 0.7 +#define DEFAULT_COPIES 1 + /* Fetcher configuration. */ extern int option_max_fetchers; extern int option_max_fetchers_per_host; diff --git a/desktop/print.c b/desktop/print.c index 931dbe087..433a0bd89 100644 --- a/desktop/print.c +++ b/desktop/print.c @@ -23,31 +23,34 @@ #include "utils/config.h" #ifdef WITH_PDF_EXPORT +#include <string.h> + +#include "desktop/options.h" #include "desktop/print.h" #include "desktop/printer.h" +#include "desktop/save_pdf/font_haru.h" #include "content/content.h" +#include "gtk/options.h" + #include "utils/log.h" #include "utils/talloc.h" #include "render/loosen.h" #include "render/box.h" -#include "pdf/font_haru.h" - static struct content *print_init(struct content *, struct print_settings *); static bool print_apply_settings(struct content *, struct print_settings *); - -/*TODO: should these be passed as parameters in order to allow simultaneous - printings? -*/ static float page_content_width, page_content_height; -static float text_margin_height; static struct content *printed_content; static float done_height; +bool html_redraw_printing = false; +int html_redraw_printing_border = 0; +int html_redraw_printing_top_cropped = 0; + /** * This function calls print setup, prints page after page until the whole * content is printed calls cleaning up afterwise. @@ -61,9 +64,9 @@ bool print_basic_run(struct content *content, struct print_settings *settings) { bool ret = true; - + if (settings == NULL) - settings = print_make_settings(DEFAULT); + settings = print_make_settings(DEFAULT, NULL); if (!print_set_up(content, printer, settings, NULL)) ret = false; @@ -71,7 +74,7 @@ bool print_basic_run(struct content *content, while (ret && (done_height < printed_content->height) ) ret = print_draw_next_page(printer, settings); - print_cleanup(content, printer); + print_cleanup(content, printer, settings); return ret; } @@ -115,11 +118,17 @@ bool print_set_up(struct content *content, bool print_draw_next_page(const struct printer *printer, struct print_settings *settings) { - /*TODO:Plotter will have to be duplicated and passed - as an argument - to allow simultaneous screen and - page plotting*/ + int clip_x1, clip_y1; + plot = *(printer->plotter); - + html_redraw_printing_top_cropped = INT_MAX; + + clip_x1 = page_content_width * settings->scale; + clip_y1 = page_content_height * settings->scale; + + html_redraw_printing = true; + html_redraw_printing_border = clip_y1; + printer->print_next_page(); if( !content_redraw(printed_content, 0, @@ -127,11 +136,13 @@ bool print_draw_next_page(const struct printer *printer, 0,0, 0, 0, - page_content_width * settings->scale, - page_content_height * settings->scale, + clip_x1, + clip_y1, settings->scale, 0xffffff)) return false; - done_height += page_content_height - text_margin_height; + done_height += page_content_height - + (html_redraw_printing_top_cropped != INT_MAX ? + clip_y1 - html_redraw_printing_top_cropped : 0) / settings->scale; return true; } @@ -194,9 +205,7 @@ bool print_apply_settings(struct content *content, return false; /*Apply settings - adjust page size etc*/ - - text_margin_height = settings->margins[MARGINTEXT]; - + page_content_width = (settings->page_width - settings->margins[MARGINLEFT] - settings->margins[MARGINRIGHT]) / settings->scale; @@ -207,9 +216,10 @@ bool print_apply_settings(struct content *content, LOG(("New layout applied.New height = %d ; New width = %d ", content->height, content->width)); - if (content->width > page_content_width) - return loosen_document_layout(content, content->data.html.layout, - page_content_width, page_content_height); + /*check if loosening is necessary and requested*/ + if (option_enable_loosening && content->width > page_content_width) + return loosen_document_layout(content, content->data.html.layout, + page_content_width, page_content_height); return true; } @@ -221,10 +231,13 @@ bool print_apply_settings(struct content *content, * \return true if successful, false otherwise */ bool print_cleanup(struct content *content, - const struct printer *printer) + const struct printer *printer, + struct print_settings *settings) { printer->print_end(); + html_redraw_printing = false; + if (printed_content) { content_remove_user(printed_content, NULL, (intptr_t)print_init, 0); talloc_free(printed_content); @@ -232,50 +245,98 @@ bool print_cleanup(struct content *content, content_remove_user(content, NULL, (intptr_t)print_init, 0); + free((void *)settings->output); + free(settings); + return true; } /** * Generates one of the predefined print settings sets. + * \param configuration the requested configuration + * \param filename the filename or NULL * \return print_settings in case if successful, NULL if unknown configuration \ * or lack of memory. */ -struct print_settings *print_make_settings(print_configuration configuration) +struct print_settings *print_make_settings(print_configuration configuration, + const char *filename) { struct print_settings *settings; + char *path; + struct css_length length; + + path = malloc(PATH_MAX * sizeof(char)); + if (path == NULL) + return NULL; + + length.unit = CSS_UNIT_MM; switch (configuration){ case DEFAULT: settings = (struct print_settings*) - malloc(sizeof (struct print_settings) ); + malloc(sizeof(struct print_settings) ); if (settings == NULL) return NULL; - settings->page_width = 595; - settings->page_height = 840; - settings->copies = 1; - /*with 0.7 the pages look the best, the value in - haru_nsfont_apply_style should be kept the same as this - */ - settings->scale = 0.7; + settings->page_width = DEFAULT_PAGE_WIDTH; + settings->page_height = DEFAULT_PAGE_HEIGHT; + settings->copies = DEFAULT_COPIES; + + settings->scale = DEFAULT_EXPORT_SCALE; + + length.value = DEFAULT_MARGIN_LEFT_MM; + settings->margins[MARGINLEFT] = css_len2px(&length, 0); + length.value = DEFAULT_MARGIN_RIGHT_MM; + settings->margins[MARGINRIGHT] = css_len2px(&length, 0); + length.value = DEFAULT_MARGIN_TOP_MM; + settings->margins[MARGINTOP] = css_len2px(&length, 0); + length.value = DEFAULT_MARGIN_BOTTOM_MM; + settings->margins[MARGINBOTTOM] = css_len2px(&length, 0); - settings->margins[MARGINLEFT] = 30; - settings->margins[MARGINRIGHT] = 30; - settings->margins[MARGINTOP] = 30; - settings->margins[MARGINBOTTOM] = 30; + settings->font_func = &haru_nsfont; - settings->margins[MARGINTEXT] = 10; + break; + /*use settings from the Export options tab*/ + case OPTIONS: + settings = (struct print_settings*) + malloc(sizeof(struct print_settings) ); + + if (settings == NULL) + return NULL; + + settings->page_width = DEFAULT_PAGE_WIDTH; + settings->page_height = DEFAULT_PAGE_HEIGHT; + settings->copies = DEFAULT_COPIES; + + settings->scale = (float)option_export_scale / 100; + + length.value = option_margin_left; + settings->margins[MARGINLEFT] = css_len2px(&length, 0); + length.value = option_margin_right; + settings->margins[MARGINRIGHT] = css_len2px(&length, 0); + length.value = option_margin_top; + settings->margins[MARGINTOP] = css_len2px(&length, 0); + length.value = option_margin_bottom; + settings->margins[MARGINBOTTOM] = css_len2px(&length, 0); - settings->output = "out.pdf"; settings->font_func = &haru_nsfont; break; - default: return NULL; } + /*if no filename is specified use one without an extension*/ + if (filename == NULL) { + /*TODO: the "/" is not platform independent*/ + strcpy(path, "/out"); + } + else + strcpy(path, filename); + + settings->output = path; + return settings; } diff --git a/desktop/print.h b/desktop/print.h index dc4cde642..98f382eca 100644 --- a/desktop/print.h +++ b/desktop/print.h @@ -37,11 +37,10 @@ struct content; struct printer; -enum { MARGINLEFT = 0, MARGINRIGHT = 1, MARGINTOP = 2, MARGINBOTTOM = 3, - MARGINTEXT = 4}; +enum { MARGINLEFT = 0, MARGINRIGHT = 1, MARGINTOP = 2, MARGINBOTTOM = 3}; /** Predefined printing configuration names*/ -typedef enum {DEFAULT} print_configuration; +typedef enum {DEFAULT, OPTIONS} print_configuration; /** Settings for a print - filled in by print_make_settings or * 'manually' by the caller @@ -49,7 +48,7 @@ typedef enum {DEFAULT} print_configuration; struct print_settings{ /*Standard parameters*/ float page_width, page_height; - float margins[5]; + int margins[4]; float scale; @@ -58,18 +57,28 @@ struct print_settings{ /*Output destinations - file/printer name*/ const char *output; - /*TODO: more options?*/ + /*the functions used to measure fonts*/ const struct font_functions *font_func; }; + bool print_basic_run(struct content *, const struct printer *, struct print_settings *); bool print_set_up(struct content *content, const struct printer *printer, struct print_settings *settings, double *height); bool print_draw_next_page(const struct printer *printer, struct print_settings *settings); -bool print_cleanup(struct content *, const struct printer *); +bool print_cleanup(struct content *, const struct printer *, + struct print_settings *settings); + +struct print_settings *print_make_settings(print_configuration configuration, + const char *url); -struct print_settings *print_make_settings(print_configuration configuration); +/*is the content currently redrawn fo printing?*/ +extern bool html_redraw_printing; +/*if something is partially under this Y coordinate it won't be drawn...*/ +extern int html_redraw_printing_border; +/*...and the highest of the tops of all cropped elements will be remembered*/ +extern int html_redraw_printing_top_cropped; #endif diff --git a/pdf/TODO b/desktop/save_pdf/TODO index 1b3a896b9..1b3a896b9 100644 --- a/pdf/TODO +++ b/desktop/save_pdf/TODO diff --git a/pdf/font_haru.c b/desktop/save_pdf/font_haru.c index 7a158d5d1..2e5f90adb 100644 --- a/pdf/font_haru.c +++ b/desktop/save_pdf/font_haru.c @@ -26,7 +26,7 @@ #include "utils/config.h" #ifdef WITH_PDF_EXPORT -/* #define FONT_HARU_DEBUG */ +/*#define FONT_HARU_DEBUG */ #include <assert.h> #include <float.h> @@ -34,8 +34,8 @@ #include <string.h> #include "hpdf.h" #include "css/css.h" +#include "desktop/save_pdf/font_haru.h" #include "render/font.h" -#include "pdf/font_haru.h" #include "utils/log.h" @@ -61,7 +61,6 @@ const struct font_functions haru_nsfont = { haru_nsfont_split }; - /** * Haru error handler * for debugging purposes - it immediately exits the program on the first error, @@ -124,8 +123,9 @@ bool haru_nsfont_width(const struct css_style *style, char *string_nt; HPDF_REAL width_real; + *width = 0; + if (length == 0) { - *width = 0; return true; } @@ -178,7 +178,7 @@ bool haru_nsfont_position_in_string(const struct css_style *style, if (!haru_nsfont_init(&pdf, &page, string, &string_nt, length)) return false; - if (!HPDF_Page_SetWidth(page, x) + if (HPDF_Page_SetWidth(page, x) != HPDF_OK || !haru_nsfont_apply_style(style, pdf, page, NULL)) { free(string_nt); HPDF_Free(pdf); @@ -238,7 +238,7 @@ bool haru_nsfont_split(const struct css_style *style, if (!haru_nsfont_init(&pdf, &page, string, &string_nt, length)) return false; - if (!HPDF_Page_SetWidth(page, x) + if (HPDF_Page_SetWidth(page, x) != HPDF_OK || !haru_nsfont_apply_style(style, pdf, page, NULL)) { free(string_nt); HPDF_Free(pdf); @@ -274,7 +274,6 @@ bool haru_nsfont_split(const struct css_style *style, * style and nothing with the page is done * \return true on success, false on error and error reported */ - bool haru_nsfont_apply_style(const struct css_style *style, HPDF_Doc doc, HPDF_Page page, HPDF_Font *font) { @@ -340,21 +339,25 @@ bool haru_nsfont_apply_style(const struct css_style *style, LOG(("Setting font: %s", font_name)); #endif + /*the functions was invoked only to get the proper font*/ if (font != NULL) { pdf_font = HPDF_GetFont(doc, font_name, "StandardEncoding"); if (pdf_font == NULL) return false; *font = pdf_font; } + /*the function was invoked to set the page parameters*/ else { if (style->font_size.value.length.unit == CSS_UNIT_PX) size = style->font_size.value.length.value; else size = css_len2pt(&style->font_size.value.length, style); - /*with 0.7 the pages look the best, this should be kept the same - as the scale in print settings*/ - size = size / 0.7; + if (size <= 0) + return false; + + if (size > HPDF_MAX_FONTSIZE) + size = HPDF_MAX_FONTSIZE; pdf_font = HPDF_GetFont(doc, font_name, "StandardEncoding"); if (pdf_font == NULL) diff --git a/pdf/font_haru.h b/desktop/save_pdf/font_haru.h index 326f6497b..eca9855e6 100644 --- a/pdf/font_haru.h +++ b/desktop/save_pdf/font_haru.h @@ -31,6 +31,6 @@ bool haru_nsfont_apply_style(const struct css_style *style, HPDF_Font *font); extern const struct font_functions haru_nsfont; - +extern float pdf_scale; #endif diff --git a/pdf/pdf_plotters.c b/desktop/save_pdf/pdf_plotters.c index 6451ca704..10ddc10bf 100644 --- a/pdf/pdf_plotters.c +++ b/desktop/save_pdf/pdf_plotters.c @@ -18,9 +18,7 @@ /** \file * Target independent PDF plotting using Haru Free PDF Library. - * Contains also the current solution for some text being cropped over page - * boundaries a 'fuzzy' bottom margin. - */ + */ #include "utils/config.h" #ifdef WITH_PDF_EXPORT @@ -29,10 +27,11 @@ #include <string.h> #include "hpdf.h" +#include "desktop/options.h" #include "desktop/plotters.h" #include "desktop/print.h" #include "desktop/printer.h" -#include "pdf/pdf_plotters.h" +#include "desktop/save_pdf/pdf_plotters.h" #include "utils/log.h" #include "utils/utils.h" #include "image/bitmap.h" @@ -71,9 +70,9 @@ static void pdf_set_solid(void); static void pdf_set_dashed(void); static void pdf_set_dotted(void); -static void pdf_page_apply_notext_clip(void); - static HPDF_Image pdf_extract_image(struct bitmap *bitmap, struct content *content); +static void apply_clip_and_mode(void); + static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *user_data); @@ -92,11 +91,11 @@ static HPDF_REAL page_height, page_width; /*Remeber if pdf_plot_clip was invoked for current page*/ static bool page_clipped; +int last_clip_x0, last_clip_y0, last_clip_x1, last_clip_y1; + +bool in_text_mode, text_mode_request; static struct print_settings* settings; -/*this is added to the bottom margin as a place where text can be plotted - when it overflows just a little bit*/ -static float text_margin; static const struct plotter_table pdf_plotters = { pdf_plot_clg, @@ -124,6 +123,10 @@ struct printer pdf_printer= { pdf_end }; +float pdf_scale; +static char *owner_pass; +static char *user_pass; + bool pdf_plot_clg(colour c) { return true; @@ -135,6 +138,8 @@ bool pdf_plot_rectangle(int x0, int y0, int width, int height, #ifdef PDF_DEBUG LOG((".")); #endif + apply_clip_and_mode(); + HPDF_Page_SetLineWidth(pdf_page, line_width); if (dotted) @@ -157,7 +162,10 @@ bool pdf_plot_line(int x0, int y0, int x1, int y1, int width, { #ifdef PDF_DEBUG LOG((".")); -#endif +#endif + + apply_clip_and_mode(); + HPDF_Page_SetLineWidth(pdf_page, width); if (dotted) @@ -188,6 +196,8 @@ bool pdf_plot_polygon(int *p, unsigned int n, colour fill) if (n == 0) return true; + apply_clip_and_mode(); + HPDF_Page_SetRGBFill(pdf_page, R(fill), G(fill), B(fill)); HPDF_Page_MoveTo(pdf_page, p[0], page_height - p[1]); @@ -227,6 +237,8 @@ bool pdf_plot_fill(int x0, int y0, int x1, int y1, colour c) x1 = min(max(x1, 0), page_width); y1 = min(max(y1, 0), page_height); + apply_clip_and_mode(); + HPDF_Page_SetRGBFill(pdf_page, R(c), G(c), B(c)); HPDF_Page_Rectangle(pdf_page, x0, page_height - y1, x1-x0, y1-y0); HPDF_Page_Fill(pdf_page); @@ -234,32 +246,20 @@ bool pdf_plot_fill(int x0, int y0, int x1, int y1, colour c) return true; } +/**here the clip is only queried */ bool pdf_plot_clip(int clip_x0, int clip_y0, int clip_x1, int clip_y1) { #ifdef PDF_DEBUG LOG(("%d %d %d %d", clip_x0, clip_y0, clip_x1, clip_y1)); #endif - HPDF_Page_GRestore(pdf_page); - if (page_clipped) - HPDF_Page_GRestore(pdf_page); - /*Normalize cllipping area - to prevent overflows. See comment in pdf_plot_fill. */ - clip_x0 = min(max(clip_x0, 0), page_width); - clip_y0 = min(max(clip_y0, 0), page_height); - clip_x1 = min(max(clip_x1, 0), page_width); - clip_y1 = min(max(clip_y1, 0), page_height); - - - HPDF_Page_GSave(pdf_page); - HPDF_Page_Rectangle(pdf_page, clip_x0, page_height-clip_y1, - clip_x1-clip_x0, clip_y1-clip_y0); - HPDF_Page_Clip(pdf_page); - HPDF_Page_EndPath(pdf_page); - - pdf_page_apply_notext_clip(); + last_clip_x0 = min(max(clip_x0, 0), page_width); + last_clip_y0 = min(max(clip_y0, 0), page_height); + last_clip_x1 = min(max(clip_x1, 0), page_width); + last_clip_y1 = min(max(clip_y1, 0), page_height); page_clipped = true; @@ -274,34 +274,37 @@ bool pdf_plot_text(int x, int y, const struct css_style *style, #endif char *word; HPDF_REAL size; - bool fuzzy=false; float text_bottom_position, descent; if (length == 0) return true; + text_mode_request = true; + apply_clip_and_mode(); + if (style->font_size.value.length.unit == CSS_UNIT_PX) size = style->font_size.value.length.value; else size = css_len2pt(&style->font_size.value.length, style); + /*this can be removed when export options get added for riscos*/ +#ifdef riscos + size *= DEFAULT_EXPORT_SCALE; +#else + size *= pdf_scale; +#endif + + if (size <= 0) + return true; + + if (size > HPDF_MAX_FONTSIZE) + size = HPDF_MAX_FONTSIZE; + haru_nsfont_apply_style(style, pdf_doc, pdf_page, &pdf_font); descent = size * (HPDF_Font_GetDescent(pdf_font) / 1000.0); text_bottom_position = page_height - y + descent; - if ( (size > y) && (y - descent <= text_margin) ) - return true; - - if (text_bottom_position < settings->margins[MARGINBOTTOM] + text_margin ) { - if ((text_bottom_position >= settings->margins[MARGINBOTTOM]) && - (page_height - (y - size) > - settings->margins[MARGINBOTTOM] + text_margin)) { - fuzzy = true; - HPDF_Page_GRestore(pdf_page); - } - } - word = (char*) malloc( sizeof(char) * (length+1) ); if (word == NULL) return false; @@ -311,13 +314,8 @@ bool pdf_plot_text(int x, int y, const struct css_style *style, HPDF_Page_SetRGBFill(pdf_page, R(c), G(c), B(c)); - HPDF_Page_BeginText(pdf_page); HPDF_Page_SetFontAndSize (pdf_page, pdf_font, size); HPDF_Page_TextOut (pdf_page, x, page_height - y, word); - HPDF_Page_EndText(pdf_page); - - if (fuzzy) - pdf_page_apply_notext_clip(); free(word); @@ -329,6 +327,8 @@ bool pdf_plot_disc(int x, int y, int radius, colour c, bool filled) #ifdef PDF_DEBUG LOG((".")); #endif + apply_clip_and_mode(); + if (filled) HPDF_Page_SetRGBFill(pdf_page, R(c), G(c), B(c)); else @@ -356,6 +356,8 @@ bool pdf_plot_arc(int x, int y, int radius, int angle1, int angle2, colour c) if (angle1 > angle2) angle1 -= 360; + apply_clip_and_mode(); + HPDF_Page_SetRGBStroke(pdf_page, R(c), G(c), B(c)); HPDF_Page_Arc(pdf_page, x, page_height-y, radius, angle1, angle2); @@ -376,6 +378,8 @@ bool pdf_plot_bitmap(int x, int y, int width, int height, if (width == 0 || height == 0) return true; + apply_clip_and_mode(); + image = pdf_extract_image(bitmap, content); if (!image) @@ -402,6 +406,8 @@ bool pdf_plot_bitmap_tile(int x, int y, int width, int height, if (width == 0 || height == 0) return true; + apply_clip_and_mode(); + image = pdf_extract_image(bitmap, content); if (image) { @@ -416,8 +422,8 @@ bool pdf_plot_bitmap_tile(int x, int y, int width, int height, for (current_y=0; current_y < max_height; current_y += height) for (current_x=0; current_x < max_width; current_x += width) HPDF_Page_DrawImage(pdf_page, image, - current_x, - page_height-current_y-height, + current_x + x, + page_height-current_y - y - height, width, height); return true; @@ -442,15 +448,12 @@ HPDF_Image pdf_extract_image(struct bitmap *bitmap, struct content *content) */ switch(content->type){ /*Handle "embeddable" types of images*/ - /*TODO:something seems to be wrong with HPDF_LoadJpegImageFromMem - no embedding at all till I'll figure it out - */ -// case CONTENT_JPEG: -// image = HPDF_LoadJpegImageFromMem(pdf_doc, -// content->source_data, -// content->total_size); -// break; - + case CONTENT_JPEG: + image = HPDF_LoadJpegImageFromMem(pdf_doc, + content->source_data, + content->source_size); + break; + /*Disabled until HARU PNG support will be more stable. case CONTENT_PNG: @@ -458,6 +461,8 @@ HPDF_Image pdf_extract_image(struct bitmap *bitmap, struct content *content) content->source_data, content->total_size); break;*/ + default: + break; } } @@ -514,6 +519,39 @@ HPDF_Image pdf_extract_image(struct bitmap *bitmap, struct content *content) return image; } +/**change the mode and clip only if it's necessary*/ +static void apply_clip_and_mode() +{ + + if (in_text_mode && (!text_mode_request || page_clipped)) { + HPDF_Page_EndText(pdf_page); + in_text_mode = false; + } + + if (page_clipped) { + + HPDF_Page_GRestore(pdf_page); + HPDF_Page_GSave(pdf_page); + + HPDF_Page_Rectangle(pdf_page, last_clip_x0, + page_height - last_clip_y1, + last_clip_x1 - last_clip_x0, + last_clip_y1 - last_clip_y0); + HPDF_Page_Clip(pdf_page); + HPDF_Page_EndPath(pdf_page); + + page_clipped = false; + } + + if (text_mode_request) { + if (!in_text_mode) { + HPDF_Page_BeginText(pdf_page); + in_text_mode = true; + } + + text_mode_request = false; + } +} static inline float transform_x(float *transform, float x, float y) { @@ -644,9 +682,10 @@ bool pdf_begin(struct print_settings *print_settings) page_height = settings->page_height - settings->margins[MARGINTOP]; - text_margin = settings->margins[MARGINTEXT]; -// HPDF_SetCompressionMode(pdf_doc, HPDF_COMP_ALL); /*Compression on*/ + if (option_enable_PDF_compression) + HPDF_SetCompressionMode(pdf_doc, HPDF_COMP_ALL); /*Compression on*/ + pdf_font = HPDF_GetFont (pdf_doc, "Times-Roman", "StandardEncoding"); pdf_page = NULL; @@ -678,9 +717,11 @@ bool pdf_next_page(void) HPDF_Page_Concat(pdf_page,1,0,0,1,settings->margins[MARGINLEFT],0); - pdf_page_apply_notext_clip(); - page_clipped = false; + HPDF_Page_GSave(pdf_page); + + text_mode_request = false; + in_text_mode = false; #ifdef PDF_DEBUG LOG(("%f %f", page_width, page_height)); @@ -692,6 +733,7 @@ bool pdf_next_page(void) void pdf_end(void) { + char *path; #ifdef PDF_DEBUG LOG(("pdf_end begins")); if (pdf_page != NULL) { @@ -702,17 +744,47 @@ void pdf_end(void) pdf_plot_grid(100, 100, 0xCCCCFF); } #endif - - /*TODO: if false notify user*/ - if (settings->output) - HPDF_SaveToFile(pdf_doc, settings->output); - - HPDF_Free(pdf_doc); - + + if (settings->output != NULL) + path = strdup(settings->output); + else + path = NULL; + + /*Encryption on*/ + if (option_enable_PDF_password) + PDF_Password(&owner_pass, &user_pass, path); + else + save_pdf(path); #ifdef PDF_DEBUG LOG(("pdf_end finishes")); #endif } +/** saves the pdf optionally encrypting it before*/ +void save_pdf(char *path) +{ + bool success = false; + + if (option_enable_PDF_password && owner_pass != NULL ) { + HPDF_SetPassword(pdf_doc, owner_pass, user_pass); + HPDF_SetEncryptionMode(pdf_doc, HPDF_ENCRYPT_R3, 16); + free(owner_pass); + free(user_pass); + } + + if (path != NULL) { + if (HPDF_SaveToFile(pdf_doc, path) != HPDF_OK) + remove(path); + else + success = true; + + free(path); + } + + if (!success) + warn_user("Unable to save PDF file.", 0); + + HPDF_Free(pdf_doc); +} /** @@ -749,31 +821,11 @@ void pdf_plot_grid(int x_dist, int y_dist, unsigned int colour) } #endif -/** - * A solution for fuzzy margins - saves the current clipping and puts the main - * clip frame (page without margins) over it. -*/ -void pdf_page_apply_notext_clip(void) +/**used to synch the text scale with the scale for the whole content*/ +void pdf_set_scale(float s) { - /*Save state underneath*/ - HPDF_Page_GSave(pdf_page); - - /*Apply no-text clipping (stadard page)*/ - HPDF_Page_Rectangle(pdf_page, - 0, - text_margin + settings->margins[MARGINBOTTOM], - page_width, - page_height - settings->margins[MARGINTOP] - text_margin); - - HPDF_Page_Clip(pdf_page); - -#ifdef PDF_DEBUG - HPDF_Page_Stroke(pdf_page); -#else - HPDF_Page_EndPath(pdf_page); -#endif + pdf_scale = s; } #endif /* WITH_PDF_EXPORT */ - diff --git a/pdf/pdf_plotters.h b/desktop/save_pdf/pdf_plotters.h index 874518980..ba815c552 100644 --- a/pdf/pdf_plotters.h +++ b/desktop/save_pdf/pdf_plotters.h @@ -37,4 +37,8 @@ bool pdf_next_page(void); /**Close pdf document and save changes to file*/ void pdf_end(void); +void pdf_set_scale(float s); + +void save_pdf(char *path); + #endif /*NETSURF_PDF_PLOTTERS_H*/ diff --git a/gtk/dialogs/gtk_about.c b/gtk/dialogs/gtk_about.c index e39af1cc2..81d22cea8 100644 --- a/gtk/dialogs/gtk_about.c +++ b/gtk/dialogs/gtk_about.c @@ -52,9 +52,10 @@ void nsgtk_about_dialog_init(GtkWindow *parent, struct browser_window *bw, const gtk_about_dialog_set_url_hook (launch_url, (gpointer) bw, NULL); gtk_show_about_dialog(parent, "artists", artists, "authors", authors, - "comments", description,"copyright", copyright, - "documenters", documenters, "license", licence, "program-name", name, - "translator-credits", translators, "version", version, "website", url, + "comments", description,"copyright", copyright, "documenters", documenters, + "license", licence, + "program-name", name, "translator-credits", translators, + "version", version, "website", url, "website-label", url_label, "wrap-license", FALSE, NULL); } diff --git a/gtk/dialogs/gtk_options.c b/gtk/dialogs/gtk_options.c index b205d2d87..29ea54b1b 100644 --- a/gtk/dialogs/gtk_options.c +++ b/gtk/dialogs/gtk_options.c @@ -20,7 +20,6 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#include <math.h> #include <gtk/gtk.h> #include <glade/glade.h> #include "utils/log.h" @@ -31,6 +30,8 @@ #include "gtk/dialogs/gtk_options.h" #include "gtk/gtk_window.h" +#include "desktop/print.h" + GtkDialog *wndPreferences; GladeXML *gladeFile; gboolean is_initialized = FALSE; @@ -86,6 +87,18 @@ DECLARE(checkClearDownloads); DECLARE(checkRequestOverwrite); DECLARE(fileChooserDownloads); +DECLARE(spinMarginTop); +DECLARE(spinMarginBottom); +DECLARE(spinMarginLeft); +DECLARE(spinMarginRight); +DECLARE(spinExportScale); +DECLARE(checkSuppressImages); +DECLARE(checkRemoveBackgrounds); +DECLARE(checkFitPage); +DECLARE(checkCompressPDF); +DECLARE(checkPasswordPDF); +DECLARE(setDefaultExportOptions); + /* Used when the feature is not implemented yet */ #define FIND_WIDGET(x) (x) = glade_xml_get_widget(gladeFile, #x); \ if ((x) == NULL) LOG(("Unable to find widget '%s'!", #x)) @@ -149,6 +162,19 @@ GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent) { CONNECT(checkRequestOverwrite, "toggled"); CONNECT(fileChooserDownloads, "current-folder-changed"); + CONNECT(spinMarginTop, "value-changed"); + CONNECT(spinMarginBottom, "value-changed"); + CONNECT(spinMarginLeft, "value-changed"); + CONNECT(spinMarginRight, "value-changed"); + CONNECT(spinExportScale, "value-changed"); + CONNECT(checkSuppressImages, "toggled"); + CONNECT(checkRemoveBackgrounds, "toggled"); + CONNECT(checkFitPage, "toggled"); + CONNECT(checkCompressPDF, "toggled"); + CONNECT(checkPasswordPDF, "toggled"); + CONNECT(setDefaultExportOptions, "clicked"); + + g_signal_connect(G_OBJECT(wndPreferences), "response", G_CALLBACK (dialog_response_handler), NULL); @@ -233,6 +259,18 @@ void nsgtk_options_load(void) { SET_CHECK(checkClearDownloads, option_downloads_clear); SET_CHECK(checkRequestOverwrite, option_request_overwrite); SET_FILE_CHOOSER(fileChooserDownloads, option_downloads_directory); + + SET_SPIN(spinMarginTop, option_margin_top); + SET_SPIN(spinMarginBottom, option_margin_bottom); + SET_SPIN(spinMarginLeft, option_margin_left); + SET_SPIN(spinMarginRight, option_margin_right); + SET_SPIN(spinExportScale, option_export_scale); + SET_CHECK(checkSuppressImages, option_suppress_images); + SET_CHECK(checkRemoveBackgrounds, option_remove_backgrounds); + SET_CHECK(checkFitPage, option_enable_loosening); + SET_CHECK(checkCompressPDF, option_enable_PDF_compression); + SET_CHECK(checkPasswordPDF, option_enable_PDF_password); + SET_BUTTON(setDefaultExportOptions); } static void dialog_response_handler (GtkDialog *dlg, gint res_id){ @@ -280,7 +318,6 @@ static gboolean on_dialog_close (GtkDialog *dlg, gboolean stay_alive){ (y) = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER((x))); #define BUTTON_CLICKED(x) gboolean on_##x##_changed(GtkWidget *widget, gpointer data) { \ LOG(("Signal emitted on '%s'", #x)); - ENTRY_CHANGED(entryHomePageURL, option_homepage_url)} return FALSE;} BUTTON_CLICKED(setCurrentPage) @@ -318,7 +355,7 @@ COMBO_CHANGED(comboProxyType, proxy_type) option_http_proxy_auth = OPTION_HTTP_PROXY_AUTH_NTLM; break; } - gboolean sensitive = (option_http_proxy_auth); + gboolean sensitive = (!proxy_type == 0); gtk_widget_set_sensitive (entryProxyHost, sensitive); gtk_widget_set_sensitive (entryProxyPort, sensitive); gtk_widget_set_sensitive (entryProxyUser, sensitive); @@ -383,3 +420,38 @@ SPIN_CHANGED(spinDiscCacheAge, option_disc_cache_age)} CHECK_CHANGED(checkClearDownloads, option_downloads_clear)} CHECK_CHANGED(checkRequestOverwrite, option_request_overwrite)} FILE_CHOOSER_CHANGED(fileChooserDownloads, option_downloads_directory)} + +SPIN_CHANGED(spinMarginTop, option_margin_top)} +SPIN_CHANGED(spinMarginBottom, option_margin_bottom)} +SPIN_CHANGED(spinMarginLeft, option_margin_left)} +SPIN_CHANGED(spinMarginRight, option_margin_right)} +SPIN_CHANGED(spinExportScale, option_export_scale)} +CHECK_CHANGED(checkSuppressImages, option_suppress_images)} +CHECK_CHANGED(checkRemoveBackgrounds, option_remove_backgrounds)} +CHECK_CHANGED(checkFitPage, option_enable_loosening)} +CHECK_CHANGED(checkCompressPDF, option_enable_PDF_compression)} +CHECK_CHANGED(checkPasswordPDF, option_enable_PDF_password)} +BUTTON_CLICKED(setDefaultExportOptions) + option_margin_top = DEFAULT_MARGIN_TOP_MM; + option_margin_bottom = DEFAULT_MARGIN_BOTTOM_MM; + option_margin_left = DEFAULT_MARGIN_LEFT_MM; + option_margin_right = DEFAULT_MARGIN_RIGHT_MM; + option_export_scale = DEFAULT_EXPORT_SCALE * 100; + option_suppress_images = false; + option_remove_backgrounds = false; + option_enable_loosening = true; + option_enable_PDF_compression = true; + option_enable_PDF_password = false; + + SET_SPIN(spinMarginTop, option_margin_top); + SET_SPIN(spinMarginBottom, option_margin_bottom); + SET_SPIN(spinMarginLeft, option_margin_left); + SET_SPIN(spinMarginRight, option_margin_right); + SET_SPIN(spinExportScale, option_export_scale); + SET_CHECK(checkSuppressImages, option_suppress_images); + SET_CHECK(checkRemoveBackgrounds, option_remove_backgrounds); + SET_CHECK(checkCompressPDF, option_enable_PDF_compression); + SET_CHECK(checkPasswordPDF, option_enable_PDF_password); + SET_CHECK(checkFitPage, option_enable_loosening); + +} diff --git a/gtk/gtk_gui.c b/gtk/gtk_gui.c index 2efa5fa15..359f1d7dd 100644 --- a/gtk/gtk_gui.c +++ b/gtk/gtk_gui.c @@ -44,6 +44,7 @@ #include "desktop/gui.h" #include "desktop/netsurf.h" #include "desktop/options.h" +#include "desktop/save_pdf/pdf_plotters.h" #include "gtk/gtk_gui.h" #include "gtk/dialogs/gtk_options.h" #include "gtk/gtk_completion.h" @@ -69,6 +70,7 @@ char *adblock_stylesheet_url; char *options_file_location; char *glade_file_location; char *res_dir_location; +char *print_options_file_location; struct gui_window *search_current_window = 0; @@ -89,6 +91,8 @@ static void nsgtk_ssl_accept(GtkButton *w, gpointer data); static void nsgtk_ssl_reject(GtkButton *w, gpointer data); static void nsgtk_select_menu_clicked(GtkCheckMenuItem *checkmenuitem, gpointer user_data); +static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data); +static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data); /** * Locate a shared resource file by searching known places in order. @@ -287,7 +291,7 @@ void gui_init(int argc, char** argv) LOG(("Using '%s' as download directory", home)); option_downloads_directory = home; } - + find_resource(buf, "messages", "./gtk/res/messages"); LOG(("Using '%s' as Messages file", buf)); messages_load(buf); @@ -304,6 +308,10 @@ void gui_init(int argc, char** argv) adblock_stylesheet_url = path_to_url(buf); LOG(("Using '%s' as AdBlock CSS URL", adblock_stylesheet_url)); + find_resource(buf, "Print", "~/.netsurf/Print"); + LOG(("Using '%s' as Print Settings file", buf)); + print_options_file_location = strdup(buf); + urldb_load(option_url_file); urldb_load_cookies(option_cookie_file); @@ -409,6 +417,7 @@ void gui_quit(void) free(adblock_stylesheet_url); free(option_cookie_file); free(option_cookie_jar); + free(print_options_file_location); gtk_fetch_filetype_fin(); #ifdef WITH_HUBBUB /* We don't care if this fails as we're about to die, anyway */ @@ -618,3 +627,104 @@ bool cookies_update(const char *domain, const struct cookie_data *data) { return true; } + +void PDF_Password(char **owner_pass, char **user_pass, char *path) +{ + GladeXML *x = glade_xml_new(glade_file_location, NULL, NULL); + GtkWindow *wnd = GTK_WINDOW(glade_xml_get_widget(x, "wndPDFPassword")); + GtkButton *ok, *no; + void **data = malloc(5 * sizeof(void *)); + + *owner_pass = NULL; + *user_pass = NULL; + + data[0] = owner_pass; + data[1] = user_pass; + data[2] = wnd; + data[3] = x; + data[4] = path; + + ok = GTK_BUTTON(glade_xml_get_widget(x, "buttonPDFSetPassword")); + no = GTK_BUTTON(glade_xml_get_widget(x, "buttonPDFNoPassword")); + + g_signal_connect(G_OBJECT(ok), "clicked", + G_CALLBACK(nsgtk_PDF_set_pass), (gpointer)data); + g_signal_connect(G_OBJECT(no), "clicked", + G_CALLBACK(nsgtk_PDF_no_pass), (gpointer)data); + + gtk_widget_show(GTK_WIDGET(wnd)); +} + +static void nsgtk_PDF_set_pass(GtkButton *w, gpointer data) +{ + char **owner_pass = ((void **)data)[0]; + char **user_pass = ((void **)data)[1]; + GtkWindow *wnd = ((void **)data)[2]; + GladeXML *x = ((void **)data)[3]; + char *path = ((void **)data)[4]; + + char *op, *op1; + char *up, *up1; + + op = strdup(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(x, + "entryPDFOwnerPassword")))); + op1 = strdup(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(x, + "entryPDFOwnerPassword1")))); + up = strdup(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(x, + "entryPDFUserPassword")))); + up1 = strdup(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(x, + "entryPDFUserPassword1")))); + + + if (op[0] == '\0') { + gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(x, + "labelInfo")), + "Owner password must be at least 1 character long:"); + free(op); + free(up); + } + else if (!strcmp(op, up)) { + gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(x, + "labelInfo")), + "User and owner passwords must be different:"); + free(op); + free(up); + } + else if (!strcmp(op, op1) && !strcmp(up, up1)) { + + *owner_pass = op; + if (up[0] == '\0') + free(up); + else + *user_pass = up; + + free(data); + gtk_widget_destroy(GTK_WIDGET(wnd)); + g_object_unref(G_OBJECT(x)); + + save_pdf(path); + } + else { + gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(x, + "labelInfo")), "Passwords not confirmed:"); + free(op); + free(up); + } + + free(op1); + free(up1); +} + +static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data) +{ + GtkWindow *wnd = ((void **)data)[2]; + GladeXML *x = ((void **)data)[3]; + char *path = ((void **)data)[4]; + + free(data); + + gtk_widget_destroy(GTK_WIDGET(wnd)); + g_object_unref(G_OBJECT(x)); + + save_pdf(path); +} diff --git a/gtk/gtk_gui.h b/gtk/gtk_gui.h index 39d4d5f16..e7cd8a1f9 100644 --- a/gtk/gtk_gui.h +++ b/gtk/gtk_gui.h @@ -25,6 +25,7 @@ extern GladeXML *gladeWindows; extern char *glade_file_location; extern char *options_file_location; extern char *res_dir_location; +extern char *print_options_file_location; extern GtkWindow *wndAbout; diff --git a/gtk/gtk_print.c b/gtk/gtk_print.c index 6f1bf976c..5828ead75 100644 --- a/gtk/gtk_print.c +++ b/gtk/gtk_print.c @@ -242,7 +242,7 @@ bool nsgtk_print_plot_clip(int clip_x0, int clip_y0, 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; } @@ -411,7 +411,6 @@ void nsgtk_print_set_colour(colour c) 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); @@ -505,28 +504,25 @@ static void gtk_print_end() * \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 = user_data; - 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->scale = 0.7;/*at 0.7 the pages look the best*/ settings->font_func = &nsfont; print_set_up(content_to_print, >k_printer, settings, &height_to_print); @@ -542,15 +538,13 @@ void gtk_print_signal_begin_print (GtkPrintOperation *operation, 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, @@ -564,13 +558,12 @@ void gtk_print_signal_draw_page(GtkPrintOperation *operation, /** 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, >k_printer); + print_cleanup(content_to_print, >k_printer, user_data); } #endif /* WITH_PDF_EXPORT */ diff --git a/gtk/gtk_print.h b/gtk/gtk_print.h index b232920de..d2b89b92d 100644 --- a/gtk/gtk_print.h +++ b/gtk/gtk_print.h @@ -33,16 +33,16 @@ 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); + GtkPrintContext *context, + gpointer user_data); void gtk_print_signal_draw_page(GtkPrintOperation *operation, - GtkPrintContext *context, - gint page_nr, - gpointer user_data); + GtkPrintContext *context, + gint page_nr, + gpointer user_data); void gtk_print_signal_end_print(GtkPrintOperation *operation, - GtkPrintContext *context, - gpointer user_data); + GtkPrintContext *context, + gpointer user_data); #endif diff --git a/gtk/gtk_scaffolding.c b/gtk/gtk_scaffolding.c index df1ea68b7..c2f546ec0 100644 --- a/gtk/gtk_scaffolding.c +++ b/gtk/gtk_scaffolding.c @@ -43,15 +43,17 @@ #include "gtk/gtk_window.h" #include "gtk/gtk_schedule.h" #include "gtk/gtk_download.h" +#include "gtk/options.h" #include "render/box.h" #include "render/font.h" #include "render/form.h" #include "render/html.h" #include "utils/messages.h" #include "utils/utils.h" +#include "utils/url.h" -#include "pdf/pdf_plotters.h" #include "desktop/print.h" +#include "desktop/save_pdf/pdf_plotters.h" #ifdef WITH_PDF_EXPORT #include "gtk/gtk_print.h" #endif @@ -146,7 +148,6 @@ MENUPROTO(open_location); MENUPROTO(open_file); MENUPROTO(export_pdf); MENUPROTO(print); -MENUPROTO(print_preview); MENUPROTO(close_window); MENUPROTO(quit); @@ -193,7 +194,6 @@ static struct menu_events menu_events[] = { #ifdef WITH_PDF_EXPORT MENUEVENT(export_pdf), MENUEVENT(print), - MENUEVENT(print_preview), #endif MENUEVENT(close_window), MENUEVENT(quit), @@ -489,10 +489,25 @@ MENUHANDLER(export_pdf){ struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level); struct print_settings* settings; + char filename[PATH_MAX]; + char dirname[PATH_MAX]; + char *url_name; LOG(("Print preview (generating PDF) started.")); - settings = print_make_settings(DEFAULT); + url_nice(bw->current_content->url, &url_name, true); + strcat(filename, url_name); + strcat(filename, ".pdf"); + + free(url_name); + + strcpy(dirname, option_downloads_directory); + strcat(dirname, "/"); + + settings = print_make_settings(OPTIONS, NULL); + /*this way the scale used by PDF functions is synchronized with that + used by the all-purpose print interface*/ + pdf_set_scale((float)option_export_scale / 100); save_dialog = gtk_file_chooser_dialog_new("Export to PDF", gw->window, GTK_FILE_CHOOSER_ACTION_SAVE, @@ -501,10 +516,10 @@ MENUHANDLER(export_pdf){ NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog), - getenv("HOME") ? getenv("HOME") : "/"); - + dirname); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog), - "out.pdf"); + filename); if (gtk_dialog_run(GTK_DIALOG(save_dialog)) == GTK_RESPONSE_ACCEPT) { settings->output = gtk_file_chooser_get_filename( @@ -512,7 +527,7 @@ MENUHANDLER(export_pdf){ } gtk_widget_destroy(save_dialog); - + print_basic_run(bw->current_content, &pdf_printer, settings); return TRUE; @@ -525,44 +540,49 @@ MENUHANDLER(print){ GtkPrintOperation* print_op; GtkPageSetup* page_setup; - struct print_settings* settings; - - settings = print_make_settings(DEFAULT); + GtkPrintSettings* gtk_print_settings; + GtkPrintOperationResult res; + struct print_settings *settings; print_op = gtk_print_operation_new(); page_setup = gtk_page_setup_new(); + /*use previously saved settings if any*/ + gtk_print_settings = gtk_print_settings_new_from_file(print_options_file_location, NULL); + if (gtk_print_settings != NULL) + gtk_print_operation_set_print_settings(print_op, + gtk_print_settings); + 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); + settings = print_make_settings(DEFAULT, NULL); + + g_signal_connect(print_op, "begin_print", G_CALLBACK (gtk_print_signal_begin_print), settings); 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); + g_signal_connect(print_op, "end_print", G_CALLBACK (gtk_print_signal_end_print), settings); - gtk_print_operation_run(print_op, + res = gtk_print_operation_run(print_op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, gw->window, NULL); + /*if the settings were used save them for future use*/ + if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { + if (gtk_print_settings != NULL) + g_object_unref(gtk_print_settings); + gtk_print_settings = g_object_ref( + gtk_print_operation_get_print_settings(print_op)); + gtk_print_settings_to_file(gtk_print_settings, + print_options_file_location ,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; -} - #endif /* WITH_PDF_EXPORT */ MENUHANDLER(close_window) @@ -1142,7 +1162,6 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) #ifndef WITH_PDF_EXPORT gtk_widget_set_sensitive(GET_WIDGET("export_pdf"), FALSE); gtk_widget_set_sensitive(GET_WIDGET("print"), FALSE); - gtk_widget_set_sensitive(GET_WIDGET("print_preview"), FALSE); #endif /* finally, show the window. */ diff --git a/gtk/res/netsurf.glade b/gtk/res/netsurf.glade index f250be753..48084e555 100644 --- a/gtk/res/netsurf.glade +++ b/gtk/res/netsurf.glade @@ -165,14 +165,14 @@ <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> - <child internal-child="image"> + <accelerator key="P" signal="activate" modifiers="GDK_CONTROL_MASK"/> + <child internal-child="image"> <widget class="GtkImage" id="image559"> <property name="visible">True</property> <property name="stock">gtk-print</property> <property name="icon_size">1</property> </widget> </child> - <accelerator key="P" signal="activate" modifiers="GDK_CONTROL_MASK"/> </widget> </child> <child> @@ -1662,4 +1662,275 @@ </widget> </child> </widget> + <widget class="GtkWindow" id="wndPDFPassword"> + <property name="title" translatable="yes">PDF Password</property> + <property name="modal">True</property> + <property name="window_position">GTK_WIN_POS_CENTER</property> + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <child> + <widget class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="yalign">0.10000000149011612</property> + <property name="xpad">12</property> + <property name="icon_size">6</property> + <property name="icon_name">gtk-dialog-authentication</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="border_width">5</property> + <child> + <widget class="GtkLabel" id="labelInfo"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Write and confirm passwords:</property> + </widget> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="border_width">5</property> + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Owner password:</property> + <property name="width_chars">15</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryPDFOwnerPassword"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="max_length">20</property> + <property name="visibility">False</property> + <property name="width_chars">20</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox3"> + <property name="visible">True</property> + <property name="border_width">5</property> + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes">Repeat password:</property> + <property name="width_chars">15</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryPDFOwnerPassword1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="max_length">20</property> + <property name="visibility">False</property> + <property name="width_chars">20</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox4"> + <property name="visible">True</property> + <property name="border_width">5</property> + <child> + <widget class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="label" translatable="yes">User password:</property> + <property name="width_chars">15</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryPDFUserPassword"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="max_length">20</property> + <property name="visibility">False</property> + <property name="width_chars">20</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox5"> + <property name="visible">True</property> + <property name="border_width">5</property> + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes">Repeat password:</property> + <property name="width_chars">15</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="entryPDFUserPassword1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="max_length">20</property> + <property name="visibility">False</property> + <property name="width_chars">20</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> + </packing> + </child> + <child> + <widget class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="border_width">5</property> + <property name="spacing">10</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + <child> + <widget class="GtkButton" id="buttonPDFSetPassword"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="response_id">0</property> + <child> + <widget class="GtkHBox" id="hbox7"> + <property name="visible">True</property> + <child> + <widget class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="stock">gtk-ok</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes">Set password</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkButton" id="buttonPDFNoPassword"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="response_id">0</property> + <child> + <widget class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <child> + <widget class="GtkHBox" id="hbox6"> + <property name="visible">True</property> + <child> + <widget class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="stock">gtk-cancel</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes">No password</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">5</property> + </packing> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> </glade-interface> diff --git a/gtk/res/options.glade b/gtk/res/options.glade index d3f5eaca8..e13d492b3 100644 --- a/gtk/res/options.glade +++ b/gtk/res/options.glade @@ -1565,6 +1565,435 @@ Fantasy</property> <property name="tab_fill">False</property> </packing> </child> + <child> + <widget class="GtkVBox" id="vbox5"> + <property name="visible">True</property> + <child> + <widget class="GtkFrame" id="frame2"> + <property name="visible">True</property> + <property name="border_width">5</property> + <property name="label_xalign">0</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <child> + <widget class="GtkAlignment" id="alignment2"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkHBox" id="hbox4"> + <property name="visible">True</property> + <property name="homogeneous">True</property> + <child> + <widget class="GtkTable" id="table1"> + <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">3</property> + <property name="column_spacing">4</property> + <property name="row_spacing">5</property> + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes">Top:</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes">Bottom:</property> + </widget> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="spinMarginTop"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Set the top margin</property> + <property name="adjustment">0 0 100 1 10 10</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="spinMarginBottom"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Set the bottom margin</property> + <property name="adjustment">0 0 100 1 10 10</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label9"> + <property name="visible">True</property> + <property name="label" translatable="yes">mm</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label10"> + <property name="visible">True</property> + <property name="label" translatable="yes">mm</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + <child> + <widget class="GtkTable" id="table2"> + <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">3</property> + <property name="column_spacing">4</property> + <property name="row_spacing">5</property> + <child> + <widget class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="label" translatable="yes">Left:</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="label" translatable="yes">Right:</property> + </widget> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="spinMarginLeft"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Set the left margin</property> + <property name="adjustment">0 0 100 1 10 10</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="spinMarginRight"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Set the right margin</property> + <property name="adjustment">0 0 100 1 10 10</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label11"> + <property name="visible">True</property> + <property name="label" translatable="yes">mm</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label12"> + <property name="visible">True</property> + <property name="label" translatable="yes">mm</property> + </widget> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="frame"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Margins</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> + <widget class="GtkFrame" id="frame3"> + <property name="visible">True</property> + <property name="border_width">5</property> + <property name="label_xalign">0</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <child> + <widget class="GtkAlignment" id="alignment3"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkHBox" id="hbox5"> + <property name="visible">True</property> + <property name="spacing">4</property> + <child> + <widget class="GtkLabel" id="label14"> + <property name="visible">True</property> + <property name="label" translatable="yes">Scale:</property> + </widget> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> + <widget class="GtkSpinButton" id="spinExportScale"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Set the scaling for the document - this way more content can fit in a page</property> + <property name="adjustment">0 0 1000 1 10 10</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label15"> + <property name="visible">True</property> + <property name="label" translatable="yes">%</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label13"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Scaling</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkFrame" id="frame4"> + <property name="visible">True</property> + <property name="border_width">5</property> + <property name="label_xalign">0</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <child> + <widget class="GtkAlignment" id="alignment4"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <child> + <widget class="GtkCheckButton" id="checkSuppressImages"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Turn off all images</property> + <property name="label" translatable="yes">Suppress images</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + </widget> + </child> + <child> + <widget class="GtkCheckButton" id="checkRemoveBackgrounds"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Remove background images and colors</property> + <property name="label" translatable="yes">Remove backgrounds</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkCheckButton" id="checkFitPage"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Try to rearrange content to fit a page</property> + <property name="label" translatable="yes">Fit page</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="position">2</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label16"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Appearance</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <widget class="GtkFrame" id="frame5"> + <property name="visible">True</property> + <property name="border_width">5</property> + <property name="label_xalign">0</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <child> + <widget class="GtkAlignment" id="alignment5"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkVBox" id="vbox7"> + <property name="visible">True</property> + <child> + <widget class="GtkCheckButton" id="checkCompressPDF"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Compress the PDF document significantly decreasing it's size</property> + <property name="label" translatable="yes">Compress PDF</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + </widget> + </child> + <child> + <widget class="GtkCheckButton" id="checkPasswordPDF"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup">Set a password and encrypt the PDF document</property> + <property name="label" translatable="yes">Set a password for PDF</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label17"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Advanced</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox7"> + <property name="visible">True</property> + <property name="border_width">10</property> + <child> + <widget class="GtkButton" id="setDefaultExportOptions"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip" translatable="yes">Reset export settings to defaults</property> + <property name="receives_default">True</property> + <property name="label" translatable="yes">Default</property> + <property name="response_id">0</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">4</property> + </packing> + </child> + </widget> + <packing> + <property name="position">6</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="label" translatable="yes">Export</property> + </widget> + <packing> + <property name="type">tab</property> + <property name="position">6</property> + <property name="tab_fill">False</property> + </packing> + </child> </widget> <packing> <property name="position">1</property> diff --git a/pdf/pdf_printer.h b/pdf/pdf_printer.h deleted file mode 100644 index a8d7d7466..000000000 --- a/pdf/pdf_printer.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - * PDF Plotter and flow manipulating functions combined as a printer -*/ - -#ifndef NETSURF_PDF_PRINTER_H -#define NETSURF_PDF_PRINTER_H - -#include "desktop/printer.h" -#include "pdf/pdf_plotters.h" - -struct printer pdf_printer= { - &pdf_plotters, - pdf_begin, - pdf_next_page, - pdf_end -}; - -#endif diff --git a/render/box.c b/render/box.c index d248f60d4..ef8b43310 100644 --- a/render/box.c +++ b/render/box.c @@ -28,6 +28,7 @@ #include <string.h> #include "content/content.h" #include "css/css.h" +#include "desktop/options.h" #include "render/box.h" #include "render/form.h" #include "utils/log.h" @@ -38,6 +39,12 @@ static bool box_contains_point(struct box *box, int x, int y); #define box_is_float(box) (box->type == BOX_FLOAT_LEFT || \ box->type == BOX_FLOAT_RIGHT) +typedef struct box_duplicate_llist box_duplicate_llist; +struct box_duplicate_llist { + struct box_duplicate_llist *prev; + struct box *box; +}; +static struct box_duplicate_llist *box_duplicate_last = NULL; /** * Create a box tree node. @@ -86,6 +93,7 @@ struct box * box_create(struct css_style *style, box->columns = 1; box->rows = 1; box->start_column = 0; + box->printed = false; box->next = NULL; box->prev = NULL; box->children = NULL; @@ -107,7 +115,6 @@ struct box * box_create(struct css_style *style, return box; } - /** * Add a child to a box tree node. * @@ -679,6 +686,8 @@ struct box* box_duplicate_tree(struct box *root, struct content *c) int box_number = 0; struct box_dict_element *box_dict, *box_dict_end; + box_duplicate_last = NULL; + /* 1. Duplicate parent - children structure, list_markers*/ new_root = talloc_memdup(c, root, sizeof (struct box)); if (!box_duplicate_main_tree(new_root, c, &box_number)) @@ -720,12 +729,13 @@ struct box* box_duplicate_tree(struct box *root, struct content *c) */ bool box_duplicate_main_tree(struct box *box, struct content *c, int *count) { - - struct box *b, *prev, *copy; + struct box *b, *prev; prev = NULL; for (b = box->children; b; b = b->next) { + struct box *copy; + /*Copy child*/ copy = talloc_memdup(c, b, sizeof (struct box)); if (copy == NULL) @@ -738,14 +748,74 @@ bool box_duplicate_main_tree(struct box *box, struct content *c, int *count) else box->children = copy; + if (copy->type == BOX_INLINE) { + struct box_duplicate_llist *temp; + + temp = malloc(sizeof(struct box_duplicate_llist)); + if (temp == NULL) + return false; + temp->prev = box_duplicate_last; + temp->box = copy; + box_duplicate_last = temp; + } + else if (copy->type == BOX_INLINE_END) { + struct box_duplicate_llist *temp; + + box_duplicate_last->box->inline_end = copy; + copy->inline_end = box_duplicate_last->box; + + temp = box_duplicate_last; + box_duplicate_last = temp->prev; + free(temp); + } + /* Recursively visit child */ - box_duplicate_main_tree(copy, c, count); + if (!box_duplicate_main_tree(copy, c, count)) + return false; prev = copy; } box->last = prev; + if (box->object && option_suppress_images && ( +#ifdef WITH_JPEG + box->object->type == CONTENT_JPEG || +#endif +#ifdef WITH_GIF + box->object->type == CONTENT_GIF || +#endif +#ifdef WITH_BMP + box->object->type == CONTENT_BMP || + box->object->type == CONTENT_ICO || +#endif +#ifdef WITH_MNG + box->object->type == CONTENT_PNG || + box->object->type == CONTENT_JNG || + box->object->type == CONTENT_MNG || +#endif +#if defined(WITH_SPRITE) || defined(WITH_NSSPRITE) + box->object->type == CONTENT_SPRITE || +#endif +#ifdef WITH_DRAW + box->object->type == CONTENT_DRAW || +#endif +#ifdef WITH_PLUGIN + box->object->type == CONTENT_PLUGIN || +#endif + box->object->type == CONTENT_DIRECTORY || +#ifdef WITH_THEME_INSTALL + box->object->type == CONTENT_THEME || +#endif +#ifdef WITH_ARTWORKS + box->object->type == CONTENT_ARTWORKS || +#endif +#if defined(WITH_NS_SVG) || defined(WITH_RSVG) + box->object->type == CONTENT_SVG || +#endif + false)) + box->object = NULL; + if (box->list_marker) { box->list_marker = talloc_memdup(c, box->list_marker, sizeof *box->list_marker); diff --git a/render/box.h b/render/box.h index a670fddb5..c1cce449f 100644 --- a/render/box.h +++ b/render/box.h @@ -189,6 +189,8 @@ struct box { unsigned int rows; /**< Number of rows for TABLE only. */ unsigned int start_column; /**< Start column for TABLE_CELL only. */ + bool printed; /** Whether this box has already been printed*/ + struct box *next; /**< Next sibling box, or 0. */ struct box *prev; /**< Previous sibling box, or 0. */ struct box *children; /**< First child box, or 0. */ diff --git a/render/html_redraw.c b/render/html_redraw.c index 51bcceb8f..d76f0d9bd 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -38,6 +38,7 @@ #include "desktop/selection.h" #include "desktop/textinput.h" #include "desktop/options.h" +#include "desktop/print.h" #include "render/box.h" #include "render/font.h" #include "render/form.h" @@ -173,6 +174,9 @@ bool html_redraw_box(struct box *box, int x0, y0, x1, y1; int x_scrolled, y_scrolled; struct box *bg_box = NULL; + + if (html_redraw_printing && box->printed) + return true; /* avoid trivial FP maths */ if (scale == 1.0) { @@ -227,6 +231,23 @@ bool html_redraw_box(struct box *box, if (clip_y1 < y0 || y1 < clip_y0 || clip_x1 < x0 || x1 < clip_x0) return true; + /*if the rectangle is under the page bottom but it can fit in a page, + don't print it now*/ + if (html_redraw_printing) + if (y1 > html_redraw_printing_border) { + if (y1 - y0 <= html_redraw_printing_border && + (box->type == BOX_TEXT || + box->type == BOX_TABLE_CELL + || box->object || box->gadget)) { + /*remember the highest of all points from the + not printed elements*/ + if (y0 < html_redraw_printing_top_cropped) + html_redraw_printing_top_cropped = y0; + return true; + } + } + else box->printed = true;/*it won't be printed anymore*/ + /* if visibility is hidden render children only */ if (box->style && box->style->visibility == CSS_VISIBILITY_HIDDEN) { if ((plot.group_start) && (!plot.group_start("hidden box"))) @@ -296,74 +317,78 @@ bool html_redraw_box(struct box *box, * element is processed, ignore the background. * + For any other box, just use its own styling. */ - if (!box->parent) { - /* Root box */ - if (box->style && - (box->style->background_color != TRANSPARENT || - box->background)) { - /* With its own background */ - bg_box = box; - } else if (!box->style || - (box->style->background_color == TRANSPARENT && - !box->background)) { - /* Without its own background */ - if (box->children && box->children->style && - (box->children->style->background_color != - TRANSPARENT || - box->children->background)) { - /* But body has one, so use that */ - bg_box = box->children; - } - } - } else if (box->parent && !box->parent->parent) { - /* Body box */ - if (box->style && - (box->style->background_color != TRANSPARENT || - box->background)) { - /* With a background */ - if (box->parent->style && - (box->parent->style->background_color != - TRANSPARENT || - box->parent->background)) { - /* Root has own background; process normally */ + + if (!html_redraw_printing || + (html_redraw_printing && !option_remove_backgrounds)) { + if (!box->parent) { + /* Root box */ + if (box->style && + (box->style->background_color != TRANSPARENT || + box->background)) { + /* With its own background */ bg_box = box; + } else if (!box->style || + (box->style->background_color == TRANSPARENT && + !box->background)) { + /* Without its own background */ + if (box->children && box->children->style && + (box->children->style->background_color != + TRANSPARENT || + box->children->background)) { + /* But body has one, so use that */ + bg_box = box->children; + } + } + } else if (box->parent && !box->parent->parent) { + /* Body box */ + if (box->style && + (box->style->background_color != TRANSPARENT || + box->background)) { + /* With a background */ + if (box->parent->style && + (box->parent->style->background_color != + TRANSPARENT || + box->parent->background)) { + /* Root has own background; process normally */ + bg_box = box; + } } + } else { + /* Any other box */ + bg_box = box; } - } else { - /* Any other box */ - bg_box = box; - } - - /* bg_box == NULL implies that this box should not have - * its background rendered. Otherwise filter out linebreaks, - * optimize away non-differing inlines, only plot background - * for BOX_TEXT it's in an inline and ensure the bg_box - * has something worth rendering */ - if (bg_box && (bg_box->style && bg_box->type != BOX_BR && - (bg_box->type != BOX_INLINE || - bg_box->style != bg_box->parent->parent->style)) && - (bg_box->type != BOX_TEXT || - (bg_box->type == BOX_TEXT && inline_depth > 0)) && - ((bg_box->style->background_color != TRANSPARENT) || - (bg_box->background))) { - /* find intersection of clip box and border edge */ - int px0 = x - border_left < x0 ? x0 : x - border_left; - int py0 = y - border_top < y0 ? y0 : y - border_top; - int px1 = x + padding_width + border_right < x1 ? - x + padding_width + border_right : x1; - int py1 = y + padding_height + border_bottom < y1 ? - y + padding_height + border_bottom : y1; - - /* valid clipping rectangles only */ - if ((px0 < px1) && (py0 < py1)) { - /* plot background */ - if (!html_redraw_background(x, y, box, scale, - px0, py0, px1, py1, - ¤t_background_color, bg_box)) - return false; - /* restore previous graphics window */ - if (!plot.clip(x0, y0, x1, y1)) - return false; + + /* bg_box == NULL implies that this box should not have + * its background rendered. Otherwise filter out linebreaks, + * optimize away non-differing inlines, only plot background + * for BOX_TEXT it's in an inline and ensure the bg_box + * has something worth rendering */ + if (bg_box && (bg_box->style && bg_box->type != BOX_BR && + (bg_box->type != BOX_INLINE || + bg_box->style != bg_box->parent->parent->style)) && + (bg_box->type != BOX_TEXT || + (bg_box->type == BOX_TEXT && inline_depth > 0)) && + ((bg_box->style->background_color != TRANSPARENT) || + (bg_box->background))) { + /* find intersection of clip box and border edge */ + int px0 = x - border_left < x0 ? x0 : x - border_left; + int py0 = y - border_top < y0 ? y0 : y - border_top; + int px1 = x + padding_width + border_right < x1 ? + x + padding_width + border_right : x1; + int py1 = y + padding_height + border_bottom < y1 ? + y + padding_height + border_bottom : y1; + + /* valid clipping rectangles only */ + if ((px0 < px1) && (py0 < py1)) { + /* plot background */ + if (!html_redraw_background(x, y, box, scale, + px0, py0, px1, py1, + ¤t_background_color, bg_box)) + return false; + /* restore previous graphics window */ + if (!plot.clip(x0, y0, x1, y1)) + return false; + } } } @@ -1419,7 +1444,10 @@ bool html_redraw_text_decoration(struct box *box, unsigned int i; /* antialias colour for under/overline */ - colour = html_redraw_aa(background_colour, box->style->color); + if (html_redraw_printing) + colour = box->style->color; + else + colour = html_redraw_aa(background_colour, box->style->color); if (box->type == BOX_INLINE) { if (!box->inline_end) diff --git a/render/layout.c b/render/layout.c index 1469a3484..252b17429 100644 --- a/render/layout.c +++ b/render/layout.c @@ -88,8 +88,6 @@ static void place_float_below(struct box *c, int width, int cx, int y, struct box *cont); static bool layout_table(struct box *box, int available_width, struct content *content); -static void layout_minmax_table(struct box *table, - const struct font_functions *font_func); static void layout_move_children(struct box *box, int x, int y); static void calculate_mbp_width(struct css_style *style, unsigned int side, int *fixed, float *frac); diff --git a/render/layout.h b/render/layout.h index 808191a6c..40504624d 100644 --- a/render/layout.h +++ b/render/layout.h @@ -36,5 +36,6 @@ bool layout_block_context(struct box *block, struct content *content); bool layout_inline_container(struct box *box, int width, struct box *cont, int cx, int cy, struct content *content); void layout_calculate_descendant_bboxes(struct box *box); - +void layout_minmax_table(struct box *table, + const struct font_functions *font_func); #endif diff --git a/render/loosen.c b/render/loosen.c index a6f3053ff..88f89a1c6 100644 --- a/render/loosen.c +++ b/render/loosen.c @@ -23,13 +23,15 @@ #include "render/box.h" #include "render/font.h" + +#include "render/layout.h" #include "render/loosen.h" #include "utils/log.h" #include "utils/talloc.h" #define AUTO INT_MIN - +#define LOOSEN_MIN_TEXT_SIZE 10 static bool loosen_text(struct box *text, int width, struct content *content); @@ -45,8 +47,10 @@ static bool loosen_all_first_pass(struct box *box, int width, int cx, struct content *content); static bool loosen_all_second_pass(struct box *box, int width, int cx, struct content *content); -static bool loosen_all_third_pass(struct box *box, int width, int cx, +static bool loosen_all_margins_paddings(struct box *box, int width, int cx, struct content *content); + +static bool loosen_shrink_text(struct box *box); /** * Main loosing procedure @@ -84,7 +88,7 @@ bool loosen_document_layout(struct content *content, struct box *layout, } if (content->width > width) { - if (!loosen_all_third_pass(layout, width, 0, content)) + if (!loosen_all_margins_paddings(layout, width, 0, content)) return false; layout->min_width = 0; layout->max_width = UNKNOWN_MAX_WIDTH; @@ -166,6 +170,9 @@ bool loosen_text(struct box *text, int width, struct content *content) /** * Changing table layout and structure to fit the contents width. + * Firstly the borders are collapsed and the text is shrunken. + * Secondly the text is loosened( this can be helpful for all data tables which + * contain only text) * In the most extreme case - the table has no influence on the width * (each row is broken into one-cell rows). * \param table - the box that contains table to be broken @@ -177,9 +184,66 @@ bool loosen_table(struct box *table, int width, struct content *content) { struct box *row_group, *row, *cell, *br, *prev, *inline_container; + struct box *text, *child; + unsigned int row_sum; + bool first_cell_in_row; + const struct font_functions *font_func; + float scale; + int new_width; + if (table->min_width <= width) - return true; + return true; + if (content->type == CONTENT_HTML) + font_func = content->data.html.font_func; + else + return false; + + table->style->border_collapse = CSS_BORDER_COLLAPSE_COLLAPSE; + + if (!loosen_shrink_text(table)) + return false; + + if (!loosen_all_margins_paddings(table, width, 0, content)) + return false; + + scale = width; + scale /= table->min_width; + + for (row_group = table->children; row_group; + row_group = row_group->next) { + for (row = row_group->children; row; row = row->next) { + for (cell = row->children; cell; cell = cell->next) { + for (child = cell->children; child; + child = child->next) { + if (child->children) + text = child->children; + else + continue; + + /*text in nested boxes won't be broken*/ + if (text->type != BOX_TEXT) + continue; + + + /*break the words propotionally to the + current cell width*/ + new_width = (float)cell->width * scale * 0.9; + loosen_text(text, new_width, content); + } + } + } + } + + + /*check if the table is loosend enough...*/ + layout_minmax_table(table, font_func); + if (table->min_width <= width) + return true; + + + /*...in case it's not continue with bigger changes, + table cells are changed into inline containers*/ inline_container = box_create(0, 0, 0, 0, 0, content); inline_container->type = BOX_INLINE_CONTAINER; inline_container->parent = table; @@ -232,6 +296,31 @@ bool loosen_table(struct box *table, int width, struct content *content) return true; } +/** +* Recursively step through the box tree applying LOOSEN_MIN_TEXT_SIZE wherever +* text is found +* \param box the box where the shrinking should be started +* \return true if successful, false otherwise +*/ +bool loosen_shrink_text(struct box *box) +{ + struct box *child; + + box->max_width = UNKNOWN_MAX_WIDTH; + + if (box->type == BOX_TEXT) { + box->style->font_size.size = CSS_FONT_SIZE_LENGTH; + box->style->font_size.value.length.unit = CSS_UNIT_PX; + box->style->font_size.value.length.value = LOOSEN_MIN_TEXT_SIZE; + } + else if (box->children) + for(child = box->children; child; child = child->next) + if (!loosen_shrink_text(child)) + return false; + + return true; +} + /** * Change absolute and relative positioned elements into block elements @@ -352,6 +441,8 @@ bool loosen_all_second_pass(struct box *box, int width, int cx, if (!loosen_table(c, width, content)) return false; break; + default: + break; } c->min_width = 0; @@ -370,7 +461,7 @@ bool loosen_all_second_pass(struct box *box, int width, int cx, * \param content talloc memory pool for new boxes * \return true if successful, false otherwise */ -bool loosen_all_third_pass(struct box *box, int width, int cx, +bool loosen_all_margins_paddings(struct box *box, int width, int cx, struct content *content) { struct box *c; @@ -379,7 +470,7 @@ bool loosen_all_third_pass(struct box *box, int width, int cx, for (c = box->children; c; c = c->next) { x = cx + c->x; if (c->children != NULL) - if (!loosen_all_third_pass(c, width, x, content)) + if (!loosen_all_margins_paddings(c, width, x, content)) return false; c->padding[LEFT] = c->padding[RIGHT] = 0; diff --git a/riscos/gui.c b/riscos/gui.c index 3f7a60527..5ff558f5d 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -2399,3 +2399,9 @@ bool ro_gui_prequit(void) { return ro_gui_download_prequit(); } + +void PDF_Password(char **owner_pass, char **user_pass, char *path) +{ + /*TODO:this waits to be written, until then no PDF encryption*/ + *owner_pass = NULL; +} diff --git a/riscos/save_pdf.c b/riscos/save_pdf.c index 2a31b1edb..456161692 100644 --- a/riscos/save_pdf.c +++ b/riscos/save_pdf.c @@ -27,7 +27,7 @@ #include "oslib/osfile.h" #include "content/content.h" #include "desktop/print.h" -#include "pdf/pdf_plotters.h" +#include "desktop/save_pdf/pdf_plotters.h" #include "riscos/save_pdf.h" #include "utils/log.h" #include "utils/config.h" @@ -42,12 +42,11 @@ bool save_as_pdf(struct content *c, const char *path) { struct print_settings *psettings; - - psettings = print_make_settings(DEFAULT); + + psettings = print_make_settings(DEFAULT, path); if (psettings == NULL) return false; - psettings->output = path; if (!print_basic_run(c, &pdf_printer, psettings)) return false; xosfile_set_type(path, 0xadf); diff --git a/testres/jpeg.jpeg b/testres/jpeg.jpeg Binary files differdeleted file mode 100644 index 636127f1f..000000000 --- a/testres/jpeg.jpeg +++ /dev/null diff --git a/testres/png.png b/testres/png.png Binary files differdeleted file mode 100644 index 14e10d224..000000000 --- a/testres/png.png +++ /dev/null diff --git a/testres/text.html b/testres/text.html deleted file mode 100644 index 8b22fcf78..000000000 --- a/testres/text.html +++ /dev/null @@ -1,68 +0,0 @@ -<html> -<head> - <title>Sample page with lots of text</title> -</head> -<body style='font-size:14pt;background-color:#CCFFCC;'> -<br><br><br><br><br><br><br><br> -This demonstrates the fuzzy margin at the bottom. After pdf-printing this page, -we can see the bottoms of letters printed just below the lower margin of this page. -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -a1312312312312dadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -a1312312312312dadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -a1312312312312dadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -a1312312312312dadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds - -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -asdadadafgsdsgsdfsdfsdfgdbbdfbxccvsds -</body> -</html>
\ No newline at end of file diff --git a/testres/text2.html b/testres/text2.html deleted file mode 100644 index 07992a86e..000000000 --- a/testres/text2.html +++ /dev/null @@ -1,29 +0,0 @@ -<html> -<head> - <title>Sample page with some text</title> - <style type="text/css"> - td {border: 2px;} - a { font-family: monospace; - font-weight: bold; - font-style: italic - } - body {font-style: oblique} - </style> -</head> -<body style='font-size:13pt;background-color:#CCFFCC;'> -<a href='http://www.google.co.uk/search?hl=en&q=making+a+very+long+hyperlink+to+demonstrate+how+it+will+be+broken+&btnG=Search&meta='> -http://www.google.co.uk/search?hl=en&q=making+a+very+long+hyperlink+to+demonstrate+how+it+will+be+broken+&btnG=Search&meta=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssss</a> -a1312312312312dadadafgsdsgsdddddddddddddddddddddddddddddfsdfsdfgdbbdfbxccvsdsddddddddddd -12345678901011121314151617181920212223242526272829303132333435363738394041424344454647484950 -<table border=5> -<tr> -<td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</td> -<td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</td> -</tr> -<tr> -<td>bbbbbbbbbbbbbbbb</td> -<td>bbbbbbbbbbbbbb</td> -</tr> -</table> -</body> -</html>
\ No newline at end of file diff --git a/utils/utils.h b/utils/utils.h index fc4479d8e..e286de76f 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -105,5 +105,6 @@ void warn_user(const char *warning, const char *detail); query_id query_user(const char *query, const char *detail, const query_callback *cb, void *pw, const char *yes, const char *no); void query_close(query_id); +void PDF_Password(char **owner_pass, char **user_pass, char *path); #endif |