summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/fapi_ft.c')
-rw-r--r--base/fapi_ft.c129
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,