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:
parent
d3340ce04a
commit
6bf2824b1f
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user