From 7b528ae8b175921a075923f169e258d618227d8d Mon Sep 17 00:00:00 2001 From: lecoanet Date: Mon, 26 Nov 2001 10:10:19 +0000 Subject: Am�lioration des reliefs. Factorisation des calcul de gradients. Implantation des gradients PATH. --- generic/Draw.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 163 insertions(+), 17 deletions(-) (limited to 'generic/Draw.c') diff --git a/generic/Draw.c b/generic/Draw.c index 3812450..555888a 100644 --- a/generic/Draw.c +++ b/generic/Draw.c @@ -890,7 +890,7 @@ PolygonRenderCB(ZnPoint *bevels, void *closure) { PolygonData *pd = closure; - int i; + int i, a, b; XColor *color = ReliefColorOfSegment(bevels[0].x, bevels[0].y, bevels[3].x, bevels[3].y, pd->relief, pd->gradient, pd->wi); @@ -898,7 +898,9 @@ PolygonRenderCB(ZnPoint *bevels, glColor4us(color->red, color->green, color->blue, pd->alpha); glBegin(GL_QUADS); for (i = 0; i < 4; i++) { - glVertex2f(REAL_TO_INT(bevels[i].x), REAL_TO_INT(bevels[i].y)); + a = REAL_TO_INT(bevels[i].x); + b = REAL_TO_INT(bevels[i].y); + glVertex2f(a, b); } glEnd(); @@ -1068,11 +1070,101 @@ RenderTile(struct _WidgetInfo *wi, } void +ComputeAxialGradient(WidgetInfo *wi, + ZnPoly *shape, + int angle, + ZnPoint *grad_geo) +{ + ZnTransfo *transfo1, *transfo2; + ZnBool *holes; + ZnContour *c; + ZnBBox bbox; + ZnPoint *points, p[4]; + int i; + + transfo1 = ZnTransfoNew(); + transfo2 = ZnTransfoNew(); + ZnRotateDeg(transfo1, angle); + ZnRotateDeg(transfo2, -angle); + holes = shape->holes; + c = shape->contours; + ResetBBox(&bbox); + for (i = 0; i < shape->num_contours; i++, c++, holes++) { + if (*holes) { + continue; + } + ZnListAssertSize(wi->work_pts, c->num_points); + points = ZnListArray(wi->work_pts); + ZnTransformPoints(transfo1, c->points, points, c->num_points); + AddPointsToBBox(&bbox, points, c->num_points); + } + p[0] = bbox.orig; + p[2] = bbox.corner; + p[1].x = p[2].x; + p[1].y = p[0].y; + p[3].x = p[0].x; + p[3].y = p[2].y; + ZnTransfoSetIdentity(transfo1); + ZnTransfoCompose(transfo1, transfo2, wi->current_transfo); + ZnTransformPoints(transfo1, p, grad_geo, 4); + ZnTransfoFree(transfo1); + ZnTransfoFree(transfo2); +} + +void +ComputeRadialGradient(WidgetInfo *wi, + ZnPoly *shape, + ZnBBox *bbox, + ZnPoint *center, + ZnPoint *grad_geo) +{ + ZnReal dist, new, x, y, fact; + ZnBool *holes; + ZnContour *c; + ZnPoint *points; + ZnTransfo *transfo1; + int i, j; + + ZnTransformPoint(wi->current_transfo, center, &grad_geo[0]); + transfo1 = ZnTransfoNew(); + ZnTranslate(transfo1, -grad_geo[0].x, -grad_geo[0].y); + fact = (bbox->corner.x-bbox->orig.x)/(bbox->corner.y-bbox->orig.y); + ZnScale(transfo1, 1.0, fact); + dist = 0.0; + holes = shape->holes; + c = shape->contours; + for (j = 0; j < shape->num_contours; j++, c++, holes++) { + if (*holes) { + continue; + } + ZnListAssertSize(wi->work_pts, c->num_points); + points = ZnListArray(wi->work_pts); + ZnTransformPoints(transfo1, c->points, points, c->num_points); + for (i = 0; i < c->num_points; i++, points++) { + x = points->x; + y = points->y; + new = x*x+y*y; + if (new > dist) { + dist = new; + } + } + } + grad_geo[1].x = sqrt(dist) + 2; /* Max radius plus a fuzz factor */ + grad_geo[1].y = grad_geo[1].x / fact; + ZnTransfoFree(transfo1); +} + +void RenderGradient(struct _WidgetInfo *wi, - ZnGradient *gradient, - void cb(void *), - void *closure, - ZnPoint *quad) + ZnGradient *gradient, /* The grdient to be drawn (static + * parameters). */ + void cb(void *), /* A callback called to clip the shape + * containing the gradient. */ + void *closure, /* The callback parameter. */ + ZnPoint *quad, /* The gradient geometric parameters + * (dynamic). */ + ZnPoly *poly /* Used only by ZN_PATH_GRADIENT */ + ) { int alpha, angle, i, j; int type = gradient->type; @@ -1085,14 +1177,8 @@ RenderGradient(struct _WidgetInfo *wi, int num_clips = ZnListSize(wi->clip_stack); ZnPoint iquad[4]; - if (!cb) { /* Render an axial gradient in the quad */ - if (type != ZN_AXIAL_GRADIENT) { - type = ZN_AXIAL_GRADIENT; - angle = 0; - } - else { - angle = gradient->g.angle; - } + if (!cb && (type == ZN_AXIAL_GRADIENT)) { /* Render an aligned + * axial gradient in the quad */ /* * Adjust the quad for 90 180 and 270 degrees axial * gradients. Other angles not supported. @@ -1125,7 +1211,7 @@ RenderGradient(struct _WidgetInfo *wi, if (cb) { /* * Draw the gradient shape in the stencil using the provided - * callback. + * callback (clipping). */ if (!num_clips) { glEnable(GL_STENCIL_TEST); @@ -1197,8 +1283,8 @@ RenderGradient(struct _WidgetInfo *wi, int num_p, alpha2; ZnPoint *genarc; XColor *color2; - - genarc = GetCirclePoints(3, ZN_CIRCLE_FINEST, 0, 360, &num_p, NULL); + + genarc = GetCirclePoints(3, ZN_CIRCLE_FINE, 0, 360, &num_p, NULL); radiusx = 0; radiusy = 0; color = gradient->colors[0]->shades[0]; @@ -1250,6 +1336,66 @@ RenderGradient(struct _WidgetInfo *wi, control = gradient->colors[j]->control; } } + else if (type == ZN_PATH_GRADIENT) { + ZnPoint p, pp, p2, pp2, p3, pp3; + int num_p, k, ii; + ZnPoint *points; + ZnReal position; + + for (k = 0; k < poly->num_contours; k++) { + if (poly->holes[k]) { + continue; + } + points = poly->contours[k].points; + num_p = poly->contours[k].num_points; + + for (i = 0; i < num_p; i++) { + if (i == num_p-1) { + ii = 0; + } + else { + ii = i+1; + } + + glBegin(GL_QUAD_STRIP); + p.x = p.y = pp.x = pp.y = 0; + control = gradient->colors[0]->control; + position = gradient->colors[0]->position; + alpha = gradient->colors[0]->alpha*wi->alpha/100*65535/100; + color = gradient->colors[0]->shades[0]; + glColor4us(color->red, color->green, color->blue, alpha); + glVertex2f(quad[0].x+p.x, quad[0].y+p.y); + glVertex2f(quad[0].x+pp.x, quad[0].y+pp.y); + for (j = 0; j < gradient->num_colors-1; j++) { + position = gradient->colors[j+1]->position; + p2.x = (points[i].x-quad[0].x)*position/100.0; + p2.y = (points[i].y-quad[0].y)*position/100.0; + pp2.x = (points[ii].x-quad[0].x)*position/100.0; + pp2.y = (points[ii].y-quad[0].y)*position/100.0; + if (control != 50) { + color = gradient->colors[j]->shades[num_shades/2]; + alpha = gradient->colors[j]->alpha*wi->alpha/100*65535/100; + p3.x = p.x+(p2.x-p.x)*control/100.0; + p3.y = p.y+(p2.y-p.y)*control/100.0; + pp3.x = pp.x+(pp2.x-pp.x)*control/100.0; + pp3.y = pp.y+(pp2.y-pp.y)*control/100.0; + glColor4us(color->red, color->green, color->blue, alpha); + glVertex2f(quad[0].x+p3.x, quad[0].y+p3.y); + glVertex2f(quad[0].x+pp3.x, quad[0].y+pp3.y); + } + control = gradient->colors[j+1]->control; + alpha = gradient->colors[j+1]->alpha*wi->alpha/100*65535/100; + color = gradient->colors[j+1]->shades[0]; + p = p2; + pp = pp2; + glColor4us(color->red, color->green, color->blue, alpha); + glVertex2f(quad[0].x+p.x, quad[0].y+p.y); + glVertex2f(quad[0].x+pp.x, quad[0].y+pp.y); + } + glEnd(); + } + } + } if (cb) { /* -- cgit v1.1