Don't use alloca
It complicates things on Windows, for no big win. Just preallocate a reasonable amount.
This commit is contained in:
parent
7c12db46ff
commit
5451b78f4a
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue