/* @(#)ag_gtxt.c 17.1.1.1 (ES0-DMD) 01/25/02 17:33:30 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* @(#)ag_gtxt.c 17.1.1.1 (OAA-ASTRONET) 01/25/02 17:33:30 */ /* * HEADER : ag_gtxt.c - Vers 3.6.001 - Sep 1993 - L. Fini, OAA * - Vers 3.6.000 - Oct 1991 - L. Fini, OAA * * * C INTERFACE MODULE */ #include #include /*****************************************************************************/ /*++ AG_GTXT (Internal AGL Use) */ /* AG_GTXT Draw text */ /* Text drawing routine. String dimension and orientation can be set via */ /* AG_SSET. Relative string position with respect to the given point can be */ /* specified by the center index argument as shown in the following figure */ /* where a box supposed to enclose the string is sketched. */ /* 22 21 20 19 18 */ /* +-----+-------------------+--------------------+-----+ */ /* | | | | | */ /* | | | | | */ /* | | | | | */ /* | 7| 6| |5 | */ /* 23+-----+ *** **** ****+ **** ***** *****+-----+17 */ /* | |* * * * * * * * * | | */ /* | |* * * * * * * * * | | */ /* | |***** **** * * * *** *** | | */ /* | |* * * * * * * * * | | */ /* | |* * * * * * * * * | | */ /* | |* * **** *** **** ***** * | | */ /* | 8| | |4 | */ /* 24+-----+- -+0 -+-----+16 */ /* | | | | | */ /* | | **** * * *** *** * * * | | */ /* | |* * * * * * * * | | */ /* | |* * * * * * * * | | */ /* | |* ** ***** * * ** * | | */ /* | |* * * * * * * * * | | */ /* | |* * * * * * * * * | | */ /* 9+-----+ **** * * *** + *** * * *****+-----+15 */ /* | 1| 2| |3 | */ /* | | | | | */ /* | | | | | */ /* | | | | | */ /* | | | | | */ /* +-----+-------------------+--------------------+-----+ */ /* 10 11 12 13 14 */ /* */ /* Note: The vertical offset of displacement codes 10,11,12,13,14 and 18,19, */ /* 20,21,22 is the character height. The horizontal offset of codes: */ /* 14,15,16,17,18 and 22,23,24,9,10, is equal to the character width. */ /* The positioning and newline is made with respect to the current */ /* character size and could be different than exepected if character */ /* size is modified by the related metacharacter sequences (see below).*/ /* The coordinate values are referred to the current graphic mode (either */ /* NORMALIZED, USER or SPECIAL) and mapped accordingly. Graphic mode is */ /* affected by: AG_WDEF, AG_TRNS, and AG_SSET items "NORMAL","USER" and */ /* "SPECIAL" */ /* The text drawing routine provides for interpretation of the following */ /* metacharacter: */ /* \{ - Begin grouping */ /* \} - End grouping */ /* \^ - move the following part of the string up by half a character */ /* \_ - move the following part of the string down by half a character*/ /* \< - Backspace by a single character */ /* \+ - Increase character size by 20% (1) */ /* \- - Decrease character size by 20% (1) */ /* \! - Force interpretation of the following part as a metasequence */ /* (this is needed to allow metasequences starting with 'n' not */ /* to be interpreted as newlines) */ /* \0 - select font 0 (Default font) (1,2) */ /* \1 - select font 1 (Quality roman font) (1,2) */ /* \2 - select font 2 (Greek font) (1,2) */ /* \3 - select font 3 (Script font) (1,2) */ /* \4 - select font 4 (Old English) (1,2) */ /* \5 - select font 5 (Tiny roman font) (1,2) */ /* \[ - Increase line width (bolding) (4) */ /* \] - Decrease line width (bolding) (4) */ /* \# - Draw marker number into the line (3) */ /* \n - Perform a "newline" */ /* ~~ - Draw a single '~' character */ /* \~ - Draw a single '~' character */ /* ~\ - Draw a single '\' character */ /* \\ - Draw a single '\' character */ /* The above "single character" instructions MUST NOT BE FOLLOWED BY BLANK */ /* The character '~' can also be used instead of '\' as metacharacter flag */ /* The '~' is more suited to C programs where '\' has a special meaning. */ /* All selections made by metacharacters are valid from the point in the */ /* string where they are defined up either to the end of current group (the */ /* part of the string enclosed in \{..\}) or to the end of the string */ /* Note 1: The same action of this metacharacter commands can be selected */ /* permanently via the suitable AG_SSET command */ /* Note 2: Correspondance of font characters (and ASCII codes) can be obtai- */ /* ned by running the test program "fonts" */ /* Note 3: This function allows to include a marker symbol within a text */ /* string. See routine AG_GPLM for the defined marker symbols. */ /* The syntax for includeing markers is sligtly different from the */ /* one used in AGL vers. 3.5x !! */ /* Note 4: This functions are optionally supported by device drivers. */ /* AGL also interprets a set of 'TEX like' keywords as listed below. */ /* Unfortunately, due to the fact that most of them require special */ /* characters to be shown, only the names are listed, while the exact */ /* meaning can only be seen by means of the "fonts" program, which is */ /* created as part of the standard AGL installation procedure. */ /* If the metacharacter sequence is more than one character long (escape */ /* not included, of course), it MUST BE FOLLOWED BY A BLANK SPACE. */ /* \AA \Alpha \Aquarius \Aries */ /* \Beta \Cancer \Capricorn \Chi */ /* \Delta \Earth \Epsilon \Eta */ /* \Gamma \Gemini \Iota \Jupiter */ /* \Kappa \Lambda \Leo \Libra */ /* \Mars \Mercury \Moon \Mu */ /* \Neptune \Nu \Omega \Omicron */ /* \PI \Phi \Pisces \Pluto */ /* \Psi \Rho \Sagittarius \Saturn */ /* \Scorpio \Sigma \Sqrt \Tau */ /* \Taurus \Theta \Upsilon \Uranus */ /* \Venus \Virgo \Xi \Zeta */ /* \aleph \alpha \asteroid \beta */ /* \bigcirc \black \blue \cent */ /* \chi \circ \cyan \clover */ /* \clubsuit \comet \dag \ddag */ /* \default \delta \diamond \div */ /* \downarro \epsilon \equinox \equiv */ /* \eta \firtree \gamma \ge */ /* \greek \green \hbar \heart */ /* \infty \int \iota \italic */ /* \kappa \lambda \larrow \le */ /* \magenta \mp \mu \!nabla */ /* \!ne \!nu \odot \oint */ /* \old \omega \omicron \oplus */ /* \otimes \palmtree \paragraph \parallel */ /* \partial \perp \phi \pi */ /* \pm \propto \psi \red */ /* \rho \rightarrow \roman \script */ /* \shield \sigma \snow \spade */ /* \sqrt \sum \tau \theta */ /* \times \tiny \uparrow \upsilon */ /* \varepsilon \varphi \vartheta \white */ /* \xi \yellow \zeta */ /* When specifying metasequences the minimum number of characters required */ /* for matching may be used. */ /* The "!" character in front of sequences starting with "n" is required to */ /* avoid the interpretation as newline single character sequence. */ void AG_GTXT (xc,yc,text,centre) double xc,yc; /* String position */ char *text; /* String to draw (max 132 chars) */ int centre; /* Centre index (see above) */ /*--*/ { static char *modnam = "GTXT"; double xstart=xc, ystart=yc; char *chstrg = text; int font; int the_color,was_color; float hoffset,voffset; int curlwdt; struct AGL_char my_char; double twd,thg,cwd,chg; double rescalx, rescaly; DEFINE_AGLDVCOM; AG_DMSG(modnam,(char *)0); font = DY(curfont); if((centre<0) ||(centre>24)) { AGL_puterr(ILLPOSWNG,modnam); centre=1; } #ifndef NO_METAFILE_SUPPORT if ( DY(filact) == SOFTMETAFILE ) { int nc=strlen(chstrg); int is; float xxx[2]; enum METACODE cod = MFGTXT; xxx[0]=xc; xxx[1]=yc; is = fwrite((void *)&cod,sizeof(int),1,DY(metafile)); is = fwrite((void *)xxx,sizeof(float),2,DY(metafile)); is = fwrite((void *)¢re,sizeof(int),1,DY(metafile)); is = fwrite((void *)&nc,sizeof(int),1,DY(metafile)); is = fwrite((void *)chstrg,sizeof(char),nc,DY(metafile)); if(is != nc) AGL_puterr(MFWRITERR,modnam); } #endif if(AGL_status.curvwp == VWPEMPTY) { AGL_puterr(NOVWPERR,modnam); return; } if(DY(modeflag)!=NORMAL) AGL_cnvt(&xstart,&ystart); /* Convert reference coordinates */ AGL_strd(chstrg,font,&twd,&thg); /* Compute text dimensions */ AGL_strd("X",font,&cwd,&chg); /* Compute character dimensions */ switch(centre) { /* compute horizontal offset */ /* value is in "pixels" */ case 9: case 10: case 22: case 23: case 24: hoffset = cwd; break; case 0: case 2: case 6: case 12: case 20: hoffset = -(twd*0.5); break; case 3: case 4: case 5: case 13: case 19: hoffset = -twd; break; case 14: case 15: case 16: case 17: case 18: hoffset = -(twd + cwd); break; case 1: case 7: case 8: case 11: case 21: default: hoffset = 0.0; break; } switch(centre) { /* compute vertical offset */ /* value is in "pixels" */ case 10: case 11: case 12: case 13: case 14: voffset = thg; break; case 0: case 4: case 8: case 16: case 24: voffset = thg*0.5 - chg; break; case 5: case 6: case 7: case 17: case 23: voffset = -chg; break; case 18: case 19: case 20: case 21: case 22: voffset = -(chg*2.0); break; case 1: case 2: case 3: case 9: case 15: voffset = thg-chg; break; } rescalx = rescaly = DY(scale) * CHARMULT(AGL_status.devid); rescalx *= DY(chrhsize) * RSLX(AGL_status.devid); rescaly *= DY(chrvsize) * RSLY(AGL_status.devid); hoffset *= rescalx; /* Scale and normalize */ voffset *= rescaly; AG_TSET(0.0,0.0,DY(changle),3); /* Rotate character offset */ AG_TROT(&hoffset,&voffset,1); xstart += hoffset; /* Drawing starts here */ ystart += voffset; AGL_status.errstat = AGLNOERR; my_char.modifier.mfact = 1.0; my_char.modifier.font = font; my_char.modifier.lwdt = DY(textlw); my_char.modifier.vshift=0.0; my_char.modifier.backspace=0; my_char.modifier.newline=0; my_char.modifier.slant=0.0; the_color=DY(color); was_color=the_color; my_char.modifier.color=the_color; curlwdt = DY(lwidth); hoffset=0.0; /* Reuse hoffset and voffset */ voffset=0.0; while ((chstrg=AGL_mchar(chstrg,&my_char))!=NULL) { int i; double xpos,ypos; double factx= rescalx * my_char.modifier.mfact; double facty= rescaly * my_char.modifier.mfact; float advance,haux,vaux; if(my_char.modifier.color!=the_color) { /* change color */ the_color=my_char.modifier.color; DY(color)=the_color; AGL_sclr(); } if(my_char.modifier.lwdt != curlwdt) { /* change line width */ AGL_swdt(my_char.modifier.lwdt); /* if required */ curlwdt=my_char.modifier.lwdt; } advance= factx*my_char.descriptor.width; if(my_char.modifier.newline>0) { hoffset = 0.0; voffset -= my_char.descriptor.heigth*facty*2.0; my_char.modifier.vshift = 0; } if(my_char.modifier.backspace>0) hoffset -= my_char.modifier.backspace*advance; haux=hoffset; vaux=voffset + my_char.modifier.vshift * my_char.descriptor.heigth * facty; AG_TSET(0.0,0.0,0.0,1); AG_TROT(&haux,&vaux,1); RBUFFR(0)=xstart+haux; /* Allow even rounding of coord. */ RBUFFR(1)=ystart+vaux; IBUFFR(0)=6; CHANNEL = DY(curchan); INITFUNCT(AGLDVCOM); xpos=RBUFFR(0); /* xpos,ypos are the coordinates */ ypos=RBUFFR(1); /* of the "closest" pixel */ AG_TSET(xpos,ypos,0.0,1); AGL_ch2pl(&my_char,1); for(i=0;i