aboutsummaryrefslogtreecommitdiff
path: root/generic/Draw.c
diff options
context:
space:
mode:
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) {
/*