mirror of
https://github.com/pdf2htmlEX/pdf2htmlEX.git
synced 2024-12-22 13:00:08 +00:00
Implement proof output
This commit is contained in:
parent
3c5d491a95
commit
f8d8a58deb
@ -296,6 +296,11 @@ Experimental and unsupported CSS drawing
|
|||||||
.B --debug <0|1> (Default: 0)
|
.B --debug <0|1> (Default: 0)
|
||||||
Print debug information.
|
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, usually red for filling, blue for stroking.
|
||||||
|
|
||||||
.SS Meta
|
.SS Meta
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
|
@ -49,4 +49,57 @@ BackgroundRenderer * BackgroundRenderer::getFallbackBackgroundRenderer(HTMLRende
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BackgroundRenderer::~BackgroundRenderer()
|
||||||
|
{
|
||||||
|
//delete proof_state
|
||||||
|
if (proof_state)
|
||||||
|
delete proof_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundRenderer::proof_begin_string(GfxState *state)
|
||||||
|
{
|
||||||
|
auto dev = (OutputDev*) dynamic_cast<SplashBackgroundRenderer*>(this);
|
||||||
|
if (!dev)
|
||||||
|
dev = (OutputDev*) dynamic_cast<CairoBackgroundRenderer*>(this);
|
||||||
|
|
||||||
|
if (!proof_state)
|
||||||
|
{
|
||||||
|
PDFRectangle rect(0, 0, state->getPageWidth(), state->getPageHeight());
|
||||||
|
proof_state = new GfxState(state->getHDPI(), state->getVDPI(), &rect, state->getRotate(), dev->upsideDown());
|
||||||
|
proof_state->setFillColorSpace(new GfxDeviceRGBColorSpace());
|
||||||
|
proof_state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
|
||||||
|
}
|
||||||
|
|
||||||
|
Color fc, sc, red(1, 0, 0), green(0, 1, 0), blue(0, 0, 1), yellow(1, 1, 0);
|
||||||
|
state->getFillRGB(&fc.rgb);
|
||||||
|
state->getStrokeRGB(&sc.rgb);
|
||||||
|
|
||||||
|
fc = fc.distance(red) > 0.4 ? red : green;
|
||||||
|
sc = sc.distance(blue) > 0.4 ? blue : yellow;
|
||||||
|
|
||||||
|
if (state->getFillColorSpace()->getMode() != csDeviceRGB)
|
||||||
|
dev->updateFillColorSpace(proof_state);
|
||||||
|
if (state->getStrokeColorSpace()->getMode() != csDeviceRGB)
|
||||||
|
dev->updateStrokeColorSpace(proof_state);
|
||||||
|
GfxColor gfc, gsc;
|
||||||
|
fc.get_gfx_color(gfc);
|
||||||
|
sc.get_gfx_color(gsc);
|
||||||
|
proof_state->setFillColor(&gfc);
|
||||||
|
proof_state->setStrokeColor(&gsc);
|
||||||
|
dev->updateFillColor(proof_state);
|
||||||
|
dev->updateStrokeColor(proof_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundRenderer::proof_end_text_object(GfxState *state)
|
||||||
|
{
|
||||||
|
auto dev = (OutputDev*) dynamic_cast<SplashBackgroundRenderer*>(this);
|
||||||
|
if (!dev)
|
||||||
|
dev = (OutputDev*) dynamic_cast<CairoBackgroundRenderer*>(this);
|
||||||
|
|
||||||
|
dev->updateFillColorSpace(state);
|
||||||
|
dev->updateStrokeColorSpace(state);
|
||||||
|
dev->updateFillColor(state);
|
||||||
|
dev->updateStrokeColor(state);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf2htmlEX
|
} // namespace pdf2htmlEX
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class PDFDoc;
|
class PDFDoc;
|
||||||
|
class GfxState;
|
||||||
|
|
||||||
namespace pdf2htmlEX {
|
namespace pdf2htmlEX {
|
||||||
|
|
||||||
@ -26,14 +27,20 @@ public:
|
|||||||
// Currently only svg bg format might need a bitmap fallback.
|
// Currently only svg bg format might need a bitmap fallback.
|
||||||
static BackgroundRenderer * getFallbackBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param);
|
static BackgroundRenderer * getFallbackBackgroundRenderer(HTMLRenderer * html_renderer, const Param & param);
|
||||||
|
|
||||||
BackgroundRenderer() {}
|
BackgroundRenderer(): proof_state(nullptr) {}
|
||||||
virtual ~BackgroundRenderer() {}
|
virtual ~BackgroundRenderer();
|
||||||
|
|
||||||
virtual void init(PDFDoc * doc) = 0;
|
virtual void init(PDFDoc * doc) = 0;
|
||||||
//return true on success, false otherwise (e.g. need a fallback)
|
//return true on success, false otherwise (e.g. need a fallback)
|
||||||
virtual bool render_page(PDFDoc * doc, int pageno) = 0;
|
virtual bool render_page(PDFDoc * doc, int pageno) = 0;
|
||||||
virtual void embed_image(int pageno) = 0;
|
virtual void embed_image(int pageno) = 0;
|
||||||
|
|
||||||
|
// for proof output
|
||||||
|
protected:
|
||||||
|
void proof_begin_string(GfxState *state);
|
||||||
|
void proof_end_text_object(GfxState *state);
|
||||||
|
private:
|
||||||
|
GfxState * proof_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf2htmlEX
|
} // namespace pdf2htmlEX
|
||||||
|
@ -53,8 +53,8 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
|
|||||||
// - OR there is special filling method
|
// - OR there is special filling method
|
||||||
// - OR using a writing mode font
|
// - OR using a writing mode font
|
||||||
// - OR using a Type 3 font while param.process_type3 is not enabled
|
// - 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())
|
||||||
&& ( (state->getFont()->getWMode())
|
&& ( (state->getFont()->getWMode())
|
||||||
|| ((state->getFont()->getType() == fontType3) && (!param.process_type3))
|
|| ((state->getFont()->getType() == fontType3) && (!param.process_type3))
|
||||||
)
|
)
|
||||||
@ -65,6 +65,20 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CairoBackgroundRenderer::beginString(GfxState *state, GooString * str)
|
||||||
|
{
|
||||||
|
if (param.proof == 2)
|
||||||
|
proof_begin_string(state);
|
||||||
|
CairoOutputDev::beginString(state, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CairoBackgroundRenderer::endTextObject(GfxState *state)
|
||||||
|
{
|
||||||
|
if (param.proof == 2)
|
||||||
|
proof_end_text_object(state);
|
||||||
|
CairoOutputDev::endTextObject(state);
|
||||||
|
}
|
||||||
|
|
||||||
void CairoBackgroundRenderer::init(PDFDoc * doc)
|
void CairoBackgroundRenderer::init(PDFDoc * doc)
|
||||||
{
|
{
|
||||||
startDoc(doc);
|
startDoc(doc);
|
||||||
|
@ -44,6 +44,10 @@ public:
|
|||||||
double originX, double originY,
|
double originX, double originY,
|
||||||
CharCode code, int nBytes, Unicode *u, int uLen);
|
CharCode code, int nBytes, Unicode *u, int uLen);
|
||||||
|
|
||||||
|
//for proof
|
||||||
|
void beginString(GfxState *state, GooString * str);
|
||||||
|
void endTextObject(GfxState *state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setMimeData(Stream *str, Object *ref, cairo_surface_t *image);
|
virtual void setMimeData(Stream *str, Object *ref, cairo_surface_t *image);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ void SplashBackgroundRenderer::drawChar(GfxState *state, double x, double y,
|
|||||||
// - OR there is special filling method
|
// - OR there is special filling method
|
||||||
// - OR using a writing mode font
|
// - OR using a writing mode font
|
||||||
// - OR using a Type 3 font while param.process_type3 is not enabled
|
// - 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())
|
||||||
&& ( (state->getFont()->getWMode())
|
&& ( (state->getFont()->getWMode())
|
||||||
|| ((state->getFont()->getType() == fontType3) && (!param.process_type3))
|
|| ((state->getFont()->getType() == fontType3) && (!param.process_type3))
|
||||||
@ -90,6 +90,20 @@ void SplashBackgroundRenderer::drawChar(GfxState *state, double x, double y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SplashBackgroundRenderer::beginString(GfxState *state, GooString * str)
|
||||||
|
{
|
||||||
|
if (param.proof == 2)
|
||||||
|
proof_begin_string(state);
|
||||||
|
SplashOutputDev::beginString(state, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashBackgroundRenderer::endTextObject(GfxState *state)
|
||||||
|
{
|
||||||
|
if (param.proof == 2)
|
||||||
|
proof_end_text_object(state);
|
||||||
|
SplashOutputDev::endTextObject(state);
|
||||||
|
}
|
||||||
|
|
||||||
void SplashBackgroundRenderer::init(PDFDoc * doc)
|
void SplashBackgroundRenderer::init(PDFDoc * doc)
|
||||||
{
|
{
|
||||||
startDoc(doc);
|
startDoc(doc);
|
||||||
|
@ -60,6 +60,10 @@ public:
|
|||||||
SplashOutputDev::fill(state);
|
SplashOutputDev::fill(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//for proof
|
||||||
|
void beginString(GfxState *state, GooString * str);
|
||||||
|
void endTextObject(GfxState *state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dump_image(const char * filename, int x1, int y1, int x2, int y2);
|
void dump_image(const char * filename, int x1, int y1, int x2, int y2);
|
||||||
HTMLRenderer * html_renderer;
|
HTMLRenderer * html_renderer;
|
||||||
|
33
src/Color.cc
33
src/Color.cc
@ -1,3 +1,5 @@
|
|||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
@ -6,6 +8,22 @@ namespace pdf2htmlEX {
|
|||||||
|
|
||||||
using std::ostream;
|
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)
|
ostream & operator << (ostream & out, const Color & color)
|
||||||
{
|
{
|
||||||
if(color.transparent)
|
if(color.transparent)
|
||||||
@ -15,4 +33,19 @@ ostream & operator << (ostream & out, const Color & color)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Color::get_gfx_color(GfxColor & gc)
|
||||||
|
{
|
||||||
|
gc.c[0] = rgb.r;
|
||||||
|
gc.c[1] = rgb.g;
|
||||||
|
gc.c[2] = rgb.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Color::distance(const Color & other)
|
||||||
|
{
|
||||||
|
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
|
} // namespace pdf2htmlEX
|
||||||
|
@ -16,6 +16,9 @@ struct Color
|
|||||||
{
|
{
|
||||||
bool transparent;
|
bool transparent;
|
||||||
GfxRGB rgb;
|
GfxRGB rgb;
|
||||||
|
Color();
|
||||||
|
Color(double r, double g, double b, bool transparent = false);
|
||||||
|
Color(const GfxRGB& rgb);
|
||||||
bool operator == (const Color & c) const {
|
bool operator == (const Color & c) const {
|
||||||
if(transparent != c.transparent)
|
if(transparent != c.transparent)
|
||||||
return false;
|
return false;
|
||||||
@ -23,6 +26,9 @@ struct Color
|
|||||||
return true;
|
return true;
|
||||||
return ((rgb.r == c.rgb.r) && (rgb.g == c.rgb.g) && (rgb.b == c.rgb.b));
|
return ((rgb.r == c.rgb.r) && (rgb.g == c.rgb.g) && (rgb.b == c.rgb.b));
|
||||||
}
|
}
|
||||||
|
void get_gfx_color(GfxColor & gc);
|
||||||
|
// Color distance, [0,1].
|
||||||
|
double distance(const Color & other);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & out, const Color & color);
|
std::ostream & operator << (std::ostream & out, const Color & color);
|
||||||
|
@ -76,6 +76,7 @@ struct Param
|
|||||||
std::string tmp_dir;
|
std::string tmp_dir;
|
||||||
int css_draw;
|
int css_draw;
|
||||||
int debug;
|
int debug;
|
||||||
|
int proof;
|
||||||
|
|
||||||
std::string input_filename, output_filename;
|
std::string input_filename, output_filename;
|
||||||
};
|
};
|
||||||
|
@ -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
|
// TODO: css drawings are hidden on print, for annot links, need to fix it for other drawings
|
||||||
// .add("css-draw", ¶m.css_draw, 0, "[experimental and unsupported] CSS drawing")
|
// .add("css-draw", ¶m.css_draw, 0, "[experimental and unsupported] CSS drawing")
|
||||||
.add("debug", ¶m.debug, 0, "print debugging information")
|
.add("debug", ¶m.debug, 0, "print debugging information")
|
||||||
|
.add("proof", ¶m.proof, 0, "texts are drawn on both text layer and background for proof.")
|
||||||
|
|
||||||
// meta
|
// meta
|
||||||
.add("version,v", "print copyright and version info", &show_version_and_exit)
|
.add("version,v", "print copyright and version info", &show_version_and_exit)
|
||||||
|
Loading…
Reference in New Issue
Block a user