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
This commit is contained in:
John Tytgat 2008-08-14 20:32:10 +00:00
parent 44856d86d4
commit e063a2a59d
33 changed files with 1559 additions and 422 deletions

View File

@ -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

View File

@ -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
};

View File

@ -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;

View File

@ -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;
settings->margins[MARGINLEFT] = 30;
settings->margins[MARGINRIGHT] = 30;
settings->margins[MARGINTOP] = 30;
settings->margins[MARGINBOTTOM] = 30;
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->font_func = &haru_nsfont;
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->margins[MARGINTEXT] = 10;
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;
}

View File

@ -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);
struct print_settings *print_make_settings(print_configuration configuration,
const char *url);
/*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

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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*/

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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, &gtk_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, &gtk_printer);
print_cleanup(content_to_print, &gtk_printer, user_data);
}
#endif /* WITH_PDF_EXPORT */

View File

@ -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

View File

@ -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. */

View File

@ -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>

View File

@ -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">&lt;b&gt;Margins&lt;/b&gt;</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">&lt;b&gt;Scaling&lt;/b&gt;</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">&lt;b&gt;Appearance&lt;/b&gt;</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">&lt;b&gt;Advanced&lt;/b&gt;</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>

View File

@ -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

View File

@ -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);

View File

@ -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. */

View File

@ -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,
&current_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,
&current_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)

View File

@ -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);

View File

@ -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

View File

@ -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;
if (table->min_width <= width)
return true;
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;
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;

View File

@ -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;
}

View File

@ -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);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -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>

View File

@ -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>

View File

@ -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