From 960cdf29197bc3f5922110cf26627aa9709ac79b Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Fri, 10 Jun 2005 10:29:11 +0000 Subject: This commit was manufactured by cvs2svn to create branch 'bogue40'. --- generic/Field.c | 2584 ------------------------------------------------------- 1 file changed, 2584 deletions(-) delete mode 100644 generic/Field.c (limited to 'generic/Field.c') diff --git a/generic/Field.c b/generic/Field.c deleted file mode 100644 index e0a428f..0000000 --- a/generic/Field.c +++ /dev/null @@ -1,2584 +0,0 @@ -/* - * Field.c -- Implementation of fields. - * - * Authors : Patrick Lecoanet. - * Creation date : - * - * $Id$ - */ - -/* - * Copyright (c) 1993 - 2005 CENA, Patrick Lecoanet -- - * - * See the file "Copyright" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - */ - - -#include "Item.h" -#include "Types.h" -#include "WidgetInfo.h" -#include "Draw.h" -#include "Geo.h" -#include "tkZinc.h" - -#include -#include - - -static const char rcsid[] = "$Id$"; -static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; - - -#define FIELD_SENSITIVE_BIT 1 -#define FIELD_VISIBLE_BIT 2 -#define FILLED_BIT 4 -#define TEXT_ON_TOP_BIT 8 -#define CACHE_OK 16 - - -/* - * Field record. - */ -typedef struct _FieldStruct { - /* Public data */ - ZnGradient *color; - ZnGradient *fill_color; - ZnGradient *border_color; - char *text; - ZnImage image; - ZnImage tile; - Tk_Font font; - unsigned short flags; - ZnBorder border_edges; - Tk_Justify alignment; - ZnReliefStyle relief; - ZnDim relief_thickness; - ZnAutoAlign auto_alignment; - - /* Private data */ - ZnGradient *gradient; - ZnPoint *grad_geo; - short orig_x; - short orig_y; - short corner_x; - short corner_y; - int insert_index; -#ifdef GL - ZnTexFontInfo *tfi; -#endif -} FieldStruct, *Field; - - -/* - * The -text, -image, -border, -relief, -visible and - * -filled attributes set the ZN_COORDS_FLAG to update - * the leader that might protude if not clipped by the text. - */ -ZnAttrConfig field_attrs[] = { - { ZN_CONFIG_ALIGNMENT, "-alignment", NULL, - Tk_Offset(FieldStruct, alignment), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_AUTO_ALIGNMENT, "-autoalignment", NULL, - Tk_Offset(FieldStruct, auto_alignment), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-backcolor", NULL, - Tk_Offset(FieldStruct, fill_color), 0, - ZN_DRAW_FLAG|ZN_BORDER_FLAG, False }, - { ZN_CONFIG_EDGE_LIST, "-border", NULL, - Tk_Offset(FieldStruct, border_edges), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-bordercolor", NULL, - Tk_Offset(FieldStruct, border_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-color", NULL, - Tk_Offset(FieldStruct, color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-filled", NULL, - Tk_Offset(FieldStruct, flags), FILLED_BIT, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BITMAP, "-fillpattern", NULL, - Tk_Offset(FieldStruct, tile), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_FONT, "-font", NULL, - Tk_Offset(FieldStruct, font), 0, ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_IMAGE, "-image", NULL, - Tk_Offset(FieldStruct, image), 0, - ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_RELIEF, "-relief", NULL, - Tk_Offset(FieldStruct, relief), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-reliefthickness", NULL, - Tk_Offset(FieldStruct, relief_thickness), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-sensitive", NULL, - Tk_Offset(FieldStruct, flags), - FIELD_SENSITIVE_BIT, ZN_REPICK_FLAG, False }, - { ZN_CONFIG_STRING, "-text", NULL, - Tk_Offset(FieldStruct, text), 0, ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_IMAGE, "-tile", NULL, - Tk_Offset(FieldStruct, tile), 0, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_BOOL, "-visible", NULL, - Tk_Offset(FieldStruct, flags), FIELD_VISIBLE_BIT, - ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, /* Keep ZN_COORDS_FLAG here */ - - { ZN_CONFIG_END, NULL, NULL, 0, 0, 0, False } -}; - -static void GetLabelBBox(ZnFieldSet field_set, ZnDim *w, ZnDim *h); - - - -/* - ********************************************************************************** - * - * ComputeFieldAttachment -- - * Compute the location/size of the field, computing attachments if any. - * - ********************************************************************************** - */ -static void -ComputeFieldAttachment(ZnFieldSet field_set, - unsigned int field, - ZnBBox *field_bbox) -{ - - ZnBBox ref_bbox; - ZnDim real_width, real_height; - unsigned int ref_field, num_fields; - char x_attach, y_attach, x_dim, y_dim; - short width_spec, height_spec; - int x_spec, y_spec, icon_width=0, icon_height=0; - Field fptr; - Tk_FontMetrics fm; - - /*printf("ComputeFieldAttachment in\n");*/ - fptr = &field_set->fields[field]; - if (ISSET(fptr->flags, CACHE_OK)) { - field_bbox->orig.x = (ZnPos) fptr->orig_x; - field_bbox->orig.y = (ZnPos) fptr->orig_y; - field_bbox->corner.x = fptr->corner_x; - field_bbox->corner.y = fptr->corner_y; - /*printf("ComputeFieldAttachment in cache\n");*/ - return; - } - - /* - * Preset this field to a default position/size and pretend - * its cache is ok to break any deadlocks. - */ - fptr->orig_x = fptr->orig_y = 0; - fptr->corner_x = fptr->corner_y = 0; - field_bbox->orig.x = field_bbox->orig.y = 0; - field_bbox->corner.x = field_bbox->corner.y = 0; - SET(fptr->flags, CACHE_OK); - - num_fields = ZnLFNumFields(field_set->label_format); - ZnLFGetField(field_set->label_format, field, - &x_attach, &y_attach, &x_dim, &y_dim, - &x_spec, &y_spec, &width_spec, &height_spec); - - /* - * First try to compute the field size which may be a factor - * of the field content (but not a factor of other fields). - */ - if ((fptr->image != ZnUnspecifiedImage) && - ((x_dim == ZN_LF_DIM_ICON) || (y_dim == ZN_LF_DIM_ICON) || - (x_dim == ZN_LF_DIM_AUTO) || (y_dim == ZN_LF_DIM_AUTO))) { - ZnSizeOfImage(fptr->image, &icon_width, &icon_height); - } - - switch (x_dim) { - case ZN_LF_DIM_FONT: - real_width = (ZnDim) (width_spec*Tk_TextWidth(fptr->font, "N", 1)/100); - break; - case ZN_LF_DIM_ICON: - real_width = (ZnDim) (width_spec*icon_width/100); - break; - case ZN_LF_DIM_AUTO: - { - int len = 0; - ZnDim text_width; - - if (fptr->text) { - len = strlen(fptr->text); - } - real_width = 0.0; - if (fptr->image != ZnUnspecifiedImage) { - real_width = (ZnDim) icon_width; - } - if (len) { - /* - * The 4 extra pixels are needed for border and padding. - */ - text_width = (ZnDim) Tk_TextWidth(fptr->font, fptr->text, len) + 4; - real_width = text_width < real_width ? real_width : text_width; - } - real_width += (ZnDim) width_spec; - break; - } - case ZN_LF_DIM_LABEL: - { - ZnDim lh; - - GetLabelBBox(field_set, &real_width, &lh); - break; - } - case ZN_LF_DIM_PIXEL: - default: - real_width = (ZnDim) width_spec; - break; - } - /*printf("field %d, width = %g\n", field, real_width);*/ - - switch (y_dim) { - case ZN_LF_DIM_FONT: - { - Tk_GetFontMetrics(fptr->font, &fm); - real_height = (ZnDim) (height_spec*(fm.ascent + fm.descent)/100); - break; - } - case ZN_LF_DIM_ICON: - real_height = (ZnDim) (height_spec*icon_height/100); - break; - case ZN_LF_DIM_AUTO: - { - ZnDim text_height; - - real_height = 0.0; - if (fptr->image != ZnUnspecifiedImage) { - real_height = (ZnDim) icon_height; - } - if (fptr->text && strlen(fptr->text)) { - Tk_GetFontMetrics(fptr->font, &fm); - text_height = (ZnDim) (fm.ascent + fm.descent); - real_height = text_height < real_height ? real_height : text_height; - } - real_height += (ZnDim) height_spec; - break; - } - case ZN_LF_DIM_LABEL: - { - ZnDim lw; - - GetLabelBBox(field_set, &lw, &real_height); - break; - } - case ZN_LF_DIM_PIXEL: - default: - real_height = (ZnDim) height_spec; - break; - } - /*printf("field %d, height = %g\n", field, real_height);*/ - - /* - * Update the cache with the newly computed infos - * (breaking of deadlocks). - */ - field_bbox->corner.x = real_width; - field_bbox->corner.y = real_height; - fptr->corner_x = (short) real_width; - fptr->corner_y = (short) real_height; - - /* - * Then try to deduce the position, resolving any attachments - * if needed. - */ - - /* - * Do the x axis. - */ - if (x_dim != ZN_LF_DIM_LABEL) { - if (x_attach == ZN_LF_ATTACH_PIXEL) { - field_bbox->orig.x = (ZnPos) x_spec; - field_bbox->corner.x = field_bbox->orig.x + real_width; - } - else { - ref_field = x_spec; - field_bbox->orig.x = field_bbox->corner.x = 0; - if (ref_field >= num_fields) { - ZnWarning ("Attached (x) to an inexistant field geometry\n"); - } - else { - ComputeFieldAttachment(field_set, ref_field, &ref_bbox); - switch (x_attach) { - case ZN_LF_ATTACH_FWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->orig.x = ref_bbox.corner.x; - } - else { - field_bbox->orig.x = ref_bbox.orig.x; - } - field_bbox->corner.x = field_bbox->orig.x + real_width; - break; - case ZN_LF_ATTACH_BWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.x = ref_bbox.orig.x; - } - else { - field_bbox->corner.x = ref_bbox.corner.x; - } - field_bbox->orig.x = field_bbox->corner.x - real_width; - break; - case ZN_LF_ATTACH_LEFT: - field_bbox->orig.x = ref_bbox.orig.x; - field_bbox->corner.x = field_bbox->orig.x + real_width; - break; - case ZN_LF_ATTACH_RIGHT: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.x = ref_bbox.corner.x; - } - else { - field_bbox->corner.x = ref_bbox.orig.x; - } - field_bbox->orig.x = field_bbox->corner.x - real_width; - break; - } - } - } - /*printf("field %d, x = %g\n", field, field_bbox->orig.x);*/ - } - - /* - * Then the y axis. - */ - if (y_dim != ZN_LF_DIM_LABEL) { - if (y_attach == ZN_LF_ATTACH_PIXEL) { - field_bbox->orig.y = (ZnPos) y_spec; - field_bbox->corner.y = field_bbox->orig.y + real_height; - } - else { - ref_field = y_spec; - field_bbox->orig.y = field_bbox->corner.y = 0; - if (ref_field >= num_fields) { - ZnWarning ("Attached (y) to an inexistant field geometry\n"); - } - else { - ComputeFieldAttachment(field_set, ref_field, &ref_bbox); - switch (y_attach) { - case ZN_LF_ATTACH_FWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->orig.y = ref_bbox.corner.y; - } - else { - field_bbox->orig.y = ref_bbox.orig.y; - } - field_bbox->corner.y = field_bbox->orig.y + real_height; - break; - case ZN_LF_ATTACH_BWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.y = ref_bbox.orig.y; - } - else { - field_bbox->corner.y = ref_bbox.corner.y; - } - field_bbox->orig.y = field_bbox->corner.y - real_height; - break; - case ZN_LF_ATTACH_LEFT: - field_bbox->orig.y = ref_bbox.orig.y; - field_bbox->corner.y = field_bbox->orig.y + real_height; - break; - case ZN_LF_ATTACH_RIGHT: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.y = ref_bbox.corner.y; - } - else { - field_bbox->corner.y = ref_bbox.orig.y; - } - field_bbox->orig.y = field_bbox->corner.y - real_height; - break; - } - } - } - /*printf("field %d, y = %g\n", field, field_bbox->orig.y);*/ - } - - fptr->orig_x = (short) field_bbox->orig.x; - fptr->orig_y = (short) field_bbox->orig.y; - fptr->corner_x = (short) field_bbox->corner.x; - fptr->corner_y = (short) field_bbox->corner.y; - SET(fptr->flags, CACHE_OK); - - /*printf("ComputeFieldAttachment out\n");*/ -} - - -/* - ********************************************************************************** - * - * ClearFieldCache -- - * Reset the geometric cache of all fields depending on a given field (or - * of all fields if the field is < 0). Clear also the label bounding box - * cache if some action has been taken on a field. - * - ********************************************************************************** - */ -static void -ClearFieldCache(ZnFieldSet field_set, - int field) -{ - unsigned int i, num_fields; - ZnBool clear_bbox; - int x_spec, y_spec; - char x_attach, y_attach, x_dim, y_dim; - short width_spec, height_spec; - - if (!field_set->num_fields) { - return; - } - if (field < 0) { - for (i = 0; i < field_set->num_fields; i++) { - CLEAR(field_set->fields[i].flags, CACHE_OK); - } - field_set->label_width = field_set->label_height = -1.0; - return; - } - - clear_bbox = False; - if (!field_set->label_format) { - return; - } - num_fields = ZnLFNumFields(field_set->label_format); - if ((unsigned int) field >= num_fields) { - return; - } - ZnLFGetField(field_set->label_format, (unsigned int) field, - &x_attach, &y_attach, &x_dim, &y_dim, - &x_spec, &y_spec, &width_spec, &height_spec); - if ((x_dim != ZN_LF_DIM_PIXEL) || (y_dim != ZN_LF_DIM_PIXEL)) { - CLEAR(field_set->fields[field].flags, CACHE_OK); - clear_bbox = True; - } - for (i = 0; i < num_fields; i++) { - ZnLFGetField(field_set->label_format, i, - &x_attach, &y_attach, &x_dim, &y_dim, - &x_spec, &y_spec, &width_spec, &height_spec); - if ((x_attach == ZN_LF_ATTACH_PIXEL) && (y_attach == ZN_LF_ATTACH_PIXEL)) { - continue; - } - if (x_attach != ZN_LF_ATTACH_PIXEL) { - if ((x_spec == field) && ISSET(field_set->fields[i].flags, CACHE_OK)) { - CLEAR(field_set->fields[i].flags, CACHE_OK); - ClearFieldCache(field_set, (int) i); - clear_bbox = True; - } - } - if (y_attach != ZN_LF_ATTACH_PIXEL) { - if ((y_spec == field) && ISSET(field_set->fields[i].flags, CACHE_OK)) { - CLEAR(field_set->fields[i].flags, CACHE_OK); - ClearFieldCache(field_set, (int) i); - clear_bbox = True; - } - } - } - - if (clear_bbox) { - field_set->label_width = field_set->label_height = -1.0; - } -} - - -/* - ********************************************************************************** - * - * GetLabelBBox -- - * - ********************************************************************************** - */ -static void -GetLabelBBox(ZnFieldSet field_set, - ZnDim *w, - ZnDim *h) -{ - ZnBBox bbox, tmp_bbox; - ZnLabelFormat lf; - unsigned int i, num_fields; - ZnDim clip_w, clip_h; - - /*printf("GetLabelBBox in\n");*/ - if ((field_set->label_width >= 0.0) && (field_set->label_height >= 0.0)) { - *w = field_set->label_width; - *h = field_set->label_height; - /*printf("GetLabelBBox in cache\n");*/ - return; - } - - lf = field_set->label_format; - if (lf == NULL) { - *w = *h = field_set->label_width = field_set->label_height = 0.0; - /*printf("GetLabelBBox no labelformat\n");*/ - return; - } - - ZnResetBBox(&bbox); - num_fields = ZnLFNumFields(lf); - for (i = 0; i < num_fields; i++) { - ComputeFieldAttachment(field_set, i, &tmp_bbox); - /*printf("field %d bbox %g %g %g %g\n", i, tmp_bbox.orig.x, tmp_bbox.orig.y, - tmp_bbox.corner.x, tmp_bbox.corner.y);*/ - ZnAddBBoxToBBox(&bbox, &tmp_bbox); - } - field_set->label_width = bbox.corner.x; - field_set->label_height = bbox.corner.y; - - /*printf("GetLabelBBox size before clipping; w = %g, h = %g\n", - field_set->label_width, field_set->label_height);*/ - if (ZnLFGetClipBox(lf, &clip_w, &clip_h)) { - if (clip_w < field_set->label_width) { - field_set->label_width = clip_w; - } - if (clip_h < field_set->label_height) { - field_set->label_height = clip_h; - } - } - - *w = field_set->label_width; - *h = field_set->label_height; - /*printf("GetLabelBBox returns computed size; w = %g, h = %g\n", *w, *h);*/ -} - - -/* - ********************************************************************************** - * - * GetFieldBBox -- - * Compute the location of the field described - * by the field entry index in the item current LabelFormat. - * - ********************************************************************************** - */ -static void -GetFieldBBox(ZnFieldSet field_set, - unsigned int index, - ZnBBox *field_bbox) -{ - ZnReal ox, oy; - - /*printf("GetFieldBBox in\n");*/ - if (field_set->label_format) { - ox = ZnNearestInt(field_set->label_pos.x); - oy = ZnNearestInt(field_set->label_pos.y); - ComputeFieldAttachment(field_set, index, field_bbox); - field_bbox->orig.x += ox; - field_bbox->orig.y += oy; - field_bbox->corner.x += ox; - field_bbox->corner.y += oy; - } - else { - ZnResetBBox(field_bbox); - } - /*printf("GetFieldBBox out\n");*/ -} - - -/* - ********************************************************************************** - * - * ComputeFieldTextLocation -- - * Compute the position of the text in a field. This is a position - * that we can give to XDrawText. The position is deduced from the - * field bounding box passed in bbox. - * Return also the text bounding box. - * - ********************************************************************************** - */ -static void -ComputeFieldTextLocation(Field fptr, - ZnBBox *bbox, - ZnPoint *pos, - ZnBBox *text_bbox) -{ - ZnDim w, h; - Tk_FontMetrics fm; - - Tk_GetFontMetrics(fptr->font, &fm); - w = 0; - if (fptr->text) { - int width; - Tk_MeasureChars(fptr->font, fptr->text, strlen(fptr->text), -1, 0, &width); - w = width; - } - h = fm.ascent + fm.descent; - text_bbox->orig.y = (bbox->orig.y + bbox->corner.y - h) / 2.0; - text_bbox->corner.y = text_bbox->orig.y + h; - pos->y = text_bbox->orig.y + fm.ascent; - - switch (fptr->alignment) { - case TK_JUSTIFY_LEFT: - text_bbox->orig.x = bbox->orig.x + 2; - break; - case TK_JUSTIFY_RIGHT: - text_bbox->orig.x = bbox->corner.x - w - 2; - break; - default: - text_bbox->orig.x = (bbox->orig.x + bbox->corner.x - w) / 2.0; - break; - } - text_bbox->corner.x = text_bbox->orig.x + w; - pos->x = text_bbox->orig.x; -} - - -/* - ********************************************************************************** - * - * LeaderToLabel -- - * Compute the segment part of segment that lies - * outside the fields of item. - * - ********************************************************************************** - */ -static void -LeaderToLabel(ZnFieldSet field_set, - ZnPoint *start, - ZnPoint *end) -{ - int b_num; - ZnPoint delta, inf, sup; - ZnPos xt=0, yu=0, yw=0, xv=0; - Field fptr; - unsigned int i; - ZnBBox field_bbox; - - /* Intersection points : */ - /* T |xt / delta_y U |x1 V |y1 W |yw / delta_x */ - /* |y2 |yu / delta_x |xv / delta_y |x2 */ - /* */ - /* y = ax + b; */ - /* a = delta_y / delta_x */ - /* b = (y * delta_x - x * delta_y) / delta_x */ - - delta.x = start->x - end->x; - delta.y = start->y - end->y; - b_num = (int) (start->y*delta.x - start->x*delta.y); - - for (i = 0; i < ZnLFNumFields(field_set->label_format); i++) { - fptr = &field_set->fields[i]; - /* - * If the field is made invisible or has no graphics of - * its own, don't clip. - */ - if (ISCLEAR(fptr->flags, FIELD_VISIBLE_BIT) || - (!fptr->text && - ISCLEAR(fptr->flags, FILLED_BIT) && - (fptr->border_edges == ZN_NO_BORDER) && - (fptr->relief == ZN_RELIEF_FLAT) && - (fptr->image == ZnUnspecifiedImage))) { - continue; - } - - /* - * field_bbox is in absolute device coordinates. - */ - GetFieldBBox(field_set, i, &field_bbox); - - /* - * Adjust leader on real text, not on field boundaries. This is - * important when there are leading and trailing spaces. - */ - if (fptr->text && - ISCLEAR(fptr->flags, FILLED_BIT) && - (fptr->border_edges == ZN_NO_BORDER) && - (fptr->relief == ZN_RELIEF_FLAT) && - (fptr->image == ZnUnspecifiedImage)) { - ZnBBox text_bbox; - ZnPoint text_pos; /* dummy */ - int space_width; - int scan_forw, scan_back; - space_width = Tk_TextWidth(fptr->font, " ", 1); - - ComputeFieldTextLocation(fptr, &field_bbox, &text_pos, &text_bbox); - /* - * Correct adjusments made by ComputeFieldTextLocation (Vincent Pomey). - * - * PLC: IMHO, this is to compensate for exotic fonts like 'symbolesATC'. - * I am not planning to port this to Tk for two reasons: - * 1/ Current positions are no longer implemented as characters - * and 2/ Tk does not give access (easily) to lbearings and rbearings. - * This patch has been contributed by Phidias team. I don't know the - * problem it was meant to solve. - * text_bbox.x -= fptr->font->per_char[fptr->text[0]].lbearing + 3; - * text_bbox.width += fptr->font->per_char[fptr->text[0]].lbearing + 3; - */ - /* - * Change bbox according to leading and trailing spaces. - */ - scan_forw = 0; - while (fptr->text[scan_forw] == ' ') { - /* leading spaces */ - text_bbox.orig.x += space_width; - scan_forw++; - } - - /* - * Empty text. - */ - if (!fptr->text || (fptr->text[scan_forw] == 0)) { - continue; - } - - scan_back = strlen(fptr->text)-1; - while ((fptr->text[scan_back] == ' ') && (scan_back > scan_forw)) { - /* trailing spaces */ - text_bbox.corner.x -= space_width; - scan_back--; - } - - field_bbox = text_bbox; - } - - if (field_bbox.corner.x <= field_bbox.orig.x) { - continue; - } - - if ((start->x >= field_bbox.orig.x) && (start->x < field_bbox.corner.x) && - (start->y >= field_bbox.orig.y) && (start->y < field_bbox.corner.y)) { - end->x = start->x; - end->y = start->y; - } - if (delta.x) { - yu = (field_bbox.orig.x*delta.y + b_num) / delta.x; - yw = (field_bbox.corner.x*delta.y + b_num) / delta.x; - } - if (delta.y) { - xt = (field_bbox.corner.y*delta.x - b_num) / delta.y; - xv = (field_bbox.orig.y*delta.x - b_num) / delta.y; - } - - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - - if (delta.x) { - if ((yu >= field_bbox.orig.y) && (yu <= field_bbox.corner.y) && - (field_bbox.orig.x >= inf.x) && (field_bbox.orig.x <= sup.x) && - (yu >= inf.y) && (yu <= sup.y)) { - end->x = field_bbox.orig.x; - end->y = yu; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - if ((yw >= field_bbox.orig.y) && (yw <= field_bbox.corner.y) && - (field_bbox.corner.x >= inf.x) && (field_bbox.corner.x <= sup.x) && - (yw >= inf.y) && (yw <= sup.y)) { - end->x = field_bbox.corner.x; - end->y = yw; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - } - if (delta.y) { - if ((xt >= field_bbox.orig.x) && (xt <= field_bbox.corner.x) && - (xt >= inf.x) && (xt <= sup.x) && - (field_bbox.corner.y >= inf.y) && (field_bbox.corner.y <= sup.y)) { - end->x = xt; - end->y = field_bbox.corner.y; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - if ((xv >= field_bbox.orig.x) && (xv <= field_bbox.corner.x) && - (xv >= inf.x) && (xv <= sup.x) && - (field_bbox.orig.y >= inf.y) && (field_bbox.orig.y <= sup.y)) { - end->x = xv; - end->y = field_bbox.orig.y; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - } - } -} - - -/* - ********************************************************************************** - * - * InitFields -- - * - * Perform the init of each field in a ZnFieldSet. The number of such - * fields must have been inited before calling this fun. - * - ********************************************************************************** - */ -static void -InitFields(ZnFieldSet field_set) -{ - ZnWInfo *wi = field_set->item->wi; - Field field; - unsigned int i, num_fields; - - /*printf("size of a field = %d\n", sizeof(FieldStruct));*/ - - if (!field_set->num_fields) { - return; - } - num_fields = field_set->num_fields; - field_set->fields = (Field) ZnMalloc(num_fields*sizeof(FieldStruct)); - - for (i = 0; i < num_fields; i++){ - field = &field_set->fields[i]; - - field->color = ZnGetGradientByValue(wi->fore_color); - field->fill_color = ZnGetGradientByValue(wi->back_color); - field->border_color = ZnGetGradientByValue(wi->fore_color); - SET(field->flags, FIELD_VISIBLE_BIT); - SET(field->flags, FIELD_SENSITIVE_BIT); - CLEAR(field->flags, FILLED_BIT); - CLEAR(field->flags, CACHE_OK); - field->text = NULL; - field->image = ZnUnspecifiedImage; - field->tile = ZnUnspecifiedImage; - field->font = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(wi->font)); -#ifdef GL - field->tfi = ZnGetTexFont(wi, field->font); -#endif - field->border_edges = ZN_NO_BORDER; - field->alignment = TK_JUSTIFY_LEFT; - field->auto_alignment.automatic = False; - - field->relief = ZN_RELIEF_FLAT; - field->relief_thickness = 2; - SET(field->flags, TEXT_ON_TOP_BIT); - - field->gradient = NULL; - field->grad_geo = NULL; - } - field_set->label_pos.x = field_set->label_pos.y = 0.0; - field_set->label_width = field_set->label_height = -1.0; -} - - -/* - ********************************************************************************** - * - * CloneFields -- - * - ********************************************************************************** - */ -static void -CloneFields(ZnFieldSet field_set) -{ - ZnWInfo *wi = field_set->item->wi; - Field field, fields_ret; - unsigned int i, num_fields; - char *text; - - num_fields = field_set->num_fields; - if (!num_fields) { - return; - } - if (field_set->label_format) { - field_set->label_format = ZnLFDuplicate(field_set->label_format); - } - fields_ret = (Field) ZnMalloc(num_fields*sizeof(FieldStruct)); - memcpy(fields_ret, field_set->fields, num_fields*sizeof(FieldStruct)); - field_set->fields = fields_ret; - - for (i = 0; i < num_fields; i++) { - field = &fields_ret[i]; - if (field->gradient) { - field->gradient = ZnGetGradientByValue(field->gradient); - } - if (field->grad_geo) { - ZnPoint *grad_geo = ZnMalloc(4*sizeof(ZnPoint)); - memcpy(grad_geo, field->grad_geo, 4*sizeof(ZnPoint)); - field->grad_geo = grad_geo; - } - if (field->image != ZnUnspecifiedImage) { - field->image = ZnGetImageByValue(field->image, ZnUpdateItemImage, field_set->item); - } - if (field->tile != ZnUnspecifiedImage) { - field->tile = ZnGetImageByValue(field->tile, ZnUpdateItemImage, field_set->item); - } - field->font = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(field->font)); -#ifdef GL - field->tfi = ZnGetTexFont(wi, field->font); -#endif - field->color = ZnGetGradientByValue(field->color); - field->fill_color = ZnGetGradientByValue(field->fill_color); - field->border_color = ZnGetGradientByValue(field->border_color); - - if (field->text) { - text = (char *) ZnMalloc((strlen(field->text) + 1) * sizeof(char)); - strcpy(text, field->text); - field->text = text; - } - } -} - - -/* - ********************************************************************************** - * - * ConfigureField -- - * - ********************************************************************************** - */ -static int -ConfigureField(ZnFieldSet fs, - int field, - int argc, - Tcl_Obj *CONST argv[], - int *flags) -{ - unsigned int i; - Field fptr; - ZnBBox bbox; - ZnWInfo *wi = fs->item->wi; - XColor *color; - unsigned short alpha; - int old_num_chars, num_chars; -#ifdef GL - Tk_Font old_font; -#endif - - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - Tcl_AppendResult(wi->interp, "invalid field index", NULL); - return TCL_ERROR; - } - - fptr = &fs->fields[field]; -#ifdef GL - old_font = fptr->font; -#endif - old_num_chars = 0; - if (fptr->text) { - old_num_chars = Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)); - } - - if (ZnConfigureAttributes(wi, fs->item, fptr, field_attrs, - argc, argv, flags) == TCL_ERROR) { - return TCL_ERROR; - } - - num_chars = 0; - if (fptr->text) { - num_chars = Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)); - } - if (old_num_chars != num_chars) { - ZnTextInfo *ti = &wi->text_info; - /* - * The text has changed, update the selection and - * insertion pos to keep them valid. - */ - if ((fs->item == ti->sel_item) && (field == ti->sel_field)) { - if (ti->sel_last > num_chars) { - ti->sel_last = num_chars; - } - if (ti->sel_first >= ti->sel_last) { - ti->sel_item = ZN_NO_ITEM; - ti->sel_field = ZN_NO_PART; - } - if ((ti->anchor_item == fs->item) && (ti->anchor_field == field) && - (ti->sel_anchor > num_chars)) { - ti->sel_anchor = num_chars; - } - } - if (fptr->insert_index > num_chars) { - fptr->insert_index = num_chars; - } - } - -#ifdef GL - if (old_font != fptr->font) { - if (fptr->tfi) { - ZnFreeTexFont(fptr->tfi); - fptr->tfi = ZnGetTexFont(wi, fptr->font); - } - } -#endif - - if (ISSET(*flags, ZN_REPICK_FLAG)) { - SET(wi->flags, ZN_INTERNAL_NEED_REPICK); - } - if (ISSET(*flags, ZN_CLFC_FLAG)) { - ClearFieldCache(fs, field); - } - - if (fptr->gradient && - (ISSET(*flags, ZN_BORDER_FLAG) || (fptr->relief == ZN_RELIEF_FLAT))) { - ZnFreeGradient(fptr->gradient); - fptr->gradient = NULL; - } - if ((fptr->relief != ZN_RELIEF_FLAT) && !fptr->gradient) { - color = ZnGetGradientColor(fptr->border_color, 51.0, &alpha); - fptr->gradient = ZnGetReliefGradient(wi->interp, wi->win, - Tk_NameOfColor(color), alpha); - if (fptr->gradient == NULL) { - return TCL_ERROR; - } - } - - /* - * This is done here to limit the redraw to the area of the - * modified fields. - */ - if (ISCLEAR(*flags, ZN_COORDS_FLAG) && - fs->label_format && ISSET(*flags, ZN_DRAW_FLAG)) { - for (i = 0; i < ZnLFNumFields(fs->label_format); i++) { - if (i == (unsigned int) field) { - GetFieldBBox(fs, i, &bbox); - ZnDamage(wi, &bbox); - break; - } - } - } - - return TCL_OK; -} - - -/* - ********************************************************************************** - * - * QueryField -- - * - ********************************************************************************** - */ -static int -QueryField(ZnFieldSet fs, - int field, - int argc, - Tcl_Obj *CONST argv[]) -{ - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - Tcl_AppendResult(fs->item->wi->interp, "invalid field index \"", NULL); - return TCL_ERROR; - } - - if (ZnQueryAttribute(fs->item->wi->interp, &fs->fields[field], field_attrs, - argv[0]) == TCL_ERROR) { - return TCL_ERROR; - } - - return TCL_OK; -} - - -/* - ********************************************************************************** - * - * FreeFields -- - * - ********************************************************************************** - */ -static void -FreeFields(ZnFieldSet field_set) -{ - unsigned int i, num_fields; - Field field; - - if (field_set->label_format) { - ZnLFDelete(field_set->label_format); - } - - num_fields = field_set->num_fields; - for (i = 0; i < num_fields; i++) { - field = &field_set->fields[i]; - - if (field->text) { - ZnFree(field->text); - } - if (field->gradient) { - ZnFreeGradient(field->gradient); - } - if (field->grad_geo) { - ZnFree(field->grad_geo); - } - if (field->image != ZnUnspecifiedImage) { - ZnFreeImage(field->image, ZnUpdateItemImage, &field->image); - field->image = ZnUnspecifiedImage; - } - if (field->tile != ZnUnspecifiedImage) { - ZnFreeImage(field->tile, ZnUpdateItemImage, &field->tile); - field->tile = ZnUnspecifiedImage; - } - Tk_FreeFont(field->font); -#ifdef GL - if (field->tfi) { - ZnFreeTexFont(field->tfi); - } -#endif - ZnFreeGradient(field->color); - ZnFreeGradient(field->fill_color); - ZnFreeGradient(field->border_color); - } - if (num_fields) { - ZnFree(field_set->fields); - } -} - - -/* - ********************************************************************************** - * - * FieldIndex, - * FieldInsertChars, - * FieldDeleteChars, - * FieldCursor, - * FieldSelection -- - * These functions implement text edition in fields. The behavior - * is the same as for Text items. - * - ********************************************************************************** - */ -static int -FieldPointToChar(ZnFieldSet fs, - unsigned int field, - int x, - int y) -{ - Field fptr; - int byte_index; - ZnBBox f_bbox, t_bbox; - ZnPoint t_orig; - unsigned int num_bytes, n, dummy; - - fptr = &fs->fields[field]; - num_bytes = 0; - byte_index = 0; - if (fptr->text) { - num_bytes = strlen(fptr->text); - } - - if (num_bytes == 0) { - return 0; - } - - GetFieldBBox(fs, field, &f_bbox); - ComputeFieldTextLocation(fptr, &f_bbox, &t_orig, &t_bbox); - - /* - * Point above text, returns index 0. - */ - if (y < t_bbox.orig.y) { - return 0; - } - - if (y < t_bbox.corner.y) { - if (x < t_bbox.orig.x) { - /* - * Point to the left of the current line, returns - * index of first char. - */ - return 0; - } - if (x >= t_bbox.corner.x) { - /* - * Point to the right of the current line, returns - * index past the last char. - */ - byte_index = num_bytes; - goto convrt; - } - n = Tk_MeasureChars(fptr->font, fptr->text, num_bytes, - x + 2 - (int) t_bbox.orig.x, TK_PARTIAL_OK, &dummy); - byte_index = n - 1; - goto convrt; - } - /* - * Point below all lines, return the index after - * the last char. - */ - byte_index = num_bytes; - convrt: - return Tcl_NumUtfChars(fptr->text, byte_index); -} - -static int -WordMoveFromIndex(char *text, - int index, - int fwd) -{ - char const *strp; - - if (!text) { - return index; - } - - strp = Tcl_UtfAtIndex(text, index); - if (fwd) { - while ((strp[1] == ' ') || (strp[1] == '\n')) { - strp++; - } - while ((strp[1] != ' ') && (strp[1] != '\n') && strp[1]) { - strp++; - } - return Tcl_NumUtfChars(text, strp + 1 - text); - } - else { - while ((strp != text) && ((strp[-1] == ' ') || (strp[-1] == '\n'))) { - strp--; - } - while ((strp != text) && (strp[-1] != ' ') && (strp[-1] != '\n')) { - strp--; - } - return Tcl_NumUtfChars(text, strp - text); - } -} - -static int -FieldIndex(ZnFieldSet fs, - int field, - Tcl_Obj *index_spec, - int *index) -{ - Field fptr; - ZnWInfo *wi = fs->item->wi; - ZnTextInfo *ti = &wi->text_info; - unsigned int length; - int c, x, y; - double tmp; - char *end, *p; - - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - *index = 0; - return TCL_OK; - } - - fptr = &fs->fields[field]; - - p = Tcl_GetString(index_spec); - c = p[0]; - length = strlen(p); - - if ((c == 'e') && (strncmp(p, "end", length) == 0)) { - *index = fptr->text ? Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)) : 0; - } - else if ((c == 'e') && (length > 1) && (strncmp(p, "eol", length) == 0)) { - *index = fptr->text ? Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)) : 0; - } - else if ((c == 'b') && (length > 1) && (strncmp(p, "bol", length) == 0)) { - *index = 0; - } - else if ((c == 'e') && (length > 1) && (strncmp(p, "eow", length) == 0)) { - *index = WordMoveFromIndex(fptr->text, fptr->insert_index, 1); - } - else if ((c == 'b') && (length > 1) && (strncmp(p, "bow", length) == 0)) { - *index = WordMoveFromIndex(fptr->text, fptr->insert_index, 0); - } - else if ((c == 'u') && (strncmp(p, "up", length) == 0)) { - *index = fptr->insert_index; - } - else if ((c == 'd') && (strncmp(p, "down", length) == 0)) { - *index = fptr->insert_index; - } - else if ((c == 'i') && (strncmp(p, "insert", length) == 0)) { - *index = fptr->insert_index; - } - else if ((c == 's') && (strncmp(p, "sel.first", length) == 0) && - (length >= 5)) { - if ((ti->sel_item != fs->item) || (ti->sel_field != field)) { - sel_err: - Tcl_AppendResult(wi->interp, "selection isn't in field", (char *) NULL); - return TCL_ERROR; - } - *index = ti->sel_first; - } - else if ((c == 's') && (strncmp(p, "sel.last", length) == 0) && - (length >= 5)) { - if ((ti->sel_item != fs->item) || (ti->sel_field != field)) { - goto sel_err; - } - /* - * We return a modified selection end so that it reflect - * the text index of the last character _not_ the insertion - * point between the last and the next. - */ - *index = ti->sel_last-1; - } - else if (c == '@') { - p++; - tmp = strtod(p, &end); - if ((end == p) || (*end != ',')) { - goto badIndex; - } - x = (int) tmp; - p = end+1; - tmp = strtod(p, &end); - if ((end == p) || (*end != 0)) { - goto badIndex; - } - y = (int) tmp; - - *index = FieldPointToChar(fs, (unsigned int) field, x, y); - } - else if (Tcl_GetIntFromObj(wi->interp, index_spec, index) == TCL_OK) { - int num_chars = fptr->text ? Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)) : 0; - if (*index < 0){ - *index = 0; - } - else if (*index > num_chars) { - *index = num_chars; - } - } - else { - badIndex: - Tcl_AppendResult(wi->interp, "bad index \"", p, "\"", (char *) NULL); - return TCL_ERROR; - } - - return TCL_OK; -} - -static ZnBool -FieldInsertChars(ZnFieldSet fs, - int field, - int *index, - char *chars) -{ - Field fptr; - ZnTextInfo *ti = &fs->item->wi->text_info; - int num_chars, num_bytes, chars_added; - unsigned int byte_index, bytes_added = strlen(chars); - char *new; - - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - return False; - } - - if (bytes_added == 0) { - return False; - } - - fptr = &fs->fields[field]; - num_chars = 0; - num_bytes = 0; - if (fptr->text) { - num_bytes = strlen(fptr->text); - num_chars = Tcl_NumUtfChars(fptr->text, num_bytes); - } - if (*index < 0) { - *index = 0; - } - if (*index > num_chars) { - *index = num_chars; - } - chars_added = Tcl_NumUtfChars(chars, (int) bytes_added); - - if (fptr->text) { - byte_index = Tcl_UtfAtIndex(fptr->text, *index) - fptr->text; - new = ZnMalloc(num_bytes + bytes_added + 1); - /* - * Copy the part before and the part after the new - * text (if any). - */ - memcpy(new, fptr->text, (size_t) byte_index); - strcpy(new + byte_index + bytes_added, fptr->text + byte_index); - ZnFree(fptr->text); - } - else { - byte_index = 0; - new = ZnMalloc(num_bytes + 1); - new[num_bytes] = 0; - } - /* - * Insert the new text. - */ - memcpy(new + byte_index, chars, bytes_added); - fptr->text = new; - - if (fptr->insert_index >= *index) { - fptr->insert_index += chars_added; - } - if ((ti->sel_item == fs->item) && (ti->sel_field == field)) { - if (ti->sel_first >= *index) { - ti->sel_first += chars_added; - } - if (ti->sel_last >= *index) { - ti->sel_last += chars_added; - } - if ((ti->anchor_item == fs->item) && (ti->anchor_field == field) && - (ti->sel_anchor >= *index)) { - ti->sel_anchor += chars_added; - } - } - - /* - * Need to redo the fields layout (maybe). - */ - ClearFieldCache(fs, field); - return True; -} - -static ZnBool -FieldDeleteChars(ZnFieldSet fs, - int field, - int *first, - int *last) -{ - Field fptr; - ZnTextInfo *ti = &fs->item->wi->text_info; - unsigned int char_count, byte_count; - unsigned int num_bytes, num_chars, first_offset; - char *new; - - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - return False; - } - - fptr = &fs->fields[field]; - num_chars = 0; - num_bytes = 0; - if (fptr->text) { - num_bytes = strlen(fptr->text); - num_chars = Tcl_NumUtfChars(fptr->text, (int) num_bytes); - } - if (num_chars == 0) { - return False; - } - - if (*first < 0) { - *first = 0; - } - if (*last >= (int) num_chars) { - *last = num_chars-1; - } - if (*first > *last) { - return False; - } - char_count = *last + 1 - *first; - first_offset = Tcl_UtfAtIndex(fptr->text, *first)-fptr->text; - byte_count = Tcl_UtfAtIndex(fptr->text + first_offset, (int) char_count) - - (fptr->text+first_offset); - - if (num_bytes - byte_count) { - new = ZnMalloc(num_bytes + 1 - byte_count); - memcpy(new, fptr->text, (size_t) first_offset); - strcpy(new + first_offset, fptr->text + first_offset + byte_count); - ZnFree(fptr->text); - fptr->text = new; - } - else { - ZnFree(fptr->text); - fptr->text = NULL; - } - - /* - * Update the cursor to reflect the new string. - */ - if (fptr->insert_index > *first) { - fptr->insert_index -= char_count; - if (fptr->insert_index < *first) { - fptr->insert_index = *first; - } - } - if ((ti->sel_item == fs->item) && (ti->sel_field == field)) { - if (ti->sel_first > *first) { - ti->sel_first -= char_count; - if (ti->sel_first < *first) { - ti->sel_first = *first; - } - } - if (ti->sel_last >= *first) { - ti->sel_last -= char_count; - if (ti->sel_last < *first - 1) { - ti->sel_last = *first - 1; - } - } - if (ti->sel_first > ti->sel_last) { - ti->sel_item = ZN_NO_ITEM; - } - if ((ti->anchor_item == fs->item) && (ti->anchor_field == field) && - (ti->sel_anchor > *first)) { - ti->sel_anchor -= char_count; - if (ti->sel_anchor < *first) { - ti->sel_anchor = *first; - } - } - } - - /* - * Need to redo the fields layout (maybe). - */ - ClearFieldCache(fs, field); - return True; -} - -static void -FieldCursor(ZnFieldSet fs, - int field, - int index) -{ - Field fptr; - int num_chars; - - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - return; - } - - fptr = &fs->fields[field]; - num_chars = 0; - if (fptr->text) { - num_chars = Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)); - } - - if (index < 0) { - fptr->insert_index = 0; - } - else if (index > num_chars) { - fptr->insert_index = num_chars; - } - else { - fptr->insert_index = index; - } -} - -static int -FieldSelection(ZnFieldSet fs, - int field, - int offset, - char *chars, - int max_bytes) -{ - Field fptr; - int count; - char const *sel_first, *sel_last; - ZnTextInfo *ti; - - if ((field < 0) || ((unsigned int) field >= fs->num_fields)) { - return 0; - } - ti = &fs->item->wi->text_info; - if ((ti->sel_first < 0) || - (ti->sel_first > ti->sel_last)) { - return 0; - } - - fptr = &fs->fields[field]; - if (!fptr->text) { - return 0; - } - - sel_first = Tcl_UtfAtIndex(fptr->text, ti->sel_first); - sel_last = Tcl_UtfAtIndex(sel_first, ti->sel_last + 1 - ti->sel_first); - count = sel_last - sel_first - offset; - if (count <= 0) { - return 0; - } - if (count > max_bytes) { - count = max_bytes; - } - - memcpy(chars, sel_first + offset, (size_t) count); - chars[count] = 0; - - return count; -} - - -/* - ********************************************************************************** - * - * ComputeFieldImageLocation -- - * Compute the bounding box of the pixmap in a field. The position is - * deduced from the field bounding box passed in bbox. - * - ********************************************************************************** - */ -static void -ComputeFieldImageLocation(Field fptr, - ZnBBox *bbox, - ZnBBox *pm_bbox) -{ - int width, height; - - ZnSizeOfImage(fptr->image, &width, &height); - pm_bbox->orig.y = (bbox->orig.y + bbox->corner.y - height) / 2; - pm_bbox->corner.y = pm_bbox->orig.y + height; - - switch (fptr->alignment) { - case TK_JUSTIFY_LEFT: - pm_bbox->orig.x = bbox->orig.x; - break; - case TK_JUSTIFY_RIGHT: - pm_bbox->orig.x = bbox->corner.x - width - 1; - break; - default: - pm_bbox->orig.x = (bbox->orig.x + bbox->corner.x - width) / 2; - break; - } - pm_bbox->corner.x = pm_bbox->orig.x + width; -} - - -/* - ********************************************************************************** - * - * FieldsEngine -- - * - ********************************************************************************** - */ -static void -FieldsEngine(ZnFieldSet field_set, - void (*cb)()) -{ - ZnWInfo *wi = field_set->item->wi; - /*int i; This one *NEED* to be an int */ - unsigned int i, num_fields, num_chars; - Field fptr; - ZnTextInfo *ti = &wi->text_info; - ZnBBox lclip_bbox, fclip_bbox, bbox, *global_clip_box; - ZnBBox tmp_bbox, text_bbox, pm_bbox; - ZnPoint pts[2]; - ZnTriStrip tristrip; - ZnPoint text_pos; - ZnBool restore = False; - ZnDim lwidth, lheight; - ZnReal val; - int cursor; - int sel_start, sel_stop; - - if (!field_set->num_fields) { - return; - } - - if (field_set->label_format && ZnLFNumFields(field_set->label_format)) { - bbox.orig.x = ZnNearestInt(field_set->label_pos.x); - bbox.orig.y = ZnNearestInt(field_set->label_pos.y); - GetLabelBBox(field_set, &lwidth, &lheight); - bbox.corner.x = bbox.orig.x + lwidth; - bbox.corner.y = bbox.orig.y + lheight; - ZnCurrentClip(wi, NULL, &global_clip_box, NULL); - - if (!wi->render) { - ZnIntersectBBox(global_clip_box, &bbox, &lclip_bbox); - if (ZnIsEmptyBBox(&lclip_bbox)) { - return; - } - } - else { - lclip_bbox = bbox; - } - - num_fields = ZnLFNumFields(field_set->label_format); - for (i = 0; i < num_fields; i++) { - fptr = &field_set->fields[i]; - - if (ISCLEAR(fptr->flags, FIELD_VISIBLE_BIT)) { - continue; - } - - GetFieldBBox(field_set, i, &bbox); - ZnIntersectBBox(&lclip_bbox, &bbox, &fclip_bbox); - if (ZnIsEmptyBBox(&fclip_bbox)) { - continue; - } - - /* we must call XSetClipRectangles only if it's required */ - val = fclip_bbox.orig.x - bbox.orig.x; - restore = val > 0; - val = fclip_bbox.orig.y - bbox.orig.y; - restore |= val > 0; - val = fclip_bbox.corner.x - bbox.corner.x; - restore |= val < 0; - val = fclip_bbox.corner.y - bbox.corner.y; - restore |= val < 0; - - cursor = ((field_set->item == wi->focus_item) && - ((unsigned int) wi->focus_field == i) && - ISSET(wi->flags, ZN_GOT_FOCUS) && ti->cursor_on) ? 0 : -1; - sel_start = -1, sel_stop = -1; - ComputeFieldTextLocation(fptr, &bbox, &text_pos, &text_bbox); - - if (fptr->text) { - if (cursor != -1) { - cursor = Tk_TextWidth(fptr->font, fptr->text, - Tcl_UtfAtIndex(fptr->text, - fptr->insert_index)-fptr->text); - } - num_chars = Tcl_NumUtfChars(fptr->text, (int) strlen(fptr->text)); - if (num_chars) { - if ((field_set->item == ti->sel_item) && ((unsigned int) ti->sel_field == i) && - (ti->sel_last >= 0) && (ti->sel_first <= (int) num_chars)) { - sel_start = Tk_TextWidth(fptr->font, fptr->text, - Tcl_UtfAtIndex(fptr->text, - ti->sel_first)-fptr->text); - sel_stop = Tk_TextWidth(fptr->font, fptr->text, - Tcl_UtfAtIndex(fptr->text, - ti->sel_last)-fptr->text); - } - - ZnIntersectBBox(&fclip_bbox, &text_bbox, &tmp_bbox); - - val = tmp_bbox.orig.x - text_bbox.orig.x; - restore |= val > 0; - val = tmp_bbox.orig.y - text_bbox.orig.y; - restore |= val > 0; - val = tmp_bbox.corner.x - text_bbox.corner.x; - restore |= val < 0; - val = tmp_bbox.corner.y - text_bbox.corner.y; - restore |= val < 0; - } - } - - if (fptr->image != ZnUnspecifiedImage) { - ComputeFieldImageLocation(fptr, &bbox, &pm_bbox); - - ZnIntersectBBox(&fclip_bbox, &pm_bbox, &tmp_bbox); - - val = tmp_bbox.orig.x - pm_bbox.orig.x; - restore |= val > 0; - val = tmp_bbox.orig.y - pm_bbox.orig.y; - restore |= val > 0; - val = tmp_bbox.corner.x - pm_bbox.corner.x; - restore |= val < 0; - val = tmp_bbox.corner.y - pm_bbox.corner.y; - restore |= val < 0; - } - - /*restore = True;*/ - if (restore) { - /* we must clip. */ - /*printf("clip: %d\n", i);*/ - pts[0] = fclip_bbox.orig; - pts[1] = fclip_bbox.corner; - ZnTriStrip1(&tristrip, pts, 2, False); - ZnPushClip(wi, &tristrip, True, True); - } - - (*cb)(wi, fptr, &bbox, &pm_bbox, - &text_pos, &text_bbox, cursor, sel_start, sel_stop); - - if (restore) { - /* Restore the previous clip. */ - ZnPopClip(wi, True); - restore = False; - } - } - } -} - - -/* - ********************************************************************************** - * - * DrawFields -- - * - ********************************************************************************** - */ -static void -DrawField(ZnWInfo *wi, - Field fptr, - ZnBBox *bbox, - ZnBBox *pm_bbox, - ZnPoint *text_pos, - ZnBBox *text_bbox, - int cursor, - int sel_start, - int sel_stop) -{ - ZnTextInfo *ti = &wi->text_info; - XGCValues values; - XRectangle r; - int j, xs, num_bytes; - int pw, ph, fw, fh; - TkRegion clip_region; - ZnBool simple; - Pixmap pixmap; - TkRegion photo_region, clip; - - ZnBBox2XRect(bbox, &r); - - /* - * Draw the background. - */ - if (ISSET(fptr->flags, FILLED_BIT)) { - values.foreground = ZnGetGradientPixel(fptr->fill_color, 0.0); - - if (fptr->tile != ZnUnspecifiedImage) { - if (!ZnImageIsBitmap(fptr->tile)) { /* Fill tiled */ - values.fill_style = FillTiled; - values.tile = ZnImagePixmap(fptr->tile, wi->win); - 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 { /* Fill stippled */ - values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(fptr->tile, wi->win); - 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); - } - 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(fptr->flags, TEXT_ON_TOP_BIT)) || - (j == 1 && ISCLEAR(fptr->flags, TEXT_ON_TOP_BIT))) { - /* - * Draw the image. - */ - if (fptr->image != ZnUnspecifiedImage) { - pw = ZnNearestInt(pm_bbox->corner.x - pm_bbox->orig.x); - ph = ZnNearestInt(pm_bbox->corner.y - pm_bbox->orig.y); - fw = ZnNearestInt(bbox->corner.x - bbox->orig.x); - fh = ZnNearestInt(bbox->corner.y - bbox->orig.y); - - pixmap = ZnImagePixmap(fptr->image, wi->win); - photo_region = ZnImageRegion(fptr->image); - ZnCurrentClip(wi, &clip_region, NULL, &simple); - clip = TkCreateRegion(); - /* - * ZnImageRegion may fail: perl/Tk 800.24 doesn't support - * some internal TkPhoto functions. - * This is a workaround using a rectangular region based - * on the image size. - */ - if (photo_region == NULL) { - XRectangle rect; - rect.x = rect.y = 0; - rect.width = pw; - rect.height = ph; - TkUnionRectWithRegion(&rect, clip, clip); - } - else { - ZnUnionRegion(clip, photo_region, clip); - } - ZnOffsetRegion(clip, (int) pm_bbox->orig.x, (int) pm_bbox->orig.y); - TkIntersectRegion(clip_region, clip, clip); - TkSetRegion(wi->dpy, wi->gc, clip); - XCopyArea(wi->dpy, pixmap, wi->draw_buffer, wi->gc, - (int) ZnNearestInt(bbox->orig.x-pm_bbox->orig.x), - (int) ZnNearestInt(bbox->orig.y-pm_bbox->orig.y), - (unsigned int) MIN(pw, fw), - (unsigned int) MIN(ph, fh), - (int) MAX(bbox->orig.x, pm_bbox->orig.x), - (int) MAX(bbox->orig.y, pm_bbox->orig.y)); - - TkSetRegion(wi->dpy, wi->gc, clip_region); - TkDestroyRegion(clip); - } - } - else if (fptr->text) { - /* - * Draw the text. - */ - num_bytes = strlen(fptr->text); - if (num_bytes) { - if (sel_start >= 0) { - values.foreground = ZnGetGradientPixel(ti->sel_color, 0.0); - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCForeground|GCFillStyle, &values); - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, - (int) (text_bbox->orig.x+sel_start), - (int) text_bbox->orig.y, - (unsigned int) (sel_stop-sel_start), - (unsigned int) (text_bbox->corner.y-text_bbox->orig.y)); - } - values.foreground = ZnGetGradientPixel(fptr->color, 0.0); - values.fill_style = FillSolid; - values.font = Tk_FontId(fptr->font); - XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle | GCFont, &values); - Tk_DrawChars(wi->dpy, wi->draw_buffer, wi->gc, fptr->font, - fptr->text, num_bytes, (int) text_pos->x, (int) text_pos->y); - } - } - } - if (cursor >= 0) { - values.line_width = ti->insert_width; - values.foreground = ZnGetGradientPixel(ti->insert_color, 0.0); - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCForeground|GCLineWidth|GCFillStyle, &values); - xs = (int) text_bbox->orig.x + cursor; - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - xs, (int) text_bbox->orig.y, - xs, (int) text_bbox->corner.y); - } - - /* - * Draw the border relief. - */ - if ((fptr->relief != ZN_RELIEF_FLAT) && (fptr->relief_thickness > 1)) { - ZnDrawRectangleRelief(wi, fptr->relief, fptr->gradient, - &r, fptr->relief_thickness); - } - - /* - * Draw the border line. - */ - if (fptr->border_edges != ZN_NO_BORDER) { - values.foreground = ZnGetGradientPixel(fptr->border_color, 0.0); - values.line_width = 0; - values.line_style = LineSolid; - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, - GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, &values); - if (fptr->border_edges & ZN_LEFT_BORDER) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, - r.x, r.y + r.height - 1); - } - if (fptr->border_edges & ZN_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 (fptr->border_edges & ZN_TOP_BORDER) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x, r.y, r.x + r.width - 1, r.y); - } - if (fptr->border_edges & ZN_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 (fptr->border_edges & ZN_OBLIQUE) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x, r.y, r.x + r.width - 1, r.y + r.height - 1); - } - if (fptr->border_edges & ZN_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(ZnFieldSet field_set) -{ - FieldsEngine(field_set, DrawField); -} - - -/* - ********************************************************************************** - * - * RenderFields -- - * - ********************************************************************************** - */ -#ifdef GL -static void -FieldRenderCB(void *closure) -{ - ZnBBox *bbox = (ZnBBox *) closure; - - glBegin(GL_QUADS); - glVertex2d(bbox->orig.x, bbox->orig.y); - glVertex2d(bbox->orig.x, bbox->corner.y); - glVertex2d(bbox->corner.x, bbox->corner.y); - glVertex2d(bbox->corner.x, bbox->orig.y); - glEnd(); -} - -static void -RenderField(ZnWInfo *wi, - Field fptr, - ZnBBox *bbox, - ZnBBox *pm_bbox, - ZnPoint *text_pos, - ZnBBox *text_bbox, - int cursor, - int sel_start, - int sel_stop) -{ - unsigned short alpha; - unsigned int j, num_bytes; - XColor *color; - ZnReal xs; - ZnTextInfo *ti = &wi->text_info; - - ZnGLMakeCurrent(wi->dpy, wi); - /* - * Draw the background. - */ - if (ISSET(fptr->flags, FILLED_BIT)) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (!ZnGradientFlat(fptr->fill_color)) { -#if 0 /* TODO_GL Faire le dégradé dans le fond des champs. */ - int type = fptr->fill_color->type; - ZnBool fast = (type == ZN_AXIAL_GRADIENT) && !fptr->grad_geo; - - RenderGradient(wi, fptr->fill_color, - fast ? NULL : FieldRenderCB, - bbox, fast ? (ZnPoint *) bbox : fptr->grad_geo); -#endif - } - else { - if (fptr->tile != ZnUnspecifiedImage) { /* Fill tiled/stippled */ - ZnRenderTile(wi, fptr->tile, fptr->fill_color, FieldRenderCB, bbox, - (ZnPoint *) bbox); - } - else { /* Fill solid */ - color = ZnGetGradientColor(fptr->fill_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - FieldRenderCB(bbox); - } - } - } - - /* - * Draw the image and the text, which one is back depends on - * the value of text_on_top. - */ - for (j = 0; j < 2; j++) { - if ((j == 0 && ISSET(fptr->flags, TEXT_ON_TOP_BIT)) || - (j == 1 && ISCLEAR(fptr->flags, TEXT_ON_TOP_BIT))) { - /* - * Draw the image. - */ - if (fptr->image != ZnUnspecifiedImage) { - ZnRenderIcon(wi, fptr->image, fptr->fill_color, - &pm_bbox->orig, False); - } - } - else if (fptr->text) { - /* - * Draw the text. - */ - num_bytes = strlen(fptr->text); - if (num_bytes) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (sel_start >= 0) { - color = ZnGetGradientColor(ti->sel_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glBegin(GL_QUADS); - glVertex2d(text_bbox->orig.x+sel_start, text_bbox->orig.y); - glVertex2d(text_bbox->orig.x+sel_stop, text_bbox->orig.y); - glVertex2d(text_bbox->orig.x+sel_stop, text_bbox->corner.y); - glVertex2d(text_bbox->orig.x+sel_start, text_bbox->corner.y); - glEnd(); - } - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - color = ZnGetGradientColor(fptr->color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glBindTexture(GL_TEXTURE_2D, ZnTexFontTex(fptr->tfi)); - glPushMatrix(); - glTranslated(text_pos->x, text_pos->y, 0.0); - ZnRenderString(fptr->tfi, fptr->text, num_bytes); - glPopMatrix(); - glDisable(GL_TEXTURE_2D); - } - } - if (cursor >= 0) { - glLineWidth((GLfloat) ti->insert_width); - color = ZnGetGradientColor(ti->insert_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - xs = text_bbox->orig.x + cursor; - glBegin(GL_LINES); - glVertex2d(xs, text_bbox->orig.y); - glVertex2d(xs, text_bbox->corner.y); - glEnd(); - } - } - - /* - * Draw the border relief. - */ - if ((fptr->relief != ZN_RELIEF_FLAT) && (fptr->relief_thickness > 1)) { - ZnPoint p[5]; - - p[0].x = bbox->orig.x; - p[0].y = bbox->orig.y; - p[2].x = bbox->corner.x; - p[2].y = bbox->corner.y; - p[1].x = p[0].x; - p[1].y = p[2].y; - p[3].x = p[2].x; - p[3].y = p[0].y; - p[4] = p[0]; - ZnRenderPolygonRelief(wi, fptr->relief, fptr->gradient, - False, p, 5, fptr->relief_thickness); - } - - /* - * Draw the border line. - */ - if (fptr->border_edges != ZN_NO_BORDER) { - color = ZnGetGradientColor(fptr->border_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glLineWidth(1.5); - ZnSetLineStyle(wi, ZN_LINE_SIMPLE); - glBegin(GL_LINES); - if (fptr->border_edges & ZN_LEFT_BORDER) { - glVertex2d(bbox->orig.x, bbox->orig.y); - glVertex2d(bbox->orig.x, bbox->corner.y); - } - if (fptr->border_edges & ZN_RIGHT_BORDER) { - glVertex2d(bbox->corner.x, bbox->orig.y); - glVertex2d(bbox->corner.x, bbox->corner.y); - } - if (fptr->border_edges & ZN_TOP_BORDER) { - glVertex2d(bbox->orig.x, bbox->orig.y); - glVertex2d(bbox->corner.x, bbox->orig.y); - } - if (fptr->border_edges & ZN_BOTTOM_BORDER) { - glVertex2d(bbox->orig.x, bbox->corner.y); - glVertex2d(bbox->corner.x, bbox->corner.y); - } - if (fptr->border_edges & ZN_OBLIQUE) { - glVertex2d(bbox->orig.x, bbox->orig.y); - glVertex2d(bbox->corner.x, bbox->corner.y); - } - if (fptr->border_edges & ZN_COUNTER_OBLIQUE) { - glVertex2d(bbox->orig.x, bbox->corner.y); - glVertex2d(bbox->corner.x, bbox->orig.y); - } - glEnd(); - } -} -#endif - -#ifdef GL -static void -RenderFields(ZnFieldSet field_set) -{ - /* glDisable(GL_LINE_SMOOTH);*/ - FieldsEngine(field_set, RenderField); - /* glEnable(GL_LINE_SMOOTH);*/ -} -#else -static void -RenderFields(ZnFieldSet field_set) -{ -} -#endif - - -/* - ********************************************************************************** - * - * PostScriptFields -- - * - ********************************************************************************** - */ -static int -PsField(ZnWInfo *wi, - ZnBool prepass, - Field fptr, - ZnBBox *bbox, - ZnBBox *pm_bbox, - ZnPoint *text_pos, - ZnBBox *text_bbox) -{ - int j; - char path[250]; - - /* - * Must set the clip rect for the whole field, not only for stipple fill. - */ - if (ISSET(fptr->flags, FILLED_BIT)) { - if (fptr->tile != ZnUnspecifiedImage) { - if (!ZnImageIsBitmap(fptr->tile)) { /* Fill tiled */ - /* TODO No support yet */ - } - else { /* Fill stippled */ - Tcl_AppendResult(wi->interp, "gsave\n", NULL); - if (Tk_PostscriptColor(wi->interp, wi->ps_info, - ZnGetGradientColor(fptr->fill_color, 0.0, NULL)) != TCL_OK) { - return TCL_ERROR; - } - if (Tk_PostscriptStipple(wi->interp, wi->win, wi->ps_info, - ZnImagePixmap(fptr->tile, wi->win)) != TCL_OK) { - return TCL_ERROR; - } - Tcl_AppendResult(wi->interp, "grestore\n", NULL); - } - } - else { /* Fill solid */ - if (Tk_PostscriptColor(wi->interp, wi->ps_info, - ZnGetGradientColor(fptr->fill_color, 0.0, NULL)) != TCL_OK) { - return TCL_ERROR; - } - Tcl_AppendResult(wi->interp, "fill\n", NULL); - } - } - - /* - * 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(fptr->flags, TEXT_ON_TOP_BIT)) || - (j == 1 && ISCLEAR(fptr->flags, TEXT_ON_TOP_BIT))) { - /* - * Draw the image. - */ - if (fptr->image != ZnUnspecifiedImage) { - int w, h; - - Tcl_AppendResult(wi->interp, "gsave\n", NULL); - sprintf(path, "%.15g %.15g translate 1 -1 scale\n", - pm_bbox->orig.x, pm_bbox->corner.y); - Tcl_AppendResult(wi->interp, path, NULL); - w = ZnNearestInt(pm_bbox->corner.x - pm_bbox->orig.x); - h = ZnNearestInt(pm_bbox->corner.y - pm_bbox->orig.y); - if (Tk_PostscriptImage(ZnImageTkImage(fptr->image), wi->interp, wi->win, - wi->ps_info, 0, 0, w, h, prepass) != TCL_OK) { - return TCL_ERROR; - } - Tcl_AppendResult(wi->interp, "grestore\n", NULL); - } - } - else if (fptr->text) { - Tcl_AppendResult(wi->interp, "gsave\n", NULL); - if (Tk_PostscriptFont(wi->interp, wi->ps_info, fptr->font) != TCL_OK) { - return TCL_ERROR; - } - if (Tk_PostscriptColor(wi->interp, wi->ps_info, - ZnGetGradientColor(fptr->color, 0.0, NULL)) != TCL_OK) { - return TCL_ERROR; - } - /* - * TODO pourquoi la text_bbox ne donne pas un texte centré verticalement ? - * Apparement la fonte PostScript n'est pas centrée comme la fonte X. - * Il faut donc opérer le calcul dans le code PostScript de DrawText. - */ - sprintf(path, "%.15g %.15g translate 1 -1 scale 0 0 [\n", - text_bbox->orig.x, text_bbox->orig.y); - Tcl_AppendResult(wi->interp, path, NULL); - /* - * strlen should do the work of counting _bytes_ in the utf8 string. - */ - ZnPostscriptString(wi->interp, fptr->text, strlen(fptr->text)); - Tcl_AppendResult(wi->interp, "] 0 0.0 0.0 0.0 false DrawText\n", NULL); - Tcl_AppendResult(wi->interp, "grestore\n", NULL); - } - } - - /* - * Draw the border relief. - */ - if ((fptr->relief != ZN_RELIEF_FLAT) && (fptr->relief_thickness > 1)) { - } - - /* - * Draw the border line. - */ - if (fptr->border_edges != ZN_NO_BORDER) { - if (Tk_PostscriptColor(wi->interp, wi->ps_info, - ZnGetGradientColor(fptr->border_color, 0.0, NULL)) != TCL_OK) { - return TCL_ERROR; - } - Tcl_AppendResult(wi->interp, "1 setlinewidth 0 setlinejoin 2 setlinecap\n", NULL); - if (fptr->border_edges & ZN_LEFT_BORDER) { - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto stroke\n", - bbox->orig.x, bbox->orig.y, bbox->orig.x, bbox->corner.y); - Tcl_AppendResult(wi->interp, path, NULL); - } - if (fptr->border_edges & ZN_RIGHT_BORDER) { - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto stroke\n", - bbox->corner.x, bbox->orig.y, bbox->corner.x, bbox->corner.y); - Tcl_AppendResult(wi->interp, path, NULL); - } - if (fptr->border_edges & ZN_TOP_BORDER) { - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto stroke\n", - bbox->orig.x, bbox->orig.y, bbox->corner.x, bbox->orig.y); - Tcl_AppendResult(wi->interp, path, NULL); - } - if (fptr->border_edges & ZN_BOTTOM_BORDER) { - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto stroke\n", - bbox->orig.x, bbox->corner.y, bbox->corner.x, bbox->corner.y); - Tcl_AppendResult(wi->interp, path, NULL); - } - if (fptr->border_edges & ZN_OBLIQUE) { - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto stroke\n", - bbox->orig.x, bbox->orig.y, bbox->corner.x, bbox->corner.y); - Tcl_AppendResult(wi->interp, path, NULL); - } - if (fptr->border_edges & ZN_COUNTER_OBLIQUE) { - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto stroke\n", - bbox->corner.x, bbox->orig.y, bbox->orig.x, bbox->corner.y); - Tcl_AppendResult(wi->interp, path, NULL); - } - } - - return TCL_OK; -} - -static int -PostScriptFields(ZnFieldSet field_set, - ZnBool prepass, - ZnBBox *area) -{ - ZnWInfo *wi = field_set->item->wi; - ZnBBox lclip_bbox, fclip_bbox; - ZnBBox bbox, text_bbox, pm_bbox; - ZnPoint text_pos; - int i, num_fields; - ZnDim lwidth, lheight; - Field fptr; - char path[250]; - - if (!field_set->num_fields) { - return TCL_OK; - } - - - if (field_set->label_format && ZnLFNumFields(field_set->label_format)) { - /* - * Fields are drawn with respect to a point already converted - * to device space, so we need to reinstate the initial transform. - */ - Tcl_AppendResult(wi->interp, "/InitialTransform load setmatrix\n", NULL); - - lclip_bbox.orig.x = ZnNearestInt(field_set->label_pos.x); - lclip_bbox.orig.y = ZnNearestInt(field_set->label_pos.y); - GetLabelBBox(field_set, &lwidth, &lheight); - lclip_bbox.corner.x = lclip_bbox.orig.x + lwidth; - lclip_bbox.corner.y = lclip_bbox.orig.y + lheight; - - num_fields = ZnLFNumFields(field_set->label_format); - for (i = 0; i < num_fields; i++) { - fptr = &field_set->fields[i]; - - if (ISCLEAR(fptr->flags, FIELD_VISIBLE_BIT)) { - continue; - } - - GetFieldBBox(field_set, i, &bbox); - ZnIntersectBBox(&lclip_bbox, &bbox, &fclip_bbox); - if (ZnIsEmptyBBox(&fclip_bbox)) { - /* The field is outside the label bbox */ - continue; - } - - /* - * Setup a clip area around the field - */ - Tcl_AppendResult(wi->interp, "gsave\n", NULL); - sprintf(path, "%.15g %.15g moveto %.15g %.15g lineto %.15g %.15g lineto %.15g %.15g", - fclip_bbox.orig.x, fclip_bbox.orig.y, fclip_bbox.corner.x+1, fclip_bbox.orig.y, - fclip_bbox.corner.x+1, fclip_bbox.corner.y+1, fclip_bbox.orig.x, - fclip_bbox.corner.y+1); - Tcl_AppendResult(wi->interp, path, " lineto closepath clip\n", NULL); - - if (fptr->text) { - ComputeFieldTextLocation(fptr, &bbox, &text_pos, &text_bbox); - } - if (fptr->image != ZnUnspecifiedImage) { - ComputeFieldImageLocation(fptr, &bbox, &pm_bbox); - } - - if (PsField(wi, prepass, fptr, &bbox, &pm_bbox, &text_pos, &text_bbox) != TCL_OK) { - return TCL_ERROR; - } - - Tcl_AppendResult(wi->interp, "grestore\n", NULL); - } - } - - return TCL_OK; -} - - -/* - ********************************************************************************** - * - * IsFieldsSensitive -- - * - ********************************************************************************** - */ -static ZnBool -IsFieldSensitive(ZnFieldSet field_set, - int part) -{ - if ((part >= 0) && ((unsigned int) part < field_set->num_fields)) { - return ISSET(field_set->fields[part].flags, FIELD_SENSITIVE_BIT); - } - else { - return False; - } -} - - -/* - ********************************************************************************** - * - * FieldsPick -- - * Return the first field that contains . - * A field is selected if is over a non transparent area. - * Such areas are : a solid filled background, a text, an icon. - * This does *NOT* do with *GLOBAL* visible and sensitive. - * But we need to take into account local field visible and - * sensitive as they modifiy local transparency. Local means - * within a single item. - * - ********************************************************************************** - */ -static double -FieldsPick(ZnFieldSet field_set, - ZnPoint *p, - int *part) -{ - Field fptr; - ZnBBox bbox; - unsigned int best_field = 0; - int i; - ZnReal new_dist, dist = 1e40; - - if (!field_set->num_fields) { - return dist; - } - - if (field_set->label_format) { - for (i = ZnLFNumFields(field_set->label_format)-1; i >= 0; i--) { - fptr = &field_set->fields[i]; - - if (ISCLEAR(fptr->flags, FIELD_VISIBLE_BIT) && - ISCLEAR(fptr->flags, FIELD_SENSITIVE_BIT)) { - continue; - } - - GetFieldBBox(field_set, (unsigned int) i, &bbox); - - new_dist = ZnRectangleToPointDist(&bbox, p); - if (new_dist < dist) { - dist = new_dist; - best_field = i; - } - if (dist <= 0.0) { - dist = 0.0; - break; - } - } - } - - *part = best_field; - return dist; -} - - -/* - ********************************************************************************** - * - * FieldsToArea -- - * Return -1 if no field is in the given area, 1 if they are - * all in it or 0 if there is some overlap. The function consider - * only fields that are either sensible or visible. - * - ********************************************************************************** - */ -static int -FieldsToArea(ZnFieldSet field_set, - ZnBBox *area) -{ - Field fptr; - ZnBBox bbox; - int i, inside = -1; - ZnBool first_done = False; - - if (!field_set->num_fields) { - return inside; - } - - for (i = ZnLFNumFields(field_set->label_format)-1; i >= 0; i--) { - fptr = &field_set->fields[i]; - - if (ISCLEAR(fptr->flags, FIELD_VISIBLE_BIT) && - ISCLEAR(fptr->flags, FIELD_SENSITIVE_BIT)) { - continue; - } - - GetFieldBBox(field_set, (unsigned int) i, &bbox); - if (!first_done) { - first_done = True; - inside = ZnBBoxInBBox(&bbox, area); - if (inside == 0) { - return 0; - } - } - else { - if (ZnBBoxInBBox(&bbox, area) != inside) { - return 0; - } - } - } - - return inside; -} - - -/* - ********************************************************************************** - * - * SetFieldsAutoAlign -- - * - ********************************************************************************** - */ -static void -SetFieldsAutoAlign(ZnFieldSet fs, - int alignment) -{ - unsigned int i; - Field field; - - if (!fs->num_fields) { - return; - } - if ((alignment >= ZN_AA_LEFT) && (alignment <= ZN_AA_RIGHT)) { - for (i = 0; i < fs->num_fields; i++) { - field = &fs->fields[i]; - if (field->auto_alignment.automatic) { - field->alignment = field->auto_alignment.align[alignment]; - } - } - } -} - -static char * -GetFieldStruct(ZnFieldSet fs, - int field) -{ - if ((unsigned int) field >= fs->num_fields) { - return NULL; - } - return (char *) &fs->fields[field]; -} - - -static unsigned int -NumFields(ZnFieldSet fs) -{ - return fs->num_fields; -} - - -struct _ZnFIELD ZnFIELD = { - field_attrs, - - InitFields, - CloneFields, - FreeFields, - ConfigureField, - QueryField, - DrawFields, - RenderFields, - PostScriptFields, - FieldsToArea, - IsFieldSensitive, - FieldsPick, - FieldIndex, - FieldInsertChars, - FieldDeleteChars, - FieldCursor, - FieldSelection, - LeaderToLabel, - GetLabelBBox, - GetFieldBBox, - SetFieldsAutoAlign, - ClearFieldCache, - GetFieldStruct, - NumFields -}; -- cgit v1.1