From 99e13a70515326ece0cbe8838c0d7c06fb8bcee7 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Fri, 15 Mar 2002 14:31:27 +0000 Subject: Portage en GL. Ajustement des ressources couleurs pour tenir compte de la g�n�ralisation des gradients. Traitement centralis� des images. Les reliefs ont leur propre alpha. --- Bezier.c | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 217 insertions(+), 38 deletions(-) diff --git a/Bezier.c b/Bezier.c index 0c0bf3d..9b95d38 100644 --- a/Bezier.c +++ b/Bezier.c @@ -34,6 +34,9 @@ #include "WidgetInfo.h" #include "Image.h" #include "Color.h" +#ifdef GPC +#include "gpc/gpc.h" +#endif #include #include @@ -84,6 +87,8 @@ typedef struct _BezierItemStruct { ZnImage tile; ZnList dev_points; ZnGradient *gradient; + ZnTriStrip tristrip; + ZnPoint *grad_geo; } BezierItemStruct, *BezierItem; @@ -180,7 +185,9 @@ Init(Item item, ZnPoint p; bz->dev_points = NULL; + bz->tristrip.num_strips = 0; bz->gradient = NULL; + bz->grad_geo = NULL; /* Init attributes */ SET(item->flags, VISIBLE_BIT); @@ -228,8 +235,8 @@ Init(Item item, bz->line_pattern = ZnUnspecifiedPattern; bz->cap_style = CapRound; - bz->fill_color = ZnGetGradientByValue(wi->fore_gradient); - bz->line_color = ZnGetGradientByValue(wi->fore_gradient); + bz->fill_color = ZnGetGradientByValue(wi->fore_color); + bz->line_color = ZnGetGradientByValue(wi->fore_color); return ZN_OK; } @@ -250,7 +257,9 @@ Clone(Item item) char *text; bz->dev_points = NULL; - + bz->grad_geo = NULL; + bz->tristrip.num_strips = 0; + if (bz->gradient) { bz->gradient = ZnGetGradientByValue(bz->gradient); } @@ -267,7 +276,7 @@ Clone(Item item) if (bz->last_end) { LineEndDuplicate(bz->last_end); } - if (strlen(bz->tile_name) != 0) { + if (bz->tile != ZnUnspecifiedImage) { text = ZnMalloc((strlen(bz->tile_name) + 1) * sizeof(char)); strcpy(text, bz->tile_name); bz->tile_name = text; @@ -302,6 +311,12 @@ Destroy(Item item) if (bz->dev_points) { ZnListFree(bz->dev_points); } + if (bz->grad_geo) { + ZnFree(bz->grad_geo); + } + if (bz->tristrip.num_strips) { + TRI_FREE(&bz->tristrip); + } if (bz->first_end) { LineEndDelete(bz->first_end); } @@ -375,6 +390,8 @@ Configure(Item item, WidgetInfo *wi = item->wi; BezierItem bz = (BezierItem) item; int status = ZN_OK; + XColor *color; + int alpha; status = ITEM_P.ConfigureAttributes((char *) item, -1, argc, argv, flags); @@ -384,34 +401,18 @@ Configure(Item item, bz->gradient = NULL; } if ((bz->relief != RELIEF_FLAT) && !bz->gradient) { + color = ZnGetGradientColor(bz->line_color, 51.0, &alpha); bz->gradient = ZnGetReliefGradient(wi->interp, wi->win, - ZnNameOfColor(ZnGetGradientColor(bz->fill_color, - 50.0, NULL))); + ZnNameOfColor(color), alpha); if (bz->gradient == NULL) { status = ZN_ERROR; } } if (ISSET(*flags, ZN_TILE_FLAG)) { - Tk_Image tile; - - if (strcmp(bz->tile_name, "") != 0) { - tile = Tk_GetImage(wi->interp, wi->win, bz->tile_name, - BzTileChange, (ClientData) bz); - if (tile == NULL) { - /* - * The name will not be in sync with the image in - * this case. - */ - status = ZN_ERROR; - } - } - else { - tile = ZnUnspecifiedImage; - } - if (bz->tile != ZnUnspecifiedImage) { - Tk_FreeImage(bz->tile); + if (ValidateImage(wi, item, bz->tile_name, BzTileChange, + &bz->tile, "bezier -tile") == ZN_ERROR) { + status = ZN_ERROR; } - bz->tile = tile; } return status; @@ -505,6 +506,10 @@ ComputeCoordinates(Item item, SetRenderFlags(bz); + if (bz->tristrip.num_strips) { + TRI_FREE(&bz->tristrip); + } + points = (ZnPoint *) ZnListArray(bz->points); num_points = ZnListSize(bz->points); @@ -574,6 +579,34 @@ 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(bz->fill_color)) { + ZnPoly poly; + + if (!bz->grad_geo) { + bz->grad_geo = ZnMalloc(4*sizeof(ZnPoint)); + } + if (bz->fill_color->type == ZN_AXIAL_GRADIENT) { + POLY_CONTOUR1(&poly, points, num_points); + ComputeAxialGradient(wi, &poly, bz->fill_color->g.angle, + bz->grad_geo); + } + else if (bz->fill_color->type == ZN_RADIAL_GRADIENT) { + POLY_CONTOUR1(&poly, dev_points, num_points); + ComputeRadialGradient(wi, &poly, &item->item_bounding_box, + &bz->fill_color->g.p, bz->grad_geo); + } + else if (bz->fill_color->type == ZN_PATH_GRADIENT) { + ZnTransformPoint(wi->current_transfo, &bz->fill_color->g.p, + &bz->grad_geo[0]); + } + } + else { + if (bz->grad_geo) { + ZnFree(bz->grad_geo); + bz->grad_geo = NULL; + } + } } @@ -677,13 +710,13 @@ Draw(Item item) ZnPoint *points; XPoint *xpoints = NULL; int lw = bz->line_width; - + if (bz->dev_points == NULL) { return; } GetBezierPath(bz->dev_points, wi->work_pts); - points = (ZnPoint *) ZnListArray(wi->work_pts); + points = ZnListArray(wi->work_pts); num_points = ZnListSize(wi->work_pts); /* @@ -736,8 +769,22 @@ Draw(Item item) * Drawing with relief disables: ends, line style and line pattern. */ if (ISSET(bz->flags, RELIEF_OK)) { - DrawPolygonRelief(wi, bz->relief, bz->gradient, - points, num_points, ISCLEAR(bz->flags, CCW)?-lw:lw); + ReliefStyle relief; + int relief_dir; + + relief = bz->relief; + relief_dir = relief & RELIEF_MASK; + if (ISCLEAR(bz->flags, CCW)) { + lw = -lw; + if (relief_dir == RELIEF_SUNKEN) { + relief_dir = RELIEF_RAISED; + } + else { + relief_dir = RELIEF_SUNKEN; + } + relief = (relief & ~RELIEF_MASK) | relief_dir; + } + DrawPolygonRelief(wi, relief, bz->gradient, points, num_points, lw); } else { SetLineStyle(wi, bz->line_style); @@ -800,12 +847,127 @@ Draw(Item item) * ********************************************************************************** */ +#ifdef GLX +void +BezierRenderCB(void *closure) +{ +#ifdef GPC + BezierItem bz = (BezierItem) closure; + WidgetInfo *wi = ((Item) closure)->wi; + int i, j, num_points; + ZnPoint *points; + + if (bz->tristrip.num_strips == 0) { + ZnPoly poly; + POLY_CONTOUR1(&poly, (ZnPoint *) ZnListArray(wi->work_pts), + ZnListSize(wi->work_pts)); + gpc_polygon_to_tristrip((gpc_polygon *) &poly, + (gpc_tristrip *) &bz->tristrip); + } + + for (i = 0; i < bz->tristrip.num_strips; i++) { + num_points = bz->tristrip.strips[i].num_points; + points = bz->tristrip.strips[i].points; + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < num_points; j++, points++) { + glVertex2f(points->x, points->y); + } + glEnd(); + } +#endif +} +#endif static void Render(Item item) { - /*WidgetInfo *wi = item->wi; - BezierItem bz = (BezierItem) item;*/ +#ifdef GLX + WidgetInfo *wi = item->wi; + BezierItem bz = (BezierItem) item; + ZnPoint *points; + int num_points; + XColor *color; + int alpha; + + if (bz->dev_points == NULL) { + return; + } + + GetBezierPath(bz->dev_points, wi->work_pts); + points = ZnListArray(wi->work_pts); + num_points = ZnListSize(wi->work_pts); + + /* + * Fill if requested. + */ + if (ISSET(bz->flags, FILLED_OK)) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (!ZnGradientFlat(bz->fill_color)) { + ZnPoly poly; + + POLY_CONTOUR1(&poly, points, num_points); + RenderGradient(wi, bz->fill_color, BezierRenderCB, bz, + bz->grad_geo, &poly); + } + else if (bz->tile != ZnUnspecifiedImage) { /* Fill tiled */ + RenderTile(wi, GetImageTexture(wi->win, bz->tile_name, bz->tile), + bz->fill_color, BezierRenderCB, bz, + (ZnPoint *) &item->item_bounding_box); + } + else { + if (bz->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ + /* + * Setup polygon stippling. + */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(GetBitmapMask(wi->dpy, bz->fill_pattern)->pixels); + } + color = ZnGetGradientColor(bz->fill_color, 0.0, &alpha); + alpha = ZnComposeAlpha(alpha, wi->alpha); + glColor4us(color->red, color->green, color->blue, alpha); + BezierRenderCB(bz); + glDisable(GL_POLYGON_STIPPLE); + } + } + /* + * Draw the lines between points + */ + if (bz->line_width) { + /* + * Drawing with relief disables: ends, line style and line pattern. + */ + if (ISSET(bz->flags, RELIEF_OK)) { + ReliefStyle relief; + ZnDim line_width; + int relief_dir; + + relief = bz->relief; + line_width = bz->line_width; + if (ISCLEAR(bz->flags, CCW)) { + line_width = -line_width; + relief_dir = relief & RELIEF_MASK; + if (relief_dir == RELIEF_SUNKEN) { + relief_dir = RELIEF_RAISED; + } + else { + relief_dir = RELIEF_SUNKEN; + } + relief = (relief & ~RELIEF_MASK) | relief_dir; + } + RenderPolygonRelief(wi, relief, bz->gradient, True, + points, num_points, line_width); + } + else { + ZnLineEnd first = ISSET(bz->flags, FIRST_END_OK) ? bz->first_end : NULL; + ZnLineEnd last = ISSET(bz->flags, LAST_END_OK) ? bz->last_end : NULL; + + RenderPolyline(wi, points, num_points, + bz->line_width, False, + bz->line_style, bz->cap_style, JoinRound, + first, last, bz->line_color); + } + } +#endif } @@ -944,21 +1106,39 @@ static ZnBool GetClipVertices(Item item, ZnTriStrip *tristrip) { -#ifdef GPC_TODO +#ifdef GPC BezierItem bz = (BezierItem) item; WidgetInfo *wi = item->wi; #else ZnPoint *points; #endif -#ifdef GPC_TODO +#ifdef GPC + tristrip->fan = False; + tristrip->num_strips = 0; + if (bz->dev_points) { - GetBezierPath(bz->dev_points, wi->work_pts); + if (bz->tristrip.num_strips == 0) { + ZnPoly poly; + + GetBezierPath(bz->dev_points, wi->work_pts); + POLY_CONTOUR1(&poly, (ZnPoint *) ZnListArray(wi->work_pts), + ZnListSize(wi->work_pts)); + gpc_polygon_to_tristrip((gpc_polygon *) &poly, + (gpc_tristrip *) &bz->tristrip); + } - POLY_CONTOUR1(poly, (ZnPoint *) ZnListArray(wi->work_pts), - ZnListSize(wi->work_pts)); + if (bz->tristrip.num_strips == 1) { + TRI_STRIP1(tristrip, + bz->tristrip.strips[0].points, + bz->tristrip.strips[0].num_points); + } + else if (bz->tristrip.num_strips > 1) { + tristrip->num_strips = bz->tristrip.num_strips; + tristrip->strips = bz->tristrip.strips; + } } - + return False; #else ZnListAssertSize(item->wi->work_pts, 2); @@ -968,7 +1148,6 @@ GetClipVertices(Item item, points[1] = item->item_bounding_box.corner; return True; - #endif } -- cgit v1.1