summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bltGrMarkerBitmap.C345
-rw-r--r--bltGrMarkerBitmap.h72
-rw-r--r--src/bltGrElemLine.C67
-rw-r--r--src/bltGrMarker.C164
-rw-r--r--src/bltGrMarker.h39
-rw-r--r--src/bltGrMarkerLine.C178
-rw-r--r--src/bltGrMarkerLine.h67
-rw-r--r--src/bltGrMarkerPolygon.C160
-rw-r--r--src/bltGrMarkerPolygon.h89
-rw-r--r--src/bltGrMarkerText.C183
-rw-r--r--src/bltGrMarkerText.h45
-rw-r--r--src/bltGrText.C138
-rw-r--r--src/bltGrText.h10
-rw-r--r--tests/bitmapmarker.tcl8
-rw-r--r--tests/textmarker.tcl2
15 files changed, 630 insertions, 937 deletions
diff --git a/bltGrMarkerBitmap.C b/bltGrMarkerBitmap.C
index cf008b9..da754bb 100644
--- a/bltGrMarkerBitmap.C
+++ b/bltGrMarkerBitmap.C
@@ -34,8 +34,6 @@ extern "C" {
#include "bltGrMarkerBitmap.h"
-#define GETBITMAP(b) (((b)->destBitmap == None) ? (b)->srcBitmap : (b)->destBitmap)
-
static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
"center", -1, Tk_Offset(BitmapMarker, anchor), 0, NULL, 0},
@@ -46,10 +44,7 @@ static Tk_OptionSpec optionSpecs[] = {
"Bitmap all", -1, Tk_Offset(BitmapMarker, obj.tags),
TK_OPTION_NULL_OK, &listObjOption, 0},
{TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
- NULL, -1, Tk_Offset(BitmapMarker, srcBitmap), TK_OPTION_NULL_OK, NULL, 0},
- {TK_OPTION_CUSTOM, "-coords", "coords", "Coords",
- NULL, -1, Tk_Offset(BitmapMarker, worldPts),
- TK_OPTION_NULL_OK, &coordsObjOption, 0},
+ NULL, -1, Tk_Offset(BitmapMarker, bitmap), TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_STRING, "-element", "element", "Element",
NULL, -1, Tk_Offset(BitmapMarker, elemName), TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
@@ -64,14 +59,16 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY",
"y", -1, Tk_Offset(BitmapMarker, axes.y), 0, &yAxisObjOption, 0},
{TK_OPTION_SYNONYM, "-outline", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
- // {TK_OPTION_DOUBLE, "-rotate", "rotate", "Rotate",
- // "0", -1, Tk_Offset(BitmapMarker, reqAngle), 0, NULL, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
"normal", -1, Tk_Offset(BitmapMarker, state), 0, &stateObjOption, 0},
{TK_OPTION_BOOLEAN, "-under", "under", "Under",
"no", -1, Tk_Offset(BitmapMarker, drawUnder), 0, NULL, 0},
+ {TK_OPTION_DOUBLE, "-x", "x", "X",
+ "0", -1, Tk_Offset(BitmapMarker, world.x), 0, NULL, 0},
{TK_OPTION_PIXELS, "-xoffset", "xOffset", "XOffset",
"0", -1, Tk_Offset(BitmapMarker, xOffset), 0, NULL, 0},
+ {TK_OPTION_DOUBLE, "-y", "y", "Y",
+ "0", -1, Tk_Offset(BitmapMarker, world.y), 0, NULL, 0},
{TK_OPTION_PIXELS, "-yoffset", "yOffset", "YOffset",
"0", -1, Tk_Offset(BitmapMarker, yOffset), 0, NULL, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
@@ -106,325 +103,170 @@ Marker* Blt_CreateBitmapProc(Graph* graphPtr)
return (Marker*)bmPtr;
}
-static int ConfigureBitmapProc(Marker *markerPtr)
+static int ConfigureBitmapProc(Marker* markerPtr)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
- GC newGC;
- XGCValues gcValues;
- unsigned long gcMask;
- if (bmPtr->srcBitmap == None)
+ if (bmPtr->bitmap == None)
return TCL_OK;
- bmPtr->angle = fmod(bmPtr->reqAngle, 360.0);
- if (bmPtr->angle < 0.0)
- bmPtr->angle += 360.0;
-
- gcMask = 0;
-
+ XGCValues gcValues;
+ unsigned long gcMask = 0;
if (bmPtr->outlineColor) {
gcMask |= GCForeground;
gcValues.foreground = bmPtr->outlineColor->pixel;
}
if (bmPtr->fillColor) {
- /* Opaque bitmap: both foreground and background (fill) colors
- * are used. */
+ // Opaque bitmap: both foreground and background (fill) colors are used
gcValues.background = bmPtr->fillColor->pixel;
gcMask |= GCBackground;
- } else {
- /* Transparent bitmap: set the clip mask to the current bitmap. */
- gcValues.clip_mask = bmPtr->srcBitmap;
+ }
+ else {
+ // Transparent bitmap: set the clip mask to the current bitmap
+ gcValues.clip_mask = bmPtr->bitmap;
gcMask |= GCClipMask;
}
- /*
- * This is technically a shared GC, but we're going to set/change the clip
- * origin anyways before we draw the bitmap. This relies on the fact that
- * no other client will be allocated this GC with the GCClipMask set to
- * this particular bitmap.
- */
- newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
- if (bmPtr->gc) {
+ // This is technically a shared GC, but we're going to set/change the clip
+ // origin anyways before we draw the bitmap. This relies on the fact that
+ // no other client will be allocated this GC with the GCClipMask set to
+ // this particular bitmap.
+ GC newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+ if (bmPtr->gc)
Tk_FreeGC(graphPtr->display, bmPtr->gc);
- }
bmPtr->gc = newGC;
- /* Create the background GC containing the fill color. */
-
+ // Create the background GC containing the fill color
if (bmPtr->fillColor) {
gcValues.foreground = bmPtr->fillColor->pixel;
newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
- if (bmPtr->fillGC) {
+ if (bmPtr->fillGC)
Tk_FreeGC(graphPtr->display, bmPtr->fillGC);
- }
bmPtr->fillGC = newGC;
}
markerPtr->flags |= MAP_ITEM;
- if (markerPtr->drawUnder) {
+ if (markerPtr->drawUnder)
graphPtr->flags |= CACHE_DIRTY;
- }
Blt_EventuallyRedrawGraph(graphPtr);
return TCL_OK;
}
-static void MapBitmapProc(Marker *markerPtr)
+static void MapBitmapProc(Marker* markerPtr)
{
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
- Region2d extents;
Graph* graphPtr = markerPtr->obj.graphPtr;
- Point2d anchorPt;
- Point2d corner1, corner2;
- int destWidth, destHeight;
- int srcWidth, srcHeight;
- int i;
- if (bmPtr->srcBitmap == None)
+ if (bmPtr->bitmap == None)
return;
+
+ int width, height;
+ Tk_SizeOfBitmap(graphPtr->display, bmPtr->bitmap, &width, &height);
- if (bmPtr->destBitmap != None) {
- Tk_FreePixmap(graphPtr->display, bmPtr->destBitmap);
- bmPtr->destBitmap = None;
- }
- /*
- * Collect the coordinates. The number of coordinates will determine the
- * calculations to be made.
- *
- * x1 y1 A single pair of X-Y coordinates. They represent
- * the anchor position of the bitmap.
- *
- * x1 y1 x2 y2 Two pairs of X-Y coordinates. They represent
- * two opposite corners of a bounding rectangle. The
- * bitmap is possibly rotated and scaled to fit into
- * this box.
- *
- */
- Tk_SizeOfBitmap(graphPtr->display, bmPtr->srcBitmap, &srcWidth,
- &srcHeight);
- corner1 = Blt_MapPoint(markerPtr->worldPts, &markerPtr->axes);
- if (markerPtr->nWorldPts > 1) {
- double hold;
-
- corner2 = Blt_MapPoint(markerPtr->worldPts + 1, &markerPtr->axes);
- /* Flip the corners if necessary */
- if (corner1.x > corner2.x) {
- hold = corner1.x, corner1.x = corner2.x, corner2.x = hold;
- }
- if (corner1.y > corner2.y) {
- hold = corner1.y, corner1.y = corner2.y, corner2.y = hold;
- }
- } else {
- corner2.x = corner1.x + srcWidth - 1;
- corner2.y = corner1.y + srcHeight - 1;
- }
- destWidth = (int)(corner2.x - corner1.x) + 1;
- destHeight = (int)(corner2.y - corner1.y) + 1;
-
- if (markerPtr->nWorldPts == 1) {
- anchorPt = Blt_AnchorPoint(corner1.x, corner1.y, (double)destWidth,
- (double)destHeight, bmPtr->anchor);
- }
- else
- anchorPt = corner1;
-
+ Point2d anchorPt = Blt_MapPoint(&bmPtr->world, &markerPtr->axes);
+ anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, width, height,
+ bmPtr->anchor);
anchorPt.x += markerPtr->xOffset;
anchorPt.y += markerPtr->yOffset;
- /* Check if the bitmap sits at least partially in the plot area. */
- extents.left = anchorPt.x;
- extents.top = anchorPt.y;
- extents.right = anchorPt.x + destWidth - 1;
- extents.bottom = anchorPt.y + destHeight - 1;
+ Region2d extents;
+ extents.left = anchorPt.x;
+ extents.top = anchorPt.y;
+ extents.right = anchorPt.x + width - 1;
+ extents.bottom = anchorPt.y + height - 1;
markerPtr->clipped = Blt_BoxesDontOverlap(graphPtr, &extents);
- if (markerPtr->clipped) {
- return; /* Bitmap is offscreen. Don't generate
- * rotated or scaled bitmaps. */
- }
- /*
- * Scale the bitmap if necessary. It's a little tricky because we only
- * want to scale what's visible on the screen, not the entire bitmap.
- */
- if ((bmPtr->angle != 0.0f) || (destWidth != srcWidth) ||
- (destHeight != srcHeight)) {
- int regionX, regionY, regionWidth, regionHeight;
- double left, right, top, bottom;
-
- /* Ignore parts of the bitmap outside of the plot area. */
- left = MAX(graphPtr->left, extents.left);
- right = MIN(graphPtr->right, extents.right);
- top = MAX(graphPtr->top, extents.top);
- bottom = MIN(graphPtr->bottom, extents.bottom);
-
- /* Determine the portion of the scaled bitmap to display. */
- regionX = regionY = 0;
- if (graphPtr->left > extents.left) {
- regionX = (int)(graphPtr->left - extents.left);
- }
- if (graphPtr->top > extents.top) {
- regionY = (int)(graphPtr->top - extents.top);
- }
- regionWidth = (int)(right - left) + 1;
- regionHeight = (int)(bottom - top) + 1;
-
- anchorPt.x = left;
- anchorPt.y = top;
- bmPtr->destBitmap = Blt_ScaleRotateBitmapArea(graphPtr->tkwin, bmPtr->srcBitmap, srcWidth, srcHeight, regionX, regionY, regionWidth, regionHeight, destWidth, destHeight, bmPtr->angle);
- bmPtr->destWidth = regionWidth;
- bmPtr->destHeight = regionHeight;
- } else {
- bmPtr->destWidth = srcWidth;
- bmPtr->destHeight = srcHeight;
- bmPtr->destBitmap = None;
- }
+ if (markerPtr->clipped)
+ return;
+
+ bmPtr->width = width;
+ bmPtr->height = height;
bmPtr->anchorPt = anchorPt;
- {
- double xScale, yScale;
- double tx, ty;
- double rotWidth, rotHeight;
- Point2d polygon[5];
- int n;
-
- /*
- * Compute a polygon to represent the background area of the bitmap.
- * This is needed for backgrounds of arbitrarily rotated bitmaps. We
- * also use it to print a background in PostScript.
- */
- Blt_GetBoundingBox(srcWidth, srcHeight, bmPtr->angle, &rotWidth,
- &rotHeight, polygon);
- xScale = (double)destWidth / rotWidth;
- yScale = (double)destHeight / rotHeight;
+
+ // Compute a polygon to represent the background area of the bitmap.
+ // This is needed for print a background in PostScript.
+ double rotWidth, rotHeight;
+ Point2d polygon[5];
+ Blt_GetBoundingBox(width, height, 0, &rotWidth, &rotHeight, polygon);
- /*
- * Adjust each point of the polygon. Both scale it to the new size and
- * translate it to the actual screen position of the bitmap.
- */
- tx = extents.left + destWidth * 0.5;
- ty = extents.top + destHeight * 0.5;
- for (i = 0; i < 4; i++) {
- polygon[i].x = (polygon[i].x * xScale) + tx;
- polygon[i].y = (polygon[i].y * yScale) + ty;
- }
- Blt_GraphExtents(graphPtr, &extents);
- n = Blt_PolyRectClip(&extents, polygon, 4, bmPtr->outline);
- if (n < 3) {
- memcpy(&bmPtr->outline, polygon, sizeof(Point2d) * 4);
- bmPtr->nOutlinePts = 4;
- } else {
- bmPtr->nOutlinePts = n;
- }
+ // Adjust each point of the polygon. Both scale it to the new size and
+ // translate it to the actual screen position of the bitmap.
+ double tx = extents.left + width * 0.5;
+ double ty = extents.top + height * 0.5;
+ for (int ii=0; ii<4; ii++) {
+ polygon[ii].x = (polygon[ii].x) + tx;
+ polygon[ii].y = (polygon[ii].y) + ty;
+ }
+ Blt_GraphExtents(graphPtr, &extents);
+ int nn = Blt_PolyRectClip(&extents, polygon, 4, bmPtr->outline);
+ if (nn < 3) {
+ memcpy(&bmPtr->outline, polygon, sizeof(Point2d) * 4);
+ bmPtr->nOutlinePts = 4;
}
+ else
+ bmPtr->nOutlinePts = nn;
}
-static int PointInBitmapProc(Marker *markerPtr, Point2d *samplePtr)
+static int PointInBitmapProc(Marker* markerPtr, Point2d *samplePtr)
{
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
- if (bmPtr->srcBitmap == None)
+ if (bmPtr->bitmap == None)
return 0;
- if (bmPtr->angle != 0.0f) {
- Point2d points[MAX_OUTLINE_POINTS];
- int i;
-
- /*
- * Generate the bounding polygon (isolateral) for the bitmap and see
- * if the point is inside of it.
- */
- for (i = 0; i < bmPtr->nOutlinePts; i++) {
- points[i].x = bmPtr->outline[i].x + bmPtr->anchorPt.x;
- points[i].y = bmPtr->outline[i].y + bmPtr->anchorPt.y;
- }
- return Blt_PointInPolygon(samplePtr, points, bmPtr->nOutlinePts);
- }
return ((samplePtr->x >= bmPtr->anchorPt.x) &&
- (samplePtr->x < (bmPtr->anchorPt.x + bmPtr->destWidth)) &&
+ (samplePtr->x < (bmPtr->anchorPt.x + bmPtr->width)) &&
(samplePtr->y >= bmPtr->anchorPt.y) &&
- (samplePtr->y < (bmPtr->anchorPt.y + bmPtr->destHeight)));
+ (samplePtr->y < (bmPtr->anchorPt.y + bmPtr->height)));
}
-static int RegionInBitmapProc(Marker *markerPtr, Region2d *extsPtr,
+static int RegionInBitmapProc(Marker* markerPtr, Region2d *extsPtr,
int enclosed)
{
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
- if (markerPtr->nWorldPts < 1)
- return FALSE;
-
- if (bmPtr->angle != 0.0f) {
- Point2d points[MAX_OUTLINE_POINTS];
- int i;
-
- /*
- * Generate the bounding polygon (isolateral) for the bitmap and see
- * if the point is inside of it.
- */
- for (i = 0; i < bmPtr->nOutlinePts; i++) {
- points[i].x = bmPtr->outline[i].x + bmPtr->anchorPt.x;
- points[i].y = bmPtr->outline[i].y + bmPtr->anchorPt.y;
- }
- return Blt_RegionInPolygon(extsPtr, points, bmPtr->nOutlinePts,
- enclosed);
- }
if (enclosed) {
return ((bmPtr->anchorPt.x >= extsPtr->left) &&
(bmPtr->anchorPt.y >= extsPtr->top) &&
- ((bmPtr->anchorPt.x + bmPtr->destWidth) <= extsPtr->right) &&
- ((bmPtr->anchorPt.y + bmPtr->destHeight) <= extsPtr->bottom));
+ ((bmPtr->anchorPt.x + bmPtr->width) <= extsPtr->right) &&
+ ((bmPtr->anchorPt.y + bmPtr->height) <= extsPtr->bottom));
}
+
return !((bmPtr->anchorPt.x >= extsPtr->right) ||
(bmPtr->anchorPt.y >= extsPtr->bottom) ||
- ((bmPtr->anchorPt.x + bmPtr->destWidth) <= extsPtr->left) ||
- ((bmPtr->anchorPt.y + bmPtr->destHeight) <= extsPtr->top));
+ ((bmPtr->anchorPt.x + bmPtr->width) <= extsPtr->left) ||
+ ((bmPtr->anchorPt.y + bmPtr->height) <= extsPtr->top));
}
-static void DrawBitmapProc(Marker *markerPtr, Drawable drawable)
+static void DrawBitmapProc(Marker* markerPtr, Drawable drawable)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
- Pixmap bitmap = GETBITMAP(bmPtr);
- if ((bitmap == None) || (bmPtr->destWidth < 1) || (bmPtr->destHeight < 1))
+ if ((bmPtr->bitmap == None) || (bmPtr->width < 1) || (bmPtr->height < 1))
return;
- double rangle = fmod(bmPtr->angle, 90.0);
- if ((bmPtr->fillColor == NULL) || (rangle != 0.0)) {
-
- /*
- * If the bitmap is rotated and a filled background is required, then
- * a filled polygon is drawn before the bitmap.
- */
- if (bmPtr->fillColor) {
- int i;
- XPoint polygon[MAX_OUTLINE_POINTS];
-
- for (i = 0; i < bmPtr->nOutlinePts; i++) {
- polygon[i].x = (short int)bmPtr->outline[i].x;
- polygon[i].y = (short int)bmPtr->outline[i].y;
- }
- XFillPolygon(graphPtr->display, drawable, bmPtr->fillGC,
- polygon, bmPtr->nOutlinePts, Convex, CoordModeOrigin);
- }
- XSetClipMask(graphPtr->display, bmPtr->gc, bitmap);
- XSetClipOrigin(graphPtr->display, bmPtr->gc, (int)bmPtr->anchorPt.x,
- (int)bmPtr->anchorPt.y);
- } else {
+ if (bmPtr->fillColor == NULL) {
+ XSetClipMask(graphPtr->display, bmPtr->gc, bmPtr->bitmap);
+ XSetClipOrigin(graphPtr->display, bmPtr->gc, bmPtr->anchorPt.x,
+ bmPtr->anchorPt.y);
+ }
+ else {
XSetClipMask(graphPtr->display, bmPtr->gc, None);
XSetClipOrigin(graphPtr->display, bmPtr->gc, 0, 0);
}
- XCopyPlane(graphPtr->display, bitmap, drawable, bmPtr->gc, 0, 0,
- bmPtr->destWidth, bmPtr->destHeight, (int)bmPtr->anchorPt.x,
- (int)bmPtr->anchorPt.y, 1);
+ XCopyPlane(graphPtr->display, bmPtr->bitmap, drawable, bmPtr->gc, 0, 0,
+ bmPtr->width, bmPtr->height, bmPtr->anchorPt.x,
+ bmPtr->anchorPt.y, 1);
}
-static void BitmapToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+static void BitmapToPostscriptProc(Marker* markerPtr, Blt_Ps ps)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
- Pixmap bitmap = GETBITMAP(bmPtr);
- if ((bitmap == None) || (bmPtr->destWidth < 1) || (bmPtr->destHeight < 1))
+ if ((bmPtr->bitmap == None) || (bmPtr->width < 1) || (bmPtr->height < 1))
return;
if (bmPtr->fillColor) {
@@ -435,19 +277,19 @@ static void BitmapToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
Blt_Ps_Format(ps,
" gsave\n %g %g translate\n %d %d scale\n",
- bmPtr->anchorPt.x, bmPtr->anchorPt.y + bmPtr->destHeight,
- bmPtr->destWidth, -bmPtr->destHeight);
+ bmPtr->anchorPt.x, bmPtr->anchorPt.y + bmPtr->height,
+ bmPtr->width, -bmPtr->height);
Blt_Ps_Format(ps, " %d %d true [%d 0 0 %d 0 %d] {",
- bmPtr->destWidth, bmPtr->destHeight, bmPtr->destWidth,
- -bmPtr->destHeight, bmPtr->destHeight);
- Blt_Ps_XSetBitmapData(ps, graphPtr->display, bitmap,
- bmPtr->destWidth, bmPtr->destHeight);
+ bmPtr->width, bmPtr->height, bmPtr->width,
+ -bmPtr->height, bmPtr->height);
+ Blt_Ps_XSetBitmapData(ps, graphPtr->display, bmPtr->bitmap,
+ bmPtr->width, bmPtr->height);
Blt_Ps_VarAppend(ps,
" } imagemask\n",
"grestore\n", (char*)NULL);
}
-static void FreeBitmapProc(Marker *markerPtr)
+static void FreeBitmapProc(Marker* markerPtr)
{
BitmapMarker* bmPtr = (BitmapMarker*)markerPtr;
Graph* graphPtr = markerPtr->obj.graphPtr;
@@ -457,8 +299,5 @@ static void FreeBitmapProc(Marker *markerPtr)
if (bmPtr->fillGC)
Tk_FreeGC(graphPtr->display, bmPtr->fillGC);
-
- if (bmPtr->destBitmap != None)
- Tk_FreePixmap(graphPtr->display, bmPtr->destBitmap);
}
diff --git a/bltGrMarkerBitmap.h b/bltGrMarkerBitmap.h
index eb5d22b..7233d0c 100644
--- a/bltGrMarkerBitmap.h
+++ b/bltGrMarkerBitmap.h
@@ -34,66 +34,34 @@
class BitmapMarker {
public:
- GraphObj obj; /* Must be first field in marker. */
-
+ GraphObj obj;
MarkerClass *classPtr;
-
- Tk_OptionTable optionTable; /* Configuration specifications */
+ Tk_OptionTable optionTable;
Tcl_HashEntry *hashPtr;
-
Blt_ChainLink link;
-
- const char* elemName; /* Element associated with marker. Let's
- * you link a marker to an element. The
- * marker is drawn only if the element
- * is also visible. */
+ const char* elemName;
Axis2d axes;
-
- Point2d *worldPts; /* Coordinate array to position
- * marker. */
- int nWorldPts; /* # of points in above array. */
-
- int drawUnder; /* If non-zero, draw the marker
- * underneath any elements. This can be
- * a performance penalty because the
- * graph must be redraw entirely each
- * time the marker is redrawn. */
-
- int clipped; /* Indicates if the marker is totally
- * clipped by the plotting area. */
-
+ int drawUnder;
+ int clipped;
int hide;
unsigned int flags;
-
-
- int xOffset, yOffset; /* Pixel offset from graph position */
-
+ int xOffset;
+ int yOffset;
int state;
- /* Fields specific to bitmap markers. */
-
- Pixmap srcBitmap; /* Original bitmap. May be further
- * scaled or rotated. */
- double reqAngle; /* Requested rotation of the bitmap */
- float angle; /* Normalized rotation (0..360
- * degrees) */
- Tk_Anchor anchor; /* If only one X-Y coordinate is given,
- * indicates how to translate the given
- * marker position. Otherwise, if there
- * are two X-Y coordinates, then this
- * value is ignored. */
- Point2d anchorPt; /* Translated anchor point. */
-
- XColor *outlineColor; /* Foreground color */
- XColor* fillColor; /* Background color */
-
- GC gc; /* Private graphic context */
- GC fillGC; /* Shared graphic context */
- Pixmap destBitmap; /* Bitmap to be drawn. */
- int destWidth, destHeight; /* Dimensions of the final bitmap */
-
- Point2d outline[MAX_OUTLINE_POINTS];/* Polygon representing the background
- * of the bitmap. */
+ // Fields specific to bitmap
+
+ Point2d world;
+ Pixmap bitmap;
+ Tk_Anchor anchor;
+ Point2d anchorPt;
+ XColor* outlineColor;
+ XColor* fillColor;
+ GC gc;
+ GC fillGC;
+ int width;
+ int height;
+ Point2d outline[MAX_OUTLINE_POINTS];
int nOutlinePts;
};
diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C
index ce946c8..dbb0d99 100644
--- a/src/bltGrElemLine.C
+++ b/src/bltGrElemLine.C
@@ -76,7 +76,7 @@ typedef struct {
typedef enum {
SYMBOL_NONE, SYMBOL_SQUARE, SYMBOL_CIRCLE, SYMBOL_DIAMOND, SYMBOL_PLUS,
SYMBOL_CROSS, SYMBOL_SPLUS, SYMBOL_SCROSS, SYMBOL_TRIANGLE, SYMBOL_ARROW,
- SYMBOL_BITMAP, SYMBOL_IMAGE
+ SYMBOL_BITMAP
} SymbolType;
typedef struct {
@@ -293,8 +293,6 @@ typedef struct {
// Defs
static void DestroySymbol(Display *display, Symbol *symbolPtr);
-static void ImageChangedProc(ClientData clientData, int x, int y, int w, int h,
- int imageWidth, int imageHeight);
typedef double (DistanceProc)(int x, int y, Point2d *p, Point2d *q, Point2d *t);
static void InitLinePen(Graph* graphPtr, LinePen* penPtr);
static void ResetLine(LineElement* elemPtr);
@@ -411,20 +409,6 @@ static int SymbolSetProc(ClientData clientData, Tcl_Interp* interp,
}
}
- // image
- {
- Element* elemPtr = (Element*)widgRec;
-
- Tk_Image tkImage =
- Tk_GetImage(interp, tkwin, string, ImageChangedProc, elemPtr);
- if (tkImage) {
- DestroySymbol(Tk_Display(tkwin), symbolPtr);
- symbolPtr->image = tkImage;
- symbolPtr->type = SYMBOL_IMAGE;
- return TCL_OK;
- }
- }
-
// bitmap
{
Tcl_Obj **objv;
@@ -920,17 +904,6 @@ static void DestroySymbol(Display *display, Symbol *symbolPtr)
symbolPtr->type = SYMBOL_NONE;
}
-static void ImageChangedProc(ClientData clientData,
- int x, int y, int w, int h,
- int imageWidth, int imageHeight)
-{
- Element* elemPtr = (Element*)clientData;
- Graph* graphPtr = elemPtr->obj.graphPtr;
- elemPtr->flags |= MAP_ITEM;
- graphPtr->flags |= CACHE_DIRTY;
- Blt_EventuallyRedrawGraph(graphPtr);
-}
-
/*
* Reset the number of points and segments, in case there are no segments or
* points
@@ -2912,44 +2885,6 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
break;
- case SYMBOL_IMAGE:
- {
- int w, h;
- int dx, dy;
-
- Tk_SizeOfImage(penPtr->symbol.image, &w, &h);
-
- dx = w / 2;
- dy = h / 2;
- if (elemPtr->symbolInterval > 0) {
- Point2d *pp, *endp;
-
- for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
- if (DRAW_SYMBOL(elemPtr)) {
- int x, y;
-
- x = Round(pp->x) - dx;
- y = Round(pp->y) - dy;
- Tk_RedrawImage(penPtr->symbol.image, 0, 0, w, h,
- drawable, x, y);
- }
- elemPtr->symbolCounter++;
- }
- } else {
- Point2d *pp, *endp;
-
- for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
- int x, y;
-
- x = Round(pp->x) - dx;
- y = Round(pp->y) - dy;
- Tk_RedrawImage(penPtr->symbol.image, 0, 0, w, h,
- drawable, x, y);
- }
- }
- }
- break;
-
case SYMBOL_BITMAP:
{
Pixmap bitmap, mask;
diff --git a/src/bltGrMarker.C b/src/bltGrMarker.C
index 221be91..3018efb 100644
--- a/src/bltGrMarker.C
+++ b/src/bltGrMarker.C
@@ -50,9 +50,6 @@ extern MarkerCreateProc Blt_CreateWindowProc;
typedef int (GraphMarkerProc)(Graph* graphPtr, Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[]);
-static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr,
- int objc, Tcl_Obj* const objv[]);
-static Tcl_Obj* PrintCoordinate(double x);
static int MarkerObjConfigure( Tcl_Interp* interp, Graph* graphPtr,
Marker* markerPtr,
int objc, Tcl_Obj* const objv[]);
@@ -72,51 +69,6 @@ extern "C" {
Marker* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under);
};
-// OptionSpecs
-
-static Tk_CustomOptionSetProc CoordsSetProc;
-static Tk_CustomOptionGetProc CoordsGetProc;
-Tk_ObjCustomOption coordsObjOption =
- {
- "coords", CoordsSetProc, CoordsGetProc, NULL, NULL, NULL
- };
-
-static int CoordsSetProc(ClientData clientData, Tcl_Interp* interp,
- Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
- int offset, char* save, int flags)
-{
- Marker* markerPtr = (Marker*)widgRec;
-
- int objc;
- Tcl_Obj** objv;
- if (Tcl_ListObjGetElements(interp, *objPtr, &objc, &objv) != TCL_OK)
- return TCL_ERROR;
-
- if (objc == 0)
- return TCL_OK;
-
- return ParseCoordinates(interp, markerPtr, objc, objv);
-}
-
-static Tcl_Obj* CoordsGetProc(ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset)
-{
- Marker* markerPtr = (Marker*)widgRec;
-
- int cnt = markerPtr->nWorldPts*2;
- Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
-
- Point2d* pp = markerPtr->worldPts;
- for (int ii=0; ii < markerPtr->nWorldPts*2; pp++) {
- ll[ii++] = PrintCoordinate(pp->x);
- ll[ii++] = PrintCoordinate(pp->y);
- }
-
- Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
- free(ll);
- return listObjPtr;
-}
-
static Tk_CustomOptionSetProc CapStyleSetProc;
static Tk_CustomOptionGetProc CapStyleGetProc;
Tk_ObjCustomOption capStyleObjOption =
@@ -630,110 +582,6 @@ int Blt_MarkerOp(Graph* graphPtr, Tcl_Interp* interp,
// Support
-static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr)
-{
- const char* expr = Tcl_GetString(objPtr);
- char c = expr[0];
- if ((c == 'I') && (strcmp(expr, "Inf") == 0))
- *valuePtr = DBL_MAX; /* Elastic upper bound */
- else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0))
- *valuePtr = -DBL_MAX; /* Elastic lower bound */
- else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0))
- *valuePtr = DBL_MAX; /* Elastic upper bound */
- else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK)
- return TCL_ERROR;
-
- return TCL_OK;
-}
-
-static Tcl_Obj* PrintCoordinate(double x)
-{
- if (x == DBL_MAX)
- return Tcl_NewStringObj("+Inf", -1);
- else if (x == -DBL_MAX)
- return Tcl_NewStringObj("-Inf", -1);
- else
- return Tcl_NewDoubleObj(x);
-}
-
-static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr,
- int objc, Tcl_Obj* const objv[])
-{
- if (objc == 0)
- return TCL_OK;
-
- if (objc & 1) {
- Tcl_AppendResult(interp, "odd number of marker coordinates specified",
- (char*)NULL);
- return TCL_ERROR;
- }
-
- int minArgs, maxArgs;
- switch (markerPtr->obj.classId) {
- case CID_MARKER_LINE:
- minArgs = 4;
- maxArgs = 0;
- break;
- case CID_MARKER_POLYGON:
- minArgs = 6;
- maxArgs = 0;
- break;
- case CID_MARKER_WINDOW:
- case CID_MARKER_TEXT:
- minArgs = 2;
- maxArgs = 2;
- break;
- case CID_MARKER_IMAGE:
- case CID_MARKER_BITMAP:
- minArgs = 2;
- maxArgs = 4;
- break;
- default:
- Tcl_AppendResult(interp, "unknown marker type", (char*)NULL);
- return TCL_ERROR;
- }
-
- if (objc < minArgs) {
- Tcl_AppendResult(interp, "too few marker coordinates specified",
- (char*)NULL);
- return TCL_ERROR;
- }
- if ((maxArgs > 0) && (objc > maxArgs)) {
- Tcl_AppendResult(interp, "too many marker coordinates specified",
- (char*)NULL);
- return TCL_ERROR;
- }
- int nWorldPts = objc / 2;
- Point2d* worldPts = (Point2d*)malloc(nWorldPts * sizeof(Point2d));
- if (worldPts == NULL) {
- Tcl_AppendResult(interp, "can't allocate new coordinate array",
- (char*)NULL);
- return TCL_ERROR;
- }
-
- Point2d* pp = worldPts;
- for (int ii=0; ii<objc; ii+=2) {
- double x, y;
- if ((GetCoordinate(interp, objv[ii], &x) != TCL_OK) ||
- (GetCoordinate(interp, objv[ii + 1], &y) != TCL_OK)) {
- free(worldPts);
- return TCL_ERROR;
- }
- pp->x = x, pp->y = y, pp++;
- }
-
- // Don't free the old coordinate array until we've parsed the new
- // coordinates without errors.
- if (markerPtr->worldPts)
- free(markerPtr->worldPts);
-
- markerPtr->worldPts = worldPts;
- markerPtr->nWorldPts = nWorldPts;
- markerPtr->flags |= MAP_ITEM;
-
- return TCL_OK;
-}
-
static int IsElementHidden(Marker *markerPtr)
{
Tcl_HashEntry *hPtr;
@@ -832,8 +680,7 @@ void Blt_MarkersToPostScript(Graph* graphPtr, Blt_Ps ps, int under)
for (Blt_ChainLink link = Blt_Chain_LastLink(graphPtr->markers.displayList);
link; link = Blt_Chain_PrevLink(link)) {
Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link);
- if ((markerPtr->classPtr->postscriptProc == NULL) ||
- (markerPtr->nWorldPts == 0))
+ if (markerPtr->classPtr->postscriptProc == NULL)
continue;
if (markerPtr->drawUnder != under)
@@ -857,8 +704,7 @@ void Blt_DrawMarkers(Graph* graphPtr, Drawable drawable, int under)
link; link = Blt_Chain_PrevLink(link)) {
Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link);
- if ((markerPtr->nWorldPts == 0) ||
- (markerPtr->drawUnder != under) ||
+ if ((markerPtr->drawUnder != under) ||
(markerPtr->clipped) ||
(markerPtr->flags & DELETE_PENDING) ||
(markerPtr->hide))
@@ -885,8 +731,6 @@ void Blt_MapMarkers(Graph* graphPtr)
for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList);
link; link = Blt_Chain_NextLink(link)) {
Marker *markerPtr = (Marker*)Blt_Chain_GetValue(link);
- if (markerPtr->nWorldPts == 0)
- continue;
if ((markerPtr->flags & DELETE_PENDING) || markerPtr->hide)
continue;
@@ -923,9 +767,7 @@ Marker* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under)
for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList);
link; link = Blt_Chain_NextLink(link)) {
Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link);
- if ((markerPtr->nWorldPts == 0) ||
- (markerPtr->flags & (DELETE_PENDING|MAP_ITEM)) ||
- (markerPtr->hide))
+ if ((markerPtr->flags & (DELETE_PENDING|MAP_ITEM)) || (markerPtr->hide))
continue; /* Don't consider markers that are
* pending to be mapped. Even if the
* marker has already been mapped, the
diff --git a/src/bltGrMarker.h b/src/bltGrMarker.h
index 9f1ebd0..e065b94 100644
--- a/src/bltGrMarker.h
+++ b/src/bltGrMarker.h
@@ -52,39 +52,25 @@ typedef struct {
MarkerPostscriptProc *postscriptProc;
} MarkerClass;
-struct _Marker {
- GraphObj obj; /* Must be first field in marker. */
+typedef struct {
+ Point2d* points;
+ int num;
+} WorldPts;
+struct _Marker {
+ GraphObj obj;
MarkerClass *classPtr;
-
- Tk_OptionTable optionTable; /* Configuration specifications */
+ Tk_OptionTable optionTable;
Tcl_HashEntry *hashPtr;
-
Blt_ChainLink link;
-
- const char* elemName; /* Element associated with marker. Let's
- * you link a marker to an element. The
- * marker is drawn only if the element
- * is also visible. */
+ const char* elemName;
Axis2d axes;
- Point2d *worldPts; /* Coordinate array to position
- * marker */
- int nWorldPts; /* Number of points in above array */
- int drawUnder; /* If non-zero, draw the marker
- * underneath any elements. This can be
- * a performance penalty because the
- * graph must be redraw entirely each
- * time the marker is redrawn. */
-
- int clipped; /* Indicates if the marker is totally
- * clipped by the plotting area. */
-
+ int drawUnder;
+ int clipped;
int hide;
unsigned int flags;
-
-
- int xOffset, yOffset; /* Pixel offset from graph position */
-
+ int xOffset;
+ int yOffset;
int state;
};
@@ -92,7 +78,6 @@ Point2d Blt_MapPoint(Point2d *pointPtr, Axis2d *axesPtr);
void Blt_FreeMarker(char*);
int Blt_BoxesDontOverlap(Graph* graphPtr, Region2d *extsPtr);
-extern Tk_ObjCustomOption coordsObjOption;
extern Tk_ObjCustomOption capStyleObjOption;
extern Tk_ObjCustomOption joinStyleObjOption;
extern Tk_ObjCustomOption xAxisObjOption;
diff --git a/src/bltGrMarkerLine.C b/src/bltGrMarkerLine.C
index 4314196..68572b1 100644
--- a/src/bltGrMarkerLine.C
+++ b/src/bltGrMarkerLine.C
@@ -33,6 +33,58 @@ extern "C" {
#include "bltGrMarkerLine.h"
+// Defs
+
+static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr);
+static Tcl_Obj* PrintCoordinate(double x);
+static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr,
+ int objc, Tcl_Obj* const objv[]);
+
+// OptionSpecs
+
+static Tk_CustomOptionSetProc CoordsSetProc;
+static Tk_CustomOptionGetProc CoordsGetProc;
+static Tk_ObjCustomOption coordsObjOption =
+ {
+ "coords", CoordsSetProc, CoordsGetProc, NULL, NULL, NULL
+ };
+
+static int CoordsSetProc(ClientData clientData, Tcl_Interp* interp,
+ Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
+ int offset, char* save, int flags)
+{
+ Marker* markerPtr = (Marker*)widgRec;
+
+ int objc;
+ Tcl_Obj** objv;
+ if (Tcl_ListObjGetElements(interp, *objPtr, &objc, &objv) != TCL_OK)
+ return TCL_ERROR;
+
+ if (objc == 0)
+ return TCL_OK;
+
+ return ParseCoordinates(interp, markerPtr, objc, objv);
+}
+
+static Tcl_Obj* CoordsGetProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset)
+{
+ LineMarker* lmPtr = (LineMarker*)widgRec;
+
+ int cnt = lmPtr->nWorldPts*2;
+ Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
+
+ Point2d* pp = lmPtr->worldPts;
+ for (int ii=0; ii < lmPtr->nWorldPts*2; pp++) {
+ ll[ii++] = PrintCoordinate(pp->x);
+ ll[ii++] = PrintCoordinate(pp->y);
+ }
+
+ Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
+ free(ll);
+ return listObjPtr;
+}
+
static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_CUSTOM, "-bindtags", "bindTags", "BindTags",
"Line all", -1, Tk_Offset(LineMarker, obj.tags),
@@ -109,7 +161,7 @@ Marker* Blt_CreateLineProc(Graph* graphPtr)
static int PointInLineProc(Marker *markerPtr, Point2d *samplePtr)
{
- LineMarker *lmPtr = (LineMarker *)markerPtr;
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
return Blt_PointInSegments(samplePtr, lmPtr->segments, lmPtr->nSegments,
(double)markerPtr->obj.graphPtr->search.halo);
@@ -117,13 +169,15 @@ static int PointInLineProc(Marker *markerPtr, Point2d *samplePtr)
static int RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
{
- if (markerPtr->nWorldPts < 2)
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
+
+ if (lmPtr->nWorldPts < 2)
return FALSE;
if (enclosed) {
Point2d *pp, *pend;
- for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts;
+ for (pp = lmPtr->worldPts, pend = pp + lmPtr->nWorldPts;
pp < pend; pp++) {
Point2d p = Blt_MapPoint(pp, &markerPtr->axes);
if ((p.x < extsPtr->left) && (p.x > extsPtr->right) &&
@@ -136,7 +190,7 @@ static int RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
else {
Point2d *pp, *pend;
int count = 0;
- for (pp = markerPtr->worldPts, pend = pp + (markerPtr->nWorldPts - 1);
+ for (pp = lmPtr->worldPts, pend = pp + (lmPtr->nWorldPts - 1);
pp < pend; pp++) {
Point2d p = Blt_MapPoint(pp, &markerPtr->axes);
Point2d q = Blt_MapPoint(pp + 1, &markerPtr->axes);
@@ -150,7 +204,7 @@ static int RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
static void DrawLineProc(Marker *markerPtr, Drawable drawable)
{
- LineMarker *lmPtr = (LineMarker *)markerPtr;
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
if (lmPtr->nSegments > 0) {
Graph* graphPtr = markerPtr->obj.graphPtr;
@@ -165,7 +219,7 @@ static void DrawLineProc(Marker *markerPtr, Drawable drawable)
static int ConfigureLineProc(Marker *markerPtr)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
- LineMarker *lmPtr = (LineMarker *)markerPtr;
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
Drawable drawable = Tk_WindowId(graphPtr->tkwin);
unsigned long gcMask = (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle);
@@ -225,7 +279,7 @@ static int ConfigureLineProc(Marker *markerPtr)
static void LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
{
- LineMarker *lmPtr = (LineMarker *)markerPtr;
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
if (lmPtr->nSegments > 0) {
Blt_Ps_XSetLineAttributes(ps, lmPtr->outlineColor,
@@ -235,7 +289,7 @@ static void LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
Blt_Ps_Append(ps, "/DashesProc {\n gsave\n ");
Blt_Ps_XSetBackground(ps, lmPtr->fillColor);
Blt_Ps_Append(ps, " ");
- Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL);
+ Blt_Ps_XSetDashes(ps, (Blt_Dashes*)NULL);
Blt_Ps_VarAppend(ps,
"stroke\n",
" grestore\n",
@@ -249,27 +303,26 @@ static void LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
static void FreeLineProc(Marker *markerPtr)
{
- LineMarker *lmPtr = (LineMarker *)markerPtr;
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
Graph* graphPtr = markerPtr->obj.graphPtr;
- if (lmPtr->gc) {
+ if (lmPtr->gc)
Blt_FreePrivateGC(graphPtr->display, lmPtr->gc);
- }
- if (lmPtr->segments) {
+
+ if (lmPtr->segments)
free(lmPtr->segments);
- }
}
static void MapLineProc(Marker *markerPtr)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
- LineMarker *lmPtr = (LineMarker *)markerPtr;
+ LineMarker *lmPtr = (LineMarker*)markerPtr;
lmPtr->nSegments = 0;
if (lmPtr->segments)
free(lmPtr->segments);
- if (markerPtr->nWorldPts < 2)
+ if (lmPtr->nWorldPts < 2)
return;
Region2d extents;
@@ -282,19 +335,19 @@ static void MapLineProc(Marker *markerPtr)
* disconnected segments.
*/
Segment2d* segments =
- (Segment2d*)malloc(markerPtr->nWorldPts * sizeof(Segment2d));
- Point2d* srcPtr = markerPtr->worldPts;
+ (Segment2d*)malloc(lmPtr->nWorldPts * sizeof(Segment2d));
+ Point2d* srcPtr = lmPtr->worldPts;
Point2d p = Blt_MapPoint(srcPtr, &markerPtr->axes);
p.x += markerPtr->xOffset;
p.y += markerPtr->yOffset;
Segment2d* segPtr = segments;
Point2d* pend;
- for (srcPtr++, pend = markerPtr->worldPts + markerPtr->nWorldPts;
+ for (srcPtr++, pend = lmPtr->worldPts + lmPtr->nWorldPts;
srcPtr < pend; srcPtr++) {
Point2d next = Blt_MapPoint(srcPtr, &markerPtr->axes);
- next.x += markerPtr->xOffset;
- next.y += markerPtr->yOffset;
+ next.x += lmPtr->xOffset;
+ next.y += lmPtr->yOffset;
Point2d q = next;
if (Blt_LineRectClip(&extents, &p, &q)) {
@@ -306,6 +359,89 @@ static void MapLineProc(Marker *markerPtr)
}
lmPtr->nSegments = segPtr - segments;
lmPtr->segments = segments;
- markerPtr->clipped = (lmPtr->nSegments == 0);
+ lmPtr->clipped = (lmPtr->nSegments == 0);
+}
+
+static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr,
+ int objc, Tcl_Obj* const objv[])
+{
+ LineMarker* lmPtr = (LineMarker*)markerPtr;
+
+ if (objc == 0)
+ return TCL_OK;
+
+ if (objc & 1) {
+ Tcl_AppendResult(interp, "odd number of marker coordinates specified",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+
+ int minArgs = 4;
+ int maxArgs = 0;
+ if (objc < minArgs) {
+ Tcl_AppendResult(interp, "too few marker coordinates specified",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+ if ((maxArgs > 0) && (objc > maxArgs)) {
+ Tcl_AppendResult(interp, "too many marker coordinates specified",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+ int nWorldPts = objc / 2;
+ Point2d* worldPts = (Point2d*)malloc(nWorldPts * sizeof(Point2d));
+ if (worldPts == NULL) {
+ Tcl_AppendResult(interp, "can't allocate new coordinate array",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+
+ Point2d* pp = worldPts;
+ for (int ii=0; ii<objc; ii+=2) {
+ double x, y;
+ if ((GetCoordinate(interp, objv[ii], &x) != TCL_OK) ||
+ (GetCoordinate(interp, objv[ii + 1], &y) != TCL_OK)) {
+ free(worldPts);
+ return TCL_ERROR;
+ }
+ pp->x = x, pp->y = y, pp++;
+ }
+
+ // Don't free the old coordinate array until we've parsed the new
+ // coordinates without errors.
+ if (lmPtr->worldPts)
+ free(lmPtr->worldPts);
+
+ lmPtr->worldPts = worldPts;
+ lmPtr->nWorldPts = nWorldPts;
+ markerPtr->flags |= MAP_ITEM;
+
+ return TCL_OK;
+}
+
+static Tcl_Obj* PrintCoordinate(double x)
+{
+ if (x == DBL_MAX)
+ return Tcl_NewStringObj("+Inf", -1);
+ else if (x == -DBL_MAX)
+ return Tcl_NewStringObj("-Inf", -1);
+ else
+ return Tcl_NewDoubleObj(x);
+}
+
+static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr)
+{
+ const char* expr = Tcl_GetString(objPtr);
+ char c = expr[0];
+ if ((c == 'I') && (strcmp(expr, "Inf") == 0))
+ *valuePtr = DBL_MAX; /* Elastic upper bound */
+ else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0))
+ *valuePtr = -DBL_MAX; /* Elastic lower bound */
+ else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0))
+ *valuePtr = DBL_MAX; /* Elastic upper bound */
+ else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK)
+ return TCL_ERROR;
+
+ return TCL_OK;
}
diff --git a/src/bltGrMarkerLine.h b/src/bltGrMarkerLine.h
index ab987c9..5401a05 100644
--- a/src/bltGrMarkerLine.h
+++ b/src/bltGrMarkerLine.h
@@ -34,63 +34,36 @@
class LineMarker {
public:
- GraphObj obj; /* Must be first field in marker. */
-
+ GraphObj obj;
MarkerClass *classPtr;
-
- Tk_OptionTable optionTable; /* Configuration specifications */
+ Tk_OptionTable optionTable;
Tcl_HashEntry *hashPtr;
-
Blt_ChainLink link;
-
- const char* elemName; /* Element associated with marker. Let's
- * you link a marker to an element. The
- * marker is drawn only if the element
- * is also visible. */
+ const char* elemName;
Axis2d axes;
-
- Point2d *worldPts; /* Coordinate array to position
- * marker. */
-
- int nWorldPts; /* Number of points in above array */
-
- int drawUnder; /* If non-zero, draw the marker
- * underneath any elements. This can be
- * a performance penalty because the
- * graph must be redraw entirely each
- * time the marker is redrawn. */
-
- int clipped; /* Indicates if the marker is totally
- * clipped by the plotting area. */
-
+ int drawUnder;
+ int clipped;
int hide;
unsigned int flags;
-
-
- int xOffset, yOffset; /* Pixel offset from graph position */
-
+ int xOffset;
+ int yOffset;
int state;
- XColor* fillColor;
- XColor* outlineColor; /* Foreground and background colors */
-
- int lineWidth; /* Line width. */
- int capStyle; /* Cap style. */
- int joinStyle; /* Join style.*/
- Blt_Dashes dashes; /* Dash list values (max 11) */
+ // Fields specific to line
- GC gc; /* Private graphic context */
-
- Segment2d *segments; /* Malloc'ed array of points.
- * Represents individual line segments
- * (2 points per segment) comprising the
- * mapped line. The segments may not
- * necessarily be connected after
- * clipping. */
- int nSegments; /* # segments in the above array. */
+ Point2d *worldPts;
+ int nWorldPts;
+ XColor* fillColor;
+ XColor* outlineColor;
+ int lineWidth;
+ int capStyle;
+ int joinStyle;
+ Blt_Dashes dashes;
+ GC gc;
+ Segment2d *segments;
+ int nSegments;
int xorr;
- int xorState; /* State of the XOR drawing. Indicates
- * if the marker is currently drawn. */
+ int xorState;
};
#endif
diff --git a/src/bltGrMarkerPolygon.C b/src/bltGrMarkerPolygon.C
index db4a80d..fd07701 100644
--- a/src/bltGrMarkerPolygon.C
+++ b/src/bltGrMarkerPolygon.C
@@ -33,6 +33,55 @@ extern "C" {
#include "bltGrMarkerPolygon.h"
+static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr);
+static Tcl_Obj* PrintCoordinate(double x);
+static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr,
+ int objc, Tcl_Obj* const objv[]);
+// OptionSpecs
+
+static Tk_CustomOptionSetProc CoordsSetProc;
+static Tk_CustomOptionGetProc CoordsGetProc;
+static Tk_ObjCustomOption coordsObjOption =
+ {
+ "coords", CoordsSetProc, CoordsGetProc, NULL, NULL, NULL
+ };
+
+static int CoordsSetProc(ClientData clientData, Tcl_Interp* interp,
+ Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
+ int offset, char* save, int flags)
+{
+ Marker* markerPtr = (Marker*)widgRec;
+
+ int objc;
+ Tcl_Obj** objv;
+ if (Tcl_ListObjGetElements(interp, *objPtr, &objc, &objv) != TCL_OK)
+ return TCL_ERROR;
+
+ if (objc == 0)
+ return TCL_OK;
+
+ return ParseCoordinates(interp, markerPtr, objc, objv);
+}
+
+static Tcl_Obj* CoordsGetProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset)
+{
+ PolygonMarker* pmPtr = (PolygonMarker*)widgRec;
+
+ int cnt = pmPtr->nWorldPts*2;
+ Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
+
+ Point2d* pp = pmPtr->worldPts;
+ for (int ii=0; ii < pmPtr->nWorldPts*2; pp++) {
+ ll[ii++] = PrintCoordinate(pp->x);
+ ll[ii++] = PrintCoordinate(pp->y);
+ }
+
+ Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
+ free(ll);
+ return listObjPtr;
+}
+
static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_CUSTOM, "-bindtags", "bindTags", "BindTags",
"Polygon all", -1, Tk_Offset(PolygonMarker, obj.tags),
@@ -115,9 +164,9 @@ static int PointInPolygonProc(Marker *markerPtr, Point2d *samplePtr)
{
PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
- if ((markerPtr->nWorldPts >= 3) && (pmPtr->screenPts)) {
+ if ((pmPtr->nWorldPts >= 3) && (pmPtr->screenPts)) {
return Blt_PointInPolygon(samplePtr, pmPtr->screenPts,
- markerPtr->nWorldPts + 1);
+ pmPtr->nWorldPts + 1);
}
return FALSE;
}
@@ -127,9 +176,9 @@ static int RegionInPolygonProc(Marker *markerPtr, Region2d *extsPtr,
{
PolygonMarker *pmPtr = (PolygonMarker *)markerPtr;
- if ((markerPtr->nWorldPts >= 3) && (pmPtr->screenPts)) {
+ if ((pmPtr->nWorldPts >= 3) && (pmPtr->screenPts)) {
return Blt_RegionInPolygon(extsPtr, pmPtr->screenPts,
- markerPtr->nWorldPts, enclosed);
+ pmPtr->nWorldPts, enclosed);
}
return FALSE;
}
@@ -357,7 +406,7 @@ static void MapPolygonProc(Marker *markerPtr)
free(pmPtr->screenPts);
pmPtr->screenPts = NULL;
}
- if (markerPtr->nWorldPts < 3) {
+ if (pmPtr->nWorldPts < 3) {
return; /* Too few points */
}
@@ -365,33 +414,33 @@ static void MapPolygonProc(Marker *markerPtr)
* Allocate and fill a temporary array to hold the screen coordinates of
* the polygon.
*/
- int nScreenPts = markerPtr->nWorldPts + 1;
+ int nScreenPts = pmPtr->nWorldPts + 1;
Point2d* screenPts = (Point2d*)malloc((nScreenPts + 1) * sizeof(Point2d));
{
Point2d *sp, *dp, *send;
dp = screenPts;
- for (sp = markerPtr->worldPts, send = sp + markerPtr->nWorldPts;
+ for (sp = pmPtr->worldPts, send = sp + pmPtr->nWorldPts;
sp < send; sp++) {
- *dp = Blt_MapPoint(sp, &markerPtr->axes);
- dp->x += markerPtr->xOffset;
- dp->y += markerPtr->yOffset;
+ *dp = Blt_MapPoint(sp, &pmPtr->axes);
+ dp->x += pmPtr->xOffset;
+ dp->y += pmPtr->yOffset;
dp++;
}
*dp = screenPts[0];
}
Region2d extents;
Blt_GraphExtents(graphPtr, &extents);
- markerPtr->clipped = TRUE;
+ pmPtr->clipped = TRUE;
if (pmPtr->fill) { /* Polygon fill required. */
Point2d* fillPts = (Point2d*)malloc(sizeof(Point2d) * nScreenPts * 3);
- int n = Blt_PolyRectClip(&extents, screenPts, markerPtr->nWorldPts,fillPts);
+ int n = Blt_PolyRectClip(&extents, screenPts, pmPtr->nWorldPts,fillPts);
if (n < 3) {
free(fillPts);
} else {
pmPtr->nFillPts = n;
pmPtr->fillPts = fillPts;
- markerPtr->clipped = FALSE;
+ pmPtr->clipped = FALSE;
}
}
if ((pmPtr->outline) && (pmPtr->lineWidth > 0)) {
@@ -421,9 +470,92 @@ static void MapPolygonProc(Marker *markerPtr)
pmPtr->nOutlinePts = segPtr - outlinePts;
pmPtr->outlinePts = outlinePts;
if (pmPtr->nOutlinePts > 0) {
- markerPtr->clipped = FALSE;
+ pmPtr->clipped = FALSE;
}
}
pmPtr->screenPts = screenPts;
}
+static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr,
+ int objc, Tcl_Obj* const objv[])
+{
+ PolygonMarker* pmPtr = (PolygonMarker*)markerPtr;
+
+ if (objc == 0)
+ return TCL_OK;
+
+ if (objc & 1) {
+ Tcl_AppendResult(interp, "odd number of marker coordinates specified",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+
+ int minArgs = 6;
+ int maxArgs = 0;
+ if (objc < minArgs) {
+ Tcl_AppendResult(interp, "too few marker coordinates specified",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+ if ((maxArgs > 0) && (objc > maxArgs)) {
+ Tcl_AppendResult(interp, "too many marker coordinates specified",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+ int nWorldPts = objc / 2;
+ Point2d* worldPts = (Point2d*)malloc(nWorldPts * sizeof(Point2d));
+ if (worldPts == NULL) {
+ Tcl_AppendResult(interp, "can't allocate new coordinate array",
+ (char*)NULL);
+ return TCL_ERROR;
+ }
+
+ Point2d* pp = worldPts;
+ for (int ii=0; ii<objc; ii+=2) {
+ double x, y;
+ if ((GetCoordinate(interp, objv[ii], &x) != TCL_OK) ||
+ (GetCoordinate(interp, objv[ii + 1], &y) != TCL_OK)) {
+ free(worldPts);
+ return TCL_ERROR;
+ }
+ pp->x = x, pp->y = y, pp++;
+ }
+
+ // Don't free the old coordinate array until we've parsed the new
+ // coordinates without errors.
+ if (pmPtr->worldPts)
+ free(pmPtr->worldPts);
+
+ pmPtr->worldPts = worldPts;
+ pmPtr->nWorldPts = nWorldPts;
+ pmPtr->flags |= MAP_ITEM;
+
+ return TCL_OK;
+}
+
+static Tcl_Obj* PrintCoordinate(double x)
+{
+ if (x == DBL_MAX)
+ return Tcl_NewStringObj("+Inf", -1);
+ else if (x == -DBL_MAX)
+ return Tcl_NewStringObj("-Inf", -1);
+ else
+ return Tcl_NewDoubleObj(x);
+}
+
+static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr)
+{
+ const char* expr = Tcl_GetString(objPtr);
+ char c = expr[0];
+ if ((c == 'I') && (strcmp(expr, "Inf") == 0))
+ *valuePtr = DBL_MAX; /* Elastic upper bound */
+ else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0))
+ *valuePtr = -DBL_MAX; /* Elastic lower bound */
+ else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0))
+ *valuePtr = DBL_MAX; /* Elastic upper bound */
+ else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK)
+ return TCL_ERROR;
+
+ return TCL_OK;
+}
+
diff --git a/src/bltGrMarkerPolygon.h b/src/bltGrMarkerPolygon.h
index 45c70d1..8b29075 100644
--- a/src/bltGrMarkerPolygon.h
+++ b/src/bltGrMarkerPolygon.h
@@ -34,90 +34,43 @@
class PolygonMarker {
public:
- GraphObj obj; /* Must be first field in marker. */
-
+ GraphObj obj;
MarkerClass *classPtr;
-
- Tk_OptionTable optionTable; /* Configuration specifications */
+ Tk_OptionTable optionTable;
Tcl_HashEntry *hashPtr;
-
Blt_ChainLink link;
-
- const char* elemName; /* Element associated with marker. Let's
- * you link a marker to an element. The
- * marker is drawn only if the element
- * is also visible. */
+ const char* elemName;
Axis2d axes;
-
- Point2d *worldPts; /* Coordinate array to position
- * marker. */
-
- int nWorldPts; /* Number of points in above array */
-
- int drawUnder; /* If non-zero, draw the marker
- * underneath any elements. This can be
- * a performance penalty because the
- * graph must be redraw entirely each
- * time the marker is redrawn. */
-
- int clipped; /* Indicates if the marker is totally
- * clipped by the plotting area. */
-
+ int drawUnder;
+ int clipped;
int hide;
unsigned int flags;
-
-
- int xOffset, yOffset; /* Pixel offset from graph position */
-
+ int xOffset;
+ int yOffset;
int state;
- // derived
-
- Point2d *screenPts; /* Array of points representing the
- * polygon in screen coordinates. It's
- * not used for drawing, but to generate
- * the outlinePts and fillPts arrays
- * that are the coordinates of the
- * possibly clipped outline and filled
- * polygon. */
+ // Fields specific to polygon
+ Point2d *worldPts;
+ int nWorldPts;
+ Point2d *screenPts;
XColor* outline;
XColor* outlineBg;
XColor* fill;
XColor* fillBg;
-
- Pixmap stipple; /* Stipple pattern to fill the
- * polygon. */
- int lineWidth; /* Width of polygon outline. */
+ Pixmap stipple;
+ int lineWidth;
int capStyle;
int joinStyle;
- Blt_Dashes dashes; /* List of dash values. Indicates how
- * to draw the dashed line. If no dash
- * values are provided, or the first
- * value is zero, then the line is drawn
- * solid. */
-
- GC outlineGC; /* Graphics context to draw the outline
- * of the polygon. */
- GC fillGC; /* Graphics context to draw the filled
- * polygon. */
-
- Point2d *fillPts; /* Malloc'ed array of points used to
- * draw the filled polygon. These points
- * may form a degenerate polygon after
- * clipping. */
- int nFillPts; /* # points in the above array. */
- Segment2d *outlinePts; /* Malloc'ed array of points.
- * Represents individual line segments
- * (2 points per segment) comprising the
- * outline of the polygon. The segments
- * may not necessarily be closed or
- * connected after clipping. */
- int nOutlinePts; /* # points in the above array. */
+ Blt_Dashes dashes;
+ GC outlineGC;
+ GC fillGC;
+ Point2d *fillPts;
+ int nFillPts;
+ Segment2d *outlinePts;
+ int nOutlinePts;
int xorr;
- int xorState; /* State of the XOR drawing. Indicates
- * if the marker is visible. We have to
- * drawn it again to erase it. */
+ int xorState;
};
#endif
diff --git a/src/bltGrMarkerText.C b/src/bltGrMarkerText.C
index 6060c08..224368a 100644
--- a/src/bltGrMarkerText.C
+++ b/src/bltGrMarkerText.C
@@ -43,9 +43,6 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_CUSTOM, "-bindtags", "bindTags", "BindTags",
"Text all", -1, Tk_Offset(TextMarker, obj.tags),
TK_OPTION_NULL_OK, &listObjOption, 0},
- {TK_OPTION_CUSTOM, "-coords", "coords", "Coords",
- NULL, -1, Tk_Offset(TextMarker, worldPts),
- TK_OPTION_NULL_OK, &coordsObjOption, 0},
{TK_OPTION_STRING, "-element", "element", "Element",
NULL, -1, Tk_Offset(TextMarker, elemName), TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
@@ -53,8 +50,7 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_FONT, "-font", "font", "Font",
STD_FONT_NORMAL, -1, Tk_Offset(TextMarker, style.font), 0, NULL, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
- STD_NORMAL_FOREGROUND, -1, Tk_Offset(TextMarker, style.color),
- TK_OPTION_NULL_OK, NULL, 0},
+ STD_NORMAL_FOREGROUND, -1, Tk_Offset(TextMarker, style.color), 0, NULL, 0},
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
"left", -1, Tk_Offset(TextMarker, style.justify), 0, NULL, 0},
{TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
@@ -64,10 +60,6 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY",
"y", -1, Tk_Offset(TextMarker, axes.y), 0, &yAxisObjOption, 0},
{TK_OPTION_SYNONYM, "-outline", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0},
- {TK_OPTION_PIXELS, "-padx", "padX", "PadX",
- "4", -1, Tk_Offset(TextMarker, style.xPad), 0, NULL, 0},
- {TK_OPTION_PIXELS, "-pady", "padY", "PadY",
- "4", -1, Tk_Offset(TextMarker, style.yPad), 0, NULL, 0},
{TK_OPTION_DOUBLE, "-rotate", "rotate", "Rotate",
"0", -1, Tk_Offset(TextMarker, style.angle), 0, NULL, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
@@ -76,8 +68,12 @@ static Tk_OptionSpec optionSpecs[] = {
NULL, -1, Tk_Offset(TextMarker, string), TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_BOOLEAN, "-under", "under", "Under",
"no", -1, Tk_Offset(TextMarker, drawUnder), 0, NULL, 0},
+ {TK_OPTION_DOUBLE, "-x", "x", "X",
+ "0", -1, Tk_Offset(TextMarker, world.x), 0, NULL, 0},
{TK_OPTION_PIXELS, "-xoffset", "xOffset", "XOffset",
"0", -1, Tk_Offset(TextMarker, xOffset), 0, NULL, 0},
+ {TK_OPTION_DOUBLE, "-y", "y", "Y",
+ "0", -1, Tk_Offset(TextMarker, world.y), 0, NULL, 0},
{TK_OPTION_PIXELS, "-yoffset", "yOffset", "YOffset",
"0", -1, Tk_Offset(TextMarker, yOffset), 0, NULL, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
@@ -110,200 +106,183 @@ Marker* Blt_CreateTextProc(Graph* graphPtr)
Blt_Ts_InitStyle(tmPtr->style);
tmPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs);
- return (Marker *)tmPtr;
+ return (Marker*)tmPtr;
}
-static int ConfigureTextProc(Marker *markerPtr)
+static int ConfigureTextProc(Marker* markerPtr)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
- TextMarker *tmPtr = (TextMarker *)markerPtr;
- GC newGC;
- XGCValues gcValues;
- unsigned long gcMask;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
tmPtr->style.angle = (float)fmod(tmPtr->style.angle, 360.0);
if (tmPtr->style.angle < 0.0f) {
tmPtr->style.angle += 360.0f;
}
- newGC = NULL;
+
+ GC newGC = NULL;
+ XGCValues gcValues;
+ unsigned long gcMask;
if (tmPtr->fillColor) {
gcMask = GCForeground;
gcValues.foreground = tmPtr->fillColor->pixel;
newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
}
- if (tmPtr->fillGC) {
+ if (tmPtr->fillGC)
Tk_FreeGC(graphPtr->display, tmPtr->fillGC);
- }
tmPtr->fillGC = newGC;
markerPtr->flags |= MAP_ITEM;
- if (markerPtr->drawUnder) {
+ if (markerPtr->drawUnder)
graphPtr->flags |= CACHE_DIRTY;
- }
+
Blt_EventuallyRedrawGraph(graphPtr);
return TCL_OK;
}
-static void MapTextProc(Marker *markerPtr)
+static void MapTextProc(Marker* markerPtr)
{
Graph* graphPtr = markerPtr->obj.graphPtr;
- TextMarker *tmPtr = (TextMarker *)markerPtr;
- Region2d extents;
- Point2d anchorPt;
- int i;
- unsigned int w, h;
- double rw, rh;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
- tmPtr->width = tmPtr->height = 0;
- if (tmPtr->string == NULL) {
+ if (!tmPtr->string)
return;
- }
+
+ tmPtr->width =0;
+ tmPtr->height =0;
+
+ unsigned int w, h;
Blt_Ts_GetExtents(&tmPtr->style, tmPtr->string, &w, &h);
+
+ double rw, rh;
Blt_GetBoundingBox(w, h, tmPtr->style.angle, &rw, &rh, tmPtr->outline);
tmPtr->width = ROUND(rw);
tmPtr->height = ROUND(rh);
- for (i = 0; i < 4; i++) {
- tmPtr->outline[i].x += ROUND(rw * 0.5);
- tmPtr->outline[i].y += ROUND(rh * 0.5);
+ for (int ii=0; ii<4; ii++) {
+ tmPtr->outline[ii].x += ROUND(rw * 0.5);
+ tmPtr->outline[ii].y += ROUND(rh * 0.5);
}
tmPtr->outline[4].x = tmPtr->outline[0].x;
tmPtr->outline[4].y = tmPtr->outline[0].y;
- anchorPt = Blt_MapPoint(markerPtr->worldPts, &markerPtr->axes);
- anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, (double)(tmPtr->width),
- (double)(tmPtr->height), tmPtr->anchor);
+
+ Point2d anchorPt = Blt_MapPoint(&tmPtr->world, &markerPtr->axes);
+ anchorPt = Blt_AnchorPoint(anchorPt.x, anchorPt.y, tmPtr->width,
+ tmPtr->height, tmPtr->anchor);
anchorPt.x += markerPtr->xOffset;
anchorPt.y += markerPtr->yOffset;
- /*
- * Determine the bounding box of the text and test to see if it is at
- * least partially contained within the plotting area.
- */
+
+ Region2d extents;
extents.left = anchorPt.x;
extents.top = anchorPt.y;
extents.right = anchorPt.x + tmPtr->width - 1;
extents.bottom = anchorPt.y + tmPtr->height - 1;
markerPtr->clipped = Blt_BoxesDontOverlap(graphPtr, &extents);
tmPtr->anchorPt = anchorPt;
-
}
-static int PointInTextProc(Marker *markerPtr, Point2d *samplePtr)
+static int PointInTextProc(Marker* markerPtr, Point2d *samplePtr)
{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
- if (tmPtr->string == NULL) {
+ if (!tmPtr->string)
return 0;
- }
+
if (tmPtr->style.angle != 0.0f) {
Point2d points[5];
- int i;
-
- /*
- * Figure out the bounding polygon (isolateral) for the text and see
- * if the point is inside of it.
- */
- for (i = 0; i < 5; i++) {
- points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x;
- points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y;
+
+ // Figure out the bounding polygon (isolateral) for the text and see
+ // if the point is inside of it.
+ for (int ii=0; ii<5; ii++) {
+ points[ii].x = tmPtr->outline[ii].x + tmPtr->anchorPt.x;
+ points[ii].y = tmPtr->outline[ii].y + tmPtr->anchorPt.y;
}
return Blt_PointInPolygon(samplePtr, points, 5);
}
+
return ((samplePtr->x >= tmPtr->anchorPt.x) &&
(samplePtr->x < (tmPtr->anchorPt.x + tmPtr->width)) &&
(samplePtr->y >= tmPtr->anchorPt.y) &&
(samplePtr->y < (tmPtr->anchorPt.y + tmPtr->height)));
}
-static int RegionInTextProc(Marker *markerPtr, Region2d *extsPtr, int enclosed)
+static int RegionInTextProc(Marker* markerPtr, Region2d *extsPtr, int enclosed)
{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
- if (markerPtr->nWorldPts < 1) {
- return FALSE;
- }
if (tmPtr->style.angle != 0.0f) {
+ // Generate the bounding polygon (isolateral) for the bitmap and see
+ // if the point is inside of it.
Point2d points[5];
- int i;
-
- /*
- * Generate the bounding polygon (isolateral) for the bitmap and see
- * if the point is inside of it.
- */
- for (i = 0; i < 4; i++) {
- points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x;
- points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y;
+ for (int ii=0; ii<4; ii++) {
+ points[ii].x = tmPtr->outline[ii].x + tmPtr->anchorPt.x;
+ points[ii].y = tmPtr->outline[ii].y + tmPtr->anchorPt.y;
}
return Blt_RegionInPolygon(extsPtr, points, 4, enclosed);
}
- if (enclosed) {
+
+ if (enclosed)
return ((tmPtr->anchorPt.x >= extsPtr->left) &&
(tmPtr->anchorPt.y >= extsPtr->top) &&
((tmPtr->anchorPt.x + tmPtr->width) <= extsPtr->right) &&
((tmPtr->anchorPt.y + tmPtr->height) <= extsPtr->bottom));
- }
+
return !((tmPtr->anchorPt.x >= extsPtr->right) ||
(tmPtr->anchorPt.y >= extsPtr->bottom) ||
((tmPtr->anchorPt.x + tmPtr->width) <= extsPtr->left) ||
((tmPtr->anchorPt.y + tmPtr->height) <= extsPtr->top));
}
-static void DrawTextProc(Marker *markerPtr, Drawable drawable)
+static void DrawTextProc(Marker* markerPtr, Drawable drawable)
{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
Graph* graphPtr = markerPtr->obj.graphPtr;
- if (tmPtr->string == NULL) {
+ if (!tmPtr->string)
return;
- }
+
if (tmPtr->fillGC) {
+ // Simulate the rotated background of the bitmap by filling a bounding
+ // polygon with the background color.
XPoint points[4];
- int i;
-
- /*
- * Simulate the rotated background of the bitmap by filling a bounding
- * polygon with the background color.
- */
- for (i = 0; i < 4; i++) {
- points[i].x = (short int)(tmPtr->outline[i].x + tmPtr->anchorPt.x);
- points[i].y = (short int)(tmPtr->outline[i].y + tmPtr->anchorPt.y);
+ for (int ii=0; ii<4; ii++) {
+ points[ii].x = (short int)(tmPtr->outline[ii].x + tmPtr->anchorPt.x);
+ points[ii].y = (short int)(tmPtr->outline[ii].y + tmPtr->anchorPt.y);
}
XFillPolygon(graphPtr->display, drawable, tmPtr->fillGC, points, 4,
Convex, CoordModeOrigin);
}
- if (tmPtr->style.color) {
- Blt_Ts_DrawText(graphPtr->tkwin, drawable, tmPtr->string, -1,
- &tmPtr->style, (int)tmPtr->anchorPt.x, (int)tmPtr->anchorPt.y);
- }
+
+ // be sure to update style->gc, things might have changed
+ tmPtr->style.flags |= UPDATE_GC;
+ Blt_Ts_DrawText(graphPtr->tkwin, drawable, tmPtr->string, -1,
+ &tmPtr->style, tmPtr->anchorPt.x, tmPtr->anchorPt.y);
}
-static void TextToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+static void TextToPostscriptProc(Marker* markerPtr, Blt_Ps ps)
{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
- if (tmPtr->string == NULL) {
+ if (!tmPtr->string)
return;
- }
+
if (tmPtr->fillGC) {
+ // Simulate the rotated background of the bitmap by filling a bounding
+ // polygon with the background color.
Point2d points[4];
- int i;
-
- /*
- * Simulate the rotated background of the bitmap by filling a bounding
- * polygon with the background color.
- */
- for (i = 0; i < 4; i++) {
- points[i].x = tmPtr->outline[i].x + tmPtr->anchorPt.x;
- points[i].y = tmPtr->outline[i].y + tmPtr->anchorPt.y;
+ for (int ii=0; ii<4; ii++) {
+ points[ii].x = tmPtr->outline[ii].x + tmPtr->anchorPt.x;
+ points[ii].y = tmPtr->outline[ii].y + tmPtr->anchorPt.y;
}
Blt_Ps_XSetBackground(ps, tmPtr->fillColor);
Blt_Ps_XFillPolygon(ps, points, 4);
}
+
Blt_Ps_DrawText(ps, tmPtr->string, &tmPtr->style, tmPtr->anchorPt.x,
tmPtr->anchorPt.y);
}
-static void FreeTextProc(Marker *markerPtr)
+static void FreeTextProc(Marker* markerPtr)
{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
+ TextMarker* tmPtr = (TextMarker*)markerPtr;
Graph* graphPtr = markerPtr->obj.graphPtr;
Blt_Ts_FreeStyle(graphPtr->display, &tmPtr->style);
diff --git a/src/bltGrMarkerText.h b/src/bltGrMarkerText.h
index b3e289d..7c26501 100644
--- a/src/bltGrMarkerText.h
+++ b/src/bltGrMarkerText.h
@@ -34,43 +34,30 @@
class TextMarker {
public:
- GraphObj obj; /* Must be first field in marker. */
+ GraphObj obj;
MarkerClass *classPtr;
-
- Tk_OptionTable optionTable; /* Configuration specifications */
+ Tk_OptionTable optionTable;
Tcl_HashEntry *hashPtr;
Blt_ChainLink link;
- const char* elemName; /* Element associated with marker. Let's
- * you link a marker to an element. The
- * marker is drawn only if the element
- * is also visible. */
+ const char* elemName;
Axis2d axes;
- Point2d *worldPts; /* Coordinate array to position
- * marker. */
- int nWorldPts; /* # of points in above array */
- int drawUnder; /* If non-zero, draw the marker
- * underneath any elements. This can be
- * a performance penalty because the
- * graph must be redraw entirely each
- * time the marker is redrawn. */
- int clipped; /* Indicates if the marker is totally
- * clipped by the plotting area. */
+ int drawUnder;
+ int clipped;
int hide;
unsigned int flags;
-
-
- int xOffset, yOffset; /* Pixel offset from graph position */
+ int xOffset;
+ int yOffset;
int state;
- /* Fields specific to text markers. */
- const char* string; /* Text string to be display. The
- * string make contain newlines. */
- Tk_Anchor anchor; /* Indicates how to translate the given
- * marker position. */
- Point2d anchorPt; /* Translated anchor point. */
- int width, height; /* Dimension of bounding box. */
- TextStyle style; /* Text attributes (font, fg, anchor,
- * etc) */
+ // Fields specific to text
+
+ Point2d world;
+ const char* string;
+ Tk_Anchor anchor;
+ Point2d anchorPt;
+ int width;
+ int height;
+ TextStyle style;
Point2d outline[5];
XColor* fillColor;
GC fillGC;
diff --git a/src/bltGrText.C b/src/bltGrText.C
index 1f3f0e5..eec1086 100644
--- a/src/bltGrText.C
+++ b/src/bltGrText.C
@@ -48,73 +48,58 @@ extern "C" {
void Blt_GetTextExtents(Tk_Font font, int leader, const char *text, int textLen,
unsigned int *widthPtr, unsigned int *heightPtr)
{
- unsigned int lineHeight;
-
- if (text == NULL)
+ if (!text) {
+ *widthPtr =0;
+ *heightPtr =0;
return;
+ }
- {
- Tk_FontMetrics fm;
+ Tk_FontMetrics fm;
+ Tk_GetFontMetrics(font, &fm);
+ unsigned int lineHeight = fm.linespace;
- Tk_GetFontMetrics(font, &fm);
- lineHeight = fm.linespace;
- }
- if (textLen < 0) {
+ if (textLen < 0)
textLen = strlen(text);
- }
- {
- unsigned int lineLen; /* # of characters on each line */
- const char *p, *pend;
- const char *line;
- unsigned int maxWidth, maxHeight;
-
- maxWidth = maxHeight = 0;
- lineLen = 0;
- for (p = line = text, pend = text + textLen; p < pend; p++) {
- if (*p == '\n') {
- if (lineLen > 0) {
- unsigned int lineWidth;
-
- lineWidth = Tk_TextWidth(font, line, lineLen);
- if (lineWidth > maxWidth) {
- maxWidth = lineWidth;
- }
- }
- maxHeight += lineHeight;
- line = p + 1; /* Point to the start of the next line. */
- lineLen = 0; /* Reset counter to indicate the start of a
- * new line. */
- continue;
+
+ unsigned int maxWidth =0;
+ unsigned int maxHeight =0;
+ unsigned int lineLen =0;
+ const char *line =NULL;
+ const char *p, *pend;
+ for (p = line = text, pend = text + textLen; p < pend; p++) {
+ if (*p == '\n') {
+ if (lineLen > 0) {
+ unsigned int lineWidth = Tk_TextWidth(font, line, lineLen);
+ if (lineWidth > maxWidth)
+ maxWidth = lineWidth;
}
- lineLen++;
- }
- if ((lineLen > 0) && (*(p - 1) != '\n')) {
- unsigned int lineWidth;
-
maxHeight += lineHeight;
- lineWidth = Tk_TextWidth(font, line, lineLen);
- if (lineWidth > maxWidth) {
- maxWidth = lineWidth;
- }
+ line = p + 1; /* Point to the start of the next line. */
+ lineLen = 0; /* Reset counter to indicate the start of a
+ * new line. */
+ continue;
}
- *widthPtr = maxWidth;
- *heightPtr = maxHeight;
+ lineLen++;
+ }
+
+ if ((lineLen > 0) && (*(p - 1) != '\n')) {
+ maxHeight += lineHeight;
+ unsigned int lineWidth = Tk_TextWidth(font, line, lineLen);
+ if (lineWidth > maxWidth)
+ maxWidth = lineWidth;
}
+
+ *widthPtr = maxWidth;
+ *heightPtr = maxHeight;
}
void Blt_Ts_GetExtents(TextStyle *tsPtr, const char *text,
unsigned int *widthPtr, unsigned int *heightPtr)
{
-
- if (text == NULL)
- *widthPtr = *heightPtr = 0;
- else {
- unsigned int w, h;
-
- Blt_GetTextExtents(tsPtr->font, tsPtr->leader, text, -1, &w, &h);
- *widthPtr = w + 2*tsPtr->xPad;
- *heightPtr = h + 2*tsPtr->yPad;
- }
+ unsigned int w, h;
+ Blt_GetTextExtents(tsPtr->font, tsPtr->leader, text, -1, &w, &h);
+ *widthPtr = w + 2*tsPtr->xPad;
+ *heightPtr = h + 2*tsPtr->yPad;
}
/*
@@ -161,11 +146,10 @@ void Blt_GetBoundingBox(int width, int height, float angle,
if (fmod(angle, (double)90.0) == 0.0) {
int ll, ur, ul, lr;
double rotWidth, rotHeight;
- int quadrant;
/* Handle right-angle rotations specially. */
- quadrant = (int)(angle / 90.0);
+ int quadrant = (int)(angle / 90.0);
switch (quadrant) {
case ROTATE_270: /* 270 degrees */
ul = 3, ur = 0, lr = 1, ll = 2;
@@ -216,12 +200,12 @@ void Blt_GetBoundingBox(int width, int height, float angle,
for (i = 0; i < 4; i++) {
x = (corner[i].x * cosTheta) - (corner[i].y * sinTheta);
y = (corner[i].x * sinTheta) + (corner[i].y * cosTheta);
- if (x > xMax) {
+ if (x > xMax)
xMax = x;
- }
- if (y > yMax) {
+
+ if (y > yMax)
yMax = y;
- }
+
if (bbox) {
bbox[i].x = x;
bbox[i].y = y;
@@ -335,19 +319,16 @@ static Point2d Rotate_Text(int x, int y, int w1, int h1, TextStyle* stylePtr)
void Blt_Ts_DrawText(Tk_Window tkwin, Drawable drawable, const char *text,
int textLen, TextStyle *stylePtr,int x, int y)
{
- Tk_TextLayout layout;
- int w1, h1;
- Point2d rr;
-
- if ((text == NULL) || (*text == '\0'))
+ if (!text || !(*text))
return;
if ((stylePtr->gc == NULL) || (stylePtr->flags & UPDATE_GC))
Blt_Ts_ResetStyle(tkwin, stylePtr);
- layout = Tk_ComputeTextLayout(stylePtr->font, text, textLen,-1,
- stylePtr->justify, 0, &w1, &h1);
- rr = Rotate_Text(x, y, w1, h1, stylePtr);
+ int w1, h1;
+ Tk_TextLayout layout = Tk_ComputeTextLayout(stylePtr->font, text, textLen,-1,
+ stylePtr->justify, 0, &w1, &h1);
+ Point2d rr = Rotate_Text(x, y, w1, h1, stylePtr);
TkDrawAngledTextLayout(Tk_Display(tkwin), drawable, stylePtr->gc, layout,
rr.x, rr.y, stylePtr->angle, 0, textLen);
}
@@ -355,19 +336,16 @@ void Blt_Ts_DrawText(Tk_Window tkwin, Drawable drawable, const char *text,
void Blt_DrawText2(Tk_Window tkwin, Drawable drawable, const char *text,
TextStyle *stylePtr, int x, int y, Dim2D *areaPtr)
{
- Tk_TextLayout layout;
- int w1, h1;
- Point2d rr;
-
- if ((text == NULL) || (*text == '\0'))
+ if (!text || !(*text))
return;
if ((stylePtr->gc == NULL) || (stylePtr->flags & UPDATE_GC))
Blt_Ts_ResetStyle(tkwin, stylePtr);
- layout = Tk_ComputeTextLayout(stylePtr->font, text, -1, -1,
+ int w1, h1;
+ Tk_TextLayout layout = Tk_ComputeTextLayout(stylePtr->font, text, -1, -1,
stylePtr->justify, 0, &w1, &h1);
- rr = Rotate_Text(x, y, w1, h1, stylePtr);
+ Point2d rr = Rotate_Text(x, y, w1, h1, stylePtr);
TkDrawAngledTextLayout(Tk_Display(tkwin), drawable, stylePtr->gc, layout,
rr.x, rr.y, stylePtr->angle, 0, -1);
@@ -377,7 +355,6 @@ void Blt_DrawText2(Tk_Window tkwin, Drawable drawable, const char *text,
if (angle != 0.0) {
double rotWidth, rotHeight;
-
Blt_GetBoundingBox(w1, h1, angle, &rotWidth, &rotHeight,
(Point2d *)NULL);
w1 = ROUND(rotWidth);
@@ -391,19 +368,16 @@ void Blt_DrawText2(Tk_Window tkwin, Drawable drawable, const char *text,
void Blt_DrawText(Tk_Window tkwin, Drawable drawable, const char *text,
TextStyle *stylePtr, int x, int y)
{
- Tk_TextLayout layout;
- int w1, h1;
- Point2d rr;
-
if (!text || (*text == '\0'))
return;
if (!stylePtr->gc || (stylePtr->flags & UPDATE_GC))
Blt_Ts_ResetStyle(tkwin, stylePtr);
- layout = Tk_ComputeTextLayout(stylePtr->font, text, -1, -1,
+ int w1, h1;
+ Tk_TextLayout layout = Tk_ComputeTextLayout(stylePtr->font, text, -1, -1,
stylePtr->justify, 0, &w1, &h1);
- rr = Rotate_Text(x, y, w1, h1, stylePtr);
+ Point2d rr = Rotate_Text(x, y, w1, h1, stylePtr);
TkDrawAngledTextLayout(Tk_Display(tkwin), drawable, stylePtr->gc, layout,
rr.x, rr.y, stylePtr->angle, 0, -1);
}
diff --git a/src/bltGrText.h b/src/bltGrText.h
index ec9399e..f01aa85 100644
--- a/src/bltGrText.h
+++ b/src/bltGrText.h
@@ -30,18 +30,8 @@
#ifndef _BLT_TEXT_H
#define _BLT_TEXT_H
-#define DEF_TEXT_FLAGS (TK_PARTIAL_OK | TK_IGNORE_NEWLINES)
#define UPDATE_GC 1
-/*
- * TextStyle --
- *
- * A somewhat convenient structure to hold text attributes that determine
- * how a text string is to be displayed on the screen or drawn with
- * PostScript commands. The alternative is to pass lots of parameters to
- * the drawing and printing routines. This seems like a more efficient
- * and less cumbersome way of passing parameters.
- */
typedef struct {
unsigned int state; /* If non-zero, indicates to draw text
* in the active color */
diff --git a/tests/bitmapmarker.tcl b/tests/bitmapmarker.tcl
index b71e58d..8d8f108 100644
--- a/tests/bitmapmarker.tcl
+++ b/tests/bitmapmarker.tcl
@@ -4,15 +4,13 @@ set w .line
set graph [bltLineGraph $w]
set mm [$graph marker create bitmap tt -element data1 \
- -coords {1.5 100} -bitmap error]
-return
+ -x 1.5 -y 100 -bitmap error]
+
bltTest3 $graph marker $mm -anchor nw
bltTest3 $graph marker $mm -background yellow
bltTest3 $graph marker $mm -bg red
bltTest3 $graph marker $mm -bindtags {aa}
bltTest3 $graph marker $mm -bitmap hourglass
-bltTest3 $graph marker $mm -coords {1 50}
-bltTest3 $graph marker $mm -coords {1 50 1.1 60}
bltTest3 $graph marker $mm -element data2
bltTest3 $graph marker $mm -fg cyan
bltTest3 $graph marker $mm -fill yellow
@@ -23,7 +21,9 @@ bltTest3 $graph marker $mm -mapy y
bltTest3 $graph marker $mm -outline green
bltTest3 $graph marker $mm -state disabled
bltTest3 $graph marker $mm -under yes
+bltTest3 $graph marker $mm -x 1
bltTest3 $graph marker $mm -xoffset 20
+bltTest3 $graph marker $mm -y 150
bltTest3 $graph marker $mm -yoffset 20
echo "done"
diff --git a/tests/textmarker.tcl b/tests/textmarker.tcl
index 29da9b2..3d1fa2a 100644
--- a/tests/textmarker.tcl
+++ b/tests/textmarker.tcl
@@ -5,7 +5,7 @@ set graph [bltLineGraph $w]
set mm [$graph marker create text tt -element data1 \
-x 1.5 -y 100 -text {Text Marker} -font {24}]
-return
+
bltTest3 $graph marker $mm -anchor nw
bltTest3 $graph marker $mm -background blue
bltTest3 $graph marker $mm -bg red