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);