From f0ebc4f3affbac34920f7be557312927e6cf8a81 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Thu, 11 May 2000 13:58:17 +0000 Subject: Adaptation suite � la r�alisation des polygones multi-contours. --- generic/Group.c | 119 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 51 deletions(-) (limited to 'generic/Group.c') diff --git a/generic/Group.c b/generic/Group.c index bc636be..029e32c 100644 --- a/generic/Group.c +++ b/generic/Group.c @@ -229,9 +229,10 @@ SetXShape(Item grp) #ifdef SHAPE WidgetInfo *wi = grp->wi; Item clip = ((GroupItem) grp)->clip; - int i, num_pts; + int i, j, num_pts, max_num_pts; ZnPos min_x, min_y, max_x, max_y; - ZnPoint *pts, *p; + ZnPoly poly; + ZnPoint *p; ZnBool simple; ZnDim width, height; XPoint *xpts, *xp; @@ -255,8 +256,8 @@ SetXShape(Item grp) /* * Get the clip shape. */ - simple = clip->class->GetClipVertices(clip, &pts, &num_pts); - if (simple || (num_pts == 0)) { + simple = clip->class->GetClipVertices(clip, &poly); + if (simple || (poly.num_contours == 0)) { /* * Nothing to do: after normalisation the rectangular shape will * fit exactly the window. We may test here if a shape is currently @@ -271,53 +272,67 @@ SetXShape(Item grp) /* * First make the vertices start at zero. */ - p = &pts[0]; - min_x = p->x; - min_y = p->y; - p++; - for (i = 1; i < num_pts; p++, i++) { - if (p->x < min_x) { - min_x = p->x; + max_x = min_x = poly.contours[0].points[0].x; + max_y = min_y = poly.contours[0].points[0].y; + max_num_pts = poly.contours[0].num_points; + for (j = 0; j < poly.num_contours; j++) { + p = poly.contours[j].points; + num_pts = poly.contours[j].num_points; + if (num_pts > max_num_pts) { + max_num_pts = num_pts; } - if (p->y < min_y) { - min_y = p->y; + for (i = 0; i < num_pts; p++, i++) { + if (p->x < min_x) { + min_x = p->x; + } + if (p->y < min_y) { + min_y = p->y; + } + if (p->x > max_x) { + max_x = p->x; + } + if (p->y > max_y) { + max_y = p->y; + } } } - for (p = &pts[0], i = 0; i < num_pts; i++, p++) { - p->x -= min_x; - p->y -= min_y; + for (j = 0; j < poly.num_contours; j++) { + p = poly.contours[j].points; + num_pts = poly.contours[j].num_points; + for (i = 0; i < num_pts; i++, p++) { + p->x -= min_x; + p->y -= min_y; + } } + max_x -= min_x; + max_y -= min_y; + /* * Now normalize the shape and map it to the window size. */ - p = &pts[0]; - max_x = p->x; - max_y = p->y; - p++; - for (i = 1; i < num_pts; p++, i++) { - if (p->x > max_x) { - max_x = p->x; - } - if (p->y > max_y) { - max_y = p->y; - } - } width = wi->width + 2*wi->border_width; height = wi->height + 2*wi->border_width; - xpts = (XPoint *) ZnMalloc(num_pts * sizeof(XPoint)); - for (p = &pts[0], xp = xpts, i = 0; i < num_pts; i++, p++, xp++) { - xp->x = (short) (p->x * width / max_x); - xp->y = (short) (p->y * height / max_y); - } - /* - * Translate it in a region and apply this region to the window. - */ - reg = XPolygonRegion(xpts, num_pts, EvenOddRule); - XShapeCombineMask(wi->dpy, wi->full_reshape ? ZnWindowId(wi->win) : wi->real_top, + xpts = (XPoint *) ZnMalloc(max_num_pts * sizeof(XPoint)); + XShapeCombineMask(wi->dpy, wi->full_reshape?ZnWindowId(wi->win):wi->real_top, ShapeBounding, 0, 0, None, ShapeSet); - XShapeCombineRegion(wi->dpy, wi->full_reshape ? wi->real_top : ZnWindowId(wi->win), - ShapeBounding, 0, 0, reg, ShapeSet); - XDestroyRegion(reg); + XShapeCombineRegion(wi->dpy, wi->full_reshape?wi->real_top:ZnWindowId(wi->win), + ShapeBounding, 0, 0, None, ShapeSet); + for (j = 0; j < poly.num_contours; j++) { + p = poly.contours[j].points; + num_pts = poly.contours[j].num_points; + for (xp = xpts, i = 0; i < num_pts; i++, p++, xp++) { + xp->x = (short) (p->x * width / max_x); + xp->y = (short) (p->y * height / max_y); + } + /* + * Translate it in a region and apply this region to the window. + */ + reg = XPolygonRegion(xpts, num_pts, EvenOddRule); + XShapeCombineRegion(wi->dpy, wi->full_reshape?wi->real_top:ZnWindowId(wi->win), + ShapeBounding, 0, 0, reg, + poly.holes[j]?ShapeSubtract:ShapeUnion); + XDestroyRegion(reg); + } ZnFree(xpts); } } @@ -402,15 +417,14 @@ PushClip(GroupItem group, ZnBool set_gc) { WidgetInfo *wi = ((Item) group)->wi; - int num_pts; - ZnPoint *pts; + ZnPoly poly; ZnBool simple; if ((group->clip != ZN_NO_ITEM) && ((((Item) group) != wi->top_group) || !wi->reshape)) { - simple = group->clip->class->GetClipVertices(group->clip, &pts, &num_pts); + simple = group->clip->class->GetClipVertices(group->clip, &poly); /*printf("Group: PushClip group %d\n", ((Item) group)->id);*/ - ITEM_P.PushClip(wi, pts, num_pts, simple, set_gc); + ITEM_P.PushClip(wi, &poly, simple, set_gc); } } @@ -980,6 +994,7 @@ Pick(Item item, */ static int Coords(Item item, + int contour, int index, int cmd, ZnPoint **pts, @@ -1038,9 +1053,9 @@ PostScript(Item item, */ static ItemClassStruct GROUP_ITEM_CLASS = { sizeof(GroupItemStruct), - False, - False, - False, + False, /* has_fields */ + False, /* has_parts */ + False, /* has_anchors */ "group", group_attrs, Init, @@ -1048,15 +1063,17 @@ static ItemClassStruct GROUP_ITEM_CLASS = { Destroy, Configure, Query, - NULL, - NULL, - NULL, + NULL, /* GetFieldSet */ + NULL, /* GetAnchor */ + NULL, /* GetClipVertices */ Coords, + NULL, /* Contour */ ComputeCoordinates, ToArea, Draw, IsSensitive, Pick, + NULL, /* PickVertex */ PostScript }; -- cgit v1.1