color support

This commit is contained in:
Lu Wang 2012-08-07 00:48:33 +08:00
parent 6a10acd3b5
commit fb24349449
3 changed files with 99 additions and 35 deletions

View File

@ -12,5 +12,5 @@ done
for f in *.pfa; do
fontforge -script "${SCRIPT_DIR}/convert.pe" $f 2>/dev/null
rm $f
# rm $f
done

View File

@ -8,13 +8,7 @@
/*
* TODO
* color
* transformation
* remove line break for divs in the same line
*
* updatetextmat, position etc.
*
* font base64 embedding
* custom css
*/
#include <cmath>
@ -47,6 +41,7 @@
* s<hex> - font Size
* w<hex> - White space
* t<hex> - Transform matrix
* c<hex> - Color
*/
const char * HTML_HEAD = "<!DOCTYPE html>\n\
@ -136,7 +131,7 @@ void TextString::addChars(GfxState *state, double x, double y,
{
if(nbytes > 0)
{
CharCode mask = 0xff << (8*(nbytes-1));
CharCode mask = (0xffLL) << (8*(nbytes-1));
while(nbytes > 0)
{
unicodes.push_back((Unicode)((code & mask) >> (8 * (nbytes-1))));
@ -179,6 +174,10 @@ HTMLRenderer::HTMLRenderer(const Param * param)
install_font_size(0);
install_transform_matrix(id_matrix);
GfxRGB black;
black.r = black.g = black.b = 0;
install_color(&black);
html_fout << HTML_HEAD;
if(param->readable) html_fout << endl;
@ -255,11 +254,10 @@ void HTMLRenderer::startPage(int pageNum, GfxState *state)
memcpy(draw_ctm, id_matrix, sizeof(draw_ctm));
draw_font_size = 0;
draw_scale = 1.0;
cur_color.r = cur_color.g = cur_color.b = 0;
pos_changed = false;
ctm_changed = false;
text_mat_changed = false;
font_changed = false;
reset_state_track();
}
void HTMLRenderer::endPage() {
@ -338,6 +336,7 @@ void HTMLRenderer::updateAll(GfxState *state)
text_mat_changed = true;
ctm_changed = true;
pos_changed = true;
color_changed = true;
}
void HTMLRenderer::updateFont(GfxState *state)
@ -360,14 +359,9 @@ void HTMLRenderer::updateTextPos(GfxState * state)
pos_changed = true;
}
void HTMLRenderer::saveTextPos(GfxState * state)
void HTMLRenderer::updateFillColor(GfxState * state)
{
cout << "save" << endl;
}
void HTMLRenderer::restoreTextPos(GfxState * state)
{
cout << "restore" << endl;
color_changed = true;
}
void HTMLRenderer::beginString(GfxState *state, GooString *s) {
@ -425,7 +419,7 @@ void HTMLRenderer::endString(GfxState *state) {
// open a new line
// classes
html_fout << "<div class=\"l "
<< boost::format("f%|1$x| s%|2$x|") % cur_fn_id % cur_fs_id;
<< boost::format("f%|1$x| s%|2$x| c%|3$x|") % cur_fn_id % cur_fs_id % cur_color_id;
// "t0" is the id_matrix
if(cur_tm_id != 0)
@ -860,13 +854,12 @@ long long HTMLRenderer::install_whitespace(double ws_width, double & actual_widt
return new_ws_id;
}
long long HTMLRenderer::install_transform_matrix(const double * tm){
long long HTMLRenderer::install_transform_matrix(const double * tm)
{
TM m(tm);
auto iter = transform_matrix_map.lower_bound(m);
if(m == (iter->first))
{
if((iter != transform_matrix_map.end()) && (m == (iter->first)))
return iter->second;
}
long long new_tm_id = transform_matrix_map.size();
transform_matrix_map.insert(std::make_pair(m, new_tm_id));
@ -874,6 +867,19 @@ long long HTMLRenderer::install_transform_matrix(const double * tm){
return new_tm_id;
}
long long HTMLRenderer::install_color(const GfxRGB * rgb)
{
Color c(rgb);
auto iter = color_map.lower_bound(c);
if((iter != color_map.end()) && (c == (iter->first)))
return iter->second;
long long new_color_id = color_map.size();
color_map.insert(std::make_pair(c, new_color_id));
export_color(new_color_id, rgb);
return new_color_id;
}
void HTMLRenderer::export_remote_font(long long fn_id, const string & suffix, GfxFont * font)
{
@ -957,7 +963,6 @@ void HTMLRenderer::export_transform_matrix (long long tm_id, const double * tm)
{
allcss_fout << boost::format(".t%|1$x|{") % tm_id;
// TODO: recognize common matices
if(_tm_equal(tm, id_matrix))
{
@ -982,7 +987,13 @@ void HTMLRenderer::export_transform_matrix (long long tm_id, const double * tm)
}
allcss_fout << "}";
if(param->readable) allcss_fout << endl;
}
void HTMLRenderer::export_color(long long color_id, const GfxRGB * rgb)
{
allcss_fout << boost::format(".c%|1$x|{color:rgb(%2%,%3%,%4%);}")
% color_id % rgb->r % rgb->g % rgb->b;
if(param->readable) allcss_fout << endl;
}
void HTMLRenderer::check_state_change(GfxState * state)
@ -994,6 +1005,19 @@ void HTMLRenderer::check_state_change(GfxState * state)
close_cur_line();
cur_line_y = state->getLineY();
}
}
if(color_changed)
{
GfxRGB new_color;
state->getFillRGB(&new_color);
if(!((new_color.r == cur_color.r) && (new_color.g == cur_color.g) && (new_color.b == cur_color.b)))
{
close_cur_line();
cur_color = new_color;
cur_color_id = install_color(&new_color);
}
}
bool need_rescale_font = true;
@ -1065,8 +1089,14 @@ void HTMLRenderer::check_state_change(GfxState * state)
close_cur_line();
}
text_mat_changed = false;
pos_changed = false;
font_changed = false;
reset_state_track();
}
void HTMLRenderer::reset_state_track()
{
pos_changed = false;
ctm_changed = false;
text_mat_changed = false;
font_changed = false;
color_changed = false;
}

View File

@ -128,8 +128,8 @@ class HTMLRenderer : public OutputDev
virtual void updateTextMat(GfxState * state);
virtual void updateCTM(GfxState * state, double m11, double m12, double m21, double m22, double m31, double m32);
virtual void updateTextPos(GfxState * state);
virtual void saveTextPos(GfxState * state);
virtual void restoreTextPos(GfxState * state);
virtual void updateFillColor(GfxState * state);
//----- text drawing
virtual void beginString(GfxState *state, GooString *s);
@ -160,6 +160,7 @@ class HTMLRenderer : public OutputDev
long long install_font_size(double font_size);
long long install_whitespace(double ws_width, double & actual_width);
long long install_transform_matrix(const double * tm);
long long install_color(const GfxRGB * rgb);
/*
* remote font: to be retrieved from the web server
@ -173,7 +174,9 @@ class HTMLRenderer : public OutputDev
void export_font_size(long long fs_id, double font_size);
void export_whitespace(long long ws_id, double ws_width);
void export_transform_matrix(long long tm_id, const double * tm);
void export_color(long long color_id, const GfxRGB * rgb);
XRef * xref;
Catalog *catalog;
Page *docPage;
@ -186,10 +189,8 @@ class HTMLRenderer : public OutputDev
// state maintained when processing pdf
void check_state_change(GfxState * state);
void reset_state_track();
// current position
double cur_line_y;
bool pos_changed;
// the string being processed
TextString * cur_string;
@ -199,10 +200,12 @@ class HTMLRenderer : public OutputDev
// (actual x) - (supposed x)
double cur_line_x_offset;
// current position
double cur_line_y;
bool pos_changed;
long long cur_fn_id;
double cur_font_size;
long long cur_fs_id;
bool font_changed;
@ -210,6 +213,9 @@ class HTMLRenderer : public OutputDev
bool ctm_changed;
bool text_mat_changed;
long long cur_color_id;
GfxRGB cur_color;
bool color_changed;
// optmize for web
// we try to render the final font size directly
@ -227,7 +233,6 @@ class HTMLRenderer : public OutputDev
unordered_map<long long, FontInfo> font_name_map;
map<double, long long> font_size_map;
map<double, long long> whitespace_map;
XRef * xref;
// transform matrix
class TM{
@ -252,6 +257,35 @@ class HTMLRenderer : public OutputDev
map<TM, long long> transform_matrix_map;
class Color{
public:
Color() {}
Color(const GfxRGB * rgb) {
_[0] = rgb->r;
_[1] = rgb->g;
_[2] = rgb->b;
}
bool operator < (const Color & c) const {
for(int i = 0; i < 3; ++i)
{
if(_[i] < c._[i])
return true;
if(_[i] > c._[i])
return false;
}
return false;
}
bool operator == (const Color & c) const {
for(int i = 0; i < 3; ++i)
if(_[i] != c._[i])
return false;
return true;
}
int _[3];
};
map<Color, long long> color_map;
const Param * param;
};