From 9a2047777f3bd38601df47415c979f6a77f90f33 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Fri, 31 Aug 2012 15:50:14 +0800 Subject: [PATCH] use asc/dec of local matched font if possible --- src/HTMLRenderer.h | 4 +- src/HTMLRenderer/export.cc | 6 +- src/HTMLRenderer/install.cc | 26 +++-- src/HTMLRenderer/text.cc | 224 ++++++++++++++++++------------------ 4 files changed, 138 insertions(+), 122 deletions(-) diff --git a/src/HTMLRenderer.h b/src/HTMLRenderer.h index bbfeb52..88e20c2 100644 --- a/src/HTMLRenderer.h +++ b/src/HTMLRenderer.h @@ -126,7 +126,7 @@ class HTMLRenderer : public OutputDev void add_tmp_file (const std::string & fn); void clean_tmp_files (); boost::filesystem::path dump_embedded_font (GfxFont * font, long long fn_id); - void embed_font(const boost::filesystem::path & filepath, GfxFont * font, FontInfo & info); + void embed_font(const boost::filesystem::path & filepath, GfxFont * font, FontInfo & info, bool get_metric_only = false); //////////////////////////////////////////////////// // manage styles @@ -153,7 +153,7 @@ class HTMLRenderer : public OutputDev */ 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); + void export_local_font(const FontInfo & info, GfxFont * font, const std::string & original_font_name, const std::string & cssfont); void export_font_size(long long fs_id, double font_size); void export_transform_matrix(long long tm_id, const double * tm); diff --git a/src/HTMLRenderer/export.cc b/src/HTMLRenderer/export.cc index 1e14d70..a61c7e6 100644 --- a/src/HTMLRenderer/export.cc +++ b/src/HTMLRenderer/export.cc @@ -50,9 +50,9 @@ void HTMLRenderer::export_remote_default_font(long long fn_id) allcss_fout << format(".f%|1$x|{font-family:sans-serif;color:transparent;visibility:hidden;}")%fn_id << endl; } -void HTMLRenderer::export_local_font(long long fn_id, GfxFont * font, const string & original_font_name, const string & cssfont) +void HTMLRenderer::export_local_font(const FontInfo & info, GfxFont * font, const string & original_font_name, const string & cssfont) { - allcss_fout << format(".f%|1$x|{") % fn_id; + allcss_fout << format(".f%|1$x|{") % info.id; allcss_fout << "font-family:" << ((cssfont == "") ? (original_font_name + "," + general_font_family(font)) : cssfont) << ";"; if(font->isBold() || ifind_first(original_font_name, "bold")) @@ -63,7 +63,7 @@ void HTMLRenderer::export_local_font(long long fn_id, GfxFont * font, const stri else if(font->isItalic() || ifind_first(original_font_name, "italic")) allcss_fout << "font-style:italic;"; - allcss_fout << "line-height:" << (font->getAscent() - font->getDescent()) << ";"; + allcss_fout << "line-height:" << (info.ascent - info.descent) << ";"; allcss_fout << "}" << endl; } diff --git a/src/HTMLRenderer/install.cc b/src/HTMLRenderer/install.cc index 4c9d135..5a6f396 100644 --- a/src/HTMLRenderer/install.cc +++ b/src/HTMLRenderer/install.cc @@ -15,6 +15,7 @@ #include "HTMLRenderer.h" #include "namespace.h" +#include "util.h" FontInfo HTMLRenderer::install_font(GfxFont * font) { @@ -102,12 +103,12 @@ void HTMLRenderer::install_embedded_font(GfxFont * font, FontInfo & info) void HTMLRenderer::install_base_font(GfxFont * font, GfxFontLoc * font_loc, FontInfo & info) { + GfxFontLoc * localfontloc = font->locateFont(xref, gFalse); if(param->embed_base_font) { - GfxFontLoc * fontloc = font->locateFont(xref, gFalse); - if(fontloc != nullptr) + if(localfontloc != nullptr) { - embed_font(path(fontloc->path->getCString()), font, info); + embed_font(path(localfontloc->path->getCString()), font, info); export_remote_font(info, param->font_suffix, param->font_format, font); return; } @@ -130,13 +131,22 @@ void HTMLRenderer::install_base_font(GfxFont * font, GfxFontLoc * font_loc, Font else cssfont = iter->second; - info.ascent = font->getAscent(); - info.descent = font->getDescent(); + // still try to get an idea of read ascent/descent + if(localfontloc != nullptr) + { + // fill in ascent/descent only, do not embed + embed_font(path(localfontloc->path->getCString()), font, info, true); + } + else + { + info.ascent = font->getAscent(); + info.descent = font->getDescent(); + } - export_local_font(info.id, font, psname, cssfont); + export_local_font(info, font, psname, cssfont); } -void HTMLRenderer::install_external_font( GfxFont * font, FontInfo & info) +void HTMLRenderer::install_external_font(GfxFont * font, FontInfo & info) { string fontname(font->getName()->getCString()); @@ -148,7 +158,7 @@ void HTMLRenderer::install_external_font( GfxFont * font, FontInfo & info) cerr << "Warning: workaround for font names in bad encodings." << endl; } - export_local_font(info.id, font, fontname, ""); + export_local_font(info, font, fontname, ""); } long long HTMLRenderer::install_font_size(double font_size) diff --git a/src/HTMLRenderer/text.cc b/src/HTMLRenderer/text.cc index 2e7117d..00f853b 100644 --- a/src/HTMLRenderer/text.cc +++ b/src/HTMLRenderer/text.cc @@ -1,7 +1,7 @@ /* * text.ccc * - * Handling text and relative stuffs + * Handling text & font, and relative stuffs * * by WangLu * 2012.08.14 @@ -153,7 +153,7 @@ path HTMLRenderer::dump_embedded_font (GfxFont * font, long long fn_id) return filepath; } -void HTMLRenderer::embed_font(const path & filepath, GfxFont * font, FontInfo & info) +void HTMLRenderer::embed_font(const path & filepath, GfxFont * font, FontInfo & info, bool get_metric_only) { string suffix = filepath.extension().string(); to_lower(suffix); @@ -172,132 +172,139 @@ void HTMLRenderer::embed_font(const path & filepath, GfxFont * font, FontInfo & Gfx8BitFont * font_8bit = nullptr; - /* - * 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 using a PostScript encoding list (glyph id <-> glpyh name) - * - * for 8bit + TrueType - * sort the glpyhs as the original order, and later will map GID (instead of char code) to Unicode - * - * for CID + nonTrueType - * Flatten the font - * - * for CID Truetype - * same as 8bitTrueType, except for that we have to check 65536 charcodes - */ - if(!font->isCIDFont()) + if(get_metric_only) { - font_8bit = dynamic_cast(font); - maxcode = 0xff; - if((suffix == ".ttf") || (suffix == ".ttc") || (suffix == ".otf")) - { - script_fout << "Reencode(\"original\")" << endl; - FoFiTrueType *fftt = nullptr; - if((fftt = FoFiTrueType::load((char*)filepath.c_str())) != nullptr) - { - code2GID = font_8bit->getCodeToGIDMap(fftt); - code2GID_len = 256; - delete fftt; - } - } - else - { - // move the slot such that it's consistent with the encoding seen in PDF - ofstream out(tmp_dir / (fn + "_.encoding")); - add_tmp_file(fn+"_.encoding"); - - out << format("/%1% [") % fn << endl; - for(int i = 0; i < 256; ++i) - { - auto cn = font_8bit->getCharName(i); - out << "/" << ((cn == nullptr) ? ".notdef" : cn) << endl; - } - out << "] def" << endl; - - script_fout << format("LoadEncodingFile(%1%)") % (tmp_dir / (fn+"_.encoding")) << endl; - script_fout << format("Reencode(\"%1%\")") % fn << endl; - } + info.use_tounicode = false; } else { - maxcode = 0xffff; - - if(suffix == ".ttf") + /* + * 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 using a PostScript encoding list (glyph id <-> glpyh name) + * + * for 8bit + TrueType + * sort the glpyhs as the original order, and later will map GID (instead of char code) to Unicode + * + * for CID + nonTrueType + * Flatten the font + * + * for CID Truetype + * same as 8bitTrueType, except for that we have to check 65536 charcodes + */ + if(!font->isCIDFont()) { - script_fout << "Reencode(\"original\")" << endl; + font_8bit = dynamic_cast(font); + maxcode = 0xff; + if((suffix == ".ttf") || (suffix == ".ttc") || (suffix == ".otf")) + { + script_fout << "Reencode(\"original\")" << endl; + FoFiTrueType *fftt = nullptr; + if((fftt = FoFiTrueType::load((char*)filepath.c_str())) != nullptr) + { + code2GID = font_8bit->getCodeToGIDMap(fftt); + code2GID_len = 256; + delete fftt; + } + } + else + { + // move the slot such that it's consistent with the encoding seen in PDF + ofstream out(tmp_dir / (fn + "_.encoding")); + add_tmp_file(fn+"_.encoding"); - GfxCIDFont * _font = dynamic_cast(font); + out << format("/%1% [") % fn << endl; + for(int i = 0; i < 256; ++i) + { + auto cn = font_8bit->getCharName(i); + out << "/" << ((cn == nullptr) ? ".notdef" : cn) << endl; + } + out << "] def" << endl; - // code2GID has been stored for embedded CID fonts - code2GID = _font->getCIDToGID(); - code2GID_len = _font->getCIDToGIDLen(); + script_fout << format("LoadEncodingFile(%1%)") % (tmp_dir / (fn+"_.encoding")) << endl; + script_fout << format("Reencode(\"%1%\")") % fn << endl; + } } else { - script_fout << "CIDFlatten()" << endl; + maxcode = 0xffff; + + if(suffix == ".ttf") + { + script_fout << "Reencode(\"original\")" << endl; + + GfxCIDFont * _font = dynamic_cast(font); + + // code2GID has been stored for embedded CID fonts + code2GID = _font->getCIDToGID(); + code2GID_len = _font->getCIDToGIDLen(); + } + else + { + script_fout << "CIDFlatten()" << endl; + } } - } - - /* - * Step 2 - * map charcode (or GID for CID truetype) - * generate an Consortium encoding file and let fontforge handle it. - * - * - Always map to Unicode for 8bit TrueType fonts and CID fonts - * - * - For 8bit nonTruetype fonts: - * Try to calculate the correct Unicode value from the glyph names, unless param->always_apply_tounicode is set - * - */ - info.use_tounicode = ((suffix == ".ttf") || (font->isCIDFont()) || (param->always_apply_tounicode)); + /* + * Step 2 + * map charcode (or GID for CID truetype) + * generate an Consortium encoding file and let fontforge handle it. + * + * - Always map to Unicode for 8bit TrueType fonts and CID fonts + * + * - For 8bit nonTruetype fonts: + * Try to calculate the correct Unicode value from the glyph names, unless param->always_apply_tounicode is set + * + */ - auto ctu = font->getToUnicode(); + info.use_tounicode = ((suffix == ".ttf") || (font->isCIDFont()) || (param->always_apply_tounicode)); - ofstream map_fout(tmp_dir / (fn + ".encoding")); - add_tmp_file(fn+".encoding"); + auto ctu = font->getToUnicode(); - int cnt = 0; - for(int i = 0; i <= maxcode; ++i) - { - if((suffix != ".ttf") && (font_8bit != nullptr) && (font_8bit->getCharName(i) == nullptr)) - continue; + ofstream map_fout(tmp_dir / (fn + ".encoding")); + add_tmp_file(fn+".encoding"); - ++ cnt; - map_fout << format("0x%|1$X|") % ((code2GID && (i < code2GID_len))? code2GID[i] : i); - - Unicode u, *pu=&u; - - if(info.use_tounicode) + int cnt = 0; + for(int i = 0; i <= maxcode; ++i) { - int n = 0; - if(ctu) - n = ctu->mapToUnicode(i, &pu); - u = check_unicode(pu, n, i, font); + if((suffix != ".ttf") && (font_8bit != nullptr) && (font_8bit->getCharName(i) == nullptr)) + continue; + + ++ cnt; + map_fout << format("0x%|1$X|") % ((code2GID && (i < code2GID_len))? code2GID[i] : i); + + Unicode u, *pu=&u; + + if(info.use_tounicode) + { + int n = 0; + if(ctu) + n = ctu->mapToUnicode(i, &pu); + u = check_unicode(pu, n, i, font); + } + else + { + u = unicode_from_font(i, font); + } + + map_fout << format(" 0x%|1$X|") % u; + map_fout << format(" # 0x%|1$X|") % i; + + map_fout << endl; } - else + + if(cnt > 0) { - u = unicode_from_font(i, font); + script_fout << format("LoadEncodingFile(%1%, \"%2%\")") % (tmp_dir / (fn+".encoding")) % fn << endl; + script_fout << format("Reencode(\"%1%\", 1)") % fn << endl; } - map_fout << format(" 0x%|1$X|") % u; - map_fout << format(" # 0x%|1$X|") % i; - - map_fout << endl; + if(ctu) + ctu->decRefCnt(); } - if(cnt > 0) - { - script_fout << format("LoadEncodingFile(%1%, \"%2%\")") % (tmp_dir / (fn+".encoding")) % fn << endl; - script_fout << format("Reencode(\"%1%\", 1)") % fn << endl; - } - - if(ctu) - ctu->decRefCnt(); - auto dest = ((param->single_html ? tmp_dir : dest_dir) / (fn+(param->font_suffix))); if(param->single_html) add_tmp_file(fn+(param->font_suffix)); @@ -307,9 +314,10 @@ void HTMLRenderer::embed_font(const path & filepath, GfxFont * font, FontInfo & * Firefox & Chrome interprets the values in different ways * Trying to unify them */ - script_fout << format("Generate(%1%)") % dest << endl; + add_tmp_file(fn + "_.ttf"); + script_fout << format("Generate(%1%)") % (tmp_dir / (fn + "_.ttf")) << endl; script_fout << "Close()" << endl; - script_fout << format("Open(%1%, 1)") % dest << endl; + script_fout << format("Open(%1%, 1)") % (tmp_dir / (fn + "_.ttf")) << endl; script_fout << ifstream(PDF2HTMLEX_DATA_PATH / UNIFY_SCRIPT_FILENAME).rdbuf(); script_fout << format("Generate(%1%)") % dest << endl; script_fout.close(); @@ -346,8 +354,6 @@ void HTMLRenderer::embed_font(const path & filepath, GfxFont * font, FontInfo & { cerr << "Ascent: " << info.ascent << " Descent: " << info.descent << endl; } - - export_remote_font(info, param->font_suffix, param->font_format, font); } void HTMLRenderer::drawString(GfxState * state, GooString * s)