aboutsummaryrefslogtreecommitdiff
path: root/generic/Draw.c
diff options
context:
space:
mode:
authorlecoanet2001-11-26 10:10:19 +0000
committerlecoanet2001-11-26 10:10:19 +0000
commit7b528ae8b175921a075923f169e258d618227d8d (patch)
treee82dec6c536e802376328fd957a215cf1259601c /generic/Draw.c
parent739d556eb6715c91d5e9748a7670badac289dfe2 (diff)
downloadtkzinc-7b528ae8b175921a075923f169e258d618227d8d.zip
tkzinc-7b528ae8b175921a075923f169e258d618227d8d.tar.gz
tkzinc-7b528ae8b175921a075923f169e258d618227d8d.tar.bz2
tkzinc-7b528ae8b175921a075923f169e258d618227d8d.tar.xz
Am�lioration des reliefs.
Factorisation des calcul de gradients. Implantation des gradients PATH.
Diffstat (limited to 'generic/Draw.c')
-rw-r--r--generic/Draw.c180
1 files changed, 163 insertions, 17 deletions
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) {
/*