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

working on type3 processing

This commit is contained in:
Lu Wang 2013-09-19 05:56:57 +08:00
parent fdcf9e634c
commit 8c4e14b1fa
11 changed files with 97 additions and 33 deletions

View File

@ -30,11 +30,11 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y,
// - in fallback mode // - in fallback mode
// - OR there is special filling method // - OR there is special filling method
// - OR using a writing mode font // - OR using a writing mode font
// - OR using a Type 3 font // - OR using a Type 3 font while param.process_type3 is not enabled
if((param.fallback) if((param.fallback)
|| ( (state->getFont()) || ( (state->getFont())
&& ( (state->getFont()->getWMode()) && ( (state->getFont()->getWMode())
|| (state->getFont()->getType() == fontType3) || ((state->getFont()->getType() == fontType3) && (!param.process_type3))
) )
) )
) )

View File

@ -37,6 +37,10 @@ public:
virtual void render_page(PDFDoc * doc, int pageno); virtual void render_page(PDFDoc * doc, int pageno);
virtual void embed_image(int pageno); virtual void embed_image(int pageno);
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return !param.process_type3; }
virtual void drawChar(GfxState *state, double x, double y, virtual void drawChar(GfxState *state, double x, double y,
double dx, double dy, double dx, double dy,
double originX, double originY, double originX, double originY,

View File

@ -53,11 +53,11 @@ void SplashBackgroundRenderer::drawChar(GfxState *state, double x, double y,
// - in fallback mode // - in fallback mode
// - OR there is special filling method // - OR there is special filling method
// - OR using a writing mode font // - OR using a writing mode font
// - OR using a Type 3 font // - OR using a Type 3 font while param.process_type3 is not enabled
if((param.fallback) if((param.fallback)
|| ( (state->getFont()) || ( (state->getFont())
&& ( (state->getFont()->getWMode()) && ( (state->getFont()->getWMode())
|| (state->getFont()->getType() == fontType3) || ((state->getFont()->getType() == fontType3) && (!param.process_type3))
) )
) )
) )
@ -136,7 +136,7 @@ void SplashBackgroundRenderer::embed_image(int pageno)
} }
} }
// There will be mem leak when exception is thrown ! // There might be mem leak when exception is thrown !
void SplashBackgroundRenderer::dump_image(const char * filename, int x1, int y1, int x2, int y2) void SplashBackgroundRenderer::dump_image(const char * filename, int x1, int y1, int x2, int y2)
{ {
int width = x2 - x1 + 1; int width = x2 - x1 + 1;

View File

@ -39,6 +39,10 @@ public:
virtual void render_page(PDFDoc * doc, int pageno); virtual void render_page(PDFDoc * doc, int pageno);
virtual void embed_image(int pageno); virtual void embed_image(int pageno);
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return !param.process_type3; }
#if POPPLER_OLDER_THAN_0_23_0 #if POPPLER_OLDER_THAN_0_23_0
virtual void startPage(int pageNum, GfxState *state); virtual void startPage(int pageNum, GfxState *state);
#else #else

View File

@ -47,6 +47,9 @@ using std::endl;
string HTMLRenderer::dump_embedded_font (GfxFont * font, long long fn_id) string HTMLRenderer::dump_embedded_font (GfxFont * font, long long fn_id)
{ {
if(font->getType() == fontType3)
return dump_type3_font(font, fn_id);
Object obj, obj1, obj2; Object obj, obj1, obj2;
Object font_obj, font_obj2, fontdesc_obj; Object font_obj, font_obj2, fontdesc_obj;
string suffix; string suffix;
@ -190,23 +193,26 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id)
double glyph_width = font_bbox[2] - font_bbox[0]; double glyph_width = font_bbox[2] - font_bbox[0];
double glyph_height = font_bbox[3] - font_bbox[1]; double glyph_height = font_bbox[3] - font_bbox[1];
glyph_width /= 10; // glyph_width /= 10;
glyph_height /= 10; // glyph_height /= 10;
for(int i = 0; i < 256; ++i) // dumpy each glyph into svg and combine them
ffw_new_font();
for(int code = 0; code < 256; ++code)
{ {
if(!used_map[i]) continue; if(!used_map[code]) continue;
cairo_glyph_t glyph; cairo_glyph_t glyph;
glyph.index = cur_font->getGlyph(i, nullptr, 0); glyph.index = cur_font->getGlyph(code, nullptr, 0);
glyph.x = 0; glyph.x = 0;
glyph.y = glyph_height; glyph.y = glyph_height;
cairo_surface_t * surface = nullptr; cairo_surface_t * surface = nullptr;
{
auto fn = str_fmt("/tmp/pdf2htmlEX/f%x-%x.svg", fn_id, i); string glyph_filename = (char*)str_fmt("%s/f%llx-%x.svg", param.tmp_dir.c_str(), fn_id, code);
surface = cairo_svg_surface_create((char*)fn, glyph_height, glyph_width); tmp_files.add(glyph_filename);
} surface = cairo_svg_surface_create(glyph_filename.c_str(), glyph_height, glyph_width);
cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2); cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2);
cairo_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi); cairo_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi);
cairo_t * cr = cairo_create(surface); cairo_t * cr = cairo_create(surface);
@ -217,17 +223,14 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id)
double * font_matrix = font->getFontMatrix(); double * font_matrix = font->getFontMatrix();
cairo_matrix_init(&matrix, font_matrix[0], font_matrix[1], font_matrix[2], font_matrix[3], font_matrix[4], font_matrix[5]); cairo_matrix_init(&matrix, font_matrix[0], font_matrix[1], font_matrix[2], font_matrix[3], font_matrix[4], font_matrix[5]);
cairo_set_font_matrix(cr, &matrix); cairo_set_font_matrix(cr, &matrix);
*/
/*
cairo_matrix_init_identity(&matrix); cairo_matrix_init_identity(&matrix);
// cairo_matrix_scale(&matrix, 10, 10); // cairo_matrix_scale(&matrix, 10, 10);
cairo_transform(cr, &matrix); cairo_transform(cr, &matrix);
*/ */
cairo_set_font_size(cr, 100); cairo_set_font_size(cr, 1000);
cairo_set_source_rgb(cr, 0., 0., 0.); // cairo_set_source_rgb(cr, 0., 0., 0.);
cairo_set_font_face(cr, cur_font->getFontFace()); cairo_set_font_face(cr, cur_font->getFontFace());
cairo_show_glyphs(cr, &glyph, 1); cairo_show_glyphs(cr, &glyph, 1);
@ -245,8 +248,19 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id)
if(status) if(status)
throw string("Error in cairo: ") + cairo_status_to_string(status); throw string("Error in cairo: ") + cairo_status_to_string(status);
} }
ffw_import_svg_glyph(code, glyph_filename.c_str());
} }
return "";
// we choose ttf as it does not use char names
// or actually we don't use char names for ttf (see embed_font)
string font_filename = (char*)str_fmt("%s/f%llx.ttf", param.tmp_dir.c_str(), fn_id);
tmp_files.add(font_filename);
ffw_save(font_filename.c_str());
ffw_close();
// combine glyphs
return font_filename;
#else #else
return ""; return "";
#endif #endif
@ -318,6 +332,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo
/* /*
* Step 1 * Step 1
* dump the font file directly from the font descriptor and put the glyphs into the correct slots * * dump the font file directly from the font descriptor and put the glyphs into the correct slots *
*
* for 8bit + nonTrueType * for 8bit + nonTrueType
* re-encoding the font by glyph names * re-encoding the font by glyph names
* *
@ -337,12 +352,18 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo
maxcode = 0xff; maxcode = 0xff;
if(is_truetype_suffix(suffix)) if(is_truetype_suffix(suffix))
{ {
ffw_reencode_glyph_order(); if(info.is_type3)
if(FoFiTrueType * fftt = FoFiTrueType::load((char*)filepath.c_str()))
{ {
code2GID = font_8bit->getCodeToGIDMap(fftt); }
code2GID_len = 256; else
delete fftt; {
ffw_reencode_glyph_order();
if(FoFiTrueType * fftt = FoFiTrueType::load((char*)filepath.c_str()))
{
code2GID = font_8bit->getCodeToGIDMap(fftt);
code2GID_len = 256;
delete fftt;
}
} }
} }
else else
@ -374,7 +395,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo
{ {
name_conflict_warned = true; name_conflict_warned = true;
//TODO: may be resolved using advanced font properties? //TODO: may be resolved using advanced font properties?
cerr << "Warning: encoding confliction detected in font: " << hex << info.id << dec << endl; cerr << "Warning: encoding conflict detected in font: " << hex << info.id << dec << endl;
} }
} }
} }
@ -717,13 +738,21 @@ const FontInfo * HTMLRenderer::install_font(GfxFont * font)
<< endl; << endl;
} }
if(font->getType() == fontType3) if(new_font_info.is_type3)
{ {
//test #if ENABLE_SVG
//dump_type3_font(font, new_fn_id); if(param.process_type3)
{
install_embedded_font(font, new_font_info);
}
else
{
export_remote_default_font(new_fn_id);
}
#else
cerr << "Type 3 fonts are unsupported and will be rendered as Image" << endl; cerr << "Type 3 fonts are unsupported and will be rendered as Image" << endl;
export_remote_default_font(new_fn_id); export_remote_default_font(new_fn_id);
#endif
return &new_font_info; return &new_font_info;
} }
if(font->getWMode()) { if(font->getWMode()) {
@ -762,7 +791,7 @@ const FontInfo * HTMLRenderer::install_font(GfxFont * font)
export_remote_default_font(new_fn_id); export_remote_default_font(new_fn_id);
} }
return &(cur_info_iter->second); return &new_font_info;
} }
void HTMLRenderer::install_embedded_font(GfxFont * font, FontInfo & info) void HTMLRenderer::install_embedded_font(GfxFont * font, FontInfo & info)

View File

@ -207,7 +207,7 @@ void HTMLRenderer::check_state_change(GfxState * state)
// The width of the type 3 font text, if shown, is likely to be wrong // The width of the type 3 font text, if shown, is likely to be wrong
// So we will create separate (absolute positioned) blocks for them, such that it won't affect other text // So we will create separate (absolute positioned) blocks for them, such that it won't affect other text
// TODO: consider the font matrix and estimate the metrics // TODO: consider the font matrix and estimate the metrics
if(new_font_info->is_type3 || cur_text_state.font_info->is_type3) if((new_font_info->is_type3 || cur_text_state.font_info->is_type3) && (!param.process_type3))
{ {
set_line_state(new_line_state, NLS_NEWLINE); set_line_state(new_line_state, NLS_NEWLINE);
} }

View File

@ -35,7 +35,7 @@ void HTMLRenderer::drawString(GfxState * state, GooString * s)
// For type 3 fonts, due to the font matrix, still it's hard to show it on HTML // For type 3 fonts, due to the font matrix, still it's hard to show it on HTML
if( (font == nullptr) if( (font == nullptr)
|| (font->getWMode()) || (font->getWMode())
// || (font->getType() == fontType3) || ((font->getType() == fontType3) && (!param.process_type3))
) )
{ {
return; return;

View File

@ -49,6 +49,7 @@ struct Param
int stretch_narrow_glyph; int stretch_narrow_glyph;
int squeeze_wide_glyph; int squeeze_wide_glyph;
int override_fstype; int override_fstype;
int process_type3;
// text // text
double h_eps, v_eps; double h_eps, v_eps;

View File

@ -298,6 +298,9 @@ void check_param()
cerr << "Image format not supported: " << param.bg_format << endl; cerr << "Image format not supported: " << param.bg_format << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
//test
//param.process_type3 = 1;
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@ -103,6 +103,12 @@ long ffw_get_version(void)
return library_version_configuration.library_source_versiondate; return library_version_configuration.library_source_versiondate;
} }
void ffw_new_font()
{
assert((cur_fv == NULL) && "Previous font is not destroyed");
cur_fv = FVAppend(_FontViewCreate(SplineFontNew()));
}
void ffw_load_font(const char * filename) void ffw_load_font(const char * filename)
{ {
assert((cur_fv == NULL) && "Previous font is not destroyed"); assert((cur_fv == NULL) && "Previous font is not destroyed");
@ -418,6 +424,21 @@ void ffw_set_widths(int * width_list, int mapping_len,
} }
} }
void ffw_import_svg_glyph(int code, const char * filename)
{
int enc = SFFindSlot(cur_fv->sf, cur_fv->map, code, "");
if(enc == -1)
return;
SFMakeChar(cur_fv->sf, cur_fv->map, enc);
memset(cur_fv->selected, 0, cur_fv->map->enccount);
cur_fv->selected[enc] = 1;
int ok = FVImportImages(cur_fv, (char*)filename, fv_svg, 0, -1);
if(!ok)
err("Import SVG glyph failed");
}
void ffw_auto_hint(void) void ffw_auto_hint(void)
{ {
// convert to quadratic // convert to quadratic

View File

@ -27,6 +27,7 @@ long ffw_get_version(void);
//////////////////////// ////////////////////////
// load & save // load & save
void ffw_new_font();
void ffw_load_font(const char * filename); void ffw_load_font(const char * filename);
void ffw_prepare_font(void); void ffw_prepare_font(void);
@ -55,6 +56,7 @@ void ffw_set_widths(int * width_list, int mapping_len,
//////////////////////// ////////////////////////
// others // others
void ffw_import_svg_glyph(int code, const char * filename);
void ffw_auto_hint(void); void ffw_auto_hint(void);
void ffw_override_fstype(void); void ffw_override_fstype(void);