1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-09-17 21:16:03 +00:00
pdf2htmlEX/src/HTMLRenderer/general.cc

275 lines
7.6 KiB
C++
Raw Normal View History

2012-08-14 08:23:15 +00:00
/*
* general.cc
*
* Hanlding general stuffs
*
* by WangLu
* 2012.08.14
*/
2012-09-09 17:40:37 +00:00
#include <cstdio>
2012-09-05 10:43:37 +00:00
2012-08-14 08:23:15 +00:00
#include <splash/SplashBitmap.h>
#include "HTMLRenderer.h"
#include "BackgroundRenderer.h"
#include "config.h"
2012-08-14 09:13:29 +00:00
#include "namespace.h"
#include "ff/ff.h"
2012-08-14 08:23:15 +00:00
using std::fixed;
2012-08-14 12:30:18 +00:00
using std::flush;
2012-09-03 13:59:39 +00:00
static void dummy(void *, ErrorCategory, int pos, char *)
{
}
2012-08-14 08:23:15 +00:00
HTMLRenderer::HTMLRenderer(const Param * param)
2012-09-04 15:33:15 +00:00
:line_opened(false)
,line_buf(this)
2012-08-14 08:23:15 +00:00
,image_count(0)
,param(param)
2012-08-14 09:50:16 +00:00
,dest_dir(param->dest_dir)
2012-08-15 06:27:59 +00:00
,tmp_dir(param->tmp_dir)
2012-08-14 08:23:15 +00:00
{
2012-09-03 13:59:39 +00:00
//disable error function of poppler
setErrorCallback(&dummy, nullptr);
ff_init();
2012-09-03 13:54:48 +00:00
cur_mapping = new int32_t [0x10000];
cur_mapping2 = new char* [0x100];
2012-08-14 08:23:15 +00:00
}
HTMLRenderer::~HTMLRenderer()
2012-08-15 04:27:41 +00:00
{
2012-09-06 23:55:10 +00:00
ff_fin();
2012-08-15 04:27:41 +00:00
clean_tmp_files();
2012-09-03 13:54:48 +00:00
delete [] cur_mapping;
delete [] cur_mapping2;
2012-08-15 04:27:41 +00:00
}
2012-08-14 08:23:15 +00:00
2012-09-07 00:13:45 +00:00
static GBool annot_cb(Annot *, void *) {
return false;
};
2012-08-14 08:23:15 +00:00
void HTMLRenderer::process(PDFDoc *doc)
{
xref = doc->getXRef();
2012-09-06 16:58:23 +00:00
cerr << "Preprocessing: ";
for(int i = param->first_page; i <= param->last_page ; ++i)
{
doc->displayPage(&font_preprocessor, i, param->h_dpi, param->v_dpi,
0, true, false, false,
nullptr, nullptr, nullptr, nullptr);
cerr << "." << flush;
}
cerr << endl;
2012-08-14 08:23:15 +00:00
2012-09-06 16:58:23 +00:00
cerr << "Working: ";
BackgroundRenderer * bg_renderer = nullptr;
2012-08-14 08:23:15 +00:00
if(param->process_nontext)
{
// Render non-text objects as image
// copied from poppler
SplashColor color;
color[0] = color[1] = color[2] = 255;
2012-08-14 12:30:18 +00:00
bg_renderer = new BackgroundRenderer(splashModeRGB8, 4, gFalse, color);
2012-08-14 08:23:15 +00:00
bg_renderer->startDoc(doc);
2012-08-14 12:30:18 +00:00
}
2012-08-14 08:23:15 +00:00
2012-08-14 12:30:18 +00:00
pre_process();
2012-09-07 00:13:45 +00:00
2012-08-14 12:30:18 +00:00
for(int i = param->first_page; i <= param->last_page ; ++i)
{
if(param->process_nontext)
2012-08-14 08:23:15 +00:00
{
2012-08-15 13:26:13 +00:00
doc->displayPage(bg_renderer, i, param->h_dpi, param->v_dpi,
2012-08-14 08:23:15 +00:00
0, true, false, false,
2012-09-07 00:13:45 +00:00
nullptr, nullptr, &annot_cb, nullptr);
2012-08-15 04:27:41 +00:00
2012-09-07 17:09:09 +00:00
{
2012-09-09 16:21:46 +00:00
auto fn = str_fmt("%s/p%llx.png", (param->single_html ? tmp_dir : dest_dir).c_str(), i);
2012-09-07 17:09:09 +00:00
if(param->single_html)
2012-09-09 16:21:46 +00:00
add_tmp_file((char*)fn);
bg_renderer->getBitmap()->writeImgFile(splashFormatPng,
(char*)fn,
param->h_dpi, param->v_dpi);
2012-09-07 17:09:09 +00:00
}
2012-08-14 08:23:15 +00:00
}
2012-08-14 12:30:18 +00:00
2012-08-15 13:26:13 +00:00
doc->displayPage(this, i, param->zoom * DEFAULT_DPI, param->zoom * DEFAULT_DPI,
2012-08-14 12:30:18 +00:00
0, true, false, false,
nullptr, nullptr, nullptr, nullptr);
cerr << "." << flush;
2012-08-14 08:23:15 +00:00
}
2012-08-14 12:30:18 +00:00
post_process();
if(bg_renderer)
delete bg_renderer;
cerr << endl;
2012-08-14 08:23:15 +00:00
}
2012-08-14 12:30:18 +00:00
void HTMLRenderer::pre_process()
2012-08-14 08:23:15 +00:00
{
2012-08-14 18:28:19 +00:00
// we may output utf8 characters, so use binary
2012-08-15 04:27:41 +00:00
if(param->single_html)
2012-08-14 12:30:18 +00:00
{
2012-09-09 16:21:46 +00:00
{
auto fn = str_fmt("%s/%s", tmp_dir.c_str(), CSS_FILENAME.c_str());
allcss_fout.open((char*)fn, ofstream::binary);
add_tmp_file((char*)fn);
}
{
// don't use output_file directly
// otherwise it'll be a disaster when tmp_dir == dest_dir
auto tmp_output_fn = str_fmt("%s/%s.part", tmp_dir.c_str(), param->output_filename.c_str());
add_tmp_file((char*)tmp_output_fn);
html_fout.open((char*)tmp_output_fn, ofstream::binary);
}
2012-08-15 04:27:41 +00:00
}
else
{
2012-09-09 16:21:46 +00:00
html_fout.open(str_fmt("%s/%s", dest_dir.c_str(), param->output_filename.c_str()), ofstream::binary);
allcss_fout.open(str_fmt("%s/%s", dest_dir.c_str(), CSS_FILENAME.c_str()), ofstream::binary);
2012-08-15 04:27:41 +00:00
2012-09-09 16:21:46 +00:00
html_fout << ifstream(str_fmt("%s/%s", PDF2HTMLEX_DATA_PATH.c_str(), HEAD_HTML_FILENAME.c_str()), ifstream::binary).rdbuf();
html_fout << "<link rel=\"stylesheet\" type=\"text/css\" href=\"" << CSS_FILENAME << "\"/>" << endl;
2012-09-09 16:21:46 +00:00
html_fout << ifstream(str_fmt("%s/%s", PDF2HTMLEX_DATA_PATH.c_str(), NECK_HTML_FILENAME.c_str()), ifstream::binary).rdbuf();
2012-08-14 12:30:18 +00:00
}
2012-09-07 16:38:41 +00:00
html_fout << fixed << hex;
allcss_fout << fixed << hex;
2012-09-09 16:21:46 +00:00
allcss_fout << ifstream(str_fmt("%s/%s", PDF2HTMLEX_DATA_PATH.c_str(), CSS_FILENAME.c_str()), ifstream::binary).rdbuf();
2012-08-14 08:23:15 +00:00
}
2012-08-14 12:30:18 +00:00
void HTMLRenderer::post_process()
2012-08-14 08:23:15 +00:00
{
2012-08-14 12:30:18 +00:00
if(!param->single_html)
{
2012-09-09 16:21:46 +00:00
html_fout << ifstream(str_fmt("%s/%s", PDF2HTMLEX_DATA_PATH.c_str(), TAIL_HTML_FILENAME.c_str()), ifstream::binary).rdbuf();
2012-08-14 12:30:18 +00:00
}
html_fout.close();
allcss_fout.close();
if(param->single_html)
{
process_single_html();
}
2012-08-14 08:23:15 +00:00
}
void HTMLRenderer::startPage(int pageNum, GfxState *state)
{
this->pageNum = pageNum;
this->pageWidth = state->getPageWidth();
this->pageHeight = state->getPageHeight();
2012-09-04 15:33:15 +00:00
assert((!line_opened) && "Open line in startPage detected!");
2012-08-14 08:23:15 +00:00
2012-09-07 16:38:41 +00:00
html_fout << "<div id=\"p" << pageNum << "\" class=\"p\" style=\"width:" << pageWidth << "px;height:" << pageHeight << "px;";
2012-08-14 08:23:15 +00:00
2012-08-14 18:54:39 +00:00
html_fout << "background-image:url(";
2012-08-14 13:23:33 +00:00
{
2012-09-07 17:09:09 +00:00
if(param->single_html)
{
2012-09-09 16:21:46 +00:00
html_fout << "'data:image/png;base64," << base64stream(ifstream(str_fmt("%s/p%llx.png", tmp_dir.c_str(), pageNum) , ifstream::binary)) << "'";
2012-09-07 17:09:09 +00:00
}
else
{
2012-09-09 16:21:46 +00:00
html_fout << str_fmt("p%llx.png", pageNum);
2012-09-07 17:09:09 +00:00
}
2012-08-14 13:23:33 +00:00
}
2012-09-07 16:38:41 +00:00
html_fout << ");background-position:0 0;background-size:" << pageWidth << "px " << pageHeight << "px;background-repeat:no-repeat;\">";
2012-08-14 08:23:15 +00:00
2012-08-21 18:37:25 +00:00
draw_scale = 1.0;
cur_font_info = install_font(nullptr);
2012-08-21 18:37:25 +00:00
cur_font_size = draw_font_size = 0;
cur_fs_id = install_font_size(cur_font_size);
2012-08-14 08:23:15 +00:00
memcpy(cur_ctm, id_matrix, sizeof(cur_ctm));
2012-08-21 18:37:25 +00:00
memcpy(draw_ctm, id_matrix, sizeof(draw_ctm));
cur_tm_id = install_transform_matrix(draw_ctm);
cur_letter_space = cur_word_space = 0;
2012-08-21 18:37:25 +00:00
cur_ls_id = install_letter_space(cur_letter_space);
cur_ws_id = install_word_space(cur_word_space);
cur_color.r = cur_color.g = cur_color.b = 0;
2012-08-21 18:37:25 +00:00
cur_color_id = install_color(&cur_color);
2012-08-24 17:40:43 +00:00
cur_rise = 0;
cur_rise_id = install_rise(cur_rise);
cur_tx = cur_ty = 0;
2012-08-14 08:23:15 +00:00
draw_tx = draw_ty = 0;
reset_state_change();
2012-08-20 22:20:20 +00:00
all_changed = true;
2012-08-14 08:23:15 +00:00
}
void HTMLRenderer::endPage() {
close_line();
2012-08-14 08:23:15 +00:00
// close page
html_fout << "</div>" << endl;
}
2012-08-14 12:30:18 +00:00
void HTMLRenderer::process_single_html()
{
2012-09-09 16:21:46 +00:00
ofstream out (dest_dir + "/" + param->output_filename, ofstream::binary);
2012-08-14 12:30:18 +00:00
2012-09-09 16:21:46 +00:00
out << ifstream(PDF2HTMLEX_DATA_PATH + "/" + HEAD_HTML_FILENAME , ifstream::binary).rdbuf();
2012-08-14 12:30:18 +00:00
out << "<style type=\"text/css\">" << endl;
2012-09-09 16:21:46 +00:00
out << ifstream(tmp_dir + "/" + CSS_FILENAME, ifstream::binary).rdbuf();
2012-08-14 12:30:18 +00:00
out << "</style>" << endl;
2012-09-09 16:21:46 +00:00
out << ifstream(PDF2HTMLEX_DATA_PATH + "/" + NECK_HTML_FILENAME, ifstream::binary).rdbuf();
2012-08-14 08:23:15 +00:00
2012-09-09 16:21:46 +00:00
out << ifstream(tmp_dir + "/" + (param->output_filename + ".part"), ifstream::binary).rdbuf();
2012-08-14 12:30:18 +00:00
2012-09-09 16:21:46 +00:00
out << ifstream(PDF2HTMLEX_DATA_PATH + "/" + TAIL_HTML_FILENAME, ifstream::binary).rdbuf();
2012-08-14 12:30:18 +00:00
}
2012-08-14 08:23:15 +00:00
2012-08-15 04:27:41 +00:00
void HTMLRenderer::add_tmp_file(const string & fn)
{
2012-08-15 07:43:49 +00:00
if(!param->clean_tmp)
return;
2012-08-15 04:27:41 +00:00
if(tmp_files.insert(fn).second && param->debug)
cerr << "Add new temporary file: " << fn << endl;
}
2012-08-14 08:23:15 +00:00
2012-08-15 04:27:41 +00:00
void HTMLRenderer::clean_tmp_files()
{
2012-08-15 07:43:49 +00:00
if(!param->clean_tmp)
return;
2012-09-09 06:48:10 +00:00
for(auto iter = tmp_files.begin(); iter != tmp_files.end(); ++iter)
2012-08-15 04:27:41 +00:00
{
2012-09-09 17:40:37 +00:00
const string & fn = *iter;
remove(fn.c_str());
2012-08-15 04:27:41 +00:00
if(param->debug)
2012-09-09 17:40:37 +00:00
cerr << "Remove temporary file: " << fn << endl;
2012-08-15 04:27:41 +00:00
}
2012-09-09 17:40:37 +00:00
remove(tmp_dir.c_str());
if(param->debug)
cerr << "Remove temporary directory: " << tmp_dir << endl;
2012-08-15 04:27:41 +00:00
}
const std::string HTMLRenderer::HEAD_HTML_FILENAME = "head.html";
const std::string HTMLRenderer::NECK_HTML_FILENAME = "neck.html";
const std::string HTMLRenderer::TAIL_HTML_FILENAME = "tail.html";
const std::string HTMLRenderer::CSS_FILENAME = "all.css";