summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure1
-rwxr-xr-xconfigure.in1
-rw-r--r--src/bltGrMarker.C330
-rw-r--r--src/bltGrMarkerText.C316
-rw-r--r--src/bltGrMarkerText.h78
5 files changed, 398 insertions, 328 deletions
diff --git a/configure b/configure
index f9fb410..7cca8f9 100755
--- a/configure
+++ b/configure
@@ -5540,6 +5540,7 @@ done
bltGrMarkerBitmap.c
bltGrMarkerLine.c
bltGrMarkerPolygon.c
+ bltGrMarkerText.c
bltGrMisc.c
bltGrPen.c
bltGrPs.c
diff --git a/configure.in b/configure.in
index 33bb2c0..cdd1d7b 100755
--- a/configure.in
+++ b/configure.in
@@ -85,6 +85,7 @@ TEA_ADD_SOURCES([
bltGrMarkerBitmap.c
bltGrMarkerLine.c
bltGrMarkerPolygon.c
+ bltGrMarkerText.c
bltGrMisc.c
bltGrPen.c
bltGrPs.c
diff --git a/src/bltGrMarker.C b/src/bltGrMarker.C
index c208fcb..31a529d 100644
--- a/src/bltGrMarker.C
+++ b/src/bltGrMarker.C
@@ -36,6 +36,7 @@
#include "bltGrMarkerBitmap.h"
#include "bltGrMarkerLine.h"
#include "bltGrMarkerPolygon.h"
+#include "bltGrMarkerText.h"
typedef int (GraphMarkerProc)(Graph* graphPtr, Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[]);
@@ -59,124 +60,6 @@ Blt_CustomOption colorPairOption =
};
static Tcl_FreeProc FreeMarker;
-
-
-
-typedef struct {
- GraphObj obj; /* Must be first field in marker. */
- MarkerClass *classPtr;
- 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. */
- 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 hide;
- unsigned int flags;
-
-
- int xOffset, yOffset; /* Pixel offset from graph position */
- 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) */
- Point2d outline[5];
- XColor* fillColor;
- GC fillGC;
-} TextMarker;
-
-static Blt_ConfigSpec textConfigSpecs[] = {
- {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center",
- Tk_Offset(TextMarker, anchor), 0},
- {BLT_CONFIG_COLOR, "-background", "background", "MarkerBackground",
- (char*)NULL, Tk_Offset(TextMarker, fillColor), BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_SYNONYM, "-bg", "background", "Background", (char*)NULL, 0, 0},
- {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Text all",
- Tk_Offset(TextMarker, obj.tags), BLT_CONFIG_NULL_OK,
- &listOption},
- {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL,
- Tk_Offset(TextMarker, worldPts), BLT_CONFIG_NULL_OK,
- &coordsOption},
- {BLT_CONFIG_STRING, "-element", "element", "Element",
- NULL, Tk_Offset(TextMarker, elemName),
- BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_SYNONYM, "-fg", "foreground", "Foreground", (char*)NULL, 0, 0},
- {BLT_CONFIG_SYNONYM, "-fill", "background", (char*)NULL, (char*)NULL,
- 0, 0},
- {BLT_CONFIG_FONT, "-font", "font", "Font", STD_FONT_NORMAL,
- Tk_Offset(TextMarker, style.font), 0},
- {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
- "black", Tk_Offset(TextMarker, style.color), 0},
- {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify",
- "left", Tk_Offset(TextMarker, style.justify),
- BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no",
- Tk_Offset(TextMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x",
- Tk_Offset(TextMarker, axes.x), 0, &bltXAxisOption},
- {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y",
- Tk_Offset(TextMarker, axes.y), 0, &bltYAxisOption},
- {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL,
- Tk_Offset(TextMarker, obj.name), BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char*)NULL, (char*)NULL,
- 0, 0},
- {BLT_CONFIG_PIXELS, "-padx", "padX", "PadX", "4",
- Tk_Offset(TextMarker, style.xPad), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_PIXELS, "-pady", "padY", "PadY", "4",
- Tk_Offset(TextMarker, style.yPad), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_DOUBLE, "-rotate", "rotate", "Rotate", "0",
- Tk_Offset(TextMarker, style.angle), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal",
- Tk_Offset(TextMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption},
- {BLT_CONFIG_STRING, "-text", "text", "Text", NULL,
- Tk_Offset(TextMarker, string), BLT_CONFIG_NULL_OK},
- {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no",
- Tk_Offset(TextMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0",
- Tk_Offset(TextMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0",
- Tk_Offset(TextMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
- {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
-};
-
-static MarkerConfigProc ConfigureTextProc;
-static MarkerCreateProc CreateTextProc;
-static MarkerDrawProc DrawTextProc;
-static MarkerFreeProc FreeTextProc;
-static MarkerMapProc MapTextProc;
-static MarkerPointProc PointInTextProc;
-static MarkerPostscriptProc TextToPostscriptProc;
-static MarkerRegionProc RegionInTextProc;
-
-static MarkerClass textMarkerClass = {
- textConfigSpecs,
- ConfigureTextProc,
- DrawTextProc,
- FreeTextProc,
- MapTextProc,
- PointInTextProc,
- RegionInTextProc,
- TextToPostscriptProc,
-};
-
typedef struct {
GraphObj obj; /* Must be first field in marker. */
@@ -675,7 +558,7 @@ static Marker* CreateMarker(Graph* graphPtr, const char* name, ClassId classId)
return NULL; /* not supported */
break;
case CID_MARKER_TEXT:
- markerPtr = CreateTextProc(); /* text */
+ markerPtr = Blt_CreateTextProc(); /* text */
break;
case CID_MARKER_POLYGON:
markerPtr = Blt_CreatePolygonProc(); /* polygon */
@@ -734,215 +617,6 @@ static void FreeMarker(char* dataPtr)
DestroyMarker(markerPtr);
}
-static int ConfigureTextProc(Marker *markerPtr)
-{
- Graph* graphPtr = markerPtr->obj.graphPtr;
- TextMarker *tmPtr = (TextMarker *)markerPtr;
- GC newGC;
- XGCValues gcValues;
- unsigned long gcMask;
-
- tmPtr->style.angle = (float)fmod(tmPtr->style.angle, 360.0);
- if (tmPtr->style.angle < 0.0f) {
- tmPtr->style.angle += 360.0f;
- }
- newGC = NULL;
- if (tmPtr->fillColor != NULL) {
- gcMask = GCForeground;
- gcValues.foreground = tmPtr->fillColor->pixel;
- newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
- }
- if (tmPtr->fillGC != NULL) {
- Tk_FreeGC(graphPtr->display, tmPtr->fillGC);
- }
- tmPtr->fillGC = newGC;
-
- markerPtr->flags |= MAP_ITEM;
- if (markerPtr->drawUnder) {
- graphPtr->flags |= CACHE_DIRTY;
- }
- Blt_EventuallyRedrawGraph(graphPtr);
- return TCL_OK;
-}
-
-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;
-
- tmPtr->width = tmPtr->height = 0;
- if (tmPtr->string == NULL) {
- return;
- }
- Blt_Ts_GetExtents(&tmPtr->style, tmPtr->string, &w, &h);
- 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);
- }
- 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);
- 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.
- */
- 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)
-{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
-
- if (tmPtr->string == NULL) {
- 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;
- }
- 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)
-{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
-
- if (markerPtr->nWorldPts < 1) {
- return FALSE;
- }
- if (tmPtr->style.angle != 0.0f) {
- 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;
- }
- return Blt_RegionInPolygon(extsPtr, points, 4, 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)
-{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
- Graph* graphPtr = markerPtr->obj.graphPtr;
-
- if (tmPtr->string == NULL) {
- return;
- }
- if (tmPtr->fillGC != NULL) {
- 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);
- }
- XFillPolygon(graphPtr->display, drawable, tmPtr->fillGC, points, 4,
- Convex, CoordModeOrigin);
- }
- if (tmPtr->style.color != NULL) {
- Blt_Ts_DrawText(graphPtr->tkwin, drawable, tmPtr->string, -1,
- &tmPtr->style, (int)tmPtr->anchorPt.x, (int)tmPtr->anchorPt.y);
- }
-}
-
-static void TextToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
-{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
-
- if (tmPtr->string == NULL) {
- return;
- }
- if (tmPtr->fillGC != NULL) {
- 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;
- }
- 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)
-{
- TextMarker *tmPtr = (TextMarker *)markerPtr;
- Graph* graphPtr = markerPtr->obj.graphPtr;
-
- Blt_Ts_FreeStyle(graphPtr->display, &tmPtr->style);
-}
-
-static Marker* CreateTextProc(void)
-{
- TextMarker *tmPtr;
-
- tmPtr = calloc(1, sizeof(TextMarker));
- tmPtr->classPtr = &textMarkerClass;
- Blt_Ts_InitStyle(tmPtr->style);
- tmPtr->style.anchor = TK_ANCHOR_NW;
- tmPtr->style.xPad = 4;
- tmPtr->style.yPad = 4;
- return (Marker *)tmPtr;
-}
-
static Tk_EventProc ChildEventProc;
static Tk_GeomRequestProc ChildGeometryProc;
static Tk_GeomLostSlaveProc ChildCustodyProc;
diff --git a/src/bltGrMarkerText.C b/src/bltGrMarkerText.C
new file mode 100644
index 0000000..84ed7d7
--- /dev/null
+++ b/src/bltGrMarkerText.C
@@ -0,0 +1,316 @@
+/*
+ * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+ * This code has been modified under the terms listed below and is made
+ * available under the same terms.
+ */
+
+/*
+ * Copyright 1993-2004 George A Howlett.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "bltGraph.h"
+#include "bltGrMarkerText.h"
+#include "bltMath.h"
+
+static Blt_ConfigSpec textConfigSpecs[] = {
+ {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center",
+ Tk_Offset(TextMarker, anchor), 0},
+ {BLT_CONFIG_COLOR, "-background", "background", "MarkerBackground",
+ (char*)NULL, Tk_Offset(TextMarker, fillColor), BLT_CONFIG_NULL_OK},
+ {BLT_CONFIG_SYNONYM, "-bg", "background", "Background", (char*)NULL, 0, 0},
+ {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Text all",
+ Tk_Offset(TextMarker, obj.tags), BLT_CONFIG_NULL_OK,
+ &listOption},
+ {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL,
+ Tk_Offset(TextMarker, worldPts), BLT_CONFIG_NULL_OK,
+ &coordsOption},
+ {BLT_CONFIG_STRING, "-element", "element", "Element",
+ NULL, Tk_Offset(TextMarker, elemName),
+ BLT_CONFIG_NULL_OK},
+ {BLT_CONFIG_SYNONYM, "-fg", "foreground", "Foreground", (char*)NULL, 0, 0},
+ {BLT_CONFIG_SYNONYM, "-fill", "background", (char*)NULL, (char*)NULL,
+ 0, 0},
+ {BLT_CONFIG_FONT, "-font", "font", "Font", STD_FONT_NORMAL,
+ Tk_Offset(TextMarker, style.font), 0},
+ {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
+ "black", Tk_Offset(TextMarker, style.color), 0},
+ {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify",
+ "left", Tk_Offset(TextMarker, style.justify),
+ BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no",
+ Tk_Offset(TextMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x",
+ Tk_Offset(TextMarker, axes.x), 0, &bltXAxisOption},
+ {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y",
+ Tk_Offset(TextMarker, axes.y), 0, &bltYAxisOption},
+ {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL,
+ Tk_Offset(TextMarker, obj.name), BLT_CONFIG_NULL_OK},
+ {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char*)NULL, (char*)NULL,
+ 0, 0},
+ {BLT_CONFIG_PIXELS, "-padx", "padX", "PadX", "4",
+ Tk_Offset(TextMarker, style.xPad), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_PIXELS, "-pady", "padY", "PadY", "4",
+ Tk_Offset(TextMarker, style.yPad), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_DOUBLE, "-rotate", "rotate", "Rotate", "0",
+ Tk_Offset(TextMarker, style.angle), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal",
+ Tk_Offset(TextMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption},
+ {BLT_CONFIG_STRING, "-text", "text", "Text", NULL,
+ Tk_Offset(TextMarker, string), BLT_CONFIG_NULL_OK},
+ {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no",
+ Tk_Offset(TextMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0",
+ Tk_Offset(TextMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0",
+ Tk_Offset(TextMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT},
+ {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
+};
+
+MarkerCreateProc Blt_CreateTextProc;
+static MarkerConfigProc ConfigureTextProc;
+static MarkerDrawProc DrawTextProc;
+static MarkerFreeProc FreeTextProc;
+static MarkerMapProc MapTextProc;
+static MarkerPointProc PointInTextProc;
+static MarkerPostscriptProc TextToPostscriptProc;
+static MarkerRegionProc RegionInTextProc;
+
+static MarkerClass textMarkerClass = {
+ textConfigSpecs,
+ ConfigureTextProc,
+ DrawTextProc,
+ FreeTextProc,
+ MapTextProc,
+ PointInTextProc,
+ RegionInTextProc,
+ TextToPostscriptProc,
+};
+
+Marker* Blt_CreateTextProc(void)
+{
+ TextMarker *tmPtr;
+
+ tmPtr = calloc(1, sizeof(TextMarker));
+ tmPtr->classPtr = &textMarkerClass;
+ Blt_Ts_InitStyle(tmPtr->style);
+ tmPtr->style.anchor = TK_ANCHOR_NW;
+ tmPtr->style.xPad = 4;
+ tmPtr->style.yPad = 4;
+ return (Marker *)tmPtr;
+}
+
+static int ConfigureTextProc(Marker *markerPtr)
+{
+ Graph* graphPtr = markerPtr->obj.graphPtr;
+ TextMarker *tmPtr = (TextMarker *)markerPtr;
+ GC newGC;
+ XGCValues gcValues;
+ unsigned long gcMask;
+
+ tmPtr->style.angle = (float)fmod(tmPtr->style.angle, 360.0);
+ if (tmPtr->style.angle < 0.0f) {
+ tmPtr->style.angle += 360.0f;
+ }
+ newGC = NULL;
+ if (tmPtr->fillColor != NULL) {
+ gcMask = GCForeground;
+ gcValues.foreground = tmPtr->fillColor->pixel;
+ newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
+ }
+ if (tmPtr->fillGC != NULL) {
+ Tk_FreeGC(graphPtr->display, tmPtr->fillGC);
+ }
+ tmPtr->fillGC = newGC;
+
+ markerPtr->flags |= MAP_ITEM;
+ if (markerPtr->drawUnder) {
+ graphPtr->flags |= CACHE_DIRTY;
+ }
+ Blt_EventuallyRedrawGraph(graphPtr);
+ return TCL_OK;
+}
+
+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;
+
+ tmPtr->width = tmPtr->height = 0;
+ if (tmPtr->string == NULL) {
+ return;
+ }
+ Blt_Ts_GetExtents(&tmPtr->style, tmPtr->string, &w, &h);
+ 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);
+ }
+ 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);
+ 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.
+ */
+ 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)
+{
+ TextMarker *tmPtr = (TextMarker *)markerPtr;
+
+ if (tmPtr->string == NULL) {
+ 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;
+ }
+ 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)
+{
+ TextMarker *tmPtr = (TextMarker *)markerPtr;
+
+ if (markerPtr->nWorldPts < 1) {
+ return FALSE;
+ }
+ if (tmPtr->style.angle != 0.0f) {
+ 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;
+ }
+ return Blt_RegionInPolygon(extsPtr, points, 4, 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)
+{
+ TextMarker *tmPtr = (TextMarker *)markerPtr;
+ Graph* graphPtr = markerPtr->obj.graphPtr;
+
+ if (tmPtr->string == NULL) {
+ return;
+ }
+ if (tmPtr->fillGC != NULL) {
+ 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);
+ }
+ XFillPolygon(graphPtr->display, drawable, tmPtr->fillGC, points, 4,
+ Convex, CoordModeOrigin);
+ }
+ if (tmPtr->style.color != NULL) {
+ Blt_Ts_DrawText(graphPtr->tkwin, drawable, tmPtr->string, -1,
+ &tmPtr->style, (int)tmPtr->anchorPt.x, (int)tmPtr->anchorPt.y);
+ }
+}
+
+static void TextToPostscriptProc(Marker *markerPtr, Blt_Ps ps)
+{
+ TextMarker *tmPtr = (TextMarker *)markerPtr;
+
+ if (tmPtr->string == NULL) {
+ return;
+ }
+ if (tmPtr->fillGC != NULL) {
+ 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;
+ }
+ 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)
+{
+ 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
new file mode 100644
index 0000000..2b73469
--- /dev/null
+++ b/src/bltGrMarkerText.h
@@ -0,0 +1,78 @@
+/*
+ * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+ * This code has been modified under the terms listed below and is made
+ * available under the same terms.
+ */
+
+/*
+ * Copyright 1993-2004 George A Howlett.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _BLT_GR_MARKER_TEXT_H
+#define _BLT_GR_MARKER_TEXT_H
+
+#include "bltGrMarker.h"
+
+typedef struct {
+ GraphObj obj; /* Must be first field in marker. */
+ MarkerClass *classPtr;
+ 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. */
+ 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 hide;
+ unsigned int flags;
+
+
+ int xOffset, yOffset; /* Pixel offset from graph position */
+ 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) */
+ Point2d outline[5];
+ XColor* fillColor;
+ GC fillGC;
+} TextMarker;
+
+extern MarkerCreateProc Blt_CreateTextProc;
+
+#endif