|
|
|
@ -38,7 +38,7 @@ |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
float r, g, b, a; |
|
|
|
|
} color_t; |
|
|
|
|
} hb_cairo_color_t; |
|
|
|
|
|
|
|
|
|
static inline cairo_extend_t |
|
|
|
|
hb_cairo_extend (hb_paint_extend_t extend) |
|
|
|
@ -373,7 +373,7 @@ hb_cairo_paint_radial_gradient (cairo_t *cr, |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
float x, y; |
|
|
|
|
} Point; |
|
|
|
|
} hb_cairo_point_t; |
|
|
|
|
|
|
|
|
|
static inline float |
|
|
|
|
interpolate (float f0, float f1, float f) |
|
|
|
@ -382,7 +382,7 @@ interpolate (float f0, float f1, float f) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void |
|
|
|
|
premultiply (color_t *c) |
|
|
|
|
premultiply (hb_cairo_color_t *c) |
|
|
|
|
{ |
|
|
|
|
c->r *= c->a; |
|
|
|
|
c->g *= c->a; |
|
|
|
@ -390,7 +390,7 @@ premultiply (color_t *c) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void |
|
|
|
|
unpremultiply (color_t *c) |
|
|
|
|
unpremultiply (hb_cairo_color_t *c) |
|
|
|
|
{ |
|
|
|
|
if (c->a != 0.f) |
|
|
|
|
{ |
|
|
|
@ -401,7 +401,7 @@ unpremultiply (color_t *c) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) |
|
|
|
|
interpolate_colors (hb_cairo_color_t *c0, hb_cairo_color_t *c1, float k, hb_cairo_color_t *c) |
|
|
|
|
{ |
|
|
|
|
// According to the COLR specification, gradients
|
|
|
|
|
// should be interpolated in premultiplied form
|
|
|
|
@ -415,44 +415,44 @@ interpolate_colors (color_t *c0, color_t *c1, float k, color_t *c) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline float |
|
|
|
|
dot (Point p, Point q) |
|
|
|
|
dot (hb_cairo_point_t p, hb_cairo_point_t q) |
|
|
|
|
{ |
|
|
|
|
return p.x * q.x + p.y * q.y; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline Point |
|
|
|
|
normalize (Point p) |
|
|
|
|
static inline hb_cairo_point_t |
|
|
|
|
normalize (hb_cairo_point_t p) |
|
|
|
|
{ |
|
|
|
|
float len = sqrt (dot (p, p)); |
|
|
|
|
|
|
|
|
|
return Point { p.x / len, p.y / len }; |
|
|
|
|
return hb_cairo_point_t { p.x / len, p.y / len }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline Point |
|
|
|
|
sum (Point p, Point q) |
|
|
|
|
static inline hb_cairo_point_t |
|
|
|
|
sum (hb_cairo_point_t p, hb_cairo_point_t q) |
|
|
|
|
{ |
|
|
|
|
return Point { p.x + q.x, p.y + q.y }; |
|
|
|
|
return hb_cairo_point_t { p.x + q.x, p.y + q.y }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline Point |
|
|
|
|
difference (Point p, Point q) |
|
|
|
|
static inline hb_cairo_point_t |
|
|
|
|
difference (hb_cairo_point_t p, hb_cairo_point_t q) |
|
|
|
|
{ |
|
|
|
|
return Point { p.x - q.x, p.y - q.y }; |
|
|
|
|
return hb_cairo_point_t { p.x - q.x, p.y - q.y }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline Point |
|
|
|
|
scale (Point p, float f) |
|
|
|
|
static inline hb_cairo_point_t |
|
|
|
|
scale (hb_cairo_point_t p, float f) |
|
|
|
|
{ |
|
|
|
|
return Point { p.x * f, p.y * f }; |
|
|
|
|
return hb_cairo_point_t { p.x * f, p.y * f }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
Point center, p0, c0, c1, p1; |
|
|
|
|
color_t color0, color1; |
|
|
|
|
} Patch; |
|
|
|
|
hb_cairo_point_t center, p0, c0, c1, p1; |
|
|
|
|
hb_cairo_color_t color0, color1; |
|
|
|
|
} hb_cairo_patch_t; |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
add_patch (cairo_pattern_t *pattern, Point *center, Patch *p) |
|
|
|
|
add_patch (cairo_pattern_t *pattern, hb_cairo_point_t *center, hb_cairo_patch_t *p) |
|
|
|
|
{ |
|
|
|
|
cairo_mesh_pattern_begin_patch (pattern); |
|
|
|
|
cairo_mesh_pattern_move_to (pattern, center->x, center->y); |
|
|
|
@ -489,27 +489,27 @@ add_patch (cairo_pattern_t *pattern, Point *center, Patch *p) |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
add_sweep_gradient_patches1 (float cx, float cy, float radius, |
|
|
|
|
float a0, color_t *c0, |
|
|
|
|
float a1, color_t *c1, |
|
|
|
|
float a0, hb_cairo_color_t *c0, |
|
|
|
|
float a1, hb_cairo_color_t *c1, |
|
|
|
|
cairo_pattern_t *pattern) |
|
|
|
|
{ |
|
|
|
|
Point center = Point { cx, cy }; |
|
|
|
|
hb_cairo_point_t center = hb_cairo_point_t { cx, cy }; |
|
|
|
|
int num_splits; |
|
|
|
|
Point p0; |
|
|
|
|
color_t color0, color1; |
|
|
|
|
hb_cairo_point_t p0; |
|
|
|
|
hb_cairo_color_t color0, color1; |
|
|
|
|
|
|
|
|
|
num_splits = ceilf (fabs (a1 - a0) / MAX_ANGLE); |
|
|
|
|
p0 = Point { cosf (a0), sinf (a0) }; |
|
|
|
|
p0 = hb_cairo_point_t { cosf (a0), sinf (a0) }; |
|
|
|
|
color0 = *c0; |
|
|
|
|
|
|
|
|
|
for (int a = 0; a < num_splits; a++) |
|
|
|
|
{ |
|
|
|
|
float k = (a + 1.) / num_splits; |
|
|
|
|
float angle1; |
|
|
|
|
Point p1; |
|
|
|
|
Point A, U; |
|
|
|
|
Point C0, C1; |
|
|
|
|
Patch patch; |
|
|
|
|
hb_cairo_point_t p1; |
|
|
|
|
hb_cairo_point_t A, U; |
|
|
|
|
hb_cairo_point_t C0, C1; |
|
|
|
|
hb_cairo_patch_t patch; |
|
|
|
|
|
|
|
|
|
angle1 = interpolate (a0, a1, k); |
|
|
|
|
interpolate_colors (c0, c1, k, &color1); |
|
|
|
@ -517,12 +517,12 @@ add_sweep_gradient_patches1 (float cx, float cy, float radius, |
|
|
|
|
patch.color0 = color0; |
|
|
|
|
patch.color1 = color1; |
|
|
|
|
|
|
|
|
|
p1 = Point { cosf (angle1), sinf (angle1) }; |
|
|
|
|
p1 = hb_cairo_point_t { cosf (angle1), sinf (angle1) }; |
|
|
|
|
patch.p0 = sum (center, scale (p0, radius)); |
|
|
|
|
patch.p1 = sum (center, scale (p1, radius)); |
|
|
|
|
|
|
|
|
|
A = normalize (sum (p0, p1)); |
|
|
|
|
U = Point { -A.y, A.x }; |
|
|
|
|
U = hb_cairo_point_t { -A.y, A.x }; |
|
|
|
|
C0 = sum (A, scale (U, dot (difference (p0, A), p0) / dot (U, p0))); |
|
|
|
|
C1 = sum (A, scale (U, dot (difference (p1, A), p1) / dot (U, p1))); |
|
|
|
|
|
|
|
|
@ -548,15 +548,15 @@ add_sweep_gradient_patches (hb_color_stop_t *stops, |
|
|
|
|
{ |
|
|
|
|
float angles_[PREALLOCATED_COLOR_STOPS]; |
|
|
|
|
float *angles = angles_; |
|
|
|
|
color_t colors_[PREALLOCATED_COLOR_STOPS]; |
|
|
|
|
color_t *colors = colors_; |
|
|
|
|
color_t color0, color1; |
|
|
|
|
hb_cairo_color_t colors_[PREALLOCATED_COLOR_STOPS]; |
|
|
|
|
hb_cairo_color_t *colors = colors_; |
|
|
|
|
hb_cairo_color_t color0, color1; |
|
|
|
|
|
|
|
|
|
if (start_angle == end_angle) |
|
|
|
|
{ |
|
|
|
|
if (extend == CAIRO_EXTEND_PAD) |
|
|
|
|
{ |
|
|
|
|
color_t c; |
|
|
|
|
hb_cairo_color_t c; |
|
|
|
|
if (start_angle > 0) |
|
|
|
|
{ |
|
|
|
|
c.r = hb_color_get_red (stops[0].color) / 255.; |
|
|
|
@ -603,7 +603,7 @@ add_sweep_gradient_patches (hb_color_stop_t *stops, |
|
|
|
|
if (n_stops > PREALLOCATED_COLOR_STOPS) |
|
|
|
|
{ |
|
|
|
|
angles = (float *) malloc (sizeof (float) * n_stops); |
|
|
|
|
colors = (color_t *) malloc (sizeof (color_t) * n_stops); |
|
|
|
|
colors = (hb_cairo_color_t *) malloc (sizeof (hb_cairo_color_t) * n_stops); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < n_stops; i++) |
|
|
|
@ -729,7 +729,7 @@ add_sweep_gradient_patches (hb_color_stop_t *stops, |
|
|
|
|
for (unsigned i = 1; i < n_stops; i++) |
|
|
|
|
{ |
|
|
|
|
float a0, a1; |
|
|
|
|
color_t *c0, *c1; |
|
|
|
|
hb_cairo_color_t *c0, *c1; |
|
|
|
|
|
|
|
|
|
if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT)) |
|
|
|
|
{ |
|
|
|
@ -750,7 +750,7 @@ add_sweep_gradient_patches (hb_color_stop_t *stops, |
|
|
|
|
continue; |
|
|
|
|
if (a0 < 0) |
|
|
|
|
{ |
|
|
|
|
color_t color; |
|
|
|
|
hb_cairo_color_t color; |
|
|
|
|
float f = (0 - a0)/(a1 - a0); |
|
|
|
|
interpolate_colors (c0, c1, f, &color); |
|
|
|
|
add_sweep_gradient_patches1 (cx, cy, radius, |
|
|
|
@ -760,7 +760,7 @@ add_sweep_gradient_patches (hb_color_stop_t *stops, |
|
|
|
|
} |
|
|
|
|
else if (a1 >= _2_M_PIf) |
|
|
|
|
{ |
|
|
|
|
color_t color; |
|
|
|
|
hb_cairo_color_t color; |
|
|
|
|
float f = (_2_M_PIf - a0)/(a1 - a0); |
|
|
|
|
interpolate_colors (c0, c1, f, &color); |
|
|
|
|
add_sweep_gradient_patches1 (cx, cy, radius, |
|
|
|
|