Don't use alloca

It complicates things on Windows, for no
big win. Just preallocate a reasonable amount.
This commit is contained in:
Matthias Clasen 2022-12-19 00:07:18 -05:00 committed by Behdad Esfahbod
parent 7c12db46ff
commit 5451b78f4a
1 changed files with 45 additions and 13 deletions

View File

@ -36,6 +36,7 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <malloc.h>
#ifndef MIN #ifndef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y)) #define MIN(x,y) ((x) < (y) ? (x) : (y))
@ -45,6 +46,8 @@
#define MAX(x,y) ((x) > (y) ? (x) : (y)) #define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif #endif
#define PREALLOCATED_COLOR_STOPS 16
typedef struct { typedef struct {
float r, g, b, a; float r, g, b, a;
} color_t; } color_t;
@ -246,16 +249,19 @@ hb_cairo_paint_linear_gradient (cairo_t *cr,
float x2, float y2) float x2, float y2)
{ {
hb_face_t *face = hb_font_get_face (font); 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; unsigned int len;
hb_color_stop_t *stops;
float xx0, yy0, xx1, yy1; float xx0, yy0, xx1, yy1;
float xxx0, yyy0, xxx1, yyy1; float xxx0, yyy0, xxx1, yyy1;
float min, max; float min, max;
cairo_pattern_t *pattern; cairo_pattern_t *pattern;
len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); 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); hb_color_line_get_color_stops (color_line, 0, &len, stops);
reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1); reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1);
normalize_color_line (stops, len, &min, &max); normalize_color_line (stops, len, &min, &max);
@ -277,6 +283,9 @@ hb_cairo_paint_linear_gradient (cairo_t *cr,
cairo_paint (cr); cairo_paint (cr);
cairo_pattern_destroy (pattern); cairo_pattern_destroy (pattern);
if (stops != stops_)
free (stops);
} }
void void
@ -287,16 +296,19 @@ hb_cairo_paint_radial_gradient (cairo_t *cr,
float x1, float y1, float r1) float x1, float y1, float r1)
{ {
hb_face_t *face = hb_font_get_face (font); 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; unsigned int len;
hb_color_stop_t *stops;
float min, max; float min, max;
float xx0, yy0, xx1, yy1; float xx0, yy0, xx1, yy1;
float rr0, rr1; float rr0, rr1;
cairo_pattern_t *pattern; cairo_pattern_t *pattern;
len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); 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); hb_color_line_get_color_stops (color_line, 0, &len, stops);
normalize_color_line (stops, len, &min, &max); normalize_color_line (stops, len, &min, &max);
xx0 = x0 + min * (x1 - x0); xx0 = x0 + min * (x1 - x0);
@ -320,6 +332,9 @@ hb_cairo_paint_radial_gradient (cairo_t *cr,
cairo_paint (cr); cairo_paint (cr);
cairo_pattern_destroy (pattern); cairo_pattern_destroy (pattern);
if (stops != stops_)
free (stops);
} }
typedef struct { typedef struct {
@ -475,8 +490,10 @@ add_sweep_gradient_patches (hb_font_t *font,
cairo_pattern_t *pattern) cairo_pattern_t *pattern)
{ {
hb_face_t *face = hb_font_get_face (font); hb_face_t *face = hb_font_get_face (font);
float *angles; float angles_[PREALLOCATED_COLOR_STOPS];
color_t *colors; float *angles = angles_;
color_t colors_[PREALLOCATED_COLOR_STOPS];
color_t *colors = colors_;
color_t color0, color1; color_t color0, color1;
if (start_angle == end_angle) if (start_angle == end_angle)
@ -521,8 +538,11 @@ add_sweep_gradient_patches (hb_font_t *font,
} }
} }
angles = alloca (sizeof (float) * n_stops); if (n_stops > PREALLOCATED_COLOR_STOPS)
colors = alloca (sizeof (color_t) * n_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++) for (unsigned i = 0; i < n_stops; i++)
{ {
@ -555,7 +575,7 @@ add_sweep_gradient_patches (hb_font_t *font,
0., &color0, 0., &color0,
2 * M_PI, &color0, 2 * M_PI, &color0,
pattern); pattern);
return; goto done;
} }
add_sweep_gradient_patches1 (cx, cy, radius, add_sweep_gradient_patches1 (cx, cy, radius,
@ -592,7 +612,7 @@ add_sweep_gradient_patches (hb_font_t *font,
angles[n_stops - 1], &color0, angles[n_stops - 1], &color0,
2 * M_PI, &color0, 2 * M_PI, &color0,
pattern); pattern);
return; goto done;
} }
} }
else 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 void
@ -706,15 +732,18 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr,
float end_angle) float end_angle)
{ {
unsigned int len; 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; cairo_extend_t extend;
double x1, y1, x2, y2; double x1, y1, x2, y2;
float max_x, max_y, radius; float max_x, max_y, radius;
cairo_pattern_t *pattern; cairo_pattern_t *pattern;
len = hb_color_line_get_color_stops (color_line, 0, NULL, NULL); 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); hb_color_line_get_color_stops (color_line, 0, &len, stops);
qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop);
cairo_clip_extents (cr, &x1, &y1, &x2, &y2); cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
@ -732,4 +761,7 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr,
cairo_paint (cr); cairo_paint (cr);
cairo_pattern_destroy (pattern); cairo_pattern_destroy (pattern);
if (stops != stops_)
free (stops);
} }