diff options
Diffstat (limited to 'gfx/cairo/07-ft-variations-runtime-check.patch')
-rw-r--r-- | gfx/cairo/07-ft-variations-runtime-check.patch | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/gfx/cairo/07-ft-variations-runtime-check.patch b/gfx/cairo/07-ft-variations-runtime-check.patch new file mode 100644 index 0000000000..a7bb4e9ad0 --- /dev/null +++ b/gfx/cairo/07-ft-variations-runtime-check.patch @@ -0,0 +1,207 @@ +diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c +--- a/gfx/cairo/cairo/src/cairo-ft-font.c ++++ b/gfx/cairo/cairo/src/cairo-ft-font.c +@@ -72,6 +72,7 @@ + #else + #define access(p, m) 0 + #endif ++#include <dlfcn.h> + + /* Fontconfig version older than 2.6 didn't have these options */ + #ifndef FC_LCD_FILTER +@@ -120,6 +121,16 @@ extern void mozilla_UnlockFTLibrary(FT_L + : (void)CAIRO_MUTEX_UNLOCK((unscaled)->mutex)) + + /** ++ * Function types for FreeType symbols we'll look up at runtime, rather than ++ * relying on build-time checks for availability. ++ */ ++typedef FT_Error (*GetVarFunc) (FT_Face, FT_MM_Var**); ++typedef FT_Error (*DoneVarFunc) (FT_Library, FT_MM_Var*); ++typedef FT_Error (*GetVarDesignCoordsFunc) (FT_Face, FT_UInt, FT_Fixed*); ++typedef FT_Error (*SetVarDesignCoordsFunc) (FT_Face, FT_UInt, FT_Fixed*); ++typedef FT_Error (*GetVarBlendCoordsFunc) (FT_Face, FT_UInt, FT_Fixed*); ++ ++/** + * SECTION:cairo-ft + * @Title: FreeType Fonts + * @Short_Description: Font support for FreeType +@@ -477,22 +488,31 @@ static cairo_status_t + unscaled->have_color = FT_HAS_COLOR (face) != 0; + unscaled->have_color_set = TRUE; + +-#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES +- { ++ static GetVarFunc getVar; ++ static DoneVarFunc doneVar; ++ static GetVarDesignCoordsFunc getVarDesignCoords; ++ ++ static int firstTime = 1; ++ if (firstTime) { ++ getVar = (GetVarFunc) dlsym (RTLD_DEFAULT, "FT_Get_MM_Var"); ++ doneVar = (DoneVarFunc) dlsym (RTLD_DEFAULT, "FT_Done_MM_Var"); ++ getVarDesignCoords = (GetVarDesignCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Get_Var_Design_Coordinates"); ++ firstTime = 0; ++ } ++ ++ if (getVar && getVarDesignCoords) { + FT_MM_Var *ft_mm_var; +- if (0 == FT_Get_MM_Var (face, &ft_mm_var)) ++ if (0 == (*getVar) (face, &ft_mm_var)) + { + unscaled->variations = calloc (ft_mm_var->num_axis, sizeof (FT_Fixed)); + if (unscaled->variations) +- FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, unscaled->variations); +-#if HAVE_FT_DONE_MM_VAR +- FT_Done_MM_Var (face->glyph->library, ft_mm_var); +-#else +- free (ft_mm_var); +-#endif ++ (*getVarDesignCoords) (face, ft_mm_var->num_axis, unscaled->variations); ++ if (doneVar) ++ (*doneVar) (face->glyph->library, ft_mm_var); ++ else ++ free (ft_mm_var); + } + } +-#endif + } else { + char *filename_copy; + +@@ -2366,7 +2386,24 @@ cairo_ft_apply_variations (FT_Face + FT_Error ret; + unsigned int instance_id = scaled_font->unscaled->id >> 16; + +- ret = FT_Get_MM_Var (face, &ft_mm_var); ++ static GetVarFunc getVar; ++ static DoneVarFunc doneVar; ++ static GetVarDesignCoordsFunc getVarDesignCoords; ++ static SetVarDesignCoordsFunc setVarDesignCoords; ++ ++ static int firstTime = 1; ++ if (firstTime) { ++ getVar = (GetVarFunc) dlsym (RTLD_DEFAULT, "FT_Get_MM_Var"); ++ doneVar = (DoneVarFunc) dlsym (RTLD_DEFAULT, "FT_Done_MM_Var"); ++ getVarDesignCoords = (GetVarDesignCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Get_Var_Design_Coordinates"); ++ setVarDesignCoords = (SetVarDesignCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Set_Var_Design_Coordinates"); ++ firstTime = 0; ++ } ++ ++ if (!getVar || !setVarDesignCoords) ++ return; ++ ++ ret = (*getVar) (face, &ft_mm_var); + if (ret == 0) { + FT_Fixed *current_coords; + FT_Fixed *coords; +@@ -2431,27 +2468,28 @@ skip: + } + + current_coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis); +-#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES +- ret = FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, current_coords); +- if (ret == 0) { +- for (i = 0; i < ft_mm_var->num_axis; i++) { +- if (coords[i] != current_coords[i]) +- break; ++ ++ if (getVarDesignCoords) { ++ ret = (*getVarDesignCoords) (face, ft_mm_var->num_axis, current_coords); ++ if (ret == 0) { ++ for (i = 0; i < ft_mm_var->num_axis; i++) { ++ if (coords[i] != current_coords[i]) ++ break; ++ } ++ if (i == ft_mm_var->num_axis) ++ goto done; + } +- if (i == ft_mm_var->num_axis) +- goto done; + } +-#endif +- +- FT_Set_Var_Design_Coordinates (face, ft_mm_var->num_axis, coords); ++ ++ (*setVarDesignCoords) (face, ft_mm_var->num_axis, coords); + done: + free (coords); + free (current_coords); +-#if HAVE_FT_DONE_MM_VAR +- FT_Done_MM_Var (face->glyph->library, ft_mm_var); +-#else +- free (ft_mm_var); +-#endif ++ ++ if (doneVar) ++ (*doneVar) (face->glyph->library, ft_mm_var); ++ else ++ free (ft_mm_var); + } + } + +@@ -2877,6 +2915,18 @@ static cairo_int_status_t + FT_Face face; + FT_Error error; + ++ static GetVarFunc getVar; ++ static DoneVarFunc doneVar; ++ static GetVarBlendCoordsFunc getVarBlendCoords; ++ ++ static int firstTime = 1; ++ if (firstTime) { ++ getVar = (GetVarFunc) dlsym (RTLD_DEFAULT, "FT_Get_MM_Var"); ++ doneVar = (DoneVarFunc) dlsym (RTLD_DEFAULT, "FT_Done_MM_Var"); ++ getVarBlendCoords = (GetVarBlendCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Get_Var_Blend_Coordinates"); ++ firstTime = 0; ++ } ++ + if (scaled_font->ft_options.synth_flags != 0) { + *is_synthetic = TRUE; + return status; +@@ -2896,7 +2946,7 @@ static cairo_int_status_t + * are the same as the font tables */ + *is_synthetic = TRUE; + +- error = FT_Get_MM_Var (face, &mm_var); ++ error = getVar ? (*getVar) (face, &mm_var) : -1; + if (error) { + status = _cairo_error (_ft_to_cairo_error (error)); + goto cleanup; +@@ -2909,15 +2959,14 @@ static cairo_int_status_t + goto cleanup; + } + +-#if FREETYPE_MAJOR > 2 || ( FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 8) + /* If FT_Get_Var_Blend_Coordinates() is available, we can check if the + * current design coordinates are the default coordinates. In this case + * the current outlines match the font tables. + */ +- { ++ if (getVarBlendCoords) { + int i; + +- FT_Get_Var_Blend_Coordinates (face, num_axis, coords); ++ (*getVarBlendCoords) (face, num_axis, coords); + *is_synthetic = FALSE; + for (i = 0; i < num_axis; i++) { + if (coords[i]) { +@@ -2926,15 +2975,13 @@ static cairo_int_status_t + } + } + } +-#endif + + cleanup: + free (coords); +-#if HAVE_FT_DONE_MM_VAR +- FT_Done_MM_Var (face->glyph->library, mm_var); +-#else +- free (mm_var); +-#endif ++ if (doneVar) ++ (*doneVar) (face->glyph->library, mm_var); ++ else ++ free (mm_var); + } + + _cairo_ft_unscaled_font_unlock_face (unscaled); |