diff --git a/src/BackgroundRenderer/CairoBackgroundRenderer.cc b/src/BackgroundRenderer/CairoBackgroundRenderer.cc
index 074e4c1..c92703b 100644
--- a/src/BackgroundRenderer/CairoBackgroundRenderer.cc
+++ b/src/BackgroundRenderer/CairoBackgroundRenderer.cc
@@ -15,12 +15,28 @@
#if ENABLE_SVG
#include "CairoBackgroundRenderer.h"
+#include "SplashBackgroundRenderer.h"
namespace pdf2htmlEX {
using std::string;
using std::ifstream;
+CairoBackgroundRenderer::CairoBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param)
+ : CairoOutputDev()
+ , html_renderer(html_renderer)
+ , param(param)
+ , surface(nullptr)
+ , use_bitmap(false)
+{
+ if (param.svg_nodes_limit > 0)
+ {
+ this->bitmap_renderer = new SplashBackgroundRenderer(html_renderer, param);
+ }
+ else
+ this->bitmap_renderer = nullptr;
+}
+
void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
@@ -46,6 +62,8 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
void CairoBackgroundRenderer::init(PDFDoc * doc)
{
startDoc(doc);
+ if (this->bitmap_renderer != nullptr)
+ this->bitmap_renderer->init(doc);
}
static GBool annot_cb(Annot *, void * pflag) {
@@ -67,13 +85,11 @@ void CairoBackgroundRenderer::render_page(PDFDoc * doc, int pageno)
page_height = doc->getPageMediaHeight(pageno);
}
- {
- auto fn = html_renderer->str_fmt("%s/bg%x.svg", (param.embed_image ? param.tmp_dir : param.dest_dir).c_str(), pageno);
- if(param.embed_image)
- html_renderer->tmp_files.add((char*)fn);
+ auto fn = html_renderer->str_fmt("%s/bg%x.svg", (param.embed_image ? param.tmp_dir : param.dest_dir).c_str(), pageno);
+ if(param.embed_image)
+ html_renderer->tmp_files.add((char*)fn);
- surface = cairo_svg_surface_create((char*)fn, page_width * param.h_dpi / DEFAULT_DPI, page_height * param.v_dpi / DEFAULT_DPI);
- }
+ surface = cairo_svg_surface_create((char*)fn, page_width * param.h_dpi / DEFAULT_DPI, page_height * param.v_dpi / DEFAULT_DPI);
cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2);
cairo_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi);
@@ -105,10 +121,39 @@ void CairoBackgroundRenderer::render_page(PDFDoc * doc, int pageno)
if(status)
throw string("Error in cairo: ") + cairo_status_to_string(status);
}
+
+ //check node count in the svg file, fall back to bitmap_renderer if necessary.
+ if (param.svg_nodes_limit > 0)
+ {
+ int n = 0;
+ char c;
+ ifstream svgfile((char*)fn);
+ //count of '<' in the file should be an approximation of node count.
+ while(svgfile >> c)
+ {
+ if (c == '<')
+ ++n;
+ }
+ svgfile.close();
+ if (n > param.svg_nodes_limit)
+ {
+ html_renderer->tmp_files.add((char*)fn);
+ use_bitmap = true;
+ bitmap_renderer->render_page(doc, pageno);
+ }
+ else
+ use_bitmap = false;
+ }
}
void CairoBackgroundRenderer::embed_image(int pageno)
{
+ if (use_bitmap)
+ {
+ bitmap_renderer->embed_image(pageno);
+ return;
+ }
+
auto & f_page = *(html_renderer->f_curpage);
f_page << "str_fmt("%s/bg%x.%s", (param.embed_image ? param.tmp_dir : param.dest_dir).c_str(), pageno, param.bg_format.c_str());
+ auto fn = html_renderer->str_fmt("%s/bg%x.%s", (param.embed_image ? param.tmp_dir : param.dest_dir).c_str(), pageno, format.c_str());
if(param.embed_image)
html_renderer->tmp_files.add((char*)fn);
@@ -118,21 +142,21 @@ void SplashBackgroundRenderer::embed_image(int pageno)
if(param.embed_image)
{
- auto path = html_renderer->str_fmt("%s/bg%x.%s", param.tmp_dir.c_str(), pageno, param.bg_format.c_str());
+ auto path = html_renderer->str_fmt("%s/bg%x.%s", param.tmp_dir.c_str(), pageno, format.c_str());
ifstream fin((char*)path, ifstream::binary);
if(!fin)
throw string("Cannot read background image ") + (char*)path;
- auto iter = FORMAT_MIME_TYPE_MAP.find(param.bg_format);
+ auto iter = FORMAT_MIME_TYPE_MAP.find(format);
if(iter == FORMAT_MIME_TYPE_MAP.end())
- throw string("Image format not supported: ") + param.bg_format;
+ throw string("Image format not supported: ") + format;
string mime_type = iter->second;
f_page << "data:" << mime_type << ";base64," << Base64Stream(fin);
}
else
{
- f_page << (char*)html_renderer->str_fmt("bg%x.%s", pageno, param.bg_format.c_str());
+ f_page << (char*)html_renderer->str_fmt("bg%x.%s", pageno, format.c_str());
}
f_page << "\"/>";
}
@@ -153,23 +177,14 @@ void SplashBackgroundRenderer::dump_image(const char * filename, int x1, int y1,
// use unique_ptr to auto delete the object upon exception
unique_ptr writer;
- if(false) { }
-#ifdef ENABLE_LIBPNG
- else if(param.bg_format == "png")
+ if(format == "png")
{
writer = unique_ptr(new PNGWriter);
}
-#endif
-#ifdef ENABLE_LIBJPEG
- else if(param.bg_format == "jpg")
+ else if(format == "jpg")
{
writer = unique_ptr(new JpegWriter);
}
-#endif
- else
- {
- throw string("Image format not supported: ") + param.bg_format;
- }
if(!writer->init(f, width, height, param.h_dpi, param.v_dpi))
throw "Cannot initialize PNGWriter";
diff --git a/src/BackgroundRenderer/SplashBackgroundRenderer.h b/src/BackgroundRenderer/SplashBackgroundRenderer.h
index e999a10..55b9a97 100644
--- a/src/BackgroundRenderer/SplashBackgroundRenderer.h
+++ b/src/BackgroundRenderer/SplashBackgroundRenderer.h
@@ -27,11 +27,7 @@ class SplashBackgroundRenderer : public BackgroundRenderer, SplashOutputDev
public:
static const SplashColor white;
- SplashBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param)
- : SplashOutputDev(splashModeRGB8, 4, gFalse, (SplashColorPtr)(&white), gTrue, gTrue)
- , html_renderer(html_renderer)
- , param(param)
- { }
+ SplashBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param);
virtual ~SplashBackgroundRenderer() { }
@@ -68,6 +64,7 @@ protected:
void dump_image(const char * filename, int x1, int y1, int x2, int y2);
HTMLRenderer * html_renderer;
const Param & param;
+ std::string format;
};
} // namespace pdf2htmlEX
diff --git a/src/Param.h b/src/Param.h
index 9d42620..806f837 100644
--- a/src/Param.h
+++ b/src/Param.h
@@ -63,6 +63,7 @@ struct Param
// background image
std::string bg_format;
+ int svg_nodes_limit = 0;
// encryption
std::string owner_password, user_password;
diff --git a/src/pdf2htmlEX.cc b/src/pdf2htmlEX.cc
index 23e8d73..0df3d30 100644
--- a/src/pdf2htmlEX.cc
+++ b/src/pdf2htmlEX.cc
@@ -190,7 +190,8 @@ void parse_options (int argc, char **argv)
// background image
.add("bg-format", ¶m.bg_format, "png", "specify background image format")
-
+ .add("svg-nodes-limit", ¶m.svg_nodes_limit, 0, "if node count in a svg background image exceeds this limit,"
+ " fall back to bitmap background. 0 or negative means no limit.")
// encryption
.add("owner-password,o", ¶m.owner_password, "", "owner password (for encrypted files)", true)
.add("user-password,u", ¶m.user_password, "", "user password (for encrypted files)", true)