diff options
-rw-r--r-- | generic/Draw.c | 251 |
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) { /* |