aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlecoanet2001-10-12 07:31:01 +0000
committerlecoanet2001-10-12 07:31:01 +0000
commit8042847f7e2f60a3e03ed339e2743e3cc46ec63d (patch)
tree4d8d77d740770a050f18a12f614e0d6bebd8db74
parentf34c1471741ccdad827ff185525fa30ae131d616 (diff)
downloadtkzinc-8042847f7e2f60a3e03ed339e2743e3cc46ec63d.zip
tkzinc-8042847f7e2f60a3e03ed339e2743e3cc46ec63d.tar.gz
tkzinc-8042847f7e2f60a3e03ed339e2743e3cc46ec63d.tar.bz2
tkzinc-8042847f7e2f60a3e03ed339e2743e3cc46ec63d.tar.xz
Ajout du rendu des champs en GL.
Ajout d'un type d'attribut ALPHA. Ajout du support de clipping (simple) en GL. La routine de rendu des champs est transform�e pour fonctionner avec des callbacks. Suppression du code libart. Correction du code de projection GL qui provoquait une certaine distorsion des textes et images. Ajout du support de tuilage de fond en GL.
-rw-r--r--generic/Item.c816
1 files changed, 493 insertions, 323 deletions
diff --git a/generic/Item.c b/generic/Item.c
index 0a06e9b..361754d 100644
--- a/generic/Item.c
+++ b/generic/Item.c
@@ -70,9 +70,9 @@ static ZnList item_stack = NULL;
typedef struct _FieldStruct {
/* Public data */
ZnColor color;
- ZnColor back_color;
- ZnColor border_color;
+ ZnGradient *fill_color;
Pixmap fill_pattern;
+ ZnColor border_color;
char *text;
char *image_name;
char *tile_name;
@@ -88,11 +88,15 @@ typedef struct _FieldStruct {
ZnImage image;
ZnImage tile;
ZnGradient *gradient;
+ ZnPoint *grad_geo;
short orig_x;
short orig_y;
short corner_x;
short corner_y;
FieldSet field_set;
+#ifdef GLX
+ TexFont *txf;
+#endif
} FieldStruct, *Field;
@@ -106,8 +110,8 @@ ZnAttrConfig field_attrs[] = {
Tk_Offset(FieldStruct, alignment), 0, ZN_DRAW_FLAG, False },
{ ZN_CONFIG_AUTO_JUSTIFY, "-autoalignment", NULL,
Tk_Offset(FieldStruct, auto_alignment), 0, ZN_DRAW_FLAG, False },
- { ZN_CONFIG_COLOR, "-backcolor", NULL,
- Tk_Offset(FieldStruct, back_color), 0,
+ { ZN_CONFIG_GRADIENT, "-backcolor", NULL,
+ Tk_Offset(FieldStruct, fill_color), 0,
ZN_DRAW_FLAG|ZN_BORDER_FLAG, False },
{ ZN_CONFIG_BORDER, "-border", NULL,
Tk_Offset(FieldStruct, border_edges), 0, ZN_COORDS_FLAG, False },
@@ -179,7 +183,8 @@ static char *attribute_type_strings[] = {
"joinstyle",
"capstyle",
"gradient",
- "window"
+ "window",
+ "alpha"
};
@@ -923,24 +928,34 @@ ConfigureAttributes(char *record,
case ZN_CONFIG_INT:
case ZN_CONFIG_UINT:
case ZN_CONFIG_ANGLE:
+ case ZN_CONFIG_ALPHA:
{
int integer;
if (Tcl_GetIntFromObj(wi->interp, args[i+1], &integer) == ZN_ERROR) {
return ZN_ERROR;
}
- if (desc->type == ZN_CONFIG_ANGLE) {
- if ((integer < 0) || (integer > 360)) {
- Tcl_AppendResult(wi->interp, " angle must be between 0 and 360 \"",
- Tcl_GetString(args[i+1]), "\"", NULL);
- return ZN_ERROR;
+ switch (desc->type) {
+ case ZN_CONFIG_ANGLE:
+ if (integer < 0) {
+ integer = 0;
}
- }
- else if (desc->type == ZN_CONFIG_UINT) {
+ if (integer > 360) {
+ integer = 360;
+ }
+ break;
+ case ZN_CONFIG_UINT:
if (integer < 0) {
- Tcl_AppendResult(wi->interp, " positive integer expected for \"",
- Tcl_GetString(args[i]), "\"", NULL);
- return ZN_ERROR;
+ integer = 0;
+ }
+ break;
+ case ZN_CONFIG_ALPHA:
+ if (integer < 0) {
+ integer = 0;
}
+ if (integer > 100) {
+ integer = 100;
+ }
+ break;
}
if (integer != *((int *) valp)) {
*((int *) valp) = integer;
@@ -1399,6 +1414,7 @@ AttributeToObj(WidgetInfo *wi,
case ZN_CONFIG_DIM:
case ZN_CONFIG_PRI:
case ZN_CONFIG_ANGLE:
+ case ZN_CONFIG_ALPHA:
Tcl_SetIntObj(result, *((int *) valp));
break;
case ZN_CONFIG_JUSTIFY:
@@ -3127,7 +3143,7 @@ PushClip(WidgetInfo *wi,
ZnBool simple,
ZnBool set_gc)
{
- int i, j, num_c;
+ int i, j, num_clips;
int num_pts, max_num_pts;
ZnPoint *p;
ClipState *previous_clip=NULL;
@@ -3150,12 +3166,12 @@ PushClip(WidgetInfo *wi,
return;
}
- num_c = ZnListSize(wi->clip_stack);
- /* printf("PushClip: num clips %d\n", num_c);fflush(stdout);*/
- if (num_c != 0) {
+ num_clips = ZnListSize(wi->clip_stack);
+ /* printf("PushClip: num clips %d\n", num_clips);fflush(stdout);*/
+ if (num_clips != 0) {
previous_clip = (ClipState *) ZnListAt(wi->clip_stack, ZnListTail);
}
- ZnListAssertSize(wi->clip_stack, num_c+1);
+ ZnListAssertSize(wi->clip_stack, num_clips+1);
wi->current_clip = (ClipState *) ZnListAt(wi->clip_stack, ZnListTail);
wi->current_clip->simple = simple;
@@ -3213,14 +3229,42 @@ PushClip(WidgetInfo *wi,
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);
+ if (wi->render) {
+#ifdef GLX
+ glEnable(GL_STENCIL_TEST);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glStencilFunc(GL_EQUAL, num_clips, 0xFF);
+ glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+#if 0
+ if (simple) {
+#endif
+ /* printf("Clip box is : %d, %d, %d, %d, num_clips : %d\n",
+ rect.x, rect.y, rect.width, rect.height, num_clips);*/
+ glBegin(GL_QUADS);
+ glVertex2f(wi->current_clip->clip_box.orig.x, wi->current_clip->clip_box.orig.y);
+ glVertex2f(wi->current_clip->clip_box.orig.x, wi->current_clip->clip_box.corner.y);
+ glVertex2f(wi->current_clip->clip_box.corner.x, wi->current_clip->clip_box.corner.y);
+ glVertex2f(wi->current_clip->clip_box.corner.x, wi->current_clip->clip_box.orig.y);
+ glEnd();
+#if 0
+ }
+ else {
+ }
+#endif
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glStencilFunc(GL_EQUAL, num_clips+1, 0xFF);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+#endif
+ }
+ else {
+ XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
+ }
}
}
@@ -3228,13 +3272,17 @@ static void
PopClip(WidgetInfo *wi,
ZnBool set_gc)
{
+ int num_clips;
+
if (wi->current_clip == NULL) {
return;
}
XDestroyRegion(wi->current_clip->region);
ZnListDelete(wi->clip_stack, ZnListTail);
- if (ZnListSize(wi->clip_stack) != 0) {
+ num_clips = ZnListSize(wi->clip_stack);
+
+ if (num_clips != 0) {
wi->current_clip = (ClipState *) ZnListAt(wi->clip_stack, ZnListTail);
}
else {
@@ -3245,12 +3293,46 @@ PopClip(WidgetInfo *wi,
* Set the clipping in the GC.
*/
if (set_gc) {
- if (wi->current_clip) {
- XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
+ if (num_clips != 0) {
+ if (wi->render) {
+#ifdef GLX
+ glStencilFunc(GL_EQUAL, num_clips+1, 0xFF);
+ glStencilOp(GL_KEEP, GL_DECR, GL_DECR);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+#if 0
+ if (wi->current_clip->simple) {
+#endif
+ glBegin(GL_QUADS);
+ glVertex2f(wi->current_clip->clip_box.orig.x, wi->current_clip->clip_box.orig.y);
+ glVertex2f(wi->current_clip->clip_box.orig.x, wi->current_clip->clip_box.corner.y);
+ glVertex2f(wi->current_clip->clip_box.corner.x, wi->current_clip->clip_box.corner.y);
+ glVertex2f(wi->current_clip->clip_box.corner.x, wi->current_clip->clip_box.orig.y);
+ glEnd();
+#if 0
+ }
+ else {
+ }
+#endif
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glStencilFunc(GL_EQUAL, num_clips, 0xFF);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+#endif
+ }
+ else {
+ XSetRegion(wi->dpy, wi->gc, wi->current_clip->region);
+ }
}
else {
/*printf("resetting clip mask\n");*/
- XSetClipMask(wi->dpy, wi->gc, None);
+ if (wi->render) {
+#ifdef GLX
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glDisable(GL_STENCIL_TEST);
+#endif
+ }
+ else {
+ XSetClipMask(wi->dpy, wi->gc, None);
+ }
}
}
/*printf("PopClip: num clips %d\n", ZnListSize(wi->clip_stack));fflush(stdout);*/
@@ -3631,7 +3713,7 @@ InitFields(FieldSet field_set)
field->field_set = field_set;
field->color = ZnGetColorByValue(wi->win, wi->fore_color);
- field->back_color = ZnGetColorByValue(wi->win, wi->back_color);
+ field->fill_color = ZnGetGradient(wi->interp, wi->win, ZnNameOfColor(wi->back_color));
field->border_color = ZnGetColorByValue(wi->win, wi->fore_color);
SET(field->flags, FIELD_VISIBLE_BIT);
SET(field->flags, FIELD_SENSITIVE_BIT);
@@ -3653,6 +3735,10 @@ InitFields(FieldSet field_set)
SET(field->flags, TEXT_ON_TOP_BIT);
field->gradient = NULL;
+ field->grad_geo = NULL;
+#ifdef GLX
+ field->txf = NULL;
+#endif
}
field_set->label_pos.x = field_set->label_pos.y = 0.0;
field_set->label_width = field_set->label_height = -1.0;
@@ -3690,7 +3776,8 @@ CloneFields(FieldSet field_set)
if (field->gradient) {
field->gradient = ZnGetGradientByValue(field->gradient);
}
-
+ field->grad_geo = NULL;
+
if (strlen(field->image_name) != 0) {
text = ZnMalloc((strlen(field->image_name) + 1) * sizeof(char));
strcpy(text, field->image_name);
@@ -3711,7 +3798,7 @@ CloneFields(FieldSet field_set)
}
field->font = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(field->font));
field->color = ZnGetColorByValue(wi->win, field->color);
- field->back_color = ZnGetColorByValue(wi->win, field->back_color);
+ field->fill_color = ZnGetGradientByValue(field->fill_color);
field->border_color = ZnGetColorByValue(wi->win, field->border_color);
if (strlen(field->text) != 0) {
@@ -3766,8 +3853,11 @@ 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));
- if (field_ptr->gradient) {
+ ZnNameOfColor(ZnGetGradientColor(wi->win,
+ field_ptr->fill_color,
+ 50.0,
+ NULL)));
+ if (field_ptr->gradient == NULL) {
return ZN_ERROR;
}
}
@@ -3889,6 +3979,9 @@ FreeFields(FieldSet field_set)
if (field->gradient) {
ZnFreeGradient(field->gradient);
}
+ if (field->grad_geo) {
+ ZnFree(field->grad_geo);
+ }
if (field->image != ZnUnspecifiedImage) {
Tk_FreeImage(field->image);
field->image = ZnUnspecifiedImage;
@@ -3910,7 +4003,7 @@ FreeFields(FieldSet field_set)
/*printf("freeing a font\n");*/
Tk_FreeFont(field->font);
ZnFreeColor(field->color);
- ZnFreeColor(field->back_color);
+ ZnFreeGradient(field->fill_color);
ZnFreeColor(field->border_color);
}
if (num_fields) {
@@ -3957,23 +4050,22 @@ ComputeFieldImageLocation(Field field_ptr,
/*
**********************************************************************************
*
- * DrawFields --
+ * FieldsEngine --
*
**********************************************************************************
*/
static void
-DrawFields(FieldSet field_set)
+FieldsEngine(FieldSet field_set,
+ void (*cb)())
{
WidgetInfo *wi = field_set->wi;
int i; /* This one *NEED* to be an int */
- int j, num;
+ int num;
Field field_ptr;
- XGCValues values;
ZnBBox label_clip_box, clip_bbox, bbox, *global_clip_box;
ZnBBox text_bbox, clip_text_bbox;
ZnPoint pts[2];
ZnPoly poly;
- XRectangle r;
ZnPoint text_pos;
ZnBBox pm_bbox, clip_pm_bbox;
ZnBool restore = False;
@@ -3986,10 +4078,19 @@ DrawFields(FieldSet field_set)
bbox.corner.x = field_set->label_pos.x + lwidth;
bbox.corner.y = field_set->label_pos.y + lheight;
CurrentClip(wi, NULL, &global_clip_box, NULL);
- IntersectBBox(global_clip_box, &bbox, &label_clip_box);
- if (IsEmptyBBox(&label_clip_box)) {
- return;
+#if GLX
+ if (!wi->render) {
+#endif
+ IntersectBBox(global_clip_box, &bbox, &label_clip_box);
+ if (IsEmptyBBox(&label_clip_box)) {
+ return;
+ }
+#if GLX
+ }
+ else {
+ label_clip_box = bbox;
}
+#endif
num = LabelFormatNumFields(field_set->label_format);
for (i = 0; i < num; i++) {
@@ -4058,131 +4159,161 @@ DrawFields(FieldSet field_set)
PushClip(wi, &poly, True, True);
}
- /*
- * Draw the background.
- */
- if (ISSET(field_ptr->flags, FILLED_BIT)) {
- values.foreground = ZnPixel(field_ptr->back_color);
-
- if (field_ptr->tile != ZnUnspecifiedImage) { /* Fill tiled */
- Pixmap pmap = GetImagePixmap(wi->win, field_ptr->tile_name,
- field_ptr->tile, NULL);
- values.fill_style = FillTiled;
- values.tile = pmap;
- values.ts_x_origin = (int) bbox.orig.x;
- values.ts_y_origin = (int) bbox.orig.y;
- XChangeGC(wi->dpy, wi->gc,
- GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCTile,
- &values);
- }
- else if (field_ptr->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */
- values.fill_style = FillStippled;
- values.stipple = field_ptr->fill_pattern;
- values.ts_x_origin = (int) bbox.orig.x;
- values.ts_y_origin = (int) bbox.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);
- }
- BBox2XRect(&clip_bbox, &r);
- XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height);
- }
+ (*cb)(wi, field_ptr, &bbox, &clip_bbox, &pm_bbox, &clip_pm_bbox, &text_pos);
- /*
- * Draw the image and the text, whichever is in back depends on
- * the value of text_on_top.
- */
- for (j = 0; j < 2; j++) {
- if ((j == 0 && ISSET(field_ptr->flags, TEXT_ON_TOP_BIT)) ||
- (j == 1 && ISCLEAR(field_ptr->flags, TEXT_ON_TOP_BIT))) {
- /*
- * Draw the image.
- */
- if (field_ptr->image != ZnUnspecifiedImage) {
- Tk_RedrawImage(field_ptr->image,
- clip_pm_bbox.orig.x-pm_bbox.orig.x,
- clip_pm_bbox.orig.y-pm_bbox.orig.y,
- REAL_TO_INT(clip_pm_bbox.corner.x-clip_pm_bbox.orig.x),
- REAL_TO_INT(clip_pm_bbox.corner.y-clip_pm_bbox.orig.y),
- wi->draw_buffer,
- clip_pm_bbox.orig.x, clip_pm_bbox.orig.y);
- }
- }
- else {
- /*
- * Draw the text.
- */
- if (field_ptr->text && strlen(field_ptr->text)) {
- values.foreground = ZnPixel(field_ptr->color);
- values.fill_style = FillSolid;
- values.font = ZnFontId(field_ptr->font);
- XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle | GCFont, &values);
- Tk_DrawChars(wi->dpy, wi->draw_buffer, wi->gc, field_ptr->font,
- field_ptr->text, strlen(field_ptr->text),
- text_pos.x, text_pos.y);
- }
- }
+ if (restore) {
+ /* Restore the previous clip. */
+ PopClip(wi, True);
+ restore = False;
}
+ }
+ }
+}
+
- BBox2XRect(&bbox, &r);
+/*
+ **********************************************************************************
+ *
+ * DrawFields --
+ *
+ **********************************************************************************
+ */
+void
+DrawField(WidgetInfo *wi,
+ Field field_ptr,
+ ZnBBox *bbox,
+ ZnBBox *clip_bbox,
+ ZnBBox *pm_bbox,
+ ZnBBox *clip_pm_bbox,
+ ZnPoint *text_pos)
+{
+ XGCValues values;
+ XRectangle r;
+ int j;
+
+ /*
+ * Draw the background.
+ */
+ if (ISSET(field_ptr->flags, FILLED_BIT)) {
+ values.foreground = ZnPixel(ZnGetGradientColor(wi->win, field_ptr->fill_color, 0.0, NULL));
+
+ if (field_ptr->tile != ZnUnspecifiedImage) { /* Fill tiled */
+ Pixmap pmap = GetImagePixmap(wi->win, field_ptr->tile_name,
+ field_ptr->tile, NULL);
+ values.fill_style = FillTiled;
+ values.tile = pmap;
+ values.ts_x_origin = (int) bbox->orig.x;
+ values.ts_y_origin = (int) bbox->orig.y;
+ XChangeGC(wi->dpy, wi->gc,
+ GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCTile,
+ &values);
+ }
+ else if (field_ptr->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */
+ values.fill_style = FillStippled;
+ values.stipple = field_ptr->fill_pattern;
+ values.ts_x_origin = (int) bbox->orig.x;
+ values.ts_y_origin = (int) bbox->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);
+ }
+ BBox2XRect(clip_bbox, &r);
+ XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height);
+ }
+
+ /*
+ * Draw the image and the text, which is in back depends on
+ * the value of text_on_top.
+ */
+ for (j = 0; j < 2; j++) {
+ if ((j == 0 && ISSET(field_ptr->flags, TEXT_ON_TOP_BIT)) ||
+ (j == 1 && ISCLEAR(field_ptr->flags, TEXT_ON_TOP_BIT))) {
/*
- * Draw the border relief.
+ * Draw the image.
*/
- if ((field_ptr->relief != RELIEF_FLAT) && (field_ptr->relief_thickness > 1)) {
- DrawRectangleRelief(wi, field_ptr->relief, field_ptr->gradient,
- &r, (unsigned int) field_ptr->relief_thickness);
+ if (field_ptr->image != ZnUnspecifiedImage) {
+ Tk_RedrawImage(field_ptr->image,
+ clip_pm_bbox->orig.x - pm_bbox->orig.x,
+ clip_pm_bbox->orig.y - pm_bbox->orig.y,
+ REAL_TO_INT(clip_pm_bbox->corner.x - clip_pm_bbox->orig.x),
+ REAL_TO_INT(clip_pm_bbox->corner.y - clip_pm_bbox->orig.y),
+ wi->draw_buffer,
+ clip_pm_bbox->orig.x, clip_pm_bbox->orig.y);
}
-
+ }
+ else {
/*
- * Draw the border line.
+ * Draw the text.
*/
- if (field_ptr->border_edges != NO_BORDER) {
- values.foreground = ZnPixel(field_ptr->border_color);
- values.line_width = 0;
- values.line_style = LineSolid;
+ if (field_ptr->text && strlen(field_ptr->text)) {
+ values.foreground = ZnPixel(field_ptr->color);
values.fill_style = FillSolid;
- XChangeGC(wi->dpy, wi->gc,
- GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, &values);
- if (field_ptr->border_edges & LEFT_BORDER) {
- XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y,
- r.x, r.y + r.height - 1);
- }
- if (field_ptr->border_edges & RIGHT_BORDER) {
- XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
- r.x + r.width - 1, r.y,
- r.x + r.width - 1, r.y + r.height - 1);
- }
- if (field_ptr->border_edges & TOP_BORDER) {
- XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
- r.x, r.y, r.x + r.width - 1, r.y);
- }
- if (field_ptr->border_edges & BOTTOM_BORDER) {
- XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
- r.x, r.y + r.height - 1,
- r.x + r.width - 1, r.y + r.height - 1);
- }
- if (field_ptr->border_edges & OBLIQUE) {
- XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
- r.x, r.y, r.x + r.width - 1, r.y + r.height - 1);
- }
- if (field_ptr->border_edges & COUNTER_OBLIQUE) {
- XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
- r.x, r.y + r.height - 1,
- r.x + r.width - 1, r.y);
- }
- }
-
- if (restore) {
- /* Restore the previous clip. */
- PopClip(wi, True);
- restore = False;
+ values.font = ZnFontId(field_ptr->font);
+ XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle | GCFont, &values);
+ Tk_DrawChars(wi->dpy, wi->draw_buffer, wi->gc, field_ptr->font,
+ field_ptr->text, strlen(field_ptr->text),
+ text_pos->x, text_pos->y);
}
}
}
+
+ BBox2XRect(bbox, &r);
+ /*
+ * Draw the border relief.
+ */
+ if ((field_ptr->relief != RELIEF_FLAT) && (field_ptr->relief_thickness > 1)) {
+ DrawRectangleRelief(wi, field_ptr->relief, field_ptr->gradient,
+ &r, (unsigned int) field_ptr->relief_thickness);
+ }
+
+ /*
+ * Draw the border line.
+ */
+ if (field_ptr->border_edges != NO_BORDER) {
+ values.foreground = ZnPixel(field_ptr->border_color);
+ values.line_width = 0;
+ values.line_style = LineSolid;
+ values.fill_style = FillSolid;
+ XChangeGC(wi->dpy, wi->gc,
+ GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, &values);
+ if (field_ptr->border_edges & LEFT_BORDER) {
+ XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y,
+ r.x, r.y + r.height - 1);
+ }
+ if (field_ptr->border_edges & RIGHT_BORDER) {
+ XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
+ r.x + r.width - 1, r.y,
+ r.x + r.width - 1, r.y + r.height - 1);
+ }
+ if (field_ptr->border_edges & TOP_BORDER) {
+ XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
+ r.x, r.y, r.x + r.width - 1, r.y);
+ }
+ if (field_ptr->border_edges & BOTTOM_BORDER) {
+ XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
+ r.x, r.y + r.height - 1,
+ r.x + r.width - 1, r.y + r.height - 1);
+ }
+ if (field_ptr->border_edges & OBLIQUE) {
+ XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
+ r.x, r.y, r.x + r.width - 1, r.y + r.height - 1);
+ }
+ if (field_ptr->border_edges & COUNTER_OBLIQUE) {
+ XDrawLine(wi->dpy, wi->draw_buffer, wi->gc,
+ r.x, r.y + r.height - 1,
+ r.x + r.width - 1, r.y);
+ }
+ }
+}
+
+static void
+DrawFields(FieldSet field_set)
+{
+ FieldsEngine(field_set, DrawField);
}
@@ -4193,11 +4324,165 @@ DrawFields(FieldSet field_set)
*
**********************************************************************************
*/
+void
+FieldRenderCB(void *closure)
+{
+#ifdef GLX
+ ZnBBox *bbox = (ZnBBox *) closure;
+
+ glBegin(GL_QUADS);
+ glVertex2f(bbox->orig.x, bbox->orig.y);
+ glVertex2f(bbox->orig.x, bbox->corner.y);
+ glVertex2f(bbox->corner.x, bbox->corner.y);
+ glVertex2f(bbox->corner.x, bbox->orig.y);
+ glEnd();
+#endif
+}
+
+void
+RenderField(WidgetInfo *wi,
+ Field field_ptr,
+ ZnBBox *bbox,
+ ZnBBox *clip_bbox,
+ ZnBBox *pm_bbox,
+ ZnBBox *clip_pm_bbox,
+ ZnPoint *text_pos)
+{
+#ifdef GLX
+ int j;
+ XColor *color;
+ int alpha;
+
+ /*
+ * Draw the background.
+ */
+ if (ISSET(field_ptr->flags, FILLED_BIT)) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ if (!ZnGradientFlat(field_ptr->fill_color)) {
+ int type = field_ptr->fill_color->type;
+ ZnBool fast = (type == ZN_AXIAL_GRADIENT) && !field_ptr->grad_geo;
+#if 0
+ RenderGradient(wi, field_ptr->fill_color,
+ fast ? NULL : FieldRenderCB,
+ bbox, fast ? (ZnPoint *) bbox : field_ptr->grad_geo);
+#endif
+ }
+ else {
+ if (field_ptr->tile != ZnUnspecifiedImage) { /* Fill tiled */
+ RenderTile(wi, GetImageTexture(wi->win, field_ptr->tile_name, field_ptr->tile),
+ field_ptr->fill_color, FieldRenderCB, bbox, (ZnPoint *) bbox);
+ }
+ else { /* Fill solid */
+ if (field_ptr->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */
+ /*
+ * Setup polygon stippling.
+ */
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(GetBitmapMask(wi->dpy, field_ptr->fill_pattern)->pixels);
+ }
+ color = ZnGetGradientColor(wi->win, field_ptr->fill_color, 0.0, &alpha);
+ glColor4us(color->red, color->green, color->blue, alpha*65535/100);
+ FieldRenderCB(clip_bbox);
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ }
+ }
+
+ /*
+ * Draw the image and the text, which is in back depends on
+ * the value of text_on_top.
+ */
+ for (j = 0; j < 2; j++) {
+ if ((j == 0 && ISSET(field_ptr->flags, TEXT_ON_TOP_BIT)) ||
+ (j == 1 && ISCLEAR(field_ptr->flags, TEXT_ON_TOP_BIT))) {
+ /*
+ * Draw the image.
+ */
+ if (field_ptr->image != ZnUnspecifiedImage) {
+ RenderImage(wi, GetImageTexture(wi->win, field_ptr->image_name, field_ptr->image),
+ NULL, 255, &(pm_bbox->orig));
+ }
+ }
+ else {
+ /*
+ * Draw the text.
+ */
+ if (field_ptr->text && strlen(field_ptr->text)) {
+ if (!field_ptr->txf) {
+ field_ptr->txf = GetTexFont(wi->win, field_ptr->font);
+ }
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ color = field_ptr->color;
+ glColor4us(color->red, color->green, color->blue, 65535);
+ glBindTexture(GL_TEXTURE_2D, field_ptr->txf->texobj);
+ glPushMatrix();
+ glTranslatef(text_pos->x, text_pos->y, 0.0);
+ txfRenderString(field_ptr->txf, field_ptr->text, strlen(field_ptr->text));
+ glPopMatrix();
+ glDisable(GL_TEXTURE_2D);
+ }
+ }
+ }
+
+ /*
+ * Draw the border relief.
+ */
+ if ((field_ptr->relief != RELIEF_FLAT) && (field_ptr->relief_thickness > 1)) {
+ ZnPoint p[5];
+ p[0] = bbox->orig;
+ p[2] = bbox->corner;
+ p[3].x = p[0].x;
+ p[3].y = p[2].y;
+ p[1].x = p[2].x;
+ p[1].y = p[0].y;
+ p[4] = p[0];
+ RenderPolygonRelief(wi, field_ptr->relief, field_ptr->gradient,
+ 255, 0, p, 5, field_ptr->relief_thickness);
+ }
+
+ /*
+ * Draw the border line.
+ */
+ if (field_ptr->border_edges != NO_BORDER) {
+ color = field_ptr->border_color;
+ glColor4us(color->red, color->green, color->blue, 65535);
+ glLineWidth(1);
+ glBegin(GL_LINES);
+ if (field_ptr->border_edges & LEFT_BORDER) {
+ glVertex2f(bbox->orig.x, bbox->orig.y);
+ glVertex2f(bbox->orig.x, bbox->corner.y);
+ }
+ if (field_ptr->border_edges & RIGHT_BORDER) {
+ glVertex2f(bbox->corner.x, bbox->orig.y);
+ glVertex2f(bbox->corner.x, bbox->corner.y);
+ }
+ if (field_ptr->border_edges & TOP_BORDER) {
+ glVertex2f(bbox->orig.x, bbox->orig.y);
+ glVertex2f(bbox->corner.x, bbox->orig.y);
+ }
+ if (field_ptr->border_edges & BOTTOM_BORDER) {
+ glVertex2f(bbox->orig.x, bbox->corner.y);
+ glVertex2f(bbox->corner.x, bbox->corner.y);
+ }
+ if (field_ptr->border_edges & OBLIQUE) {
+ glVertex2f(bbox->orig.x, bbox->orig.y);
+ glVertex2f(bbox->corner.x, bbox->corner.y);
+ }
+ if (field_ptr->border_edges & COUNTER_OBLIQUE) {
+ glVertex2f(bbox->orig.x, bbox->corner.y);
+ glVertex2f(bbox->corner.x, bbox->orig.y);
+ }
+ glEnd();
+ }
+#endif
+}
+
static void
RenderFields(FieldSet field_set)
{
- /* WidgetInfo *wi = field_set->wi;*/
-
+ FieldsEngine(field_set, RenderField);
}
@@ -4417,132 +4702,6 @@ Update(WidgetInfo *wi)
}
-#ifdef LIBART
-#ifdef SHM
-static void
-EnsureRGBBuf(WidgetInfo *wi,
- int r,
- int g,
- int b)
-{
- unsigned char *ptr;
- int y;
-
- ptr = wi->buf.buf;
- for (y = wi->buf.oy; y < wi->buf.cy; y++) {
- art_rgb_fill_run(ptr, r, g, b, wi->buf.cx - wi->buf.ox);
- ptr += wi->buf.rowstride;
- }
-}
-
-static void
-RenderSVP(WidgetInfo *wi,
- ArtSVP *svp,
- int r,
- int g,
- int b,
- int alpha,
- int tile_x,
- int tile_y,
- ArtPixBuf *tile)
-{
- if (tile) {
- tile_svp_alpha(svp, wi->buf.ox, wi->buf.oy,
- wi->buf.cx, wi->buf.cy,
- tile_x, tile_y, tile, alpha,
- wi->buf.buf, wi->buf.rowstride);
- }
- else {
- art_rgb_svp_alpha(svp,
- wi->buf.ox, wi->buf.oy,
- wi->buf.cx, wi->buf.cy,
- ((r & 0xff00) << 16) | ((g & 0xff00) << 8) |
- (b & 0xff00) | (alpha & 0xff),
- wi->buf.buf, wi->buf.rowstride, NULL);
- }
-}
-
-
-/*
- * Working only for 16 bits displays with 5r6g5b mask.
- */
-static void
-RGBToXImage(WidgetInfo *wi,
- int x0,
- int y0,
- int width,
- int height)
-{
- int x, y;
- int rowstride;
- art_u8 *obuf, *obptr;
- int bpl;
- art_u8 *bptr, *bp2;
- art_u8 r, g, b;
-
- /*printf("RGBToXImage: x0 %d, y0 %d, width %d, height %d, wwidth %d, wheight %d\n",
- x0, y0, width, height, wi->width, wi->height);*/
- rowstride = wi->buf.rowstride;
- bptr = wi->buf.buf/* + y0 * rowstride + x0 * 3*/;
- bpl = wi->draw_buffer_im->bytes_per_line;
- obuf = ((art_u8 *) wi->draw_buffer_im->data) + y0 * bpl + x0 * 2;
- for (y = 0; y < height; y++) {
- bp2 = bptr;
- obptr = obuf;
- if (((unsigned long) obuf | (unsigned long) bp2) & 3) {
- for (x = 0; x < width; x++) {
- r = *bp2++;
- g = *bp2++;
- b = *bp2++;
- ((art_u16 *)obptr)[0] = ((r & 0xf8) << 8) |
- ((g & 0xfc) << 3) |
- (b >> 3);
- obptr += 2;
- }
- }
- else {
- for (x = 0; x < width - 3; x += 4) {
- art_u32 r1b0g0r0;
- art_u32 g2r2b1g1;
- art_u32 b3g3r3b2;
-
- r1b0g0r0 = ((art_u32 *)bp2)[0];
- g2r2b1g1 = ((art_u32 *)bp2)[1];
- b3g3r3b2 = ((art_u32 *)bp2)[2];
- ((art_u32 *)obptr)[0] =
- ((r1b0g0r0 & 0xf8) << 8) |
- ((r1b0g0r0 & 0xfc00) >> 5) |
- ((r1b0g0r0 & 0xf80000) >> 19) |
- (r1b0g0r0 & 0xf8000000) |
- ((g2r2b1g1 & 0xfc) << 19) |
- ((g2r2b1g1 & 0xf800) << 5);
- ((art_u32 *)obptr)[1] =
- ((g2r2b1g1 & 0xf80000) >> 8) |
- ((g2r2b1g1 & 0xfc000000) >> 21) |
- ((b3g3r3b2 & 0xf8) >> 3) |
- ((b3g3r3b2 & 0xf800) << 16) |
- ((b3g3r3b2 & 0xfc0000) << 3) |
- ((b3g3r3b2 & 0xf8000000) >> 11);
- bp2 += 12;
- obptr += 8;
- }
- for (; x < width; x++) {
- r = *bp2++;
- g = *bp2++;
- b = *bp2++;
- ((art_u16 *)obptr)[0] = ((r & 0xf8) << 8) |
- ((g & 0xfc) << 3) |
- (b >> 3);
- obptr += 2;
- }
- }
- bptr += rowstride;
- obuf += bpl;
- }
-}
-#endif
-#endif
-
static void
Repair(WidgetInfo *wi)
{
@@ -4555,62 +4714,76 @@ Repair(WidgetInfo *wi)
there is something to update. */
if (wi->realized && !IsEmptyBBox(&wi->damaged_area)) {
- /* Set the whole damaged area as clip rect. */
- wi->damaged_area.orig.x = r.x = REAL_TO_INT(wi->damaged_area.orig.x);
- wi->damaged_area.orig.y = r.y = REAL_TO_INT(wi->damaged_area.orig.y);
- wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x);
- 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;
- pts[0] = wi->damaged_area.orig;
- pts[1] = wi->damaged_area.corner;
- POLY_CONTOUR1(&poly, pts, 2);
- PushClip(wi, &poly, True, True);
-
if (wi->render) {
-#ifdef LIBART
- /* if (wi->tile == ZnUnspecifiedImage) {
- * }
- * else {
- * }*/
-
- wi->buf.ox = (int) wi->damaged_area.orig.x;
- wi->buf.oy = (int) wi->damaged_area.orig.y;
- wi->buf.cx = (int) wi->damaged_area.corner.x;
- wi->buf.cy = (int) wi->damaged_area.corner.y;
- EnsureRGBBuf(wi,
- wi->back_color->red >> 8,
- wi->back_color->green >> 8,
- wi->back_color->blue >> 8);
- wi->top_group->class->Render(wi->top_group);
- RGBToXImage(wi, r.x, r.y, r.width, r.height);
-#endif
#ifdef GLX
+ ZnReal int_width, int_height;
+
+ int_width = Tk_Width(wi->win) - 2*wi->inset;
+ int_height = Tk_Height(wi->win) - 2*wi->inset;
+
+ /*
+ * We do not use the samaged area for GL rendering,
+ * set it to the whole area.
+ */
+ wi->damaged_area.orig.x = wi->damaged_area.orig.y = 0.0;
+ wi->damaged_area.corner.x = int_width;
+ wi->damaged_area.corner.y = int_height;
+
/* Set the viewport (should be moved to the resize code) */
/*glViewport(0, 0, (GLsizei) Tk_Width(wi->win), (GLsizei) Tk_Height(wi->win));*/
- glViewport(wi->inset, wi->inset,
- (GLsizei) Tk_Width(wi->win) - 2*wi->inset,
- (GLsizei) Tk_Height(wi->win) - 2*wi->inset);
+ glViewport(wi->inset, wi->inset, (GLsizei) int_width, (GLsizei) int_height);
/* Set the base coord system to the X device coord system. */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- gluOrtho2D(0.0, (GLdouble) Tk_Width(wi->win),
- (GLdouble) Tk_Height(wi->win), 0.0);
+ gluOrtho2D(0.0, int_width, int_height, 0.0);
+ glMatrixMode(GL_MODELVIEW);
/* Clear the GL buffers. */
glClearColor(wi->back_color->red/65536.0, wi->back_color->green/65536.0,
wi->back_color->blue/65536.0, 0.0);
glClearStencil(0);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_BLEND);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ /*
+ * Setup the background tile if needed.
+ */
+ if (wi->tile != ZnUnspecifiedImage) {
+ ZnBBox bbox;
+
+ bbox.orig.x = bbox.orig.y = 0.0;
+ bbox.corner.x = int_width;
+ bbox.corner.y = int_height;
+
+ RenderTile(wi, GetImageTexture(wi->win, wi->tile_name, wi->tile),
+ NULL, NULL, NULL, (ZnPoint *) &bbox);
+ }
+
+ glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+#if 0
+ glEnable(GL_POLYGON_SMOOTH); /* expensive ? */
+#endif
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
wi->top_group->class->Render(wi->top_group);
glFlush();
#endif
}
else {
+ /* Set the whole damaged area as clip rect. */
+ wi->damaged_area.orig.x = r.x = REAL_TO_INT(wi->damaged_area.orig.x);
+ wi->damaged_area.orig.y = r.y = REAL_TO_INT(wi->damaged_area.orig.y);
+ wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x);
+ 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;
+ pts[0] = wi->damaged_area.orig;
+ pts[1] = wi->damaged_area.corner;
+ POLY_CONTOUR1(&poly, pts, 2);
+ PushClip(wi, &poly, True, True);
+
/* Fill the background of the double buffer pixmap. */
if (wi->tile == ZnUnspecifiedImage) {
values.foreground = ZnPixel(wi->back_color);
@@ -4631,9 +4804,9 @@ Repair(WidgetInfo *wi)
/* Draw the items */
/*printf("Drawing\n");*/
wi->top_group->class->Draw(wi->top_group);
- }
- PopClip(wi, True);
+ PopClip(wi, True);
+ }
}
}
@@ -4678,9 +4851,6 @@ struct _ITEM_P ITEM_P = {
PushClip,
PopClip,
CurrentClip,
-#ifdef LIBART
- RenderSVP
-#endif
};
struct _ITEM ITEM = {