diff options
Diffstat (limited to 'generic/Draw.c')
-rw-r--r-- | generic/Draw.c | 140 |
1 files changed, 130 insertions, 10 deletions
diff --git a/generic/Draw.c b/generic/Draw.c index 2d96d43..f62d405 100644 --- a/generic/Draw.c +++ b/generic/Draw.c @@ -45,7 +45,6 @@ #include <math.h> #include <stdarg.h> -#include <alloca.h> #define POLYGON_RELIEF_DRAW 0 @@ -276,9 +275,7 @@ GetLineShape(ZnPoint *p1, ********************************************************************************** */ void -DrawLineShape(Display *display, - Drawable draw_buffer, - GC gc, +DrawLineShape(WidgetInfo *wi, ZnPoint *p, int num_p, LineStyle line_style, @@ -293,20 +290,21 @@ DrawLineShape(Display *display, /* * Setup GC. */ - SetLineStyle(display, gc, line_style); + SetLineStyle(wi->dpy, wi->gc, line_style); values.foreground = ZnPixel(foreground); values.line_width = (line_width == 1) ? 0 : line_width; values.fill_style = FillSolid; values.join_style = JoinRound; values.cap_style = CapRound; - XChangeGC(display, gc, - GCFillStyle | GCLineWidth | GCJoinStyle | GCCapStyle | GCForeground, &values); - xpoints = (XPoint *) alloca(num_p * sizeof(XPoint)); + XChangeGC(wi->dpy, wi->gc, + GCFillStyle|GCLineWidth|GCJoinStyle|GCCapStyle|GCForeground, &values); + ZnListAssertSize(wi->work_xpts, num_p); + xpoints = (XPoint *) ZnListArray(wi->work_xpts); for (i = 0; i < num_p; i++) { xpoints[i].x = p[i].x; xpoints[i].y = p[i].y; } - XDrawLines(display, draw_buffer, gc, xpoints, num_p, CoordModeOrigin); + XDrawLines(wi->dpy, wi->draw_buffer, wi->gc, xpoints, num_p, CoordModeOrigin); } @@ -357,7 +355,7 @@ ReliefColorOfSegment(ZnReal x1, RadianToDegrees(angle), RadianToDegrees(origin));*/ - return ZnColorGradientPixel(gradient, wi->win, color_index); + return ZnPixel(ZnColorGradientColor(wi->win, gradient, color_index)); } @@ -824,3 +822,125 @@ DrawPolygonRelief(WidgetInfo *wi, } } +void +DrawPolygonGradient(struct _WidgetInfo *wi, + ZnGradientGeom grad_geom, + ZnColorGradient grad_color, + ZnPoint *pts, + int num_pts, + ZnBBox *bbox) +{ + ZnBBox lbbox; + XRectangle r; + + if (!bbox) { + ResetBBox(&lbbox); + AddPointsToBBox(&lbbox, pts, num_pts); + bbox = &lbbox; + } + BBox2XRect(bbox, &r); + ITEM_P.PushClip(wi, pts, num_pts, False, True); + DrawRectangleGradient(wi, grad_geom, grad_color, &r); + ITEM_P.PopClip(wi, True); +} + +void +DrawRectangleGradient(struct _WidgetInfo *wi, + ZnGradientGeom grad_geom, + ZnColorGradient grad_color, + XRectangle *bbox) +{ + int steps = ZnColorGradientSpan(grad_color); + ZnReal d1, d2; + int angle = grad_geom->angle; + int x, y, c, y_d2, w, h, i, j; + int *optr, *hptr; + short yorig, ycorner; + ZnBool dir; + + + /* + * We can only hangle 0, 90, 180, 270. + */ + angle = (angle / 90) * 90; + + x = bbox->x; + y = bbox->y; + if ((angle == 90) || (angle == 270)) { + optr = &x; + yorig = bbox->x; + ycorner = bbox->x+bbox->width; + h = bbox->height; + hptr = &w; + d1 = grad_geom->d1*bbox->width/100; + d2 = grad_geom->d2*bbox->width/100; + } + else { + optr = &y; + yorig = bbox->y; + ycorner = bbox->y+bbox->height; + w = bbox->width; + hptr = &h; + d1 = grad_geom->d1*bbox->height/100.0; + d2 = bbox->height*(1.0-grad_geom->d2/100.0); + } + + dir = True; + if ((angle == 180) || (angle == 270)) { + dir = False; + } +#if 1 + XSetFillStyle(wi->dpy, wi->gc, FillSolid); + c = ycorner; + for (i = 2, j = steps-1; i < steps; i += 2, j--) { + *optr = REAL_TO_INT(ycorner - (i * d2 / steps)); + *hptr = c - *optr; + XSetForeground(wi->dpy, wi->gc, + ZnPixel(ZnColorGradientColor(wi->win, grad_color, + dir?j:steps-1-j))); + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, x, y, w, h); + c = *optr; + } + y_d2 = *optr; + + *optr = yorig; + for (i = 2, j = 0; i < steps; i += 2, j++) { + c = REAL_TO_INT(yorig + (i * d1 / steps)); + *hptr = c - *optr; + XSetForeground(wi->dpy, wi->gc, + ZnPixel(ZnColorGradientColor(wi->win, grad_color, dir?j:steps-1-j))); + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, x, y, w, h); + *optr = c; + } + + XSetForeground(wi->dpy, wi->gc, + ZnPixel(ZnColorGradientMidColor(wi->win, grad_color))); + *hptr = y_d2 - *optr; + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, x, y, w, h); +#endif + /* + * Draw over with a 50% gray pattern to smooth the color + * waves. + */ + XSetFillStyle(wi->dpy, wi->gc, FillStippled); + XSetStipple(wi->dpy, wi->gc, wi->alpha_stipples[7]); + c = REAL_TO_INT(ycorner - d2 / steps); + for (i = 3, j = steps-2; i <= steps; i += 2, j--) { + *optr = REAL_TO_INT(ycorner - (i * d2 / steps)); + *hptr = c - *optr; + XSetForeground(wi->dpy, wi->gc, + ZnPixel(ZnColorGradientColor(wi->win, grad_color, + dir?j:steps-1-j))); + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, x, y, w, h); + c = *optr; + } + *optr = REAL_TO_INT(yorig + d1 / steps); + for (i = 3, j = 1; i <= steps; i += 2, j++) { + c = REAL_TO_INT(yorig + (i * d1 / steps)); + *hptr = c - *optr; + XSetForeground(wi->dpy, wi->gc, + ZnPixel(ZnColorGradientColor(wi->win, grad_color, dir?j:steps-1-j))); + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, x, y, w, h); + *optr = c; + } +} |