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

Merge pull request #371 from duanyao/proof_output

Implement proof output
This commit is contained in:
Lu Wang 2014-06-27 01:32:05 -07:00
commit 54c346fb22
11 changed files with 188 additions and 3 deletions

View File

@ -296,6 +296,12 @@ Experimental and unsupported CSS drawing
.B --debug <0|1> (Default: 0)
Print debug information.
.TP
.B --proof <0|1|2> (Default: 0)
Output a proof version. If a positive value is specified, texts are drawn on both text layer and background image for comparision.
If 2 is specified, texts on background are in different colors. If png/jpg background format is used,
a higher hdpi/vdpi (e.g. 288) is recommended for legibility.
.SS Meta
.TP

View File

@ -49,4 +49,80 @@ BackgroundRenderer * BackgroundRenderer::getFallbackBackgroundRenderer(HTMLRende
return nullptr;
}
void BackgroundRenderer::proof_begin_text_object(GfxState *state, OutputDev * dev)
{
if (!proof_state)
{
PDFRectangle rect(0, 0, state->getPageWidth(), state->getPageHeight());
proof_state.reset(new GfxState(state->getHDPI(), state->getVDPI(), &rect, state->getRotate(), dev->upsideDown()));
proof_state->setFillColorSpace(new GfxDeviceRGBColorSpace());
proof_state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
}
int render = state->getRender();
// Save original render mode in proof_state, and restore in proof_end_text_object()
// This is due to poppler's OutputDev::updateRender() actually has no effect, we have to
// modify state directly, see proof_begin_string().
proof_state->setRender(render);
}
void BackgroundRenderer::proof_begin_string(GfxState *state, OutputDev * dev)
{
int render = proof_state->getRender();
if (render == 3 || state->getRender() == 3) // hidden
return;
double lx = state->getFontSize() / 50, ly = lx;
tm_transform(state->getTextMat(), lx, ly, true);
proof_state->setLineWidth(std::min(fabs(lx), fabs(ly)));
static const Color red(1, 0, 0), green(0, 1, 0), blue(0, 0, 1), yellow(1, 1, 0), white(1, 1, 1);
Color fc, sc;
const Color *pfc, *psc;
state->getFillRGB(&fc.rgb);
state->getStrokeRGB(&sc.rgb);
if (render == 0 || render == 2) //has fill
pfc = fc.distance(red) > 0.4 ? &red : &green;
else
pfc = &red;
if (render == 1 || render == 2) // has stroke
psc = sc.distance(blue) > 0.4 ? &blue : &yellow;
else if(render == 0) // fill only
psc = &white;
else
psc = &blue;
GfxColor gfc, gsc;
pfc->get_gfx_color(gfc);
psc->get_gfx_color(gsc);
proof_state->setFillColor(&gfc);
proof_state->setStrokeColor(&gsc);
if (state->getFillColorSpace()->getMode() != csDeviceRGB)
dev->updateFillColorSpace(proof_state.get());
if (state->getStrokeColorSpace()->getMode() != csDeviceRGB)
dev->updateStrokeColorSpace(proof_state.get());
dev->updateLineWidth(proof_state.get());
dev->updateFillColor(proof_state.get());
dev->updateStrokeColor(proof_state.get());
state->setRender(2); // fill & stroke
dev->updateRender(state);
}
void BackgroundRenderer::proof_end_text_object(GfxState *state, OutputDev * dev)
{
state->setRender(proof_state->getRender());
dev->updateRender(state);
dev->updateLineWidth(state);
dev->updateFillColorSpace(state);
dev->updateStrokeColorSpace(state);
dev->updateFillColor(state);
dev->updateStrokeColor(state);
}
} // namespace pdf2htmlEX

View File

@ -10,8 +10,11 @@
#define BACKGROUND_RENDERER_H__
#include <string>
#include <memory>
class PDFDoc;
class GfxState;
class OutputDev;
namespace pdf2htmlEX {
@ -34,6 +37,13 @@ public:
virtual bool render_page(PDFDoc * doc, int pageno) = 0;
virtual void embed_image(int pageno) = 0;
// for proof output
protected:
void proof_begin_text_object(GfxState * state, OutputDev * dev);
void proof_begin_string(GfxState * state, OutputDev * dev);
void proof_end_text_object(GfxState * state, OutputDev * dev);
private:
std::unique_ptr<GfxState> proof_state;
};
} // namespace pdf2htmlEX

View File

