diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Item.c | 816 |
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 = { |