aboutsummaryrefslogtreecommitdiff
path: root/generic/Draw.c
diff options
context:
space:
mode:
authorlecoanet2003-06-16 15:03:58 +0000
committerlecoanet2003-06-16 15:03:58 +0000
commit5c4123794ec312dbb6b5f3bbe580d333c09cd51f (patch)
tree6ab27ca796827901f991762aea790ae2c166791c /generic/Draw.c
parentacbf7c334cae1f0d6dc9ea111324cd6af679d852 (diff)
downloadtkzinc-5c4123794ec312dbb6b5f3bbe580d333c09cd51f.zip
tkzinc-5c4123794ec312dbb6b5f3bbe580d333c09cd51f.tar.gz
tkzinc-5c4123794ec312dbb6b5f3bbe580d333c09cd51f.tar.bz2
tkzinc-5c4123794ec312dbb6b5f3bbe580d333c09cd51f.tar.xz
Use of the new ZnGetGradientPixel when possible.
Adaptation for the new gradient structure. Added the processing of conical gradients. Simplified gradient preparation only one function need to be called ZnComputeGradient.
Diffstat (limited to 'generic/Draw.c')
-rw-r--r--generic/Draw.c251
1 files changed, 166 insertions, 85 deletions
diff --git a/generic/Draw.c b/generic/Draw.c
index 577b115..f64372f 100644
--- a/generic/Draw.c
+++ b/generic/Draw.c
@@ -306,7 +306,7 @@ ZnDrawLineShape(ZnWInfo *wi,
ZnPoint *p,
unsigned int num_p,
ZnLineStyle line_style,
- XColor *foreground,
+ int foreground_pixel,
ZnDim line_width,
ZnLineShape shape __unused)
{
@@ -318,7 +318,7 @@ ZnDrawLineShape(ZnWInfo *wi,
* Setup GC.
*/
ZnSetLineStyle(wi, line_style);
- values.foreground = ZnPixel(foreground);
+ values.foreground = foreground_pixel;
values.line_width = (line_width == 1) ? 0 : (int) line_width;
values.fill_style = FillSolid;
values.join_style = JoinRound;
@@ -418,25 +418,20 @@ ZnGetLineEnd(ZnPoint *p1,
}
}
-
-/*
- * ReliefColorOfSegment --
- */
-static XColor *
-ReliefColorOfSegment(ZnReal x1,
+static ZnReal
+SegmentPosInRelief(ZnReal x1,
ZnReal y1,
ZnReal x2,
ZnReal y2,
ZnReliefStyle relief,
- ZnGradient *gradient,
- ZnWInfo *wi)
+ int light_angle)
{
ZnReal angle, angle_step, origin, position;
int num_colors, color_index;
num_colors = ZN_RELIEF_STEPS*2+1;
angle_step = M_PI / (num_colors-1);
- origin = -(ZnDegRad(wi->light_angle))-(angle_step/2.0);
+ origin = -(ZnDegRad(light_angle))-(angle_step/2.0);
if (relief == ZN_RELIEF_SUNKEN) {
origin += M_PI;
}
@@ -468,8 +463,38 @@ ReliefColorOfSegment(ZnReal x1,
RadianToDegrees(angle),
angle,
RadianToDegrees(origin));*/
+ return position;
+}
- return ZnGetGradientColor(gradient, position, NULL);
+/*
+ * ReliefColorOfSegment --
+ * ReliefPixelOfSegment --
+ */
+static XColor *
+ReliefColorOfSegment(ZnReal x1,
+ ZnReal y1,
+ ZnReal x2,
+ ZnReal y2,
+ ZnReliefStyle relief,
+ ZnGradient *gradient,
+ int light_angle)
+{
+ return ZnGetGradientColor(gradient,
+ SegmentPosInRelief(x1, y1, x2, y2, relief, light_angle),
+ NULL);
+}
+
+static int
+ReliefPixelOfSegment(ZnReal x1,
+ ZnReal y1,
+ ZnReal x2,
+ ZnReal y2,
+ ZnReliefStyle relief,
+ ZnGradient *gradient,
+ int light_angle)
+{
+ return ZnGetGradientPixel(gradient,
+ SegmentPosInRelief(x1, y1, x2, y2, relief, light_angle));
}
@@ -531,9 +556,9 @@ ZnDrawRectangleRelief(ZnWInfo *wi,
bevel[2].x = bevel[1].x - (short) line_width;
bevel[3].x = bevel[0].x + (short) line_width;
XSetForeground(wi->dpy, wi->gc,
- ZnPixel(ReliefColorOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
- (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
- relief, gradient, wi)));
+ ReliefPixelOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
+ (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
+ relief, gradient, wi->light_angle));
XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, bevel, 4, Convex, CoordModeOrigin);
bevel[0] = bevel[1];
@@ -541,9 +566,9 @@ ZnDrawRectangleRelief(ZnWInfo *wi,
bevel[1].y += bbox->height;
bevel[2].y = bevel[1].y - (short) line_width;
XSetForeground(wi->dpy, wi->gc,
- ZnPixel(ReliefColorOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
- (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
- relief, gradient, wi)));
+ ReliefPixelOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
+ (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
+ relief, gradient, wi->light_angle));
XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, bevel, 4, Convex, CoordModeOrigin);
bevel[0] = bevel[1];
@@ -551,9 +576,9 @@ ZnDrawRectangleRelief(ZnWInfo *wi,
bevel[1].x -= bbox->width;
bevel[2].x = bevel[1].x + (short) line_width;
XSetForeground(wi->dpy, wi->gc,
- ZnPixel(ReliefColorOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
- (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
- relief, gradient, wi)));
+ ReliefPixelOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
+ (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
+ relief, gradient, wi->light_angle));
XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, bevel, 4, Convex, CoordModeOrigin);
bevel[0] = bevel[1];
@@ -563,9 +588,9 @@ ZnDrawRectangleRelief(ZnWInfo *wi,
bevel[2].x = bevel[3].x;
bevel[2].y = bbox->y + (short) line_width;
XSetForeground(wi->dpy, wi->gc,
- ZnPixel(ReliefColorOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
- (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
- relief, gradient, wi)));
+ ReliefPixelOfSegment((ZnReal) bevel[1].x, (ZnReal) bevel[1].y,
+ (ZnReal) bevel[0].x, (ZnReal) bevel[0].y,
+ relief, gradient, wi->light_angle));
XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, bevel, 4, Convex, CoordModeOrigin);
}
@@ -920,9 +945,10 @@ PolygonDrawCB(ZnPoint *bevels,
XGCValues values;
int j;
- values.foreground = ZnPixel(ReliefColorOfSegment(bevels[0].x, bevels[0].y,
- bevels[3].x, bevels[3].y,
- pd->relief, pd->gradient, pd->wi));
+ values.foreground = ReliefPixelOfSegment(bevels[0].x, bevels[0].y,
+ bevels[3].x, bevels[3].y,
+ pd->relief, pd->gradient,
+ pd->wi->light_angle);
values.fill_style = FillSolid;
XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &values);
@@ -1010,17 +1036,21 @@ PolygonRenderCB(ZnPoint *bevels,
}
c[0]=c[1]=c[2]=c[3] = ReliefColorOfSegment(bevels[0].x, bevels[0].y,
bevels[3].x, bevels[3].y,
- relief, pd->gradient, pd->wi);
+ relief, pd->gradient,
+ pd->wi->light_angle);
c[4]=c[5]=c[6]=c[7] = ReliefColorOfSegment(bevels[0].x, bevels[0].y,
bevels[3].x, bevels[3].y,
- int_relief, pd->gradient, pd->wi);
+ int_relief, pd->gradient,
+ pd->wi->light_angle);
if (pd->smooth && pd->p0) {
c[2]=c[3] = ReliefColorOfSegment(pd->p0->x, pd->p0->y,
pd->p1->x, pd->p1->y,
- relief, pd->gradient, pd->wi);
+ relief, pd->gradient,
+ pd->wi->light_angle);
c[6]=c[7] = ReliefColorOfSegment(pd->p0->x, pd->p0->y,
pd->p1->x, pd->p1->y,
- int_relief, pd->gradient, pd->wi);
+ int_relief, pd->gradient,
+ pd->wi->light_angle);
}
if (round) {
if (!rule) {
@@ -1059,11 +1089,13 @@ PolygonRenderCB(ZnPoint *bevels,
else { /* Single face */
c[0]=c[1]=c[2]=c[3] = ReliefColorOfSegment(bevels[0].x, bevels[0].y,
bevels[3].x, bevels[3].y,
- relief, pd->gradient, pd->wi);
+ relief, pd->gradient,
+ pd->wi->light_angle);
if (pd->smooth && pd->p0) {
c[2]=c[3] = ReliefColorOfSegment(pd->p0->x, pd->p0->y,
pd->p1->x, pd->p1->y,
- relief, pd->gradient, pd->wi);
+ relief, pd->gradient,
+ pd->wi->light_angle);
}
if (round) {
c[1]=c[2] = color;
@@ -1425,11 +1457,12 @@ ZnRenderTile(ZnWInfo *wi,
glDisable(GL_TEXTURE_2D);
}
-void
-ZnComputeAxialGradient(ZnWInfo *wi,
- ZnPoly *shape,
- ZnReal angle,
- ZnPoint *grad_geo)
+
+static void
+ComputeAxialGradient(ZnWInfo *wi,
+ ZnPoly *shape,
+ ZnReal angle,
+ ZnPoint *grad_geo)
{
ZnTransfo *transfo1, *transfo2;
ZnContour *c;
@@ -1466,17 +1499,18 @@ ZnComputeAxialGradient(ZnWInfo *wi,
ZnTransfoFree(transfo2);
}
-void
-ZnComputeRadialGradient(ZnWInfo *wi,
+static void
+ComputeCircularGradient(ZnWInfo *wi,
ZnPoly *shape,
ZnBool oval,
ZnPoint *focal_pp, /* in percent of bbox */
+ ZnReal angle,
ZnPoint *grad_geo)
{
ZnReal dist, new, x, y, ff;
ZnBBox bbox;
ZnContour *c;
- ZnPoint offset, focal_point, radius;
+ ZnPoint offset, radius, focal_point;
ZnPoint *points;
ZnTransfo t1;
unsigned int i, j;
@@ -1552,7 +1586,7 @@ ZnComputeRadialGradient(ZnWInfo *wi,
}
}
}
-
+
/*
* Create a transform to map a unit circle to another one that
* could fill the item when centered at the focal point.
@@ -1560,6 +1594,7 @@ ZnComputeRadialGradient(ZnWInfo *wi,
dist = sqrt(dist); /* Max radius plus a fuzz factor */
ZnTransfoSetIdentity(&t1);
ZnScale(&t1, dist, dist);
+ ZnRotateDeg(&t1, -angle);
/*
* Then, center the oval on the focal point.
@@ -1571,11 +1606,11 @@ ZnComputeRadialGradient(ZnWInfo *wi,
ZnTransfoCompose((ZnTransfo *) grad_geo, &t1, wi->current_transfo);
}
-void
-ZnComputePathGradient(ZnWInfo *wi,
- ZnPoly *shape,
- ZnPoint *focal_pp, /* in percent of the bbox */
- ZnPoint *grad_geo)
+static void
+ComputePathGradient(ZnWInfo *wi,
+ ZnPoly *shape,
+ ZnPoint *focal_pp, /* in percent of the bbox */
+ ZnPoint *grad_geo)
{
ZnBBox bbox;
ZnContour *c;
@@ -1603,8 +1638,28 @@ ZnComputePathGradient(ZnWInfo *wi,
}
void
+ZnComputeGradient(ZnGradient *grad,
+ ZnWInfo *wi,
+ ZnPoly *shape,
+ ZnPoint *grad_geo)
+{
+ switch (grad->type) {
+ case ZN_AXIAL_GRADIENT:
+ ComputeAxialGradient(wi, shape, grad->angle, grad_geo);
+ break;
+ case ZN_RADIAL_GRADIENT:
+ case ZN_CONICAL_GRADIENT:
+ ComputeCircularGradient(wi, shape, False, &grad->p, grad->angle, grad_geo);
+ break;
+ case ZN_PATH_GRADIENT:
+ ComputePathGradient(wi, shape, &grad->p, grad_geo);
+ break;
+ }
+}
+
+void
ZnRenderGradient(ZnWInfo *wi,
- ZnGradient *gradient, /* The grdient to be drawn (static
+ ZnGradient *gradient, /* The gradient to be drawn (static
* parameters). */
void (*cb)(void *), /* A callback called to clip the shape
* containing the gradient. */
@@ -1619,16 +1674,15 @@ ZnRenderGradient(ZnWInfo *wi,
unsigned int i, j;
int type = gradient->type;
XColor *color;
- ZnPoint p;
ZnPoint dposa, dposb, dposc, dposd;
- ZnPoint dcontrol;
+ ZnPoint p, dcontrol;
ZnReal npos, pos, control;
unsigned int num_clips = ZnListSize(wi->clip_stack);
ZnPoint iquad[4];
if (!cb && (type == ZN_AXIAL_GRADIENT)) { /* Render an aligned
* axial gradient in the quad */
- angle = gradient->g.angle;
+ angle = gradient->angle;
/*
* Adjust the quad for 90 180 and 270 degrees axial
* gradients. Other angles not supported.
@@ -1675,13 +1729,13 @@ ZnRenderGradient(ZnWInfo *wi,
* to its previous state in the process.
*/
glBegin(GL_QUAD_STRIP);
- for (i = 0; i < gradient->num_colors; i++) {
- color = gradient->colors[i].rgb;
- alpha = ZnComposeAlpha(gradient->colors[i].alpha, wi->alpha);
+ for (i = 0; i < gradient->num_actual_colors; i++) {
+ color = gradient->actual_colors[i].rgb;
+ alpha = ZnComposeAlpha(gradient->actual_colors[i].alpha, wi->alpha);
glColor4us(color->red, color->green, color->blue, alpha);
- pos = gradient->colors[i].position;
- control = gradient->colors[i].control;
+ pos = gradient->actual_colors[i].position;
+ control = gradient->actual_colors[i].control;
dposa.x = (quad[1].x - quad[0].x)*pos/100.0;
dposa.y = (quad[1].y - quad[0].y)*pos/100.0;
p.x = quad[0].x + dposa.x;
@@ -1694,12 +1748,12 @@ ZnRenderGradient(ZnWInfo *wi,
p.y = quad[3].y + dposb.y;
glVertex2d(p.x, p.y);
- if ((control != 50.0) && (i != gradient->num_colors-1)) {
- color = gradient->colors[i].mid_rgb;
- alpha = ZnComposeAlpha(gradient->colors[i].mid_alpha, wi->alpha);
+ if ((control != 50.0) && (i != gradient->num_actual_colors-1)) {
+ color = gradient->actual_colors[i].mid_rgb;
+ alpha = ZnComposeAlpha(gradient->actual_colors[i].mid_alpha, wi->alpha);
glColor4us(color->red, color->green, color->blue, alpha);
- npos = gradient->colors[i+1].position;
+ npos = gradient->actual_colors[i+1].position;
dposc.x = (quad[1].x - quad[0].x)*npos/100.0;
dposc.y = (quad[1].y - quad[0].y)*npos/100.0;
dcontrol.x = (dposc.x - dposa.x)*control/100.0;
@@ -1721,8 +1775,7 @@ ZnRenderGradient(ZnWInfo *wi,
glEnd();
}
else if (type == ZN_RADIAL_GRADIENT) {
- ZnReal x, position, position2, position3;
- ZnReal y;
+ ZnReal x, y, position, position2, position3;
unsigned int num_p;
ZnPoint *genarc, *tarc, p, focalp;
XColor *color2;
@@ -1735,15 +1788,15 @@ ZnRenderGradient(ZnWInfo *wi,
ZnTransformPoint((ZnTransfo *) quad, &p, &focalp);
position = 0.0;
- color = gradient->colors[0].rgb;
- alpha = ZnComposeAlpha(gradient->colors[0].alpha, wi->alpha);
- control = gradient->colors[0].control;
- for (j = 1; j < gradient->num_colors; j++) {
- position2 = gradient->colors[j].position/100.0;
- if ((control != 50) && (j != gradient->num_colors-1)) {
+ color = gradient->actual_colors[0].rgb;
+ alpha = ZnComposeAlpha(gradient->actual_colors[0].alpha, wi->alpha);
+ control = gradient->actual_colors[0].control;
+ for (j = 1; j < gradient->num_actual_colors; j++) {
+ position2 = gradient->actual_colors[j].position/100.0;
+ if ((control != 50) && (j != gradient->num_actual_colors-1)) {
glBegin(GL_QUAD_STRIP);
- color2 = gradient->colors[j-1].mid_rgb;
- alpha2 = ZnComposeAlpha(gradient->colors[j-1].mid_alpha, wi->alpha);
+ color2 = gradient->actual_colors[j-1].mid_rgb;
+ alpha2 = ZnComposeAlpha(gradient->actual_colors[j-1].mid_alpha, wi->alpha);
position3 = position + (position2-position)*control/100.0;
for (i = 0; i < num_p; i++) {
x = focalp.x + (tarc[i].x-focalp.x) * position;
@@ -1761,8 +1814,8 @@ ZnRenderGradient(ZnWInfo *wi,
glEnd();
}
glBegin(GL_QUAD_STRIP);
- color2 = gradient->colors[j].rgb;
- alpha2 = ZnComposeAlpha(gradient->colors[j].alpha, wi->alpha);
+ color2 = gradient->actual_colors[j].rgb;
+ alpha2 = ZnComposeAlpha(gradient->actual_colors[j].alpha, wi->alpha);
for (i = 0; i < num_p; i++) {
x = focalp.x + (tarc[i].x-focalp.x) * position;
y = focalp.y + (tarc[i].y-focalp.y) * position;
@@ -1777,7 +1830,7 @@ ZnRenderGradient(ZnWInfo *wi,
position = position2;
color = color2;
alpha = alpha2;
- control = gradient->colors[j].control;
+ control = gradient->actual_colors[j].control;
}
}
else if (type == ZN_PATH_GRADIENT) {
@@ -1787,7 +1840,7 @@ ZnRenderGradient(ZnWInfo *wi,
ZnReal position;
for (k = 0; k < poly->num_contours; k++) {
- /* if (poly->contours[k].cw) {
+ /*if (poly->contours[k].cw) {
continue;
}*/
points = poly->contours[k].points;
@@ -1803,22 +1856,22 @@ ZnRenderGradient(ZnWInfo *wi,
glBegin(GL_QUAD_STRIP);
p.x = p.y = pp.x = pp.y = 0;
- control = gradient->colors[0].control;
- position = gradient->colors[0].position;
- alpha = ZnComposeAlpha(gradient->colors[0].alpha, wi->alpha);
- color = gradient->colors[0].rgb;
+ control = gradient->actual_colors[0].control;
+ position = gradient->actual_colors[0].position;
+ alpha = ZnComposeAlpha(gradient->actual_colors[0].alpha, wi->alpha);
+ color = gradient->actual_colors[0].rgb;
glColor4us(color->red, color->green, color->blue, alpha);
glVertex2d(quad[0].x+p.x, quad[0].y+p.y);
glVertex2d(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;
+ for (j = 0; j < gradient->num_actual_colors-1; j++) {
+ position = gradient->actual_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].mid_rgb;
- alpha = ZnComposeAlpha(gradient->colors[j].mid_alpha, wi->alpha);
+ color = gradient->actual_colors[j].mid_rgb;
+ alpha = ZnComposeAlpha(gradient->actual_colors[j].mid_alpha, wi->alpha);
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;
@@ -1827,9 +1880,9 @@ ZnRenderGradient(ZnWInfo *wi,
glVertex2d(quad[0].x+p3.x, quad[0].y+p3.y);
glVertex2d(quad[0].x+pp3.x, quad[0].y+pp3.y);
}
- control = gradient->colors[j+1].control;
- alpha = ZnComposeAlpha(gradient->colors[j+1].alpha, wi->alpha);
- color = gradient->colors[j+1].rgb;
+ control = gradient->actual_colors[j+1].control;
+ alpha = ZnComposeAlpha(gradient->actual_colors[j+1].alpha, wi->alpha);
+ color = gradient->actual_colors[j+1].rgb;
p = p2;
pp = pp2;
glColor4us(color->red, color->green, color->blue, alpha);
@@ -1840,6 +1893,34 @@ ZnRenderGradient(ZnWInfo *wi,
}
}
}
+ else if (type == ZN_CONICAL_GRADIENT) {
+ ZnReal position;
+ unsigned int num_p;
+ ZnPoint *genarc, *tarc, p, focalp;
+ XColor col;
+
+ genarc = ZnGetCirclePoints(3, ZN_CIRCLE_FINEST, 0.0, 2*M_PI, &num_p, NULL);
+ ZnListAssertSize(wi->work_pts, num_p);
+ tarc = ZnListArray(wi->work_pts);
+ ZnTransformPoints((ZnTransfo *) quad, genarc, tarc, num_p);
+ p.x = p.y = 0;
+ ZnTransformPoint((ZnTransfo *) quad, &p, &focalp);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ for (i = 0; i < num_p; i++) {
+ position = i*100.0/(num_p-1);
+ ZnInterpGradientColor(gradient, position, &col, &alpha);
+ alpha = ZnComposeAlpha(alpha, wi->alpha);
+
+ /*printf("position: %g --> color: %d %d %d, alpha: %d\n",
+ position, col.red, col.green, col.blue, alpha);*/
+
+ glColor4us(col.red, col.green, col.blue, alpha);
+ glVertex2d(tarc[i].x, tarc[i].y);
+ glVertex2d(focalp.x, focalp.y);
+ }
+ glEnd();
+ }
if (cb) {
/*