DIV // has to open a new
} new_line_state;
// The order is according to the appearance in check_state_change
// any state changed
bool all_changed;
// current position
double cur_tx, cur_ty; // real text position, in text coords
bool text_pos_changed;
// font & size
const FontInfo * cur_font_info;
double cur_font_size;
long long cur_fs_id;
bool font_changed;
// transform matrix
long long cur_tm_id;
bool ctm_changed;
bool text_mat_changed;
// horizontal scaling
bool hori_scale_changed;
// this is CTM * TextMAT in PDF, not only CTM
// [4] and [5] are ignored,
// as we'll calculate the position of the origin separately
// TODO: changed this for images
double cur_ctm[6]; // unscaled
// letter spacing
long long cur_ls_id;
double cur_letter_space;
bool letter_space_changed;
// word spacing
long long cur_ws_id;
double cur_word_space;
bool word_space_changed;
// color
long long cur_color_id;
GfxRGB cur_color;
bool color_changed;
// rise
long long cur_rise_id;
double cur_rise;
bool rise_changed;
// optimize for web
// we try to render the final font size directly
// to reduce the effect of ctm as much as possible
// draw_ctm is cur_ctm scaled by 1/draw_scale,
// so everything redenered should be multiplied by draw_scale
double draw_ctm[6];
double draw_font_size;
double draw_scale;
// the position of next char, in text coords
// this is actual position (in HTML), which might be different from cur_tx/ty (in PDF)
// also keep in mind that they are not the final position, as they will be transform by CTM (also true for cur_tx/ty)
double draw_tx, draw_ty;
// some metrics have to be determined after all elements in the lines have been seen
class LineBuffer {
public:
LineBuffer (HTMLRenderer * renderer) : renderer(renderer) { }
class State {
public:
void begin(std::ostream & out, const State * prev_state);
void end(std::ostream & out) const;
void hash(void);
int diff(const State & s) const;
enum {
FONT_ID,
FONT_SIZE_ID,
COLOR_ID,
LETTER_SPACE_ID,
WORD_SPACE_ID,
RISE_ID,
ID_COUNT
};
long long ids[ID_COUNT];
double ascent;
double descent;
double draw_font_size;
size_t start_idx; // index of the first Text using this state
// for optimzation
long long hash_value;
int depth; // the depth in the state tree
bool need_close;
static const char * format_str; // class names for each id
};
class Offset {
public:
size_t start_idx; // should put this idx before text[start_idx];
double width;
};
void reset(GfxState * state);
void append_unicodes(const Unicode * u, int l);
void append_offset(double width);
void append_state(void);
void flush(void);
private:
// retrieve state from renderer
void set_state(State & state);
// build the state tree in order to minimize the size of output
void optimize_states(void);
HTMLRenderer * renderer;
double x, y;
long long tm_id;
std::vector states;
std::vector offsets;
std::vector text;
} line_buf;
friend class LineBuffer;
// for font reencoding
int32_t * cur_mapping;
char ** cur_mapping2;
////////////////////////////////////////////////////
// styles & resources
////////////////////////////////////////////////////
std::unordered_map font_name_map;
std::map font_size_map;
std::map transform_matrix_map;
std::map letter_space_map;
std::map word_space_map;
std::map color_map;
std::map whitespace_map;
std::map rise_map;
int image_count;
const Param * param;
boost::filesystem::path dest_dir, tmp_dir;
boost::filesystem::ofstream html_fout, allcss_fout;
std::set tmp_files;
static const std::string HEAD_HTML_FILENAME;
static const std::string NECK_HTML_FILENAME;
static const std::string TAIL_HTML_FILENAME;
static const std::string CSS_FILENAME;
};
#endif /* HTMLRENDERER_H_ */