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/Rectangle.c | 440 ++++++++++++++++++++++------------------------------ 1 file changed, 188 insertions(+), 252 deletions(-) (limited to 'generic/Rectangle.c') 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