@ -53,8 +53,8 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
// - OR there is special filling method
// - OR using a writing mode font
// - OR using a Type 3 font while param.process_type3 is not enabled
if((param.fallback)
|| ( (state->getFont())
if((param.fallback || param.proof)
|| ( (state->getFont())
&& ( (state->getFont()->getWMode())
|| ((state->getFont()->getType() == fontType3) && (!param.process_type3))
)
@ -65,6 +65,27 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
}
}
void CairoBackgroundRenderer::beginTextObject(GfxState *state)
{
if (param.proof == 2)
proof_begin_text_object(state, this);
CairoOutputDev::beginTextObject(state);
}
void CairoBackgroundRenderer::beginString(GfxState *state, GooString * str)
{
if (param.proof == 2)
proof_begin_string(state, this);
CairoOutputDev::beginString(state, str);
}
void CairoBackgroundRenderer::endTextObject(GfxState *state)
{
if (param.proof == 2)
proof_end_text_object(state, this);
CairoOutputDev::endTextObject(state);
}
void CairoBackgroundRenderer::init(PDFDoc * doc)
{
startDoc(doc);

View File

@ -44,6 +44,11 @@ public:
double originX, double originY,
CharCode code, int nBytes, Unicode *u, int uLen);
//for proof
void beginTextObject(GfxState *state);
void beginString(GfxState *state, GooString * str);
void endTextObject(GfxState *state);
protected:
virtual void setMimeData(Stream *str, Object *ref, cairo_surface_t *image);

View File

@ -78,7 +78,7 @@ void SplashBackgroundRenderer::drawChar(GfxState *state, double x, double y,
// - OR there is special filling method
// - OR using a writing mode font
// - OR using a Type 3 font while param.process_type3 is not enabled
if((param.fallback)
if((param.fallback || param.proof)
|| ( (state->getFont())
&& ( (state->getFont()->getWMode())
|| ((state->getFont()->getType() == fontType3) && (!param.process_type3))
@ -90,6 +90,27 @@ void SplashBackgroundRenderer::drawChar(GfxState *state, double x, double y,
}
}
void SplashBackgroundRenderer::beginTextObject(GfxState *state)
{
if (param.proof == 2)
proof_begin_text_object(state, this);
SplashOutputDev::beginTextObject(state);
}
void SplashBackgroundRenderer::beginString(GfxState *state, GooString * str)
{
if (param.proof == 2)
proof_begin_string(state, this);
SplashOutputDev::beginString(state, str);
}
void SplashBackgroundRenderer::endTextObject(GfxState *state)
{
if (param.proof == 2)
proof_end_text_object(state, this);
SplashOutputDev::endTextObject(state);
}
void SplashBackgroundRenderer::init(PDFDoc * doc)
{
startDoc(doc);

View File

@ -60,6 +60,11 @@ public:
SplashOutputDev::fill(state);
}
//for proof
void beginTextObject(GfxState *state);
void beginString(GfxState *state, GooString * str);
void endTextObject(GfxState *state);
protected:
void dump_image(const char * filename, int x1, int y1, int x2, int y2);
HTMLRenderer * html_renderer;

View File

@ -1,3 +1,5 @@
#include <cmath>
#include "Color.h"
#include "util/misc.h"
@ -6,6 +8,22 @@ namespace pdf2htmlEX {
using std::ostream;
Color::Color()
{
memset(this, 0, sizeof(Color));
}
Color::Color(double r, double g, double b, bool transparent)
:transparent(transparent)
{
rgb.r = (GfxColorComp)(r * gfxColorComp1);
rgb.g = (GfxColorComp)(g * gfxColorComp1);
rgb.b = (GfxColorComp)(b * gfxColorComp1);
}
Color::Color(const GfxRGB& rgb)
:transparent(false), rgb(rgb) { }
ostream & operator << (ostream & out, const Color & color)
{
if(color.transparent)
@ -15,4 +33,19 @@ ostream & operator << (ostream & out, const Color & color)
return out;
}
void Color::get_gfx_color(GfxColor & gc) const
{
gc.c[0] = rgb.r;
gc.c[1] = rgb.g;
gc.c[2] = rgb.b;
}
double Color::distance(const Color & other) const
{
double dr = (double)rgb.r - other.rgb.r,
dg = (double)rgb.g - other.rgb.g,
db = (double)rgb.b - other.rgb.b;
return sqrt((dr * dr + dg * dg + db * db) / (3.0 * gfxColorComp1 * gfxColorComp1));
}
} // namespace pdf2htmlEX

View File

@ -16,6 +16,9 @@ struct Color
{
bool transparent;
GfxRGB rgb;
Color();
Color(double r, double g, double b, bool transparent = false);
Color(const GfxRGB& rgb);
bool operator == (const Color & c) const {
if(transparent != c.transparent)
return false;
@ -23,6 +26,9 @@ struct Color
return true;
return ((rgb.r == c.rgb.r) && (rgb.g == c.rgb.g) && (rgb.b == c.rgb.b));
}
void get_gfx_color(GfxColor & gc) const;
// Color distance, [0,1].
double distance(const Color & other) const;
};
std::ostream & operator << (std::ostream & out, const Color & color);

View File

@ -76,6 +76,7 @@ struct Param
std::string tmp_dir;
int css_draw;
int debug;
int proof;
std::string input_filename, output_filename;
};

View File

@ -206,6 +206,7 @@ void parse_options (int argc, char **argv)
// TODO: css drawings are hidden on print, for annot links, need to fix it for other drawings
// .add("css-draw", &param.css_draw, 0, "[experimental and unsupported] CSS drawing")
.add("debug", &param.debug, 0, "print debugging information")
.add("proof", &param.proof, 0, "texts are drawn on both text layer and background for proof.")
// meta
.add("version,v", "print copyright and version info", &show_version_and_exit)