1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-12-22 13:00:08 +00:00

letter_space_tracker

This commit is contained in:
Lu Wang 2013-02-05 13:57:11 +08:00
parent f4ae2e26dd
commit 4858f12d9b
8 changed files with 47 additions and 86 deletions

View File

@ -30,6 +30,7 @@
#include "util/StringFormatter.h"
#include "util/TmpFiles.h"
#include "util/misc.h"
#include "util/StateTracker.h"
/*
* Naming Convention
@ -197,7 +198,6 @@ class HTMLRenderer : public OutputDev
long long install_font_size(double font_size);
long long install_transform_matrix(const double * tm);
long long install_letter_space(double letter_space);
long long install_word_space(double word_space);
long long install_fill_color(const GfxRGB * rgb);
long long install_stroke_color(const GfxRGB * rgb);
@ -219,7 +219,6 @@ class HTMLRenderer : public OutputDev
void export_font_size(long long fs_id, double font_size);
void export_transform_matrix(long long tm_id, const double * tm);
void export_letter_space(long long ls_id, double letter_space);
void export_word_space(long long ws_id, double word_space);
void export_fill_color(long long color_id, const GfxRGB * rgb);
void export_stroke_color(long long color_id, const GfxRGB * rgb);
@ -334,9 +333,8 @@ class HTMLRenderer : public OutputDev
double cur_text_tm[6]; // unscaled
// letter spacing
long long cur_ls_id;
double cur_letter_space;
bool letter_space_changed;
LetterSpaceTracker letter_space_tracker;
// word spacing
long long cur_ws_id;
@ -399,7 +397,6 @@ class HTMLRenderer : public OutputDev
std::unordered_map<long long, FontInfo> font_name_map;
std::map<double, long long> font_size_map;
std::map<Matrix, long long, Matrix_less> transform_matrix_map;
std::map<double, long long> letter_space_map;
std::map<double, long long> word_space_map;
std::unordered_map<GfxRGB, long long, GfxRGB_hash, GfxRGB_equal> fill_color_map, stroke_color_map;
std::map<double, long long> whitespace_map;

View File

@ -189,7 +189,7 @@ void HTMLRenderer::TextLineBuffer::set_state (State & state)
state.ids[State::FONT_SIZE_ID] = renderer->cur_fs_id;
state.ids[State::FILL_COLOR_ID] = renderer->cur_fill_color_id;
state.ids[State::STROKE_COLOR_ID] = renderer->cur_stroke_color_id;
state.ids[State::LETTER_SPACE_ID] = renderer->cur_ls_id;
state.ids[State::LETTER_SPACE_ID] = renderer->letter_space_tracker.get_id();
state.ids[State::WORD_SPACE_ID] = renderer->cur_ws_id;
state.ids[State::RISE_ID] = renderer->cur_rise_id;

View File

@ -168,11 +168,6 @@ void HTMLRenderer::export_transform_matrix (long long tm_id, const double * tm)
f_css.fs << "}" << endl;
}
void HTMLRenderer::export_letter_space (long long ls_id, double letter_space)
{
f_css.fs << ".l" << ls_id << "{letter-spacing:" << round(letter_space) << "px;}" << endl;
}
void HTMLRenderer::export_word_space (long long ws_id, double word_space)
{
f_css.fs << ".w" << ws_id << "{word-spacing:" << round(word_space) << "px;}" << endl;

View File

@ -55,6 +55,8 @@ HTMLRenderer::HTMLRenderer(const Param * param)
cur_mapping = new int32_t [0x10000];
cur_mapping2 = new char* [0x100];
width_list = new int [0x10000];
letter_space_tracker.set_param("l", EPS);
}
HTMLRenderer::~HTMLRenderer()
@ -331,6 +333,9 @@ void HTMLRenderer::pre_process(PDFDoc * doc)
void HTMLRenderer::post_process()
{
// dump css
letter_space_tracker.dump_css(f_css.fs);
// close files
f_outline.fs.close();
f_pages.fs.close();

View File

@ -240,18 +240,6 @@ long long HTMLRenderer::install_transform_matrix(const double * tm)
return new_tm_id;
}
long long HTMLRenderer::install_letter_space(double letter_space)
{
auto iter = letter_space_map.lower_bound(letter_space - EPS);
if((iter != letter_space_map.end()) && (equal(iter->first, letter_space)))
return iter->second;
long long new_ls_id = letter_space_map.size();
letter_space_map.insert(make_pair(letter_space, new_ls_id));
export_letter_space(new_ls_id, letter_space);
return new_ls_id;
}
long long HTMLRenderer::install_word_space(double word_space)
{
auto iter = word_space_map.lower_bound(word_space - EPS);

View File

@ -104,8 +104,9 @@ void HTMLRenderer::reset_state()
memcpy(draw_text_tm, ID_MATRIX, sizeof(draw_text_tm));
cur_ttm_id = install_transform_matrix(draw_text_tm);
cur_letter_space = cur_word_space = 0;
cur_ls_id = install_letter_space(cur_letter_space);
letter_space_tracker.reset();
cur_word_space = 0;
cur_ws_id = install_word_space(cur_word_space);
cur_fill_color.r = cur_fill_color.g = cur_fill_color.b = 0;
@ -339,15 +340,10 @@ void HTMLRenderer::check_state_change(GfxState * state)
// letter space
// depends: draw_text_scale
if(all_changed || letter_space_changed || draw_text_scale_changed)
if((all_changed || letter_space_changed || draw_text_scale_changed)
&& (letter_space_tracker.install(state->getCharSpace() * draw_text_scale)))
{
double new_letter_space = state->getCharSpace();
if(!equal(cur_letter_space, new_letter_space))
{
new_line_state = max<NewLineState>(new_line_state, NLS_SPAN);
cur_letter_space = new_letter_space;
cur_ls_id = install_letter_space(cur_letter_space * draw_text_scale);
}
new_line_state = max<NewLineState>(new_line_state, NLS_SPAN);
}
// word space

View File

@ -504,6 +504,7 @@ void HTMLRenderer::drawString(GfxState * state, GooString * s)
return;
auto font = state->getFont();
double cur_letter_space = state->getCharSpace();
// Writing mode fonts and Type 3 fonts are rendered as images
// I don't find a way to display writing mode fonts in HTML except for one div for each character, which is too costly

View File

@ -13,7 +13,7 @@
#include <iostream>
#include <map>
#include <GfxState.h>
#include "util/math.h"
namespace pdf2htmlEX {
@ -25,8 +25,7 @@ class StateTracker<double, Imp>
public:
StateTracker()
: eps(0)
, changed(false)
, imp(static_cast<Imp>(this))
, imp(static_cast<Imp*>(this))
{
reset();
}
@ -38,49 +37,26 @@ public:
}
// usually called at the beginning of a page
void reset(void) { value = imp->default_value(); }
void reset(void) {
value = imp->default_value();
_install(value);
}
// is called when PDF updates the state
void update(GfxState * state) { changed = true; }
/*
* retrive the new state if update() is called recently, or force == true
* install new_value if changed (equal() should be faster than map::lower_bound)
* return if the state has been indeed changed
*/
bool sync(GfxState * state, bool force) {
if(!(changed || force))
return false;
changed = false;
double new_value = imp->get_value(state);
bool install(double new_value) {
if(equal(new_value, value))
return false;
install(new_value);
return true;
return _install(new_value);
}
long long get_id (void) const { return id; }
double get_actual_value (void) const { return actual_value; }
long long install(double new_value) {
value = new_value;
auto iter = value_map.lower_bound(new_value - eps);
if((iter != value_map.end()) && (abs(iter->first - value) <= eps))
{
actual_value = iter->first;
return iter->second;
}
actual_value = new_value;
long long new_id = map.size();
map.insert(make_pair(new_value, new_id));
return new_id;
}
void dump_css(std::ostream & out) {
for(auto iter = map.begin(); iter != map.end(); ++iter)
for(auto iter = value_map.begin(); iter != value_map.end(); ++iter)
{
out << "." << css_class_name << iter->second << "{";
imp->dump_value(out, iter->first);
@ -89,9 +65,26 @@ public:
}
protected:
// this version of install does not check if value has been updated
bool _install(double new_value) {
value = new_value;
auto iter = value_map.lower_bound(new_value - eps);
if((iter != value_map.end()) && (abs(iter->first - value) <= eps))
{
actual_value = iter->first;
id = iter->second;
return false;
}
actual_value = new_value;
id = value_map.size();
value_map.insert(std::make_pair(new_value, id));
return true;
}
const char * css_class_name;
double eps;
bool changed;
Imp * imp;
long long id;
@ -105,8 +98,7 @@ class FontSizeTracker : public StateTracker<double, FontSizeTracker>
public:
double default_value(void) { return 0; }
double get_value(GfxState * state) { return state->getFontSize(); }
void dump_value(std::ostream & out, double value) { out "font-size:" << round(value) << "px;"; }
}
void dump_value(std::ostream & out, double value) { out << "font-size:" << round(value) << "px;"; }
};
class LetterSpaceTracker : public StateTracker<double, LetterSpaceTracker>
@ -114,22 +106,9 @@ class LetterSpaceTracker : public StateTracker<double, LetterSpaceTracker>
public:
double default_value(void) { return 0; }
double get_value(GfxState * state) { return state->getCharSpace(); }
void dump_value(std::ostream & out, double value) { out "font-size:" << round(value) << "px;"; }
}
void dump_value(std::ostream & out, double value) { out << "letter-spacing:" << round(value) << "px;"; }
};
std::map<Matrix, long long, Matrix_less> transform_matrix_map;
std::map<double, long long> letter_space_map;
std::map<double, long long> word_space_map;
std::unordered_map<GfxRGB, long long, GfxRGB_hash, GfxRGB_equal> fill_color_map, stroke_color_map;
std::map<double, long long> whitespace_map;
std::map<double, long long> rise_map;
std::map<double, long long> height_map;
std::map<double, long long> left_map;
} // namespace pdf2htmlEX
#endif //STATETRACKER_H__