mirror of
https://github.com/pdf2htmlEX/pdf2htmlEX.git
synced 2024-12-22 04:50:09 +00:00
purge css draw
This commit is contained in:
parent
80b8e1f5de
commit
ffa7ead922
@ -50,16 +50,6 @@ public:
|
||||
double originX, double originY,
|
||||
CharCode code, int nBytes, Unicode *u, int uLen);
|
||||
|
||||
virtual void stroke(GfxState *state) {
|
||||
if(!html_renderer->can_stroke(state))
|
||||
SplashOutputDev::stroke(state);
|
||||
}
|
||||
|
||||
virtual void fill(GfxState *state) {
|
||||
if(!html_renderer->can_fill(state))
|
||||
SplashOutputDev::fill(state);
|
||||
}
|
||||
|
||||
//for proof
|
||||
void beginTextObject(GfxState *state);
|
||||
void beginString(GfxState *state, GooString * str);
|
||||
|
@ -139,17 +139,13 @@ public:
|
||||
GfxImageColorMap *maskColorMap,
|
||||
GBool maskInterpolate);
|
||||
|
||||
virtual void stroke(GfxState *state); ////{ css_do_path(state, false); }
|
||||
virtual void fill(GfxState *state); ////{ css_do_path(state, true); }
|
||||
virtual void stroke(GfxState *state);
|
||||
virtual void fill(GfxState *state);
|
||||
virtual void eoFill(GfxState *state);
|
||||
virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax);
|
||||
|
||||
virtual void processLink(AnnotLink * al);
|
||||
|
||||
/* capacity test */
|
||||
bool can_stroke(GfxState *state) { return false; } ////{ return css_do_path(state, false, true); }
|
||||
bool can_fill(GfxState *state) { return false; } ////{ return css_do_path(state, true, true); }
|
||||
|
||||
/*
|
||||
* Covered text handling.
|
||||
*/
|
||||
@ -219,29 +215,6 @@ protected:
|
||||
// make sure the current HTML style consistent with PDF
|
||||
void prepare_text_line(GfxState * state);
|
||||
|
||||
#if 0 //disable CSS drawing
|
||||
////////////////////////////////////////////////////
|
||||
// CSS drawing
|
||||
////////////////////////////////////////////////////
|
||||
/*
|
||||
* test_only is for capacity check
|
||||
*/
|
||||
bool css_do_path(GfxState *state, bool fill, bool test_only = false);
|
||||
/*
|
||||
* coordinates are to transformed by state->getCTM()
|
||||
* (x,y) should be the bottom-left corner INCLUDING border
|
||||
* w,h should be the metrics WITHOUT border
|
||||
*
|
||||
* line_color & fill_color may be specified as nullptr to indicate none
|
||||
* style_function & style_function_data may be provided to provide more styles
|
||||
*/
|
||||
void css_draw_rectangle(double x, double y, double w, double h, const double * tm,
|
||||
double * line_width_array, int line_width_count,
|
||||
const GfxRGB * line_color, const GfxRGB * fill_color,
|
||||
void (*style_function)(void *, std::ostream &) = nullptr, void * style_function_data = nullptr );
|
||||
#endif //disable CSS drawing
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// PDF stuffs
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -62,393 +62,4 @@ GBool HTMLRenderer::axialShadedFill(GfxState *state, GfxAxialShading *shading, d
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0 //disable css drawing
|
||||
static bool is_horizontal_line(GfxSubpath * path)
|
||||
{
|
||||
return ((path->getNumPoints() == 2)
|
||||
&& (!path->getCurve(1))
|
||||
&& (equal(path->getY(0), path->getY(1))));
|
||||
}
|
||||
|
||||
static bool is_vertical_line(GfxSubpath * path)
|
||||
{
|
||||
return ((path->getNumPoints() == 2)
|
||||
&& (!path->getCurve(1))
|
||||
&& (equal(path->getX(0), path->getX(1))));
|
||||
}
|
||||
|
||||
static bool is_rectangle(GfxSubpath * path)
|
||||
{
|
||||
if (!(((path->getNumPoints() != 4) && (path->isClosed()))
|
||||
|| ((path->getNumPoints() == 5)
|
||||
&& equal(path->getX(0), path->getX(4))
|
||||
&& equal(path->getY(0), path->getY(4)))))
|
||||
return false;
|
||||
|
||||
for(int i = 1; i < path->getNumPoints(); ++i)
|
||||
if(path->getCurve(i))
|
||||
return false;
|
||||
|
||||
return (equal(path->getY(0), path->getY(1))
|
||||
&& equal(path->getX(1), path->getX(2))
|
||||
&& equal(path->getY(2), path->getY(3))
|
||||
&& equal(path->getX(3), path->getX(0)))
|
||||
|| (equal(path->getX(0), path->getX(1))
|
||||
&& equal(path->getY(1), path->getY(2))
|
||||
&& equal(path->getX(2), path->getX(3))
|
||||
&& equal(path->getY(3), path->getY(0)));
|
||||
}
|
||||
|
||||
static void get_shading_bbox(GfxState * state, GfxShading * shading,
|
||||
double & x1, double & y1, double & x2, double & y2)
|
||||
{
|
||||
// from SplashOutputDev.cc in poppler
|
||||
if(shading->getHasBBox())
|
||||
{
|
||||
shading->getBBox(&x1, &y1, &x2, &y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
state->getClipBBox(&x1, &y1, &x2, &y2);
|
||||
Matrix ctm, ictm;
|
||||
state->getCTM(&ctm);
|
||||
ctm.invertTo(&ictm);
|
||||
|
||||
double x[4], y[4];
|
||||
ictm.transform(x1, y1, &x[0], &y[0]);
|
||||
ictm.transform(x2, y1, &x[1], &y[1]);
|
||||
ictm.transform(x1, y2, &x[2], &y[2]);
|
||||
ictm.transform(x2, y2, &x[3], &y[3]);
|
||||
|
||||
x1 = x2 = x[0];
|
||||
y1 = y2 = y[0];
|
||||
|
||||
for(int i = 1; i < 4; ++i)
|
||||
{
|
||||
x1 = min<double>(x1, x[i]);
|
||||
y1 = min<double>(y1, y[i]);
|
||||
x2 = max<double>(x2, x[i]);
|
||||
y2 = max<double>(y2, y[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the coordinate system in HTML and PDF are different
|
||||
* This functions returns the angle of vector (dx,dy) in the PDF coordinate system, in rad
|
||||
*/
|
||||
static double get_angle(double dx, double dy)
|
||||
{
|
||||
double r = hypot(dx, dy);
|
||||
|
||||
/*
|
||||
* acos always returns [0, pi]
|
||||
*/
|
||||
double ang = acos(dx / r);
|
||||
/*
|
||||
* for angle below x-axis
|
||||
*/
|
||||
if(dy < 0)
|
||||
ang = -ang;
|
||||
|
||||
return ang;
|
||||
}
|
||||
|
||||
class LinearGradient
|
||||
{
|
||||
public:
|
||||
LinearGradient(GfxAxialShading * shading,
|
||||
double x1, double y1, double x2, double y2);
|
||||
|
||||
void dumpto (ostream & out);
|
||||
|
||||
static void style_function (void * p, ostream & out)
|
||||
{
|
||||
static_cast<LinearGradient*>(p)->dumpto(out);
|
||||
}
|
||||
|
||||
// TODO, add alpha
|
||||
|
||||
class ColorStop
|
||||
{
|
||||
public:
|
||||
GfxRGB rgb;
|
||||
double pos; // [0,1]
|
||||
};
|
||||
|
||||
vector<ColorStop> stops;
|
||||
double angle;
|
||||
};
|
||||
|
||||
LinearGradient::LinearGradient (GfxAxialShading * shading,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
// coordinate for t = 0 and t = 1
|
||||
double t0x, t0y, t1x, t1y;
|
||||
shading->getCoords(&t0x, &t0y, &t1x, &t1y);
|
||||
|
||||
angle = get_angle(t1x - t0x, t1y - t0y);
|
||||
|
||||
// get the range of t in the box
|
||||
// from GfxState.cc in poppler
|
||||
double box_tmin, box_tmax;
|
||||
{
|
||||
double idx = t1x - t0x;
|
||||
double idy = t1y - t0y;
|
||||
double inv_len = 1.0 / (idx * idx + idy * idy);
|
||||
idx *= inv_len;
|
||||
idy *= inv_len;
|
||||
|
||||
// t of (x1,y1)
|
||||
box_tmin = box_tmax = (x1 - t0x) * idx + (y1 - t0y) * idy;
|
||||
double tdx = (x2 - x1) * idx;
|
||||
if(tdx < 0)
|
||||
box_tmin += tdx;
|
||||
else
|
||||
box_tmax += tdx;
|
||||
|
||||
double tdy = (y2 - y1) * idy;
|
||||
if(tdy < 0)
|
||||
box_tmin += tdy;
|
||||
else
|
||||
box_tmax += tdy;
|
||||
}
|
||||
|
||||
// get the domain of t in the box
|
||||
double domain_tmin = max<double>(box_tmin, shading->getDomain0());
|
||||
double domain_tmax = min<double>(box_tmax, shading->getDomain1());
|
||||
|
||||
// TODO: better sampling
|
||||
// TODO: check background color
|
||||
{
|
||||
stops.clear();
|
||||
double tstep = (domain_tmax - domain_tmin) / 13.0;
|
||||
for(double t = domain_tmin; t <= domain_tmax; t += tstep)
|
||||
{
|
||||
GfxColor color;
|
||||
shading->getColor(t, &color);
|
||||
|
||||
ColorStop stop;
|
||||
shading->getColorSpace()->getRGB(&color, &stop.rgb);
|
||||
stop.pos = (t - box_tmin) / (box_tmax - box_tmin);
|
||||
|
||||
stops.push_back(stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LinearGradient::dumpto (ostream & out)
|
||||
{
|
||||
auto prefixes = {"", "-ms-", "-webkit-"};
|
||||
for(auto iter = prefixes.begin(); iter != prefixes.end(); ++iter)
|
||||
{
|
||||
out << "background-image:" << (*iter) << "linear-gradient(" << round(angle) << "rad";
|
||||
for(auto iter2 = stops.begin(); iter2 != stops.end(); ++iter2)
|
||||
{
|
||||
out << "," << (iter2->rgb) << " " << round((iter2->pos) * 100) << "%";
|
||||
}
|
||||
out << ");";
|
||||
}
|
||||
}
|
||||
|
||||
GBool HTMLRenderer::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax)
|
||||
{
|
||||
if(!(param.css_draw)) return gFalse;
|
||||
|
||||
double x1, y1, x2, y2;
|
||||
get_shading_bbox(state, shading, x1, y1, x2, y2);
|
||||
|
||||
LinearGradient lg(shading, x1, y1, x2, y2);
|
||||
|
||||
// TODO: check background color
|
||||
css_draw_rectangle(x1, y1, x2-x1, y2-y1, state->getCTM(),
|
||||
nullptr, 0,
|
||||
nullptr, nullptr,
|
||||
LinearGradient::style_function, &lg);
|
||||
|
||||
return gTrue;
|
||||
}
|
||||
|
||||
//TODO track state
|
||||
//TODO connection style
|
||||
bool HTMLRenderer::css_do_path(GfxState *state, bool fill, bool test_only)
|
||||
{
|
||||
if(!(param.css_draw)) return false;
|
||||
|
||||
GfxPath * path = state->getPath();
|
||||
/*
|
||||
* capacity check
|
||||
*/
|
||||
for(int i = 0; i < path->getNumSubpaths(); ++i)
|
||||
{
|
||||
GfxSubpath * subpath = path->getSubpath(i);
|
||||
if(!(is_horizontal_line(subpath)
|
||||
|| is_vertical_line(subpath)
|
||||
|| is_rectangle(subpath)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(test_only)
|
||||
return true;
|
||||
|
||||
for(int i = 0; i < path->getNumSubpaths(); ++i)
|
||||
{
|
||||
GfxSubpath * subpath = path->getSubpath(i);
|
||||
|
||||
if(is_horizontal_line(subpath))
|
||||
{
|
||||
double x1 = subpath->getX(0);
|
||||
double x2 = subpath->getX(1);
|
||||
double y = subpath->getY(0);
|
||||
if(x1 > x2) swap(x1, x2);
|
||||
|
||||
GfxRGB stroke_color;
|
||||
state->getStrokeRGB(&stroke_color);
|
||||
|
||||
double lw = state->getLineWidth();
|
||||
|
||||
css_draw_rectangle(x1, y - lw/2, x2-x1, lw, state->getCTM(),
|
||||
nullptr, 0,
|
||||
nullptr, &stroke_color);
|
||||
}
|
||||
else if(is_vertical_line(subpath))
|
||||
{
|
||||
double x = subpath->getX(0);
|
||||
double y1 = subpath->getY(0);
|
||||
double y2 = subpath->getY(1);
|
||||
if(y1 > y2) swap(y1, y2);
|
||||
|
||||
GfxRGB stroke_color;
|
||||
state->getStrokeRGB(&stroke_color);
|
||||
|
||||
double lw = state->getLineWidth();
|
||||
|
||||
css_draw_rectangle(x-lw/2, y1, lw, y2-y1, state->getCTM(),
|
||||
nullptr, 0,
|
||||
nullptr, &stroke_color);
|
||||
}
|
||||
else if(is_rectangle(subpath))
|
||||
{
|
||||
double x1 = subpath->getX(0);
|
||||
double x2 = subpath->getX(2);
|
||||
double y1 = subpath->getY(0);
|
||||
double y2 = subpath->getY(2);
|
||||
|
||||
if(x1 > x2) swap(x1, x2);
|
||||
if(y1 > y2) swap(y1, y2);
|
||||
|
||||
double x,y,w,h,lw[2];
|
||||
css_fix_rectangle_border_width(x1, y1, x2, y2, (fill ? 0.0 : state->getLineWidth()),
|
||||
x,y,w,h,lw[0],lw[1]);
|
||||
|
||||
GfxRGB stroke_color;
|
||||
if(!fill) state->getStrokeRGB(&stroke_color);
|
||||
|
||||
GfxRGB fill_color;
|
||||
if(fill) state->getFillRGB(&fill_color);
|
||||
|
||||
int lw_count = 2;
|
||||
|
||||
GfxRGB * ps = fill ? nullptr : (&stroke_color);
|
||||
GfxRGB * pf = fill ? (&fill_color) : nullptr;
|
||||
|
||||
if(equal(h, 0) || equal(w, 0))
|
||||
{
|
||||
// orthogonal line
|
||||
|
||||
// TODO: check length
|
||||
pf = ps;
|
||||
ps = nullptr;
|
||||
h += lw[0];
|
||||
w += lw[1];
|
||||
}
|
||||
|
||||
css_draw_rectangle(x, y, w, h, state->getCTM(),
|
||||
lw, lw_count,
|
||||
ps, pf);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HTMLRenderer::css_draw_rectangle(double x, double y, double w, double h, const double * tm,
|
||||
double * line_width_array, int line_width_count,
|
||||
const GfxRGB * line_color, const GfxRGB * fill_color,
|
||||
void (*style_function)(void *, ostream &), void * style_function_data)
|
||||
{
|
||||
double new_tm[6];
|
||||
memcpy(new_tm, tm, sizeof(new_tm));
|
||||
|
||||
tm_transform(new_tm, x, y);
|
||||
|
||||
double scale = 1.0;
|
||||
{
|
||||
static const double sqrt2 = sqrt(2.0);
|
||||
|
||||
double i1 = (new_tm[0] + new_tm[2]) / sqrt2;
|
||||
double i2 = (new_tm[1] + new_tm[3]) / sqrt2;
|
||||
scale = hypot(i1, i2);
|
||||
if(is_positive(scale))
|
||||
{
|
||||
for(int i = 0; i < 4; ++i)
|
||||
new_tm[i] /= scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
(*f_curpage) << "<div class=\"" << CSS::CSS_DRAW_CN
|
||||
<< ' ' << CSS::TRANSFORM_MATRIX_CN << all_manager.transform_matrix.install(new_tm)
|
||||
<< "\" style=\"";
|
||||
|
||||
if(line_color)
|
||||
{
|
||||
(*f_curpage) << "border-color:" << *line_color << ";";
|
||||
|
||||
(*f_curpage) << "border-width:";
|
||||
for(int i = 0; i < line_width_count; ++i)
|
||||
{
|
||||
if(i > 0) (*f_curpage) << ' ';
|
||||
|
||||
double lw = line_width_array[i] * scale;
|
||||
(*f_curpage) << round(lw);
|
||||
if(is_positive(lw)) (*f_curpage) << "px";
|
||||
}
|
||||
(*f_curpage) << ";";
|
||||
}
|
||||
else
|
||||
{
|
||||
(*f_curpage) << "border:none;";
|
||||
}
|
||||
|
||||
if(fill_color)
|
||||
{
|
||||
(*f_curpage) << "background-color:" << (*fill_color) << ";";
|
||||
}
|
||||
else
|
||||
{
|
||||
(*f_curpage) << "background-color:transparent;";
|
||||
}
|
||||
|
||||
if(style_function)
|
||||
{
|
||||
style_function(style_function_data, (*f_curpage));
|
||||
}
|
||||
|
||||
(*f_curpage) << "bottom:" << round(y) << "px;"
|
||||
<< "left:" << round(x) << "px;"
|
||||
<< "width:" << round(w * scale) << "px;"
|
||||
<< "height:" << round(h * scale) << "px;";
|
||||
|
||||
(*f_curpage) << "\"></div>";
|
||||
}
|
||||
#endif //disable css drawing
|
||||
|
||||
|
||||
} // namespace pdf2htmlEX
|
||||
|
@ -75,7 +75,6 @@ struct Param
|
||||
int clean_tmp;
|
||||
std::string data_dir;
|
||||
std::string tmp_dir;
|
||||
int css_draw;
|
||||
int debug;
|
||||
int proof;
|
||||
|
||||
|
@ -204,8 +204,6 @@ void parse_options (int argc, char **argv)
|
||||
.add("clean-tmp", ¶m.clean_tmp, 1, "remove temporary files after conversion")
|
||||
.add("tmp-dir", ¶m.tmp_dir, param.tmp_dir, "specify the location of temporary directory.")
|
||||
.add("data-dir", ¶m.data_dir, param.data_dir, "specify data directory")
|
||||
// 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("debug", ¶m.debug, 0, "print debugging information")
|
||||
.add("proof", ¶m.proof, 0, "texts are drawn on both text layer and background for proof.")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user