Rotated.C

Index

      /* ********************************************************************** */
      
      /* xvertext, Copyright (c) 1992 Alan Richardson (mppa3@uk.ac.sussex.syma)
       *
       * Permission to use, copy, modify, and distribute this software and its
       * documentation for any purpose and without fee is hereby granted, provided
       * that the above copyright notice appear in all copies and that both the
       * copyright notice and this permission notice appear in supporting
       * documentation.  All work developed as a consequence of the use of
  10   * this program should duly acknowledge such use. No representations are
       * made about the suitability of this software for any purpose.  It is
       * provided "as is" without express or implied warranty.
       */
      
      /* ********************************************************************** */
      
      // Minor modifications by Chris Cannam for wm2/wmx
      // Major modifications by Kazushi (Jam) Marukawa for wm2/wmx i18n patch
      
  20  
      #include <X11/Xlib.h>
      #include <X11/Xutil.h>
      #include <stdlib.h>
      #include <string.h>
      #include <stdio.h>
      #include "Config.h"
      #include "Rotated.h"
      
      
  30  #if I18N
      #undef NOPIXMAP
      #define NOPIXMAP 1      // anyway, NOPIXMAP
      #endif
      
      /* ---------------------------------------------------------------------- */
      
      
      int xv_errno;
      
  40  static char *my_strdup(char *);
      static char *my_strtok(char *, char *);
      
      
      /* ---------------------------------------------------------------------- */  
      
      
      /* *** Routine to mimic `strdup()' (some machines don't have it) *** */
      
      static char *my_strdup(char *str)
  50  {
        char *s;
      
        if (str == NULL) return NULL;
      
        s = (char *)malloc((unsigned)(strlen(str)+1));
        /* this error is highly unlikely ... */
        if (s == NULL) {
          fprintf(stderr, "Fatal error: my_strdup(): Couldn't do malloc (gulp!)\n");
          exit(1); 
  60    }
      
        strcpy(s, str);
        return s;
      }
      
      
      /* ---------------------------------------------------------------------- */
      
      
  70  /* *** Routine to replace `strtok' : this one returns a zero
             length string if it encounters two consecutive delimiters *** */
      
      static char *my_strtok(char *str1, char *str2)
      {
        char *ret;
        int i, j, stop;
        static int start, len;
        static char *stext;
      
  80    /* this error should never occur ... */
        if (str2 == NULL) {
          fprintf(stderr,
                  "Fatal error: my_strtok(): recieved null delimiter string\n");
          exit(1);
        }
      
        /* initialise if str1 not NULL ... */
        if (str1 != NULL) {
          start = 0;
  90      stext = str1;
          len = strlen(str1);
        }
      
        /* run out of tokens ? ... */
        if (start >= len) return NULL;
      
        /* loop through characters ... */
        for (i = start; i < len; i++) {
      
 100      /* loop through delimiters ... */
          stop = 0;
          for (j = 0; j < strlen(str2); j++)
            if (stext[i] == str2[j]) stop = 1;
       
          if (stop) break;
        }
      
        stext[i] = '\0';
        ret = stext + start;
 110    start = i+1;
      
        return ret;
      }
      
      
      /* ---------------------------------------------------------------------- */
        
      
      /* *** Routine to return version/copyright information *** */
 120  
      float XRotVersion(char *str, int n)
      {
        if (str != NULL) strncpy(str, XV_COPYRIGHT, n);
        return XV_VERSION;
      }
      
      
      /* ---------------------------------------------------------------------- */
      
 130  
      /* *** Load the rotated version of a given font *** */
       
      XRotFontStruct *XRotLoadFont(Display *dpy, char *fontname, float angle)
      {
        char val;
        XImage *I1, *I2;
        Pixmap canvas;
        Window root;
        int screen;
 140    GC font_gc;
        char text[3];/*, errstr[300];*/
        XFontStruct *fontstruct;
        XRotFontStruct *rotfont;
        int ichar, i, j, index, boxlen = 60, dir;
        int vert_w, vert_h, vert_len, bit_w, bit_h, bit_len;
        int min_char, max_char;
        unsigned char *vertdata, *bitdata;
        int ascent, descent, lbearing, rbearing;
        int on = 1, off = 0;
 150  
        /* make angle positive ... */
        if (angle < 0) do angle += 360; while (angle < 0);
      
        /* get nearest vertical or horizontal direction ... */
        dir = (int)((angle+45.)/90.)%4;
      
        /* useful macros ... */
        screen = DefaultScreen(dpy);
        root = DefaultRootWindow(dpy);
 160  
        /* create the depth 1 canvas bitmap ... */
        canvas = XCreatePixmap(dpy, root, boxlen, boxlen, 1);
       
        /* create a GC ... */
        font_gc = XCreateGC(dpy, canvas, 0, 0);
        XSetBackground(dpy, font_gc, off);
      
        /* load the font ... */
      #if I18N
 170    char **ml;
        int mc;
        char *ds;
      
        XFontSet fontset;
        fontset = XCreateFontSet(dpy, fontname, &ml, &mc, &ds);
        if (fontset) {
          XFontStruct **fs_list;
          XFontsOfFontSet(fontset, &fs_list, &ml);
          fontstruct = fs_list[0];
 180    } else {
          fontstruct = NULL;
        }
      #define XTextWidth(x,y,z)     XmbTextEscapement(rotfont->xfontset,y,z)
      #define XDrawString(t,u,v,w,x,y,z) XmbDrawString(t,u,rotfont->xfontset,v,w,x,y,z)
      #define XDrawImageString(t,u,v,w,x,y,z) XmbDrawString(t,u,rotfont->xfontset,v,w,x,y,z)
      #else
        fontstruct = XLoadQueryFont(dpy, fontname);
      #endif
        if (fontstruct == NULL) {
 190      xv_errno = XV_NOFONT;
          return NULL;
        }
       
        XSetFont(dpy, font_gc, fontstruct->fid);
      
        /* allocate space for rotated font ... */
        rotfont = (XRotFontStruct *)malloc((unsigned)sizeof(XRotFontStruct));
        if (rotfont == NULL) {
          xv_errno = XV_NOMEM;
 200      return NULL;
        }
         
        /* determine which characters are defined in font ... */
        min_char = fontstruct->min_char_or_byte2; 
        max_char = fontstruct->max_char_or_byte2;
       
        /* we only want printing characters ... */
        if (min_char<32)  min_char = 32;
        if (max_char>126) max_char = 126;
 210       
        /* some overall font data ... */
        rotfont->name = my_strdup(fontname);
        rotfont->dir = dir;
        rotfont->min_char = min_char;
        rotfont->max_char = max_char;
        rotfont->max_ascent = fontstruct->max_bounds.ascent;
        rotfont->max_descent = fontstruct->max_bounds.descent;   
        rotfont->height = rotfont->max_ascent+rotfont->max_descent;
      
 220    /* remember xfontstruct for `normal' text ... */
      #if NOPIXMAP
      #if I18N
        rotfont->xfontset = fontset;
      #endif
        rotfont->xfontstruct = fontstruct;
      #else
      #if I18N
        PIXMAP implementation cannot treat I18N
      #endif
 230    if (dir == 0) rotfont->xfontstruct = fontstruct;
      
        else {
          /* font needs rotation ... */
          /* loop through each character ... */
          for (ichar = min_char; ichar <= max_char; ichar++) {
      
            index = ichar-fontstruct->min_char_or_byte2;
       
            /* per char dimensions ... */
 240        ascent =   rotfont->per_char[ichar-32].ascent = 
              fontstruct->per_char[index].ascent;
            descent =  rotfont->per_char[ichar-32].descent = 
              fontstruct->per_char[index].descent;
            lbearing = rotfont->per_char[ichar-32].lbearing = 
              fontstruct->per_char[index].lbearing;
            rbearing = rotfont->per_char[ichar-32].rbearing = 
              fontstruct->per_char[index].rbearing;
            rotfont->per_char[ichar-32].width = 
              fontstruct->per_char[index].width;
 250  
            /* some space chars have zero body, but a bitmap can't have ... */
            if (!ascent && !descent)   
              ascent =   rotfont->per_char[ichar-32].ascent =   1;
            if (!lbearing && !rbearing) 
              rbearing = rotfont->per_char[ichar-32].rbearing = 1;
      
            /* glyph width and height when vertical ... */
            vert_w = rbearing-lbearing;
            vert_h = ascent+descent;
 260  
            /* width in bytes ... */
            vert_len = (vert_w-1)/8+1;   
       
            XSetForeground(dpy, font_gc, off);
            XFillRectangle(dpy, canvas, font_gc, 0, 0, boxlen, boxlen);
      
            /* draw the character centre top right on canvas ... */
            sprintf(text, "%c", ichar);
            XSetForeground(dpy, font_gc, on);
 270        XDrawImageString(dpy, canvas, font_gc, boxlen/2 - lbearing,
                             boxlen/2 - descent, text, 1);
      
            /* reserve memory for first XImage ... */
            vertdata = (unsigned char *) malloc((unsigned)(vert_len*vert_h));
            if (vertdata == NULL) {
              xv_errno = XV_NOMEM;
              return NULL;
            }
        
 280        /* create the XImage ... */
            I1 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap,
                              0, (char *)vertdata, vert_w, vert_h, 8, 0);
      
            if (I1 == NULL) {
              xv_errno = XV_NOXIMAGE;
              return NULL;
            }
        
            I1->byte_order = I1->bitmap_bit_order = MSBFirst;
 290     
            /* extract character from canvas ... */
            XGetSubImage(dpy, canvas, boxlen/2, boxlen/2-vert_h,
                         vert_w, vert_h, 1, XYPixmap, I1, 0, 0);
            I1->format = XYBitmap; 
       
            /* width, height of rotated character ... */
            if (dir == 2) { 
              bit_w = vert_w;
              bit_h = vert_h; 
 300        } else {
              bit_w = vert_h;
              bit_h = vert_w; 
            }
      
            /* width in bytes ... */
            bit_len = (bit_w-1)/8 + 1;
      
            rotfont->per_char[ichar-32].glyph.bit_w = bit_w;
            rotfont->per_char[ichar-32].glyph.bit_h = bit_h;
 310  
            /* reserve memory for the rotated image ... */
            bitdata = (unsigned char *)calloc((unsigned)(bit_h*bit_len), 1);
            if (bitdata == NULL) {
              xv_errno = XV_NOMEM;
              return NULL;
            }
      
            /* create the image ... */
            I2 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0,
 320                          (char *)bitdata, bit_w, bit_h, 8, 0); 
       
            if (I2 == NULL) {
              xv_errno = XV_NOXIMAGE;
              return NULL;
            }
      
            I2->byte_order = I2->bitmap_bit_order = MSBFirst;
       
            /* map vertical data to rotated character ... */
 330        for (j = 0; j < bit_h; j++) {
              for (i = 0; i < bit_w; i++) {
                /* map bits ... */
                if (dir == 1)
                  val = vertdata[i*vert_len + (vert_w-j-1)/8] &
                    (128>>((vert_w-j-1)%8));
         
                else if (dir == 2)
                  val = vertdata[(vert_h-j-1)*vert_len + (vert_w-i-1)/8] &
                    (128>>((vert_w-i-1)%8));
 340                      
                else 
                  val = vertdata[(vert_h-i-1)*vert_len + j/8] & 
                    (128>>(j%8));
              
                if (val) 
                  bitdata[j*bit_len + i/8] = bitdata[j*bit_len + i/8] |
                    (128>>(i%8));
              }
            }
 350     
            /* create this character's bitmap ... */
            rotfont->per_char[ichar-32].glyph.bm = 
              XCreatePixmap(dpy, root, bit_w, bit_h, 1);
           
            /* put the image into the bitmap ... */
            XPutImage(dpy, rotfont->per_char[ichar-32].glyph.bm, 
                      font_gc, I2, 0, 0, 0, 0, bit_w, bit_h);
        
            /* free the image and data ... */
 360        XDestroyImage(I1);
            XDestroyImage(I2);
            /*      free((char *)bitdata);  -- XDestroyImage does this
                    free((char *)vertdata);*/
          }
      
          XFreeFont(dpy, fontstruct);
        }
      #endif
      
 370    /* free pixmap and GC ... */
        XFreePixmap(dpy, canvas);
        XFreeGC(dpy, font_gc);
      
        return rotfont;
      }
      
      
      /* ---------------------------------------------------------------------- */
      
 380  
      /* *** Free the resources associated with a rotated font *** */
      
      void XRotUnloadFont(Display *dpy, XRotFontStruct *rotfont)
      {
        int ichar;
      
      #if NOPIXMAP
      #if I18N
        XFreeFontSet(dpy, rotfont->xfontset);
 390  #else
        XFreeFont(dpy, rotfont->xfontstruct);
      #endif
      #else
      #if I18N
        PIXMAP implementation cannot treat I18N
      #endif
        if (rotfont->dir == 0) XFreeFont(dpy, rotfont->xfontstruct);
      
        else
 400      /* loop through each character, freeing its pixmap ... */
          for (ichar = rotfont->min_char-32; ichar <= rotfont->max_char-32; ichar++)
            XFreePixmap(dpy, rotfont->per_char[ichar].glyph.bm);
      #endif
      
        /* rotfont should never be referenced again ... */
        free((char *)rotfont->name);
        free((char *)rotfont);
      }
      
 410  
      /* ---------------------------------------------------------------------- */
         
      
      /* *** Return the width of a string *** */
      
      int XRotTextWidth(XRotFontStruct *rotfont, char *str, int len)
      {
        int i, width = 0, ichar;
      
 420    if (str == NULL) return 0;
      
      #if NOPIXMAP
        width = XTextWidth(rotfont->xfontstruct, str, strlen(str));
      #else
        if (rotfont->dir == 0)
          width = XTextWidth(rotfont->xfontstruct, str, strlen(str));
      
        else
          for (i = 0; i<len; i++) {
 430        ichar = str[i]-32;
        
            /* make sure it's a printing character ... */
            if (ichar >= 0 && ichar<95) 
              width += rotfont->per_char[ichar].width;
          }
      #endif
      
        return width;
      }
 440  
      
      /* ---------------------------------------------------------------------- */
      
      
      /* *** A front end to XRotPaintString : mimics XDrawString *** */
      
      void XRotDrawString(Display *dpy, XRotFontStruct *rotfont, Drawable drawable,
                          GC gc, int x, int y, char *str, int len)
      {            
 450    static GC my_gc = 0;
        int i, xp, yp, dir, ichar;
      
        if (str == NULL || len<1) return;
      
        dir = rotfont->dir;
        if (my_gc == 0) my_gc = XCreateGC(dpy, drawable, 0, 0);
      
        XCopyGC(dpy, gc, GCForeground|GCBackground, my_gc);
      
 460  #if NOPIXMAP
        /* a horizontal string is easy ... */
        if (dir == 0) {
          XSetFillStyle(dpy, my_gc, FillSolid);
          XSetFont(dpy, my_gc, rotfont->xfontstruct->fid);
          XDrawString(dpy, drawable, my_gc, x, y, str, len);
      
          return;
        }
      
 470    /* vertical or upside down ... */
      
        XImage *I1, *I2;
        unsigned char *vertdata, *bitdata;
        int vert_w, vert_h, vert_len, bit_w, bit_h, bit_len;
        char val;
      
        /* useful macros ... */
        int screen = DefaultScreen(dpy);
        Window root = DefaultRootWindow(dpy);
 480  
        int ascent = rotfont->max_ascent;
        int descent = rotfont->max_descent;
        int width = XRotTextWidth(rotfont, str, len);
        int height = rotfont->height;
        if (width < 1) width = 1;
        if (height < 1) height = 1;
      
        /* glyph width and height when vertical ... */
        vert_w = width;
 490    vert_h = height;
      
        /* width in bytes ... */
        vert_len = (vert_w-1)/8+1;   
       
        /* create the depth 1 canvas bitmap ... */
        Pixmap canvas = XCreatePixmap(dpy, root, width, height, 1);
      
        /* create a GC ... */
        GC font_gc = XCreateGC(dpy, canvas, 0, 0);
 500    XSetBackground(dpy, font_gc, 0);
      
        /* clear canvas */
        XSetForeground(dpy, font_gc, 0);
        XFillRectangle(dpy, canvas, font_gc, 0, 0, width, height);
      
        /* draw the character centre top right on canvas ... */
        XSetForeground(dpy, font_gc, 1);
        XSetFont(dpy, font_gc, rotfont->xfontstruct->fid);
        XDrawImageString(dpy, canvas, font_gc, 0, height-descent, str, len);
 510  
        /* reserve memory for first XImage ... */
        vertdata = (unsigned char *) malloc((unsigned)(vert_len*vert_h));
        if (vertdata == NULL) {
          xv_errno = XV_NOMEM;
          return;
        }
      
        /* create the XImage ... */
        I1 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap,
 520                      0, (char *)vertdata, vert_w, vert_h, 8, 0);
      
        if (I1 == NULL) {
          xv_errno = XV_NOXIMAGE;
          return;
        }
      
        I1->byte_order = I1->bitmap_bit_order = MSBFirst;
      
        /* extract character from canvas ... */
 530    XGetSubImage(dpy, canvas, 0, 0,
                     vert_w, vert_h, 1, XYPixmap, I1, 0, 0);
        I1->format = XYBitmap; 
      
        /* width, height of rotated character ... */
        if (dir == 2) { 
          bit_w = vert_w;
          bit_h = vert_h; 
        } else {
          bit_w = vert_h;
 540      bit_h = vert_w; 
        }
      
        /* width in bytes ... */
        bit_len = (bit_w-1)/8 + 1;
      
        /* reserve memory for the rotated image ... */
        bitdata = (unsigned char *)calloc((unsigned)(bit_h*bit_len), 1);
        if (bitdata == NULL) {
          xv_errno = XV_NOMEM;
 550      return;
        }
      
        /* create the image ... */
        I2 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0,
                          (char *)bitdata, bit_w, bit_h, 8, 0); 
      
        if (I2 == NULL) {
          xv_errno = XV_NOXIMAGE;
          return;
 560    }
      
        I2->byte_order = I2->bitmap_bit_order = MSBFirst;
      
        /* map vertical data to rotated character ... */
        int j;
        for (j = 0; j < bit_h; j++) {
          for (i = 0; i < bit_w; i++) {
            /* map bits ... */
            if (dir == 1)
 570          val = vertdata[i*vert_len + (vert_w-j-1)/8] &
                (128>>((vert_w-j-1)%8));
      
            else if (dir == 2)
              val = vertdata[(vert_h-j-1)*vert_len + (vert_w-i-1)/8] &
                (128>>((vert_w-i-1)%8));
                      
            else 
              val = vertdata[(vert_h-i-1)*vert_len + j/8] & 
                (128>>(j%8));
 580      
            if (val) 
              bitdata[j*bit_len + i/8] = bitdata[j*bit_len + i/8] |
                (128>>(i%8));
          }
        }
      
        /* create this character's bitmap ... */
        Pixmap image = XCreatePixmap(dpy, root, bit_w, bit_h, 1);
           
 590    /* put the image into the bitmap ... */
        XPutImage(dpy, image, font_gc, I2, 0, 0, 0, 0, bit_w, bit_h);
        
        /* free the image and data ... */
        XDestroyImage(I1);
        XDestroyImage(I2);
        /*      free((char *)bitdata);  -- XDestroyImage does this
                free((char *)vertdata);*/
      
        /* free pixmap and GC ... */
 600    XFreePixmap(dpy, canvas);
        XFreeGC(dpy, font_gc);
      
        /* suitable offset ... */
        if (dir == 1) {
          xp = x-rotfont->max_ascent;
          yp = y-width; //rotfont->rbearing; 
        }
        else if (dir == 2) {
          xp = x-width; //rotfont->rbearing;
 610      yp = y-rotfont->max_descent+1;
        }
        else {
          xp = x-rotfont->max_descent+1;
          yp = y+0; //rotfont->lbearing; 
        }
      
        XSetFillStyle(dpy, my_gc, FillStippled);
        XSetStipple(dpy, my_gc, image);
        XSetTSOrigin(dpy, my_gc, xp, yp);
 620    XFillRectangle(dpy, drawable, my_gc, xp, yp,
                       bit_w, bit_h);
      
        XFreePixmap(dpy, image);
      #else
        /* a horizontal string is easy ... */
        if (dir == 0) {
          XSetFillStyle(dpy, my_gc, FillSolid);
          XSetFont(dpy, my_gc, rotfont->xfontstruct->fid);
          XDrawString(dpy, drawable, my_gc, x, y, str, len);
 630  
          return;
        }
      
        /* vertical or upside down ... */
      
        XSetFillStyle(dpy, my_gc, FillStippled);
      
        /* loop through each character in string ... */
        for (i = 0; i<len; i++) {
 640      ichar = str[i]-32;
      
          /* make sure it's a printing character ... */
          if (ichar >= 0 && ichar<95) {
            /* suitable offset ... */
            if (dir == 1) {
              xp = x-rotfont->per_char[ichar].ascent;
              yp = y-rotfont->per_char[ichar].rbearing; 
            }
            else if (dir == 2) {
 650          xp = x-rotfont->per_char[ichar].rbearing;
              yp = y-rotfont->per_char[ichar].descent+1; 
            }
            else {
              xp = x-rotfont->per_char[ichar].descent+1;  
              yp = y+rotfont->per_char[ichar].lbearing; 
            }
                         
            /* draw the glyph ... */
            XSetStipple(dpy, my_gc, rotfont->per_char[ichar].glyph.bm);
 660      
            XSetTSOrigin(dpy, my_gc, xp, yp);
            
            XFillRectangle(dpy, drawable, my_gc, xp, yp,
                           rotfont->per_char[ichar].glyph.bit_w,
                           rotfont->per_char[ichar].glyph.bit_h);
          
            /* advance position ... */
            if (dir == 1)
              y -= rotfont->per_char[ichar].width;
 670        else if (dir == 2)
              x -= rotfont->per_char[ichar].width;
            else 
              y += rotfont->per_char[ichar].width;
          }
        }
      #endif
      }
      
        
 680      
      /* ---------------------------------------------------------------------- */
      
      
      /* *** A front end to XRotPaintAlignedString : uses XRotDrawString *** */
      
      void XRotDrawAlignedString(Display *dpy, XRotFontStruct *rotfont,
                                 Drawable drawable, GC gc, int x, int y,
                                 char *text, int align)
      {  
 690    int xp = 0, yp = 0, dir;
        int i, nl = 1, max_width = 0, this_width;
        char *str1, *str2 = "\n\0", *str3;
      
        if (text == NULL) 
          return;
        
        dir = rotfont->dir;
      
        /* count number of sections in string ... */
 700    for (i = 0; i<strlen(text); i++) 
          if (text[i] == '\n') 
            nl++;
      
        /* find width of longest section ... */
        str1 = my_strdup(text);
        str3 = my_strtok(str1, str2);
        max_width = XRotTextWidth(rotfont, str3, strlen(str3));
      
        do {
 710      str3 = my_strtok((char *)NULL, str2);
          if (str3 != NULL)
            if (XRotTextWidth(rotfont, str3, strlen(str3))>max_width)
              max_width = XRotTextWidth(rotfont, str3, strlen(str3));
        }
        while (str3 != NULL);
       
        /* calculate vertical starting point according to alignment policy and
           rotation angle ... */
        if (dir == 0) {
 720      if (align == TLEFT || align == TCENTRE || align == TRIGHT)
            yp = y+rotfont->max_ascent;
      
          else if (align == BLEFT || align == BCENTRE || align == BRIGHT)
            yp = y-(nl-1)*rotfont->height - rotfont->max_descent;
      
          else 
            yp = y-(nl-1)/2*rotfont->height + rotfont->max_ascent -
              rotfont->height/2 - ((nl%2 == 0)?rotfont->height/2:0); 
        }
 730  
        else if (dir == 1) {
          if (align == TLEFT || align == TCENTRE || align == TRIGHT)
            xp = x+rotfont->max_ascent;
      
          else if (align == BLEFT || align == BCENTRE || align == BRIGHT)
            xp = x-(nl-1)*rotfont->height - rotfont->max_descent;
      
          else 
            xp = x-(nl-1)/2*rotfont->height + rotfont->max_ascent -
 740          rotfont->height/2 - ((nl%2 == 0)?rotfont->height/2:0); 
        }
      
        else if (dir == 2) {
          if (align == TLEFT || align == TCENTRE || align == TRIGHT)
            yp = y-rotfont->max_ascent;
           
          else if (align == BLEFT || align == BCENTRE || align == BRIGHT)
            yp = y+(nl-1)*rotfont->height + rotfont->max_descent;
           
 750      else 
            yp = y+(nl-1)/2*rotfont->height - rotfont->max_ascent +
              rotfont->height/2 + ((nl%2 == 0)?rotfont->height/2:0); 
        }
      
        else {
          if (align == TLEFT || align == TCENTRE || align == TRIGHT)
            xp = x-rotfont->max_ascent;
          
          else if (align == BLEFT || align == BCENTRE || align == BRIGHT)
 760        xp = x+(nl-1)*rotfont->height + rotfont->max_descent;
        
          else 
            xp = x+(nl-1)/2*rotfont->height - rotfont->max_ascent +
              rotfont->height/2 + ((nl%2 == 0)?rotfont->height/2:0); 
        }
      
        free(str1);
        str1 = my_strdup(text);
        str3 = my_strtok(str1, str2);
 770    
        /* loop through each section in the string ... */
        do {
          /* width of this section ... */
          this_width = XRotTextWidth(rotfont, str3, strlen(str3));
      
          /* horizontal alignment ... */
          if (dir == 0) {
            if (align == TLEFT || align == MLEFT || align == BLEFT)
              xp = x;
 780    
            else if (align == TCENTRE || align == MCENTRE || align == BCENTRE)
              xp = x-this_width/2;
       
            else 
              xp = x-max_width; 
          }   
      
          else if (dir == 1) {
            if (align == TLEFT || align == MLEFT || align == BLEFT)
 790          yp = y;
      
            else if (align == TCENTRE || align == MCENTRE || align == BCENTRE)
              yp = y+this_width/2;
      
            else 
              yp = y+max_width; 
          }
      
          else if (dir == 2) {
 800        if (align == TLEFT || align == MLEFT || align == BLEFT)
              xp = x;
        
            else if (align == TCENTRE || align == MCENTRE || align == BCENTRE)
              xp = x+this_width/2;
       
            else 
              xp = x+max_width; 
          }
      
 810      else {
            if (align == TLEFT || align == MLEFT || align == BLEFT)  
              yp = y;
           
            else if (align == TCENTRE || align == MCENTRE || align == BCENTRE)
              yp = y-this_width/2;
           
            else 
              yp = y-max_width; 
          }
 820  
          /* draw the section ... */
          XRotDrawString(dpy, rotfont, drawable, gc, xp, yp,
                         str3, strlen(str3));
      
          str3 = my_strtok((char *)NULL, str2);
      
          /* advance position ... */
          if (dir == 0)
            yp += rotfont->height;
 830      else if (dir == 1)
            xp += rotfont->height;
          else if (dir == 2)
            yp -= rotfont->height;
          else 
            xp -= rotfont->height;
        }
        while (str3 != NULL);
      
        free(str1);
 840  }
      
      

Index

  • my_strdup (prototype) returns static char *
  • my_strtok (prototype) returns static char *
  • my_strdup (function) returns static char *
  • my_strtok (function) returns static char *
  • XRotVersion (function) returns float
  • XRotLoadFont (function) returns XRotFontStruct *
  • XRotUnloadFont (function) returns void
  • XRotTextWidth (function) returns int
  • XRotDrawString (function) returns void
  • XRotDrawAlignedString (function) returns void