diff --git a/TODO b/TODO index 27c056a..6c5aa73 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -better solution for ascent/descent (cross-platform, embeded/not) +check exact asc/dsc option to embed local matched fonts for non-embedded ones diff --git a/share/all.css b/share/all.css index 9d5b559..e3f9f89 100644 --- a/share/all.css +++ b/share/all.css @@ -19,7 +19,7 @@ .l { position:absolute; white-space:pre; - font-size:0; + font-size:1px; transform-origin:0% 190%; -ms-transform-origin:0% 100%; -moz-transform-origin:0% 100%; diff --git a/src/HTMLRenderer.h b/src/HTMLRenderer.h index e159d48..f789df2 100644 --- a/src/HTMLRenderer.h +++ b/src/HTMLRenderer.h @@ -130,7 +130,7 @@ class HTMLRenderer : public OutputDev // manage styles //////////////////////////////////////////////////// FontInfo install_font(GfxFont * font); - void install_embedded_font(GfxFont * font, const std::string & suffix, long long fn_id, bool & use_tounicode); + void install_embedded_font(GfxFont * font, const std::string & suffix, long long fn_id, FontInfo & info); void install_base_font(GfxFont * font, GfxFontLoc * font_loc, long long fn_id); void install_external_font (GfxFont * font, long long fn_id); @@ -149,7 +149,7 @@ class HTMLRenderer : public OutputDev * remote font: to be retrieved from the web server * local font: to be substituted with a local (client side) font */ - void export_remote_font(long long fn_id, const std::string & suffix, const std::string & fontfileformat, GfxFont * font); + void export_remote_font(const FontInfo & info, const std::string & suffix, const std::string & fontfileformat, GfxFont * font); void export_remote_default_font(long long fn_id); void export_local_font(long long fn_id, GfxFont * font, const std::string & original_font_name, const std::string & cssfont); diff --git a/src/HTMLRenderer/export.cc b/src/HTMLRenderer/export.cc index 59a81ea..1e14d70 100644 --- a/src/HTMLRenderer/export.cc +++ b/src/HTMLRenderer/export.cc @@ -16,21 +16,22 @@ using boost::algorithm::ifind_first; -void HTMLRenderer::export_remote_font(long long fn_id, const string & suffix, const string & fontfileformat, GfxFont * font) +void HTMLRenderer::export_remote_font(const FontInfo & info, const string & suffix, const string & fontfileformat, GfxFont * font) { - allcss_fout << format("@font-face{font-family:f%|1$x|;src:url(") % fn_id; + allcss_fout << format("@font-face{font-family:f%|1$x|;src:url(") % info.id; - const std::string fn = (format("f%|1$x|%2%") % fn_id % suffix).str(); + const std::string fn = (format("f%|1$x|") % info.id).str(); if(param->single_html) { - allcss_fout << "'data:font/" << fontfileformat << ";base64," << base64stream(ifstream(tmp_dir / fn, ifstream::binary)) << "'"; + allcss_fout << "'data:font/" << fontfileformat << ";base64," << base64stream(ifstream(tmp_dir / (fn+suffix), ifstream::binary)) << "'"; } else { - allcss_fout << fn; + allcss_fout << (fn+suffix); } + - allcss_fout << format(")format(\"%1%\");}.f%|2$x|{font-family:f%|2$x|;line-height:%3%;}") % fontfileformat % fn_id % (font->getAscent() - font->getDescent()) << endl; + allcss_fout << format(")format(\"%1%\");}.f%|2$x|{font-family:f%|2$x|;line-height:%3%;}") % fontfileformat % info.id % (info.ascent - info.descent) << endl; } static string general_font_family(GfxFont * font) diff --git a/src/HTMLRenderer/install.cc b/src/HTMLRenderer/install.cc index 9835ceb..a983065 100644 --- a/src/HTMLRenderer/install.cc +++ b/src/HTMLRenderer/install.cc @@ -19,7 +19,6 @@ #include "namespace.h" using std::all_of; -using std::round; FontInfo HTMLRenderer::install_font(GfxFont * font) { @@ -68,7 +67,7 @@ FontInfo HTMLRenderer::install_font(GfxFont * font) string suffix = dump_embedded_font(font, new_fn_id); if(suffix != "") { - install_embedded_font(font, suffix, new_fn_id, cur_info_iter->second.use_tounicode); + install_embedded_font(font, suffix, new_fn_id, cur_info_iter->second); } else { @@ -99,7 +98,7 @@ FontInfo HTMLRenderer::install_font(GfxFont * font) // TODO // add a new function and move to text.cc -void HTMLRenderer::install_embedded_font(GfxFont * font, const string & suffix, long long fn_id, bool & use_tounicode) +void HTMLRenderer::install_embedded_font(GfxFont * font, const string & suffix, long long fn_id, FontInfo & info) { string fn = (format("f%|1$x|") % fn_id).str(); @@ -202,7 +201,7 @@ void HTMLRenderer::install_embedded_font(GfxFont * font, const string & suffix, * */ - use_tounicode = ((suffix == ".ttf") || (font->isCIDFont()) || (param->always_apply_tounicode)); + info.use_tounicode = ((suffix == ".ttf") || (font->isCIDFont()) || (param->always_apply_tounicode)); auto ctu = font->getToUnicode(); @@ -220,7 +219,7 @@ void HTMLRenderer::install_embedded_font(GfxFont * font, const string & suffix, Unicode u, *pu=&u; - if(use_tounicode) + if(info.use_tounicode) { int n = 0; if(ctu) @@ -247,16 +246,45 @@ void HTMLRenderer::install_embedded_font(GfxFont * font, const string & suffix, if(ctu) ctu->decRefCnt(); - script_fout << format("Generate(%1%)") % ((param->single_html ? tmp_dir : dest_dir) / (fn+".ttf")) << endl; + auto dest = ((param->single_html ? tmp_dir : dest_dir) / (fn+".ttf")); if(param->single_html) add_tmp_file(fn+".ttf"); - if(system((boost::format("fontforge -script %1% 2>%2%") % script_path % (tmp_dir / NULL_FILENAME)).str().c_str()) != 0) + script_fout << format("Generate(%1%)") % dest << endl; + script_fout << format("Open(%1%, 1)") % dest << endl; + + for(const string & s1 : {"Win", "Typo", "HHead"}) + { + for(const string & s2 : {"Ascent", "Descent"}) + { + script_fout << "Print(GetOS2Value(\"" << s1 << s2 << "\"))" << endl; + } + } + script_fout << "SetOS2Value(\"TypoLineGap\", 0)" << endl; + script_fout << "SetOS2Value(\"HHeadLineGap\", 0)" << endl; + script_fout << format("Generate(%1%)") % dest << endl; + + if(system((boost::format("fontforge -script %1% 1>%2% 2>%3%") % script_path % (tmp_dir / (fn+".info")) % (tmp_dir / NULL_FILENAME)).str().c_str()) != 0) cerr << "Warning: fontforge failed." << endl; + add_tmp_file(fn+".info"); add_tmp_file(NULL_FILENAME); - export_remote_font(fn_id, ".ttf", "truetype", font); + // read metric + int WinAsc, WinDes, TypoAsc, TypoDes, HHeadAsc, HHeadDes; + if(ifstream(tmp_dir / (fn+".info")) >> WinAsc >> WinDes >> TypoAsc >> TypoDes >> HHeadAsc >> HHeadDes) + { + double em = TypoAsc - TypoDes; + info.ascent = ((double)HHeadAsc) / em; + info.descent = ((double)HHeadDes) / em; + } + else + { + info.ascent = font->getAscent(); + info.descent = font->getDescent(); + } + + export_remote_font(info, ".ttf", "truetype", font); } void HTMLRenderer::install_base_font(GfxFont * font, GfxFontLoc * font_loc, long long fn_id) diff --git a/src/HTMLRenderer/state.cc b/src/HTMLRenderer/state.cc index 1c24a43..5581c9b 100644 --- a/src/HTMLRenderer/state.cc +++ b/src/HTMLRenderer/state.cc @@ -354,11 +354,11 @@ void HTMLRenderer::prepare_line(GfxState * state) // TODO class for height html_fout << format("
") - % x + % x % y % cur_tm_id - % (state->getFont()->getAscent() * draw_font_size) - % (2*(state->getFont()->getAscent() * draw_font_size)) + % (cur_font_info.ascent * draw_font_size) + % (2 * cur_font_info.ascent * draw_font_size) ; //resync position diff --git a/src/util.h b/src/util.h index 84dbe63..853bc23 100644 --- a/src/util.h +++ b/src/util.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ using std::noskipws; using std::endl; using std::flush; using std::cerr; +using std::floor; // mute gcc warning of unused function namespace @@ -178,6 +180,7 @@ class FontInfo public: long long id; bool use_tounicode; + double ascent, descent; }; // wrapper of the transform matrix double[6]