aboutsummaryrefslogtreecommitdiff
path: root/generic/Item.c
diff options
context:
space:
mode:
authorlecoanet2000-03-23 14:06:04 +0000
committerlecoanet2000-03-23 14:06:04 +0000
commitb461fb032468c9a7b0a07ddd34156b1ff41bc57f (patch)
treee40dc3271d9a3121cee367f91743a17352b5640d /generic/Item.c
parent6e88adfac1e3b390b0cba62c905942a895712ea4 (diff)
downloadtkzinc-b461fb032468c9a7b0a07ddd34156b1ff41bc57f.zip
tkzinc-b461fb032468c9a7b0a07ddd34156b1ff41bc57f.tar.gz
tkzinc-b461fb032468c9a7b0a07ddd34156b1ff41bc57f.tar.bz2
tkzinc-b461fb032468c9a7b0a07ddd34156b1ff41bc57f.tar.xz
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.
Diffstat (limited to 'generic/Item.c')
-rw-r--r--generic/Item.c426
1 files changed, 339 insertions, 87 deletions
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
};