diff --git a/src/BackgroundRenderer/CairoBackgroundRenderer.cc b/src/BackgroundRenderer/CairoBackgroundRenderer.cc index 0368868..346c0a0 100644 --- a/src/BackgroundRenderer/CairoBackgroundRenderer.cc +++ b/src/BackgroundRenderer/CairoBackgroundRenderer.cc @@ -30,11 +30,11 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y, // - in fallback mode // - OR there is special filling method // - 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) || ( (state->getFont()) && ( (state->getFont()->getWMode()) - || (state->getFont()->getType() == fontType3) + || ((state->getFont()->getType() == fontType3) && (!param.process_type3)) ) ) ) diff --git a/src/BackgroundRenderer/CairoBackgroundRenderer.h b/src/BackgroundRenderer/CairoBackgroundRenderer.h index 5c0b465..8e3b255 100644 --- a/src/BackgroundRenderer/CairoBackgroundRenderer.h +++ b/src/BackgroundRenderer/CairoBackgroundRenderer.h @@ -37,6 +37,10 @@ public: virtual void render_page(PDFDoc * doc, 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, double dx, double dy, double originX, double originY, diff --git a/src/BackgroundRenderer/SplashBackgroundRenderer.cc b/src/BackgroundRenderer/SplashBackgroundRenderer.cc index 8e6a412..8280850 100644 --- a/src/BackgroundRenderer/SplashBackgroundRenderer.cc +++ b/src/BackgroundRenderer/SplashBackgroundRenderer.cc @@ -53,11 +53,11 @@ void SplashBackgroundRenderer::drawChar(GfxState *state, double x, double y, // - in fallback mode // - OR there is special filling method // - 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) || ( (state->getFont()) && ( (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) { int width = x2 - x1 + 1; diff --git a/src/BackgroundRenderer/SplashBackgroundRenderer.h b/src/BackgroundRenderer/SplashBackgroundRenderer.h index dea2bf0..e999a10 100644 --- a/src/BackgroundRenderer/SplashBackgroundRenderer.h +++ b/src/BackgroundRenderer/SplashBackgroundRenderer.h @@ -39,6 +39,10 @@ public: virtual void render_page(PDFDoc * doc, 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 virtual void startPage(int pageNum, GfxState *state); #else diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index 82bb146..1f8cb33 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -47,6 +47,9 @@ using std::endl; 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 font_obj, font_obj2, fontdesc_obj; 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_height = font_bbox[3] - font_bbox[1]; - glyph_width /= 10; - glyph_height /= 10; + // glyph_width /= 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; - glyph.index = cur_font->getGlyph(i, nullptr, 0); + glyph.index = cur_font->getGlyph(code, nullptr, 0); glyph.x = 0; glyph.y = glyph_height; cairo_surface_t * surface = nullptr; - { - auto fn = str_fmt("/tmp/pdf2htmlEX/f%x-%x.svg", fn_id, i); - surface = cairo_svg_surface_create((char*)fn, glyph_height, glyph_width); - } + + string glyph_filename = (char*)str_fmt("%s/f%llx-%x.svg", param.tmp_dir.c_str(), fn_id, code); + 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_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi); 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(); 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_matrix_init_identity(&matrix); // cairo_matrix_scale(&matrix, 10, 10); 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_show_glyphs(cr, &glyph, 1); @@ -245,8 +248,19 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id) if(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 return ""; #endif @@ -318,6 +332,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo /* * Step 1 * dump the font file directly from the font descriptor and put the glyphs into the correct slots * + * * for 8bit + nonTrueType * re-encoding the font by glyph names * @@ -337,12 +352,18 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo maxcode = 0xff; if(is_truetype_suffix(suffix)) { - ffw_reencode_glyph_order(); - if(FoFiTrueType * fftt = FoFiTrueType::load((char*)filepath.c_str())) + if(info.is_type3) { - code2GID = font_8bit->getCodeToGIDMap(fftt); - code2GID_len = 256; - delete fftt; + } + else + { + ffw_reencode_glyph_order(); + if(FoFiTrueType * fftt = FoFiTrueType::load((char*)filepath.c_str())) + { + code2GID = font_8bit->getCodeToGIDMap(fftt); + code2GID_len = 256; + delete fftt; + } } } else @@ -374,7 +395,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo { name_conflict_warned = true; //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; } - if(font->getType() == fontType3) + if(new_font_info.is_type3) { - //test - //dump_type3_font(font, new_fn_id); - +#if ENABLE_SVG + 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; export_remote_default_font(new_fn_id); +#endif return &new_font_info; } if(font->getWMode()) { @@ -762,7 +791,7 @@ const FontInfo * HTMLRenderer::install_font(GfxFont * font) 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) diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 3486314..6754d84 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -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 // 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 - 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); } diff --git a/src/HTMLRenderer/text.cc b/src/HTMLRenderer/text.cc index 323b209..fc56eff 100644 --- a/src/HTMLRenderer/text.cc +++ b/src/HTMLRenderer/text.cc @@ -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 if( (font == nullptr) || (font->getWMode()) -// || (font->getType() == fontType3) + || ((font->getType() == fontType3) && (!param.process_type3)) ) { return; diff --git a/src/Param.h b/src/Param.h index 2662736..8a566e7 100644 --- a/src/Param.h +++ b/src/Param.h @@ -49,6 +49,7 @@ struct Param int stretch_narrow_glyph; int squeeze_wide_glyph; int override_fstype; + int process_type3; // text double h_eps, v_eps; diff --git a/src/pdf2htmlEX.cc b/src/pdf2htmlEX.cc index 0de8a5b..069fb37 100644 --- a/src/pdf2htmlEX.cc +++ b/src/pdf2htmlEX.cc @@ -298,6 +298,9 @@ void check_param() cerr << "Image format not supported: " << param.bg_format << endl; exit(EXIT_FAILURE); } + + //test + //param.process_type3 = 1; } int main(int argc, char **argv) diff --git a/src/util/ffw.c b/src/util/ffw.c index a8c29fc..b16a126 100644 --- a/src/util/ffw.c +++ b/src/util/ffw.c @@ -103,6 +103,12 @@ long ffw_get_version(void) 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) { 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) { // convert to quadratic diff --git a/src/util/ffw.h b/src/util/ffw.h index ef9a041..ebd5378 100644 --- a/src/util/ffw.h +++ b/src/util/ffw.h @@ -27,6 +27,7 @@ long ffw_get_version(void); //////////////////////// // load & save +void ffw_new_font(); void ffw_load_font(const char * filename); void ffw_prepare_font(void); @@ -55,6 +56,7 @@ void ffw_set_widths(int * width_list, int mapping_len, //////////////////////// // others +void ffw_import_svg_glyph(int code, const char * filename); void ffw_auto_hint(void); void ffw_override_fstype(void);