From 5451b78f4a4d97277d3a411762844e97adda62cd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Dec 2022 00:07:18 -0500 Subject: [PATCH] Don't use alloca It complicates things on Windows, for no big win. Just preallocate a reasonable amount. --- util/hb-cairo-utils.c | 58 +++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index 285811afb..11aedb6ea 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -36,6 +36,7 @@ #define _USE_MATH_DEFINES #include #include +#include #ifndef MIN #define MIN(x,y) ((x) < (y) ? (x) : (y)) @@ -45,6 +46,8 @@ #define MAX(x,y) ((x) > (y) ? (x) : (y)) #endif +#define PREALLOCATED_COLOR_STOPS 16 + typedef struct { float r, g, b, a; } color_t; @@ -246,16 +249,19 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, float x2, float y2) { hb_face_t *face = hb_font_get_face (font); + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; unsigned int len; - hb_color_stop_t *stops; float xx0, yy0, xx1, yy1; float xxx0, yyy0, xxx1, yyy1; float min, max; cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = (hb_color_stop_t *) alloca (len * sizeof (hb_color_stop_t)); + if (len > PREALLOCATED_COLOR_STOPS) + stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t)); hb_color_line_get_color_stops (color_line, 0, &len, stops); + reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1); normalize_color_line (stops, len, &min, &max); @@ -277,6 +283,9 @@ hb_cairo_paint_linear_gradient (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); + + if (stops != stops_) + free (stops); } void @@ -287,16 +296,19 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, float x1, float y1, float r1) { hb_face_t *face = hb_font_get_face (font); + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; unsigned int len; - hb_color_stop_t *stops; float min, max; float xx0, yy0, xx1, yy1; float rr0, rr1; cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = (hb_color_stop_t *) alloca (len * sizeof (hb_color_stop_t)); + if (len > PREALLOCATED_COLOR_STOPS) + stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t)); hb_color_line_get_color_stops (color_line, 0, &len, stops); + normalize_color_line (stops, len, &min, &max); xx0 = x0 + min * (x1 - x0); @@ -320,6 +332,9 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); + + if (stops != stops_) + free (stops); } typedef struct { @@ -475,8 +490,10 @@ add_sweep_gradient_patches (hb_font_t *font, cairo_pattern_t *pattern) { hb_face_t *face = hb_font_get_face (font); - float *angles; - color_t *colors; + float angles_[PREALLOCATED_COLOR_STOPS]; + float *angles = angles_; + color_t colors_[PREALLOCATED_COLOR_STOPS]; + color_t *colors = colors_; color_t color0, color1; if (start_angle == end_angle) @@ -521,8 +538,11 @@ add_sweep_gradient_patches (hb_font_t *font, } } - angles = alloca (sizeof (float) * n_stops); - colors = alloca (sizeof (color_t) * n_stops); + if (n_stops > PREALLOCATED_COLOR_STOPS) + { + angles = (float *) malloc (sizeof (float) * n_stops); + colors = (color_t *) malloc (sizeof (color_t) * n_stops); + } for (unsigned i = 0; i < n_stops; i++) { @@ -555,7 +575,7 @@ add_sweep_gradient_patches (hb_font_t *font, 0., &color0, 2 * M_PI, &color0, pattern); - return; + goto done; } add_sweep_gradient_patches1 (cx, cy, radius, @@ -592,7 +612,7 @@ add_sweep_gradient_patches (hb_font_t *font, angles[n_stops - 1], &color0, 2 * M_PI, &color0, pattern); - return; + goto done; } } else @@ -693,8 +713,14 @@ add_sweep_gradient_patches (hb_font_t *font, } } } -done: ; } + +done: + + if (angles != angles_) + free (angles); + if (colors != colors_) + free (colors); } void @@ -706,15 +732,18 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr, float end_angle) { unsigned int len; - hb_color_stop_t *stops; + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; cairo_extend_t extend; double x1, y1, x2, y2; float max_x, max_y, radius; cairo_pattern_t *pattern; len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); - stops = alloca (len * sizeof (hb_color_stop_t)); + if (len > PREALLOCATED_COLOR_STOPS) + stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t)); hb_color_line_get_color_stops (color_line, 0, &len, stops); + qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); cairo_clip_extents (cr, &x1, &y1, &x2, &y2); @@ -732,4 +761,7 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); + + if (stops != stops_) + free (stops); }