From b461fb032468c9a7b0a07ddd34156b1ff41bc57f Mon Sep 17 00:00:00 2001 From: lecoanet Date: Thu, 23 Mar 2000 14:06:04 +0000 Subject: R�alisation des d�grad�s (ressources). Mise � dispo des routines de gestion de la pile de transfo et de la pile de clip. Utilisation des routines de clip pour la r�alisation des champs. --- generic/Item.c | 426 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 339 insertions(+), 87 deletions(-) (limited to 'generic') diff --git a/generic/Item.c b/generic/Item.c index acc362e..edb90eb 100644 --- a/generic/Item.c +++ b/generic/Item.c @@ -417,6 +417,30 @@ ConfigureAttributes(char *record, } break; } + case ZN_CONFIG_GRADIENT_COLOR: + { + ZnColorGradient cg; + Tk_Uid new_name = Tk_GetUid(LangString(args[i+1])); + char *name = NULL; + if (*((ZnColorGradient *) valp)) { + name = ZnNameOfColorGradient(*((ZnColorGradient *) valp)); + } + if (name != new_name) { + cg = ZnGetColorGradient(wi->interp, wi->win, new_name); + if (!cg) { + Tcl_AppendResult(wi->interp, + " color gradient expected for attribute \"", + LangString(args[i]), "\"", NULL); + return ZN_ERROR; + } + if (*((ZnColorGradient *) valp)) { + ZnFreeColorGradient(*((ZnColorGradient *) valp)); + } + *((ZnColorGradient *) valp) = cg; + *flags |= desc->flags; + } + break; + } case ZN_CONFIG_BOOL: { int b; @@ -739,7 +763,7 @@ ConfigureAttributes(char *record, } case ZN_CONFIG_LINE_END: { - LineEnd line_end = NULL; + ZnLineEnd line_end = NULL; char *ptr = LangString(args[i+1]); if (strlen(ptr) != 0) { line_end = LineEndCreate(wi->interp, LangString(args[i+1])); @@ -747,14 +771,37 @@ ConfigureAttributes(char *record, return ZN_ERROR; } } - if (*((LineEnd *) valp) != NULL) { - LineEndDelete(*((LineEnd *) valp)); - *((LineEnd *) valp) = line_end; + if (*((ZnLineEnd *) valp) != NULL) { + LineEndDelete(*((ZnLineEnd *) valp)); + *((ZnLineEnd *) valp) = line_end; *flags |= desc->flags; } else { if (line_end != NULL) { - *((LineEnd *) valp) = line_end; + *((ZnLineEnd *) valp) = line_end; + *flags |= desc->flags; + } + } + break; + } + case ZN_CONFIG_GRADIENT_GEOM: + { + ZnGradientGeom gg = NULL; + char *ptr = LangString(args[i+1]); + if (strlen(ptr) != 0) { + gg = GradientGeomCreate(wi->interp, LangString(args[i+1])); + if (gg == NULL) { + return ZN_ERROR; + } + } + if (*((ZnGradientGeom *) valp) != NULL) { + GradientGeomDelete(*((ZnGradientGeom *) valp)); + *((ZnGradientGeom *) valp) = gg; + *flags |= desc->flags; + } + else { + if (gg != NULL) { + *((ZnGradientGeom *) valp) = gg; *flags |= desc->flags; } } @@ -1005,7 +1052,7 @@ ConfigureAttributes(char *record, } case ZN_CONFIG_LABEL_FORMAT: { - LabelFormat frmt = NULL; + ZnLabelFormat frmt = NULL; char *ptr = LangString(args[i+1]); while (*ptr && (*ptr == ' ')) { @@ -1019,14 +1066,14 @@ ConfigureAttributes(char *record, } } - if (*((LabelFormat *) valp) != NULL) { - LabelFormatDelete(*((LabelFormat *) valp)); - *((LabelFormat *) valp) = frmt; + if (*((ZnLabelFormat *) valp) != NULL) { + LabelFormatDelete(*((ZnLabelFormat *) valp)); + *((ZnLabelFormat *) valp) = frmt; *flags |= desc->flags; } else { if (frmt != NULL) { - *((LabelFormat *) valp) = frmt; + *((ZnLabelFormat *) valp) = frmt; *flags |= desc->flags; } } @@ -1415,7 +1462,7 @@ AttributeToString(WidgetInfo *wi, } case ZN_CONFIG_LINE_END: { - LineEnd line_end = *((LineEnd *) valp); + ZnLineEnd line_end = *((ZnLineEnd *) valp); if (!line_end) { LangSetString(&result, ""); @@ -1425,6 +1472,18 @@ AttributeToString(WidgetInfo *wi, } break; } + case ZN_CONFIG_GRADIENT_GEOM: + { + ZnGradientGeom gg = *((ZnGradientGeom *) valp); + + if (!gg) { + LangSetString(&result, ""); + } + else { + LangSetString(&result, GradientGeomGetString(gg)); + } + break; + } case ZN_CONFIG_RELIEF: LangSetString(&result , Tk_NameOfRelief(*((ReliefStyle *) valp))); break; @@ -1498,7 +1557,7 @@ AttributeToString(WidgetInfo *wi, break; case ZN_CONFIG_LABEL_FORMAT: { - LabelFormat frmt = *((LabelFormat *) valp); + ZnLabelFormat frmt = *((ZnLabelFormat *) valp); if (!frmt) { LangSetString(&result, ""); @@ -2025,7 +2084,7 @@ GetLabelBBox(FieldSet field_set, ZnDim *h) { ZnBBox bbox, tmp_bbox; - LabelFormat lf; + ZnLabelFormat lf; int i, num_fields; ZnDim clip_w, clip_h; @@ -2978,22 +3037,23 @@ QueryItem(Item item, /* ********************************************************************************** * - * ComposeItemTransform -- - * Compose the item transform with current_t transform in new_t. + * ComposeTransform -- + * Compose a (item) transform with current_t in new_t. * ********************************************************************************** */ static void -ComposeItemTransform(Item item, - ZnTransfo *current_t, - ZnTransfo *new_t) +ComposeTransform(ZnTransfo *transfo, + ZnTransfo *current_t, + ZnTransfo *new_t, + ZnBool compose_scale, + ZnBool compose_rot) { ZnBool full; - full = (ISSET(item->flags, COMPOSE_SCALE_BIT) && - ISSET(item->flags, COMPOSE_ROTATION_BIT)); + full = compose_scale && compose_rot; - if (!item->transfo && full) { + if (!transfo && full) { *new_t = *current_t; return; } @@ -3001,8 +3061,8 @@ ComposeItemTransform(Item item, /* * Full concatenation. */ - /*printf("Item transfo for item: 0x%X;", item); ZnPrintTransfo(item->transfo);*/ - ZnTransfoCompose(new_t, item->transfo, current_t); + /*ZnPrintTransfo(transfo);*/ + ZnTransfoCompose(new_t, transfo, current_t); } else { ZnPoint scale, trans, local_scale, local_trans; @@ -3015,14 +3075,14 @@ ComposeItemTransform(Item item, */ ZnTransfoSetIdentity(&t); ZnTransfoSetIdentity(new_t); - ZnTransfoDecompose(item->transfo, &local_scale, &local_trans, &local_rot, NULL); + ZnTransfoDecompose(transfo, &local_scale, &local_trans, &local_rot, NULL); ZnTranslate(&t, local_trans.x, local_trans.y); ZnTransfoCompose(&t2, &t, current_t); ZnTransfoDecompose(&t2, &scale, &trans, &rot, NULL); - if (ISSET(item->flags, COMPOSE_SCALE_BIT)) { + if (compose_scale) { ZnScale(new_t, scale.x, scale.y); } - if (ISSET(item->flags, COMPOSE_ROTATION_BIT)) { + if (compose_rot) { ZnRotateRad(new_t, rot); } ZnScale(new_t, local_scale.x, local_scale.y); @@ -3035,14 +3095,14 @@ ComposeItemTransform(Item item, /* ********************************************************************************** * - * GetTransform -- + * GetItemTransform -- * Compute the current transform for an item. * ********************************************************************************** */ static void -GetTransform(Item item, - ZnTransfo *t) +GetItemTransform(Item item, + ZnTransfo *t) { Item *items; int i; @@ -3065,7 +3125,9 @@ GetTransform(Item item, t2 = &t_tmp; items = (Item *) ZnListArray(item_stack); for (i = ZnListSize(item_stack)-1; i >= 0; i--) { - ComposeItemTransform(items[i], t1, t2); + ComposeTransform(items[i]->transfo, t1, t2, + ISSET(items[i]->flags, COMPOSE_SCALE_BIT), + ISSET(items[i]->flags, COMPOSE_ROTATION_BIT)); swap = t2; t2 = t1; t1 = swap; @@ -3076,11 +3138,16 @@ GetTransform(Item item, } + /* ********************************************************************************** * - * ResetTransformStack -- - * Empty the transform stack and restore the first transform on the stack. + * ResetTransformStack + * InitTransformStack + * FreeTransformStack + * CurrentTransform + * PushTransform + * PopTransform -- * ********************************************************************************** */ @@ -3092,14 +3159,79 @@ ResetTransformStack(WidgetInfo *wi) ZnTransfoSetIdentity(wi->current_transfo); } +static void +InitTransformStack(WidgetInfo *wi) +{ + wi->transfo_stack = ZnListNew(8, sizeof(ZnTransfo)); + ResetTransformStack(wi); +} + +static void +FreeTransformStack(WidgetInfo *wi) +{ + ZnListFree(wi->transfo_stack); +} + +static void +PushTransform(WidgetInfo *wi, + ZnTransfo *transfo, + ZnBool compose_scale, + ZnBool compose_rot) +{ + ZnTransfo *next_t; + int num_t; + + if (transfo == NULL) { + return; + } + + /* + * Push the current transform and concatenate + * the new transform taking into account the + * combination flags. + */ + num_t = ZnListSize(wi->transfo_stack); + ZnListAssertSize(wi->transfo_stack, num_t+1); + next_t = (ZnTransfo *) ZnListAt(wi->transfo_stack, num_t); + ComposeTransform(transfo, wi->current_transfo, next_t, + compose_scale, compose_rot); + wi->current_transfo = next_t; +} + +static void +PopTransform(WidgetInfo *wi) +{ + /* + * Restore the previous transform. + */ + ZnListDelete(wi->transfo_stack, ZnListTail); + wi->current_transfo = (ZnTransfo *) ZnListAt(wi->transfo_stack, ZnListTail); +} + /* ********************************************************************************** * - * ResetClipStack -- + * ResetClipStack + * InitClipStack + * FreeClipStack + * CurrentClip + * PushClip + * PopClip -- * ********************************************************************************** */ +/* + * Describe the clipping at a given node + * of the item hierarchy. + */ +typedef struct _ClipState { + ZnBool simple; /* The clip is an aligned rectangle. */ + Region region; /* The X region used to draw and to */ + /* probe for picking. */ + ZnBBox clip_box; /* The bounding box of the clip area. */ +} ClipState; + static void ResetClipStack(WidgetInfo *wi) { @@ -3117,6 +3249,149 @@ ResetClipStack(WidgetInfo *wi) wi->current_clip = NULL; } +static void +InitClipStack(WidgetInfo *wi) +{ + wi->clip_stack = ZnListNew(8, sizeof(ClipState)); + ResetClipStack(wi); +} + +static void +FreeClipStack(WidgetInfo *wi) +{ + ZnListFree(wi->clip_stack); +} + +static ZnBool +CurrentClip(WidgetInfo *wi, + Region *reg, + ZnBBox **clip_box, + ZnBool *simple) +{ + if (wi->current_clip) { + if (reg) { + *reg = wi->current_clip->region; + } + if (clip_box) { + *clip_box = &wi->current_clip->clip_box; + } + if (simple) { + *simple = wi->current_clip->simple; + } + return True; + } + + return False; +} + +static void +PushClip(WidgetInfo *wi, + ZnPoint *pts, + int num_pts, + ZnBool simple, + ZnBool set_gc) +{ + int i, num_c; + ClipState *previous_clip=NULL; + Region reg; + XRectangle rect; + XPoint *xpts; + + if (num_pts == 0) { + return; + } + + num_c = ZnListSize(wi->clip_stack); + /* printf("PushClip: num clips %d\n", num_c);fflush(stdout);*/ + if (num_c != 0) { + previous_clip = (ClipState *) ZnListAt(wi->clip_stack, ZnListTail); + } + ZnListAssertSize(wi->clip_stack, num_c+1); + wi->current_clip = (ClipState *) ZnListAt(wi->clip_stack, ZnListTail); + wi->current_clip->simple = simple; + + /* + * Compute the local region. + */ + if (simple) { + rect.x = pts[0].x; + rect.y = pts[0].y; + rect.width = pts[1].x - pts[0].x; + rect.height = pts[1].y - pts[0].y; + reg = XCreateRegion(); + XUnionRectWithRegion(&rect, reg, reg); + /*printf("Adding a simple clip: %d, %d, %d, %d\n", + rect.x, rect.y, rect.width, rect.height);*/ + } + else { + xpts = (XPoint *) ZnMalloc(num_pts * sizeof(XPoint)); + for (i = 0; i < num_pts; i++) { + xpts[i].x = pts[i].x; + xpts[i].y = pts[i].y; + } + reg = XPolygonRegion(xpts, num_pts, EvenOddRule); + ZnFree(xpts); + } + /* + * Combine with previous region if any. + */ + if (previous_clip) { + wi->current_clip->region = XCreateRegion(); + XIntersectRegion(reg, previous_clip->region, wi->current_clip->region); + XDestroyRegion(reg); + /*printf("Merging with previous clip\n");*/ + } + else { + wi->current_clip->region = reg; + } + XClipBox(wi->current_clip->region, &rect); + wi->current_clip->clip_box.orig.x = rect.x; + wi->current_clip->clip_box.orig.y = rect.y; + wi->current_clip->clip_box.corner.x = rect.x + rect.width; + wi->current_clip->clip_box.corner.y = rect.y + rect.height; + /*printf("Clip box is : %d, %d, %d, %d\n", + rect.x, rect.y, rect.width, rect.height);*/ + + /* + * Set the clipping in the GC. + */ + if (set_gc) { + XSetRegion(wi->dpy, wi->gc, wi->current_clip->region); + } +} + +static void +PopClip(WidgetInfo *wi, + ZnBool set_gc) +{ + if (wi->current_clip == NULL) { + return; + } + + XDestroyRegion(wi->current_clip->region); + ZnListDelete(wi->clip_stack, ZnListTail); + if (ZnListSize(wi->clip_stack) != 0) { + wi->current_clip = (ClipState *) ZnListAt(wi->clip_stack, ZnListTail); + } + else { + wi->current_clip = NULL; + } + + /* + * Set the clipping in the GC. + */ + if (set_gc) { + if (wi->current_clip) { + XSetRegion(wi->dpy, wi->gc, wi->current_clip->region); + } + else { + /*printf("resetting clip mask\n");*/ + XSetClipMask(wi->dpy, wi->gc, None); + } + } + /*printf("PopClip: num clips %d\n", ZnListSize(wi->clip_stack));fflush(stdout);*/ +} + /* ********************************************************************************** @@ -3614,7 +3889,7 @@ ConfigureField(FieldSet field_set, } if ((field_ptr->relief != RELIEF_FLAT) && !field_ptr->gradient) { field_ptr->gradient = ZnGetReliefGradient(wi->interp, wi->win, - ZnNameOfColor(field_ptr->back_color)); + ZnNameOfColor(field_ptr->back_color)); } if (ISSET(*flags, ZN_IMAGE_FLAG)) { @@ -3816,24 +4091,19 @@ DrawFields(FieldSet field_set) XGCValues values; ZnBBox label_clip_box, clip_bbox, bbox, *global_clip_box; ZnBBox text_bbox, clip_text_bbox; + ZnPoint pts[2]; XRectangle r; - Region reg, reg2; ZnPoint text_pos; ZnBBox pm_bbox, clip_pm_bbox; ZnBool restore = False; ZnDim lwidth, lheight; - + if (field_set->label_format && LabelFormatNumFields(field_set->label_format)) { bbox.orig = field_set->label_pos; GetLabelBBox(field_set, &lwidth, &lheight); bbox.corner.x = field_set->label_pos.x + lwidth; bbox.corner.y = field_set->label_pos.y + lheight; - if (wi->current_clip) { - global_clip_box = &wi->current_clip->clip_box; - } - else { - global_clip_box = &wi->damaged_area; - } + CurrentClip(wi, NULL, &global_clip_box, NULL); IntersectBBox(global_clip_box, &bbox, &label_clip_box); if (IsEmptyBBox(&label_clip_box)) { return; @@ -3882,35 +4152,11 @@ DrawFields(FieldSet field_set) clip_pm_bbox.corner.x != pm_bbox.corner.x || clip_pm_bbox.corner.y != pm_bbox.corner.y) { /* we must clip. */ - BBox2XRect(&clip_bbox, &r); - /*printf("must clip to %g %g %g %g, clip rect %d %d %d %d\n", - clip_bbox.orig.x, clip_bbox.orig.y, - clip_bbox.corner.x, clip_bbox.corner.y, - r.x, r.y, r.x+r.width, r.y+r.height);*/ - reg = XCreateRegion(); - XUnionRectWithRegion(&r, reg, reg); - if (wi->current_clip) { - reg2 = XCreateRegion(); - XIntersectRegion(reg, wi->current_clip->region, reg2); - XDestroyRegion(reg); - reg = reg2; - } - XSetRegion(wi->dpy, wi->gc, reg); - XDestroyRegion(reg); + pts[0] = clip_bbox.orig; + pts[1] = clip_bbox.corner; + PushClip(wi, pts, 2, True, True); restore = True; } - else { - if (restore) { - /* Restore the previous clip. */ - if (wi->current_clip) { - XSetRegion(wi->dpy, wi->gc, wi->current_clip->region); - } - else { - XSetRegion(wi->dpy, wi->gc, wi->damaged_region); - } - restore = False; - } - } /* * Draw the background. @@ -4029,15 +4275,11 @@ DrawFields(FieldSet field_set) r.x + r.width - 1, r.y); } } - } - if (restore) { - /* Restore the previous clip. */ - if (wi->current_clip) { - XSetRegion(wi->dpy, wi->gc, wi->current_clip->region); - } - else { - XSetRegion(wi->dpy, wi->gc, wi->damaged_region); + if (restore) { + /* Restore the previous clip. */ + PopClip(wi, True); + restore = False; } } } @@ -4249,7 +4491,8 @@ Repair(WidgetInfo *wi) { XGCValues values; XRectangle r; - + ZnPoint pts[2]; + /* To be done only if we are realized and there is something to update. */ if (wi->realized && !IsEmptyBBox(&wi->damaged_area)) { @@ -4265,9 +4508,10 @@ Repair(WidgetInfo *wi) wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y); r.width = wi->damaged_area.corner.x - wi->damaged_area.orig.x; r.height = wi->damaged_area.corner.y - wi->damaged_area.orig.y; - - wi->damaged_region = XCreateRegion(); - XUnionRectWithRegion(&r, wi->damaged_region, wi->damaged_region); + pts[0] = wi->damaged_area.orig; + pts[1] = wi->damaged_area.corner; + + PushClip(wi, pts, 2, True, True); #ifdef PERFOS XStartChrono(draw_time, wi->dpy, wi->draw_buffer); @@ -4287,7 +4531,7 @@ Repair(WidgetInfo *wi) GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin, &values); } - /*printf("filling rectangle: %d %d %d %d\n", r.x, r.y, r.width, r.height);*/ + /*printf("Repair : filling rectangle: %d %d %d %d\n", r.x, r.y, r.width, r.height);*/ XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height); /* Draw the items */ @@ -4298,8 +4542,8 @@ Repair(WidgetInfo *wi) /*StopChrono(int_draw_time);*/ XStopChrono(draw_time, wi->dpy, wi->draw_buffer); #endif - XDestroyRegion(wi->damaged_region); - wi->damaged_region = None; + + PopClip(wi, True); } } @@ -4332,8 +4576,17 @@ struct _ITEM_P ITEM_P = { LeaderToLabel, GetLabelBBox, GetFieldBBox, + InitTransformStack, + FreeTransformStack, ResetTransformStack, - ResetClipStack + PushTransform, + PopTransform, + InitClipStack, + FreeClipStack, + ResetClipStack, + PushClip, + PopClip, + CurrentClip }; struct _ITEM ITEM = { @@ -4360,6 +4613,5 @@ struct _ITEM ITEM = { RotateItem, Invalidate, InvalidateItems, - ComposeItemTransform, - GetTransform + GetItemTransform }; -- cgit v1.1