diff options
Diffstat (limited to 'base/fapi_ft.c')
-rw-r--r-- | base/fapi_ft.c | 129 |
1 files changed, 76 insertions, 53 deletions
diff --git a/base/fapi_ft.c b/base/fapi_ft.c index 4b4b6857..c7cb22ea 100644 --- a/base/fapi_ft.c +++ b/base/fapi_ft.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -59,6 +59,7 @@ #include FT_TRUETYPE_TABLES_H #include FT_MULTIPLE_MASTERS_H #include FT_TYPE1_TABLES_H +#include FT_SIZES_H /* Note: structure definitions here start with FF_, which stands for 'FAPI FreeType". */ @@ -642,14 +643,15 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, data. (NOTE: if those do not match the original font's metrics, again, the hinting can be distorted) */ - if (a_char_ref->metrics_type == gs_fapi_metrics_replace && !a_fapi_font->is_mtx_skipped) - face->ft_inc_int->object->metrics_type = gs_fapi_metrics_replace_width; - else + if (a_char_ref->metrics_type == gs_fapi_metrics_replace && !a_fapi_font->is_mtx_skipped) { + face->ft_inc_int->object->glyph_metrics_index = 0xFFFFFFFF; + delta.x = FT_MulFix(a_char_ref->sb_x >> 16, ft_face->size->metrics.x_scale); + delta.y = FT_MulFix(a_char_ref->sb_y >> 16, ft_face->size->metrics.y_scale); + FT_Vector_Transform( &delta, &face->ft_transform); + } + else { face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type; - - delta.x = FT_MulFix(a_char_ref->sb_x >> 16, ft_face->size->metrics.x_scale); - delta.y = FT_MulFix(a_char_ref->sb_y >> 16, ft_face->size->metrics.y_scale); - FT_Vector_Transform( &delta, &face->ft_transform); + } } else if (face->ft_inc_int) /* Make sure we don't leave this set to the last value, as we may then use inappropriate metrics values */ @@ -705,6 +707,20 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, if (ft_error == FT_Err_Out_Of_Memory || ft_error == FT_Err_Array_Too_Large) { + /* An out of memory error can leave the FT TTF hinting context in a partially initialized state. + Meaning bad things can happen if we try to render another glyph using the same context. + Ideally this would be handled by FT internally, but that means some implications for supporting + out of spec fonts, and performance. + By destroying, recreating and resetting the size, it invalidates the (possibly corrupt) hinting + context, and ensures a fresh start in any subsequent call. + */ + FT_Size ftsize = NULL; + FT_Done_Size(ft_face->size); + FT_New_Size(face->ft_face, &ftsize); + FT_Activate_Size(ftsize); + ft_error = FT_Set_Char_Size(face->ft_face, face->width, face->height, face->horz_res, face->vert_res); + if (ft_error != 0) return_error(gs_error_invalidfont); + return (gs_error_VMerror); } @@ -809,6 +825,10 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font, FT_Render_Mode mode = FT_RENDER_MODE_MONO; ft_error = FT_Render_Glyph(ft_face->glyph, mode); + if (ft_error != 0) { + (*a_glyph) = NULL; + return (gs_error_VMerror); + } } else { (*a_glyph) = NULL; @@ -1072,8 +1092,8 @@ transform_decompose(FT_Matrix * a_transform, FT_UInt * xresp, FT_UInt * yresp, * scalex/y we calculate will be >64 after rounding. */ - if (scalex < 10.0) { - fact = 10.016 / scalex; + if (scalex < 1.0) { + fact = 1.016 / scalex; scalex = scalex * fact; scaley = scaley * fact; } @@ -1330,6 +1350,50 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font, return_error(gs_error_VMerror); } a_font->server_font_data = face; + + if (!a_font->is_type1) { + for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) { + if (a_font->ttf_cmap_req[i].platform_id > 0) { + for (j = 0; j < face->ft_face->num_charmaps; j++) { + if (FT_Get_CMap_Format(face->ft_face->charmaps[j]) >= 0 + && face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id + && face->ft_face->charmaps[j]->encoding_id == a_font->ttf_cmap_req[i].encoding_id) { + + cmap = face->ft_face->charmaps[j]; + break; + } + } + } + else { + break; + } + } + if (cmap) { + (void)FT_Set_Charmap(face->ft_face, cmap); + } + else if (a_font->full_font_buf != NULL || a_font->font_file_path != NULL) { + /* If we've passed a complete TTF to Freetype, but *haven't* requested a + * specific cmap table above, try to use a Unicode one + * If that doesn't work, just leave the default in place. + */ + (void)FT_Select_Charmap(face->ft_face, ft_encoding_unicode); + } + /* For PDF, we have to know which cmap table actually was selected */ + if (face->ft_face->charmap != NULL) { + a_font->ttf_cmap_selected.platform_id = face->ft_face->charmap->platform_id; + a_font->ttf_cmap_selected.encoding_id = face->ft_face->charmap->encoding_id; + } + else { + /* Just in case */ + a_font->ttf_cmap_selected.platform_id = -1; + a_font->ttf_cmap_selected.encoding_id = -1; + } + } + else { + /* Just in case */ + a_font->ttf_cmap_selected.platform_id = -1; + a_font->ttf_cmap_selected.encoding_id = -1; + } } else a_font->server_font_data = NULL; @@ -1378,49 +1442,6 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font, FT_Set_Transform(face->ft_face, &face->ft_transform, NULL); - if (!a_font->is_type1) { - for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) { - if (a_font->ttf_cmap_req[i].platform_id > 0) { - for (j = 0; j < face->ft_face->num_charmaps; j++) { - if (FT_Get_CMap_Format(face->ft_face->charmaps[j]) >= 0 - && face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id - && face->ft_face->charmaps[j]->encoding_id == a_font->ttf_cmap_req[i].encoding_id) { - - cmap = face->ft_face->charmaps[j]; - break; - } - } - } - else { - break; - } - } - if (cmap) { - (void)FT_Set_Charmap(face->ft_face, cmap); - } - else if (a_font->full_font_buf != NULL || a_font->font_file_path != NULL) { - /* If we've passed a complete TTF to Freetype, but *haven't* requested a - * specific cmap table above, try to use a Unicode one - * If that doesn't work, just leave the default in place. - */ - (void)FT_Select_Charmap(face->ft_face, ft_encoding_unicode); - } - /* For PDF, we have to know which cmap table actually was selected */ - if (face->ft_face->charmap != NULL) { - a_font->ttf_cmap_selected.platform_id = face->ft_face->charmap->platform_id; - a_font->ttf_cmap_selected.encoding_id = face->ft_face->charmap->encoding_id; - } - else { - /* Just in case */ - a_font->ttf_cmap_selected.platform_id = -1; - a_font->ttf_cmap_selected.encoding_id = -1; - } - } - else { - /* Just in case */ - a_font->ttf_cmap_selected.platform_id = -1; - a_font->ttf_cmap_selected.encoding_id = -1; - } } /* dpf("gs_fapi_ft_get_scaled_font return %d\n", a_font->server_font_data ? 0 : -1); */ @@ -1856,6 +1877,8 @@ static const gs_fapi_server freetypeserver = { {0}, 0, false, + false, + {1, 0, 0, 1, 0, 0}, 1, {1, 0, 0, 1, 0, 0}, gs_fapi_ft_ensure_open, |