|
|
|
@ -36,6 +36,7 @@ |
|
|
|
|
#define _USE_MATH_DEFINES |
|
|
|
|
#include <math.h> |
|
|
|
|
#include <assert.h> |
|
|
|
|
#include <malloc.h> |
|
|
|
|
|
|
|
|
|
#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); |
|
|
|
|
} |
|
|
|
|