2012-10-01 17:59:04 +00:00
|
|
|
/*
|
|
|
|
* Draw.cc
|
|
|
|
*
|
|
|
|
* Handling path drawing
|
|
|
|
*
|
|
|
|
* by WangLu
|
|
|
|
* 2012.10.01
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "HTMLRenderer.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "namespace.h"
|
|
|
|
|
|
|
|
namespace pdf2htmlEX {
|
|
|
|
|
|
|
|
using std::swap;
|
|
|
|
|
|
|
|
static bool is_horizontal_line(GfxSubpath * path)
|
|
|
|
{
|
|
|
|
return ((path->getNumPoints() == 2)
|
|
|
|
&& (!path->getCurve(1))
|
|
|
|
&& (_equal(path->getY(0), path->getY(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;
|
|
|
|
|
2012-10-01 20:06:38 +00:00
|
|
|
for(int i = 1; i < path->getNumPoints(); ++i)
|
|
|
|
if(path->getCurve(i))
|
|
|
|
return false;
|
|
|
|
|
2012-10-01 17:59:04 +00:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO track state
|
|
|
|
//TODO connection style
|
2012-10-01 20:06:38 +00:00
|
|
|
void HTMLRenderer::css_draw(GfxState *state, bool fill)
|
2012-10-01 17:59:04 +00:00
|
|
|
{
|
2012-10-02 08:06:08 +00:00
|
|
|
if(!(param->css_draw)) return;
|
|
|
|
|
2012-10-01 17:59:04 +00:00
|
|
|
GfxPath * path = state->getPath();
|
|
|
|
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);
|
|
|
|
|
2012-10-01 20:06:38 +00:00
|
|
|
GfxRGB stroke_color;
|
|
|
|
state->getStrokeRGB(&stroke_color);
|
2012-10-01 17:59:04 +00:00
|
|
|
|
2012-10-01 20:06:38 +00:00
|
|
|
double lw = state->getLineWidth();
|
|
|
|
|
|
|
|
css_draw_rectangle(x1, y - lw/2, x2-x1, lw,
|
|
|
|
nullptr, 0,
|
|
|
|
nullptr, &stroke_color, state);
|
2012-10-01 17:59:04 +00:00
|
|
|
}
|
|
|
|
else if (is_rectangle(subpath))
|
|
|
|
{
|
|
|
|
close_text_line();
|
|
|
|
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);
|
|
|
|
|
2012-10-01 20:06:38 +00:00
|
|
|
double x,y,w,h,lw[2];
|
2012-10-01 20:31:55 +00:00
|
|
|
css_fix_rectangle_border_width(x1, y1, x2, y2, (fill ? 0.0 : state->getLineWidth()),
|
2012-10-01 20:06:38 +00:00
|
|
|
x,y,w,h,lw[0],lw[1]);
|
|
|
|
|
|
|
|
GfxRGB stroke_color;
|
2012-10-01 20:31:55 +00:00
|
|
|
if(!fill) state->getStrokeRGB(&stroke_color);
|
2012-10-01 20:06:38 +00:00
|
|
|
|
|
|
|
GfxRGB fill_color;
|
|
|
|
if(fill) state->getFillRGB(&fill_color);
|
|
|
|
|
|
|
|
int lw_count = 2;
|
|
|
|
|
2012-10-01 20:31:55 +00:00
|
|
|
GfxRGB * ps = fill ? nullptr : (&stroke_color);
|
2012-10-01 20:06:38 +00:00
|
|
|
GfxRGB * pf = fill ? (&fill_color) : nullptr;
|
|
|
|
|
|
|
|
if(_equal(h, 0) || _equal(w, 0))
|
|
|
|
{
|
|
|
|
// orthogonal line
|
|
|
|
|
|
|
|
// TODO: check length
|
2012-10-01 20:31:55 +00:00
|
|
|
pf = ps;
|
2012-10-01 20:06:38 +00:00
|
|
|
ps = nullptr;
|
|
|
|
h += lw[0];
|
|
|
|
w += lw[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
css_draw_rectangle(x, y, w, h,
|
|
|
|
lw, lw_count,
|
|
|
|
ps, pf, state);
|
2012-10-01 17:59:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-01 20:06:38 +00:00
|
|
|
void HTMLRenderer::css_draw_rectangle(double x, double y, double w, double h,
|
|
|
|
double * line_width_array, int line_width_count,
|
|
|
|
const GfxRGB * line_color, const GfxRGB * fill_color,
|
|
|
|
GfxState * state)
|
|
|
|
{
|
|
|
|
close_text_line();
|
|
|
|
|
2012-10-02 08:06:08 +00:00
|
|
|
double ctm[6];
|
|
|
|
memcpy(ctm, state->getCTM(), sizeof(ctm));
|
|
|
|
|
|
|
|
_transform(ctm, x, y);
|
|
|
|
|
|
|
|
double scale = 1.0;
|
|
|
|
{
|
|
|
|
double i1 = ctm[0] + ctm[2];
|
|
|
|
double i2 = ctm[1] + ctm[3];
|
|
|
|
scale = sqrt((i1 * i1 + i2 * i2) / 2.0);
|
|
|
|
if(_is_positive(scale))
|
|
|
|
{
|
|
|
|
for(int i = 0; i < 4; ++i)
|
|
|
|
ctm[i] /= scale;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scale = 1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
html_fout << "<div class=\"Cd t" << install_transform_matrix(ctm) << "\" style=\"";
|
2012-10-01 20:06:38 +00:00
|
|
|
|
|
|
|
if(line_color)
|
|
|
|
{
|
|
|
|
html_fout << "border-color:" << *line_color << ";";
|
|
|
|
|
|
|
|
html_fout << "border-width:";
|
|
|
|
for(int i = 0; i < line_width_count; ++i)
|
|
|
|
{
|
|
|
|
if(i > 0) html_fout << ' ';
|
|
|
|
|
2012-10-02 08:06:08 +00:00
|
|
|
double lw = line_width_array[i] * scale;
|
2012-10-01 20:06:38 +00:00
|
|
|
html_fout << _round(lw);
|
2012-10-02 08:06:08 +00:00
|
|
|
if(_is_positive(lw)) html_fout << "px";
|
2012-10-01 20:06:38 +00:00
|
|
|
}
|
|
|
|
html_fout << ";";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
html_fout << "border:none;";
|
|
|
|
}
|
|
|
|
|
|
|
|
if(fill_color)
|
|
|
|
{
|
|
|
|
html_fout << "background-color:" << (*fill_color) << ";";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
html_fout << "background-color:transparent;";
|
|
|
|
}
|
|
|
|
|
|
|
|
html_fout << "bottom:" << _round(y) << "px;"
|
|
|
|
<< "left:" << _round(x) << "px;"
|
2012-10-02 08:06:08 +00:00
|
|
|
<< "width:" << _round(w * scale) << "px;"
|
|
|
|
<< "height:" << _round(h * scale) << "px;";
|
2012-10-01 20:26:13 +00:00
|
|
|
|
|
|
|
html_fout << "\"></div>";
|
2012-10-01 20:06:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-01 17:59:04 +00:00
|
|
|
} // namespace pdf2htmlEX
|