diff options
-rwxr-xr-x | configure | 1 | ||||
-rwxr-xr-x | configure.in | 1 | ||||
-rw-r--r-- | src/bltGrMarker.C | 330 | ||||
-rw-r--r-- | src/bltGrMarkerText.C | 316 | ||||
-rw-r--r-- | src/bltGrMarkerText.h | 78 |
5 files changed, 398 insertions, 328 deletions
@@ -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 |