diff options
Diffstat (limited to 'tksao/frame/text.C')
-rw-r--r-- | tksao/frame/text.C | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/tksao/frame/text.C b/tksao/frame/text.C new file mode 100644 index 0000000..2873043 --- /dev/null +++ b/tksao/frame/text.C @@ -0,0 +1,324 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include <tk.h> + +#include "text.h" +#include "fitsimage.h" + +EXTERN void TkDrawAngledChars(Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *source, int numBytes, double x, + double y, double angle); + +Text::Text(const Text& a) : Marker(a) +{ + rotate = a.rotate; +} + +Text::Text(Base* p, const Vector& ctr, + double ang, int rot, + const char* clr, int* dsh, + int wth, const char* fnt, const char* txt, + unsigned short prop, const char* cmt, + const List<Tag>& tg, const List<CallBack>& cb) + : Marker(p, ctr, ang, clr, dsh, wth, fnt, txt, prop, cmt, tg, cb) +{ + strcpy(type_,"text"); + handle = new Vector[4]; + numHandle = 4; + rotate = rot; + + updateBBox(); +} + +void Text::renderX(Drawable drawable, Coord::InternalSystem sys, RenderMode mode) +{ + if (text && *text && tkfont_) { + GC lgc = renderXGC(mode); + XSetFont(display, lgc, Tk_FontId(tkfont_)); + + // origin is center of text + Tk_FontMetrics metrics; + Tk_GetFontMetrics(tkfont_, &metrics); + int width = Tk_TextWidth(tkfont_, text, strlen(text)); + int delta = (metrics.ascent-metrics.descent)/2.; + + double ang = rotate ? calcAngle() : 0; + Vector cc = parent->mapFromRef(center,sys); + Matrix mm = Translate(-cc) * + Translate(-width/2., delta) * + Rotate(ang) * + Translate(cc); + Vector vv = cc * mm; + + TkDrawAngledChars(display, drawable, lgc, tkfont_, + text, strlen(text), + vv[0], vv[1], radToDeg(ang)); + } +} + +void Text::renderPS(int mode) +{ + renderPSGC(mode); + + if (text && *text && psfont_) { + ostringstream str; + + const char* ff = Tk_NameOfFont(psfont_); + str << '/' << psFontName(ff) + << " findfont " << int(psFontSize(ff)*parent->getDisplayRatio()) + << " scalefont setfont" << endl; + + double ang = rotate ? calcAngle() : 0; + Vector cc = (parent->mapFromRef(center,Coord::CANVAS)).TkCanvasPs(parent->canvas); + str << "gsave" << endl + << "newpath " << endl + << cc << " moveto" << endl + << '(' << psQuote(text) << ')' << endl + << "dup true charpath pathbbox " << endl + << "closepath " << endl + << "3 -1 roll sub 3.6 div neg " << endl + << "3 1 roll sub 2 div exch " << endl + << cc << " moveto " << endl + << radToDeg(ang) << " rotate " << endl + << " rmoveto show" << endl + << "grestore" << endl; + + str << ends; + Tcl_AppendResult(parent->interp, str.str().c_str(), NULL); + } +} + +#ifdef MAC_OSX_TK +void Text::renderMACOSX() +{ + renderMACOSXGC(); + + if (text && *text && psfont_) { + Tcl_DString psdstr; + Tcl_DStringInit(&psdstr); + int psSize = Tk_PostscriptFontName(psfont_, &psdstr); + macosxFont(Tcl_DStringValue(&psdstr), psSize); + Tcl_DStringFree(&psdstr); + + Tk_FontMetrics metrics; + Tk_GetFontMetrics(psfont_, &metrics); + int width = Tk_TextWidth(psfont_, text, strlen(text)); + + double ang = rotate ? calcAngle() : 0; + Vector cc = parent->mapFromRef(center,Coord::CANVAS); + Matrix mm = Translate(-cc) * + Translate(-width/2.,metrics.descent) * + Rotate(ang) * + Translate(cc); + + macosxDrawText(cc*mm, 0, text); + } +} +#endif + +#ifdef __WIN32 +void Text::renderWIN32() +{ + renderWIN32GC(); + + if (text && *text && tkfont_) { + win32Font(tkfont_); + + Tk_FontMetrics metrics; + Tk_GetFontMetrics(tkfont_, &metrics); + int width = Tk_TextWidth(tkfont_, text, strlen(text)); + int delta = (metrics.ascent-metrics.descent)/2.; + + double ang = rotate ? calcAngle() : 0; + Vector cc = parent->mapFromRef(center,Coord::CANVAS); + Matrix mm = Translate(-cc) * + Translate(-width/2., delta) * + Rotate(ang) * + Translate(cc); + Vector vv = cc * mm; + + win32DrawText(vv, 0, text); + } +} +#endif + +// Support + +void Text::updateHandles() +{ + Vector cc = parent->mapFromRef(center,Coord::CANVAS); + + if (text && *text && tkfont_) { + Tk_FontMetrics metrics; + Tk_GetFontMetrics(tkfont_, &metrics); + int width = Tk_TextWidth(tkfont_, text, strlen(text)); + + Vector s(width, metrics.linespace); + double ang = rotate ? calcAngle() : 0; + Matrix mm = Rotate(ang) * Translate(cc); + handle[0] = Vector(-s[0],-s[1])/2 * mm; + handle[1] = Vector( s[0],-s[1])/2 * mm; + handle[2] = Vector( s[0], s[1])/2 * mm; + handle[3] = Vector(-s[0], s[1])/2 * mm; + } + else { + Vector s(10,10); + Matrix mm = Translate(cc); + handle[0] = Vector(-s[0],-s[1])/2 * mm; + handle[1] = Vector( s[0],-s[1])/2 * mm; + handle[2] = Vector( s[0], s[1])/2 * mm; + handle[3] = Vector(-s[0], s[1])/2 * mm; + } +} + +void Text::calcAllBBox() +{ + allBBox = bbox; +} + +int Text::isIn(const Vector& vv) +{ + if (text && *text && tkfont_) { + // origin is center of text + Tk_FontMetrics metrics; + Tk_GetFontMetrics(tkfont_, &metrics); + float ww = Tk_TextWidth(tkfont_, text, strlen(text))/2./parent->zoom_[0]; + float hh = metrics.linespace/2./parent->zoom_[1]; + + Vector pp = bckMap(vv,Coord::CANVAS); + + if (pp[0]<-ww || pp[0]>ww || pp[1]<-hh || pp[1]>hh) + return 0; + else + return 1; + } + else + return 0; +} + +void Text::setRotate(int rot) +{ + rotate = rot ? 1 : 0; + updateBBox(); +} + +// list + +void Text::list(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, + Coord::SkyFormat format, int conj, int strip) +{ + if (!text || !*text) + return; + + if (!strip) { + FitsImage* ptr = parent->findFits(sys,center); + listPre(str, sys, sky, ptr, strip, 1); + + switch (sys) { + case Coord::IMAGE: + case Coord::PHYSICAL: + case Coord::DETECTOR: + case Coord::AMPLIFIER: + listNonCel(ptr, str, sys); + break; + default: + if (ptr->hasWCSCel(sys)) { + switch (format) { + case Coord::DEGREES: + { + Vector vv = ptr->mapFromRef(center,sys,sky); + str << type_ << '(' << setprecision(10) << vv << ')'; + } + break; + case Coord::SEXAGESIMAL: + listRADEC(ptr,center,sys,sky,format); + str << type_ << '(' << ra << ',' << dec << ')'; + break; + } + } + else + listNonCel(ptr, str, sys); + } + + if (conj) + str << " ||"; + + if (angle != 0) + str << " textangle=" << radToDeg(parent->mapAngleFromRef(angle,sys,sky)); + if (!rotate) + str << " textrotate=" << 0; + listProperties(str, 0); + } +} + +void Text::listNonCel(FitsImage* ptr, ostream& str, Coord::CoordSystem sys) +{ + Vector vv = ptr->mapFromRef(center,sys); + str << type_ << '(' << setprecision(8) << vv << ')'; +} + +void Text::listXML(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, + Coord::SkyFormat format) +{ + FitsImage* ptr = parent->findFits(sys,center); + + XMLRowInit(); + XMLRow(XMLSHAPE,type_); + + XMLRowCenter(ptr,sys,sky,format); + XMLRowAng(sys,sky); + XMLRow(XMLPARAM,rotate); + + XMLRowProps(ptr,sys); + XMLRowEnd(str); +} + +void Text::listSAOtng(ostream& str, Coord::CoordSystem sys, Coord::SkyFrame sky, + Coord::SkyFormat format, int strip) +{ + if (!text || !*text) + return; + + FitsImage* ptr = parent->findFits(); + if (properties&INCLUDE) + str << '+'; + else + str << '-'; + + switch (sys) { + case Coord::IMAGE: + case Coord::PHYSICAL: + case Coord::DETECTOR: + case Coord::AMPLIFIER: + { + Vector vv = ptr->mapFromRef(center,Coord::IMAGE); + str << type_ << '(' << setprecision(8) << vv << ", \"" << text << "\")"; + } + break; + default: + if (ptr->hasWCSCel(sys)) { + switch (format) { + case Coord::DEGREES: + { + Vector vv = ptr->mapFromRef(center,sys,sky); + str << type_ << '(' << setprecision(10) << vv + << ", \"" << text << "\")"; + } + break; + case Coord::SEXAGESIMAL: + listRADEC(ptr,center,sys,sky,format); + str << type_ << '(' << ra << ',' << dec << ", \"" << text << "\")"; + break; + } + } + } + + listSAOtngPost(str, strip); +} + + + + |