summaryrefslogtreecommitdiffstats
path: root/generic/tkbltGrText.C
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkbltGrText.C')
-rw-r--r--generic/tkbltGrText.C240
1 files changed, 240 insertions, 0 deletions
diff --git a/generic/tkbltGrText.C b/generic/tkbltGrText.C
new file mode 100644
index 0000000..20709f1
--- /dev/null
+++ b/generic/tkbltGrText.C
@@ -0,0 +1,240 @@
+/*
+ * 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 <cmath>
+
+#include <tk.h>
+#include <tkInt.h>
+
+#include "tkbltGrText.h"
+#include "tkbltGraph.h"
+#include "tkbltGrPSOutput.h"
+
+using namespace Blt;
+
+TextStyle::TextStyle(Graph* graphPtr)
+{
+ ops_ = (TextStyleOptions*)calloc(1, sizeof(TextStyleOptions));
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+ graphPtr_ = graphPtr;
+ manageOptions_ = 1;
+
+ ops->anchor =TK_ANCHOR_NW;
+ ops->color =NULL;
+ ops->font =NULL;
+ ops->angle =0;
+ ops->justify =TK_JUSTIFY_LEFT;
+
+ xPad_ = 0;
+ yPad_ = 0;
+ gc_ = NULL;
+}
+
+TextStyle::TextStyle(Graph* graphPtr, TextStyleOptions* ops)
+{
+ ops_ = (TextStyleOptions*)ops;
+ graphPtr_ = graphPtr;
+ manageOptions_ = 0;
+
+ xPad_ = 0;
+ yPad_ = 0;
+ gc_ = NULL;
+}
+
+TextStyle::~TextStyle()
+{
+ // TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ if (gc_)
+ Tk_FreeGC(graphPtr_->display_, gc_);
+
+ if (manageOptions_)
+ free(ops_);
+}
+
+void TextStyle::drawText(Drawable drawable, const char *text, int x, int y)
+{
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ if (!text || !(*text))
+ return;
+
+ if (!gc_)
+ resetStyle();
+
+ int w1, h1;
+ Tk_TextLayout layout = Tk_ComputeTextLayout(ops->font, text, -1, -1,
+ ops->justify, 0, &w1, &h1);
+ Point2d rr = rotateText(x, y, w1, h1);
+#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 6)
+ TkDrawAngledTextLayout(graphPtr_->display_, drawable, gc_, layout,
+ rr.x, rr.y, ops->angle, 0, -1);
+#else
+ Tk_DrawTextLayout(graphPtr_->display_, drawable, gc_, layout,
+ rr.x, rr.y, 0, -1);
+#endif
+}
+
+void TextStyle::drawText2(Drawable drawable, const char *text,
+ int x, int y, int* ww, int* hh)
+{
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ if (!text || !(*text))
+ return;
+
+ if (!gc_)
+ resetStyle();
+
+ int w1, h1;
+ Tk_TextLayout layout = Tk_ComputeTextLayout(ops->font, text, -1, -1,
+ ops->justify, 0, &w1, &h1);
+ Point2d rr = rotateText(x, y, w1, h1);
+#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 6)
+ TkDrawAngledTextLayout(graphPtr_->display_, drawable, gc_, layout,
+ rr.x, rr.y, ops->angle, 0, -1);
+#else
+ Tk_DrawTextLayout(graphPtr_->display_, drawable, gc_, layout,
+ rr.x, rr.y, 0, -1);
+#endif
+
+ float angle = fmod(ops->angle, 360.0);
+ if (angle < 0.0)
+ angle += 360.0;
+
+ if (angle != 0.0) {
+ double rotWidth, rotHeight;
+ graphPtr_->getBoundingBox(w1, h1, angle, &rotWidth, &rotHeight, NULL);
+ w1 = rotWidth;
+ h1 = rotHeight;
+ }
+
+ *ww = w1;
+ *hh = h1;
+}
+
+void TextStyle::printText(PSOutput* psPtr, const char *text, int x, int y)
+{
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ if (!text || !(*text))
+ return;
+
+ int w1, h1;
+ Tk_TextLayout layout = Tk_ComputeTextLayout(ops->font, text, -1, -1,
+ ops->justify, 0, &w1, &h1);
+
+ int xx =0;
+ int yy =0;
+ switch (ops->anchor) {
+ case TK_ANCHOR_NW: xx = 0; yy = 0; break;
+ case TK_ANCHOR_N: xx = 1; yy = 0; break;
+ case TK_ANCHOR_NE: xx = 2; yy = 0; break;
+ case TK_ANCHOR_E: xx = 2; yy = 1; break;
+ case TK_ANCHOR_SE: xx = 2; yy = 2; break;
+ case TK_ANCHOR_S: xx = 1; yy = 2; break;
+ case TK_ANCHOR_SW: xx = 0; yy = 2; break;
+ case TK_ANCHOR_W: xx = 0; yy = 1; break;
+ case TK_ANCHOR_CENTER: xx = 1; yy = 1; break;
+ }
+
+ const char* justify =NULL;
+ switch (ops->justify) {
+ case TK_JUSTIFY_LEFT: justify = "0"; break;
+ case TK_JUSTIFY_CENTER: justify = "0.5"; break;
+ case TK_JUSTIFY_RIGHT: justify = "1"; break;
+ }
+
+ psPtr->setFont(ops->font);
+ psPtr->setForeground(ops->color);
+
+ psPtr->format("%g %d %d [\n", ops->angle, x, y);
+ Tcl_ResetResult(graphPtr_->interp_);
+ Tk_TextLayoutToPostscript(graphPtr_->interp_, layout);
+ psPtr->append(Tcl_GetStringResult(graphPtr_->interp_));
+ Tcl_ResetResult(graphPtr_->interp_);
+ psPtr->format("] %g %g %s DrawText\n", xx/-2.0, yy/-2.0, justify);
+}
+
+void TextStyle::resetStyle()
+{
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ unsigned long gcMask;
+ gcMask = GCFont;
+
+ XGCValues gcValues;
+ gcValues.font = Tk_FontId(ops->font);
+ if (ops->color) {
+ gcMask |= GCForeground;
+ gcValues.foreground = ops->color->pixel;
+ }
+ GC newGC = Tk_GetGC(graphPtr_->tkwin_, gcMask, &gcValues);
+ if (gc_)
+ Tk_FreeGC(graphPtr_->display_, gc_);
+
+ gc_ = newGC;
+}
+
+Point2d TextStyle::rotateText(int x, int y, int w1, int h1)
+{
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ // Matrix t0 = Translate(-x,-y);
+ // Matrix t1 = Translate(-w1/2,-h1/2);
+ // Matrix rr = Rotate(angle);
+ // Matrix t2 = Translate(w2/2,h2/2);
+ // Matrix t3 = Translate(x,y);
+
+ double angle = ops->angle;
+ double ccos = cos(M_PI*angle/180.);
+ double ssin = sin(M_PI*angle/180.);
+ double w2, h2;
+ graphPtr_->getBoundingBox(w1, h1, angle, &w2, &h2, NULL);
+
+ double x1 = x+w1/2.;
+ double y1 = y+h1/2.;
+ double x2 = w2/2.+x;
+ double y2 = h2/2.+y;
+
+ double rx = x*ccos + y*ssin + (-x1*ccos -y1*ssin +x2);
+ double ry = -x*ssin + y*ccos + ( x1*ssin -y1*ccos +y2);
+
+ return graphPtr_->anchorPoint(rx, ry, w2, h2, ops->anchor);
+}
+
+void TextStyle::getExtents(const char *text, int* ww, int* hh)
+{
+ TextStyleOptions* ops = (TextStyleOptions*)ops_;
+
+ int w, h;
+ graphPtr_->getTextExtents(ops->font, text, -1, &w, &h);
+ *ww = w + 2*xPad_;
+ *hh = h + 2*yPad_;
+}