static inline int fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, const gs_fixed_point *p0, const gs_fixed_point *p1, const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) { /* p0 must be the lowest vertex. */ int code; gs_linear_color_edge e0, e1, e2; int num_components = dev->color_info.num_components; if (p0->y == p1->y) return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p2, p1, p2, c0, c2, c1, c2); if (p1->y == p2->y) return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p2, p0, p1, c0, c2, c0, c1); e0.start = *p0; e0.end = *p2; e0.c0 = c0; e0.c1 = c2; e0.clip_x = fa->clip->p.x; e1.start = *p0; e1.end = *p1; e1.c0 = c0; e1.c1 = c1; e1.clip_x = fa->clip->q.x; if (p0->y < p1->y && p1->y < p2->y) { e2.start = *p1; e2.end = *p2; e2.c0 = c1; e2.c1 = c2; e2.clip_x = fa->clip->q.x; if (check_gradient_overflow(&e0, &e1, num_components)) return 0; if (check_gradient_overflow(&e0, &e2, num_components)) return 0; code = fill_linear_color_trapezoid_nocheck(dev, fa, &e0, &e1); if (code <= 0) /* Sic! */ return code; return fill_linear_color_trapezoid_nocheck(dev, fa, &e0, &e2); } else { /* p0->y < p2->y && p2->y < p1->y */ e2.start = *p2; e2.end = *p1; e2.c0 = c2; e2.c1 = c1; e2.clip_x = fa->clip->q.x; if (check_gradient_overflow(&e0, &e1, num_components)) return 0; if (check_gradient_overflow(&e2, &e1, num_components)) return 0; code = fill_linear_color_trapezoid_nocheck(dev, fa, &e0, &e1); if (code <= 0) /* Sic! */ return code; return fill_linear_color_trapezoid_nocheck(dev, fa, &e2, &e1); } }
/* Fill a trapezoid with a linear color. [p0 : p1] - left edge, from bottom to top. [p2 : p3] - right edge, from bottom to top. The filled area is within Y-spans of both edges. This implemetation actually handles a bilinear color, in which the generatrix keeps a parallelizm to the X axis. In general a bilinear function doesn't keep the generatrix parallelizm, so the caller must decompose/approximate such functions. Return values : 1 - success; 0 - Too big. The area isn't filled. The client must decompose the area. <0 - error. */ int gx_default_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, const gs_fixed_point *p0, const gs_fixed_point *p1, const gs_fixed_point *p2, const gs_fixed_point *p3, const frac31 *c0, const frac31 *c1, const frac31 *c2, const frac31 *c3) { gs_linear_color_edge le, re; le.start = *p0; le.end = *p1; le.c0 = c0; le.c1 = c1; le.clip_x = fa->clip->p.x; re.start = *p2; re.end = *p3; re.c0 = c2; re.c1 = c3; re.clip_x = fa->clip->q.x; if (check_gradient_overflow(&le, &re)) return 0; return fill_linear_color_trapezoid_nocheck(dev, fa, &le, &re); }