From 95c3ef2c408cf8f570582cbd0a79eb5fc0f42887 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Fri, 12 Oct 2001 07:08:48 +0000 Subject: Suppression du gradient dans le code X11. Suppression du code libart. Extension du code de rendu GL. --- generic/Curve.c | 456 ++++++++++++++++++++++++++++++++++++---------------- generic/Rectangle.c | 440 ++++++++++++++++++++++---------------------------- 2 files changed, 501 insertions(+), 395 deletions(-) (limited to 'generic') diff --git a/generic/Curve.c b/generic/Curve.c index c8d2a35..3522a87 100644 --- a/generic/Curve.c +++ b/generic/Curve.c @@ -37,6 +37,9 @@ #ifdef GPC #include "gpc/gpc.h" #endif +#ifdef GLX +#include +#endif #include #include @@ -88,20 +91,16 @@ typedef struct _CurveItemStruct { ZnColor line_color; ZnColor marker_color; int line_alpha; - int fill_alpha; char *tile_name; /* Private data */ ZnImage tile; ZnPoly dev_shape; ZnGradient *gradient; -#ifdef LIBART - ArtSVP *outline_svp; - ArtSVP *fill_svp; -#endif #ifdef GPC gpc_tristrip tristrip; #endif + ZnPoint *grad_geo; } CurveItemStruct, *CurveItem; static ZnAttrConfig cv_attrs[] = { @@ -116,8 +115,6 @@ static ZnAttrConfig cv_attrs[] = { { ZN_CONFIG_BOOL, "-composescale", NULL, Tk_Offset(CurveItemStruct, header.flags), COMPOSE_SCALE_BIT, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_UINT, "-fillalpha", NULL, - Tk_Offset(CurveItemStruct, fill_alpha), 0, ZN_DRAW_FLAG, False }, { ZN_CONFIG_GRADIENT, "-fillcolor", NULL, Tk_Offset(CurveItemStruct, fill_color), 0, ZN_DRAW_FLAG|ZN_BORDER_FLAG, False }, @@ -132,7 +129,7 @@ static ZnAttrConfig cv_attrs[] = { ZN_COORDS_FLAG, False }, { ZN_CONFIG_LINE_END, "-lastend", NULL, Tk_Offset(CurveItemStruct, last_end), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_UINT, "-linealpha", NULL, + { ZN_CONFIG_ALPHA, "-linealpha", NULL, Tk_Offset(CurveItemStruct, line_alpha), 0, ZN_DRAW_FLAG, False }, { ZN_CONFIG_COLOR, "-linecolor", NULL, Tk_Offset(CurveItemStruct, line_color), 0, @@ -215,6 +212,7 @@ Init(Item item, cv->tristrip.num_strips = 0; #endif cv->gradient = NULL; + cv->grad_geo = NULL; /* Init attributes */ SET(item->flags, VISIBLE_BIT); @@ -278,15 +276,11 @@ Init(Item item, */ SET(cv->flags, MARKED_BIT); cv->marker = ZnUnspecifiedPattern; - cv->fill_alpha = 255; cv->fill_color = ZnGetGradient(wi->interp, wi->win, ZnNameOfColor(wi->fore_color)); - cv->line_alpha = 255; + cv->line_alpha = 100; cv->line_color = ZnGetColorByValue(wi->win, wi->fore_color); cv->marker_color = ZnGetColorByValue(wi->win, wi->fore_color); -#ifdef LIBART - cv->outline_svp = cv->fill_svp = NULL; -#endif return ZN_OK; } @@ -310,6 +304,7 @@ Clone(Item item) ZnBool *holes; POLY_INIT(&cv->dev_shape); + cv->grad_geo = NULL; if (cv->shape.num_contours) { conts = cv->shape.contours; @@ -362,9 +357,6 @@ Clone(Item item) cv->line_color = ZnGetColorByValue(wi->win, cv->line_color); cv->fill_color = ZnGetGradientByValue(cv->fill_color); cv->marker_color = ZnGetColorByValue(wi->win, cv->marker_color); -#ifdef LIBART - cv->outline_svp = cv->fill_svp = NULL; -#endif } @@ -382,6 +374,9 @@ Destroy(Item item) CurveItem cv = (CurveItem) item; POLY_FREE(&cv->shape); + if (cv->grad_geo) { + ZnFree(cv->grad_geo); + } cv->dev_shape.holes = NULL; POLY_FREE(&cv->dev_shape); @@ -418,14 +413,6 @@ Destroy(Item item) gpc_free_tristrip(&cv->tristrip); } #endif -#ifdef LIBART - if (cv->outline_svp) { - art_svp_free(cv->outline_svp); - } - if (cv->fill_svp) { - art_svp_free(cv->fill_svp); - } -#endif } @@ -494,7 +481,9 @@ Configure(Item item, } if ((cv->relief != RELIEF_FLAT) && !cv->gradient) { cv->gradient = ZnGetReliefGradient(wi->interp, wi->win, - ZnNameOfColor(ZnGetGradientColor(wi->win, cv->fill_color, 50.0))); + ZnNameOfColor(ZnGetGradientColor(wi->win, + cv->fill_color, + 50.0, NULL))); if (cv->gradient == NULL) { status = ZN_ERROR; } @@ -718,51 +707,6 @@ ComputeCoordinates(Item item, lw = cv->line_width; - /* - * PLC Rendering works only with one contour, no relief, no markers, - * round ends, round joins. - */ - if (wi->render) { -#ifdef LIBART - ArtVpath *vpath; - - c2 = cv->dev_shape.contours; - vpath = (ArtVpath *) ZnMalloc((c2->num_points+2) * sizeof(ArtVpath)); - points = c2->points; - for (i = 0; i < c2->num_points; i++, points++) { - vpath[i].code = ART_LINETO; - vpath[i].x = points->x; - vpath[i].y = points->y; - } - if (ISSET(cv->flags, CLOSED_BIT)) { - vpath[0].code = ART_MOVETO; - } - else { - vpath[0].code = ART_MOVETO_OPEN; - } - vpath[i].code = ART_END; - - if (cv->fill_svp) { - art_svp_free(cv->fill_svp); - cv->fill_svp = NULL; - } - if (ISSET(cv->flags, FILLED_BIT)) { - cv->fill_svp = art_svp_from_vpath(vpath); - } - if (cv->outline_svp) { - art_svp_free(cv->outline_svp); - cv->outline_svp = NULL; - } - if (cv->line_width) { - cv->outline_svp = art_svp_vpath_stroke(vpath, - ART_PATH_STROKE_JOIN_ROUND, - ART_PATH_STROKE_CAP_ROUND, - lw, 2, 1); - } - ZnFree(vpath); -#endif - } - if (ISSET(cv->flags, RELIEF_OK)) { holes = cv->shape.holes; c2 = cv->dev_shape.contours; @@ -864,6 +808,77 @@ ComputeCoordinates(Item item, item->item_bounding_box.orig.y -= 1; item->item_bounding_box.corner.x += 1; item->item_bounding_box.corner.y += 1; + + if (!ZnGradientFlat(cv->fill_color)) { + if (!cv->grad_geo) { + cv->grad_geo = ZnMalloc(4*sizeof(ZnPoint)); + } + if (cv->fill_color->type == ZN_AXIAL_GRADIENT) { + int angle = cv->fill_color->g.angle; + ZnTransfo *transfo1, *transfo2; + ZnPoint p[4]; + ZnBBox bbox; + + transfo1 = ZnTransfoNew(); + transfo2 = ZnTransfoNew(); + ZnRotateDeg(transfo1, angle); + ZnRotateDeg(transfo2, -angle); + holes = cv->shape.holes; + c1 = cv->shape.contours; + ResetBBox(&bbox); + for (j = 0; j < num_contours; j++, c1++, holes++) { + if (*holes) { + continue; + } + ZnListAssertSize(wi->work_pts, c1->num_points); + points = ZnListArray(wi->work_pts); + ZnTransformPoints(transfo1, c1->points, points, c1->num_points); + AddPointsToBBox(&bbox, points, c1->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, cv->grad_geo, 4); + ZnTransfoFree(transfo1); + ZnTransfoFree(transfo2); + } + else if (cv->fill_color->type == ZN_RADIAL_GRADIENT) { + ZnReal dist, new, x0, x, y0, y; + + ZnTransformPoint(wi->current_transfo, &cv->fill_color->g.p, &cv->grad_geo[0]); + x0 = cv->grad_geo[0].x; + y0 = cv->grad_geo[0].y; + dist = 0.0; + holes = cv->shape.holes; + c1 = cv->dev_shape.contours; + for (j = 0; j < num_contours; j++, c1++, holes++) { + if (*holes) { + continue; + } + points = c1->points; + for (i = 0; i < c1->num_points; i++, points++) { + x = points->x; + y = points->y; + new = (x-x0)*(x-x0) + (y-y0)*(y-y0); + if (new > dist) { + dist = new; + } + } + } + cv->grad_geo[1].x = sqrt(dist) + 2; /* Max radius plus a fuzz factor */ + } + } + else { + if (cv->grad_geo) { + ZnFree(cv->grad_geo); + cv->grad_geo = NULL; + } + } } @@ -1044,67 +1059,61 @@ Draw(Item item) * Fill if requested. */ if (ISSET(cv->flags, FILLED_OK)) { - if (!ZnGradientFlat(cv->fill_color)) { - DrawPolygonGradient(wi, cv->fill_color, &cv->dev_shape, - &item->item_bounding_box); - } - else { - values.foreground = ZnPixel(ZnGetGradientColor(wi->win, cv->fill_color, 50.0)); - gc_mask = GCFillStyle; - if (cv->tile != ZnUnspecifiedImage) { /* Fill tiled */ - Pixmap pmap = GetImagePixmap(wi->win, cv->tile_name, cv->tile, NULL); - values.fill_style = FillTiled; - values.tile = pmap; - values.ts_x_origin = REAL_TO_INT(item->item_bounding_box.orig.x); - values.ts_y_origin = REAL_TO_INT(item->item_bounding_box.orig.y); - gc_mask |= GCTileStipXOrigin|GCTileStipYOrigin|GCTile; - } - else if (cv->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ - values.fill_style = FillStippled; - values.stipple = cv->fill_pattern; - values.ts_x_origin = REAL_TO_INT(item->item_bounding_box.orig.x); - values.ts_y_origin = REAL_TO_INT(item->item_bounding_box.orig.y); - gc_mask |= GCTileStipXOrigin|GCTileStipYOrigin|GCStipple|GCForeground; - } - else { /* Fill solid */ - values.fill_style = FillSolid; - gc_mask |= GCForeground; - } - XChangeGC(wi->dpy, wi->gc, gc_mask, &values); - + values.foreground = ZnPixel(ZnGetGradientColor(wi->win, cv->fill_color, 0.0, NULL)); + gc_mask = GCFillStyle; + if (cv->tile != ZnUnspecifiedImage) { /* Fill tiled */ + Pixmap pmap = GetImagePixmap(wi->win, cv->tile_name, cv->tile, NULL); + values.fill_style = FillTiled; + values.tile = pmap; + values.ts_x_origin = REAL_TO_INT(item->item_bounding_box.orig.x); + values.ts_y_origin = REAL_TO_INT(item->item_bounding_box.orig.y); + gc_mask |= GCTileStipXOrigin|GCTileStipYOrigin|GCTile; + } + else if (cv->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ + values.fill_style = FillStippled; + values.stipple = cv->fill_pattern; + values.ts_x_origin = REAL_TO_INT(item->item_bounding_box.orig.x); + values.ts_y_origin = REAL_TO_INT(item->item_bounding_box.orig.y); + gc_mask |= GCTileStipXOrigin|GCTileStipYOrigin|GCStipple|GCForeground; + } + else { /* Fill solid */ + values.fill_style = FillSolid; + gc_mask |= GCForeground; + } + XChangeGC(wi->dpy, wi->gc, gc_mask, &values); + #ifdef GPC - if (cv->tristrip.num_strips == 0) { - gpc_polygon_to_tristrip((gpc_polygon *) &cv->dev_shape, &cv->tristrip); - } - for (i = 0; i < cv->tristrip.num_strips; i++) { - num_points = cv->tristrip.strip[i].num_vertices; - points = (ZnPoint *) cv->tristrip.strip[i].vertex; - ZnListAssertSize(wi->work_xpts, num_points); - xpoints = (XPoint *) ZnListArray(wi->work_xpts); - for (j = 0; j < num_points; j++) { - xpoints[j].x = REAL_TO_INT(points[j].x); - xpoints[j].y = REAL_TO_INT(points[j].y); - } - for (j = 0; j < num_points-2; j++) { - XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, - &xpoints[j], 3, Convex, CoordModeOrigin); - } - } -#else - num_points = cv->dev_shape.contours[0].num_points; - points = cv->dev_shape.contours[0].points; + if (cv->tristrip.num_strips == 0) { + gpc_polygon_to_tristrip((gpc_polygon *) &cv->dev_shape, &cv->tristrip); + } + for (i = 0; i < cv->tristrip.num_strips; i++) { + num_points = cv->tristrip.strip[i].num_vertices; + points = (ZnPoint *) cv->tristrip.strip[i].vertex; ZnListAssertSize(wi->work_xpts, num_points); xpoints = (XPoint *) ZnListArray(wi->work_xpts); - for (i = 0; i < num_points; i++) { - xpoints[i].x = REAL_TO_INT(points[i].x); - xpoints[i].y = REAL_TO_INT(points[i].y); + for (j = 0; j < num_points; j++) { + xpoints[j].x = REAL_TO_INT(points[j].x); + xpoints[j].y = REAL_TO_INT(points[j].y); + } + for (j = 0; j < num_points-2; j++) { + XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, + &xpoints[j], 3, Convex, CoordModeOrigin); } - XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, - xpoints, num_points, Complex, CoordModeOrigin); -#endif } +#else + num_points = cv->dev_shape.contours[0].num_points; + points = cv->dev_shape.contours[0].points; + ZnListAssertSize(wi->work_xpts, num_points); + xpoints = (XPoint *) ZnListArray(wi->work_xpts); + for (i = 0; i < num_points; i++) { + xpoints[i].x = REAL_TO_INT(points[i].x); + xpoints[i].y = REAL_TO_INT(points[i].y); + } + XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, + xpoints, num_points, Complex, CoordModeOrigin); +#endif } - + /* * Draw the lines between points */ @@ -1146,7 +1155,7 @@ Draw(Item item) } } else { - SetLineStyle(wi->dpy, wi->gc, cv->line_style); + SetLineStyle(wi, cv->line_style); values.foreground = ZnPixel(cv->line_color); values.line_width = (cv->line_width == 1) ? 0 : cv->line_width; values.join_style = cv->join_style; @@ -1254,28 +1263,189 @@ Draw(Item item) * ********************************************************************************** */ +#ifdef GLX +void +CurveRenderCB(void *closure) +{ + CurveItem cv = (CurveItem) closure; + int i, j, num_points; + ZnPoint *points; + +#ifdef GPC + if (cv->tristrip.num_strips == 0) { + gpc_polygon_to_tristrip((gpc_polygon *) &cv->dev_shape, &cv->tristrip); + } +#else +#error "GPC needed to render filled curves with GLX" +#endif + for (i = 0; i < cv->tristrip.num_strips; i++) { + num_points = cv->tristrip.strip[i].num_vertices; + points = (ZnPoint *) cv->tristrip.strip[i].vertex; + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < num_points; j++) { + glVertex2f(points[j].x, points[j].y); + } + glEnd(); + } +} +#endif static void Render(Item item) { -#ifdef LIBART - WidgetInfo *wi = item->wi; +#ifdef GLX + WidgetInfo *wi = item->wi; CurveItem cv = (CurveItem) item; - XColor *color = ZnGetGradientColor(wi->win, cv->fill_color, 50.0); - ArtPixBuf *pixbuf = NULL; + int i, j, num_points; + ZnPoint *points; + XColor *color; + int alpha; + + if ((cv->dev_shape.num_contours == 0) || + (ISCLEAR(cv->flags, FILLED_OK) && + !cv->line_width && + ISCLEAR(cv->flags, MARKER_OK))) { + return; + } + + /* + * Fill if requested. + */ + if (ISSET(cv->flags, FILLED_OK)) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (!ZnGradientFlat(cv->fill_color)) { + RenderGradient(wi, cv->fill_color, CurveRenderCB, cv, cv->grad_geo); + } + else if (cv->tile != ZnUnspecifiedImage) { /* Fill tiled */ + RenderTile(wi, GetImageTexture(wi->win, cv->tile_name, cv->tile), + cv->fill_color, CurveRenderCB, cv, (ZnPoint *) &item->item_bounding_box); + } + else { + if (cv->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ + /* + * Setup polygon stippling. + */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(GetBitmapMask(wi->dpy, cv->fill_pattern)->pixels); + } + color = ZnGetGradientColor(wi->win, cv->fill_color, 0.0, &alpha); + glColor4us(color->red, color->green, color->blue, alpha*65535/100); + CurveRenderCB(cv); + glDisable(GL_POLYGON_STIPPLE); + } + } + + /* + * Draw the lines between points + */ + if (cv->line_width) { + /* + * Drawing with relief disables: ends, line style and line pattern. + */ + if (ISSET(cv->flags, RELIEF_OK)) { + } + else { + color = cv->line_color; + glColor4us(color->red, color->green, color->blue, cv->line_alpha*65535/100); + if ((cv->line_width <= wi->max_line_width) && + (cv->line_width <= wi->max_point_width)) { + glLineWidth(cv->line_width); + SetLineStyle(wi, cv->line_style); + for (j = 0; j < cv->dev_shape.num_contours; j++) { + num_points = cv->dev_shape.contours[j].num_points; + points = cv->dev_shape.contours[j].points; + if (ISSET(cv->flags, CLOSED_BIT)) { + glBegin(GL_LINE_LOOP); + } + else { + glBegin(GL_LINE_STRIP); + } + for (i = 0; i < num_points; i++) { + glVertex2f(points[i].x, points[i].y); + } + glEnd(); + } + if (cv->line_width > 1) { + glPointSize(cv->line_width); + for (j = 0; j < cv->dev_shape.num_contours; j++) { + num_points = cv->dev_shape.contours[j].num_points; + points = cv->dev_shape.contours[j].points; + glBegin(GL_POINTS); + for (i = 0; i < num_points; i++) { + glVertex2f(points[i].x, points[i].y); + } + glEnd(); + } + } + } + else { + double lw_2 = (double) cv->line_width / 2.0; + double section[2][2] = { { 0.0, -lw_2 }, { 0.0, lw_2 } }; + double up[3] = { 1.0, 0.0, 0.0 }; + double (*gl_pts)[3]; + int style, num; + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + for (j = 0; j < cv->dev_shape.num_contours; j++) { + num_points = cv->dev_shape.contours[j].num_points; + points = cv->dev_shape.contours[j].points; + ZnListAssertSize(wi->work_doubles, (num_points+3)*3); + gl_pts = (void *) ZnListArray(wi->work_doubles); + if (ISSET(cv->flags, CLOSED_BIT)) { + gl_pts[0][0] = points[num_points-1].x; + gl_pts[0][1] = points[num_points-1].y; + gl_pts[0][2] = 0; + gl_pts[num_points+1][0] = points[0].x; + gl_pts[num_points+1][1] = points[0].y; + gl_pts[num_points+1][2] = 0; + gl_pts[num_points+2][0] = points[1].x; + gl_pts[num_points+2][1] = points[1].y; + gl_pts[num_points+2][2] = 0; + } + else { + gl_pts[0][0] = points[0].x; + gl_pts[1][1] = points[0].y; + gl_pts[2][2] = 0; + gl_pts[num_points+1][0] = points[num_points-1].x; + gl_pts[num_points+1][1] = points[num_points-1].y; + gl_pts[num_points+1][2] = 0; + } + for (i = 0; i < num_points; i++) { + gl_pts[i+1][0] = points[i].x; + gl_pts[i+1][1] = points[i].y; + gl_pts[i+1][2] = 0; + } + switch (cv->join_style) { + case JoinRound: + style = TUBE_JN_ROUND; + break; + case JoinMiter: + style = TUBE_JN_ANGLE; + break; + case JoinBevel: + style = TUBE_JN_CUT; + break; + } + if (cv->cap_style == CapRound) { + style |= TUBE_JN_CAP; + } + style |= TUBE_CONTOUR_CLOSED; + + num = num_points+2; + if (ISSET(cv->flags, CLOSED_BIT)) { + num++; + } + gleSetJoinStyle(style); + gleExtrusion(2, section, NULL, up, num, gl_pts, NULL); + } + } + } + } - if (cv->fill_svp != NULL) { - if (strlen(cv->tile_name) != 0) { - pixbuf = GetImagePixbuf(wi->win, cv->tile_name, cv->tile); - } - ITEM_P.RenderSVP(wi, cv->fill_svp, color->red, color->green, - color->blue, cv->fill_alpha & 0xff, - item->item_bounding_box.orig.x, - item->item_bounding_box.orig.y, pixbuf); - } - if (cv->outline_svp != NULL) { - ITEM_P.RenderSVP(wi, cv->outline_svp, cv->line_color->red, - cv->line_color->green, cv->line_color->blue, - cv->line_alpha & 0xff, 0, 0, NULL); + /* + * Draw the marks at each point. If arrows are specified or + * if last point join first point suppress markers at end points. + */ + if (ISSET(cv->flags, MARKER_OK)) { } #endif } diff --git a/generic/Rectangle.c b/generic/Rectangle.c index fb2fc38..6a5ea69 100644 --- a/generic/Rectangle.c +++ b/generic/Rectangle.c @@ -28,6 +28,9 @@ #include +#ifdef GLX +#include +#endif #include "Item.h" #include "Geo.h" @@ -70,17 +73,13 @@ typedef struct _RectangleItemStruct { Pixmap line_pattern; ZnGradient *fill_color; int line_alpha; - int fill_alpha; char *tile_name; /* Private data */ ZnPoint dev[4]; ZnImage tile; ZnGradient *gradient; -#ifdef LIBART - ArtSVP *outline_svp; - ArtSVP *fill_svp; -#endif + ZnPoint *grad_geo; } RectangleItemStruct, *RectangleItem; @@ -91,8 +90,6 @@ static ZnAttrConfig rect_attrs[] = { { ZN_CONFIG_BOOL, "-composescale", NULL, Tk_Offset(RectangleItemStruct, header.flags), COMPOSE_SCALE_BIT, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_UINT, "-fillalpha", NULL, - Tk_Offset(RectangleItemStruct, fill_alpha), 0, ZN_DRAW_FLAG, False }, { ZN_CONFIG_GRADIENT, "-fillcolor", NULL, Tk_Offset(RectangleItemStruct, fill_color), 0, ZN_DRAW_FLAG|ZN_BORDER_FLAG, False }, @@ -100,7 +97,7 @@ static ZnAttrConfig rect_attrs[] = { Tk_Offset(RectangleItemStruct, flags), FILLED_BIT, ZN_COORDS_FLAG, False }, { ZN_CONFIG_PATTERN, "-fillpattern", NULL, Tk_Offset(RectangleItemStruct, fill_pattern), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_UINT, "-linealpha", NULL, + { ZN_CONFIG_ALPHA, "-linealpha", NULL, Tk_Offset(RectangleItemStruct, line_alpha), 0, ZN_DRAW_FLAG, False }, { ZN_CONFIG_COLOR, "-linecolor", NULL, Tk_Offset(RectangleItemStruct, line_color), 0, @@ -173,6 +170,7 @@ Init(Item item, int num_elems; rect->gradient = NULL; + rect->grad_geo = NULL; /* Init attributes */ SET(item->flags, VISIBLE_BIT); @@ -206,13 +204,9 @@ Init(Item item, rect->tile = ZnUnspecifiedImage; rect->fill_pattern = ZnUnspecifiedPattern; rect->line_color = ZnGetColorByValue(wi->win, wi->fore_color); - rect->line_alpha = 255; + rect->line_alpha = 100; rect->fill_color = ZnGetGradient(wi->interp, wi->win, ZnNameOfColor(wi->fore_color)); - rect->fill_alpha = 255; -#ifdef LIBART - rect->outline_svp = rect->fill_svp = NULL; -#endif return ZN_OK; } @@ -235,6 +229,7 @@ Clone(Item item) if (rect->gradient) { rect->gradient = ZnGetGradientByValue(rect->gradient); } + rect->grad_geo = NULL; if (strlen(rect->tile_name) != 0) { text = ZnMalloc((strlen(rect->tile_name) + 1) * sizeof(char)); strcpy(text, rect->tile_name); @@ -252,9 +247,6 @@ Clone(Item item) } rect->line_color = ZnGetColorByValue(wi->win, rect->line_color); rect->fill_color = ZnGetGradientByValue(rect->fill_color); -#ifdef LIBART - rect->outline_svp = rect->fill_svp = NULL; -#endif } @@ -287,16 +279,11 @@ Destroy(Item item) if (rect->fill_pattern != ZnUnspecifiedPattern) { Tk_FreeBitmap(wi->dpy, rect->fill_pattern); } + if (rect->grad_geo) { + ZnFree(rect->grad_geo); + } ZnFreeGradient(rect->fill_color); ZnFreeColor(rect->line_color); -#ifdef LIBART - if (rect->outline_svp) { - art_svp_free(rect->outline_svp); - } - if (rect->fill_svp) { - art_svp_free(rect->fill_svp); - } -#endif } @@ -326,7 +313,10 @@ Configure(Item item, } if ((rect->relief != RELIEF_FLAT) && !rect->gradient) { rect->gradient = ZnGetReliefGradient(wi->interp, wi->win, - ZnNameOfColor(ZnGetGradientColor(wi->win, rect->fill_color, 50.0))); + ZnNameOfColor(ZnGetGradientColor(wi->win, + rect->fill_color, + 50.0, + NULL))); if (rect->gradient == NULL) { status = ZN_ERROR; } @@ -436,47 +426,73 @@ ComputeCoordinates(Item item, delta = ABS(delta); aligned |= delta < X_PRECISION_LIMIT; ASSIGN(rect->flags, ALIGNED_BIT, aligned); - - if (wi->render) { -#ifdef LIBART - ArtVpath vpath[6]; - - if (ISSET(rect->flags, FILLED_BIT) || rect->line_width) { - vpath[0].code = ART_MOVETO; - vpath[0].x = rect->dev[0].x; - vpath[0].y = rect->dev[0].y; - vpath[1].code = ART_LINETO; - vpath[1].x = rect->dev[3].x; - vpath[1].y = rect->dev[3].y; - vpath[2].code = ART_LINETO; - vpath[2].x = rect->dev[2].x; - vpath[2].y = rect->dev[2].y; - vpath[3].code = ART_LINETO; - vpath[3].x = rect->dev[1].x; - vpath[3].y = rect->dev[1].y; - vpath[4].code = ART_LINETO; - vpath[4].x = rect->dev[0].x; - vpath[4].y = rect->dev[0].y; - vpath[5].code = ART_END; - } - if (rect->fill_svp) { - art_svp_free(rect->fill_svp); - rect->fill_svp = NULL; - } - if (ISSET(rect->flags, FILLED_BIT)) { - rect->fill_svp = art_svp_from_vpath(vpath); + + /* + * If there is an axial gradient with an unaligned axis + * compute the bbox in the coordinate system defined + * by the gradient axis. + */ + if (!ZnGradientFlat(rect->fill_color)) { + if (rect->fill_color->type == ZN_AXIAL_GRADIENT) { + int angle = rect->fill_color->g.angle; + ZnTransfo *transfo1, *transfo2; + ZnPoint p1[4]; + ZnBBox bbox; + + if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) { + if (!rect->grad_geo) { + rect->grad_geo = ZnMalloc(4*sizeof(ZnPoint)); + } + transfo1 = ZnTransfoNew(); + transfo2 = ZnTransfoNew(); + ZnRotateDeg(transfo1, angle); + ZnRotateDeg(transfo2, -angle); + ZnTransformPoints(transfo1, p, p1, 4); + ResetBBox(&bbox); + AddPointsToBBox(&bbox, p1, 4); + p1[0] = bbox.orig; + p1[2] = bbox.corner; + p1[1].x = p1[2].x; + p1[1].y = p1[0].y; + p1[3].x = p1[0].x; + p1[3].y = p1[2].y; + ZnTransfoSetIdentity(transfo1); + ZnTransfoCompose(transfo1, transfo2, wi->current_transfo); + ZnTransformPoints(transfo1, p1, rect->grad_geo, 4); + ZnTransfoFree(transfo1); + ZnTransfoFree(transfo2); + } + else { + goto free_ggeo; + } } - if (rect->outline_svp) { - art_svp_free(rect->outline_svp); - rect->outline_svp = NULL; + else if (rect->fill_color->type == ZN_RADIAL_GRADIENT) { + ZnReal dist, new, x0, x, y0, y; + + if (!rect->grad_geo) { + rect->grad_geo = ZnMalloc(2*sizeof(ZnPoint)); + } + ZnTransformPoint(wi->current_transfo, &rect->fill_color->g.p, &rect->grad_geo[0]); + x0 = rect->grad_geo[0].x; + y0 = rect->grad_geo[0].y; + dist = 0.0; + for (i = 0; i < 4; i++) { + x = rect->dev[i].x; + y = rect->dev[i].y; + new = (x-x0)*(x-x0) + (y-y0)*(y-y0); + if (new > dist) { + dist = new; + } + } + rect->grad_geo[1].x = sqrt(dist); } - if (rect->line_width) { - rect->outline_svp = art_svp_vpath_stroke(vpath, - ART_PATH_STROKE_JOIN_MITER, - ART_PATH_STROKE_CAP_SQUARE, - rect->line_width, 2, 1); + } + else { + free_ggeo: + if (rect->grad_geo) { + ZnFree(rect->grad_geo); + rect->grad_geo = NULL; } -#endif } } @@ -568,63 +584,50 @@ Draw(Item item) * Fill if requested. */ if (ISSET(rect->flags, FILLED_BIT)) { - if (!ZnGradientFlat(rect->fill_color)) { + values.foreground = ZnPixel(ZnGetGradientColor(wi->win, rect->fill_color, 0.0, NULL)); + if (rect->tile != ZnUnspecifiedImage) { /* Fill tiled */ + Pixmap pmap = GetImagePixmap(wi->win, rect->tile_name, rect->tile, NULL); + values.fill_style = FillTiled; + values.tile = pmap; if (ISSET(rect->flags, ALIGNED_BIT)) { - DrawRectangleGradient(wi, rect->fill_color, &r); + values.ts_x_origin = (int) r.x; + values.ts_y_origin = (int) r.y; } else { - ZnPoly poly; - POLY_CONTOUR1(&poly, rect->dev, 4); - DrawPolygonGradient(wi, rect->fill_color, &poly, - &item->item_bounding_box); + values.ts_x_origin = (int) item->item_bounding_box.orig.x; + values.ts_y_origin = (int) item->item_bounding_box.orig.y; } - } - else { - values.foreground = ZnPixel(ZnGetGradientColor(wi->win, rect->fill_color, 50.0)); - if (rect->tile != ZnUnspecifiedImage) { /* Fill tiled */ - Pixmap pmap = GetImagePixmap(wi->win, rect->tile_name, rect->tile, NULL); - values.fill_style = FillTiled; - values.tile = pmap; - if (ISSET(rect->flags, ALIGNED_BIT)) { - values.ts_x_origin = (int) r.x; - values.ts_y_origin = (int) r.y; - } - else { - values.ts_x_origin = (int) item->item_bounding_box.orig.x; - values.ts_y_origin = (int) item->item_bounding_box.orig.y; - } - XChangeGC(wi->dpy, wi->gc, + XChangeGC(wi->dpy, wi->gc, GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCTile, &values); - } - else if (rect->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ - values.fill_style = FillStippled; - values.stipple = rect->fill_pattern; - if (ISSET(rect->flags, ALIGNED_BIT)) { - values.ts_x_origin = (int) r.x; - values.ts_y_origin = (int) r.y; - } - else { - values.ts_x_origin = (int) item->item_bounding_box.orig.x; - values.ts_y_origin = (int) item->item_bounding_box.orig.y; - } - XChangeGC(wi->dpy, wi->gc, - GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCStipple|GCForeground, - &values); - } - else { /* Fill solid */ - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle, &values); - } + } + else if (rect->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ + values.fill_style = FillStippled; + values.stipple = rect->fill_pattern; if (ISSET(rect->flags, ALIGNED_BIT)) { - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, - r.width, r.height); - } + values.ts_x_origin = (int) r.x; + values.ts_y_origin = (int) r.y; + } else { - XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, xp, 4, Convex, CoordModeOrigin); + values.ts_x_origin = (int) item->item_bounding_box.orig.x; + values.ts_y_origin = (int) item->item_bounding_box.orig.y; } + XChangeGC(wi->dpy, wi->gc, + GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCStipple|GCForeground, + &values); + } + else { /* Fill solid */ + values.fill_style = FillSolid; + XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle, &values); + } + if (ISSET(rect->flags, ALIGNED_BIT)) { + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, + r.width, r.height); + } + else { + XFillPolygon(wi->dpy, wi->draw_buffer, wi->gc, xp, 4, Convex, CoordModeOrigin); } } - + /* Draw the outline */ if (rect->line_width) { if (rect->relief != RELIEF_FLAT) { @@ -644,7 +647,7 @@ Draw(Item item) } } else { - SetLineStyle(wi->dpy, wi->gc, rect->line_style); + SetLineStyle(wi, rect->line_style); gc_mask = GCFillStyle|GCLineWidth|GCForeground|GCJoinStyle; values.foreground = ZnPixel(rect->line_color); values.line_width = (rect->line_width == 1) ? 0 : rect->line_width; @@ -682,170 +685,103 @@ Draw(Item item) * ********************************************************************************** */ +#ifdef GLX +static void +RectRenderCB(void *closure) +{ + RectangleItem rect = (RectangleItem) closure; + + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(rect->dev[0].x, rect->dev[0].y); + glVertex2f(rect->dev[3].x, rect->dev[3].y); + glVertex2f(rect->dev[1].x, rect->dev[1].y); + glVertex2f(rect->dev[2].x, rect->dev[2].y); + glEnd(); +} +#endif + static void Render(Item item) { +#ifdef GLX WidgetInfo *wi = item->wi; RectangleItem rect = (RectangleItem) item; - XColor *color = ZnGetGradientColor(wi->win, rect->fill_color, 50.0); -#ifdef LIBART - ArtPixBuf *pixbuf = NULL; - - if (rect->fill_svp != NULL) { - if (strlen(rect->tile_name) != 0) { - pixbuf = GetImagePixbuf(wi->win, rect->tile_name, rect->tile); - } - - ITEM_P.RenderSVP(wi, rect->fill_svp, color->red, color->green, - color->blue, rect->fill_alpha & 0xff, - item->item_bounding_box.orig.x, - item->item_bounding_box.orig.y, pixbuf); - } - if (rect->outline_svp != NULL) { - ITEM_P.RenderSVP(wi, rect->outline_svp, rect->line_color->red, - rect->line_color->green, rect->line_color->blue, - rect->line_alpha & 0xff, 0, 0, NULL); - } -#endif -#ifdef GLX - int i; + XColor *color; + int i, alpha; if (ISSET(rect->flags, FILLED_BIT)) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (!ZnGradientFlat(rect->fill_color)) { + ZnBool fast = (rect->fill_color->type == ZN_AXIAL_GRADIENT) && !rect->grad_geo; + RenderGradient(wi, rect->fill_color, + fast ? NULL : RectRenderCB, + rect, fast ? rect->dev : rect->grad_geo); } else { if (rect->tile != ZnUnspecifiedImage) { /* Fill tiled */ - ImageBits *im_bits = GetImageTexture(wi->win, rect->tile_name, rect->tile); - ZnReal x, y, nx, ny, lx, ly, s, t; - - /* - ZnReal dx, dy, width, height; - - if (ISSET(rect->flags, ALIGNED_BIT)) { - width = rect->dev[1].x - rect->dev[0].x; - if (width < 0) { - width = -width; - } - height = rect->dev[3].y - rect->dev[0].y; - if (height < 0) { - height = -height; - } - } - else { - dx = rect->dev[1].x - rect->dev[0].x; - dy = rect->dev[1].y - rect->dev[0].y; - width = sqrt(dx*dx + dy*dy); - dx = rect->dev[3].x - rect->dev[0].x; - dy = rect->dev[3].y - rect->dev[0].y; - height = sqrt(dx*dx + dy*dy); - } - dx = width/im_bits->width * im_bits->s; - dy = height/im_bits->height * im_bits->t; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, im_bits->texture); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex2f(rect->dev[0].x, rect->dev[0].y); - glTexCoord2f(0.0, dy); - glVertex2f(rect->dev[3].x, rect->dev[3].y); - glTexCoord2f(dx, dy); - glVertex2f(rect->dev[2].x, rect->dev[2].y); - glTexCoord2f(dx, 0.0); - glVertex2f(rect->dev[1].x, rect->dev[1].y); - glEnd(); - glDisable(GL_TEXTURE_2D);*/ - - /* - * Setup the stencil buffer with the shape to be drawn. - */ - glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 1, 1); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glBegin(GL_QUADS); - glVertex2f(rect->dev[0].x, rect->dev[0].y); - glVertex2f(rect->dev[3].x, rect->dev[3].y); - glVertex2f(rect->dev[2].x, rect->dev[2].y); - glVertex2f(rect->dev[1].x, rect->dev[1].y); - glEnd(); - /* - * Then texture map the rectangle through the shape. - * The rectangle is drawn using quad-strips, each - * quad matching the size of the texture tile. - */ - /* glDisable(GL_STENCIL_TEST);*/ - glStencilFunc(GL_EQUAL, 1, 1); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, im_bits->texture); - y = item->item_bounding_box.orig.y; - lx = item->item_bounding_box.corner.x; - ly = item->item_bounding_box.corner.y; - glBegin(GL_QUADS); - do { - x = item->item_bounding_box.orig.x; - t = 1.0; - ny = y + im_bits->height; - if (ny > ly) { - ny = ly; - t = (ly - y) / (ZnReal) im_bits->height; - } - t *= im_bits->t; - do { - s = 1.0; - nx = x + im_bits->width; - if (nx > lx) { - nx = lx; - s = (lx - x) / (ZnReal) im_bits->width; - } - s *= im_bits->s; - glTexCoord2f(0.0, 0.0); - glVertex2f(x, y); - glTexCoord2f(0.0, t); - glVertex2f(x, ny); - glTexCoord2f(s, t); - glVertex2f(nx, ny); - glTexCoord2f(s, 0.0); - glVertex2f(nx, y); - x = nx; - } - while (x != lx); - y = ny; - } - while (y != ly); - glEnd(); - glDisable(GL_TEXTURE_2D); - glDisable(GL_STENCIL_TEST); - } - else if (rect->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ + RenderTile(wi, GetImageTexture(wi->win, rect->tile_name, rect->tile), + rect->fill_color, RectRenderCB, rect, (ZnPoint *) &item->item_bounding_box); } - else { /* Fill solid */ - glColor4us(color->red, color->green, color->blue, rect->fill_alpha*256); - glBegin(GL_QUADS); - for (i = 0; i < 4; i++) { - glVertex2f(rect->dev[i].x, rect->dev[i].y); + else { + if (rect->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ + /* + * Setup polygon stippling. + */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(GetBitmapMask(wi->dpy, rect->fill_pattern)->pixels); } - glEnd(); + color = ZnGetGradientColor(wi->win, rect->fill_color, 0.0, &alpha); + glColor4us(color->red, color->green, color->blue, alpha*65535/100); + RectRenderCB(rect); + glDisable(GL_POLYGON_STIPPLE); } } } if (rect->line_width) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (rect->relief != RELIEF_FLAT) { + ZnPoint p[5]; + for (i = 0; i < 4; i++) { + p[4-i].x = rect->dev[i].x; + p[4-i].y = rect->dev[i].y; + } + p[0] = p[4]; + RenderPolygonRelief(wi, rect->relief, rect->gradient, + rect->line_alpha, 0, p, 5, rect->line_width); } else { - glColor4us(rect->line_color->red, rect->line_color->green, - rect->line_color->blue, rect->line_alpha*256); - glLineWidth(rect->line_width); - glBegin(GL_QUADS); - for (i = 0; i < 4; i++) { - glVertex2f(rect->dev[i].x, rect->dev[i].y); + color = rect->line_color; + glColor4us(color->red, color->green, color->blue, rect->line_alpha*65535/100); + if (rect->line_width < 3) { + SetLineStyle(wi, rect->line_style); + glLineWidth(rect->line_width); + glBegin(GL_LINE_LOOP); + for (i = 0; i < 4; i++) { + glVertex2f(rect->dev[i].x, rect->dev[i].y); + } + glEnd(); + } + else { + double lw_2 = (double) rect->line_width / 2.0; + double section[2][2] = { { 0.0, -lw_2 }, { 0.0, lw_2 } }; + double up[3] = { 1.0, 0.0, 0.0 }; + double vertices[7][3]; + + vertices[0][0] = vertices[4][0] = rect->dev[3].x; + vertices[0][1] = vertices[4][1] = rect->dev[3].y; + vertices[1][0] = vertices[5][0] = rect->dev[0].x; + vertices[1][1] = vertices[5][1] = rect->dev[0].y; + vertices[2][0] = vertices[6][0] = rect->dev[1].x; + vertices[2][1] = vertices[6][1] = rect->dev[1].y; + vertices[3][0] = rect->dev[2].x; + vertices[3][1] = rect->dev[2].y; + vertices[0][2] = vertices[1][2] = vertices[2][2] = vertices[3][2] = 0; + vertices[4][2] = vertices[5][2] = vertices[6][2] = 0; + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + gleSetJoinStyle(TUBE_JN_ANGLE | TUBE_CONTOUR_CLOSED); + gleExtrusion(2, section, NULL, up, 7, vertices, NULL); } - glEnd(); } } #endif -- cgit v1.1