home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xvertext / part01 < prev    next >
Encoding:
Text File  |  1993-04-27  |  46.6 KB  |  1,729 lines

  1. Newsgroups: comp.sources.x
  2. From: mppa3@syma.sussex.ac.uk (Alan Richardson)
  3. Subject: v19i073:  xvertext - functions for drawing text at ANY ANGLE in an X window, Part01/01
  4. Message-ID: <1993Apr4.003759.2031@sparky.imd.sterling.com>
  5. X-Md4-Signature: 46155073a9f74abae8a50ab17627deea
  6. Date: Sun, 4 Apr 1993 00:37:59 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: mppa3@syma.sussex.ac.uk (Alan Richardson)
  10. Posting-number: Volume 19, Issue 73
  11. Archive-name: xvertext/part01
  12. Environment: X11
  13.  
  14. [There is no Imakefile with this submission.]
  15. [    Chris Olson                            ]
  16. # Submission to comp.sources.x
  17. #
  18. # This is part 1/1 of xvertext.3.0
  19. #
  20. # Use: functions for drawing text at ANY ANGLE in an X window
  21. #                                    ^^^^^^^^^
  22. #
  23. ############################################################################
  24.  
  25.  
  26. # This is a shell archive.  Remove anything before this line,
  27. # then unpack it by saving it in a file and typing "sh file".
  28. #
  29. # Wrapped by Alan Richardson <mppa3@hp720> on Wed Mar 31 21:27:33 1993
  30. #
  31. # This archive contains:
  32. #    xvertext.3.0    
  33. #
  34.  
  35. LANG=""; export LANG
  36. PATH=/bin:/usr/bin:$PATH; export PATH
  37.  
  38. echo mkdir - xvertext.3.0
  39. mkdir xvertext.3.0
  40.  
  41. echo x - xvertext.3.0/example.c
  42. cat >xvertext.3.0/example.c <<'@EOF'
  43. /**************************************************************************/
  44. /*                                                                        */
  45. /*                                                                        */
  46. /* This is an example program designed to utilise and manipulate the      */
  47. /* `xvertext' routines.                                                   */
  48. /*                                                                        */
  49. /* Version 3.0                                                            */
  50. /*                                                                        */
  51. /* Copyright (c) 1993 Alan Richardson (mppa3@uk.ac.sussex.syma)           */
  52. /*                                                                        */
  53. /*                                                                        */
  54. /* ********************************************************************** */
  55.  
  56.  
  57. #include <X11/Xlib.h>
  58. #include <X11/Xutil.h>
  59. #include <stdio.h>
  60. #include <math.h>
  61. #include "rotated.h"
  62.  
  63.  
  64. /* ---------------------------------------------------------------------- */
  65.  
  66.  
  67. extern char *getenv();
  68. unsigned long AllocNamedColor();
  69. void DrawRosette();
  70. void DrawAlignments();
  71. void DrawRandom();
  72.  
  73.  
  74. /* ---------------------------------------------------------------------- */
  75.  
  76.  
  77. GC gc;
  78. Display *dpy;
  79. Window window;
  80. int depth, screen;
  81. unsigned long white, black;
  82.  
  83. #define NCOLORS 9
  84.  
  85. char *colors[]={
  86.     "white", "red", "orange", "yellow", "green", "cyan",
  87.     "blue", "violet", "wheat"
  88. };
  89.  
  90.  
  91. /* ---------------------------------------------------------------------- */
  92.  
  93.  
  94. /**************************************************************************/
  95. /* Allocate a colour from the default colour map                          */
  96. /**************************************************************************/
  97.  
  98. unsigned long AllocNamedColor(colname)  
  99.     char *colname;    
  100. {
  101.     XColor scrncol, excol;
  102.     
  103.     if(depth==1)
  104.     return white;
  105.     
  106.     if(XAllocNamedColor(dpy, DefaultColormap(dpy, screen), colname,
  107.             &scrncol, &excol))
  108.     return scrncol.pixel;
  109.     
  110.     else
  111.     return white;
  112. }
  113.  
  114.  
  115. /* ---------------------------------------------------------------------- */
  116.  
  117.  
  118. /**************************************************************************/
  119. /* Main routine                                                           */
  120. /**************************************************************************/
  121.  
  122. main()
  123. {
  124.     XEvent ev;
  125.     char *host;
  126.     char buf[1];
  127.     int mode=0;
  128.     float version;
  129.     char copyright[100];
  130.     
  131.     /* get copyright information */
  132.     version=XRotVersion(copyright, 100);
  133.     fprintf(stderr, "%s - version %.1f\n", copyright, version);
  134.     
  135.     /* establish connection to display */
  136.     if((host=getenv("DISPLAY"))==NULL) {
  137.     fprintf(stderr,"can't connect to host\n");
  138.     exit(1); 
  139.     }
  140.     
  141.     /* open connection to display */
  142.     if((dpy=XOpenDisplay(host))==NULL) {
  143.     fprintf(stderr,"can't open display\n");
  144.     exit(1); 
  145.     }
  146.     
  147.     /* useful macros */
  148.     screen=DefaultScreen(dpy);
  149.     depth=DefaultDepth(dpy, screen);
  150.     
  151.     white=WhitePixel(dpy, screen);
  152.     black=BlackPixel(dpy, screen);
  153.  
  154.     /* create a window */
  155.     window=XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 600, 600,
  156.              0, depth, InputOutput, DefaultVisual(dpy, screen),
  157.              0, NULL);
  158.     
  159.     XSelectInput(dpy, window, ExposureMask|KeyPressMask);
  160.     XSetWindowBackground(dpy, window, black);
  161.     XMapWindow(dpy, window);
  162.     
  163.     /* create a GC */
  164.     gc=XCreateGC(dpy, window, NULL, 0);
  165.  
  166.     /* simple event loop */
  167.     for(;;) {
  168.     XNextEvent(dpy, &ev);
  169.     
  170.     /* process each event */
  171.     switch(ev.type) {
  172.       case Expose:
  173.         if(ev.xexpose.count==0) {
  174.         /* redraw screen on expose event */
  175.         XClearWindow(dpy, window);
  176.         if(mode==0)
  177.             DrawRosette();
  178.         else if(mode==1)
  179.             DrawAlignments();
  180.         else
  181.             DrawRandom();
  182.         }
  183.         break;
  184.         
  185.       case KeyPress: 
  186.         XLookupString(&ev.xkey, buf, 1, NULL, NULL);
  187.         /* quit if `q' pressed */
  188.         if(buf[0]=='q' || buf[0]=='Q')
  189.         exit(0);
  190.         else {
  191.         /* go to next screen */
  192.         mode=(++mode)%3;
  193.  
  194.         /* draw next screen */
  195.         XClearWindow(dpy, window);
  196.         if(mode==0)
  197.                     DrawRosette();
  198.                 else if(mode==1)
  199.                     DrawAlignments();
  200.         else
  201.             DrawRandom();
  202.         }
  203.         break;
  204.         
  205.       default:
  206.         break;  
  207.     }
  208.     }
  209. }
  210.  
  211.  
  212. /* ---------------------------------------------------------------------- */
  213.  
  214.  
  215. /**************************************************************************/
  216. /* Draw an `Adobe PostScript'-style word rosette                          */
  217. /**************************************************************************/
  218.  
  219. void DrawRosette()
  220. {
  221.     int i;
  222.     XFontStruct *font;
  223.     char *str="Just like PostScript?";
  224.     char *fontname=
  225.     "-adobe-helvetica-medium-o-normal--24-240-75-75-p-130-iso8859-1";
  226.     
  227.     /* load the font */
  228.     font=XLoadQueryFont(dpy, fontname);
  229.     if(font==NULL) {
  230.         fprintf(stderr, "no font `%s'\n", fontname);
  231.         font=XLoadQueryFont(dpy, "fixed");
  232.     }
  233.     
  234.     /* loop through each angle */
  235.     for(i=0; i<16; i++) {
  236.     XSetForeground(dpy, gc, AllocNamedColor(colors[i%NCOLORS]));
  237.     XRotDrawAlignedString(dpy, font, (float)(360*i/16), window, 
  238.                   gc, 300, 270, str, MLEFT);
  239.     }    
  240.  
  241.     XSetForeground(dpy, gc, white);
  242.     XSetBackground(dpy, gc, black);
  243.     XRotDrawAlignedImageString(dpy, font, 0., window, gc, 300, 590,
  244.                    "Press any key to continue...", BCENTRE);
  245. }
  246.  
  247.  
  248. /* ---------------------------------------------------------------------- */
  249.  
  250.  
  251. /**************************************************************************/
  252. /* Demonstrate alignment of blocks of text                                */
  253. /**************************************************************************/
  254.  
  255. void DrawAlignments()
  256. {
  257.     int i;
  258.     int align, x, y;
  259.     XFontStruct *font;
  260.     char *str="Many\nalignments\nare\npossible";
  261.     char *fontname="-adobe-times-bold-r-normal--18-180-75-75-p-99-iso8859-1";
  262.     
  263.     /* load the font */
  264.     font=XLoadQueryFont(dpy, fontname);
  265.     if(font==NULL) {
  266.     fprintf(stderr, "no font `%s'\n", fontname);
  267.     font=XLoadQueryFont(dpy, "fixed");
  268.     }
  269.     
  270.     if(depth==1)
  271.         XSetBackground(dpy, gc, black);
  272.     else
  273.         XSetBackground(dpy, gc, AllocNamedColor("red"));
  274.  
  275.     /* loop through nine positions */
  276.     for(i=0; i<9; i++) {
  277.     /* alignment */
  278.     if(i%3==0)
  279.         align=BRIGHT;
  280.     else if(i%3==1)
  281.         align=MCENTRE;
  282.     else
  283.         align=TLEFT;
  284.     
  285.     /* position */
  286.     x=(i%3)*200+100;
  287.     y=(i/3)*200+100;
  288.     
  289.     /* draw some crosshairs */
  290.     XSetForeground(dpy, gc, AllocNamedColor("yellow"));
  291.     XDrawLine(dpy, window, gc, x-30, y, x+30, y);
  292.     XDrawLine(dpy, window, gc, x, y+30, x, y-30);
  293.  
  294.     /* draw the text */
  295.     XSetForeground(dpy, gc, AllocNamedColor("cyan"));
  296.     XRotDrawAlignedImageString(dpy, font, 120.*(float)(i/3),
  297.                    window, gc, x, y, str, align);
  298.     }
  299.  
  300.     XSetForeground(dpy, gc, white);
  301.     XSetBackground(dpy, gc, black);
  302.     XRotDrawAlignedImageString(dpy, font, 0., window, gc, 300, 590,
  303.                    "Press any key to continue...",BCENTRE);
  304. }
  305.  
  306.  
  307. /* ---------------------------------------------------------------------- */
  308.  
  309.  
  310. /**************************************************************************/
  311. /* Draw strings at random positions/orientations                          */
  312. /**************************************************************************/
  313.  
  314. void DrawRandom()
  315. {
  316.     int i;
  317.     XFontStruct *font[6];
  318.     char *str="Rotated Text!";
  319.     static char *fontnames[]={
  320.     "-adobe-courier-bold-o-normal--18-180-75-75-m-110-iso8859-1",
  321.     "-adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1",
  322.     "-adobe-helvetica-bold-r-normal--24-240-75-75-p-138-iso8859-1",
  323.     "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1",
  324.     "-adobe-times-bold-i-normal--18-180-75-75-p-98-iso8859-1",
  325.     "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1"
  326.     };
  327.     
  328.  
  329.     /* load all fonts first */
  330.     for(i=0; i<6; i++) {
  331.     font[i]=XLoadQueryFont(dpy, fontnames[i]);
  332.     if(font[i]==NULL) {
  333.         fprintf(stderr, "no font `%s'\n", fontnames[i]);
  334.         font[i]=XLoadQueryFont(dpy, "fixed");
  335.     }
  336.     }
  337.  
  338.     if(depth==1)
  339.         XSetBackground(dpy, gc, black);
  340.     else
  341.         XSetBackground(dpy, gc, AllocNamedColor("grey"));
  342.  
  343.     /* do lots of strings */
  344.     for(i=0; i<75; i++) {
  345.     /* random color */
  346.     XSetForeground(dpy, gc, AllocNamedColor(colors[rand()%NCOLORS]));
  347.  
  348.     /* draw string */
  349.     if(rand()%1000>500)
  350.         XRotDrawString(dpy, font[rand()%6],
  351.                (float)(rand()%100)*360./100.,
  352.                window, gc, rand()%600, rand()%600, str);
  353.     else
  354.         XRotDrawImageString(dpy, font[rand()%6], 
  355.                 (float)(rand()%100)*360./100.,
  356.                 window, gc, rand()%600, rand()%600, str);
  357.     }    
  358.  
  359.     XSetForeground(dpy, gc, white);
  360.     XSetBackground(dpy, gc, black);
  361.     XRotDrawAlignedImageString(dpy, font[2], 0., window, gc, 300, 590,
  362.                    "Press any key to continue...", BCENTRE);
  363. }
  364. @EOF
  365.  
  366. chmod 600 xvertext.3.0/example.c
  367.  
  368. echo x - xvertext.3.0/Makefile
  369. cat >xvertext.3.0/Makefile <<'@EOF'
  370. #############################################################################
  371.  
  372.  
  373. # Makefile for xvertext version 3.0
  374.  
  375.  
  376. #############################################################################
  377.  
  378.  
  379. # Nuthin' fancy:
  380.  
  381.  
  382.                  CC = cc
  383.              CFLAGS = -O
  384.  
  385.  
  386. #############################################################################
  387.  
  388.  
  389. # This is where the library and header files will go, if you use
  390. #  `make install' to install them. Change as required:
  391.  
  392.  
  393.           THELIBDIR = ./lib
  394.           THEINCDIR = ./include
  395.  
  396.  
  397. # This is where the manual pages will go:
  398. # (you'll want something ending in man/man3 since the manual page
  399. #  for `foo' will be installed as `foo.3')
  400.  
  401.  
  402.           THEMANDIR = ./man/man3
  403.  
  404.  
  405. #############################################################################
  406.  
  407.  
  408. # On a HP9000s300 you probably need to add `-lmalloc' to the end of this,
  409. # or it might core dump:
  410.  
  411.  
  412.                LIBS = -lX11 -lm 
  413.  
  414.  
  415. #############################################################################
  416.  
  417. # No user servicable parts below!
  418.  
  419. #############################################################################
  420.  
  421.  
  422.      OBJS = rotated.o example.o
  423.     SHELL = /bin/sh
  424.  
  425. example: $(OBJS)
  426.     $(CC) $(CFLAGS) -o example $(OBJS) $(LIBS)
  427.  
  428. lib: rotated.o
  429.     rm -f libXrot.a
  430.     ar cq libXrot.a rotated.o 
  431.     ranlib libXrot.a
  432.  
  433. install: example
  434.     rm -f libXrot.a
  435.     ar cq libXrot.a rotated.o
  436.     ranlib libXrot.a  
  437.     @if [ -d $(THELIBDIR) ]; then set +x; \
  438.     else (set -x; mkdir $(THELIBDIR)); fi
  439.     cp libXrot.a $(THELIBDIR)
  440.     @if [ -d $(THEINCDIR) ]; then set +x; \
  441.     else (set -x; mkdir $(THEINCDIR)); fi
  442.     cp rotated.h $(THEINCDIR)
  443.     @if [ -d $(THEMANDIR) ]; then set +x; \
  444.     else (set -x; mkdir $(THEMANDIR)); fi
  445.     cp man/XRotDrawAlignedString.3 $(THEMANDIR)/XRotDrawAlignedImageString.3
  446.     cp man/XRotDrawAlignedString.3 $(THEMANDIR)/XRotDrawAlignedString.3
  447.     cp man/XRotDrawAlignedString.3 $(THEMANDIR)/XRotDrawImageString.3
  448.     cp man/XRotDrawAlignedString.3 $(THEMANDIR)/XRotDrawString.3
  449.     cp man/XRotVersion.3 $(THEMANDIR)/XRotVersion.3
  450.     cp man/xvertext.3 $(THEMANDIR)/xvertext.3
  451.  
  452. clean:
  453.     rm -f $(OBJS) example example~ libXrot.a
  454.  
  455. $(OBJS): rotated.h
  456.  
  457. @EOF
  458.  
  459. chmod 600 xvertext.3.0/Makefile
  460.  
  461. echo x - xvertext.3.0/rotated.h
  462. cat >xvertext.3.0/rotated.h <<'@EOF'
  463. /* ************************************************************************ */
  464.  
  465.  
  466. /* Header file for the `xvertext 3.0' routines.
  467.  
  468.    Copyright (c) 1993 Alan Richardson (mppa3@uk.ac.sussex.syma) */
  469.  
  470.  
  471. /* ************************************************************************ */
  472.  
  473.  
  474. #ifndef _XVERTEXT_INCLUDED_ 
  475. #define _XVERTEXT_INCLUDED_
  476.  
  477.  
  478. #define XV_VERSION      3.0
  479. #define XV_COPYRIGHT    "xvertext routines Copyright (c) 1993 Alan Richardson"
  480.  
  481.  
  482. /* ---------------------------------------------------------------------- */
  483.  
  484.  
  485. /* text alignment */
  486.  
  487. #define NONE             0
  488. #define TLEFT            1
  489. #define TCENTRE          2
  490. #define TRIGHT           3
  491. #define MLEFT            4
  492. #define MCENTRE          5
  493. #define MRIGHT           6
  494. #define BLEFT            7
  495. #define BCENTRE          8
  496. #define BRIGHT           9
  497.  
  498.  
  499. /* ---------------------------------------------------------------------- */
  500.  
  501.  
  502. extern float              XRotVersion();
  503. extern int                XRotDrawString();
  504. extern int                XRotDrawImageString();
  505. extern int                XRotDrawAlignedString();
  506. extern int                XRotDrawAlignedImageString();
  507. extern int                XRotPaintAlignedString();
  508.  
  509.  
  510. /* ---------------------------------------------------------------------- */
  511.  
  512.  
  513. #endif /* _XVERTEXT_INCLUDED_ */
  514.  
  515.  
  516.  
  517. @EOF
  518.  
  519. chmod 600 xvertext.3.0/rotated.h
  520.  
  521. echo x - xvertext.3.0/rotated.c
  522. cat >xvertext.3.0/rotated.c <<'@EOF'
  523. /* ********************************************************************** */
  524.  
  525. /* xvertext 3.0, Copyright (c) 1993 Alan Richardson (mppa3@uk.ac.sussex.syma)
  526.  *
  527.  * Permission to use, copy, modify, and distribute this software and its
  528.  * documentation for any purpose and without fee is hereby granted, provided
  529.  * that the above copyright notice appear in all copies and that both the
  530.  * copyright notice and this permission notice appear in supporting
  531.  * documentation.  All work developed as a consequence of the use of
  532.  * this program should duly acknowledge such use. No representations are
  533.  * made about the suitability of this software for any purpose.  It is
  534.  * provided "as is" without express or implied warranty.
  535.  */
  536.  
  537. /* ********************************************************************** */
  538.  
  539.  
  540. /* BETTER: xvertext now does rotation at any angle!!
  541.  *
  542.  * BEWARE: function arguments have CHANGED since version 2.0!!
  543.  */
  544.  
  545. /* ********************************************************************** */
  546.  
  547.  
  548. #include <X11/Xlib.h>
  549. #include <X11/Xutil.h>
  550. #include <stdio.h>
  551. #include <math.h>
  552. #include "rotated.h"
  553. #include <malloc.h>   /* maybe your system doesn't want this */
  554.  
  555.  
  556. /* ---------------------------------------------------------------------- */
  557.  
  558.  
  559. #define ERROR 1
  560.  
  561. #ifndef M_PI
  562. #define M_PI 3.14159265358979323846
  563. #endif
  564.  
  565.  
  566. /* ---------------------------------------------------------------------- */
  567.  
  568.  
  569. static char  *my_strdup();
  570. static char  *my_strtok();
  571.  
  572. float         XRotVersion();
  573. XImage       *MakeXImage();
  574. int           XRotDrawString();
  575. int           XRotDrawImageString();
  576. int           XRotDrawAlignedString();
  577. int           XRotDrawAlignedImageString();
  578. int           XRotPaintAlignedString();
  579.  
  580.  
  581. /* ---------------------------------------------------------------------- */
  582.  
  583.  
  584. /**************************************************************************/
  585. /* Routine to mimic `strdup()' (some machines don't have it)              */
  586. /**************************************************************************/
  587.  
  588. static char *my_strdup(str)
  589.     char *str;
  590. {
  591.     char *s;
  592.     
  593.     if(str==NULL)
  594.     return NULL;
  595.     
  596.     s=(char *)malloc((unsigned)(strlen(str)+1));
  597.     if(s!=NULL) 
  598.     strcpy(s, str);
  599.     
  600.     return s;
  601. }
  602.  
  603.  
  604. /* ---------------------------------------------------------------------- */
  605.  
  606.  
  607. /**************************************************************************/
  608. /* Routine to replace `strtok' : this one returns a zero length string if */
  609. /* it encounters two consecutive delimiters                               */
  610. /**************************************************************************/
  611.  
  612. static char *my_strtok(str1, str2)
  613.     char *str1, *str2;
  614. {
  615.     char *ret;
  616.     int i, j, stop;
  617.     static int start, len;
  618.     static char *stext;
  619.     
  620.     /* this error should never occur ... */
  621.     if(str2==NULL) {
  622.     fprintf(stderr,
  623.         "Fatal error: my_strtok(): recieved null delimiter string\n");
  624.     exit(1);
  625.     }
  626.     
  627.     /* initialise if str1 not NULL ... */
  628.     if(str1!=NULL) {
  629.     start=0;
  630.     stext=str1;
  631.     len=strlen(str1);
  632.     }
  633.     
  634.     /* run out of tokens ? ... */
  635.     if(start>=len)
  636.     return NULL;
  637.     
  638.     /* loop through characters ... */
  639.     for(i=start; i<len; i++) {
  640.     /* loop through delimiters ... */
  641.     stop=0;
  642.     for(j=0; j<strlen(str2); j++)
  643.         if(stext[i]==str2[j])
  644.         stop=1;
  645.     
  646.     if(stop)
  647.         break;
  648.     }
  649.     
  650.     stext[i]='\0';
  651.     
  652.     ret=stext+start;
  653.     
  654.     start=i+1;
  655.     
  656.     return ret;
  657. }
  658.  
  659.  
  660. /* ---------------------------------------------------------------------- */
  661.  
  662.  
  663. /**************************************************************************/
  664. /* Return version/copyright information                                   */
  665. /**************************************************************************/
  666.  
  667. float XRotVersion(str, n)
  668.     char *str;
  669.     int n;
  670. {
  671.     if(str!=NULL)
  672.     strncpy(str, XV_COPYRIGHT, n);
  673.     return XV_VERSION;
  674. }
  675.  
  676.  
  677. /* ---------------------------------------------------------------------- */
  678.  
  679.  
  680. /**************************************************************************/
  681. /*  Create an XImage structure and allocate memory for it                 */
  682. /**************************************************************************/
  683.  
  684. XImage *MakeXImage(dpy, w, h)
  685.     Display *dpy;
  686.     int w, h;
  687. {
  688.     XImage *I;
  689.     unsigned char *data;
  690.     
  691.     /* reserve memory for image */
  692.     data=(unsigned char *)calloc((unsigned)(((w-1)/8+1)*h), 1);
  693.     if(data==NULL)
  694.     return NULL;
  695.     
  696.     /* create the XImage */
  697.     I=XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), 1, XYBitmap,
  698.                    0, data, w, h, 8, 0);
  699.     if(I==NULL)
  700.     return NULL;
  701.     
  702.     I->byte_order=I->bitmap_bit_order=MSBFirst;
  703.     return I;
  704. }
  705.  
  706.  
  707. /* ---------------------------------------------------------------------- */
  708.  
  709.  
  710. /**************************************************************************/
  711. /*  A front end to XRotPaintAlignedString:                                */
  712. /*      -no alignment, no background                                      */
  713. /**************************************************************************/
  714.  
  715. int XRotDrawString(dpy, font, angle, drawable, gc, x, y, str)
  716.     Display *dpy;
  717.     XFontStruct *font;
  718.     float angle;
  719.     Drawable drawable;
  720.     GC gc;
  721.     int x, y;
  722.     char *str;
  723. {
  724.     return (XRotPaintAlignedString(dpy, font, angle, drawable, gc,
  725.                    x, y, str, NONE, 0));
  726. }
  727.  
  728.  
  729. /* ---------------------------------------------------------------------- */
  730.  
  731.  
  732. /**************************************************************************/
  733. /*  A front end to XRotPaintAlignedString:                                */
  734. /*      -no alignment, paints background                                  */
  735. /**************************************************************************/
  736.  
  737. int XRotDrawImageString(dpy, font, angle, drawable, gc, x, y, str)
  738.     Display *dpy;
  739.     XFontStruct *font;
  740.     float angle;
  741.     Drawable drawable;
  742.     GC gc;
  743.     int x, y;
  744.     char *str;
  745. {
  746.     return(XRotPaintAlignedString(dpy, font, angle, drawable, gc,
  747.                   x, y, str, NONE, 1));
  748. }
  749.  
  750.  
  751. /* ---------------------------------------------------------------------- */
  752.  
  753.  
  754. /**************************************************************************/
  755. /*  A front end to XRotPaintAlignedString:                                */
  756. /*      -does alignment, no background                                    */
  757. /**************************************************************************/
  758.  
  759. int XRotDrawAlignedString(dpy, font, angle, drawable, gc, x, y, text, align)
  760.     Display *dpy;
  761.     XFontStruct *font;
  762.     float angle;
  763.     Drawable drawable;
  764.     GC gc;
  765.     int x, y;
  766.     char *text;
  767.     int align;
  768. {
  769.     return(XRotPaintAlignedString(dpy, font, angle, drawable, gc,
  770.                   x, y, text, align, 0));
  771. }
  772.  
  773.  
  774. /* ---------------------------------------------------------------------- */
  775.  
  776.  
  777. /**************************************************************************/
  778. /*  A front end to XRotPaintAlignedString:                                */
  779. /*      -does alignment, paints background                                */
  780. /**************************************************************************/
  781.  
  782. int XRotDrawAlignedImageString(dpy, font, angle, drawable, gc, x, y, text,
  783.                    align)
  784.     Display *dpy;
  785.     XFontStruct *font;
  786.     float angle;
  787.     Drawable drawable;
  788.     GC gc;
  789.     int x, y;
  790.     char *text;
  791.     int align;
  792. {
  793.     return(XRotPaintAlignedString(dpy, font, angle, drawable, gc,
  794.                   x, y, text, align, 1));
  795. }
  796.  
  797.  
  798. /* ---------------------------------------------------------------------- */
  799.  
  800.  
  801. /**************************************************************************/
  802. /*  The routine which does the rotating and painting                      */
  803. /**************************************************************************/
  804.  
  805. int XRotPaintAlignedString(dpy, font, angle, drawable, gc, x, y, text,
  806.                align, bg)
  807.     Display *dpy;
  808.     XFontStruct *font;
  809.     float angle;
  810.     Drawable drawable;
  811.     GC gc;
  812.     int x, y;
  813.     char *text;
  814.     int align;
  815.     int bg;
  816. {
  817.     Pixmap canvas;
  818.     GC font_gc, my_gc;
  819.     XImage *I_in;
  820.     XImage *I_out;
  821.     XPoint *xpoints;
  822.     int nl=1;
  823.     int max_width;
  824.     register int i, j;
  825.     char *str1, *str2, *str3;
  826.     int height, ascent, descent;
  827.     int cols_in, rows_in;
  828.     int cols_out, rows_out;
  829.     int byte_w_in, byte_w_out;
  830.     int xp, yp;
  831.     float hot_x, hot_y;
  832.     float hot_xp, hot_yp;
  833.     float sin_angle, cos_angle;
  834.     float *corners_x, *corners_y;
  835.     int it, jt;
  836.     float di, dj;
  837.     int ic;
  838.     int bestw, besth;
  839.     Pixmap empty_stipple;
  840.     float xl, xr, xinc;
  841.     int byte_out;
  842.     
  843.     if(text==NULL)
  844.         return 0;
  845.     
  846.     /* manipulate angle */
  847.     while(angle<-360)
  848.         angle+=360;
  849.     
  850.     while(angle>360)
  851.         angle-=360;
  852.     
  853.     angle*=M_PI/180;
  854.     
  855.     /* this gc has similar properties to the user's gc */
  856.     my_gc=XCreateGC(dpy, drawable, NULL, 0);
  857.     XCopyGC(dpy, gc, GCForeground|GCBackground|GCFunction, my_gc);
  858.     
  859.     /* count number of sections in string */
  860.     if(align!=NONE)
  861.     for(i=0; i<strlen(text)-1; i++)
  862.         if(text[i]=='\n')
  863.         nl++;
  864.     
  865.     /* ignore newline characters if not doing alignment */
  866.     if(align==NONE)
  867.     str2=my_strdup("\0");
  868.     else
  869.     str2=my_strdup("\n\0");
  870.     
  871.     if(str2==NULL)
  872.     return ERROR;
  873.     
  874.     /* find width of longest section */
  875.     str1=my_strdup(text);
  876.     if(str1==NULL)
  877.         return ERROR;
  878.     
  879.     str3=my_strtok(str1, str2);
  880.     max_width=XTextWidth(font, str3, strlen(str3));
  881.     
  882.     /* loop through each section */
  883.     do {
  884.         str3=my_strtok((char *)NULL, str2);
  885.         if(str3!=NULL)
  886.             if(XTextWidth(font, str3, strlen(str3))>max_width)
  887.                 max_width=XTextWidth(font, str3, strlen(str3));
  888.     }
  889.     while(str3!=NULL);
  890.     
  891.     /* overall font info */
  892.     ascent=font->ascent;
  893.     descent=font->descent;
  894.     height=ascent+descent;
  895.     
  896.     /* dimensions horizontal text will have */
  897.     cols_in=max_width;
  898.     rows_in=nl*height;
  899.     
  900.     cols_in+=2;
  901.     
  902.     if(cols_in%2==0)
  903.     cols_in++;
  904.     
  905.     if(rows_in%2==0)
  906.     rows_in++;
  907.     
  908.     /* is text horizontal ... */
  909.     if(angle==0)
  910.     XSetFont(dpy, my_gc, font->fid);
  911.     
  912.     /* or vertical ? */
  913.     else {
  914.     /* bitmap for drawing on */
  915.     canvas=XCreatePixmap(dpy, DefaultRootWindow(dpy),
  916.                  cols_in, rows_in, 1);
  917.  
  918.     /* create a GC for the bitmap */
  919.     font_gc=XCreateGC(dpy, canvas, NULL, 0);
  920.     XSetBackground(dpy, font_gc, 0);
  921.     XSetFont(dpy, font_gc, font->fid);
  922.     
  923.     /* make sure the bitmap is blank */
  924.     XSetForeground(dpy, font_gc, 0);
  925.     XFillRectangle(dpy, canvas, font_gc, 0, 0, cols_in+1, rows_in+1);
  926.     }
  927.     
  928.     /* alignment : which point (hot_x, hot_y) relative to bitmap centre
  929.        coincides with user's specified point? */
  930.     
  931.     /* y position */
  932.     if(align==TLEFT || align==TCENTRE || align==TRIGHT)
  933.         hot_y=(float)rows_in/2;
  934.     else if(align==MLEFT || align==MCENTRE || align==MRIGHT)
  935.     hot_y=0;
  936.     else if(align==BLEFT || align==BCENTRE || align==BRIGHT)
  937.     hot_y=-(float)rows_in/2;
  938.     else
  939.     hot_y=-(float)rows_in/2+(float)descent;
  940.     
  941.     /* x position */
  942.     if(align==TLEFT || align==MLEFT || align==BLEFT || align==NONE)
  943.     hot_x=-(float)max_width/2;
  944.     else if(align==TCENTRE || align==MCENTRE || align==BCENTRE)
  945.     hot_x=0;
  946.     else
  947.         hot_x=(float)max_width/2;
  948.     
  949.     /* pre-calculate sin and cos */
  950.     sin_angle=sin(angle);
  951.     cos_angle=cos(angle);
  952.     
  953.     /* rotate hot_x and hot_y around bitmap centre */
  954.     hot_xp= hot_x*cos_angle - hot_y*sin_angle;
  955.     hot_yp= hot_x*sin_angle + hot_y*cos_angle;
  956.     
  957.     /* text background will be drawn using XFillPolygon */
  958.     if(angle!=0) {
  959.     if(bg) {
  960.         xpoints=(XPoint *)malloc((unsigned)(4*nl*sizeof(XPoint)));
  961.         if(!xpoints)
  962.         return ERROR;
  963.         corners_x=(float *)malloc((unsigned)(4*nl*sizeof(float)));
  964.         if(!corners_x)
  965.         return ERROR;
  966.         corners_y=(float *)malloc((unsigned)(4*nl*sizeof(float)));
  967.         if(!corners_y)
  968.         return ERROR;
  969.         
  970.         ic=0;
  971.     }
  972.     XSetForeground(dpy, font_gc, 1);
  973.     }
  974.     
  975.     /* draw text horizontally */
  976.     
  977.     /* start at top of bitmap */
  978.     yp=ascent;
  979.     
  980.     str1=my_strdup(text);
  981.     if(str1==NULL)
  982.     return ERROR;
  983.     
  984.     str3=my_strtok(str1, str2);
  985.     
  986.     /* loop through each section in the string */
  987.     do {
  988.     /* where to draw section in x ? */
  989.     if(align==TLEFT || align==MLEFT || align==BLEFT || align==NONE)
  990.         xp=0;
  991.     else if(align==TCENTRE || align==MCENTRE || align==BCENTRE)
  992.         xp=(max_width-XTextWidth(font, str3, strlen(str3)))/2;
  993.     else
  994.         xp=max_width-XTextWidth(font, str3, strlen(str3));
  995.     
  996.     /* if no rotation is required, draw straight to target drawable */
  997.     if(angle==0) {
  998.         if(bg)
  999.         XDrawImageString(dpy, drawable, my_gc, 
  1000.                  (int)((float)x+
  1001.                        (float)xp-((float)cols_in/2+hot_x)),
  1002.                  (int)((float)y-
  1003.                        ((float)rows_in/2-hot_y-(float)yp)),
  1004.                  str3, strlen(str3));
  1005.         else
  1006.         XDrawString(dpy, drawable, my_gc, 
  1007.                 (int)((float)x+
  1008.                   (float)xp-((float)cols_in/2+hot_x)),
  1009.                 (int)((float)y-
  1010.                   ((float)rows_in/2-hot_y-(float)yp)),
  1011.                 str3, strlen(str3));
  1012.         
  1013.     }
  1014.     /* rotation is required */
  1015.     else {
  1016.         /* draw string onto bitmap */
  1017.         XDrawString(dpy, canvas, font_gc, xp, yp, str3, strlen(str3));
  1018.         
  1019.         /* keep a note of corner positions of this string */
  1020.         if(bg) {
  1021.         corners_x[ic]=(float)xp-(float)cols_in/2-hot_x;
  1022.         corners_y[ic]=(float)(yp-ascent)-(float)rows_in/2+hot_y;
  1023.         corners_x[ic+1]=corners_x[ic];
  1024.         corners_y[ic+1]=corners_y[ic]+(float)height;
  1025.         corners_x[nl*4-1-ic]=corners_x[ic]+
  1026.             (float)XTextWidth(font, str3, strlen(str3));
  1027.         corners_y[nl*4-1-ic]=corners_y[ic];
  1028.         corners_x[nl*4-2-ic]=corners_x[nl*4-1-ic];
  1029.         corners_y[nl*4-2-ic]=corners_y[ic+1];
  1030.         ic+=2;
  1031.         }
  1032.     }
  1033.     /* move to next line */
  1034.     yp+=height;
  1035.     
  1036.         str3=my_strtok((char *)NULL, str2);
  1037.     }
  1038.     while(str3!=NULL);
  1039.     
  1040.     /* we can leave here if no rotation is required */
  1041.     if(angle==0)
  1042.     return 0;
  1043.     
  1044.     /* create image to hold horizontal text */
  1045.     I_in=MakeXImage(dpy, cols_in, rows_in);
  1046.     if(I_in==NULL)
  1047.     return ERROR;
  1048.     
  1049.     /* extract horizontal text */
  1050.     XGetSubImage(dpy, canvas, 0, 0, cols_in, rows_in,
  1051.          1, XYPixmap, I_in, 0, 0);
  1052.     I_in->format=XYBitmap;
  1053.     
  1054.     /* how big will rotated text be ? */
  1055.     cols_out=fabs((float)rows_in*sin_angle) +
  1056.         fabs((float)cols_in*cos_angle) +0.99999;
  1057.     rows_out=fabs((float)rows_in*cos_angle) +
  1058.         fabs((float)cols_in*sin_angle) +0.99999;
  1059.     
  1060.     if(cols_out%2==0)
  1061.     cols_out++;
  1062.     
  1063.     if(rows_out%2==0)
  1064.     rows_out++;
  1065.     
  1066.     /* create image to hold rotated text */
  1067.     I_out=MakeXImage(dpy, cols_out, rows_out);
  1068.     if(I_out==NULL)
  1069.     return ERROR;
  1070.     
  1071.     byte_w_in=(cols_in-1)/8+1;
  1072.     byte_w_out=(cols_out-1)/8+1;
  1073.     
  1074.     /* loop through all bits in rotated image */
  1075.  
  1076.     /* we try to make this as fast as possible - which is why it looks
  1077.        a bit over-the-top */
  1078.  
  1079.     /* loop through all rows in the image */
  1080.     for(j=0; j<rows_out; j++) {
  1081.  
  1082.     /* distance from centre */
  1083.     dj=(float)j+0.5-(float)rows_out/2;
  1084.  
  1085.     /* some bits in final image don't map to bits in original -
  1086.        try to pre-calculate these */
  1087.     if(j==0) {
  1088.         if(angle==M_PI/2 || angle==M_PI || angle==3*M_PI/2) {
  1089.         xl=0;
  1090.                 xr=(float)cols_out;
  1091.                 xinc=0;
  1092.             }
  1093.         else if(angle<M_PI) {
  1094.         xl=(float)cols_out/2+
  1095.             (dj-(float)rows_in/(2*cos_angle))/tan(angle)-2;
  1096.         xr=(float)cols_out/2+
  1097.             (dj+(float)rows_in/(2*cos_angle))/tan(angle)+2;
  1098.         xinc=1./tan(angle);
  1099.         }
  1100.         else {
  1101.         xl=(float)cols_out/2+
  1102.             (dj+(float)rows_in/(2*cos_angle))/tan(angle)-2;
  1103.         xr=(float)cols_out/2+
  1104.             (dj-(float)rows_in/(2*cos_angle))/tan(angle)+2;
  1105.  
  1106.         xinc=1./tan(angle);
  1107.         }
  1108.     }
  1109.     else {
  1110.         xl+=xinc;
  1111.         xr+=xinc;
  1112.     }
  1113.  
  1114.     /* no point re-calculating these every pass */
  1115.     di=(float)((xl<0)?0:(int)xl)+0.5-(float)cols_out/2;
  1116.     byte_out=(rows_out-j)*byte_w_out;
  1117.  
  1118.     /* loop through meaningful columns */
  1119.     for(i=((xl<0)?0:(int)xl); i<((xr>=cols_out)?cols_out:(int)xr); i++) {
  1120.         /* rotate coordinates */
  1121.         it=(float)cols_in/2 + ( di*cos_angle + dj*sin_angle);
  1122.         jt=(float)rows_in/2 - (-di*sin_angle + dj*cos_angle);
  1123.         
  1124.         /* set pixel if required */
  1125.         if(it>=0 && it<cols_in && jt>=0 && jt<rows_in) 
  1126.         if((I_in->data[jt*byte_w_in+it/8] & 128>>(it%8))>0)
  1127.             I_out->data[byte_out+i/8] | = 128>>i%8;
  1128.  
  1129.         di+=1.;
  1130.     }
  1131.     }
  1132.  
  1133.     XFreePixmap(dpy, canvas);
  1134.     
  1135.     /* create a new bitmap to hold rotated text */
  1136.     canvas=XCreatePixmap(dpy, DefaultRootWindow(dpy), cols_out, rows_out, 1);
  1137.     XPutImage(dpy, canvas, font_gc, I_out, 0, 0, 0, 0, cols_out, rows_out);
  1138.     
  1139.     /* fill in the background to the text, if required */
  1140.     if(bg) {
  1141.     /* rotate corner positions */
  1142.     for(i=0; i<4*nl; i++) {
  1143.         xpoints[i].x=(float)x + ( corners_x[i]*cos_angle + 
  1144.                      corners_y[i]*sin_angle);
  1145.         xpoints[i].y=(float)y + (-corners_x[i]*sin_angle + 
  1146.                      corners_y[i]*cos_angle);
  1147.     }
  1148.     
  1149.     /* we would like to swap foreground and background colors here,
  1150.        using XGetGCValues, but X11R3 doesn't have it */
  1151.  
  1152.     XQueryBestStipple(dpy, drawable, 1, 1, &bestw, &besth);
  1153.     empty_stipple=XCreatePixmap(dpy, drawable, bestw, besth, 1);
  1154.  
  1155.     XSetForeground(dpy, font_gc, 0);
  1156.     XFillRectangle(dpy, empty_stipple, font_gc, 0, 0, bestw+1, besth+1);
  1157.         
  1158.     XSetStipple(dpy, my_gc, empty_stipple);
  1159.     XSetFillStyle(dpy, my_gc, FillOpaqueStippled);
  1160.         
  1161.     XFillPolygon(dpy, drawable, my_gc, xpoints, 4*nl, 
  1162.              Nonconvex, CoordModeOrigin);
  1163.     
  1164.     /* free our resources */
  1165.     free((char *)xpoints);
  1166.     free((char *)corners_x);
  1167.     free((char *)corners_y);
  1168.     }
  1169.     
  1170.     /* where should top left corner of bitmap go ? */
  1171.     xp=(float)x-((float)cols_out/2 +hot_xp);
  1172.     yp=(float)y-((float)rows_out/2 -hot_yp);
  1173.     
  1174.     /* paint text using stipple technique */
  1175.     XSetFillStyle(dpy, my_gc, FillStippled);
  1176.     XSetStipple(dpy, my_gc, canvas);
  1177.     XSetTSOrigin(dpy, my_gc, xp, yp);
  1178.     XFillRectangle(dpy, drawable, my_gc, xp, yp, cols_out, rows_out);
  1179.     
  1180.     /* free our resources */
  1181.     XDestroyImage(I_in);
  1182.     XDestroyImage(I_out);
  1183.     XFreePixmap(dpy, canvas);
  1184.     XFreeGC(dpy, my_gc);
  1185.     XFreeGC(dpy, font_gc);
  1186.     
  1187.     /* we got to the end OK! */
  1188.     return 0;
  1189. }
  1190.  
  1191.  
  1192. @EOF
  1193.  
  1194. chmod 600 xvertext.3.0/rotated.c
  1195.  
  1196.  
  1197. rm -f /tmp/uud$$
  1198. (echo "begin 666 /tmp/uud$$\n#;VL*n#6%@x\n \nend" | uudecode) >/dev/null 2>&1
  1199. if [ X"`cat /tmp/uud$$ 2>&1`" = Xok ]
  1200. then
  1201.     unpacker=uudecode
  1202. else
  1203.     echo Compiling unpacker for non-ascii files
  1204.     pwd=`pwd`; cd /tmp
  1205.     cat >unpack$$.c <<'EOF'
  1206. #include <stdio.h>
  1207. #define C (*p++ - ' ' & 077)
  1208. main()
  1209. {
  1210.     int n;
  1211.     char buf[128], *p, a,b;
  1212.  
  1213.     scanf("begin %o ", &n);
  1214.     gets(buf);
  1215.  
  1216.     if (freopen(buf, "w", stdout) == NULL) {
  1217.         perror(buf);
  1218.         exit(1);
  1219.     }
  1220.  
  1221.     while (gets(p=buf) && (n=C)) {
  1222.         while (n>0) {
  1223.             a = C;
  1224.             if (n-- > 0) putchar(a << 2 | (b=C) >> 4);
  1225.             if (n-- > 0) putchar(b << 4 | (a=C) >> 2);
  1226.             if (n-- > 0) putchar(a << 6 | C);
  1227.         }
  1228.     }
  1229.     exit(0);
  1230. }
  1231. EOF
  1232.     cc -o unpack$$ unpack$$.c
  1233.     rm unpack$$.c
  1234.     cd $pwd
  1235.     unpacker=/tmp/unpack$$
  1236. fi
  1237. rm -f /tmp/uud$$
  1238.  
  1239. echo x - xvertext.3.0/INSTALL '[non-ascii]'
  1240. $unpacker <<'@eof'
  1241. begin 600 xvertext.3.0/INSTALL
  1242. M(" @2&]W('1O(&-O;7!I;&4@=&AI<R!S='5F9@H@("!^?GY^?GY^?GY^?GY^X
  1243. M?GY^?GY^?GY^?GY^"@H@("!);F-L=61E9"!I;B!T:&ES('!A8VMA9V4@:7,@X
  1244. M82!-86ME9FEL92!W:&EC:"!G96YE<F%T97,@86X@97AA;7!L90IP<F]G<F%MX
  1245. M(&%N9"P@;W!T:6]N86QL>2P@;6%K97,@86YD(&EN<W1A;&QS(&$@;&EN:VENX
  1246. M9R!L:6)R87)Y+"!H96%D97(*9FEL92!A;F0@;6%N=6%L('!A9V5S+@H*(" @X
  1247. M0F5F;W)E('1Y<&EN9R!@;6%K92<@>6]U(&UI9VAT(&=I=F4@82!C=7)S;W)YX
  1248. M(&=L86YC92!T;R!T:&4@36%K969I;&4N"D%L;"!Y;W4@;F5E9"!T;R!E9&ETX
  1249. M(&%R92!T:&4@=&%R9V5T(&1I<F5C=&]R:65S(&9O<B!L:6)R87)Y+"!I;F-LX
  1250. M=61E(&9I;&4*86YD(&UA;G5A;"!P86=E<R!I9B!Y;W4@<&QA;B!O;B!I;G-TX
  1251. M86QL:6YG+B!9;W4@;6EG:'0@86QS;R!C;VYS:61E<@IW:&5T:&5R(&]R(&YOX
  1252. M="!Y;W5R('-Y<W1E;2!N965D<R!@(VEN8VQU9&4@(FUA;&QO8RYH(B<@86YDX
  1253. M(& M;&UA;&QO8R<N"@H@("!4>7!I;F<@8&UA:V4G('!R;V1U8V5S('1H92!EX
  1254. M>&%M<&QE('!R;V=R86T@8&5X86UP;&4G+B!2=6X@:70N($1E<&5N9&EN9PIOX
  1255. M;B!Y;W5R(&UA8VAI;F4@>6]U(&UI9VAT(&)E('!L96%S96YT;'D@.BTI(&]RX
  1256. M('5N<&QE87-E;G1L>2 Z+2@*<W5R<')I<V5D(0H*(" @5'EP:6YG("!@;6%KX
  1257. M92!I;G-T86QL)R!C86QL<R!@87(G('1O('!R;V1U8V4@86X@87)C:&EV92!FX
  1258. M:6QE(&QI8EAR;W0N82P*86YD(&EN<W1A;&QS('1H:7,L(')O=&%T960N:"!AX
  1259. M;F0@=&AE(&UA;G5A;"!P86=E<RX*"@H@("!3;VUE=&AI;F<@9V]N92!W<F]NX
  1260. M9S\*(" @?GY^?GY^?GY^?GY^?GY^?GY^?GY^"B @($EF('1H92!C;VUP;&%IX
  1261. M;G0@=V%S"B *(" @(" @8')O=&%T960N8SH@;&EN92 S,CH@0V%N)W0@9FENX
  1262. M9"!I;F-L=61E(&9I;&4@;6%L;&]C+F@G"@H@(" @(" @('EO=7(@<WES=&5MX
  1263. M(&1O97-N)W0@;F5E9"!@(VEN8VQU9&4@(FUA;&QO8RYH(B<@+2!D96QE=&4@X
  1264. M=&AE( IO9F9E;F1I;F<@;&EN92X@22!B96QI979E('1H:7,@:7,@=')U92!OX
  1265. M9B!$64Y)6"!M86-H:6YE<R!A="!L96%S="X*"B @($]T:&5R=VES92P@<&QEX
  1266. M87-E(&UA:6P@;64@86YD($DG;&P@9&\@;7D@8F5S="X*"@H@("!3=6-C97-SX
  1267. M9G5L(&-O;7!I;&%T:6]N<PH@("!^?GY^?GY^?GY^?GY^?GY^?GY^?GY^?@H*X
  1268. M(" @5&AE('!R;V=R86US(&EN('1H:7,@<&%C:V%G92!H879E(&)E96X@<W5CX
  1269. M8V5S<V9U;&QY(&-O;7!I;&5D(&%N9 IR=6X@;VXZ"@H@("!O($A0(#DP,#!SX
  1270. M,S P+" Y,# P<S<P,"!A;F0@.3 P,',X,# @;6%C:&EN97,*(" @;R!3;VQBX
  1271. M;W5R;F5S(')U;FYI;F<@4W5N3U,@-"XQ+C$*(" @;R!!(%-E<75E;G0@4WEMX
  1272. M;65T<GD@<G5N;FEN9R!$64Y)6 H*(" @1V]O9"!L=6-K('=I=&@@86YY=&AIX
  1273. M;F<@96QS92 Z+2D*"@H@("!!;&%N(%)I8VAA<F1S;VXL(#,Q+S,O.3,@*&UPX
  1274. M<&$S0'5K+F%C+G-U<W-E>"YS>6UA*0H@(" M+2TM+2TM+2TM+2TM+2TM+2TMX
  1275. ?+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM                X
  1276.                                                              X
  1277. end
  1278. @eof
  1279.  
  1280. chmod 600 xvertext.3.0/INSTALL
  1281.  
  1282. echo x - xvertext.3.0/CHANGES
  1283. cat >xvertext.3.0/CHANGES <<'@EOF'
  1284.    This is version 3.0 of xvertext (31/3/92)
  1285.    -----------------------------------------
  1286.  
  1287.    The biggest change since version 2.0 is this:
  1288.  
  1289.                 *****************************************
  1290.  
  1291.          xvertext now paints strings at any angle!
  1292.  
  1293.                 *****************************************
  1294.  
  1295.    The way xvertext works now is not to bother pre-rotating a font
  1296. before drawing, just draw the whole string horizontally and rotate it all
  1297. at once. Is this good or bad news?
  1298.  
  1299.     Advantages:
  1300.     -----------
  1301.        o  A single function call will rotate and paint you a string.
  1302.        o  Text looks good at any angle, particulary big fonts.
  1303.        o  Small strings are quick to draw.
  1304.  
  1305.     Disadvantages:
  1306.     --------------
  1307.        o  The arguments to the remaining functions (XRotDraw.....) are
  1308. *different* to their counterparts in version 2.0. Thus code using the
  1309. earlier version will need altering (which will probably mean deleting
  1310. loads of stuff, and altering a fer arguments).
  1311.        o  Long strings in big fonts take a while.
  1312.        o  Speed seems more dependent now on computing power rather
  1313. than X server speed (the maths involved in rotating big bitmaps!)
  1314.  
  1315.  
  1316.     Alan Richardson, 31/3/93 (mppa3@uk.ac.sussex.syma)
  1317.     --------------------------------------------------
  1318.  
  1319.  
  1320. @EOF
  1321.  
  1322. chmod 600 xvertext.3.0/CHANGES
  1323.  
  1324. echo x - xvertext.3.0/README
  1325. cat >xvertext.3.0/README <<'@EOF'
  1326.    This is version 3.0 of xvertext (31/3/92)
  1327.    -----------------------------------------
  1328.  
  1329.    This package contains routines which can be used to draw text at ANY
  1330. ANGLE in an X window or pixmap. This is done via a single call to one of
  1331. four functions:
  1332.  
  1333.     XRotDrawString();
  1334.     XRotDrawImageString();
  1335.     XRotDrawAlignedString();
  1336.     XRotDrawAlignedImageString();
  1337.  
  1338.    The difference between these functions is given in the manual page.
  1339.  
  1340.  
  1341.    Why is it called xvertext?
  1342.    --------------------------
  1343.    Previous versions only used to be able to do vertical text. This version is
  1344. not so limited. Unfortunately programs using version 2.0 and earlier are not
  1345. comaptible with this release, although the changes that need making should
  1346. be straight forward.
  1347.  
  1348.  
  1349.    Is it fast?
  1350.    -----------
  1351.    Depends on your X server and processing power. In general, it's faster
  1352. for short strings in small fonts (although bigger fonts look better).
  1353. If you're doing a lot of vertical text, use version 2.0. If you're doing
  1354. a lot of other-angle text, try turning your monitor on its side :-)
  1355.    Note that in the case of text `the right way up' (ie horizontal),
  1356. no rotation is done and theses functions are just a wrapper around Xlib's
  1357. own XDrawText() and XDrawImageText() functions. In this way,
  1358. XRotDrawAlignedString() provides an easy way of doing centered horizontal text
  1359. (with no speed penalty).
  1360.  
  1361.    Any bugs?
  1362.    ---------
  1363.    Some small fonts look poor at some angles. I've tried to prevent the 
  1364. dropping of bits during rotation - if you can see a problem, please
  1365. and tell me about it! 
  1366.    Some machines I've tried it on have been unacceptably slow (eq HP 9000s300).
  1367. Again, if you can see a speed up please let me know.
  1368.  
  1369.  
  1370.    So what's in the package?
  1371.    -------------------------
  1372.    You get `rotated.c' and `rotated.h', the source and header files
  1373. for the rotating routines. There's also an example program to illustrate
  1374. their use, and a Makefile. See the file `INSTALL' to make the code.
  1375. There are also a few cursory manual pages.
  1376.  
  1377.  
  1378.    How do I use the functions in my own program?
  1379.    ---------------------------------------------
  1380.    You can either:
  1381.  
  1382.      o Copy `rotated.c' and `rotated.h' to sit with your program's source files
  1383. and compile them all together. Or:
  1384.  
  1385.      o Type `make install' to create a linking library and install it
  1386. and the header file into directories of your choice. You then specify
  1387. `-lXrot' prior to `-lX11' when linking your program. Remember that if you
  1388. don't install in a standard place like /usr/lib, you'll need to use the
  1389. -L and -I compiler options.
  1390.  
  1391.      If you want to distribute programs using these routines you're very
  1392. welcome; all I ask is that you let me know!
  1393.  
  1394.  
  1395.      Alan Richardson, 31/3/93 (mppa3@uk.ac.sussex.syma)
  1396.      --------------------------------------------------  
  1397. @EOF
  1398.  
  1399. chmod 600 xvertext.3.0/README
  1400.  
  1401. echo mkdir - xvertext.3.0/man
  1402. mkdir xvertext.3.0/man
  1403.  
  1404. echo x - xvertext.3.0/man/XRotDrawAlignedString.3
  1405. sed 's/^@//' >xvertext.3.0/man/XRotDrawAlignedString.3 <<'@EOF'
  1406. @.\" @(#)XRotDrawAlignedString 3.0 30/3/93; Copyright (c) 1992 Alan Richardson
  1407. @.TH XRotDrawAlignedString 3 "30 Mar 1993" "xvertext routines"
  1408. @.SH NAME
  1409. XRotDrawString, XRotDrawImageString,
  1410. XRotDrawAlignedString, XRotDrawAlignedImageString \- draw strings 
  1411. at any angle
  1412. @.SH SYNOPSIS
  1413. @.B int XRotDrawString(dpy, font, angle, drawable,
  1414. @.B gc, x, y, text)
  1415. @.br
  1416. @.B Display *dpy;
  1417. @.br
  1418. @.B XFontStruct *font;
  1419. @.br
  1420. @.B float angle;
  1421. @.br
  1422. @.B Drawable drawable;
  1423. @.br
  1424. @.B GC gc;
  1425. @.br
  1426. @.B int x, y;
  1427. @.br
  1428. @.B char *text;
  1429. @.PP
  1430. @.B int XRotDrawImageString(dpy, font, angle, drawable,
  1431. @.B gc, x, y, text)
  1432. @.br
  1433. @.B Display *dpy;
  1434. @.br
  1435. @.B XFontStruct *font;
  1436. @.br
  1437. @.B float angle;
  1438. @.br
  1439. @.B Drawable drawable;
  1440. @.br
  1441. @.B GC gc;
  1442. @.br
  1443. @.B int x, y;
  1444. @.br
  1445. @.B char *text;
  1446. @.PP
  1447. @.B int XRotDrawAlignedString(dpy, font, angle, drawable,
  1448. @.B gc, x, y, text, align)
  1449. @.br
  1450. @.B Display *dpy;
  1451. @.br
  1452. @.B XFontStruct *font;
  1453. @.br
  1454. @.B float angle;
  1455. @.br
  1456. @.B Drawable drawable;
  1457. @.br
  1458. @.B GC gc;
  1459. @.br
  1460. @.B int x, y;
  1461. @.br
  1462. @.B char *text;
  1463. @.br
  1464. @.B int align;
  1465. @.PP
  1466. @.B int XRotDrawAlignedImageString(dpy, font, angle, drawable,
  1467. @.B gc, x, y, text, align)
  1468. @.br
  1469. @.B Display *dpy;
  1470. @.br
  1471. @.B XFontStruct *font;
  1472. @.br
  1473. @.B float angle;
  1474. @.br
  1475. @.B Drawable drawable;
  1476. @.br
  1477. @.B GC gc;
  1478. @.br
  1479. @.B int x, y;
  1480. @.br
  1481. @.B char *text;
  1482. @.br
  1483. @.B int align;
  1484. @.SH ARGUMENTS
  1485. @.IP \fIdisplay\fP 1i     
  1486. Specifies the connection to the X server.
  1487. @.IP \fIfont\fP 1i
  1488. Pointer to an XFontStruct structure.
  1489. @.IP \fIangle\fP 1i
  1490. Angle in degrees between direction of text and horizontal
  1491. (anticlockwise is positive).
  1492. @.IP \fIdrawable\fP 1i
  1493. The window or pixmap in which to paint the text.
  1494. @.IP \fIgc\fP 1i
  1495. The graphics context to use when painting text.
  1496. @.IP \fIx\,\ y\fP 1i
  1497. Coordinates whose relation to the postion of the painted text is given
  1498. by \fIalign\fP.
  1499. @.IP \fItext\fP 1i
  1500. A character string.
  1501. @.IP \fIalign\fP 1i
  1502. Describes the alignment with which to draw the string.
  1503. @.SH DESCRIPTION
  1504. @.PP
  1505. These four functions are used to draw text at any angle in an X window
  1506. or pixmap. 
  1507. All four have several arguments in common. In particular, 
  1508. @.I font
  1509. is an XFontStruct structure describing which font to use.
  1510. Only the foreground and background attributes of
  1511. @.I gc
  1512. have any relevence. The coordinate pair
  1513. @.I (x\,\ y)
  1514. describes the location to place the string on the
  1515. drawable - exactly what `location' means depends on the function
  1516. called.
  1517. @.PP
  1518. The two functions
  1519. @.I XRotDrawString
  1520. and
  1521. @.I XRotDrawImageString
  1522. paint a string such that the specified point
  1523. @.I (x\,\ y)
  1524. coincides with the origin of the first character in the string,
  1525. after rotation.
  1526. No interpretation is placed on newline characters appearing in the
  1527. string.
  1528. @.PP
  1529. The
  1530. @.I XRotDrawAlignedString
  1531. and
  1532. @.I XRotDrawAlignedImageString
  1533. functions interpret newline characters in the string as delimiters of
  1534. smaller strings to appear on seperate lines. These seperate
  1535. strings are aligned with respect to one another according to the value
  1536. of
  1537. @.I align,
  1538. which can take the values
  1539. @.I TLEFT, TCENTRE, TRIGHT, MLEFT, MCENTRE, MRIGHT,
  1540. @.I BLEFT, BCENTRE, BRIGHT.
  1541. Alignment is done before rotation.
  1542. The first character corresponds to the position of the block of text
  1543. relative to
  1544. @.I (x\,\ y):
  1545. @.I T
  1546. places the top of the block at 
  1547. @.I y,
  1548. @.I M
  1549. places the middle of the block there and
  1550. @.I B
  1551. the bottom. The remaining word indicates horizontal alignment:
  1552. @.I LEFT
  1553. places the left of the block at
  1554. @.I x,
  1555. and so on.
  1556. Rotation of the whole block is then performed around
  1557. @.I (x\,\ y).
  1558. @.PP
  1559. The two functions with `Image' in their names fill in the
  1560. text background with the background colour of
  1561. @.I gc
  1562. before painting the text. The remaining two functions leave
  1563. the background untouched.
  1564. @.SH ALIGNMENT EXAMPLE
  1565. Suppose the string "This\\nis\\nno\\nordinary\\ntest" were passed to
  1566. @.I XRotDrawAlignedString()
  1567. with an alignment of
  1568. @.I MLEFT
  1569. and no rotation;
  1570. the result would be:
  1571. @.PP
  1572.                               |This
  1573.                               |is
  1574.                      ---------+no-------
  1575.                               |ordinary
  1576.                               |test
  1577. @.PP
  1578. where the cross hairs indicate the position of
  1579. @.I (x\,\ y).
  1580. Alignments of MCENTER and MRIGHT would result in:
  1581. @.PP
  1582.                  |                                   |
  1583.                 This                         This    |
  1584.                  is                          is      |
  1585.          --------no--------                 -no------+---------
  1586.               ordinary                       ordinary|
  1587.                 test                         test    |
  1588.                  |                                   |
  1589.  
  1590. @.SH RETURN VALUE
  1591. All four functions return 0 on success, 1 on failure. Failure is
  1592. probably due to an unsuccessful call to malloc().
  1593. @.SH SEE ALSO
  1594. xvertext
  1595. @EOF
  1596.  
  1597. chmod 600 xvertext.3.0/man/XRotDrawAlignedString.3
  1598.  
  1599. echo x - xvertext.3.0/man/xvertext.3
  1600. sed 's/^@//' >xvertext.3.0/man/xvertext.3 <<'@EOF'
  1601. @.\" @(#)xvertext 3.0 31/3/93; Copyright (c) 1992 Alan Richardson
  1602. @.TH xvertext 3 "31 Mar 1993" "xvertext routines"
  1603. @.SH NAME
  1604. xvertext - a collection of functions for rendering rotated text in an
  1605. X window
  1606. @.SH GENERAL
  1607. As of version 3.0 there are 5 functions in the xvertext package 
  1608. intended for general use. These are
  1609. @.I XRotVersion,
  1610. @.I XRotDrawString,
  1611. @.I XRotDrawImageString,
  1612. @.I XRotDrawAlignedString
  1613. and
  1614. @.I XRotDrawAlignedImageString.
  1615. @.SH REMARK
  1616. Rotation at any angle is an improvement over the vertical text
  1617. available in version 2.0. Some functions have been deleted from that
  1618. version, and some remaining functions
  1619. @.I have had their arguments changed.
  1620. @.SH USAGE
  1621. @.I XRotVersion 
  1622. is used to obtain the current release number and a copyright string.
  1623. @.PP
  1624. Using the painting routines typically involves three steps: creating 
  1625. a GC, loading a font and calling the painting function.
  1626. For example:
  1627.  
  1628. |
  1629. @.br
  1630. |
  1631. @.br
  1632. GC gc;
  1633. @.br
  1634. XFontStruct *font;
  1635. @.br
  1636. char *fontname=
  1637. "lucidasans-bold-18";
  1638. @.br
  1639. @.PP
  1640. font=XLoadQueryFont(dpy, fontname);
  1641. @.br
  1642.     if(font==NULL) {
  1643.         fprintf(stderr, "no font `%s'\\n", fontname);
  1644.         font=XLoadQueryFont(dpy, "fixed");
  1645.     }
  1646. @.PP
  1647. gc=XCreateGC(dpy, window, NULL, 0);
  1648. @.br
  1649. XSetForeground(dpy, gc, WhitePixel(dpy, DefaultScreen(dpy)));
  1650. @.br
  1651. XSetBackground(dpy, gc, BlackPixel(dpy, DefaultScreen(dpy)));
  1652. @.PP
  1653. XRotDrawAlignedImageString(dpy, font, 45., 
  1654. window, gc, 300, 300, "hello", BLEFT);
  1655. @.br
  1656. |
  1657. @.br
  1658. |
  1659. @.PP
  1660. Note that dpy and window are display connections and a window
  1661. already assumed created.
  1662. This code segment obtains an XFontStruct for the font 
  1663. "lucidasans-bolditalic-10" if it exists, or "fixed" if not.
  1664. A graphics context is created with white foreground and black
  1665. background. The string "hello" is then painted at 45 degrees with
  1666. bottom left hand corner at (300, 300).
  1667. @.SH SEE ALSO
  1668. XRotVersion,
  1669. XRotDrawString,
  1670. XRotDrawImageString,
  1671. XRotDrawAlignedString,
  1672. XRotDrawAlignedImageString.
  1673.  
  1674. @EOF
  1675.  
  1676. chmod 600 xvertext.3.0/man/xvertext.3
  1677.  
  1678. echo x - xvertext.3.0/man/XRotVersion.3
  1679. sed 's/^@//' >xvertext.3.0/man/XRotVersion.3 <<'@EOF'
  1680. @.\" @(#)XRotVersion 1.3 31/3/92; Copyright (c) 1993 Alan Richardson
  1681. @.TH XRotVersion 3 "31 Mar 1992" "xvertext routines"
  1682. @.SH NAME
  1683. XRotVersion \- return version number and copyright of xvertext routines
  1684. @.SH SYNOPSIS
  1685. @.B float XRotVersion(copyright, nmax)
  1686. @.br
  1687. @.B "   " char *copyright;
  1688. @.br
  1689. @.B "   " int nmax;
  1690. @.SH ARGUMENTS
  1691. @.IP \fIcopyright\fP 1i
  1692. A character string to hold copyright information.
  1693. @.IP \fInmax\fP 1i
  1694. The maximum number of characters to be placed in \fIcopyright\fP.
  1695. @.SH DESCRIPTION
  1696. @.PP
  1697. The
  1698. @.I XRotVersion
  1699. function returns the current version number of the xvertext routines.
  1700. It also places into
  1701. @.I copyright
  1702. at most
  1703. @.I nmax
  1704. characters of a copyright string.
  1705. @.SH SEE ALSO
  1706. xvertext,
  1707. XRotDrawString,
  1708. XRotDrawImageString,
  1709. XRotDrawAlignedString,
  1710. XRotDrawAlignedImageString.
  1711.  
  1712. @EOF
  1713.  
  1714. chmod 600 xvertext.3.0/man/XRotVersion.3
  1715.  
  1716. chmod 700 xvertext.3.0/man
  1717.  
  1718. chmod 700 xvertext.3.0
  1719.  
  1720. rm -f /tmp/unpack$$
  1721. exit 0
  1722.  
  1723. exit 0 # Just in case...
  1724. -- 
  1725.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  1726. \X/  Amiga - The only way to fly!      |
  1727.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  1728.   casual observer..."                  |
  1729.