1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-07-05 01:28:39 +00:00

Move BackgroundRenderer fallback logic to HTMLRenderer.

This commit is contained in:
Duan Yao 2014-06-08 12:43:20 +08:00 committed by Lu Wang
parent d3340ce04a
commit 6bf2824b1f
8 changed files with 66 additions and 70 deletions

View File

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

View File

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

View File

@ -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 << "<img class=\"" << CSS::FULL_BACKGROUND_IMAGE_CN

View File

@ -20,8 +20,6 @@
namespace pdf2htmlEX {
class SplashBackgroundRenderer;
// Based on BackgroundRenderer from poppler
class CairoBackgroundRenderer : public BackgroundRenderer, CairoOutputDev
{
@ -31,7 +29,7 @@ public:
virtual ~CairoBackgroundRenderer() { }
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,
@ -47,8 +45,6 @@ protected:
HTMLRenderer * html_renderer;
const Param & param;
cairo_surface_t * surface;
SplashBackgroundRenderer * bitmap_renderer;
bool use_bitmap;
};
}

View File

@ -28,27 +28,26 @@ using std::unique_ptr;
const SplashColor SplashBackgroundRenderer::white = {255,255,255};
SplashBackgroundRenderer::SplashBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param)
SplashBackgroundRenderer::SplashBackgroundRenderer(const string & imgFormat, HTMLRenderer * html_renderer, const Param & param)
: SplashOutputDev(splashModeRGB8, 4, gFalse, (SplashColorPtr)(&white), gTrue, gTrue)
, html_renderer(html_renderer)
, param(param)
, format(imgFormat)
{
if(false) { }
bool supported = false;
#ifdef ENABLE_LIBPNG
else if(param.bg_format == "png" || param.bg_format == "svg")
{
if (format.empty())
format = "png";
}
supported = supported || format == "png";
#endif
#ifdef ENABLE_LIBJPEG
else if(param.bg_format == "jpg" || param.bg_format == "svg")
{
if (format.empty())
format = "jpg";
}
supported = supported || format == "jpg";
#endif
else
if (!supported)
{
throw string("Image format not supported: ") + param.bg_format;
throw string("Image format not supported: ") + format;
}
}
@ -100,7 +99,7 @@ static GBool annot_cb(Annot *, void * pflag) {
return (*((bool*)pflag)) ? gTrue : gFalse;
};
void SplashBackgroundRenderer::render_page(PDFDoc * doc, int pageno)
bool SplashBackgroundRenderer::render_page(PDFDoc * doc, int pageno)
{
bool process_annotation = param.process_annotation;
doc->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)

View File

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

View File

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

View File

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