1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-12-22 13:00:08 +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) BackgroundRenderer * BackgroundRenderer::getBackgroundRenderer(const std::string & format, HTMLRenderer * html_renderer, const Param & param)
{ {
#ifdef ENABLE_LIBPNG if (format == "png" || format == "jpg")
if(format == "png") return new SplashBackgroundRenderer(format, html_renderer, param);
{
return new SplashBackgroundRenderer(html_renderer, param);
}
#endif
#ifdef ENABLE_LIBJPEG
if(format == "jpg")
{
return new SplashBackgroundRenderer(html_renderer, param);
}
#endif
#if ENABLE_SVG #if ENABLE_SVG
if (format == "svg") if (format == "svg")
{ {
@ -42,4 +33,11 @@ BackgroundRenderer * BackgroundRenderer::getBackgroundRenderer(const std::string
return nullptr; 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 } // namespace pdf2htmlEX

View File

@ -22,12 +22,16 @@ class BackgroundRenderer
public: public:
// return nullptr upon failure // return nullptr upon failure
static BackgroundRenderer * getBackgroundRenderer(const std::string & format, HTMLRenderer * html_renderer, const Param & param); 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() {} BackgroundRenderer() {}
virtual ~BackgroundRenderer() {} virtual ~BackgroundRenderer() {}
virtual void init(PDFDoc * doc) = 0; 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; virtual void embed_image(int pageno) = 0;
}; };

View File

@ -23,19 +23,11 @@ using std::string;
using std::ifstream; using std::ifstream;
CairoBackgroundRenderer::CairoBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param) CairoBackgroundRenderer::CairoBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param)
: CairoOutputDev() : CairoOutputDev()
, html_renderer(html_renderer) , html_renderer(html_renderer)
, param(param) , param(param)
, surface(nullptr) , 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, void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
double dx, double dy, double dx, double dy,
@ -62,15 +54,13 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
void CairoBackgroundRenderer::init(PDFDoc * doc) void CairoBackgroundRenderer::init(PDFDoc * doc)
{ {
startDoc(doc); startDoc(doc);
if (this->bitmap_renderer != nullptr)
this->bitmap_renderer->init(doc);
} }
static GBool annot_cb(Annot *, void * pflag) { static GBool annot_cb(Annot *, void * pflag) {
return (*((bool*)pflag)) ? gTrue : gFalse; 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_width;
double page_height; double page_height;
@ -85,11 +75,11 @@ void CairoBackgroundRenderer::render_page(PDFDoc * doc, int pageno)
page_height = doc->getPageMediaHeight(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) 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_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2);
cairo_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi); 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; int n = 0;
char c; char c;
ifstream svgfile((char*)fn); ifstream svgfile(fn);
//count of '<' in the file should be an approximation of node count. //count of '<' in the file should be an approximation of node count.
while(svgfile >> c) while(svgfile >> c)
{ {
if (c == '<') if (c == '<')
++n; ++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) void CairoBackgroundRenderer::embed_image(int pageno)
{ {
if (use_bitmap)
{
bitmap_renderer->embed_image(pageno);
return;
}
auto & f_page = *(html_renderer->f_curpage); auto & f_page = *(html_renderer->f_curpage);
f_page << "<img class=\"" << CSS::FULL_BACKGROUND_IMAGE_CN f_page << "<img class=\"" << CSS::FULL_BACKGROUND_IMAGE_CN

View File

@ -20,8 +20,6 @@
namespace pdf2htmlEX { namespace pdf2htmlEX {
class SplashBackgroundRenderer;
// Based on BackgroundRenderer from poppler // Based on BackgroundRenderer from poppler
class CairoBackgroundRenderer : public BackgroundRenderer, CairoOutputDev class CairoBackgroundRenderer : public BackgroundRenderer, CairoOutputDev
{ {
@ -31,7 +29,7 @@ public:
virtual ~CairoBackgroundRenderer() { } virtual ~CairoBackgroundRenderer() { }
virtual void init(PDFDoc * doc); 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); virtual void embed_image(int pageno);
// Does this device use beginType3Char/endType3Char? Otherwise, // Does this device use beginType3Char/endType3Char? Otherwise,
@ -47,8 +45,6 @@ protected:
HTMLRenderer * html_renderer; HTMLRenderer * html_renderer;
const Param & param; const Param & param;
cairo_surface_t * surface; 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}; 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) : SplashOutputDev(splashModeRGB8, 4, gFalse, (SplashColorPtr)(&white), gTrue, gTrue)
, html_renderer(html_renderer) , html_renderer(html_renderer)
, param(param) , param(param)
, format(imgFormat)
{ {
if(false) { } bool supported = false;
#ifdef ENABLE_LIBPNG #ifdef ENABLE_LIBPNG
else if(param.bg_format == "png" || param.bg_format == "svg") if (format.empty())
{
format = "png"; format = "png";
} supported = supported || format == "png";
#endif #endif
#ifdef ENABLE_LIBJPEG #ifdef ENABLE_LIBJPEG
else if(param.bg_format == "jpg" || param.bg_format == "svg") if (format.empty())
{
format = "jpg"; format = "jpg";
} supported = supported || format == "jpg";
#endif #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; 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; bool process_annotation = param.process_annotation;
doc->displayPage(this, pageno, param.h_dpi, param.v_dpi, 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)), (!(param.use_cropbox)),
false, false, false, false,
nullptr, nullptr, &annot_cb, &process_annotation); nullptr, nullptr, &annot_cb, &process_annotation);
return true;
} }
void SplashBackgroundRenderer::embed_image(int pageno) void SplashBackgroundRenderer::embed_image(int pageno)

View File

@ -26,13 +26,13 @@ class SplashBackgroundRenderer : public BackgroundRenderer, SplashOutputDev
{ {
public: public:
static const SplashColor white; static const SplashColor white;
//format: "png" or "jpg", or "" for a default format
SplashBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param); SplashBackgroundRenderer(const std::string & format, HTMLRenderer * html_renderer, const Param & param);
virtual ~SplashBackgroundRenderer() { } virtual ~SplashBackgroundRenderer() { }
virtual void init(PDFDoc * doc); 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); virtual void embed_image(int pageno);
// Does this device use beginType3Char/endType3Char? Otherwise, // Does this device use beginType3Char/endType3Char? Otherwise,

View File

@ -327,7 +327,8 @@ protected:
friend class CairoBackgroundRenderer; // ugly! friend class CairoBackgroundRenderer; // ugly!
#endif #endif
BackgroundRenderer * bg_renderer; BackgroundRenderer * bg_renderer;
BackgroundRenderer * fallback_bg_renderer;
bool fallback_bg_required;
struct { struct {
std::ofstream fs; std::ofstream fs;

View File

@ -98,12 +98,17 @@ void HTMLRenderer::process(PDFDoc *doc)
// Process pages // Process pages
bg_renderer = nullptr; bg_renderer = nullptr;
fallback_bg_renderer = nullptr;
if(param.process_nontext) if(param.process_nontext)
{ {
bg_renderer = BackgroundRenderer::getBackgroundRenderer(param.bg_format, this, param); bg_renderer = BackgroundRenderer::getBackgroundRenderer(param.bg_format, this, param);
if(!bg_renderer) if(!bg_renderer)
throw "Cannot initialize background renderer, unsupported format"; throw "Cannot initialize background renderer, unsupported format";
bg_renderer->init(doc); 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); int page_count = (param.last_page - param.first_page + 1);
@ -130,7 +135,9 @@ void HTMLRenderer::process(PDFDoc *doc)
if(param.process_nontext) 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, doc->displayPage(this, i,
@ -163,6 +170,11 @@ void HTMLRenderer::process(PDFDoc *doc)
delete bg_renderer; delete bg_renderer;
bg_renderer = nullptr; bg_renderer = nullptr;
} }
if(fallback_bg_renderer)
{
delete fallback_bg_renderer;
fallback_bg_renderer = nullptr;
}
cerr << endl; cerr << endl;
} }
@ -219,7 +231,10 @@ void HTMLRenderer::startPage(int pageNum, GfxState *state, XRef * xref)
if(param.process_nontext) 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(); reset_state();