summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/fapi_ft.c')
-rw-r--r--base/fapi_ft.c77
1 files changed, 39 insertions, 38 deletions
diff --git a/base/fapi_ft.c b/base/fapi_ft.c
index c7cb22ea..a4b4fe69 100644
--- a/base/fapi_ft.c
+++ b/base/fapi_ft.c
@@ -59,7 +59,6 @@
#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". */
@@ -707,20 +706,6 @@ 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);
}
@@ -857,7 +842,7 @@ load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font,
FF_free(s->ftmemory, bmg);
}
}
- else {
+ else if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_OutlineGlyph olg;
ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & olg);
@@ -1292,31 +1277,45 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font,
/* Get the length of the TrueType data. */
unsigned long ms;
- code = a_font->get_long(a_font, gs_fapi_font_feature_TT_size, 0, &ms);
- if (code < 0)
- return code;
- if (ms == 0)
- return_error(gs_error_invalidfont);
-
- open_args.memory_size = (FT_Long)ms;
-
- /* Load the TrueType data into a single buffer. */
- open_args.memory_base = own_font_data =
- FF_alloc(s->ftmemory, open_args.memory_size);
- if (!own_font_data)
- return_error(gs_error_VMerror);
-
- own_font_data_len = open_args.memory_size;
+ if (a_font->retrieve_tt_font != NULL) {
+ code = a_font->retrieve_tt_font(a_font, &own_font_data, &ms);
+ if (code == 0) {
+ data_owned = false;
+ open_args.memory_base = own_font_data;
+ open_args.memory_size = own_font_data_len = ms;
+ }
+ }
+ else
+ code = gs_error_unregistered;
- code = a_font->serialize_tt_font(a_font, own_font_data,
- open_args.memory_size);
- if (code < 0)
- return code;
+ if (code < 0) {
+ code = a_font->get_long(a_font, gs_fapi_font_feature_TT_size, 0, &ms);
+ if (code < 0)
+ return code;
+ if (ms == 0)
+ return_error(gs_error_invalidfont);
+
+ open_args.memory_size = (FT_Long)ms;
+
+ /* Load the TrueType data into a single buffer. */
+ open_args.memory_base = own_font_data =
+ FF_alloc(s->ftmemory, open_args.memory_size);
+ if (!own_font_data)
+ return_error(gs_error_VMerror);
+
+ own_font_data_len = open_args.memory_size;
+
+ code = a_font->serialize_tt_font(a_font, own_font_data,
+ open_args.memory_size);
+ if (code < 0)
+ return code;
+ }
/* We always load incrementally. */
ft_inc_int = new_inc_int(a_server, a_font);
if (!ft_inc_int) {
- FF_free(s->ftmemory, own_font_data);
+ if (data_owned)
+ FF_free(s->ftmemory, own_font_data);
return_error(gs_error_VMerror);
}
}
@@ -1334,7 +1333,8 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font,
&ft_face);
if (ft_error) {
delete_inc_int (a_server, ft_inc_int);
- FF_free(s->ftmemory, own_font_data);
+ if (data_owned)
+ FF_free(s->ftmemory, own_font_data);
return ft_to_gs_error(ft_error);
}
}
@@ -1344,7 +1344,8 @@ gs_fapi_ft_get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font,
new_face(a_server, ft_face, ft_inc_int, ft_strm,
own_font_data, own_font_data_len, data_owned);
if (!face) {
- FF_free(s->ftmemory, own_font_data);
+ if (data_owned)
+ FF_free(s->ftmemory, own_font_data);
FT_Done_Face(ft_face);
delete_inc_int(a_server, ft_inc_int);
return_error(gs_error_VMerror);