From 8812bb52fb2ee05a039b37547e44720ce63a4097 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Thu, 19 Sep 2013 22:02:12 +0800 Subject: [PATCH 1/7] scale type 3 fonts --- .../SplashBackgroundRenderer.h | 3 +- src/HTMLRenderer/HTMLRenderer.h | 4 +- src/HTMLRenderer/font.cc | 141 ++++++++++++++---- src/HTMLRenderer/state.cc | 13 +- src/HTMLState.h | 12 ++ src/pdf2htmlEX.cc | 2 +- src/util/math.cc | 28 ++++ src/util/math.h | 1 + 8 files changed, 171 insertions(+), 33 deletions(-) diff --git a/src/BackgroundRenderer/SplashBackgroundRenderer.h b/src/BackgroundRenderer/SplashBackgroundRenderer.h index e999a10..be56418 100644 --- a/src/BackgroundRenderer/SplashBackgroundRenderer.h +++ b/src/BackgroundRenderer/SplashBackgroundRenderer.h @@ -41,7 +41,8 @@ public: // 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; } + // debug +// virtual GBool interpretType3Chars() { return !param.process_type3; } #if POPPLER_OLDER_THAN_0_23_0 virtual void startPage(int pageNum, GfxState *state); diff --git a/src/HTMLRenderer/HTMLRenderer.h b/src/HTMLRenderer/HTMLRenderer.h index 317d6c8..a3fe23e 100644 --- a/src/HTMLRenderer/HTMLRenderer.h +++ b/src/HTMLRenderer/HTMLRenderer.h @@ -166,8 +166,8 @@ protected: * local font: to be substituted with a local (client side) font */ //////////////////////////////////////////////////// - std::string dump_embedded_font(GfxFont * font, long long fn_id); - std::string dump_type3_font(GfxFont * font, long long fn_id); + std::string dump_embedded_font(GfxFont * font, FontInfo & info); + std::string dump_type3_font(GfxFont * font, FontInfo & info); void embed_font(const std::string & filepath, GfxFont * font, FontInfo & info, bool get_metric_only = false); const FontInfo * install_font(GfxFont * font); void install_embedded_font(GfxFont * font, FontInfo & info); diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index 17a0979..79da04f 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -36,6 +36,8 @@ #include #include #include "BackgroundRenderer/CairoOutputDev/CairoFontEngine.h" +#include "BackgroundRenderer/CairoOutputDev/CairoOutputDev.h" +#include #endif namespace pdf2htmlEX { @@ -45,16 +47,18 @@ using std::unordered_set; using std::cerr; using std::endl; -string HTMLRenderer::dump_embedded_font (GfxFont * font, long long fn_id) +string HTMLRenderer::dump_embedded_font (GfxFont * font, FontInfo & info) { - if(font->getType() == fontType3) - return dump_type3_font(font, fn_id); + if(info.is_type3) + return dump_type3_font(font, info); Object obj, obj1, obj2; Object font_obj, font_obj2, fontdesc_obj; string suffix; string filepath; + long long fn_id = info.id; + try { // inspired by mupdf @@ -178,11 +182,13 @@ string HTMLRenderer::dump_embedded_font (GfxFont * font, long long fn_id) return filepath; } -string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id) +string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) { - assert(font->getFontType() == fontType3); + assert(info.is_type3); #if ENABLE_SVG + long long fn_id = info.id; + FT_Library ft_lib; FT_Init_FreeType(&ft_lib); CairoFontEngine font_engine(ft_lib); @@ -190,13 +196,36 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id) auto used_map = preprocessor.get_code_map(hash_ref(font->getID())); double * font_bbox = font->getFontBBox(); - double glyph_width = font_bbox[2] - font_bbox[0]; - double glyph_height = font_bbox[3] - font_bbox[1]; + // TODO: font matrix may not exists + double * font_matrix = font->getFontMatrix(); - // glyph_width /= 10; - // glyph_height /= 10; + //calculate transformations + double transformed_bbox[4]; + memcpy(transformed_bbox, font_bbox, 4 * sizeof(double)); + tm_transform_bbox(font_matrix, transformed_bbox); + double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0]; + double transformed_bbox_height = transformed_bbox[3] - transformed_bbox[1]; + //debug + std::cerr << "transformed bbox:"; + for(int i = 0; i < 4; ++i) + std::cerr << ' ' << transformed_bbox[i]; + std::cerr << std::endl; + // we want the glyphs is rendered in a box of size around 100 x 100 + // for rectangles, the longer edge should be 100 + info.type3_font_size_scale = std::max(transformed_bbox_width, transformed_bbox_height); - // dumpy each glyph into svg and combine them + const double GLYPH_DUMP_SIZE = 100.0; + double scale = GLYPH_DUMP_SIZE / info.type3_font_size_scale; + + // determine the position of the origin of the glyph + double ox, oy; + ox = oy = 0; + tm_transform(font_matrix, ox, oy); + ox -= transformed_bbox[0]; + oy -= transformed_bbox[1]; + + + // dump each glyph into svg and combine them ffw_new_font(); for(int code = 0; code < 256; ++code) { @@ -204,36 +233,86 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, long long fn_id) cairo_glyph_t glyph; glyph.index = cur_font->getGlyph(code, nullptr, 0); - glyph.x = 0; - glyph.y = glyph_height; + glyph.x = ox; + glyph.y = transformed_bbox_width * scale - oy; cairo_surface_t * surface = nullptr; 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); + + surface = cairo_svg_surface_create(glyph_filename.c_str(), transformed_bbox_width * scale, transformed_bbox_height * scale); 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); - // zoom the image to prevent CairoOutputDev from rounding/increasing thin borders - //cairo_matrix_t matrix; + //debug + std::cerr << "debug " << code << std::endl; + std::cerr << "pdf width " << ((Gfx8BitFont*)font)->getWidth(code) << std::endl; /* - 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, 1000); - -// cairo_set_source_rgb(cr, 0., 0., 0.); - + cairo_set_font_size(cr, scale); cairo_set_font_face(cr, cur_font->getFontFace()); cairo_show_glyphs(cr, &glyph, 1); + */ + + // manually draw the char to get the metrics + // adapted from _render_type3_glyph of poppler + { + cairo_matrix_t m1, m2; + cairo_matrix_init_translate(&m1, glyph.x, glyph.y); + cairo_transform(cr, &m1); + cairo_matrix_init_scale(&m1, scale, scale); + cairo_transform(cr, &m1); + + cairo_matrix_init(&m1, font_matrix[0], font_matrix[1], font_matrix[2], font_matrix[3], font_matrix[4], font_matrix[5]); + cairo_matrix_init_scale(&m2, 1, -1); + cairo_matrix_multiply(&m1, &m1, &m2); + cairo_transform(cr, &m1); + + auto output_dev = new CairoOutputDev(); + output_dev->setCairo(cr); + output_dev->setPrinting(true); + + PDFRectangle box; + box.x1 = font_bbox[0]; + box.y1 = font_bbox[1]; + box.x2 = font_bbox[2]; + box.y2 = font_bbox[3]; + auto gfx = new Gfx(cur_doc, output_dev, + ((Gfx8BitFont*)font)->getResources(), + &box, nullptr); + output_dev->startDoc(cur_doc, &font_engine); + output_dev->startPage(1, gfx->getState(), gfx->getXRef()); + output_dev->setInType3Char(gTrue); + auto char_procs = ((Gfx8BitFont*)font)->getCharProcs(); + Object char_proc_obj; + gfx->display(char_procs->getVal(glyph.index, &char_proc_obj)); + + double wx, wy; + output_dev->getType3GlyphWidth(&wx, &wy); + cairo_matrix_transform_distance(&m1, &wx, &wy); + std::cerr << "wx " << wx << " wy " << wy << std::endl; + + if(output_dev->hasType3GlyphBBox()) + { + double *bbox = output_dev->getType3GlyphBBox(); + + cairo_matrix_transform_point (&m1, &bbox[0], &bbox[1]); + cairo_matrix_transform_point (&m1, &bbox[2], &bbox[3]); + std::cerr << "*bbox"; + for(int i = 0; i < 4; ++i) + std::cerr << ' ' << bbox[i]; + std::cerr << std::endl; + } + + char_proc_obj.free(); + delete gfx; + delete output_dev; + } + + +// cairo_set_source_rgb(cr, 0., 0., 0.); { auto status = cairo_status(cr); cairo_destroy(cr); @@ -568,6 +647,9 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo cur_width = font_cid->getWidth(buf, 2) ; } + if(info.is_type3) + cur_width /= info.type3_font_size_scale; + if(u == ' ') { /* @@ -611,6 +693,9 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo char buf[2] = {0, ' '}; info.space_width = font_cid->getWidth(buf, 2); } + if(info.is_type3) + info.space_width /= info.type3_font_size_scale; + /* See comments above */ if(equal(info.space_width,0)) info.space_width = 0.001; @@ -802,7 +887,7 @@ const FontInfo * HTMLRenderer::install_font(GfxFont * font) void HTMLRenderer::install_embedded_font(GfxFont * font, FontInfo & info) { - auto path = dump_embedded_font(font, info.id); + auto path = dump_embedded_font(font, info); if(path != "") { diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 6754d84..813b5ca 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -206,7 +206,6 @@ 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) && (!param.process_type3)) { set_line_state(new_line_state, NLS_NEWLINE); @@ -218,6 +217,12 @@ void HTMLRenderer::check_state_change(GfxState * state) cur_text_state.font_info = new_font_info; } + /* + * For Type 3 fonts, we need to take type3_font_size_scale into consideration + */ + if((new_font_info->is_type3 || cur_text_state.font_info->is_type3) && param.process_type3) + need_rescale_font = true; + double new_font_size = state->getFontSize(); if(!equal(cur_font_size, new_font_size)) { @@ -268,6 +273,12 @@ void HTMLRenderer::check_state_change(GfxState * state) double new_draw_text_scale = 1.0/text_scale_factor2 * hypot(new_draw_text_tm[2], new_draw_text_tm[3]); double new_draw_font_size = cur_font_size; + + if(cur_text_state.font_info->is_type3 && param.process_type3) + { + new_draw_font_size *= cur_text_state.font_info->type3_font_size_scale; + } + if(is_positive(new_draw_text_scale)) { // scale both font size and matrix diff --git a/src/HTMLState.h b/src/HTMLState.h index d53fea2..853a300 100644 --- a/src/HTMLState.h +++ b/src/HTMLState.h @@ -17,6 +17,18 @@ struct FontInfo double space_width; double ascent, descent; bool is_type3; + /* + * As Type 3 fonts have a font matrix + * a glyph of 1pt can be very large or very small + * however it might not be true for other font formats such as ttf + * + * Therefore when we save a Type 3 font into ttf, + * we have to scale the font to about 1, + * then apply the scaling when using the font + * + * The scaling factor is stored as type3_font_size_scale + */ + double type3_font_size_scale; }; struct HTMLTextState diff --git a/src/pdf2htmlEX.cc b/src/pdf2htmlEX.cc index 069fb37..2df3568 100644 --- a/src/pdf2htmlEX.cc +++ b/src/pdf2htmlEX.cc @@ -300,7 +300,7 @@ void check_param() } //test - //param.process_type3 = 1; + param.process_type3 = 1; } int main(int argc, char **argv) diff --git a/src/util/math.cc b/src/util/math.cc index d23d48f..fd8e77c 100644 --- a/src/util/math.cc +++ b/src/util/math.cc @@ -1,4 +1,6 @@ #include +#include + #include "math.h" namespace pdf2htmlEX { @@ -28,5 +30,31 @@ void tm_multiply(double * tm_left, const double * tm_right) tm_left[5] += old[1] * tm_right[4] + old[3] * tm_right[5]; } +void tm_transform_bbox(const double * tm, double * bbox) +{ + double & x1 = bbox[0]; + double & y1 = bbox[1]; + double & x2 = bbox[2]; + double & y2 = bbox[3]; + double _[4][2]; + _[0][0] = _[1][0] = x1; + _[0][1] = _[2][1] = y1; + _[2][0] = _[3][0] = x2; + _[1][1] = _[3][1] = y2; + + x1 = y1 = std::numeric_limits::max(); + x2 = y2 = std::numeric_limits::min(); + for(int i = 0; i < 4; ++i) + { + auto & x = _[i][0]; + auto & y = _[i][1]; + tm_transform(tm, x, y); + if(x < x1) x1 = x; + if(x > x2) x2 = x; + if(y < y1) y1 = y; + if(y > y2) y2 = y; + } +} + } //namespace pdf2htmlEX diff --git a/src/util/math.h b/src/util/math.h index 7db46d7..759bbcc 100644 --- a/src/util/math.h +++ b/src/util/math.h @@ -38,6 +38,7 @@ static inline double hypot(double x, double y) { return std::sqrt(x*x+y*y); } void tm_transform(const double * tm, double & x, double & y, bool is_delta = false); void tm_multiply(double * tm_left, const double * tm_right); +void tm_transform_bbox(const double * tm, double * bbox); } //namespace pdf2htmlEX #endif //MATH_H__ From 09856c091032fe4769ad19ada8d180e6332131da Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Fri, 20 Sep 2013 16:35:19 +0800 Subject: [PATCH 2/7] improve ascent/descent for type 3 fonts --- src/HTMLRenderer/font.cc | 33 +++++++++++++---------- src/HTMLRenderer/state.cc | 5 ---- src/HTMLState.h | 6 +++-- src/HTMLTextLine.cc | 12 ++++++--- src/util/ffw.c | 57 ++++++++++++++++++++++++--------------- src/util/ffw.h | 10 +++++-- 6 files changed, 74 insertions(+), 49 deletions(-) diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index 79da04f..9b077fa 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -58,6 +58,7 @@ string HTMLRenderer::dump_embedded_font (GfxFont * font, FontInfo & info) string filepath; long long fn_id = info.id; + info.font_size_scale = 1.0; try { @@ -195,13 +196,17 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) auto * cur_font = font_engine.getFont(font, cur_doc, true, xref); auto used_map = preprocessor.get_code_map(hash_ref(font->getID())); + //calculate transformed metrics double * font_bbox = font->getFontBBox(); // TODO: font matrix may not exists double * font_matrix = font->getFontMatrix(); - - //calculate transformations double transformed_bbox[4]; memcpy(transformed_bbox, font_bbox, 4 * sizeof(double)); + // add the origin to the bbox + if(transformed_bbox[0] > 0) transformed_bbox[0] = 0; + if(transformed_bbox[1] > 0) transformed_bbox[1] = 0; + if(transformed_bbox[2] < 0) transformed_bbox[2] = 0; + if(transformed_bbox[3] < 0) transformed_bbox[3] = 0; tm_transform_bbox(font_matrix, transformed_bbox); double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0]; double transformed_bbox_height = transformed_bbox[3] - transformed_bbox[1]; @@ -212,10 +217,10 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) std::cerr << std::endl; // we want the glyphs is rendered in a box of size around 100 x 100 // for rectangles, the longer edge should be 100 - info.type3_font_size_scale = std::max(transformed_bbox_width, transformed_bbox_height); + info.font_size_scale = std::max(transformed_bbox_width, transformed_bbox_height); const double GLYPH_DUMP_SIZE = 100.0; - double scale = GLYPH_DUMP_SIZE / info.type3_font_size_scale; + double scale = GLYPH_DUMP_SIZE / info.font_size_scale; // determine the position of the origin of the glyph double ox, oy; @@ -224,9 +229,11 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) ox -= transformed_bbox[0]; oy -= transformed_bbox[1]; - - // dump each glyph into svg and combine them + // we choose ttf as it does not use char names + // or actually we don't use char names for ttf (see embed_font) ffw_new_font(); + ffw_set_metric(transformed_bbox[3] / transformed_bbox_height, transformed_bbox[1] / transformed_bbox_height); + // dump each glyph into svg and combine them for(int code = 0; code < 256; ++code) { if(!used_map[code]) continue; @@ -331,8 +338,6 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) ffw_import_svg_glyph(code, glyph_filename.c_str()); } - // 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()); @@ -400,7 +405,8 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo if(get_metric_only) { - ffw_metric(&info.ascent, &info.descent); + ffw_fix_metric(); + ffw_get_metric(&info.ascent, &info.descent); ffw_close(); return; } @@ -647,8 +653,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo cur_width = font_cid->getWidth(buf, 2) ; } - if(info.is_type3) - cur_width /= info.type3_font_size_scale; + cur_width /= info.font_size_scale; if(u == ' ') { @@ -693,8 +698,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo char buf[2] = {0, ' '}; info.space_width = font_cid->getWidth(buf, 2); } - if(info.is_type3) - info.space_width /= info.type3_font_size_scale; + info.space_width /= info.font_size_scale; /* See comments above */ if(equal(info.space_width,0)) @@ -777,7 +781,8 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo tmp_files.add(fn); ffw_load_font(cur_tmp_fn.c_str()); - ffw_metric(&info.ascent, &info.descent); + ffw_fix_metric(); + ffw_get_metric(&info.ascent, &info.descent); if(param.override_fstype) ffw_override_fstype(); ffw_save(fn.c_str()); diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 813b5ca..9309b24 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -274,11 +274,6 @@ void HTMLRenderer::check_state_change(GfxState * state) double new_draw_font_size = cur_font_size; - if(cur_text_state.font_info->is_type3 && param.process_type3) - { - new_draw_font_size *= cur_text_state.font_info->type3_font_size_scale; - } - if(is_positive(new_draw_text_scale)) { // scale both font size and matrix diff --git a/src/HTMLState.h b/src/HTMLState.h index 853a300..b8a470b 100644 --- a/src/HTMLState.h +++ b/src/HTMLState.h @@ -26,9 +26,11 @@ struct FontInfo * we have to scale the font to about 1, * then apply the scaling when using the font * - * The scaling factor is stored as type3_font_size_scale + * The scaling factor is stored as font_size_scale + * + * The value is 1 for other fonts */ - double type3_font_size_scale; + double font_size_scale; }; struct HTMLTextState diff --git a/src/HTMLTextLine.cc b/src/HTMLTextLine.cc index d37269c..5a0ab2d 100644 --- a/src/HTMLTextLine.cc +++ b/src/HTMLTextLine.cc @@ -60,7 +60,10 @@ void HTMLTextLine::append_state(const HTMLTextState & text_state) states.back().hash_umask = 0; } - (HTMLTextState&)(states.back()) = text_state; + HTMLTextState & last_state = states.back(); + last_state = text_state; + //apply font scale + last_state.font_size *= last_state.font_info->font_size_scale; } void HTMLTextLine::dump_text(ostream & out) @@ -251,7 +254,8 @@ void HTMLTextLine::prepare(void) // note that vertical_align cannot be calculated here for(auto iter = states.begin(); iter != states.end(); ++iter) { - iter->ids[State::FONT_ID] = iter->font_info->id; + auto font_info = iter->font_info; + iter->ids[State::FONT_ID] = font_info->id; iter->ids[State::FONT_SIZE_ID] = all_manager.font_size.install(iter->font_size); iter->ids[State::FILL_COLOR_ID] = all_manager.fill_color.install(iter->fill_color); iter->ids[State::STROKE_COLOR_ID] = all_manager.stroke_color.install(iter->stroke_color); @@ -260,10 +264,10 @@ void HTMLTextLine::prepare(void) iter->hash(); accum_vertical_align += iter->vertical_align; - double cur_ascent = accum_vertical_align + iter->font_info->ascent * iter->font_size; + double cur_ascent = accum_vertical_align + font_info->ascent * iter->font_size; if(cur_ascent > ascent) ascent = cur_ascent; - double cur_descent = accum_vertical_align + iter->font_info->descent * iter->font_size; + double cur_descent = accum_vertical_align + font_info->descent * iter->font_size; if(cur_descent < descent) descent = cur_descent; } diff --git a/src/util/ffw.c b/src/util/ffw.c index b16a126..b2d9eb6 100644 --- a/src/util/ffw.c +++ b/src/util/ffw.c @@ -302,29 +302,22 @@ int ffw_get_em_size(void) return cur_fv->sf->ascent + cur_fv->sf->descent; } -void ffw_metric(double * ascent, double * descent) +void ffw_fix_metric() +{ + double ascent, descent; + ffw_get_metric(&ascent, &descent); + //debug + printf("fix metrix: %lf %lf\n", ascent, descent); + ffw_set_metric(ascent, descent); +} + +void ffw_get_metric(double * ascent, double * descent) { SplineFont * sf = cur_fv->sf; - struct pfminfo * info = &sf->pfminfo; - - SFDefaultOS2Info(info, sf, sf->fontname); - info->pfmset = 1; - sf->changed = 1; DBounds bb; SplineFontFindBounds(sf, &bb); - /* - printf("bb %lf %lf\n", bb.maxy, bb.miny); - printf("_ %d %d\n", sf->ascent, sf->descent); - printf("win %d %d\n", info->os2_winascent, info->os2_windescent); - printf("%d %d\n", info->winascent_add, info->windescent_add); - printf("typo %d %d\n", info->os2_typoascent, info->os2_typodescent); - printf("%d %d\n", info->typoascent_add, info->typodescent_add); - printf("hhead %d %d\n", info->hhead_ascent, info->hhead_descent); - printf("%d %d\n", info->hheadascent_add, info->hheaddescent_add); - */ - int em = sf->ascent + sf->descent; if (em > 0) @@ -336,10 +329,21 @@ void ffw_metric(double * ascent, double * descent) { *ascent = *descent = 0; } +} + +void ffw_set_metric(double ascent, double descent) +{ + SplineFont * sf = cur_fv->sf; + struct pfminfo * info = &sf->pfminfo; + + SFDefaultOS2Info(info, sf, sf->fontname); + info->pfmset = 1; + sf->changed = 1; + + int em = sf->ascent + sf->descent; + int a = floor(ascent * em + 0.5); + int d = floor(descent * em + 0.5); - int a = floor(bb.maxy + 0.5); - int d = floor(bb.miny + 0.5); - if(a < 0) a = 0; if(d > 0) d = 0; @@ -354,7 +358,6 @@ void ffw_metric(double * ascent, double * descent) * But have to unify them, for different browsers on different platforms * Things may become easier when there are CSS rules for baseline-based positioning. */ - info->os2_winascent = a; info->os2_typoascent = a; info->hhead_ascent = a; @@ -430,13 +433,23 @@ void ffw_import_svg_glyph(int code, const char * filename) if(enc == -1) return; - SFMakeChar(cur_fv->sf, cur_fv->map, enc); + SplineChar * sc = 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"); + + // correct the origin + { + real transform[6]; + transform[0] = 1.0; + transform[3] = 1.0; + transform[1] = transform[2] = transform[4]; + transform[5] = cur_fv->sf->descent; + FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth); + } } void ffw_auto_hint(void) diff --git a/src/util/ffw.h b/src/util/ffw.h index ebd5378..b66c24b 100644 --- a/src/util/ffw.h +++ b/src/util/ffw.h @@ -48,8 +48,14 @@ void ffw_add_empty_char(int32_t unicode, int width); //////////////////////// // metrics int ffw_get_em_size(void); -// fix metrics and get them -void ffw_metric(double * ascent, double * descent); +// manipulate ascent and descent +// asscent is between 0 and 1 +// descent is between -1 and 0 +void ffw_fix_metric(); +// get ascent/descent based on the shape +void ffw_get_metric(double * ascent, double * descent); +// set corresponding fields +void ffw_set_metric(double ascent, double descent); void ffw_set_widths(int * width_list, int mapping_len, int stretch_narrow, int squeeze_wide); From 8cac1e6aaf3b556ba04e11a2e218c2b18177f60d Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Fri, 20 Sep 2013 20:06:06 +0800 Subject: [PATCH 3/7] improve accuray for type 3 fonts --- src/HTMLRenderer/font.cc | 67 +++++++++++++++++++++++----------------- src/util/ffw.c | 11 ++++--- src/util/ffw.h | 3 +- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index 9b077fa..e3056e8 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -58,7 +58,6 @@ string HTMLRenderer::dump_embedded_font (GfxFont * font, FontInfo & info) string filepath; long long fn_id = info.id; - info.font_size_scale = 1.0; try { @@ -198,15 +197,16 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) //calculate transformed metrics double * font_bbox = font->getFontBBox(); - // TODO: font matrix may not exists double * font_matrix = font->getFontMatrix(); double transformed_bbox[4]; memcpy(transformed_bbox, font_bbox, 4 * sizeof(double)); + /* // add the origin to the bbox if(transformed_bbox[0] > 0) transformed_bbox[0] = 0; if(transformed_bbox[1] > 0) transformed_bbox[1] = 0; if(transformed_bbox[2] < 0) transformed_bbox[2] = 0; if(transformed_bbox[3] < 0) transformed_bbox[3] = 0; + */ tm_transform_bbox(font_matrix, transformed_bbox); double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0]; double transformed_bbox_height = transformed_bbox[3] - transformed_bbox[1]; @@ -219,30 +219,17 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) // for rectangles, the longer edge should be 100 info.font_size_scale = std::max(transformed_bbox_width, transformed_bbox_height); - const double GLYPH_DUMP_SIZE = 100.0; - double scale = GLYPH_DUMP_SIZE / info.font_size_scale; - - // determine the position of the origin of the glyph - double ox, oy; - ox = oy = 0; - tm_transform(font_matrix, ox, oy); - ox -= transformed_bbox[0]; - oy -= transformed_bbox[1]; + const double GLYPH_DUMP_EM_SIZE = 100.0; + double scale = GLYPH_DUMP_EM_SIZE / info.font_size_scale; // we choose ttf as it does not use char names // or actually we don't use char names for ttf (see embed_font) ffw_new_font(); - ffw_set_metric(transformed_bbox[3] / transformed_bbox_height, transformed_bbox[1] / transformed_bbox_height); // dump each glyph into svg and combine them for(int code = 0; code < 256; ++code) { if(!used_map[code]) continue; - cairo_glyph_t glyph; - glyph.index = cur_font->getGlyph(code, nullptr, 0); - glyph.x = ox; - glyph.y = transformed_bbox_width * scale - oy; - cairo_surface_t * surface = nullptr; string glyph_filename = (char*)str_fmt("%s/f%llx-%x.svg", param.tmp_dir.c_str(), fn_id, code); @@ -263,20 +250,42 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) cairo_show_glyphs(cr, &glyph, 1); */ + // track the positio of the origin + double ox, oy; + ox = oy = 0.0; + // manually draw the char to get the metrics // adapted from _render_type3_glyph of poppler { - cairo_matrix_t m1, m2; - cairo_matrix_init_translate(&m1, glyph.x, glyph.y); - cairo_transform(cr, &m1); - cairo_matrix_init_scale(&m1, scale, scale); - cairo_transform(cr, &m1); + cairo_matrix_t ctm, m, m1; + cairo_matrix_init_identity(&ctm); - cairo_matrix_init(&m1, font_matrix[0], font_matrix[1], font_matrix[2], font_matrix[3], font_matrix[4], font_matrix[5]); - cairo_matrix_init_scale(&m2, 1, -1); - cairo_matrix_multiply(&m1, &m1, &m2); - cairo_transform(cr, &m1); + // apply font-matrix + cairo_matrix_init(&m, font_matrix[0], font_matrix[1], font_matrix[2], font_matrix[3], font_matrix[4], font_matrix[5]); + cairo_matrix_multiply(&ctm, &ctm, &m); + // shift origin + cairo_matrix_init_translate(&m1, -transformed_bbox[0], -transformed_bbox[1]); + cairo_matrix_multiply(&ctm, &ctm, &m1); + + // make it upside down since the difference between the glyph coordination and cairo coordination + cairo_matrix_init_scale(&m1, 1, -1); + cairo_matrix_multiply(&ctm, &ctm, &m1); + // save m*m1 to m1 for later use + cairo_matrix_multiply(&m1, &m, &m1); + + // shift up to the bounding box + cairo_matrix_init_translate(&m, 0.0, transformed_bbox_height); + cairo_matrix_multiply(&ctm, &ctm, &m); + + // scale up + cairo_matrix_init_scale(&m, scale, scale); + cairo_matrix_multiply(&ctm, &ctm, &m); + + // set ctm + cairo_set_matrix(cr, &ctm); + + // draw the glyph auto output_dev = new CairoOutputDev(); output_dev->setCairo(cr); output_dev->setPrinting(true); @@ -294,7 +303,8 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) output_dev->setInType3Char(gTrue); auto char_procs = ((Gfx8BitFont*)font)->getCharProcs(); Object char_proc_obj; - gfx->display(char_procs->getVal(glyph.index, &char_proc_obj)); + auto glyph_index = cur_font->getGlyph(code, nullptr, 0); + gfx->display(char_procs->getVal(glyph_index, &char_proc_obj)); double wx, wy; output_dev->getType3GlyphWidth(&wx, &wy); @@ -335,7 +345,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) throw string("Error in cairo: ") + cairo_status_to_string(status); } - ffw_import_svg_glyph(code, glyph_filename.c_str()); + ffw_import_svg_glyph(code, glyph_filename.c_str(), ox / GLYPH_DUMP_EM_SIZE, oy / GLYPH_DUMP_EM_SIZE); } string font_filename = (char*)str_fmt("%s/f%llx.ttf", param.tmp_dir.c_str(), fn_id); @@ -808,6 +818,7 @@ const FontInfo * HTMLRenderer::install_font(GfxFont * font) FontInfo & new_font_info = cur_info_iter->second; new_font_info.id = new_fn_id; new_font_info.use_tounicode = true; + new_font_info.font_size_scale = 1.0; if(font == nullptr) { diff --git a/src/util/ffw.c b/src/util/ffw.c index b2d9eb6..84bcd4e 100644 --- a/src/util/ffw.c +++ b/src/util/ffw.c @@ -306,8 +306,6 @@ void ffw_fix_metric() { double ascent, descent; ffw_get_metric(&ascent, &descent); - //debug - printf("fix metrix: %lf %lf\n", ascent, descent); ffw_set_metric(ascent, descent); } @@ -427,7 +425,7 @@ void ffw_set_widths(int * width_list, int mapping_len, } } -void ffw_import_svg_glyph(int code, const char * filename) +void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy) { int enc = SFFindSlot(cur_fv->sf, cur_fv->map, code, ""); if(enc == -1) @@ -443,11 +441,14 @@ void ffw_import_svg_glyph(int code, const char * filename) // correct the origin { + int a = cur_fv->sf->ascent; + int d = cur_fv->sf->descent; real transform[6]; transform[0] = 1.0; transform[3] = 1.0; - transform[1] = transform[2] = transform[4]; - transform[5] = cur_fv->sf->descent; + transform[1] = transform[2] = 0.0; + transform[4] = -ox * (a+d); + transform[5] = -oy * (a+d) + d; FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth); } } diff --git a/src/util/ffw.h b/src/util/ffw.h index b66c24b..fcb57dc 100644 --- a/src/util/ffw.h +++ b/src/util/ffw.h @@ -62,7 +62,8 @@ void ffw_set_widths(int * width_list, int mapping_len, //////////////////////// // others -void ffw_import_svg_glyph(int code, const char * filename); +// (ox,oy) is the position of the true origin, fractions related to em_size +void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy); void ffw_auto_hint(void); void ffw_override_fstype(void); From 84b096655143a13e60e12925d8a04bc972271384 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Fri, 20 Sep 2013 20:30:46 +0800 Subject: [PATCH 4/7] set correct width --- src/HTMLRenderer/font.cc | 29 ++++++++--------------------- src/util/ffw.c | 6 ++++-- src/util/ffw.h | 3 ++- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index e3056e8..18d3a4d 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -241,9 +241,6 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) cairo_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi); cairo_t * cr = cairo_create(surface); - //debug - std::cerr << "debug " << code << std::endl; - std::cerr << "pdf width " << ((Gfx8BitFont*)font)->getWidth(code) << std::endl; /* cairo_set_font_size(cr, scale); cairo_set_font_face(cr, cur_font->getFontFace()); @@ -254,6 +251,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) double ox, oy; ox = oy = 0.0; + auto glyph_width = ((Gfx8BitFont*)font)->getWidth(code); // manually draw the char to get the metrics // adapted from _render_type3_glyph of poppler { @@ -285,6 +283,12 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) // set ctm cairo_set_matrix(cr, &ctm); + // calculate the position of origin + cairo_matrix_transform_point(&ctm, &ox, &oy); + // calculate glyph width + double dummy = 0; + cairo_matrix_transform_point(&ctm, &glyph_width, &dummy); + // draw the glyph auto output_dev = new CairoOutputDev(); output_dev->setCairo(cr); @@ -306,23 +310,6 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) auto glyph_index = cur_font->getGlyph(code, nullptr, 0); gfx->display(char_procs->getVal(glyph_index, &char_proc_obj)); - double wx, wy; - output_dev->getType3GlyphWidth(&wx, &wy); - cairo_matrix_transform_distance(&m1, &wx, &wy); - std::cerr << "wx " << wx << " wy " << wy << std::endl; - - if(output_dev->hasType3GlyphBBox()) - { - double *bbox = output_dev->getType3GlyphBBox(); - - cairo_matrix_transform_point (&m1, &bbox[0], &bbox[1]); - cairo_matrix_transform_point (&m1, &bbox[2], &bbox[3]); - std::cerr << "*bbox"; - for(int i = 0; i < 4; ++i) - std::cerr << ' ' << bbox[i]; - std::cerr << std::endl; - } - char_proc_obj.free(); delete gfx; delete output_dev; @@ -345,7 +332,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) throw string("Error in cairo: ") + cairo_status_to_string(status); } - ffw_import_svg_glyph(code, glyph_filename.c_str(), ox / GLYPH_DUMP_EM_SIZE, oy / GLYPH_DUMP_EM_SIZE); + ffw_import_svg_glyph(code, glyph_filename.c_str(), ox / GLYPH_DUMP_EM_SIZE, 1.0 - oy / GLYPH_DUMP_EM_SIZE, glyph_width / GLYPH_DUMP_EM_SIZE); } string font_filename = (char*)str_fmt("%s/f%llx.ttf", param.tmp_dir.c_str(), fn_id); diff --git a/src/util/ffw.c b/src/util/ffw.c index 84bcd4e..01228df 100644 --- a/src/util/ffw.c +++ b/src/util/ffw.c @@ -425,7 +425,7 @@ void ffw_set_widths(int * width_list, int mapping_len, } } -void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy) +void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy, double width) { int enc = SFFindSlot(cur_fv->sf, cur_fv->map, code, ""); if(enc == -1) @@ -439,7 +439,7 @@ void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy) if(!ok) err("Import SVG glyph failed"); - // correct the origin + // correct origin and width { int a = cur_fv->sf->ascent; int d = cur_fv->sf->descent; @@ -450,6 +450,8 @@ void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy) transform[4] = -ox * (a+d); transform[5] = -oy * (a+d) + d; FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth); + + SCSynchronizeWidth(sc, floor(width * (a+d) + 0.5), sc->width, cur_fv); } } diff --git a/src/util/ffw.h b/src/util/ffw.h index fcb57dc..1beddfd 100644 --- a/src/util/ffw.h +++ b/src/util/ffw.h @@ -63,7 +63,8 @@ void ffw_set_widths(int * width_list, int mapping_len, //////////////////////// // others // (ox,oy) is the position of the true origin, fractions related to em_size -void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy); +// also true for glyph_width +void ffw_import_svg_glyph(int code, const char * filename, double ox, double oy, double glyph_width); void ffw_auto_hint(void); void ffw_override_fstype(void); From 197317a9a741c0da71123376443a97dcd4648d15 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Fri, 20 Sep 2013 21:17:39 +0800 Subject: [PATCH 5/7] clean code --- .../SplashBackgroundRenderer.h | 3 +- src/HTMLRenderer/font.cc | 56 +++++++++++++------ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/BackgroundRenderer/SplashBackgroundRenderer.h b/src/BackgroundRenderer/SplashBackgroundRenderer.h index be56418..e999a10 100644 --- a/src/BackgroundRenderer/SplashBackgroundRenderer.h +++ b/src/BackgroundRenderer/SplashBackgroundRenderer.h @@ -41,8 +41,7 @@ public: // Does this device use beginType3Char/endType3Char? Otherwise, // text in Type 3 fonts will be drawn with drawChar/drawString. - // debug -// virtual GBool interpretType3Chars() { return !param.process_type3; } + virtual GBool interpretType3Chars() { return !param.process_type3; } #if POPPLER_OLDER_THAN_0_23_0 virtual void startPage(int pageNum, GfxState *state); diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index 18d3a4d..f94c4df 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -210,11 +210,6 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) tm_transform_bbox(font_matrix, transformed_bbox); double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0]; double transformed_bbox_height = transformed_bbox[3] - transformed_bbox[1]; - //debug - std::cerr << "transformed bbox:"; - for(int i = 0; i < 4; ++i) - std::cerr << ' ' << transformed_bbox[i]; - std::cerr << std::endl; // we want the glyphs is rendered in a box of size around 100 x 100 // for rectangles, the longer edge should be 100 info.font_size_scale = std::max(transformed_bbox_width, transformed_bbox_height); @@ -241,20 +236,48 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) cairo_surface_set_fallback_resolution(surface, param.h_dpi, param.v_dpi); cairo_t * cr = cairo_create(surface); - /* - cairo_set_font_size(cr, scale); - cairo_set_font_face(cr, cur_font->getFontFace()); - cairo_show_glyphs(cr, &glyph, 1); - */ - // track the positio of the origin double ox, oy; ox = oy = 0.0; auto glyph_width = ((Gfx8BitFont*)font)->getWidth(code); - // manually draw the char to get the metrics - // adapted from _render_type3_glyph of poppler + { + // pain the glyph + cairo_set_font_face(cr, cur_font->getFontFace()); + + cairo_matrix_t m1, m2, m3; + // set up m1 + // m1 shift the bottom-left corner of the glyph bbox to the origin + // also set font size to scale + cairo_matrix_init_translate(&m1, -transformed_bbox[0], transformed_bbox[1]); + cairo_matrix_init_scale(&m2, scale, scale); + cairo_matrix_multiply(&m1, &m1, &m2); + cairo_set_font_matrix(cr, &m1); + + cairo_glyph_t glyph; + glyph.index = cur_font->getGlyph(code, nullptr, 0); + glyph.x = 0; + glyph.y = GLYPH_DUMP_EM_SIZE; + cairo_show_glyphs(cr, &glyph, 1); + + + // apply the type 3 font's font matrix before m1 + // such that we got the mapping from type 3 font space to user space, then we will be able to calculate mapped position for ox,oy and glyph_width + cairo_matrix_init(&m2, font_matrix[0], font_matrix[1], font_matrix[2], font_matrix[3], font_matrix[4], font_matrix[5]); + cairo_matrix_init_scale(&m3, 1, -1); + cairo_matrix_multiply(&m2, &m2, &m3); + cairo_matrix_multiply(&m2, &m2, &m1); + + cairo_matrix_transform_point(&m2, &ox, &oy); + double dummy = 0; + cairo_matrix_transform_distance(&m2, &glyph_width, &dummy); + } + + /* + { + // manually draw the char to get the metrics + // adapted from _render_type3_glyph of poppler cairo_matrix_t ctm, m, m1; cairo_matrix_init_identity(&ctm); @@ -287,7 +310,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) cairo_matrix_transform_point(&ctm, &ox, &oy); // calculate glyph width double dummy = 0; - cairo_matrix_transform_point(&ctm, &glyph_width, &dummy); + cairo_matrix_transform_distance(&ctm, &glyph_width, &dummy); // draw the glyph auto output_dev = new CairoOutputDev(); @@ -314,9 +337,8 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) delete gfx; delete output_dev; } + */ - -// cairo_set_source_rgb(cr, 0., 0., 0.); { auto status = cairo_status(cr); cairo_destroy(cr); @@ -332,7 +354,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) throw string("Error in cairo: ") + cairo_status_to_string(status); } - ffw_import_svg_glyph(code, glyph_filename.c_str(), ox / GLYPH_DUMP_EM_SIZE, 1.0 - oy / GLYPH_DUMP_EM_SIZE, glyph_width / GLYPH_DUMP_EM_SIZE); + ffw_import_svg_glyph(code, glyph_filename.c_str(), ox / GLYPH_DUMP_EM_SIZE, -oy / GLYPH_DUMP_EM_SIZE, glyph_width / GLYPH_DUMP_EM_SIZE); } string font_filename = (char*)str_fmt("%s/f%llx.ttf", param.tmp_dir.c_str(), fn_id); From 7c0505ffec21993057fc0cad119f1854a6a1c98c Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Fri, 20 Sep 2013 21:19:46 +0800 Subject: [PATCH 6/7] changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 2e76c41..61bb5f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Developing v0.10 * Background image optimization * Support output background image in JPEG (--bg-format jpg) * [Experimental] Support output background image in SVG (--bg-format svg) +* [Experimental] Support Type 3 fonts * New options --bg-format --font-format (same as --font-sufix, but without the leading dot) From 09203f61a483762c16f649e797e2439337e8939b Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Sat, 21 Sep 2013 13:56:57 +0800 Subject: [PATCH 7/7] new option --process-type3 --- pdf2htmlEX.1.in | 7 +++++++ src/HTMLRenderer/font.cc | 11 ++++++----- src/pdf2htmlEX.cc | 10 ++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pdf2htmlEX.1.in b/pdf2htmlEX.1.in index c1e8de7..830b209 100644 --- a/pdf2htmlEX.1.in +++ b/pdf2htmlEX.1.in @@ -184,6 +184,13 @@ Clear the fstype bits in TTF/OTF fonts. Turn this on if Internet Explorer complains about 'Permission must be Installable' AND you have permission to do so. +.TP +.B --process-type3 <0|1> (Default: 0) +If turned on, pdf2htmlEX will try to convert Type 3 fonts such that text can be rendered natively in HTML. +Otherwise all text with Type 3 fonts will be rendered as image. + +This feature is highly experimental. + .SS Text .TP diff --git a/src/HTMLRenderer/font.cc b/src/HTMLRenderer/font.cc index f94c4df..54c4e38 100644 --- a/src/HTMLRenderer/font.cc +++ b/src/HTMLRenderer/font.cc @@ -210,10 +210,10 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) tm_transform_bbox(font_matrix, transformed_bbox); double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0]; double transformed_bbox_height = transformed_bbox[3] - transformed_bbox[1]; - // we want the glyphs is rendered in a box of size around 100 x 100 - // for rectangles, the longer edge should be 100 info.font_size_scale = std::max(transformed_bbox_width, transformed_bbox_height); + // we want the glyphs is rendered in a box of size around GLYPH_DUMP_EM_SIZE x GLYPH_DUMP_EM_SIZE + // for rectangles, the longer edge should be GLYPH_DUMP_EM_SIZE const double GLYPH_DUMP_EM_SIZE = 100.0; double scale = GLYPH_DUMP_EM_SIZE / info.font_size_scale; @@ -242,6 +242,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) auto glyph_width = ((Gfx8BitFont*)font)->getWidth(code); +#if 1 { // pain the glyph cairo_set_font_face(cr, cur_font->getFontFace()); @@ -273,8 +274,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) double dummy = 0; cairo_matrix_transform_distance(&m2, &glyph_width, &dummy); } - - /* +#else { // manually draw the char to get the metrics // adapted from _render_type3_glyph of poppler @@ -308,6 +308,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) // calculate the position of origin cairo_matrix_transform_point(&ctm, &ox, &oy); + oy -= transformed_bbox_height * scale; // calculate glyph width double dummy = 0; cairo_matrix_transform_distance(&ctm, &glyph_width, &dummy); @@ -337,7 +338,7 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) delete gfx; delete output_dev; } - */ +#endif { auto status = cairo_status(cr); diff --git a/src/pdf2htmlEX.cc b/src/pdf2htmlEX.cc index 2df3568..91547db 100644 --- a/src/pdf2htmlEX.cc +++ b/src/pdf2htmlEX.cc @@ -146,6 +146,7 @@ void parse_options (int argc, char **argv) .add("stretch-narrow-glyph", ¶m.stretch_narrow_glyph, 0, "stretch narrow glyphs instead of padding them") .add("squeeze-wide-glyph", ¶m.squeeze_wide_glyph, 1, "shrink wide glyphs instead of truncating them") .add("override-fstype", ¶m.override_fstype, 0, "clear the fstype bits in TTF/OTF fonts") + .add("process-type3", ¶m.process_type3, 0, "convert Type 3 fonts for web (experimental)") // text .add("heps", ¶m.h_eps, 1.0, "horizontal threshold for merging text, in pixels") @@ -299,8 +300,13 @@ void check_param() exit(EXIT_FAILURE); } - //test - param.process_type3 = 1; +#if not ENABLE_SVG + if(param.process_type3) + { + cerr << "process-type3 is enabled, however SVG support is not built in this version of pdf2htmlEX." << endl; + exit(EXIT_FAILURE); + } +#endif } int main(int argc, char **argv)