diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 18:59:29 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 18:59:29 (GMT) |
commit | d4d595fa7fb12903db9227d33d48b2b00120dbd1 (patch) | |
tree | 7d18365de0d6d1b29399b6a17c7eb01c2eb3ed49 /tksao/util | |
parent | 949f96e29bfe0bd8710d775ce220e597064e2589 (diff) | |
download | blt-d4d595fa7fb12903db9227d33d48b2b00120dbd1.zip blt-d4d595fa7fb12903db9227d33d48b2b00120dbd1.tar.gz blt-d4d595fa7fb12903db9227d33d48b2b00120dbd1.tar.bz2 |
Initial commit
Diffstat (limited to 'tksao/util')
-rw-r--r-- | tksao/util/FlexLexer.h | 208 | ||||
-rw-r--r-- | tksao/util/attribute.C | 193 | ||||
-rw-r--r-- | tksao/util/attribute.h | 62 | ||||
-rw-r--r-- | tksao/util/fdstream.hpp | 184 | ||||
-rw-r--r-- | tksao/util/fuzzy.h | 38 | ||||
-rw-r--r-- | tksao/util/grf.C | 642 | ||||
-rw-r--r-- | tksao/util/grf3d.C | 516 | ||||
-rw-r--r-- | tksao/util/grid25dbase.C | 191 | ||||
-rw-r--r-- | tksao/util/grid25dbase.h | 26 | ||||
-rw-r--r-- | tksao/util/grid2dbase.C | 175 | ||||
-rw-r--r-- | tksao/util/grid2dbase.h | 26 | ||||
-rw-r--r-- | tksao/util/grid3dbase.C | 241 | ||||
-rw-r--r-- | tksao/util/grid3dbase.h | 35 | ||||
-rw-r--r-- | tksao/util/gridbase.C | 461 | ||||
-rw-r--r-- | tksao/util/gridbase.h | 67 | ||||
-rw-r--r-- | tksao/util/ps.C | 377 | ||||
-rw-r--r-- | tksao/util/ps.h | 171 | ||||
-rw-r--r-- | tksao/util/smooth.C | 67 | ||||
-rw-r--r-- | tksao/util/smooth.h | 12 | ||||
-rw-r--r-- | tksao/util/util.C | 486 | ||||
-rw-r--r-- | tksao/util/util.h | 125 |
21 files changed, 4303 insertions, 0 deletions
diff --git a/tksao/util/FlexLexer.h b/tksao/util/FlexLexer.h new file mode 100644 index 0000000..1d783f1 --- /dev/null +++ b/tksao/util/FlexLexer.h @@ -0,0 +1,208 @@ +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include <FlexLexer.h> in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include <FlexLexer.h> +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include <FlexLexer.h> +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include <iostream> +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() const { return yytext; } + size_t YYLeng() const { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( FLEX_STD istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream* new_in = 0, + FLEX_STD ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + size_t yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif // FLEXLEXER_H + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex manual. +#define yyFlexLexerOnce + +extern "C++" { + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( FLEX_STD istream* s ); + + void yypush_buffer_state( struct yy_buffer_state* new_buffer ); + void yypop_buffer_state(); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ); + virtual int yywrap(); + + void begin(int,int); + +protected: + virtual size_t LexerInput( char* buf, size_t max_size ); + virtual void LexerOutput( const char* buf, size_t size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream* yyin; // input source for default LexerInput + FLEX_STD ostream* yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + size_t yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +} + +#endif // yyFlexLexer || ! yyFlexLexerOnce + diff --git a/tksao/util/attribute.C b/tksao/util/attribute.C new file mode 100644 index 0000000..23e49d4 --- /dev/null +++ b/tksao/util/attribute.C @@ -0,0 +1,193 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "attribute.h" +#include "util.h" +#include "widget.h" + +Attribute::Attribute(Widget* p) : parent(p) +{ + style_ = SOLID; + width_ = 1; + + font_ = 2; // helvetica normal roman + size_ = 10; + tkfont_ = NULL; + psfont_ = NULL; + initFonts(); + + colour_ = 0xffffff; // white + colorName_ = dupstr("white"); + color_ = parent->getColor("white"); +} + +Attribute::~Attribute() +{ + if (tkfont_) + Tk_FreeFont(tkfont_); + if (psfont_) + Tk_FreeFont(psfont_); + + if (colorName_) + delete [] colorName_; +} + +void Attribute::setStyle(double v) +{ + switch ((int)v) { + case SOLID: + case DASH: + break; + default: + return; + } + + style_ = (Style)((int)v); +} + +void Attribute::setWidth(double v) +{ + if (v>0) + width_ = v; + else + width_ = 1; +} + +void Attribute::setSize(double v) +{ + if (v >= 1) { +#ifdef MAC_OSX_TK + size_ = int(v*parent->getDisplayRatio()); +#else + size_ = (int)v; +#endif + initFonts(); + } +} + +void Attribute::setFont(double v) +{ + font_ = (int)v; + initFonts(); +} + +void Attribute::initFonts() +{ + if (tkfont_) + Tk_FreeFont(tkfont_); + tkfont_ = NULL; + if (psfont_) + Tk_FreeFont(psfont_); + psfont_ = NULL; + + WidgetOptions* opts = parent->options; + + ostringstream fstr; + ostringstream pstr; + switch (font_) { + case 0: + case 2: + case 3: + fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " normal roman" << ends; + pstr << "helvetica " << size_ << " normal roman" << ends; + break; + case 1: + fstr << '{' << opts->times << '}' << ' ' << size_ << " normal roman" << ends; + pstr << "times " << size_ << " normal roman" << ends; + break; + case 4: + fstr << '{' << opts->courier << '}' << ' ' << size_ << " normal roman" << ends; + pstr << "courier " << size_ << " normal roman" << ends; + break; + + case 10: + case 12: + case 13: + fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " bold roman" << ends; + pstr << "helvetica " << size_ << " bold roman" << ends; + break; + case 11: + fstr << '{' << opts->times << '}' << ' ' << size_ << " bold roman" << ends; + pstr << "times " << size_ << " bold roman" << ends; + break; + case 14: + fstr << '{' << opts->courier << '}' << ' ' << size_ << " bold roman" << ends; + pstr << "courier " << size_ << " bold roman" << ends; + break; + + case 20: + case 22: + case 23: + fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " normal italic" << ends; + pstr << "helvetica " << size_ << " normal italic" << ends; + break; + case 21: + fstr << '{' << opts->times << '}' << ' ' << size_ << " normal italic" << ends; + pstr << "times " << size_ << " normal italic" << ends; + break; + case 24: + fstr << '{' << opts->courier << '}' << ' ' << size_ << " normal italic" << ends; + pstr << "courier " << size_ << " normal italic" << ends; + break; + + case 30: + case 32: + case 33: + fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " bold italic" << ends; + pstr << "helvetica " << size_ << " bold italic" << ends; + break; + case 31: + fstr << '{' << opts->times << '}' << ' ' << size_ << " bold italic" << ends; + pstr << "times " << size_ << " bold italic" << ends; + break; + case 34: + fstr << '{' << opts->courier << '}' << ' ' << size_ << " bold italic" << ends; + pstr << "courier " << size_ << " bold italic" << ends; + break; + + default: + fstr << '{' << opts->helvetica << '}' << ' ' << size_ << " normal roman" << ends; + pstr << "helvetica " << size_ << " normal roman" << ends; + font_ = 2; + break; + } + + tkfont_ = Tk_GetFont(parent->getInterp(), parent->getTkwin(), + fstr.str().c_str()); + psfont_ = Tk_GetFont(parent->getInterp(), parent->getTkwin(), + pstr.str().c_str()); +} + +void Attribute::setColour(double v) +{ + if (v == colour_) + return; + + if (colorName_) + delete [] colorName_; + colorName_ = NULL; + + // still provide backward compatibility for old color scheme + if (v==1) + colour_ = (int)0xffffff; // white + else if (v==2) + colour_ = (int)0xff0000; // red + else if (v==3) + colour_ = (int)0x00ff00; // green + else if (v==4) + colour_ = (int)0x0000ff; // blue + else if (v==5) + colour_ = (int)0x00ffff; // cyan + else if (v==6) + colour_ = (int)0xff00ff; // magneta + else if (v==7) + colour_ = (int)0xffff00; // yellow + else + colour_ = (int)v; + + ostringstream str; + str << '#' << setw(6) << setfill('0') << hex << colour_ << ends; + colorName_ = dupstr(str.str().c_str()); + color_ = parent->getColor(str.str().c_str()); + } diff --git a/tksao/util/attribute.h b/tksao/util/attribute.h new file mode 100644 index 0000000..e32efde --- /dev/null +++ b/tksao/util/attribute.h @@ -0,0 +1,62 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __attribute_h__ +#define __attribute_h__ + +#include <tk.h> + +#include "vector.h" + +class Widget; + +class Attribute { + public: + enum Style {SOLID,DASH}; + enum Colour {BLACK,WHITE,RED,GREEN,BLUE,CYAN,MAGENTA,YELLOW}; + + private: + Widget* parent; + + Style style_; + float width_; + + int font_; + int size_; + Tk_Font tkfont_; + Tk_Font psfont_; + + unsigned long colour_; + char* colorName_; + unsigned long color_; + + private: + void initFonts(); + + public: + Attribute(Widget*); + ~Attribute(); + + void setStyle(double); + void setWidth(double); + + void setSize(double); + void setFont(double); + + void setColour(double); + + Style style() {return style_;} + float width() {return width_;} + + int size() {return size_;} + int font() {return font_;} + Tk_Font tkfont() {return tkfont_;} + Tk_Font psfont() {return psfont_;} + + unsigned long colour() {return colour_;} + char* colorName() {return colorName_;} + unsigned long color() {return color_;} +}; + +#endif diff --git a/tksao/util/fdstream.hpp b/tksao/util/fdstream.hpp new file mode 100644 index 0000000..585e03d --- /dev/null +++ b/tksao/util/fdstream.hpp @@ -0,0 +1,184 @@ +/* The following code declares classes to read from and write to + * file descriptore or file handles. + * + * See + * http://www.josuttis.com/cppcode + * for details and the latest version. + * + * - open: + * - integrating BUFSIZ on some systems? + * - optimized reading of multiple characters + * - stream for reading AND writing + * - i18n + * + * (C) Copyright Nicolai M. Josuttis 2001. + * Permission to copy, use, modify, sell and distribute this software + * is granted provided this copyright notice appears in all copies. + * This software is provided "as is" without express or implied + * warranty, and with no claim as to its suitability for any purpose. + * + * Version: Jul 28, 2002 + * History: + * Jul 28, 2002: bugfix memcpy() => memmove() + * fdinbuf::underflow(): cast for return statements + * Aug 05, 2001: first public version + */ +#ifndef BOOST_FDSTREAM_HPP +#define BOOST_FDSTREAM_HPP + +#include <istream> +#include <ostream> +#include <streambuf> +// for EOF: +#include <cstdio> +// for memmove(): +#include <cstring> + + +// low-level read and write functions +#ifdef _MSC_VER +# include <io.h> +#else +# include <unistd.h> +//extern "C" { +// int write (int fd, const char* buf, int num); +// int read (int fd, char* buf, int num); +//} +#endif + + +// BEGIN namespace BOOST +namespace boost { + + +/************************************************************ + * fdostream + * - a stream that writes on a file descriptor + ************************************************************/ + + +class fdoutbuf : public std::streambuf { + protected: + int fd; // file descriptor + public: + // constructor + fdoutbuf (int _fd) : fd(_fd) { + } + protected: + // write one character + virtual int_type overflow (int_type c) { + if (c != EOF) { + char z = c; + if (write (fd, &z, 1) != 1) { + return EOF; + } + } + return c; + } + // write multiple characters + virtual + std::streamsize xsputn (const char* s, + std::streamsize num) { + return write(fd,s,num); + } +}; + +class fdostream : public std::ostream { + protected: + fdoutbuf buf; + public: + fdostream (int fd) : std::ostream(0), buf(fd) { + rdbuf(&buf); + } +}; + + +/************************************************************ + * fdistream + * - a stream that reads on a file descriptor + ************************************************************/ + +class fdinbuf : public std::streambuf { + protected: + int fd; // file descriptor + protected: + /* data buffer: + * - at most, pbSize characters in putback area plus + * - at most, bufSize characters in ordinary read buffer + */ + static const int pbSize = 4; // size of putback area + static const int bufSize = 1024; // size of the data buffer + char buffer[bufSize+pbSize]; // data buffer + + public: + /* constructor + * - initialize file descriptor + * - initialize empty data buffer + * - no putback area + * => force underflow() + */ + fdinbuf (int _fd) : fd(_fd) { + setg (buffer+pbSize, // beginning of putback area + buffer+pbSize, // read position + buffer+pbSize); // end position + } + + protected: + // insert new characters into the buffer + virtual int_type underflow () { +#ifndef _MSC_VER + using std::memmove; +#endif + + // is read position before end of buffer? + if (gptr() < egptr()) { + return traits_type::to_int_type(*gptr()); + } + + /* process size of putback area + * - use number of characters read + * - but at most size of putback area + */ + int numPutback; + numPutback = gptr() - eback(); + if (numPutback > pbSize) { + numPutback = pbSize; + } + + /* copy up to pbSize characters previously read into + * the putback area + */ + memmove (buffer+(pbSize-numPutback), gptr()-numPutback, + numPutback); + + // read at most bufSize new characters + int num; + num = read (fd, buffer+pbSize, bufSize); + if (num <= 0) { + // ERROR or EOF + return EOF; + } + + // reset buffer pointers + setg (buffer+(pbSize-numPutback), // beginning of putback area + buffer+pbSize, // read position + buffer+pbSize+num); // end of buffer + + // return next character + return traits_type::to_int_type(*gptr()); + } +}; + +class fdistream : public std::istream { + protected: + fdinbuf buf; + public: + fdistream (int fd) : std::istream(0), buf(fd) { + rdbuf(&buf); + } +}; + + +} // END namespace boost + +#endif /*BOOST_FDSTREAM_HPP*/ diff --git a/tksao/util/fuzzy.h b/tksao/util/fuzzy.h new file mode 100644 index 0000000..512e079 --- /dev/null +++ b/tksao/util/fuzzy.h @@ -0,0 +1,38 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __fuzzy_h__ +#define __fuzzy_h__ + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <float.h> + +inline void tzero(double* ff, const double epsilon= DBL_EPSILON) +{if (*ff>=-epsilon && *ff<=epsilon) *ff = 0;} + +inline bool teq(const double f1, const double f2, + const double epsilon= DBL_EPSILON) +{return f1-f2 >= -epsilon && f1-f2 <= epsilon;} + +inline bool tlt(const double f1, const double f2, + const double epsilon= DBL_EPSILON) +{return f1-f2 < -epsilon;} + +inline bool tle(const double f1, const double f2, + const double epsilon= DBL_EPSILON) +{return f1-f2 <= -epsilon; } + +inline bool tgt(const double f1, const double f2, + const double epsilon= DBL_EPSILON) +{return f1-f2 > epsilon;} + +inline bool tge(const double f1, const double f2, + const double epsilon= DBL_EPSILON) +{return f1-f2 >= epsilon;} + +#endif diff --git a/tksao/util/grf.C b/tksao/util/grf.C new file mode 100644 index 0000000..f4f98d7 --- /dev/null +++ b/tksao/util/grf.C @@ -0,0 +1,642 @@ +extern "C" { +#include "grf.h" +} + +#include "grid2dbase.h" +#include "grid25dbase.h" + +extern Grid2dBase* astGrid2dPtr; +extern Grid25dBase* astGrid25dPtr; + +/* + * Name: + * astGFlush + * + * Purpose: + * Flush all pending graphics to the output device + * + * Synopsis: + * #include "grf.h" + * int astGFlush( void ) + * + * Description: + * This function ensures that the display device is up-to-date, + * by flushing any pending graphics to the output device. + * + * Parameters: + * None + * + * Returned Value: + * A value of 0 is returned if an error occurrs, and 1 is returned + * otherwise + */ + +int astGFlush(void) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gFlush(); + else if (astGrid25dPtr) + return astGrid25dPtr->gFlush(); + return 0; +} + +/* + * Name: + * astGLine + * + * Purpose: + * Draw a polyline (i.e. a set of connected lines) + * + * Synopsis: + * #include "grf.h" + * int astGLine( int n, const float *x, const float *y ) + * + * Description: + * This function displays lines joining the given positions + * + * Parameters: + * n + * The number of positions to be joined together + * x + * A pointer to an array holding the "n" x values + * y + * A pointer to an array holding the "n" y values + * + * Returned Value: + * A value of 0 is returned if an error occurrs, and 1 is returned + * otherwise + * + * Notes: + * - Nothing is done if "n" is less than 2, or if a NULL pointer is + * given for either "x" or "y" + */ + +int astGLine(int n, const float *x, const float *y) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gLine(n, (float*)x, (float*)y); + else if (astGrid25dPtr) + return astGrid25dPtr->gLine(n, (float*)x, (float*)y); + return 0; +} + +/* + * Name: + * astGQch + * + * Purpose: + * Return the character height in world cooridnates + * + * Synopsis: + * #include "grf.h" + * int astGQch( float *chv, float *chh ) + * + * Description: + * This function returns the heights of characters drawn vertically and + * horizontally in world coordinates + * + * Parameters: + * chv + * A pointer to the double which is to receive the height of + * characters drawn vertically. This will be an increment in the X + * axis + * chh + * A pointer to the double which is to receive the height of + * characters drawn vertically. This will be an increment in the Y + * axis + * + * Returned Value: + * A value of 0 is returned if an error occurrs, and 1 is returned + * otherwise + */ + +int astGQch(float *chv, float *chh) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gQch(chv, chh); + else if (astGrid25dPtr) + return astGrid25dPtr->gQch(chv, chh); + return 0; +} + +/* + * Name: + * astGMark + * + * Purpose: + * Draw a set of markers + * + * Synopsis: + * #include "grf.h" + * int astGMark( int n, const float *x, const float *y, int type ) + * + * Description: + * This function displays markers at the given positions + * + * Parameters: + * n + * The number of markers to draw + * x + * A pointer to an array holding the "n" x values + * y + * A pointer to an array holding the "n" y values + * type + * An integer which can be used to indicate the type of marker symbol + * required + * + * Returned Value: + * A value of 0 is returned if an error occurrs, and 1 is returned + * otherwise + * + * Notes: + * - Nothing is done if "n" is less than 1, or if a NULL pointer is + * given for either "x" or "y" + * + */ + +int astGMark(int n, const float *x, const float *y, int type) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gMark(n, x, y, type); + else if (astGrid25dPtr) + return astGrid25dPtr->gMark(n, x, y, type); + return 0; +} + +/* + * Name: + * astGText + * + * Purpose: + * Draw a character string + * + * Synopsis: + * #include "grf.h" + * int astGText( const char *text, float x, float y, const char *just, + * float upx, float upy ) + * + * Description: + * This function displays a character string at a given position + * using a specified justification and up-vector + * + * Parameters: + * text + * Pointer to a null-terminated character string to be displayed + * x + * The reference x coordinate + * y + * The reference y coordinate + * just + * A character string which specifies the location within the + * text string which is to be placed at the reference position + * given by x and y. The first character may be 'T' for "top", + * 'C' for "centre", or 'B' for "bottom", and specifies the + * vertical location of the reference position. Note, "bottom" + * corresponds to the base-line of normal text. Some characters + * (eg "y", "g", "p", etc) descend below the base-line. The second + * character may be 'L' for "left", 'C' for "centre", or 'R' + * for "right", and specifies the horizontal location of the + * reference position. If the string has less than 2 characters + * then 'C' is used for the missing characters + * upx + * The x component of the up-vector for the text, in graphics world + * coordinates. If necessary the supplied value should be negated + * to ensure that positive values always refer to displacements from + * left to right on the screen + * upy + * The y component of the up-vector for the text, in graphics world + * coordinates. If necessary the supplied value should be negated + * to ensure that positive values always refer to displacements from + * bottom to top on the screen + * + * Returned Value: + * A value of 0 is returned if an error occurrs, and 1 is returned + * otherwise + * + * Notes: + * - Any graphics within the rotated box enclosing the text are erased + * - A NULL value for "just" causes a value of "CC" to be used + * - Both "upx" and "upy" being zero causes an error + * - Any unrecognised character in "just" causes an error + */ + +int astGText(const char *text, float x, float y, const char *just, + float upx, float upy) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gText(text, x ,y, just, upx, upy); + else if (astGrid25dPtr) + return astGrid25dPtr->gText(text, x ,y, just, upx, upy); + return 0; +} + +/* +* Name: +* astGTxExt +* +* Purpose: +* Get the extent of a character string +* +* Synopsis: +* #include "grf.h" +* int astGTxExt( const char *text, float x, float y, const char *just, +* float upx, float upy, float *xb, float *yb ) +* +* Description: +* This function returns the corners of a box which would enclose the +* supplied character string if it were displayed using astGText +* +* The returned box INCLUDES any leading or trailing spaces +* +* Parameters: +* text +* Pointer to a null-terminated character string to be displayed +* x +* The reference x coordinate +* y +* The reference y coordinate +* just +* A character string which specifies the location within the +* text string which is to be placed at the reference position +* given by x and y. The first character may be 'T' for "top", +* 'C' for "centre", or 'B' for "bottom", and specifies the +* vertical location of the reference position. Note, "bottom" +* corresponds to the base-line of normal text. Some characters +* (eg "y", "g", "p", etc) descend below the base-line. The second +* character may be 'L' for "left", 'C' for "centre", or 'R' +* for "right", and specifies the horizontal location of the +* reference position. If the string has less than 2 characters +* then 'C' is used for the missing characters +* upx +* The x component of the up-vector for the text, in graphics world +* coordinates. If necessary the supplied value should be negated +* to ensure that positive values always refer to displacements from +* left to right on the screen +* upy +* The y component of the up-vector for the text, in graphics world +* coordinates. If necessary the supplied value should be negated +* to ensure that positive values always refer to displacements from +* bottom to top on the screen +* xb +* An array of 4 elements in which to return the x coordinate of +* each corner of the bounding box +* yb +* An array of 4 elements in which to return the y coordinate of +* each corner of the bounding box +* +* Returned Value: +* A value of 0 is returned if an error occurrs, and 1 is returned +* otherwise +* +* Notes: +* - The order of the corners is anti-clockwise (in world coordinates) +* starting at the bottom left +* - A NULL value for "just" causes a value of "CC" to be used +* - Both "upx" and "upy" being zero causes an error +* - Any unrecognised character in "just" causes an error +* - Zero is returned for all bounds of the box if an error occurs +*/ + +int astGTxExt(const char *text, float x, float y, const char *just, + float upx, float upy, float *xb, float *yb) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gTxExt(text, x, y, just, upx, upy, xb, yb); + else if (astGrid25dPtr) + return astGrid25dPtr->gTxExt(text, x, y, just, upx, upy, xb, yb); + return 0; +} + +/* + * Name: + * astGAttr + * + * Purpose: + * Enquire or set a graphics attribute value + * + * Synopsis: + * #include "grf.h" + * int int astGAttr( int attr, double value, double *old_value, int prim ) + * + * Description: + * This function returns the current value of a specified graphics + * attribute, and optionally establishes a new value. The supplied + * value is converted to an integer value if necessary before use + * + * Parameters: + * attr + * An integer value identifying the required attribute. The + * following symbolic values are defined in grf.h: + * + * GRF__STYLE - Line style + * GRF__WIDTH - Line width + * GRF__SIZE - Character and marker size scale factor + * GRF__FONT - Character font + * GRF__COLOUR - Colour index + * value + * A new value to store for the attribute. If this is AST__BAD + * no value is stored + * old_value + * A pointer to a double in which to return the attribute value + * If this is NULL, no value is returned + * prim + * The sort of graphics primative to be drawn with the new attribute + * Identified by the following values defined in grf.h: + * GRF__LINE + * GRF__MARK + * GRF__TEXT + * + * Returned Value: + * A value of 0 is returned if an error occurrs, and 1 is returned + * otherwise + * + * Notes: + */ + +int astGAttr(int attr, double value, double *old, int prim) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gAttr(attr, value, old, prim); + else if (astGrid25dPtr) + return astGrid25dPtr->gAttr(attr, value, old, prim); + return 0; +} + +/* +* Name: +* astGScales +* +* Purpose: +* Get the axis scales. +* +* Synopsis: +* #include "grf.h" +* int astGScales( float *alpha, float *beta ) +* +* Description: +* This function returns two values (one for each axis) which scale +* increments on the corresponding axis into a "normal" coordinate +* system in which: +* 1 - The axes have equal scale in terms of (for instance) +* millimetres per unit distance. +* 2 - X values increase from left to right. +* 3 - Y values increase from bottom to top. +* +* Parameters: +* alpha +* A pointer to the location at which to return the scale for the +* X axis (i.e. Xnorm = alpha*Xworld). +* beta +* A pointer to the location at which to return the scale for the +* Y axis (i.e. Ynorm = beta*Yworld). +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +*/ + +int astGScales(float *alpha, float *beta) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gScales(alpha,beta); + else if (astGrid25dPtr) + return astGrid25dPtr->gScales(alpha,beta); + return 0; +} + +/* +* Name: +* astGCap +* +* Purpose: +* Indicate if this grf module has a given capability. +* +* Synopsis: +* #include "grf.h" +* int astGCap( int cap, int value ) +* +* Description: +* This function is called by the AST Plot class to determine if the +* grf module has a given capability, as indicated by the "cap" +* argument. +* +* Parameters: +* cap +* The capability being inquired about. This will be one of the +* following constants defined in grf.h: +* +* GRF__SCALES: This function should return a non-zero value if +* it implements the astGScales function, and zero otherwise. The +* supplied "value" argument should be ignored. +* +* GRF__MJUST: This function should return a non-zero value if +* the astGText and astGTxExt functions recognise "M" as a +* character in the justification string. If the first character of +* a justification string is "M", then the text should be justified +* with the given reference point at the bottom of the bounding box. +* This is different to "B" justification, which requests that the +* reference point be put on the baseline of the text, since some +* characters hang down below the baseline. If the astGText or +* astGTxExt function cannot differentiate between "M" and "B", +* then this function should return zero, in which case "M" +* justification will never be requested by Plot. The supplied +* "value" argument should be ignored. +* +* GRF__ESC: This function should return a non-zero value if the +* astGText and astGTxExt functions can recognise and interpret +* graphics escape sequences within the supplied string. These +* escape sequences are described below. Zero should be returned +* if escape sequences cannot be interpreted (in which case the +* Plot class will interpret them itself if needed). The supplied +* "value" argument should be ignored only if escape sequences cannot +* be interpreted by astGText and astGTxExt. Otherwise, "value" +* indicates whether astGText and astGTxExt should interpret escape +* sequences in subsequent calls. If "value" is non-zero then +* escape sequences should be interpreted by astGText and +* astGTxExt. Otherwise, they should be drawn as literal text. +* +* Returned Value: +* The return value, as described above. Zero should be returned if +* the supplied capability is not recognised. +* +* Escape Sequences: +* Escape sequences are introduced into the text string by a percent +* "%" character. The following escape sequences are currently recognised +* ("..." represents a string of one or more decimal digits): +* +* %% - Print a literal "%" character (type GRF__ESPER ). +* +* %^...+ - Draw subsequent characters as super-scripts. The digits +* "..." give the distance from the base-line of "normal" +* text to the base-line of the super-script text, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF__ESSUP ). +* %^+ - Draw subsequent characters with the normal base-line. +* +* %v...+ - Draw subsequent characters as sub-scripts. The digits +* "..." give the distance from the base-line of "normal" +* text to the base-line of the sub-script text, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF__ESSUB ). +* +* %v+ - Draw subsequent characters with the normal base-line +* (equivalent to %^+). +* +* %>...+ - Leave a gap before drawing subsequent characters. +* The digits "..." give the size of the gap, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF__ESGAP ). +* +* %<...+ - Move backwards before drawing subsequent characters. +* The digits "..." give the size of the movement, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF_ESBAC). +* +* %s...+ - Change the Size attribute for subsequent characters. The +* digits "..." give the new Size as a fraction of the +* "normal" Size, scaled so that a value of "100" corresponds +* to 1.0 (type GRF__ESSIZ ). +* +* %s+ - Reset the Size attribute to its "normal" value. +* +* %w...+ - Change the Width attribute for subsequent characters. The +* digits "..." give the new width as a fraction of the +* "normal" Width, scaled so that a value of "100" corresponds +* to 1.0 (type GRF__ESWID ). +* +* %w+ - Reset the Size attribute to its "normal" value. +* +* %f...+ - Change the Font attribute for subsequent characters. The +* digits "..." give the new Font value (type GRF__ESFON ). +* +* %f+ - Reset the Font attribute to its "normal" value. +* +* %c...+ - Change the Colour attribute for subsequent characters. The +* digits "..." give the new Colour value (type GRF__ESCOL ). +* +* %c+ - Reset the Colour attribute to its "normal" value. +* +* %t...+ - Change the Style attribute for subsequent characters. The +* digits "..." give the new Style value (type GRF__ESSTY ). +* +* %t+ - Reset the Style attribute to its "normal" value. +* +* %- - Push the current graphics attribute values onto the top of +* the stack - see "%+" (type GRF__ESPSH). +* +* %+ - Pop attributes values of the top the stack - see "%-". If +* the stack is empty, "normal" attribute values are restored +* (type GRF__ESPOP). +* +* The astFindEscape function (in libast.a) can be used to locate escape +* sequences within a text string. It has the following signature: +* +* #include "plot.h" +* int astFindEscape( const char *text, int *type, int *value, int *nc ) +* +* Parameters: +* text +* Pointer to the string to be checked. +* type +* Pointer to a location at which to return the type of escape +* sequence. Each type is identified by a symbolic constant defined +* in grf.h and is indicated in the above section. The returned value +* is undefined if the supplied text does not begin with an escape +* sequence. +* value +* Pointer to a lcation at which to return the integer value +* associated with the escape sequence. All usable values will be +* positive. Zero is returned if the escape sequence has no associated +* integer. A value of -1 indicates that the attribute identified by +* "type" should be reset to its "normal" value (as established using +* the astGAttr function, etc). The returned value is undefined if +* the supplied text does not begin with an escape sequence. +* nc +* Pointer to a location at which to return the number of +* characters read by this call. If the text starts with an escape +* sequence, the returned value will be the number of characters in +* the escape sequence. Otherwise, the returned value will be the +* number of characters prior to the first escape sequence, or the +* length of the supplied text if no escape sequence is found. +* +* Returned Value: +* A non-zero value is returned if the supplied text starts with a +* graphics escape sequence, and zero is returned otherwise. +*/ + +int astGCap(int cap, int value) +{ + if (astGrid2dPtr) + return astGrid2dPtr->gCap(cap,value); + else if (astGrid25dPtr) + return astGrid25dPtr->gCap(cap,value); + return 0; +} + +/* +* Name: +* astGBBuf +* +* Purpose: +* Start a new graphics buffering context. +* +* Synopsis: +* #include "grf.h" +* int astGBBuf( void ) +* +* Description: +* This function begins saving graphical output commands in an +* internal buffer; the commands are held until a matching astGEBuf +* call (or until the buffer is emptied by astGFlush). This can +* greatly improve the efficiency of some graphics systems. astGBBuf +* increments an internal counter, while astGEBuf decrements this +* counter and flushes the buffer to the output device when the +* counter drops to zero. astGBBuf and astGEBuf calls should always +* be paired. +* +* Parameters: +* None. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +*/ + +int astGBBuf(void) +{ + return 1; +} + +/* +* Name: +* astGEBuf +* +* Purpose: +* End a graphics buffering context. +* +* Synopsis: +* #include "grf.h" +* int astGEBuf( void ) +* +* Description: +* This function marks the end of a batch of graphical output begun +* with the last call of astGBBuf. astGBBuf and astGEBUF calls should +* always be paired. Each call to astGBBuf increments a counter, while +* each call to astGEBuf decrements the counter. When the counter +* reaches 0, the batch of output is written on the output device. +* +* Parameters: +* None. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +*/ + +int astGEBuf(void) +{ + return 1; +} + diff --git a/tksao/util/grf3d.C b/tksao/util/grf3d.C new file mode 100644 index 0000000..c6381a7 --- /dev/null +++ b/tksao/util/grf3d.C @@ -0,0 +1,516 @@ +extern "C" { +#include "grf3d.h" +} + +#include "grid3dbase.h" + +extern Grid3dBase* astGrid3dPtr; + +/* +* Name: +* astG3DCap +* +* Purpose: +* Indicate if this grf3d module has a given capability. +* +* Synopsis: +* #include "grf3d.h" +* int astG3DCap( int cap, int value ) +* +* Description: +* This function is called by the AST Plot class to determine if the +* grf3d module has a given capability, as indicated by the "cap" +* argument. +* +* Parameters: +* cap +* The capability being inquired about. This will be one of the +* following constants defined in grf3d.h: +* +* GRF3D__ESC: This function should return a non-zero value if the +* astG3DText and astG3DTxExt functions can recognise and interpret +* graphics escape sequences within the supplied string. These +* escape sequences are described below. Zero should be returned +* if escape sequences cannot be interpreted (in which case the +* Plot class will interpret them itself if needed). The supplied +* "value" argument should be ignored only if escape sequences cannot +* be interpreted by astG3DText and astG3DTxExt. Otherwise, "value" +* indicates whether astG3DText and astG3DTxExt should interpret escape +* sequences in subsequent calls. If "value" is non-zero then +* escape sequences should be interpreted by astG3DText and +* astG3DTxExt. Otherwise, they should be drawn as literal text. +* +* Returned Value: +* The return value, as described above. Zero should be returned if +* the supplied capability is not recognised. +* +* Escape Sequences: +* Escape sequences are introduced into the text string by a percent +* "%" character. The following escape sequences are currently recognised +* ("..." represents a string of one or more decimal digits): +* +* %% - Print a literal "%" character (type GRF__ESPER ). +* +* %^...+ - Draw subsequent characters as super-scripts. The digits +* "..." give the distance from the base-line of "normal" +* text to the base-line of the super-script text, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF__ESSUP ). +* %^+ - Draw subsequent characters with the normal base-line. +* +* %v...+ - Draw subsequent characters as sub-scripts. The digits +* "..." give the distance from the base-line of "normal" +* text to the base-line of the sub-script text, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF__ESSUB ). +* +* %v+ - Draw subsequent characters with the normal base-line +* (equivalent to %^+). +* +* %>...+ - Leave a gap before drawing subsequent characters. +* The digits "..." give the size of the gap, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF__ESGAP ). +* +* %<...+ - Move backwards before drawing subsequent characters. +* The digits "..." give the size of the movement, scaled +* so that a value of "100" corresponds to the height of +* "normal" text (type GRF_ESBAC). +* +* %s...+ - Change the Size attribute for subsequent characters. The +* digits "..." give the new Size as a fraction of the +* "normal" Size, scaled so that a value of "100" corresponds +* to 1.0 (type GRF__ESSIZ ). +* +* %s+ - Reset the Size attribute to its "normal" value. +* +* %w...+ - Change the Width attribute for subsequent characters. The +* digits "..." give the new width as a fraction of the +* "normal" Width, scaled so that a value of "100" corresponds +* to 1.0 (type GRF__ESWID ). +* +* %w+ - Reset the Size attribute to its "normal" value. +* +* %f...+ - Change the Font attribute for subsequent characters. The +* digits "..." give the new Font value (type GRF__ESFON ). +* +* %f+ - Reset the Font attribute to its "normal" value. +* +* %c...+ - Change the Colour attribute for subsequent characters. The +* digits "..." give the new Colour value (type GRF__ESCOL ). +* +* %c+ - Reset the Colour attribute to its "normal" value. +* +* %t...+ - Change the Style attribute for subsequent characters. The +* digits "..." give the new Style value (type GRF__ESSTY ). +* +* %t+ - Reset the Style attribute to its "normal" value. +* +* %- - Push the current graphics attribute values onto the top of +* the stack - see "%+" (type GRF__ESPSH). +* +* %+ - Pop attributes values of the top the stack - see "%-". If +* the stack is empty, "normal" attribute values are restored +* (type GRF__ESPOP). +* +* The astFindEscape function (in libast.a) can be used to locate escape +* sequences within a text string. It has the following signature: +* +* #include "plot.h" +* int astFindEscape( const char *text, int *type, int *value, int *nc ) +* +* Parameters: +* text +* Pointer to the string to be checked. +* type +* Pointer to a location at which to return the type of escape +* sequence. Each type is identified by a symbolic constant defined +* in grf.h and is indicated in the above section. The returned value +* is undefined if the supplied text does not begin with an escape +* sequence. +* value +* Pointer to a lcation at which to return the integer value +* associated with the escape sequence. All usable values will be +* positive. Zero is returned if the escape sequence has no associated +* integer. A value of -1 indicates that the attribute identified by +* "type" should be reset to its "normal" value (as established using +* the astG3DAttr function, etc). The returned value is undefined if +* the supplied text does not begin with an escape sequence. +* nc +* Pointer to a location at which to return the number of +* characters read by this call. If the text starts with an escape +* sequence, the returned value will be the number of characters in +* the escape sequence. Otherwise, the returned value will be the +* number of characters prior to the first escape sequence, or the +* length of the supplied text if no escape sequence is found. +* +* Returned Value: +* A non-zero value is returned if the supplied text starts with a +* graphics escape sequence, and zero is returned otherwise. +* +*/ + +int astG3DCap(int cap, int value) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gCap(cap, value); + return 0; +} + +/* +* Name: +* astG3DFlush +* +* Purpose: +* Flush all pending graphics to the output device. +* +* Synopsis: +* #include "grf3d.h" +* int astG3DFlush( void ) +* +* Description: +* This function ensures that the display device is up-to-date, +* by flushing any pending graphics to the output device. +* +* Parameters: +* None. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +*/ + +int astG3DFlush(void) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gFlush(); + return 0; +} + +/* +* Name: +* astG3DLine +* +* Purpose: +* Draw a polyline (i.e. a set of connected lines). +* +* Synopsis: +* #include "grf3d.h" +* int astG3DLine( int n, float *x, float *y, float *z ) +* +* Description: +* This function displays lines joining the given positions. +* +* Parameters: +* n +* The number of positions to be joined together. +* x +* A pointer to an array holding the "n" x values. +* y +* A pointer to an array holding the "n" y values. +* z +* A pointer to an array holding the "n" z values. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +* Notes: +* - A camera must have been established prior to calling this +* function using either astG3DSetCamera or astG3DAutoCamera. +* - Nothing is done if "n" is less than 2, or if a NULL pointer is +* given for either "x", "y" or "z". +* +*/ + +int astG3DLine(int n, float *x, float *y, float *z) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gLine(n, x, y, z); + return 0; +} + +/* +* Name: +* astG3DQch +* +* Purpose: +* Return the character height in world coordinates. +* +* Synopsis: +* #include "grf3d.h" +* int astG3DQch( float *ch ) +* +* Description: +* This function returns the height of characters drawn using astG3DText. +* +* Parameters: +* ch +* A pointer to the double which is to receive the height of +* characters drawn with astG3DText. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +* Notes: +* - Since the 3D world coordinate axes are assumed to be equally +* scaled, the height of text in world coordinate units is independent +* of the orientation of the text. Therefore, this function returns +* only one height value, unlike the equivalent 2D astGQch function +* that returns two heights. +*/ + +int astG3DQch(float *ch) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gQch(ch); + return 0; +} + +/* +* Name: +* astG3DMark +* +* Purpose: +* Draw a set of markers. +* +* Synopsis: +* #include "grf.h" +* int astG3DMark( int n, float *x, float *y, float *z, int type, +* float norm[3] ) +* +* Description: +* This function draws markers centred at the given positions, on a +* plane with a specified normal vector. +* +* Parameters: +* n +* The number of markers to draw. +* x +* A pointer to an array holding the "n" x values. +* y +* A pointer to an array holding the "n" y values. +* z +* A pointer to an array holding the "n" z values. +* type +* An integer which can be used to indicate the type of marker symbol +* required. See the description of routine PGPT in the PGPLOT manual. +* norm +* The (x,y,z) components of a vector that is normal to the plane +* containing the marker. The given vector passes through the marker +* from the back to the front. If all components of this vector are +* zero, then a normal vector pointing from the position of the +* first marker towards the camera eye is used. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +* Notes: +* - Nothing is done if "n" is less than 1, or if a NULL pointer is +* given for "x", "y" or "z". +* +*/ + +int astG3DMark(int n, float *x, float *y, float *z, int type, float norm[3]) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gMark(n, x, y, z, type, norm); + return 0; +} + +/* +* Name: +* astG3DText +* +* Purpose: +* Draw a character string. +* +* Synopsis: +* #include "grf3d.h" +* int astG3DText( const char *text, float ref[3], const char *just, +* float up[3], float norm[3] ) +* +* Description: +* This function displays a character string at a given position +* on a given plane in 3D world coords, using a specified +* justification and up-vector. +* +* Parameters: +* text +* Pointer to a null-terminated character string to be displayed. +* ref +* The reference (x,y,z) coordinates. +* just +* A character string which specifies the location within the +* text string which is to be placed at the reference position +* given by x and y. The first character may be 'T' for "top", +* 'C' for "centre", or 'B' for "bottom", and specifies the +* vertical location of the reference position. Note, "bottom" +* corresponds to the base-line of normal text. Some characters +* (eg "y", "g", "p", etc) descend below the base-line. The second +* character may be 'L' for "left", 'C' for "centre", or 'R' +* for "right", and specifies the horizontal location of the +* reference position. If the string has less than 2 characters +* then 'C' is used for the missing characters. +* up +* The (x,y,z) up-vector for the text. The actual up vector used is +* the projection of the supplied vector onto the plane specified by +* "norm". +* norm +* The (x,y,z) components of a vector that is normal to the plane +* containing the text. The given vector passes through the text +* from the back to the front. If all components of this vector are +* zero, then a normal vector pointing towards the camera eye is used. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +* Notes: +* - This routine does not recognise PGPLOT escape sequences. +* - A NULL value for "just" causes a value of "CC" to be used. +*/ + +int astG3DText(const char *text, float ref[3], const char *just, + float up[3], float norm[3] ) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gText(text, ref, just, up, norm); + return 0; +} + +/* +* Name: +* astG3DTxExt +* +* Purpose: +* Get the extent of a character string. +* +* Synopsis: +* #include "grf3d.h" +* int astG3DTxExt( const char *text, float ref[3], const char *just, +* float up[3], float norm[3], float *xb, float *yb, +* float *zb, float bl[3] ) +* +* Description: +* This function returns the corners of a box which would enclose the +* supplied character string if it were displayed using astG3DText. +* +* The returned box INCLUDES any leading or trailing spaces. +* +* Parameters: +* text +* Pointer to a null-terminated character string to be displayed. +* ref +* The reference (x,y,z) coordinates. +* just +* A character string which specifies the location within the +* text string which is to be placed at the reference position +* given by x and y. The first character may be 'T' for "top", +* 'C' for "centre", 'B' for "baseline", or "M" for "bottom", and +* specifies the vertical location of the reference position. Note, +* "baseline" corresponds to the base-line of normal text. Some +* characters (eg "y", "g", "p", etc) descend below the base-line, +* and so "M" and "B" will produce different effects for such +* characters. The second character may be 'L' for "left", 'C' for +* "centre", or 'R' for "right", and specifies the horizontal +* location of the reference position. If the string has less than +* 2 characters then 'C' is used for the missing characters. +* up +* The (x,y,z) up-vector for the text. The actual up vector used is +* the projection of the supplied vector onto the plane specified by +* "norm". +* norm +* The (x,y,z) components of a vector that is normal to the plane +* containing the text. The given vector passes through the text +* from the back to the front. If all components of this vector are +* zero, then a normal vector pointing towards the camera eye is used. +* xb +* An array of 4 elements in which to return the x coordinate of +* each corner of the bounding box. +* yb +* An array of 4 elements in which to return the y coordinate of +* each corner of the bounding box. +* zb +* An array of 4 elements in which to return the z coordinate of +* each corner of the bounding box. +* bl +* The 3D world coordinates at the left hand end of the text +* baseline. +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +* Notes: +* - The order of the corners is anti-clockwise starting at the +* bottom left when viewing the text normally (i.e. face on). +* - This routine does not recognise PGPLOT escape sequences. +* - A NULL value for "just" causes a value of "CC" to be used. +*/ + +int astG3DTxExt(const char *text, float ref[3], const char *just, + float up[3], float norm[3], float *xb, float *yb, + float *zb, float bl[3]) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gTxExt(text, ref, just, up, norm, xb, yb, zb, bl); + return 0; +} + +/* +* Name: +* astG3DAttr +* +* Purpose: +* Enquire or set a 3D graphics attribute value. +* +* Synopsis: +* #include "grf3d.h" +* int int astG3DAttr( int attr, double value, double *old_value, int prim ) +* +* Description: +* This function returns the current value of a specified 3D graphics +* attribute, and optionally establishes a new value. The supplied +* value is converted to an integer value if necessary before use. +* +* Parameters: +* attr +* An integer value identifying the required attribute. The +* following symbolic values are defined in grf3d.h: +* +* GRF__STYLE - Line style. +* GRF__WIDTH - Line width. +* GRF__SIZE - Character and marker size scale factor. +* GRF__FONT - Character font. +* GRF__COLOUR - Colour index. +* value +* A new value to store for the attribute. If this is AST__BAD +* no value is stored. +* old_value +* A pointer to a double in which to return the attribute value. +* If this is NULL, no value is returned. +* prim +* The sort of graphics primitive to be drawn with the new attribute. +* Identified by the following values defined in grf.h: +* GRF__LINE +* GRF__MARK +* GRF__TEXT +* +* Returned Value: +* A value of 0 is returned if an error occurs, and 1 is returned +* otherwise. +* +* Notes: +* +*/ + +int astG3DAttr(int attr, double value, double *old_value, int prim) +{ + if (astGrid3dPtr) + return astGrid3dPtr->gAttr(attr, value, old_value, prim); + return 0; +} diff --git a/tksao/util/grid25dbase.C b/tksao/util/grid25dbase.C new file mode 100644 index 0000000..95faf7f --- /dev/null +++ b/tksao/util/grid25dbase.C @@ -0,0 +1,191 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "grid25dbase.h" +#include "attribute.h" +#include "widget.h" +#include "frame3dbase.h" + +extern "C" { + #include "ast.h" + #include "grf.h" +} + +Grid25dBase* astGrid25dPtr = NULL; + +Grid25dBase::Grid25dBase(Widget* p) : GridBase(p) +{} + +Grid25dBase::Grid25dBase(Widget* p, const char* o) : GridBase(p,o) +{} + +Grid25dBase::~Grid25dBase() +{} + +int Grid25dBase::gLine(int n, float* x, float* y) +{ + Frame3dBase* pp = (Frame3dBase*)parent_; + float xx[n]; + float yy[n]; + + for (int ii=0; ii<n; ii++) { + Vector vv = pp->mapFromRef(Vector(x[ii],y[ii]),Coord::WIDGET); + xx[ii] = vv[0]; + yy[ii] = vv[1]; + } + + switch (renderMode_) { + case X11: + x11Line(n,xx,yy); + break; + case PS: + psLine(n,xx,yy); + break; + case MACOSX: +#ifdef MAC_OSX_TK + macosxLine(n,xx,yy); +#endif + break; + case GWIN32: +#ifdef __WIN32 + win32Line(n,xx,yy); +#endif + break; + } + + return 1; +} + +int Grid25dBase::gQch(float* chv, float* chh) +{ + Tk_Font font =NULL; + switch (renderMode_) { + case X11: + font = text_->tkfont(); + break; + case PS: + font = text_->psfont(); + break; + case MACOSX: +#ifdef MAC_OSX_TK + font = text_->tkfont(); +#endif + break; + case GWIN32: +#ifdef __WIN32 + font = text_->tkfont(); +#endif + break; + } + + if (font) { + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + + *chv = (float)metrics.linespace; + *chh = (float)metrics.linespace; + return 1; + } + else { + *chv = *chh = 0; + return 0; + } +} + +int Grid25dBase::gText(const char* txt, float x, float y, const char* just, + float upx, float upy) +{ + if (!(txt && txt[0] && just && just[0] && just[1])) + return 0; + + Frame3dBase* pp = (Frame3dBase*)parent_; + Vector vv = pp->mapFromRef(Vector(x,y),Coord::WIDGET); + + switch (renderMode_) { + case X11: + return x11Text(txt,vv[0],vv[1],just,Vector(0,1)); + case PS: + return psText(txt,vv[0],vv[1],just,Vector(0,1)); + case MACOSX: +#ifdef MAC_OSX_TK + return macosxText(txt,vv[0],vv[1],just,Vector(0,1)); +#endif + break; + case GWIN32: +#ifdef __WIN32 + return win32Text(txt,vv[0],vv[1],just,Vector(0,1)); +#endif + break; + } + + return 0; +} + +int Grid25dBase::gTxExt(const char* txt, float x, float y, const char* just, + float upx, float upy, float* xb, float* yb) +{ + if (!(txt && txt[0] && just)) { + xb[0] = xb[1] = xb[2] = xb[3] = 0; + yb[0] = yb[1] = yb[2] = yb[3] = 0; + + return 0; + } + + Tk_Font font =NULL; + + switch (renderMode_) { + case X11: + font = text_->tkfont(); + break; + case PS: + font = text_->psfont(); + break; + case MACOSX: +#ifdef MAC_OSX_TK + font = text_->tkfont(); +#endif + break; + case GWIN32: +#ifdef __WIN32 + font = text_->tkfont(); +#endif + break; + } + + if (!font) + return 0; + + Frame3dBase* pp = (Frame3dBase*)parent_; + Vector vv = pp->mapFromRef(Vector(x,y),Coord::WIDGET); + + double angle = 0; + Vector cc = vv * calcTextPos(vv, angle, txt, just, Vector(0, 1), font); + + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + int width = Tk_TextWidth(font, txt, strlen(txt)); + + BBox nn = BBox(Vector(0,-metrics.descent), Vector(width,metrics.ascent)); + BBox bb = nn * Rotate(angle) * Translate(cc); + + xb[0] = bb.ll[0]; + yb[0] = bb.ll[1]; + + xb[1] = bb.ur[0]; + yb[1] = bb.ll[1]; + + xb[2] = bb.ur[0]; + yb[2] = bb.ur[1]; + + xb[3] = bb.ll[0]; + yb[3] = bb.ur[1]; + + return 1; +} + +int Grid25dBase::gScales(float* alpha, float* beta) +{ + return 1; +} + diff --git a/tksao/util/grid25dbase.h b/tksao/util/grid25dbase.h new file mode 100644 index 0000000..adfe844 --- /dev/null +++ b/tksao/util/grid25dbase.h @@ -0,0 +1,26 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __grid25dbase_h__ +#define __grid25dbase_h__ + +#include "gridbase.h" + +class Grid25dBase : public GridBase { + public: + Grid25dBase(Widget*); + Grid25dBase(Widget*, const char*); + virtual ~Grid25dBase(); + + int gLine(int n, float* x, float* y); + int gQch(float*, float*); + int gMark(int, const float*, const float*, int) {return 1;} + int gText(const char* txt, float x, float y, const char* just, + float upx, float upy); + int gTxExt(const char*, float, float, const char*, + float, float, float*, float*); + int gScales(float *alpha, float *beta); +}; + +#endif diff --git a/tksao/util/grid2dbase.C b/tksao/util/grid2dbase.C new file mode 100644 index 0000000..606b592 --- /dev/null +++ b/tksao/util/grid2dbase.C @@ -0,0 +1,175 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "grid2dbase.h" +#include "attribute.h" +#include "widget.h" + +extern "C" { + #include "ast.h" + #include "grf.h" +} + +Grid2dBase* astGrid2dPtr = NULL; + +Grid2dBase::Grid2dBase(Widget* p) : GridBase(p) +{} + +Grid2dBase::Grid2dBase(Widget* p, const char* o) : GridBase(p,o) +{} + +Grid2dBase::~Grid2dBase() +{} + +int Grid2dBase::gLine(int n, float* x, float* y) +{ + switch (renderMode_) { + case X11: + x11Line(n,x,y); + break; + case PS: + psLine(n,x,y); + break; + case MACOSX: +#ifdef MAC_OSX_TK + macosxLine(n,x,y); +#endif + break; + case GWIN32: +#ifdef __WIN32 + win32Line(n,x,y); +#endif + break; + } + + return 1; +} + +int Grid2dBase::gQch(float* chv, float* chh) +{ + Tk_Font font =NULL; + switch (renderMode_) { + case X11: + font = text_->tkfont(); + break; + case PS: + font = text_->psfont(); + break; + case MACOSX: +#ifdef MAC_OSX_TK + font = text_->tkfont(); +#endif + break; + case GWIN32: +#ifdef __WIN32 + font = text_->tkfont(); +#endif + break; + } + + if (font) { + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + + *chv = (float)metrics.linespace; + *chh = (float)metrics.linespace; + return 1; + } + else { + *chv = *chh = 0; + return 0; + } +} + +int Grid2dBase::gText(const char* txt, float x, float y, const char* just, + float upx, float upy) +{ + if (!(txt && txt[0] && just && just[0] && just[1])) + return 0; + + switch (renderMode_) { + case X11: + return x11Text(txt,x,y,just,Vector(upx,upy)); + case PS: + return psText(txt,x,y,just,Vector(upx,upy)); + case MACOSX: +#ifdef MAC_OSX_TK + return macosxText(txt,x,y,just,Vector(upx,upy)); +#endif + break; + case GWIN32: +#ifdef __WIN32 + return win32Text(txt,x,y,just,Vector(upx,upy)); +#endif + break; + } + + return 0; +} + +int Grid2dBase::gTxExt(const char* txt, float x, float y, const char* just, + float upx, float upy, float* xb, float* yb) +{ + if (!(txt && txt[0] && just)) { + xb[0] = xb[1] = xb[2] = xb[3] = 0; + yb[0] = yb[1] = yb[2] = yb[3] = 0; + + return 0; + } + + Tk_Font font =NULL; + + switch (renderMode_) { + case X11: + font = text_->tkfont(); + break; + case PS: + font = text_->psfont(); + break; + case MACOSX: +#ifdef MAC_OSX_TK + font = text_->tkfont(); +#endif + break; + case GWIN32: +#ifdef __WIN32 + font = text_->tkfont(); +#endif + break; + } + + if (!font) + return 0; + + Vector vv = Vector(x,y); + double angle = calcTextAngle(just, Vector(upx, upy)); + Vector cc = vv * calcTextPos(vv, angle, txt, just, Vector(upx, upy), font); + + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + int width = Tk_TextWidth(font, txt, strlen(txt)); + + BBox nn = BBox(Vector(0,-metrics.descent), Vector(width,metrics.ascent)); + BBox bb = nn * Rotate(angle) * Translate(cc); + + xb[0] = bb.ll[0]; + yb[0] = bb.ll[1]; + + xb[1] = bb.ur[0]; + yb[1] = bb.ll[1]; + + xb[2] = bb.ur[0]; + yb[2] = bb.ur[1]; + + xb[3] = bb.ll[0]; + yb[3] = bb.ur[1]; + + return 1; +} + +int Grid2dBase::gScales(float* alpha, float* beta) +{ + return 1; +} + diff --git a/tksao/util/grid2dbase.h b/tksao/util/grid2dbase.h new file mode 100644 index 0000000..ae4c1ac --- /dev/null +++ b/tksao/util/grid2dbase.h @@ -0,0 +1,26 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __grid2dbase_h__ +#define __grid2dbase_h__ + +#include "gridbase.h" + +class Grid2dBase : public GridBase { + public: + Grid2dBase(Widget*); + Grid2dBase(Widget*, const char*); + virtual ~Grid2dBase(); + + int gLine(int n, float* x, float* y); + int gQch(float*, float*); + int gMark(int, const float*, const float*, int) {return 1;} + int gText(const char* txt, float x, float y, const char* just, + float upx, float upy); + int gTxExt(const char*, float, float, const char*, + float, float, float*, float*); + int gScales(float *alpha, float *beta); +}; + +#endif diff --git a/tksao/util/grid3dbase.C b/tksao/util/grid3dbase.C new file mode 100644 index 0000000..9463d73 --- /dev/null +++ b/tksao/util/grid3dbase.C @@ -0,0 +1,241 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "grid3dbase.h" +#include "attribute.h" +#include "widget.h" + +extern "C" { + #include "ast.h" + #include "grf.h" +} + +Grid3dBase* astGrid3dPtr = NULL; + +Grid3dBase::Grid3dBase(Widget* p) : GridBase(p) +{} + +Grid3dBase::Grid3dBase(Widget* p, const char* o) : GridBase(p,o) +{} + +Grid3dBase::~Grid3dBase() +{} + +int Grid3dBase::gLine(int n, float* x, float* y, float* z) +{ + float xx[n]; + float yy[n]; + + for (int ii=0; ii<n; ii++) { + Vector3d vv = Vector3d(x[ii],y[ii],z[ii])*mx_; + xx[ii] = vv[0]; + yy[ii] = vv[1]; + } + + switch (renderMode_) { + case X11: + x11Line(n,xx,yy); + break; + case PS: + psLine(n,xx,yy); + break; + case MACOSX: +#ifdef MAC_OSX_TK + macosxLine(n,xx,yy); +#endif + break; + case GWIN32: +#ifdef __WIN32 + win32Line(n,xx,yy); +#endif + break; + } + return 1; +} + +int Grid3dBase::gQch(float* ch) +{ + Tk_Font font =NULL; + switch (renderMode_) { + case X11: + font = text_->tkfont(); + break; + case PS: + font = text_->psfont(); + break; + case MACOSX: +#ifdef MAC_OSX_TK + font = text_->tkfont(); +#endif + break; + case GWIN32: +#ifdef __WIN32 + font = text_->tkfont(); +#endif + break; + } + + if (font) { + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + + *ch = (float)metrics.linespace; + return 1; + } + else { + *ch = 0; + return 0; + } +} + +int Grid3dBase::gText(const char* txt, float* ref, const char* just, + float* up, float* norm) +{ + if (!(txt && txt[0] && just && just[0] && just[1])) + return 0; + + Vector3d vv = Vector3d(ref[0],ref[1],ref[2])*mx_; + + switch (renderMode_) { + case X11: + return x11Text(txt,vv[0],vv[1],just,Vector(0,1)); + case PS: + return psText(txt,vv[0],vv[1],just,Vector(0,1)); + case MACOSX: +#ifdef MAC_OSX_TK + return macosxText(txt,vv[0],vv[1],just,Vector(0,1)); +#endif + break; + case GWIN32: +#ifdef __WIN32 + return win32Text(txt,vv[0],vv[1],just,Vector(0,1)); +#endif + break; + } + + return 0; +} + +int Grid3dBase::gTxExt(const char* txt, float* ref, const char* just, + float* up, float* norm, float* xb, float* yb, + float* zb, float* bl) +{ + if (!(txt && txt[0] && just)) { + xb[0] = xb[1] = xb[2] = xb[3] = 0; + yb[0] = yb[1] = yb[2] = yb[3] = 0; + zb[0] = zb[1] = zb[2] = zb[3] = 0; + + return 0; + } + + /* + cerr << txt + << Vector3d(ref[0],ref[1],ref[2]) << ' ' + << just[0] << just[1] + << Vector3d(up[0],up[1],up[2]) + << Vector3d(norm[0],norm[1],norm[2]) + << endl; + */ + + Tk_Font font =NULL; + + switch (renderMode_) { + case X11: + font = text_->tkfont(); + break; + case PS: + font = text_->psfont(); + break; + case MACOSX: +#ifdef MAC_OSX_TK + font = text_->tkfont(); +#endif + break; + case GWIN32: +#ifdef __WIN32 + font = text_->tkfont(); +#endif + break; + } + + if (!font) + return 0; + + Vector3d vv = Vector3d(ref[0],ref[1],ref[2])*mx_; + // cerr << " vv: " << vv << endl; + Vector3d cc = vv * calcTextPos(vv, txt, just, font); + // cerr << " cc: " << cc << endl; + + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + int width = Tk_TextWidth(font, txt, strlen(txt)); + + BBox3d nn(Vector3d(0,-metrics.descent,0), Vector3d(width,metrics.ascent,0)); + // cerr << " nn: " << nn << endl; + Matrix3d mm = Translate3d(-nn.center()) * rx_ * Translate3d(nn.center()); + // cerr << mm << endl; + BBox3d bb = nn * mm * Translate3d(cc); + // cerr << " bb: " << bb << endl; + Vector3d ll = cc * mm; + + xb[0] = bb.ll[0]; + yb[0] = bb.ll[1]; + zb[0] = bb.ll[2]; + + xb[1] = bb.ur[0]; + yb[1] = bb.ll[1]; + zb[1] = bb.ll[2]; + + xb[2] = bb.ur[0]; + yb[2] = bb.ur[1]; + zb[2] = bb.ll[2]; + + xb[3] = bb.ll[0]; + yb[3] = bb.ur[1]; + zb[3] = bb.ll[2]; + + bl[0] = ll[0]; + bl[1] = ll[1]; + bl[2] = ll[2]; + + return 1; +} + +Matrix3d Grid3dBase::calcTextPos(const Vector3d& vv, const char* txt, + const char* just, Tk_Font font) +{ + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + int width = Tk_TextWidth(font, txt, strlen(txt)); + + Matrix3d m1,m2; + switch (just[0]) { + case 'T': + break; + case 'C': + m1 = Translate3d(0,metrics.linespace/2,0); + break; + case 'B': + m1 = Translate3d(0,metrics.ascent,0); + break; + case 'M': + m1 = Translate3d(0,metrics.linespace,0); + break; + } + + switch (just[1]) { + case 'L': + break; + case 'C': + m2 = Translate3d(-width/2.,0,0); + break; + case 'R': + m2 = Translate3d(-width,0,0); + break; + } + + return Translate3d(-vv) * + m1 * m2 * + Translate3d(vv); +} diff --git a/tksao/util/grid3dbase.h b/tksao/util/grid3dbase.h new file mode 100644 index 0000000..b81d17f --- /dev/null +++ b/tksao/util/grid3dbase.h @@ -0,0 +1,35 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __grid3dbase_h__ +#define __grid3dbase_h__ + +#include <tk.h> + +#include "gridbase.h" +#include "vector3d.h" + +class Grid3dBase : public GridBase { + protected: + Matrix3d mx_; + Matrix3d rx_; + + Matrix3d calcTextPos(const Vector3d&, const char*, const char*, Tk_Font); + + public: + Grid3dBase(Widget*); + Grid3dBase(Widget*, const char*); + virtual ~Grid3dBase(); + + int gLine(int n, float* x, float* y, float* z); + int gQch(float* ch); + int gMark(int n, float* x, float* y, float* z, int type, float* norm) + {return 1;} + int gText(const char* txt, float* ref, const char* just, float* up, + float* norm); + int gTxExt(const char* txt, float* ref, const char* just, float* up, + float* norm, float* xb, float* yb, float* zb, float* bl); +}; + +#endif diff --git a/tksao/util/gridbase.C b/tksao/util/gridbase.C new file mode 100644 index 0000000..a941755 --- /dev/null +++ b/tksao/util/gridbase.C @@ -0,0 +1,461 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "gridbase.h" +#include "attribute.h" +#include "widget.h" +#include "util.h" + +EXTERN void TkDrawAngledChars(Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *source, int numBytes, double x, + double y, double angle); +extern "C" { + #include "ast.h" + #include "grf.h" +} + +GridBase::GridBase(Widget* pp) : parent_(pp) +{ + option_ = NULL; + + renderMode_ = X11; + line_ = new Attribute(parent_); + text_ = new Attribute(parent_); + + gridGC_ = XCreateGC(parent_->getDisplay(), Tk_WindowId(parent_->getTkwin()), + 0, NULL); + pixmap_ = 0; + + mode_ = Widget::RGB; +} + +GridBase::GridBase(Widget* pp, const char* op) : parent_(pp) +{ + option_ = dupstr(op); + + renderMode_ = X11; + line_ = new Attribute(parent_); + text_ = new Attribute(parent_); + + gridGC_ = XCreateGC(parent_->getDisplay(), Tk_WindowId(parent_->getTkwin()), + 0, NULL); + pixmap_ = 0; + + mode_ = Widget::RGB; +} + +GridBase::~GridBase() +{ + if (option_) + delete [] option_; + + if (gridGC_) + XFreeGC(parent_->getDisplay(), gridGC_); + + if (line_) + delete line_; + if (text_) + delete text_; +} + +int GridBase::gAttr(int which, double value, double* old, int prim) +{ + Attribute* attr; + switch (prim) { + case GRF__TEXT: + attr = text_; + + switch (which) { + case GRF__STYLE: + break; + case GRF__WIDTH: + break; + case GRF__SIZE: + if (old) + *old = attr->size(); + if (value != AST__BAD) + attr->setSize(value); + break; + case GRF__FONT: + if (old) + *old = attr->font(); + if (value != AST__BAD) + attr->setFont(value); + break; + case GRF__COLOUR: + if (old) + *old = attr->colour(); + if (value != AST__BAD) + attr->setColour(value); + break; + } + + break; + case GRF__LINE: + attr = line_; + + switch (which) { + case GRF__STYLE: + if (old) + *old = attr->style(); + if (value != AST__BAD) + attr->setStyle(value); + break; + case GRF__WIDTH: + if (old) + *old = attr->width(); + if (value != AST__BAD) + attr->setWidth(value); + break; + case GRF__SIZE: + break; + case GRF__FONT: + break; + case GRF__COLOUR: + if (old) + *old = attr->colour(); + if (value != AST__BAD) + attr->setColour(value); + break; + } + + break; + } + + return 1; +} + +int GridBase::gCap(int cap, int value) +{ + switch (cap) { + case GRF__SCALES: + return 0; + case GRF__MJUST: + return 1; + case GRF__ESC: + return 0; + } + return 0; +} + +// X11 Render functions + +int GridBase::x11Line(int n, float* x, float* y) +{ + if (n<2 || !x || !y) + return 1; + + XSetForeground(parent_->getDisplay(), gridGC_, line_->color()); + int w = (int)line_->width(); + if (w<1) + w = 1; + switch (line_->style()) { + case Attribute::SOLID: + XSetLineAttributes(parent_->getDisplay(), gridGC_, w, + LineSolid, CapButt, JoinMiter); + break; + case Attribute::DASH: + XSetLineAttributes(parent_->getDisplay(), gridGC_, w, + LineOnOffDash, CapButt, JoinMiter); + char dlist[] = {8,3}; + XSetDashes(parent_->getDisplay(), gridGC_, 0, dlist, 2); + break; + } + + for (int i=0; i<n-1; i++) { + Vector s = Vector(x[i],y[i]).round(); + Vector e = Vector(x[i+1],y[i+1]).round(); + XDrawLine(parent_->getDisplay(), pixmap_, gridGC_, + (int)s[0],(int)s[1],(int)e[0],(int)e[1]); + } + + return 1; +} + +int GridBase::x11Text(const char* txt, float x, float y, + const char* just, Vector up) +{ + XSetFont(parent_->getDisplay(), gridGC_, Tk_FontId(text_->tkfont())); + XSetForeground(parent_->getDisplay(), gridGC_, text_->color()); + + Vector vv = Vector(x,y); + double angle = calcTextAngle(just, up); + Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont()); + + TkDrawAngledChars(parent_->getDisplay(), pixmap_, gridGC_, text_->tkfont(), + txt, strlen(txt), + cc[0], cc[1], radToDeg(angle)); + return 1; +} + +// PS Render functions + +int GridBase::psLine(int n, float* x, float* y) +{ + if (n<2 || !x || !y) + return 1; + + psColor(line_); + { + ostringstream str; + str << line_->width() << " setlinewidth" << endl << ends; + Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); + } + { + ostringstream str; + switch (line_->style()) { + case Attribute::SOLID: + str << "[] 0 setdash" << endl << ends; + break; + case Attribute::DASH: + str << "[8 3] 0 setdash" << endl << ends; + break; + } + Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); + } + + for (int i=0; i<n; i++) { + Vector v = Vector(x[i],y[i]) * matrix_; + + ostringstream str; + if (i == 0) { + str << "newpath " << endl; + str << v.TkCanvasPs(parent_->getCanvas()) << " moveto" << endl << ends; + } + else + str << v.TkCanvasPs(parent_->getCanvas()) << " lineto" << endl << ends; + + Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); + } + + ostringstream str; + str << "stroke" << endl << ends; + Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); + + return 1; +} + +int GridBase::psText(const char* txt, float x, float y, + const char* just, Vector up) +{ + Tcl_DString psdstr; + Tcl_DStringInit(&psdstr); + + Vector vv = Vector(x,y) * matrix_; + double angle = calcTextAngle(just, up); + Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->psfont()); + + ostringstream str; + const char* ff = Tk_NameOfFont(text_->psfont()); + str << '/' << psFontName(ff) + << " findfont " << int(psFontSize(ff)*parent_->getDisplayRatio()) + << " scalefont setfont" << endl; + + psColor(text_); + + str << "gsave " + << cc.TkCanvasPs(parent_->getCanvas()) << " moveto" << endl + << radToDeg(angle) << " rotate " + << '(' << psQuote(txt) << ')' << " show" + << " grestore" << endl << ends; + Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); + + return 1; +} + +void GridBase::psColor(Attribute* attr) +{ + ostringstream str; + switch ((Widget::PSColorSpace)mode_) { + case Widget::BW: + case Widget::GRAY: + psColorGray(parent_->getXColor(attr->colorName()), str); + str << " setgray"; + break; + case Widget::RGB: + psColorRGB(parent_->getXColor(attr->colorName()), str); + str << " setrgbcolor"; + break; + case Widget::CMYK: + psColorCMYK(parent_->getXColor(attr->colorName()), str); + str << " setcmykcolor"; + break; + } + str << endl << ends; + Tcl_AppendResult(parent_->getInterp(), str.str().c_str(), NULL); +} + +#ifdef MAC_OSX_TK +int GridBase::macosxLine(int n, float* x, float* y) +{ + if (n<2 || !x || !y) + return 1; + + macosxColor(parent_->getXColor(line_->colorName())); + macosxWidth(line_->width()); + switch (line_->style()) { + case Attribute::SOLID: + macosxDash(NULL,0); + break; + case Attribute::DASH: + float dlist[] = {8,3}; + macosxDash(dlist,2); + break; + } + + Vector* v = new Vector[n]; + for (int i=0; i<n; i++) + v[i] = Vector(x[i],y[i]) * matrix_; + + macosxDrawLines(v, n); + delete [] v; + + return 1; +} + +int GridBase::macosxText(const char* txt, float x, float y, + const char* just, Vector up) +{ + // change this later + Tcl_DString psdstr; + Tcl_DStringInit(&psdstr); + int psSize = Tk_PostscriptFontName(text_->tkfont(), &psdstr); + + macosxFont(Tcl_DStringValue(&psdstr),psSize); + Tcl_DStringFree(&psdstr); + + Vector vv = Vector(x,y) * matrix_; + double angle = calcTextAngle(just, up); + Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont()); + + macosxColor(parent_->getXColor(text_->colorName())); + macosxDrawText(cc, angle, txt); + + return 1; +} +#endif + +#ifdef __WIN32 +int GridBase::win32Line(int n, float* x, float* y) +{ + if (n<2 || !x || !y) + return 1; + + win32Color(parent_->getXColor(line_->colorName())); + win32Width(line_->width()); + switch (line_->style()) { + case Attribute::SOLID: + win32Dash(NULL,0); + break; + case Attribute::DASH: + float dlist[] = {8,3}; + win32Dash(dlist,2); + break; + } + + Vector v[n]; + for (int i=0; i<n; i++) + v[i] = Vector(x[i],y[i]) * matrix_; + + win32DrawLines(v, n); + + return 1; +} + +int GridBase::win32Text(const char* txt, float x, float y, + const char* just, Vector up) +{ + win32Font(text_->tkfont()); + win32Color(parent_->getXColor(text_->colorName())); + + Vector vv = Vector(x,y) * matrix_; + double angle = calcTextAngle(just, up);; + Vector cc = vv * calcTextPos(vv, angle, txt, just, up, text_->tkfont()); + + win32DrawText(cc, angle, txt); + + return 1; +} +#endif + +// Support + +double GridBase::calcTextAngle(const char* just, Vector up) +{ + double a = up.angle(); + + // our angle is 90 off from ast's, and the other direction + double rr = -(a - M_PI_2); + + // special case for text rotated exactly 90 + if (up[0]==-1 && up[1]==0) + rr += M_PI; + + // normalize + if (rr>0) + while (rr>M_TWOPI) + rr -= M_TWOPI; + else + while (rr<0) + rr += M_TWOPI; + + return rr; +} + +Matrix GridBase::calcTextPos(const Vector& vv, double angle, const char* txt, + const char* just, Vector up, Tk_Font font) +{ + Tk_FontMetrics metrics; + Tk_GetFontMetrics(font, &metrics); + int width = Tk_TextWidth(font, txt, strlen(txt)); + + Matrix m1,m2; + switch (just[0]) { + case 'T': + break; + case 'C': + m1 = Translate(0,metrics.linespace/2); + break; + case 'B': + m1 = Translate(0,metrics.ascent); + break; + case 'M': + m1 = Translate(0,metrics.linespace); + break; + } + + switch (just[1]) { + case 'L': + break; + case 'C': + m2 = Translate(-width/2.,0); + break; + case 'R': + m2 = Translate(-width,0); + break; + } + + Matrix rr = Translate(-vv) * + Rotate(-angle) * + m1 * m2 * + Rotate(angle) * + Translate(vv); + + // special case for text rotated exactly 90 + Matrix mm; + if (up[0] == -1 && up[1] == 0) { + Vector cc = vv*rr; + mm = Translate(-cc) * + Rotate(-angle) * + Translate(-width/2.,metrics.linespace/2.) * + FlipY() * + Translate(width/2.,-metrics.linespace/2.) * + Rotate(angle) * + Translate(cc); + } + + return rr*mm; +} + diff --git a/tksao/util/gridbase.h b/tksao/util/gridbase.h new file mode 100644 index 0000000..fec7705 --- /dev/null +++ b/tksao/util/gridbase.h @@ -0,0 +1,67 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __gridbase_h__ +#define __gridbase_h__ + +#include <tk.h> + +#include "vector.h" + +class Widget; +class Attribute; + +class GridBase { + public: + enum RenderMode {X11, PS, MACOSX, GWIN32}; + + protected: + Widget* parent_; + char* option_; + + RenderMode renderMode_; + Attribute* line_; + Attribute* text_; + + GC gridGC_; + Pixmap pixmap_; + + Matrix matrix_; + int mode_; + + protected: + int x11Line(int n, float* x, float* y); + int x11Text(const char*, float, float, const char*, Vector); + + int psLine(int n, float* x, float* y); + int psText(const char*, float, float, const char*, Vector); + void psColor(Attribute*); + +#ifdef MAC_OSX_TK + int macosxLine(int n, float* x, float* y); + int macosxText(const char*, float, float, const char*, Vector); +#endif + +#ifdef __WIN32 + int win32Line(int n, float* x, float* y); + int win32Text(const char*, float, float, const char*, Vector); +#endif + + double calcTextAngle(const char*, Vector); + Matrix calcTextPos(const Vector&, double, const char*, + const char*, Vector, Tk_Font); + + public: + GridBase(Widget*); + GridBase(Widget*, const char*); + virtual ~GridBase(); + + int gAttr(int attr, double value, double* old, int prim); + int gCap(int, int); + int gFlush() {return 1;} + + const char* option() {return option_;} +}; + +#endif diff --git a/tksao/util/ps.C b/tksao/util/ps.C new file mode 100644 index 0000000..b3a5b1e --- /dev/null +++ b/tksao/util/ps.C @@ -0,0 +1,377 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include <string.h> + +#include "ps.h" +#include "util.h" + +Filter::Filter() +{ + buf_ = new unsigned char[BUFSIZE]; + ptr_ = buf_; +} + +Filter::~Filter() +{ + if (buf_) + delete [] buf_; +} + +void Filter::flush(ostream& str) +{ + cflush(); + eflush(str); +} + +// Compress + +void NoCompress::in(unsigned char c) +{ + *ptr_++ = c; +} + +// RLE + +RLE::RLE() +{ + state = 0; + num = 0; +} + +void RLE::in(unsigned char c) +{ + current = c; + switch (state) { + case 0: // start state + if (num == 0) // not enough info yet + rle[num++] = current; + else { + if (current != rle[num-1]) { // looks like non repeating + rle[num++] = current; + state = 1; + } + else { // looks like repeating + num++; + state = 2; + } + } + break; + + case 1: // non repeat state + if (current != rle[num-1]) { + rle[num++] = current; + + if (num >= RLESIZE) { // time to dump the rlefer + dumpNonRepeat(); // dump the buffer + num = 0; // and reset counter + state = 0; + } + } + else { + num--; // decr + dumpNonRepeat(); // dump the buffer + + state = 2; // repeat state + rle[0] = current; // save repeat char + num = 2; // we aready have two now + } + break; + + case 2: // repeat state + if (current == rle[0]) { + if (++num >= RLESIZE) { + dumpRepeat(); // dump the repeat count + state = 0; + num = 0; + } + } + else { + dumpRepeat(); // dump the repeat count + state = 1; // back to non repeat state + rle[0] = current; // save first char + num = 1; // we have one now + } + break; + } +} + +void RLE::dumpNonRepeat() +{ + if (num) { + *ptr_++ = (unsigned char)(num-1); + for (int i=0; i<num; i++) + *ptr_++ = rle[i]; + } +} + +void RLE::dumpRepeat() +{ + if (num) { + *ptr_++ = (unsigned char)(257-num); + *ptr_++ = rle[0]; + } +} + +void RLE::cflush() +{ + switch (state) { + case 0: + case 1: + dumpNonRepeat(); + break; + case 2: + dumpRepeat(); + break; + } +} + +// GZIP + +GZIP::GZIP() +{ + stream_ = new z_stream; + gzip_ = new unsigned char[GZIPSIZE]; + + stream_->next_in = NULL; + stream_->avail_in = 0; + stream_->next_out = NULL; + stream_->avail_out = 0; + + stream_->zalloc = NULL; + stream_->zfree = NULL; + stream_->opaque = NULL; + + if (deflateInit(stream_, Z_DEFAULT_COMPRESSION) != Z_OK) { + if (DebugGZ) + cerr << "deflateInit error" << endl; + return; + } + + stream_->next_out = gzip_; + stream_->avail_out = GZIPSIZE; +} + +GZIP::~GZIP() +{ + if (deflateEnd(stream_) != Z_OK) + if (DebugGZ) + cerr << "deflateEnd error" << endl; + + if (gzip_) + delete [] gzip_; + + if (stream_) + delete stream_; +} + +void GZIP::in(unsigned char c) +{ + stream_->next_in = &c; + stream_->avail_in = 1; + + while (stream_->avail_in > 0 && deflategz(Z_NO_FLUSH) == Z_OK); +} + +void GZIP::cflush() +{ + // flush any pending output + while (deflategz(Z_FINISH) == Z_OK); +} + +int GZIP::deflategz(int flush) +{ + int result = deflate(stream_, flush); + + switch (result) { + case Z_OK: + if (DebugGZ) + cerr << "deflate OK: avail_in " << stream_->avail_in + << " avail_out " << stream_->avail_out << endl; + break; + case Z_STREAM_END: + if (DebugGZ) + cerr << "deflate STRM_END: avail_in " << stream_->avail_in + << " avail_out " << stream_->avail_out << endl; + break; + default: + if (DebugGZ) + cerr << "deflate Error " << result << endl; + return result; + } + + if (stream_->avail_out == 0 || result != Z_OK) { + int s = GZIPSIZE - stream_->avail_out; + unsigned char* d = gzip_; + + if (s>0) { + if (ptr_+s > buf_+BUFSIZE) { + cerr << "deflate buffer overflow " + << stream_->avail_out << ' ' << result << endl; + return result; + } + + memcpy(ptr_,d,s); + ptr_ += s; + + if (DebugGZ) + cerr << "deflate send " << s << ' ' << result << endl; + } + + stream_->next_out = gzip_; + stream_->avail_out = GZIPSIZE; + } + + return result; +} + +// Encode + +Encode::Encode(int l) +{ + level = l; + lineCount = 0; +} + +// AsciiHex + +AsciiHex::AsciiHex(int l) : Encode(l) {} + +void AsciiHex::out(ostream& str) +{ + unsigned char* p = buf_; + while (p < ptr_) { + unsigned short c = *p++; + str << hex << setfill('0') << setw(2) << c; + + lineCount += 2; + if (lineCount >= LINELIMIT) { + str << endl; + lineCount = 0; + } + } + ptr_ = buf_; // reset buffer +} + +void AsciiHex::eflush(ostream& str) +{ + out(str); + switch (level) { + case 1: + str << endl; + break; + case 2: + case 3: + str << endl << '>' << endl; + break; + } +} + +// Ascii85 + +Ascii85::Ascii85(int l) : Encode(l) +{ + byteswap = (*(short *)"\001\000" & 0x0001); + + buf85.c = 0; + index = 0; +} + +int32_t Ascii85::swap(uint32_t* p) +{ + int32_t r; + swap4((char*)p, (char*)&r); + return r; +} + +void Ascii85::out(ostream& str) +{ + unsigned char* p = buf_; + while (p < ptr_) { + buf85.b[index++] = *p++; + if (index==4) { + dump(str); + } + } + + ptr_ = buf_; // reset buffer +} + +void Ascii85::dump(ostream& str) +{ + // all zeros? + if (buf85.c == 0) { + str << 'z'; + if (++lineCount >= LINELIMIT) { + str << endl; + lineCount = 0; + } + } + else { + uint32_t b; + if (!byteswap) + b = buf85.c; + else + b = swap(&buf85.c); + + for (int ii=4; ii>=0 ; ii--) { + uint32_t base = 1; + for (int jj=0; jj<ii; jj++) + base *= 85; + + uint32_t a = b / base; + b -= a * base; + str << (char)(a + '!'); + if (++lineCount >= LINELIMIT) { + str << endl; + lineCount = 0; + } + } + } + index = 0; + buf85.c = 0; +} + +void Ascii85::eflush(ostream& str) +{ + // dump the remainder + out(str); + + // we can't have any z's here + // also, only write index+1 chars + if (index) { + uint32_t b; + if (!byteswap) + b = buf85.c; + else + b = swap(&buf85.c); + + for (int ii=4; ii>=(4-index); ii--) { + uint32_t base = 1; + for (int jj=0; jj<ii; jj++) + base *= 85; + + uint32_t a = b / base; + b -= a * base; + str << (char)(a + '!'); + if (++lineCount >= LINELIMIT) { + str << endl; + lineCount = 0; + } + } + } + index = 0; + buf85.c = 0; + + switch (level) { + case 1: + str << endl; + break; + case 2: + case 3: + str << endl << "~>" << endl; + break; + } +} + diff --git a/tksao/util/ps.h b/tksao/util/ps.h new file mode 100644 index 0000000..83c6e70 --- /dev/null +++ b/tksao/util/ps.h @@ -0,0 +1,171 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __ps_h__ +#define __ps_h__ + +#include <stdint.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include "zlib.h" +extern int DebugGZ; + +// we need this large for gzip +#define GZIPSIZE 8192 +#define BUFSIZE GZIPSIZE*8 +#define RLESIZE 128 +#define LINELIMIT 80 + +// Filter Base Class +class Filter { +protected: + unsigned char* buf_; + unsigned char* ptr_; + + virtual void cflush() =0; + virtual void eflush(ostream&) =0; + +public: + Filter(); + virtual ~Filter(); + + virtual void in(unsigned char) =0; + virtual void out(ostream&) =0; + void flush(ostream&); + + friend Filter& operator<<(Filter& f, unsigned char c) {f.in(c); return f;} + friend ostream& operator<<(ostream& s, Filter& f) {f.out(s); return s;} +}; + +// Compress Base Class +class Compress : public virtual Filter { +public: + virtual void in(unsigned char) =0; + virtual void cflush() =0; +}; + +class NoCompress : public virtual Filter, public Compress { +public: + void in(unsigned char); + void cflush() {} +}; + +// RLE +class RLE : public virtual Filter, public Compress { +private: + int state; + unsigned char current; + unsigned char rle[RLESIZE]; + int num; + + void dumpNonRepeat(); + void dumpRepeat(); + +public: + RLE(); + + void in(unsigned char); + void cflush(); +}; + +// GZIP +class GZIP : public virtual Filter, public Compress { +private: + z_stream* stream_; + unsigned char* gzip_; + + int deflategz(int); + +public: + GZIP(); + ~GZIP(); + + void in(unsigned char); + void cflush(); +}; + +// Encode Base Class +class Encode : public virtual Filter { +protected: + int level; + int lineCount; + +public: + Encode(int); + + virtual void out(ostream&) =0; + virtual void eflush(ostream&) =0; +}; + +// AsciiHex +class AsciiHex : public virtual Filter, public Encode { +public: + AsciiHex(int); + + void out(ostream&); + void eflush(ostream&); +}; + +// Ascii85 +class Ascii85 : public virtual Filter, public Encode { +private: + int index; + int byteswap; + union { + unsigned char b[4]; + uint32_t c; + } buf85; + + void dump(ostream&); + int32_t swap(uint32_t* ptr); + +public: + Ascii85(int); + + void out(ostream&); + void eflush(ostream&); +}; + +// PS Filters +class NoCompressAsciiHex : +public virtual Filter, public NoCompress, public AsciiHex { + public: + NoCompressAsciiHex(int l) : AsciiHex(l) {}; +}; + +class NoCompressAscii85 : +public virtual Filter, public NoCompress, public Ascii85 { + public: + NoCompressAscii85(int l) : Ascii85(l) {}; +}; + +class RLEAsciiHex : +public virtual Filter, public RLE, public AsciiHex { + public: + RLEAsciiHex(int l) : AsciiHex(l) {}; +}; + +class RLEAscii85 : +public virtual Filter, public RLE, public Ascii85 { + public: + RLEAscii85(int l) : Ascii85(l) {}; +}; + +class GZIPAsciiHex : +public virtual Filter, public GZIP, public AsciiHex { + public: + GZIPAsciiHex(int l) : AsciiHex(l) {}; +}; + +class GZIPAscii85 : +public virtual Filter, public GZIP, public Ascii85 { + public: + GZIPAscii85(int l) : Ascii85(l) {}; +}; + +#endif diff --git a/tksao/util/smooth.C b/tksao/util/smooth.C new file mode 100644 index 0000000..db70981 --- /dev/null +++ b/tksao/util/smooth.C @@ -0,0 +1,67 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <math.h> + +#include "smooth.h" + +void boxcar(double* kernel, int r) +{ + int rr = 2*r+1; + int ksz = rr*rr; + + double* ptr = kernel; + for (int jj=0; jj<rr; jj++) + for (int ii=0; ii<rr; ii++, ptr++) + *ptr = 1./ksz; +} + +void tophat(double* kernel, int r) +{ + int rr = 2*r+1; + int ksz = rr*rr; + + double kt = 0; + for (int y=-r; y<=r; y++) { + for (int x=-r; x<=r; x++) { + if ((x*x + y*y) <= r*r) { + kernel[(y+r)*rr+(x+r)] = 1; + kt++; + } + } + } + + // normalize kernel + for (int aa=0; aa<ksz; aa++) + kernel[aa] /= kt; +} + +void gaussian(double* kernel, int r) +{ + int rr = 2*r+1; + int ksz = rr*rr; + double sigma = r/2.; + double s2 = sigma*sigma; + + double kt = 0; + for (int y=-r; y<=r; y++) { + for (int x=-r; x<=r; x++) { + if ((x*x + y*y) <= r*r) { + double vv = exp(-.5*((x*x + y*y)/s2)); + kernel[(y+r)*rr+(x+r)] = vv; + kt += vv; + } + } + } + + // normalize kernel + for (int aa=0; aa<ksz; aa++) + kernel[aa] /= kt; +} + diff --git a/tksao/util/smooth.h b/tksao/util/smooth.h new file mode 100644 index 0000000..fccf252 --- /dev/null +++ b/tksao/util/smooth.h @@ -0,0 +1,12 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __smooth_h__ +#define __smooth_h__ + +void boxcar(double* kernel, int r); +void tophat(double* kernel, int r); +void gaussian(double* kernel, int r); + +#endif diff --git a/tksao/util/util.C b/tksao/util/util.C new file mode 100644 index 0000000..644290c --- /dev/null +++ b/tksao/util/util.C @@ -0,0 +1,486 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include <tkInt.h> + +#include "util.h" + +// Error in mapping +int maperr= 0; + +static char tobuf[1024]; + +int sexSign; // used by parser and lex to indicate sign of dms or hms + +void swap2(char* src, char* dest) { + *(dest ) = *(src+1); + *(dest+1) = *(src ); +} + +void swap4(char* src, char* dest) { + *(dest ) = *(src+3); + *(dest+1) = *(src+2); + *(dest+2) = *(src+1); + *(dest+3) = *(src ); +} + +void swap8(char* src, char* dest) { + *(dest ) = *(src+7); + *(dest+1) = *(src+6); + *(dest+2) = *(src+5); + *(dest+3) = *(src+4); + *(dest+4) = *(src+3); + *(dest+5) = *(src+2); + *(dest+6) = *(src+1); + *(dest+7) = *(src ); +} + +int lsb() +{ + return (*(short *)"\001\000" & 0x0001); +} + +char* dupstr(const char* str) +{ + char* copy; + if (str) { + copy=new char[strlen(str)+1]; + strcpy(copy,str); + } + else + copy=NULL; + + return copy; +} + +char* trim(const char* str) +{ + char* rr = dupstr(str); + char* ptr = rr; + while (ptr && *ptr) + ptr++; + ptr--; + while (ptr && (*ptr == ' ')) + ptr--; + ptr++; + *ptr = '\0'; + + return rr; +} + +char* toLower(const char* str) +{ + char* rr = dupstr(str); + char* ptr = rr; + while (*ptr) { + *ptr = (char)(tolower(((int)(*ptr)))); + ptr++; + } + return rr; +} + +char* toUpper(const char* str) +{ + char* rr = dupstr(str); + char* ptr = rr; + while (*ptr) { + *ptr = (char)(toupper(((int)(*ptr)))); + ptr++; + } + return rr; +} + +char* toConstLower(const char* str) +{ + strncpy(tobuf,str,1024); + char* ptr = tobuf; + while (*ptr) { + *ptr = (char)(tolower(((int)(*ptr)))); + ptr++; + } + return tobuf; +} + +char* toConstUpper(const char* str) +{ + strncpy(tobuf,str,1024); + char* ptr = tobuf; + while (*ptr) { + *ptr = (char)(toupper(((int)(*ptr)))); + ptr++; + } + return tobuf; +} + +double zeroTWOPI(double aa) +{ + double rr = aa; + if (rr>0) + while (rr>=M_TWOPI) + rr -= M_TWOPI; + else + while (rr<0) + rr += M_TWOPI; + return rr; +} + +double zero360(double aa) +{ + double rr = aa; + if (rr>=0) + while (rr>360) + rr -= 360; + else + while (rr<0) + rr += 360; + return rr; +} + +double m180To180(double aa) +{ + // incoming 0-360 + double rr = aa; + if (rr>180) + rr -= 360; + return rr; +} + +double degToRad(double dd) +{ + double rr = M_PI*dd/180.; + return zeroTWOPI(rr); +} + +double radToDeg(double rr) +{ + double dd = 180.*rr/M_PI; + return zero360(dd); +} + +double dmsToDegree(int sign, int degree, int min, double sec) +{ + // sign is needed because of -00 vs +00 + return double(sign) * (abs(degree) + (min/60.) + (sec/60./60.)); +} + +int parseSection(char* lbuf, Vector* v1, Vector* v2) +{ + double x1, y1, x2, y2; + char d1,d2,d3,d4,d5; // dummy char + string x(lbuf); + istringstream str(x); + str >> d1 >> x1 >> d2 >> x2 >> d3 >> y1 >> d4 >> y2 >> d5; + + // verify input + if (!(d1=='[' && d2==':' && d3==',' && d4==':' && d5==']')) + return 0; + + // it looks ok + *v1 = Vector(x1,y1); + *v2 = Vector(x2,y2); + + return 1; +} + +double parseSEXStr(const char* d) +{ + char* dms = dupstr(d); // its going to get clobbered + char* ptr = dms; + + int sign = 1; + int degree = atoi(strtok(ptr,":")); + int minute = atoi(strtok(NULL,":")); + float sec = atof(strtok(NULL,":")); + + // assumes the minus sign is the first char + if (degree != 0) + sign = degree>0 ? 1 : -1; + else + sign = d[0] == '-' ? -1 : 1; + + delete [] dms; + + return dmsToDegree(sign,abs(degree),minute,sec); +} + +double parseHMSStr(const char* str) +{ + char* hms = dupstr(str); // its going to get clobbered + char* ptr = hms; + + int sign = 1; + int hour = atoi(strtok(ptr,"h")); + int minute = atoi(strtok(NULL,"m")); + float second = atof(strtok(NULL,"s")); + + // assumes the minus sign is the first char + if (hour != 0) + sign = hour>0 ? 1 : -1; + else + sign = str[0] == '-' ? -1 : 1; + + delete [] hms; + + return dmsToDegree(sign,abs(hour),minute,second)/24.*360.; +} + +double parseDMSStr(const char* str) +{ + char* dms = dupstr(str); // its going to get clobbered + char* ptr = dms; + + int sign = 1; + int degree = atoi(strtok(ptr,"d")); + int minute = atoi(strtok(NULL,"m")); + float sec = atof(strtok(NULL,"s")); + + // assumes the minus sign is the first char + if (degree != 0) + sign = degree>0 ? 1 : -1; + else + sign = str[0] == '-' ? -1 : 1; + + delete [] dms; + + return dmsToDegree(sign,abs(degree),minute,sec); +} + +double RGB2Gray(double red, double green, double blue) +{ + return 0.30*red + 0.59*green + 0.11*blue; +} + +unsigned char RGB2Gray(unsigned char red, unsigned char green, + unsigned char blue) +{ + // we have a round off problem here, add FLT_EPSILON to kick it over + return (unsigned char)(0.30*red + 0.59*green + 0.11*blue + FLT_EPSILON); +} + +void RGB2CMYK(unsigned char red, unsigned char green, unsigned char blue, + unsigned char* cyan, unsigned char* magenta, + unsigned char* yellow, unsigned char* black) +{ + // convert To CMY + + *cyan = UCHAR_MAX-red; + *magenta = UCHAR_MAX-green; + *yellow = UCHAR_MAX-blue; + *black =0; + + // determine black + + *black = UCHAR_MAX; + if (*cyan < *black) + *black = *cyan; + if (*magenta < *black) + *black = *magenta; + if (*yellow < *black) + *black = *yellow; + + // substract out black + + *cyan -= *black; + *magenta -= *black; + *yellow -= *black; +} + +void RGB2CMYK(unsigned short red, unsigned short green, unsigned short blue, + unsigned short* cyan, unsigned short* magenta, + unsigned short* yellow, unsigned short* black) +{ + // convert To CMY + + *cyan = USHRT_MAX-red; + *magenta = USHRT_MAX-green; + *yellow = USHRT_MAX-blue; + *black =0; + + // determine black + + *black = USHRT_MAX; + if (*cyan < *black) + *black = *cyan; + if (*magenta < *black) + *black = *magenta; + if (*yellow < *black) + *black = *yellow; + + // substract out black + + *cyan -= *black; + *magenta -= *black; + *yellow -= *black; +} + +ostream& psColorGray(XColor* clr, ostream& str) +{ + if (clr) { + float red = clr->red/float(USHRT_MAX); + float green = clr->green/float(USHRT_MAX); + float blue = clr->blue/float(USHRT_MAX); + str << dec << RGB2Gray(red,green,blue); + } + + return str; +} + +ostream& psColorRGB(XColor* clr, ostream& str) +{ + if (clr) { + float red = clr->red/float(USHRT_MAX); + float green = clr->green/float(USHRT_MAX); + float blue = clr->blue/float(USHRT_MAX); + str << dec << red << ' ' << green << ' ' << blue; + } + + return str; +} + +ostream& psColorCMYK(XColor* clr, ostream& str) +{ + if (clr) { + unsigned short cyan; + unsigned short magenta; + unsigned short yellow; + unsigned short black; + + RGB2CMYK(clr->red, clr->green, clr->blue, &cyan, &magenta, &yellow, &black); + + str << dec + << cyan/float(USHRT_MAX) << ' ' + << magenta/float(USHRT_MAX) << ' ' + << yellow/float(USHRT_MAX) << ' ' + << black/float(USHRT_MAX); + } + return str; +} + +char* psStr = NULL; // psQuote returned string +char* psQuote(const char* str) +{ + // we must must quote '(', ')', and '\' + if (psStr) + delete [] psStr; + + psStr = new char[strlen(str)*2+1]; // worst case size + + char* out = psStr; + const char* in = str; + while (in && *in) { + if (*in == '(' || *in == ')' || *in == '\\') + *out++ = '\\'; + *out++ = *in++; + } + + *out++ = '\0'; // terminating char + return psStr; +} + +const char* psFontName(const char* font) +{ + char* str = (char*)font; + char* ff = str; + while (*str && *str++ != ' '); + // char* zz = str; + while (*str && *str++ != ' '); + char* ww = str; + while (*str && *str++ != ' '); + char* ss = str; + + if (ff && ww && ss) + return psFontName(ff,ww,ss); + else + return psFonts[0]; +} + +int psFontSize(const char* font) +{ + char* str = (char*)font; + while (*str && *str++ != ' '); + return atoi(str); +} + +const char* psFontName(const char* font, const char* weight, const char* slant) +{ + int ptr = 0; + if (!strncmp(font,"helvetica",4)) + ptr = 0; + else if (!strncmp(font,"times",4)) + ptr = 4; + else if (!strncmp(font,"courier",4)) + ptr = 8; + + if (!strncmp(weight,"normal",4)) + ; + else if (!strncmp(weight,"bold",4)) + ptr +=2; + + if (!strncmp(slant,"roman",4)) + ; + else if (!strncmp(slant,"italic",4)) + ptr++; + + return psFonts[ptr]; +} + +int fCompare(const void* a, const void* b) +{ + float* aa = (float*)a; + float* bb = (float*)b; + + if (*aa < *bb) + return -1; + if (*aa > *bb) + return 1; + return 0; +} + +int dCompare(const void* a, const void* b) +{ + double* aa = (double*)a; + double* bb = (double*)b; + + if (*aa < *bb) + return -1; + if (*aa > *bb) + return 1; + return 0; +} + +Vector mapLen(const Vector& v, const Matrix& mx) +{ + // remove translation + Vector t = Vector() * mx; + Matrix sr = mx * Translate(-t); + + // remove rotation + Vector r = Vector(1,0) * sr; + Matrix s = sr * Rotate(r.angle()); + + // all that is left is Scaling + return (v*s).abs(); +} + +#if defined (MAC_OSX_TK) || (_WIN32) + +int XSetClipRectangles(Display *d, GC gc, int clip_x_origin, int clip_y_origin, + XRectangle* rectangles, int n, int ordering) +{ + TkRegion clipRgn = TkCreateRegion(); + + while (n--) { + XRectangle rect = *rectangles; + + rect.x += clip_x_origin; + rect.y += clip_y_origin; + TkUnionRectWithRegion(&rect, clipRgn, clipRgn); + rectangles++; + } + TkSetRegion(d, gc, clipRgn); + TkDestroyRegion(clipRgn); + return 1; +} + +#endif diff --git a/tksao/util/util.h b/tksao/util/util.h new file mode 100644 index 0000000..383095a --- /dev/null +++ b/tksao/util/util.h @@ -0,0 +1,125 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __util_h__ +#define __util_h__ + +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <float.h> +#include <math.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include "fuzzy.h" +#include "vector.h" + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#ifdef _WIN32 +#include <win32lib.h> +#endif + +#ifdef MAC_OSX_TK +#include <macosxlib.h> +void XXWarpPointer(Display* display, Window src_w, Window dest_w, + int src_x, int src_y, + unsigned int src_width, unsigned int src_height, + int dest_x, int dest_y); +#endif + +#if defined (MAC_OSX_TK) || (_WIN32) +int XSetClipRectangles(Display *d, GC gc, int clip_x_origin, int clip_y_origin, + XRectangle* rectangles, int n, int ordering); +#endif + +#define STRCMP(which,str,cnt) (!strncmp(toConstLower(which), str, cnt) && strlen(which)==cnt) + +static const char psFonts[12][32] = { + {"Helvetica"}, + {"Helvetica-Oblique"}, + {"Helvetica-Bold"}, + {"Helvetica-BoldOblique"}, + + {"Times-Roman"}, + {"Times-Italic"}, + {"Times-Bold"}, + {"Times-BoldItalic"}, + + {"Courier"}, + {"Courier-Oblique"}, + {"Courier-Bold"}, + {"Courier-BoldOblique"} +}; + +#ifndef __CYGWIN__ +static const double M_TWOPI = 2*M_PI; +#endif +static const double M_THREEPI = 3*M_PI; +static const double M_FOURPI = 4*M_PI; + +extern int maperr; + +extern int lsb(); + +extern void swap2(char* src, char* dest); +extern void swap4(char* src, char* dest); +extern void swap8(char* src, char* dest); + +// defined in ds9.C +extern void internalError(const char*); + +extern char* dupstr(const char*); +extern char* trim(const char*); +extern char* toLower(const char*); +extern char* toUpper(const char*); +extern char* toConstLower(const char*); +extern char* toConstUpper(const char*); + +extern double zeroTWOPI(double); +extern double zero360(double); +extern double m180To180(double); +extern double degToRad(double); +extern double radToDeg(double); + +extern int parseSection(char*, Vector*, Vector*); + +extern double dmsToDegree(int, int, int, double); +extern double parseSEXStr(const char*); +extern double parseHMSStr(const char*); +extern double parseDMSStr(const char*); + +extern double RGB2Gray(double, double, double); +extern unsigned char RGB2Gray(unsigned char, unsigned char, unsigned char); +extern void RGB2CMYK(unsigned char, unsigned char, unsigned char, + unsigned char*, unsigned char*, unsigned char*, + unsigned char*); +extern void RGB2CMYK(unsigned short, unsigned short, unsigned short, + unsigned short*, unsigned short*, unsigned short*, + unsigned short*); +extern ostream& psColorGray(XColor*, ostream&); +extern ostream& psColorRGB(XColor*, ostream&); +extern ostream& psColorCMYK(XColor*, ostream&); + +extern char* psQuote(const char*); + +extern const char* psFontName(const char*); +extern int psFontSize(const char*); +extern const char* psFontName(const char*, const char*, const char*); + +extern int fCompare(const void*, const void*); +extern int dCompare(const void*, const void*); + +extern Vector mapLen(const Vector& v, const Matrix& mx); + +#endif |