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:
parent
09856c0910
commit
8cac1e6aaf
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user