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

improve accuray for type 3 fonts

This commit is contained in:
Lu Wang 2013-09-20 20:06:06 +08:00
parent 09856c0910
commit 8cac1e6aaf
3 changed files with 47 additions and 34 deletions

View File

@ -58,7 +58,6 @@ string HTMLRenderer::dump_embedded_font (GfxFont * font, FontInfo & info)
string filepath; string filepath;
long long fn_id = info.id; long long fn_id = info.id;
info.font_size_scale = 1.0;
try try
{ {
@ -198,15 +197,16 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info)
//calculate transformed metrics //calculate transformed metrics
double * font_bbox = font->getFontBBox(); double * font_bbox = font->getFontBBox();
// TODO: font matrix may not exists
double * font_matrix = font->getFontMatrix(); double * font_matrix = font->getFontMatrix();
double transformed_bbox[4]; double transformed_bbox[4];
memcpy(transformed_bbox, font_bbox, 4 * sizeof(double)); memcpy(transformed_bbox, font_bbox, 4 * sizeof(double));
/*
// add the origin to the bbox // add the origin to the bbox
if(transformed_bbox[0] > 0) transformed_bbox[0] = 0; if(transformed_bbox[0] > 0) transformed_bbox[0] = 0;
if(transformed_bbox[1] > 0) transformed_bbox[1] = 0; if(transformed_bbox[1] > 0) transformed_bbox[1] = 0;
if(transformed_bbox[2] < 0) transformed_bbox[2] = 0; if(transformed_bbox[2] < 0) transformed_bbox[2] = 0;
if(transformed_bbox[3] < 0) transformed_bbox[3] = 0; if(transformed_bbox[3] < 0) transformed_bbox[3] = 0;
*/
tm_transform_bbox(font_matrix, transformed_bbox); tm_transform_bbox(font_matrix, transformed_bbox);
double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0]; double transformed_bbox_width = transformed_bbox[2] - transformed_bbox[0];
double transformed_bbox_height = transformed_bbox[3] - transformed_bbox[1]; 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 // for rectangles, the longer edge should be 100
info.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; const double GLYPH_DUMP_EM_SIZE = 100.0;
double scale = GLYPH_DUMP_SIZE / info.font_size_scale; double scale = GLYPH_DUMP_EM_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];
// we choose ttf as it does not use char names // we choose ttf as it does not use char names
// or actually we don't use char names for ttf (see embed_font) // or actually we don't use char names for ttf (see embed_font)
ffw_new_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 // dump each glyph into svg and combine them
for(int code = 0; code < 256; ++code) for(int code = 0; code < 256; ++code)
{ {
if(!used_map[code]) continue; 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; cairo_surface_t * surface = nullptr;
string glyph_filename = (char*)str_fmt("%s/f%llx-%x.svg", param.tmp_dir.c_str(), fn_id, code); 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); 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 // manually draw the char to get the metrics
// adapted from _render_type3_glyph of poppler // adapted from _render_type3_glyph of poppler
{ {
cairo_matrix_t m1, m2; cairo_matrix_t ctm, m, m1;
cairo_matrix_init_translate(&m1, glyph.x, glyph.y); cairo_matrix_init_identity(&ctm);
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]); // apply font-matrix
cairo_matrix_init_scale(&m2, 1, -1); 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(&m1, &m1, &m2); cairo_matrix_multiply(&ctm, &ctm, &m);
cairo_transform(cr, &m1);
// 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(); auto output_dev = new CairoOutputDev();
output_dev->setCairo(cr); output_dev->setCairo(cr);
output_dev->setPrinting(true); output_dev->setPrinting(true);
@ -294,7 +303,8 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info)
output_dev->setInType3Char(gTrue); output_dev->setInType3Char(gTrue);
auto char_procs = ((Gfx8BitFont*)font)->getCharProcs(); auto char_procs = ((Gfx8BitFont*)font)->getCharProcs();
Object char_proc_obj; 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; double wx, wy;
output_dev->getType3GlyphWidth(&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); 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); 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; FontInfo & new_font_info = cur_info_iter->second;
new_font_info.id = new_fn_id; new_font_info.id = new_fn_id;
new_font_info.use_tounicode = true; new_font_info.use_tounicode = true;
new_font_info.font_size_scale = 1.0;
if(font == nullptr) if(font == nullptr)
{ {

View File

@ -306,8 +306,6 @@ void ffw_fix_metric()
{ {
double ascent, descent; double ascent, descent;
ffw_get_metric(&ascent, &descent); ffw_get_metric(&ascent, &descent);
//debug
printf("fix metrix: %lf %lf\n", ascent, descent);
ffw_set_metric(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, ""); int enc = SFFindSlot(cur_fv->sf, cur_fv->map, code, "");
if(enc == -1) if(enc == -1)
@ -443,11 +441,14 @@ void ffw_import_svg_glyph(int code, const char * filename)
// correct the origin // correct the origin
{ {
int a = cur_fv->sf->ascent;
int d = cur_fv->sf->descent;
real transform[6]; real transform[6];
transform[0] = 1.0; transform[0] = 1.0;
transform[3] = 1.0; transform[3] = 1.0;
transform[1] = transform[2] = transform[4]; transform[1] = transform[2] = 0.0;
transform[5] = cur_fv->sf->descent; transform[4] = -ox * (a+d);
transform[5] = -oy * (a+d) + d;
FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth); FVTrans(cur_fv, sc, transform, NULL, fvt_alllayers | fvt_dontmovewidth);
} }
} }

View File

@ -62,7 +62,8 @@ void ffw_set_widths(int * width_list, int mapping_len,
//////////////////////// ////////////////////////
// others // 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_auto_hint(void);
void ffw_override_fstype(void); void ffw_override_fstype(void);