aboutsummaryrefslogtreecommitdiff
path: root/generic/Field.c
diff options
context:
space:
mode:
authorcvs2svn2005-06-10 10:29:11 +0000
committercvs2svn2005-06-10 10:29:11 +0000
commit960cdf29197bc3f5922110cf26627aa9709ac79b (patch)
tree7d6e4a472376b203d21826c2230b4a8c6a9024bd /generic/Field.c
parent3fc9c4bc1d6f70db41ad418992bf3d461059d3c0 (diff)
downloadtkzinc-960cdf29197bc3f5922110cf26627aa9709ac79b.zip
tkzinc-960cdf29197bc3f5922110cf26627aa9709ac79b.tar.gz
tkzinc-960cdf29197bc3f5922110cf26627aa9709ac79b.tar.bz2
tkzinc-960cdf29197bc3f5922110cf26627aa9709ac79b.tar.xz
This commit was manufactured by cvs2svn to create branch 'bogue40'.
Diffstat (limited to 'generic/Field.c')
-rw-r--r--generic/Field.c2584
1 files changed, 0 insertions, 2584 deletions
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 <string.h>
-#include <stdlib.h>
-
-
-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 <start, end> 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 <x, y>.
- * A field is selected if <x, y> 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
-};