mirror of
https://github.com/pdf2htmlEX/pdf2htmlEX.git
synced 2024-12-22 04:50:09 +00:00
Move BackgroundRenderer fallback logic to HTMLRenderer.
This commit is contained in:
parent
1764c1c334
commit
4add9da6e4
@ -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
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user