aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlecoanet2002-03-15 14:31:27 +0000
committerlecoanet2002-03-15 14:31:27 +0000
commit99e13a70515326ece0cbe8838c0d7c06fb8bcee7 (patch)
treec60602a45f65feb33e8c869cf5f02f032c5a556e
parentfc3bcbc6d77e78745e6174b89aae71f0fbe295a7 (diff)
downloadtkzinc-99e13a70515326ece0cbe8838c0d7c06fb8bcee7.zip
tkzinc-99e13a70515326ece0cbe8838c0d7c06fb8bcee7.tar.gz
tkzinc-99e13a70515326ece0cbe8838c0d7c06fb8bcee7.tar.bz2
tkzinc-99e13a70515326ece0cbe8838c0d7c06fb8bcee7.tar.xz
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.
-rw-r--r--Bezier.c255
1 files 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 <ctype.h>
#include <malloc.h>
@@ -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
}