mirror of
https://github.com/pdf2htmlEX/pdf2htmlEX.git
synced 2024-12-22 13:00:08 +00:00
check clip changes
This commit is contained in:
parent
c30bc8a353
commit
a82996eeb7
@ -289,6 +289,7 @@ protected:
|
||||
AllStateManager all_manager;
|
||||
HTMLTextState cur_text_state;
|
||||
HTMLLineState cur_line_state;
|
||||
HTMLClipState cur_clip_state;
|
||||
|
||||
HTMLTextPage html_text_page;
|
||||
|
||||
@ -296,7 +297,8 @@ protected:
|
||||
{
|
||||
NLS_NONE,
|
||||
NLS_NEWSTATE,
|
||||
NLS_NEWLINE
|
||||
NLS_NEWLINE,
|
||||
NLS_NEWCLIP
|
||||
} new_line_state;
|
||||
|
||||
// for font reencoding
|
||||
|
@ -119,6 +119,11 @@ void HTMLRenderer::reset_state()
|
||||
cur_line_state.y = 0;
|
||||
memcpy(cur_line_state.transform_matrix, ID_MATRIX, sizeof(cur_line_state.transform_matrix));
|
||||
|
||||
cur_clip_state.xmin = 0;
|
||||
cur_clip_state.xmax = 0;
|
||||
cur_clip_state.ymin = 0;
|
||||
cur_clip_state.ymax = 0;
|
||||
|
||||
cur_tx = cur_ty = 0;
|
||||
draw_tx = draw_ty = 0;
|
||||
|
||||
@ -145,6 +150,14 @@ void HTMLRenderer::reset_state_change()
|
||||
|
||||
clip_changed = false;
|
||||
}
|
||||
|
||||
template<class NewLineState>
|
||||
void set_line_state(NewLineState & cur_ls, NewLineState new_ls)
|
||||
{
|
||||
if(new_ls > cur_ls)
|
||||
cur_ls = new_ls;
|
||||
}
|
||||
|
||||
void HTMLRenderer::check_state_change(GfxState * state)
|
||||
{
|
||||
// DEPENDENCY WARNING
|
||||
@ -154,11 +167,16 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
|
||||
if(all_changed || clip_changed)
|
||||
{
|
||||
//TODO: compare with current clip box
|
||||
double x1, x2, y1, y2;
|
||||
state->getClipBBox(&x1, &y1, &x2, &y2);
|
||||
html_text_page.clip(x1, y1, x2, y2);
|
||||
new_line_state = NLS_NEWLINE;
|
||||
HTMLClipState new_clip_state;
|
||||
state->getClipBBox(&new_clip_state.xmin, &new_clip_state.ymin, &new_clip_state.xmax, &new_clip_state.ymax);
|
||||
if(!(equal(cur_clip_state.xmin, new_clip_state.xmin)
|
||||
&& equal(cur_clip_state.xmax, new_clip_state.xmax)
|
||||
&& equal(cur_clip_state.ymin, new_clip_state.ymin)
|
||||
&& equal(cur_clip_state.ymax, new_clip_state.ymax)))
|
||||
{
|
||||
cur_clip_state = new_clip_state;
|
||||
set_line_state(new_line_state, NLS_NEWCLIP);
|
||||
}
|
||||
}
|
||||
|
||||
bool need_recheck_position = false;
|
||||
@ -191,11 +209,11 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
// TODO: consider the font matrix and estimate the metrics
|
||||
if(new_font_info->is_type3 || cur_text_state.font_info->is_type3)
|
||||
{
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWLINE);
|
||||
set_line_state(new_line_state, NLS_NEWLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
}
|
||||
cur_text_state.font_info = new_font_info;
|
||||
}
|
||||
@ -279,13 +297,13 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
|
||||
if(!equal(new_draw_font_size, cur_text_state.font_size))
|
||||
{
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
cur_text_state.font_size = new_draw_font_size;
|
||||
}
|
||||
|
||||
if(!tm_equal(new_draw_text_tm, cur_line_state.transform_matrix, 4))
|
||||
{
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWLINE);
|
||||
set_line_state(new_line_state, NLS_NEWLINE);
|
||||
memcpy(cur_line_state.transform_matrix, new_draw_text_tm, sizeof(cur_line_state.transform_matrix));
|
||||
}
|
||||
}
|
||||
@ -368,14 +386,14 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
else
|
||||
{
|
||||
cur_text_state.vertical_align = (dy * old_draw_text_scale);
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
}
|
||||
draw_tx = cur_tx;
|
||||
draw_ty = cur_ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWLINE);
|
||||
set_line_state(new_line_state, NLS_NEWLINE);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -392,7 +410,7 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
if(!equal(new_letter_space, cur_text_state.letter_space))
|
||||
{
|
||||
cur_text_state.letter_space = new_letter_space;
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,7 +422,7 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
if(!equal(new_word_space, cur_text_state.word_space))
|
||||
{
|
||||
cur_text_state.word_space = new_word_space;
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,7 +447,7 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
if(!(new_fill_color == cur_text_state.fill_color))
|
||||
{
|
||||
cur_text_state.fill_color = new_fill_color;
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +473,7 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
if(!(new_stroke_color == cur_text_state.stroke_color))
|
||||
{
|
||||
cur_text_state.stroke_color = new_stroke_color;
|
||||
new_line_state = max<NewLineState>(new_line_state, NLS_NEWSTATE);
|
||||
set_line_state(new_line_state, NLS_NEWSTATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,9 +483,14 @@ void HTMLRenderer::check_state_change(GfxState * state)
|
||||
void HTMLRenderer::prepare_text_line(GfxState * state)
|
||||
{
|
||||
if(!(html_text_page.get_cur_line()))
|
||||
new_line_state = NLS_NEWLINE;
|
||||
new_line_state = NLS_NEWCLIP;
|
||||
|
||||
if(new_line_state == NLS_NEWLINE)
|
||||
if(new_line_state >= NLS_NEWCLIP)
|
||||
{
|
||||
html_text_page.clip(cur_clip_state);
|
||||
}
|
||||
|
||||
if(new_line_state >= NLS_NEWLINE)
|
||||
{
|
||||
// update position such that they will be recorded by text_line_buf
|
||||
state->transform(state->getCurX(), state->getCurY(), &cur_line_state.x, &cur_line_state.y);
|
||||
|
@ -233,10 +233,10 @@ void HTMLTextLine::clear(void)
|
||||
text.clear();
|
||||
}
|
||||
|
||||
void HTMLTextLine::clip(double x1, double y1, double x2, double y2)
|
||||
void HTMLTextLine::clip(const HTMLClipState & clip_state)
|
||||
{
|
||||
clip_x1 = x1;
|
||||
clip_y1 = y1;
|
||||
clip_x1 = clip_state.xmin;
|
||||
clip_y1 = clip_state.ymin;
|
||||
}
|
||||
|
||||
void HTMLTextLine::prepare(void)
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
bool text_empty(void) const { return text.empty(); }
|
||||
void clear(void);
|
||||
|
||||
void clip(double x1, double y1, double x2, double y2);
|
||||
void clip(const HTMLClipState &);
|
||||
|
||||
/*
|
||||
* Optimize and calculate necessary values
|
||||
|
@ -30,39 +30,49 @@ void HTMLTextPage::dump_text(ostream & out)
|
||||
optimize();
|
||||
|
||||
//push a dummy entry for convenience
|
||||
clip_boxes.emplace_back(0, 0, page_width, page_height, text_lines.size());
|
||||
clips.emplace_back(HTMLClipState{0, 0, page_width, page_height}, text_lines.size());
|
||||
|
||||
ClipBox cur_cb(0, 0, page_width, page_height, 0);
|
||||
Clip cur_clip(HTMLClipState{0, 0, page_width, page_height}, 0);
|
||||
bool has_clip = false;
|
||||
|
||||
auto text_line_iter = text_lines.begin();
|
||||
for(auto clip_iter = clip_boxes.begin(); clip_iter != clip_boxes.end(); ++clip_iter)
|
||||
for(auto clip_iter = clips.begin(); clip_iter != clips.end(); ++clip_iter)
|
||||
{
|
||||
if(has_clip)
|
||||
{
|
||||
out << "<div class=\"" << CSS::CLIP_CN
|
||||
<< " " << CSS::LEFT_CN << all_manager.left.install(cur_cb.x1)
|
||||
<< " " << CSS::BOTTOM_CN << all_manager.bottom.install(cur_cb.y1)
|
||||
<< " " << CSS::WIDTH_CN << all_manager.width.install(cur_cb.x2 - cur_cb.x1)
|
||||
<< " " << CSS::HEIGHT_CN << all_manager.height.install(cur_cb.y2 - cur_cb.y1)
|
||||
<< "\">";
|
||||
}
|
||||
|
||||
auto next_text_line_iter = text_lines.begin() + clip_iter->start_idx;
|
||||
while(text_line_iter != next_text_line_iter)
|
||||
if(text_line_iter != next_text_line_iter)
|
||||
{
|
||||
(*text_line_iter)->clip(cur_cb.x1, cur_cb.y1, cur_cb.x2, cur_cb.y2);
|
||||
(*text_line_iter)->dump_text(out);
|
||||
++text_line_iter;
|
||||
}
|
||||
if(has_clip)
|
||||
{
|
||||
out << "</div>";
|
||||
const auto & cs = cur_clip.clip_state;
|
||||
if(has_clip)
|
||||
{
|
||||
out << "<div class=\"" << CSS::CLIP_CN
|
||||
<< " " << CSS::LEFT_CN << all_manager.left.install(cs.xmin)
|
||||
<< " " << CSS::BOTTOM_CN << all_manager.bottom.install(cs.ymin)
|
||||
<< " " << CSS::WIDTH_CN << all_manager.width.install(cs.xmax - cs.xmin)
|
||||
<< " " << CSS::HEIGHT_CN << all_manager.height.install(cs.ymax - cs.ymin)
|
||||
<< "\">";
|
||||
}
|
||||
|
||||
while(text_line_iter != next_text_line_iter)
|
||||
{
|
||||
if(has_clip)
|
||||
{
|
||||
(*text_line_iter)->clip(cs);
|
||||
}
|
||||
(*text_line_iter)->dump_text(out);
|
||||
++text_line_iter;
|
||||
}
|
||||
if(has_clip)
|
||||
{
|
||||
out << "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
cur_cb = *clip_iter;
|
||||
has_clip = !(equal(0, cur_cb.x1) && equal(0, cur_cb.y1)
|
||||
&& equal(page_width, cur_cb.x2) && equal(page_height, cur_cb.y2));
|
||||
{
|
||||
cur_clip = *clip_iter;
|
||||
const auto & cs = cur_clip.clip_state;
|
||||
has_clip = !(equal(0, cs.xmin) && equal(0, cs.ymin)
|
||||
&& equal(page_width, cs.xmax) && equal(page_height, cs.ymax));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +84,7 @@ void HTMLTextPage::dump_css(ostream & out)
|
||||
void HTMLTextPage::clear(void)
|
||||
{
|
||||
text_lines.clear();
|
||||
clip_boxes.clear();
|
||||
clips.clear();
|
||||
cur_line = nullptr;
|
||||
}
|
||||
|
||||
@ -94,32 +104,21 @@ void HTMLTextPage::set_page_size(double width, double height)
|
||||
page_height = height;
|
||||
}
|
||||
|
||||
void HTMLTextPage::clip(double x1, double y1, double x2, double y2)
|
||||
void HTMLTextPage::clip(const HTMLClipState & clip_state)
|
||||
{
|
||||
if(!clip_boxes.empty())
|
||||
if(!clips.empty())
|
||||
{
|
||||
auto & cb = clip_boxes.back();
|
||||
if(cb.start_idx == text_lines.size())
|
||||
auto & clip = clips.back();
|
||||
if(clip.start_idx == text_lines.size())
|
||||
{
|
||||
/*
|
||||
* Previous ClipBox is not used
|
||||
*/
|
||||
cb.x1 = x1;
|
||||
cb.y1 = y1;
|
||||
cb.x2 = x2;
|
||||
cb.y2 = y2;
|
||||
return;
|
||||
}
|
||||
if(equal(cb.x1, x1) && equal(cb.y1, y1)
|
||||
&& equal(cb.x2, x2) && equal(cb.y2, y2))
|
||||
{
|
||||
/*
|
||||
* same as previous ClipBox
|
||||
*/
|
||||
clip.clip_state = clip_state;
|
||||
return;
|
||||
}
|
||||
}
|
||||
clip_boxes.emplace_back(x1, y1, x2, y2, text_lines.size());
|
||||
clips.emplace_back(clip_state, text_lines.size());
|
||||
}
|
||||
|
||||
void HTMLTextPage::optimize(void)
|
||||
|
@ -22,7 +22,6 @@ namespace pdf2htmlEX {
|
||||
*
|
||||
* contains a series of HTMLTextLine
|
||||
*/
|
||||
|
||||
class HTMLTextPage
|
||||
{
|
||||
public:
|
||||
@ -38,7 +37,7 @@ public:
|
||||
|
||||
/* for clipping */
|
||||
void set_page_size(double width, double height);
|
||||
void clip(double x1, double y1, double x2, double y2);
|
||||
void clip(const HTMLClipState & clip_state);
|
||||
|
||||
private:
|
||||
void optimize(void);
|
||||
@ -50,14 +49,14 @@ private:
|
||||
|
||||
std::vector<std::unique_ptr<HTMLTextLine>> text_lines;
|
||||
|
||||
struct ClipBox {
|
||||
ClipBox(double x1, double y1, double x2, double y2, size_t start_idx)
|
||||
:x1(x1),y1(y1),x2(x2),y2(y2),start_idx(start_idx)
|
||||
{ }
|
||||
double x1, y1, x2, y2;
|
||||
struct Clip {
|
||||
HTMLClipState clip_state;
|
||||
size_t start_idx;
|
||||
Clip(const HTMLClipState & clip_state, size_t start_idx)
|
||||
:clip_state(clip_state),start_idx(start_idx)
|
||||
{ }
|
||||
};
|
||||
std::vector<ClipBox> clip_boxes;
|
||||
std::vector<Clip> clips;
|
||||
};
|
||||
|
||||
} //namespace pdf2htmlEX
|
||||
|
Loading…
Reference in New Issue
Block a user