From 6bf2824b1f0d7ede75a1f83dc27be544a944b6c3 Mon Sep 17 00:00:00 2001 From: Duan Yao Date: Sun, 8 Jun 2014 12:43:20 +0800 Subject: [PATCH] Move BackgroundRenderer fallback logic to HTMLRenderer. --- src/BackgroundRenderer/BackgroundRenderer.cc | 22 ++++---- src/BackgroundRenderer/BackgroundRenderer.h | 6 ++- .../CairoBackgroundRenderer.cc | 52 ++++++------------- .../CairoBackgroundRenderer.h | 6 +-- .../SplashBackgroundRenderer.cc | 22 ++++---- .../SplashBackgroundRenderer.h | 6 +-- src/HTMLRenderer/HTMLRenderer.h | 3 +- src/HTMLRenderer/general.cc | 19 ++++++- 8 files changed, 66 insertions(+), 70 deletions(-) diff --git a/src/BackgroundRenderer/BackgroundRenderer.cc b/src/BackgroundRenderer/BackgroundRenderer.cc index e6cf59c..164e766 100644 --- a/src/BackgroundRenderer/BackgroundRenderer.cc +++ b/src/BackgroundRenderer/BackgroundRenderer.cc @@ -20,18 +20,9 @@ namespace pdf2htmlEX { BackgroundRenderer * BackgroundRenderer::getBackgroundRenderer(const std::string & format, HTMLRenderer * html_renderer, const Param & param) { -#ifdef ENABLE_LIBPNG - if(format == "png") - { - return new SplashBackgroundRenderer(html_renderer, param); - } -#endif -#ifdef ENABLE_LIBJPEG - if(format == "jpg") - { - return new SplashBackgroundRenderer(html_renderer, param); - } -#endif + if (format == "png" || format == "jpg") + return new SplashBackgroundRenderer(format, html_renderer, param); + #if ENABLE_SVG if (format == "svg") { @@ -42,4 +33,11 @@ BackgroundRenderer * BackgroundRenderer::getBackgroundRenderer(const std::string return nullptr; } +BackgroundRenderer * BackgroundRenderer::getFallbackBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param) +{ + if (param.bg_format == "svg" && param.svg_nodes_limit > 0) + return new SplashBackgroundRenderer("", html_renderer, param); + return nullptr; +} + } // namespace pdf2htmlEX diff --git a/src/BackgroundRenderer/BackgroundRenderer.h b/src/BackgroundRenderer/BackgroundRenderer.h index f6d898e..29e03b6 100644 --- a/src/BackgroundRenderer/BackgroundRenderer.h +++ b/src/BackgroundRenderer/BackgroundRenderer.h @@ -22,12 +22,16 @@ class BackgroundRenderer public: // return nullptr upon failure static BackgroundRenderer * getBackgroundRenderer(const std::string & format, HTMLRenderer * html_renderer, const Param & param); + // Return a fallback bg renderer according to param.bg_format. + // Currently only svg bg format might need a bitmap fallback. + static BackgroundRenderer * getFallbackBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param); BackgroundRenderer() {} virtual ~BackgroundRenderer() {} virtual void init(PDFDoc * doc) = 0; - virtual void render_page(PDFDoc * doc, int pageno) = 0; + //return true on success, false otherwise (e.g. need a fallback) + virtual bool render_page(PDFDoc * doc, int pageno) = 0; virtual void embed_image(int pageno) = 0; }; diff --git a/src/BackgroundRenderer/CairoBackgroundRenderer.cc b/src/BackgroundRenderer/CairoBackgroundRenderer.cc index c92703b..4f30305 100644 --- a/src/BackgroundRenderer/CairoBackgroundRenderer.cc +++ b/src/BackgroundRenderer/CairoBackgroundRenderer.cc @@ -23,19 +23,11 @@ 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; -} + : CairoOutputDev() + , html_renderer(html_renderer) + , param(param) + , surface(nullptr) +{ } void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y, double dx, double dy, @@ -62,15 +54,13 @@ 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) { return (*((bool*)pflag)) ? gTrue : gFalse; }; -void CairoBackgroundRenderer::render_page(PDFDoc * doc, int pageno) +bool CairoBackgroundRenderer::render_page(PDFDoc * doc, int pageno) { double page_width; double page_height; @@ -85,11 +75,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); + string fn = (char*)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); + html_renderer->tmp_files.add(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(fn.c_str(), 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); @@ -127,33 +117,25 @@ void CairoBackgroundRenderer::render_page(PDFDoc * doc, int pageno) { int n = 0; char c; - ifstream svgfile((char*)fn); + ifstream svgfile(fn); //count of '<' in the file should be an approximation of node count. while(svgfile >> c) { if (c == '<') ++n; + if (n > param.svg_nodes_limit) + { + html_renderer->tmp_files.add(fn); + return false; + } } - 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; } + + return true; } void CairoBackgroundRenderer::embed_image(int pageno) { - if (use_bitmap) - { - bitmap_renderer->embed_image(pageno); - return; - } - auto & f_page = *(html_renderer->f_curpage); f_page << "displayPage(this, pageno, param.h_dpi, param.v_dpi, @@ -108,6 +107,7 @@ void SplashBackgroundRenderer::render_page(PDFDoc * doc, int pageno) (!(param.use_cropbox)), false, false, nullptr, nullptr, &annot_cb, &process_annotation); + return true; } void SplashBackgroundRenderer::embed_image(int pageno) diff --git a/src/BackgroundRenderer/SplashBackgroundRenderer.h b/src/BackgroundRenderer/SplashBackgroundRenderer.h index 55b9a97..9ec8de9 100644 --- a/src/BackgroundRenderer/SplashBackgroundRenderer.h +++ b/src/BackgroundRenderer/SplashBackgroundRenderer.h @@ -26,13 +26,13 @@ class SplashBackgroundRenderer : public BackgroundRenderer, SplashOutputDev { public: static const SplashColor white; - - SplashBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param); + //format: "png" or "jpg", or "" for a default format + SplashBackgroundRenderer(const std::string & format, HTMLRenderer * html_renderer, const Param & param); virtual ~SplashBackgroundRenderer() { } virtual void init(PDFDoc * doc); - virtual void render_page(PDFDoc * doc, int pageno); + virtual bool render_page(PDFDoc * doc, int pageno); virtual void embed_image(int pageno); // Does this device use beginType3Char/endType3Char? Otherwise, diff --git a/src/HTMLRenderer/HTMLRenderer.h b/src/HTMLRenderer/HTMLRenderer.h index 7d67f70..73929ab 100644 --- a/src/HTMLRenderer/HTMLRenderer.h +++ b/src/HTMLRenderer/HTMLRenderer.h @@ -327,7 +327,8 @@ protected: friend class CairoBackgroundRenderer; // ugly! #endif BackgroundRenderer * bg_renderer; - + BackgroundRenderer * fallback_bg_renderer; + bool fallback_bg_required; struct { std::ofstream fs; diff --git a/src/HTMLRenderer/general.cc b/src/HTMLRenderer/general.cc index 9c85a97..803bc2d 100644 --- a/src/HTMLRenderer/general.cc +++ b/src/HTMLRenderer/general.cc @@ -98,12 +98,17 @@ void HTMLRenderer::process(PDFDoc *doc) // Process pages bg_renderer = nullptr; + fallback_bg_renderer = nullptr; if(param.process_nontext) { bg_renderer = BackgroundRenderer::getBackgroundRenderer(param.bg_format, this, param); if(!bg_renderer) throw "Cannot initialize background renderer, unsupported format"; bg_renderer->init(doc); + + fallback_bg_renderer = BackgroundRenderer::getFallbackBackgroundRenderer(this, param); + if (fallback_bg_renderer) + fallback_bg_renderer->init(doc); } int page_count = (param.last_page - param.first_page + 1); @@ -130,7 +135,9 @@ void HTMLRenderer::process(PDFDoc *doc) if(param.process_nontext) { - bg_renderer->render_page(doc, i); + fallback_bg_required = !bg_renderer->render_page(doc, i); + if (fallback_bg_required && fallback_bg_renderer != nullptr) + fallback_bg_renderer->render_page(doc, i); } doc->displayPage(this, i, @@ -163,6 +170,11 @@ void HTMLRenderer::process(PDFDoc *doc) delete bg_renderer; bg_renderer = nullptr; } + if(fallback_bg_renderer) + { + delete fallback_bg_renderer; + fallback_bg_renderer = nullptr; + } cerr << endl; } @@ -219,7 +231,10 @@ void HTMLRenderer::startPage(int pageNum, GfxState *state, XRef * xref) if(param.process_nontext) { - bg_renderer->embed_image(pageNum); + if (!fallback_bg_required) + bg_renderer->embed_image(pageNum); + else if (fallback_bg_renderer != nullptr) + fallback_bg_renderer->embed_image(pageNum); } reset_state();