07-ft-variations-runtime-check.patch (6773B)
1 diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c 2 --- a/gfx/cairo/cairo/src/cairo-ft-font.c 3 +++ b/gfx/cairo/cairo/src/cairo-ft-font.c 4 @@ -72,6 +72,7 @@ 5 #else 6 #define access(p, m) 0 7 #endif 8 +#include <dlfcn.h> 9 10 /* Fontconfig version older than 2.6 didn't have these options */ 11 #ifndef FC_LCD_FILTER 12 @@ -120,6 +121,16 @@ extern void mozilla_UnlockFTLibrary(FT_L 13 : (void)CAIRO_MUTEX_UNLOCK((unscaled)->mutex)) 14 15 /** 16 + * Function types for FreeType symbols we'll look up at runtime, rather than 17 + * relying on build-time checks for availability. 18 + */ 19 +typedef FT_Error (*GetVarFunc) (FT_Face, FT_MM_Var**); 20 +typedef FT_Error (*DoneVarFunc) (FT_Library, FT_MM_Var*); 21 +typedef FT_Error (*GetVarDesignCoordsFunc) (FT_Face, FT_UInt, FT_Fixed*); 22 +typedef FT_Error (*SetVarDesignCoordsFunc) (FT_Face, FT_UInt, FT_Fixed*); 23 +typedef FT_Error (*GetVarBlendCoordsFunc) (FT_Face, FT_UInt, FT_Fixed*); 24 + 25 +/** 26 * SECTION:cairo-ft 27 * @Title: FreeType Fonts 28 * @Short_Description: Font support for FreeType 29 @@ -477,22 +488,31 @@ static cairo_status_t 30 unscaled->have_color = FT_HAS_COLOR (face) != 0; 31 unscaled->have_color_set = TRUE; 32 33 -#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES 34 - { 35 + static GetVarFunc getVar; 36 + static DoneVarFunc doneVar; 37 + static GetVarDesignCoordsFunc getVarDesignCoords; 38 + 39 + static int firstTime = 1; 40 + if (firstTime) { 41 + getVar = (GetVarFunc) dlsym (RTLD_DEFAULT, "FT_Get_MM_Var"); 42 + doneVar = (DoneVarFunc) dlsym (RTLD_DEFAULT, "FT_Done_MM_Var"); 43 + getVarDesignCoords = (GetVarDesignCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Get_Var_Design_Coordinates"); 44 + firstTime = 0; 45 + } 46 + 47 + if (getVar && getVarDesignCoords) { 48 FT_MM_Var *ft_mm_var; 49 - if (0 == FT_Get_MM_Var (face, &ft_mm_var)) 50 + if (0 == (*getVar) (face, &ft_mm_var)) 51 { 52 unscaled->variations = calloc (ft_mm_var->num_axis, sizeof (FT_Fixed)); 53 if (unscaled->variations) 54 - FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, unscaled->variations); 55 -#if HAVE_FT_DONE_MM_VAR 56 - FT_Done_MM_Var (face->glyph->library, ft_mm_var); 57 -#else 58 - free (ft_mm_var); 59 -#endif 60 + (*getVarDesignCoords) (face, ft_mm_var->num_axis, unscaled->variations); 61 + if (doneVar) 62 + (*doneVar) (face->glyph->library, ft_mm_var); 63 + else 64 + free (ft_mm_var); 65 } 66 } 67 -#endif 68 } else { 69 char *filename_copy; 70 71 @@ -2366,7 +2386,24 @@ cairo_ft_apply_variations (FT_Face 72 FT_Error ret; 73 unsigned int instance_id = scaled_font->unscaled->id >> 16; 74 75 - ret = FT_Get_MM_Var (face, &ft_mm_var); 76 + static GetVarFunc getVar; 77 + static DoneVarFunc doneVar; 78 + static GetVarDesignCoordsFunc getVarDesignCoords; 79 + static SetVarDesignCoordsFunc setVarDesignCoords; 80 + 81 + static int firstTime = 1; 82 + if (firstTime) { 83 + getVar = (GetVarFunc) dlsym (RTLD_DEFAULT, "FT_Get_MM_Var"); 84 + doneVar = (DoneVarFunc) dlsym (RTLD_DEFAULT, "FT_Done_MM_Var"); 85 + getVarDesignCoords = (GetVarDesignCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Get_Var_Design_Coordinates"); 86 + setVarDesignCoords = (SetVarDesignCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Set_Var_Design_Coordinates"); 87 + firstTime = 0; 88 + } 89 + 90 + if (!getVar || !setVarDesignCoords) 91 + return; 92 + 93 + ret = (*getVar) (face, &ft_mm_var); 94 if (ret == 0) { 95 FT_Fixed *current_coords; 96 FT_Fixed *coords; 97 @@ -2431,27 +2468,28 @@ skip: 98 } 99 100 current_coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis); 101 -#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES 102 - ret = FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, current_coords); 103 - if (ret == 0) { 104 - for (i = 0; i < ft_mm_var->num_axis; i++) { 105 - if (coords[i] != current_coords[i]) 106 - break; 107 + 108 + if (getVarDesignCoords) { 109 + ret = (*getVarDesignCoords) (face, ft_mm_var->num_axis, current_coords); 110 + if (ret == 0) { 111 + for (i = 0; i < ft_mm_var->num_axis; i++) { 112 + if (coords[i] != current_coords[i]) 113 + break; 114 + } 115 + if (i == ft_mm_var->num_axis) 116 + goto done; 117 } 118 - if (i == ft_mm_var->num_axis) 119 - goto done; 120 } 121 -#endif 122 - 123 - FT_Set_Var_Design_Coordinates (face, ft_mm_var->num_axis, coords); 124 + 125 + (*setVarDesignCoords) (face, ft_mm_var->num_axis, coords); 126 done: 127 free (coords); 128 free (current_coords); 129 -#if HAVE_FT_DONE_MM_VAR 130 - FT_Done_MM_Var (face->glyph->library, ft_mm_var); 131 -#else 132 - free (ft_mm_var); 133 -#endif 134 + 135 + if (doneVar) 136 + (*doneVar) (face->glyph->library, ft_mm_var); 137 + else 138 + free (ft_mm_var); 139 } 140 } 141 142 @@ -2877,6 +2915,18 @@ static cairo_int_status_t 143 FT_Face face; 144 FT_Error error; 145 146 + static GetVarFunc getVar; 147 + static DoneVarFunc doneVar; 148 + static GetVarBlendCoordsFunc getVarBlendCoords; 149 + 150 + static int firstTime = 1; 151 + if (firstTime) { 152 + getVar = (GetVarFunc) dlsym (RTLD_DEFAULT, "FT_Get_MM_Var"); 153 + doneVar = (DoneVarFunc) dlsym (RTLD_DEFAULT, "FT_Done_MM_Var"); 154 + getVarBlendCoords = (GetVarBlendCoordsFunc) dlsym (RTLD_DEFAULT, "FT_Get_Var_Blend_Coordinates"); 155 + firstTime = 0; 156 + } 157 + 158 if (scaled_font->ft_options.synth_flags != 0) { 159 *is_synthetic = TRUE; 160 return status; 161 @@ -2896,7 +2946,7 @@ static cairo_int_status_t 162 * are the same as the font tables */ 163 *is_synthetic = TRUE; 164 165 - error = FT_Get_MM_Var (face, &mm_var); 166 + error = getVar ? (*getVar) (face, &mm_var) : -1; 167 if (error) { 168 status = _cairo_error (_ft_to_cairo_error (error)); 169 goto cleanup; 170 @@ -2909,15 +2959,14 @@ static cairo_int_status_t 171 goto cleanup; 172 } 173 174 -#if FREETYPE_MAJOR > 2 || ( FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 8) 175 /* If FT_Get_Var_Blend_Coordinates() is available, we can check if the 176 * current design coordinates are the default coordinates. In this case 177 * the current outlines match the font tables. 178 */ 179 - { 180 + if (getVarBlendCoords) { 181 int i; 182 183 - FT_Get_Var_Blend_Coordinates (face, num_axis, coords); 184 + (*getVarBlendCoords) (face, num_axis, coords); 185 *is_synthetic = FALSE; 186 for (i = 0; i < num_axis; i++) { 187 if (coords[i]) { 188 @@ -2926,15 +2975,13 @@ static cairo_int_status_t 189 } 190 } 191 } 192 -#endif 193 194 cleanup: 195 free (coords); 196 -#if HAVE_FT_DONE_MM_VAR 197 - FT_Done_MM_Var (face->glyph->library, mm_var); 198 -#else 199 - free (mm_var); 200 -#endif 201 + if (doneVar) 202 + (*doneVar) (face->glyph->library, mm_var); 203 + else 204 + free (mm_var); 205 } 206 207 _cairo_ft_unscaled_font_unlock_face (unscaled);