home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part19 / w_drawprim.c
Encoding:
C/C++ Source or Header  |  1993-05-27  |  36.9 KB  |  985 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  4.  * Copyright (c) 1992 by Brian V. Smith
  5.  *
  6.  * "Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both the copyright
  9.  * notice and this permission notice appear in supporting documentation. 
  10.  * No representations are made about the suitability of this software for 
  11.  * any purpose.  It is provided "as is" without express or implied warranty."
  12.  */
  13.  
  14. /*
  15.  * This file provides some drawing primitives which make use of the
  16.  * underlying low-level windowing system operations.
  17.  *
  18.  * The file is divided into routines for:
  19.  *
  20.  * GRAPHICS CONTEXTS (which are used by all the following)
  21.  * FONTS
  22.  * LINES
  23.  * SHADING
  24.  */
  25.  
  26. /* IMPORTS */
  27.  
  28. #include "fig.h"
  29. #include "figx.h"
  30. #include "resources.h"
  31. #include "paintop.h"
  32. #include "mode.h"
  33. #include "object.h"
  34. #include "u_fonts.h"
  35. #include "w_canvas.h"
  36. #include "w_drawprim.h"
  37. #include "w_icons.h"        /* for none_ic in init_fill_pm */
  38. #include "w_indpanel.h"
  39. #include "w_setup.h"
  40. #include "w_util.h"
  41. #include "w_zoom.h"
  42.  
  43. extern struct _xfstruct x_fontinfo[NUM_X_FONTS];
  44. extern struct _fstruct ps_fontinfo[];    /* font names */
  45. extern choice_info fillstyle_choices[];
  46.  
  47. /* EXPORTS */
  48.  
  49. PIX_FONT    bold_font;
  50. PIX_FONT    roman_font;
  51. PIX_FONT    button_font;
  52. PIX_ROT_FONT    canvas_font;
  53.  
  54. /* LOCAL */
  55.  
  56. static Pixel    gc_color[NUMOPS];
  57. static XRectangle clip[1];
  58. static pr_size    pfx_textwidth();
  59. static int    parsesize();
  60.  
  61. #define MAXNAMES 35
  62.  
  63. static struct {
  64.     char       *fn;
  65.     int            s;
  66. }        flist[MAXNAMES];
  67.  
  68. init_font()
  69. {
  70.     struct xfont   *newfont, *nf;
  71.     int            f, count, i, p, ss;
  72.     char        template[200];
  73.     char      **fontlist, **fname;
  74.  
  75.     if (appres.boldFont == NULL || *appres.boldFont == '\0')
  76.     appres.boldFont = BOLD_FONT;
  77.     if (appres.normalFont == NULL || *appres.normalFont == '\0')
  78.     appres.normalFont = NORMAL_FONT;
  79.     if (appres.buttonFont == NULL || *appres.buttonFont == '\0')
  80.     appres.buttonFont = BUTTON_FONT;
  81.  
  82.     roman_font = XLoadQueryFont(tool_d, appres.normalFont);
  83.     hidden_text_length = 4 * roman_font->max_bounds.width;
  84.     if ((bold_font = XLoadQueryFont(tool_d, appres.boldFont)) == 0) {
  85.     fprintf(stderr, "Can't load font: %s, using %s\n",
  86.         appres.boldFont, appres.normalFont);
  87.     bold_font = XLoadQueryFont(tool_d, appres.normalFont);
  88.     }
  89.     if ((button_font = XLoadQueryFont(tool_d, appres.buttonFont)) == 0) {
  90.     fprintf(stderr, "Can't load font: %s, using %s\n",
  91.         appres.buttonFont, appres.normalFont);
  92.     button_font = XLoadQueryFont(tool_d, appres.normalFont);
  93.     }
  94.     /*
  95.      * Now initialize the font structure for the X fonts corresponding to the
  96.      * Postscript fonts for the canvas.     OpenWindows can use any LaserWriter
  97.      * fonts at any size, so we don't need to load anything if we are using
  98.      * it.
  99.      */
  100.  
  101. #ifndef OPENWIN
  102.     /* if the user asked for scalable fonts, check that the server 
  103.        really has them by checking for font of 0-0 size */
  104.     if (appres.SCALABLEFONTS) {
  105.     strcpy(template,x_fontinfo[0].template);  /* just check the first font */
  106.     strcat(template,"0-0-*-*-*-*-*-*");
  107.     if ((fontlist = XListFonts(tool_d, template, 1, &count))==0)
  108.         appres.SCALABLEFONTS = False;    /* none, turn off request for them */
  109.     }
  110.  
  111.     /* X11R5 has scalable fonts - skip next section in that case */
  112.     if (!appres.SCALABLEFONTS) {
  113.     for (f = 0; f < NUM_X_FONTS; f++) {
  114.         nf = NULL;
  115.         strcpy(template,x_fontinfo[f].template);
  116.         strcat(template,"*-*-*-*-*-*-");
  117.         /* add ISO8859 (if not Symbol font or ZapfDingbats) to font name */
  118.         if (strstr(template,"symbol") == NULL && 
  119.         strstr(template,"zapfdingbats") == NULL)
  120.             strcat(template,"ISO8859-*");
  121.         else
  122.         strcat(template,"*-*");
  123.         /* don't free the Fontlist because we keep pointers into it */
  124.         p = 0;
  125.         if ((fontlist = XListFonts(tool_d, template, MAXNAMES, &count))==0) {
  126.         /* no fonts by that name found, substitute the -normal font name */
  127.         flist[p].fn = appres.normalFont;
  128.         flist[p++].s = 12;    /* just set the size to 12 */
  129.         } else {
  130.         fname = fontlist; /* go through the list finding point
  131.                    * sizes */
  132.         while (count--) {
  133.         ss = parsesize(*fname);    /* get the point size from
  134.                      * the name */
  135.         flist[p].fn = *fname++;    /* save name of this size
  136.                      * font */
  137.         flist[p++].s = ss;    /* and save size */
  138.         }
  139.         }
  140.         for (ss = 4; ss <= 50; ss++) {
  141.         for (i = 0; i < p; i++)
  142.             if (flist[i].s == ss)
  143.                 break;
  144.         if (i < p && flist[i].s == ss) {
  145.             newfont = (struct xfont *) malloc(sizeof(struct xfont));
  146.             if (nf == NULL)
  147.                 x_fontinfo[f].xfontlist = newfont;
  148.             else
  149.                 nf->next = newfont;
  150.             nf = newfont;    /* keep current ptr */
  151.             nf->size = ss;    /* store the size here */
  152.             nf->fname = flist[i].fn;    /* keep actual name */
  153.             nf->list = NULL;
  154.             nf->next = NULL;
  155.             }
  156.         } /* next size */
  157.     } /* next font, f */
  158.     } /* !appres.SCALABLEFONTS */
  159. #endif /* OPENWIN */
  160. }
  161.  
  162. /* parse the point size of font 'name' */
  163. /* e.g. -adobe-courier-bold-o-normal--10-100-75-75-m-60-ISO8859-1 */
  164.  
  165. static int
  166. parsesize(name)
  167.     char       *name;
  168. {
  169.     int            s;
  170.     char       *np;
  171.  
  172.     for (np = name; *(np + 1); np++)
  173.     if (*np == '-' && *(np + 1) == '-')    /* look for the -- */
  174.         break;
  175.     s = 0;
  176.     if (*(np + 1)) {
  177.     np += 2;        /* point past the -- */
  178.     s = atoi(np);        /* get the point size */
  179.     } else
  180.     fprintf(stderr, "Can't parse '%s'\n", name);
  181.     return s;
  182. }
  183.  
  184. /*
  185.  * Lookup an X font corresponding to a Postscript font style that is close in
  186.  * size and with angle "angle"
  187.  */
  188.  
  189. PIX_ROT_FONT
  190. lookfont(f, s, angle)
  191.     int            f, s;
  192.     float        angle;
  193. {
  194.     struct xfont   *xf;
  195.     PIX_ROT_FONT   fontst;
  196.     int           dir;
  197.  
  198.     /*** Must fix the following to actually return the "-normal font" ROTATED font */
  199.     if (f == DEFAULT)
  200.     f = 0;        /* pass back the -normal font font */
  201.     if (s < 0)
  202.     s = DEF_FONTSIZE;    /* default font size */
  203.  
  204. #ifdef OPENWIN
  205.   {
  206.     /* to search for OpenWindows font - see below */
  207.     char        fn[128];
  208.     int            i;
  209.  
  210.     for (i = 1; i < NUM_PS_FONTS + 1; i++)
  211.     if (ps_fontinfo[i].xfontnum == f)
  212.         {
  213.         sprintf(fn, "%s-%d", ps_fontinfo[i].name, s);
  214.         break;
  215.         }
  216.  
  217.     for (i = strlen(fn) - 1; i >= 0; i--)
  218.     if (isupper(fn[i]))
  219.         fn[i] = tolower(fn[i]);
  220.     if (appres.DEBUG)
  221.     fprintf(stderr, "Loading font %s\n", fn);
  222.     set_temp_cursor(wait_cursor);
  223.     app_flush();
  224.     fontst = XRotLoadFont(tool_d, fn, angle);
  225.     if (fontst == NULL) {
  226.     fprintf(stderr, "xfig: Can't load font %s ?!, using %s\n",
  227.         fn, appres.normalFont);
  228.     fontst = XRotLoadFont(tool_d, appres.normalFont, angle);
  229.     }
  230.     reset_cursor();
  231.     return (fontst);
  232.   }
  233.  
  234. #else
  235.   {
  236.     char        fn[128];
  237.     char        template[200];
  238.     Boolean        found;
  239.     struct xfont   *newfont, *nf, *oldnf;
  240.     struct flist   *lp, *nlp, *oldlp;
  241.  
  242.     /* see if we've already loaded that font size 's' at angle 'angle' 
  243.        from the font family 'f' */
  244.     /* actually, we've reduced the number of angles to four - 0, 90, 180 and 270 */
  245.     if (angle < 0.0)
  246.         angle += 2.0*M_PI;
  247.     dir = (int)(angle/M_PI_2+0.0001);
  248.     if (dir > 3)
  249.         dir -= 4;
  250.     found = False;
  251.     /* start with the basic font name (e.g. adobe-times-medium-r-normal-...) */
  252.     nf = x_fontinfo[f].xfontlist;
  253.     oldnf = nf;
  254.     if (nf != NULL) {
  255.         if (nf->size > s && !appres.SCALABLEFONTS)
  256.         found = True;
  257.         else while (nf != NULL){
  258.         if (nf->size == s || (!appres.SCALABLEFONTS &&
  259.              (nf->size >= s && oldnf->size <= s ))) {
  260.         found = True;
  261.         break;
  262.         }
  263.         oldnf = nf;
  264.         nf = nf->next;
  265.         }
  266.     }
  267.     if (found) {        /* found exact size (or only larger available) */
  268.         strcpy(fn,nf->fname);  /* put the name in fn */
  269.         if (s < nf->size)
  270.         put_msg("Font size %d not found, using larger %d point",s,nf->size);
  271.     } else if (!appres.SCALABLEFONTS) {    /* not found, use largest available */
  272.         nf = oldnf;
  273.         strcpy(fn,nf->fname);  /* put the name in fn */
  274.         if (s > nf->size)
  275.         put_msg("Font size %d not found, using smaller %d point",s,nf->size);
  276.     } else { /* SCALABLE; none yet of that size, alloc one and put it in the list */
  277.         newfont = (struct xfont *) malloc(sizeof(struct xfont));
  278.         /* add it on to the end of the list */
  279.         if (x_fontinfo[f].xfontlist == NULL)
  280.             x_fontinfo[f].xfontlist = newfont;
  281.         else
  282.             oldnf->next = newfont;
  283.         nf = newfont;        /* keep current ptr */
  284.         nf->size = s;        /* store the size here */
  285.         nf->list = NULL;
  286.         nf->next = NULL;
  287.  
  288.         /* create a full XLFD font name */
  289.         strcpy(template,x_fontinfo[f].template);
  290.         /* attach pointsize to font name */
  291.         strcat(template,"%d-*-*-*-*-*-");
  292.         /* add ISO8859 (if not Symbol font or ZapfDingbats) to font name */
  293.         if (strstr(template,"symbol") == NULL && 
  294.         strstr(template,"zapfdingbats") == NULL)
  295.             strcat(template,"ISO8859-*");
  296.         else
  297.         strcat(template,"*-*");
  298.         /* use the pixel field instead of points in the fontname so that the
  299.         font scales with screen size */
  300.         sprintf(fn, template, s);
  301.         /* allocate space for the name and put it in the structure */
  302.         nf->fname = (char *) malloc(strlen(fn));
  303.         strcpy(nf->fname, fn);
  304.     } /* if (!found) */
  305.     if (appres.DEBUG)
  306.         fprintf(stderr, "Loading font %s at angle %f (%f)\n", 
  307.             fn, (float) dir*90.0, angle);
  308.     lp = nf->list;
  309.     oldlp = lp;
  310.     found = False;
  311.     while (lp) {
  312.         if (lp->dir == dir) {
  313.             found = True;
  314.             break;
  315.         }
  316.         oldlp = lp;
  317.         lp = lp->next;
  318.     } /* while (lp) */
  319.     if (!found) {
  320.         nlp = (struct flist *) malloc(sizeof(struct flist));
  321.         nlp->next = NULL;
  322.         if (oldlp)
  323.             oldlp->next = nlp;    /* add this to the list */
  324.         else
  325.             nf->list = nlp;        /* first on the list */
  326.         nlp->dir = dir;
  327.         set_temp_cursor(wait_cursor);
  328.         app_flush();
  329.         fontst = XRotLoadFont(tool_d, fn, (float) dir*90.0);
  330.         reset_cursor();
  331.         if (fontst == NULL) {
  332.             fprintf(stderr, "xfig: Can't load font %s ?!, using %s\n",
  333.             fn, appres.normalFont);
  334.             fontst = XRotLoadFont(tool_d, appres.normalFont, (float) dir*90.0);
  335.             nf->fname = fn;    /* keep actual name */
  336.         }
  337.         /* put the structure in the list */
  338.         nlp->fstruct = fontst;
  339.         lp = nlp;
  340.     } /* if (!found) */
  341.     fontst = lp->fstruct;
  342.     return (fontst);
  343.   }
  344.  
  345. #endif                /* !OPENWIN */
  346.  
  347. }
  348.  
  349. /* print "string" in window "w" using font specified in fstruct at (x,y) */
  350.  
  351. pw_text(w, x, y, op, fstruct, string, color)
  352.     Window        w;
  353.     int            x, y, op;
  354.     PIX_ROT_FONT    fstruct;
  355.     char       *string;
  356.     Color        color;
  357. {
  358.     if (fstruct == NULL)
  359.     fprintf(stderr,"Error, in pw_text, fstruct==NULL\n");
  360.     pwx_text(w, x, y, op, fstruct, string, color);
  361. }
  362.  
  363. pwx_text(w, x, y, op, fstruct, string, color)
  364.     Window        w;
  365.     int            x, y, op;
  366.     PIX_ROT_FONT    fstruct;
  367.     char       *string;
  368.     Color        color;
  369. {
  370.     /* if we're drawing to the bitmap instead of the canvas
  371.        map colors white => white, all others => black */
  372.     if (writing_bitmap)
  373.     {
  374.     if (color == WHITE)
  375.         color = 0;
  376.     else
  377.         color = 1;
  378.     }
  379.     if (writing_bitmap? color != gc_color[op] : x_color(color) != gc_color[op]) {
  380.         if (op == PAINT) {
  381.         if (writing_bitmap)
  382.             XSetForeground(tool_d,gccache[op],color);
  383.         else
  384.             set_x_color(gccache[op], color);
  385.         gc_color[op] = writing_bitmap? color : x_color(color);
  386.         }
  387.     }
  388.     zXRotDrawString(tool_d, w, fstruct, gccache[op], x, y, 
  389.             string, strlen(string));
  390. }
  391.  
  392. pr_size
  393. pf_textwidth(fstruct, n, s)
  394.     PIX_ROT_FONT    fstruct;
  395.     int            n;
  396.     char       *s;
  397. {
  398.     pr_size        ret;
  399.  
  400.     ret.x = XRotTextWidth(fstruct, s, n);
  401.     ret.y = XRotTextHeight(fstruct, s, n);
  402.     return (ret);
  403. }
  404.  
  405. /* LINES */
  406.  
  407. static int    gc_thickness[NUMOPS], gc_line_style[NUMOPS];
  408.  
  409. static        GC
  410. makegc(op, fg, bg)
  411.     int            op;
  412.     Pixel        fg;
  413.     Pixel        bg;
  414. {
  415.     register GC        ngc;
  416.     XGCValues        gcv;
  417.     unsigned long   gcmask;
  418.  
  419.     gcv.font = roman_font->fid;
  420.     gcv.join_style = JoinMiter;
  421.     gcmask = GCJoinStyle | GCFunction | GCForeground | GCBackground | GCFont;
  422.     switch (op) {
  423.     case PAINT:
  424.     gcv.foreground = fg;
  425.     gcv.background = bg;
  426.     gcv.function = GXcopy;
  427.     break;
  428.     case ERASE:
  429.     gcv.foreground = bg;
  430.     gcv.background = bg;
  431.     gcv.function = GXcopy;
  432.     break;
  433.     case INV_PAINT:
  434.     gcv.foreground = fg ^ bg;
  435.     gcv.background = bg;
  436.     gcv.function = GXxor;
  437.     break;
  438.     case MERGE:
  439.     gcv.foreground = fg;
  440.     gcv.background = bg;
  441.     gcv.function = GXor;
  442.     break;
  443.     }
  444.  
  445.     ngc = XCreateGC(tool_d, XtWindow(canvas_sw), gcmask, &gcv);
  446.     XCopyGC(tool_d, gc, ~(gcmask), ngc);    /* add main gc's values to
  447.                          * the new one */
  448.     return (ngc);
  449. }
  450.  
  451. init_gc()
  452. {
  453.     int            i;
  454.  
  455.     gccache[PAINT] = makegc(PAINT, x_fg_color.pixel, x_bg_color.pixel);
  456.     gccache[ERASE] = makegc(ERASE, x_fg_color.pixel, x_bg_color.pixel);
  457.     gccache[INV_PAINT] = makegc(INV_PAINT, x_fg_color.pixel, x_bg_color.pixel);
  458.     gccache[MERGE] = makegc(MERGE, x_fg_color.pixel, x_bg_color.pixel);
  459.  
  460.     for (i = 0; i < NUMOPS; i++) {
  461.     gc_color[i] = -1;
  462.     gc_thickness[i] = -1;
  463.     gc_line_style[i] = -1;
  464.     }
  465. }
  466.  
  467. /* create the gc's for fill style (PAINT and ERASE) */
  468. /* the fill_pm[] and unfill_pm[] must already be created */
  469.  
  470. init_fill_gc()
  471. {
  472.     XGCValues        gcv;
  473.     int            i;
  474.  
  475.     gcv.fill_style = FillOpaqueStippled;
  476.     gcv.arc_mode = ArcPieSlice; /* fill mode for arcs */
  477.     gcv.fill_rule = EvenOddRule /* WindingRule */ ;
  478.     for (i = 0; i < NUMFILLPATS; i++) {
  479.     /* make color fill pattern with black bg (fg is set later in set_x_color() */
  480.     fill_gc[i] = makegc(PAINT, x_fg_color.pixel, x_color(BLACK));
  481.     un_fill_gc[i] = makegc(ERASE, x_fg_color.pixel, x_color(BLACK));
  482.     /* make black fill pattern with default background */
  483.     black_fill_gc[i] = makegc(PAINT, x_fg_color.pixel, x_bg_color.pixel);
  484.     black_un_fill_gc[i] = makegc(ERASE, x_fg_color.pixel, x_bg_color.pixel);
  485.     gcv.stipple = fill_pm[i];
  486.     XChangeGC(tool_d, fill_gc[i],
  487.           GCStipple | GCFillStyle | GCFillRule | GCArcMode, &gcv);
  488.     XChangeGC(tool_d, black_fill_gc[i],
  489.           GCStipple | GCFillStyle | GCFillRule | GCArcMode, &gcv);
  490.     XChangeGC(tool_d, un_fill_gc[i],
  491.           GCStipple | GCFillStyle | GCArcMode, &gcv);
  492.     XChangeGC(tool_d, black_un_fill_gc[i],
  493.           GCStipple | GCFillStyle | GCArcMode, &gcv);
  494.     }
  495. }
  496.  
  497. /* SHADING */
  498.  
  499. /* grey images for fill patterns (32x32) */
  500.  
  501. static unsigned char fill_images[NUMFILLPATS][128] = {
  502.  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  503.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  504.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  505.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  506.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  507.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  508.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  509.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  510.  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  511.  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x88,0x88,
  512.  0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,
  513.  0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,
  514.  0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  515.  0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  516.  0x00,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  517.  0x00,0x00,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  518.  0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  519.  0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08},
  520.  {0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x00,0x00,0x00,
  521.  0x00,0x01,0x11,0x01,0x11,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x00,0x00,
  522.  0x00,0x00,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x00,
  523.  0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,
  524.  0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x44,0x44,0x44,
  525.  0x44,0x00,0x00,0x00,0x00,0x01,0x11,0x01,0x11,0x00,0x00,0x00,0x00,0x44,0x44,
  526.  0x44,0x44,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x44,
  527.  0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
  528.  0x44,0x44,0x44,0x44,0x00,0x00,0x00,0x00},
  529.  {0x00,0x00,0x00,0x00,0x11,0x51,0x11,0x51,0x00,0x00,0x00,0x00,0x44,0x44,0x44,
  530.  0x44,0x00,0x00,0x00,0x00,0x15,0x15,0x15,0x15,0x00,0x00,0x00,0x00,0x44,0x44,
  531.  0x44,0x44,0x00,0x00,0x00,0x00,0x51,0x11,0x51,0x11,0x00,0x00,0x00,0x00,0x44,
  532.  0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x15,0x15,0x15,0x15,0x00,0x00,0x00,0x00,
  533.  0x44,0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x11,0x51,0x11,0x51,0x00,0x00,0x00,
  534.  0x00,0x44,0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x15,0x15,0x15,0x15,0x00,0x00,
  535.  0x00,0x00,0x44,0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x51,0x11,0x51,0x11,0x00,
  536.  0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x15,0x15,0x15,0x15,
  537.  0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44},
  538.  {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x00,0x8a,0x88,0x8a,
  539.  0x88,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x00,0x88,0x88,
  540.  0x88,0x88,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x00,0x8a,
  541.  0x8a,0x8a,0x8a,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x00,
  542.  0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,
  543.  0x00,0x8a,0x88,0x8a,0x88,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,0x00,
  544.  0x00,0x00,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,0x00,
  545.  0x00,0x00,0x00,0x8a,0x8a,0x8a,0x8a,0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
  546.  0x00,0x00,0x00,0x00,0x88,0x88,0x88,0x88},
  547.  {0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,
  548.  0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,
  549.  0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,
  550.  0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,
  551.  0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,
  552.  0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,
  553.  0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,
  554.  0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,
  555.  0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00},
  556.  {0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x88,0x88,0x88,
  557.  0x88,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x80,0x80,
  558.  0x80,0x80,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x88,
  559.  0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,
  560.  0x88,0x80,0x88,0x80,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,
  561.  0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,
  562.  0x55,0x55,0x80,0x80,0x80,0x80,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,
  563.  0x55,0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,
  564.  0x55,0x55,0x55,0x55,0x88,0x80,0x88,0x80},
  565.  {0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x80,0x80,0x80,0x80,0x55,0x55,0x55,
  566.  0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x88,0x08,0x88,0x08,0x55,0x55,
  567.  0x55,0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x80,0x80,0x80,0x80,0x55,
  568.  0x55,0x55,0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x08,0x08,0x08,0x08,
  569.  0x55,0x55,0x55,0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x80,0x80,0x80,
  570.  0x80,0x55,0x55,0x55,0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x88,0x08,
  571.  0x88,0x08,0x55,0x55,0x55,0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,0x80,
  572.  0x80,0x80,0x80,0x55,0x55,0x55,0x55,0x22,0x22,0x22,0x22,0x55,0x55,0x55,0x55,
  573.  0x08,0x08,0x08,0x08,0x55,0x55,0x55,0x55},
  574.  {0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x22,0xa2,0x22,0xa2,0x55,0x55,0x55,
  575.  0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x2a,0x2a,0x2a,0x2a,0x55,0x55,
  576.  0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0xa2,0x22,0xa2,0x22,0x55,
  577.  0x55,0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x2a,0x2a,0x2a,0x2a,
  578.  0x55,0x55,0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x22,0xa2,0x22,
  579.  0xa2,0x55,0x55,0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0x2a,0x2a,
  580.  0x2a,0x2a,0x55,0x55,0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,0xa2,
  581.  0x22,0xa2,0x22,0x55,0x55,0x55,0x55,0x88,0x88,0x88,0x88,0x55,0x55,0x55,0x55,
  582.  0x2a,0x2a,0x2a,0x2a,0x55,0x55,0x55,0x55},
  583.  {0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x54,0x54,0x54,
  584.  0x54,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x44,0x44,
  585.  0x44,0x44,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x44,
  586.  0x54,0x44,0x54,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,
  587.  0x44,0x44,0x44,0x44,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,
  588.  0xaa,0x54,0x54,0x54,0x54,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,
  589.  0xaa,0xaa,0x44,0x44,0x44,0x44,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,
  590.  0xaa,0xaa,0xaa,0x44,0x54,0x44,0x54,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,
  591.  0xaa,0xaa,0xaa,0xaa,0x44,0x44,0x44,0x44},
  592.  {0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,
  593.  0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,
  594.  0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,
  595.  0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,
  596.  0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,
  597.  0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,
  598.  0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,
  599.  0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,
  600.  0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa},
  601.  {0xdd,0xdd,0xdd,0xdd,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,
  602.  0xaa,0xd5,0xd5,0xd5,0xd5,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,0xaa,
  603.  0xaa,0xaa,0xdd,0xdd,0xdd,0xdd,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,0xaa,
  604.  0xaa,0xaa,0xaa,0xdd,0xd5,0xdd,0xd5,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,0x55,
  605.  0xaa,0xaa,0xaa,0xaa,0xdd,0xdd,0xdd,0xdd,0xaa,0xaa,0xaa,0xaa,0x55,0x55,0x55,
  606.  0x55,0xaa,0xaa,0xaa,0xaa,0xd5,0xd5,0xd5,0xd5,0xaa,0xaa,0xaa,0xaa,0x55,0x55,
  607.  0x55,0x55,0xaa,0xaa,0xaa,0xaa,0xdd,0xdd,0xdd,0xdd,0xaa,0xaa,0xaa,0xaa,0x55,
  608.  0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa,0xdd,0xd5,0xdd,0xd5,0xaa,0xaa,0xaa,0xaa,
  609.  0x55,0x55,0x55,0x55,0xaa,0xaa,0xaa,0xaa},
  610.  {0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xd5,0xd5,0xd5,0xd5,0xaa,0xaa,0xaa,
  611.  0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xdd,0x5d,0xdd,0x5d,0xaa,0xaa,
  612.  0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xd5,0xd5,0xd5,0xd5,0xaa,
  613.  0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0x5d,0xdd,0x5d,0xdd,
  614.  0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xd5,0xd5,0xd5,
  615.  0xd5,0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xdd,0x5d,
  616.  0xdd,0x5d,0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xd5,
  617.  0xd5,0xd5,0xd5,0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,
  618.  0x5d,0xdd,0x5d,0xdd,0xaa,0xaa,0xaa,0xaa},
  619.  {0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,0x55,0x55,0x55,0xfe,0xfe,0xfe,
  620.  0xfe,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,0x55,0x55,0x55,0xee,0xef,
  621.  0xee,0xef,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,0x55,0x55,0x55,0xfe,
  622.  0xfe,0xfe,0xfe,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,0x55,0x55,0x55,
  623.  0xef,0xef,0xef,0xef,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,0x55,0x55,
  624.  0x55,0xfe,0xfe,0xfe,0xfe,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,0x55,
  625.  0x55,0x55,0xee,0xef,0xee,0xef,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,0x55,
  626.  0x55,0x55,0x55,0xfe,0xfe,0xfe,0xfe,0x55,0x55,0x55,0x55,0xbb,0xbb,0xbb,0xbb,
  627.  0x55,0x55,0x55,0x55,0xef,0xef,0xef,0xef},
  628.  {0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,0xaa,0xaa,
  629.  0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x77,0x7f,0x77,0x7f,0xaa,0xaa,
  630.  0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,0x77,0xaa,
  631.  0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x7f,0x7f,0x7f,0x7f,
  632.  0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x77,0x77,0x77,
  633.  0x77,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x77,0x7f,
  634.  0x77,0x7f,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0x77,
  635.  0x77,0x77,0x77,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,
  636.  0x7f,0x7f,0x7f,0x7f,0xaa,0xaa,0xaa,0xaa},
  637.  {0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,
  638.  0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,
  639.  0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,
  640.  0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,
  641.  0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,
  642.  0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,
  643.  0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,
  644.  0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,
  645.  0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa},
  646.  {0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0xdd,0xdd,0xdd,0xdd,0xff,0xff,0xff,
  647.  0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0x5d,0xdd,0x5d,0xdd,0xff,0xff,
  648.  0xff,0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0xdd,0xdd,0xdd,0xdd,0xff,
  649.  0xff,0xff,0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0x5d,0x5d,0x5d,0x5d,
  650.  0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0xdd,0xdd,0xdd,
  651.  0xdd,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0x5d,0xdd,
  652.  0x5d,0xdd,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0xdd,
  653.  0xdd,0xdd,0xdd,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,
  654.  0x5d,0x5d,0x5d,0x5d,0xff,0xff,0xff,0xff},
  655.  {0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xbb,0xba,0xba,0xba,0xff,0xff,0xff,
  656.  0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xab,0xbb,0xab,0xbb,0xff,0xff,
  657.  0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xbb,0xba,0xba,0xba,0xff,
  658.  0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xbb,0xab,0xbb,0xab,
  659.  0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xbb,0xba,0xba,
  660.  0xba,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xab,0xbb,
  661.  0xab,0xbb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xbb,
  662.  0xba,0xba,0xba,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,
  663.  0xbb,0xab,0xbb,0xab,0xff,0xff,0xff,0xff},
  664.  {0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xfb,0xfb,0xfb,
  665.  0xfb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xbf,0xbb,
  666.  0xbf,0xbb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,0xfb,
  667.  0xfb,0xfb,0xfb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,0xff,
  668.  0xbf,0xbf,0xbf,0xbf,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,0xff,
  669.  0xff,0xfb,0xfb,0xfb,0xfb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,0xff,
  670.  0xff,0xff,0xbf,0xbb,0xbf,0xbb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,0xff,
  671.  0xff,0xff,0xff,0xfb,0xfb,0xfb,0xfb,0xff,0xff,0xff,0xff,0xee,0xee,0xee,0xee,
  672.  0xff,0xff,0xff,0xff,0xbf,0xbf,0xbf,0xbf},
  673.  {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbb,0xbb,0xbb,
  674.  0xbb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xfb,
  675.  0xfb,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbb,
  676.  0xbb,0xbb,0xbb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  677.  0xfb,0xfb,0xfb,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  678.  0xff,0xbb,0xbb,0xbb,0xbb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  679.  0xff,0xff,0xfb,0xfb,0xfb,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  680.  0xff,0xff,0xff,0xbb,0xbb,0xbb,0xbb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  681.  0xff,0xff,0xff,0xff,0xfb,0xfb,0xfb,0xfb},
  682.  {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  683.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  684.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  685.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  686.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  687.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  688.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  689.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  690.  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
  691. };
  692.  
  693. /* generate the fill pixmaps */
  694.  
  695. init_fill_pm()
  696. {
  697.     int            i;
  698.  
  699.     for (i = 0; i < NUMFILLPATS + 1; i++) {
  700.     fillstyle_choices[i].value = i;
  701.     fillstyle_choices[i].icon = &none_ic;
  702.     }
  703.     /* use same colors for "NONE" indicator for black and color */
  704.     fillstyle_choices[0].normalPM = 
  705.     fillstyle_choices[0].blackPM = XCreatePixmapFromBitmapData(tool_d,
  706.             XtWindow(ind_panel), (char *) none_ic.data, none_ic.width,
  707.             none_ic.height, x_fg_color.pixel, x_bg_color.pixel,
  708.             DefaultDepthOfScreen(tool_s));
  709.  
  710.     for (i = 0; i < NUMFILLPATS; i++) {
  711.     fill_pm[i] = XCreateBitmapFromData(tool_d, XtWindow(canvas_sw),
  712.                        (char *) fill_images[i], 32, 32);
  713.     /* create fill style pixmaps for indicator button */
  714.     fillstyle_choices[i + 1].normalPM = XCreatePixmapFromBitmapData(tool_d,
  715.          XtWindow(canvas_sw), (char *) fill_images[i], 32, 32, 
  716.          x_bg_color.pixel,x_fg_color.pixel,DefaultDepthOfScreen(tool_s));
  717.     fillstyle_choices[i + 1].blackPM = XCreatePixmapFromBitmapData(tool_d,
  718.          XtWindow(canvas_sw), (char *) fill_images[i], 32, 32, 
  719.          x_fg_color.pixel,x_bg_color.pixel,DefaultDepthOfScreen(tool_s));
  720.     }
  721. }
  722.  
  723. pw_vector(w, x1, y1, x2, y2, op, line_width, line_style, style_val, color)
  724.     Window        w;
  725.     int            x1, y1, x2, y2, op, line_width, line_style;
  726.     float        style_val;
  727.     Color        color;
  728. {
  729.     if (line_width == 0)
  730.     return;
  731.     set_line_stuff(line_width, line_style, style_val, op, color);
  732.     if (line_style == PANEL_LINE)
  733.     XDrawLine(tool_d, w, gccache[op], x1, y1, x2, y2);
  734.     else
  735.     zXDrawLine(tool_d, w, gccache[op], x1, y1, x2, y2);
  736. }
  737.  
  738. pw_curve(w, xstart, ystart, xend, yend,
  739.      op, linewidth, style, style_val, fill_style, color)
  740.     Window        w;
  741.     int            xstart, ystart, xend, yend;
  742.     int            op, linewidth, style, fill_style;
  743.     float        style_val;
  744.     Color        color;
  745. {
  746.     short        xmin, ymin;
  747.     unsigned short  wd, ht;
  748.  
  749.     xmin = (short) min2(xstart, xend);
  750.     ymin = (short) min2(ystart, yend);
  751.     wd = (unsigned short) abs(xstart - xend);
  752.     ht = (unsigned short) abs(ystart - yend);
  753.  
  754.     /* if it's a fill pat we know about */
  755.     if (fill_style >= 1 && fill_style <= NUMFILLPATS) {
  756.     set_fillgc(fill_style, op, color);
  757.     zXFillArc(tool_d, w, fillgc, xmin, ymin, wd, ht, 0, 360 * 64);
  758.     }
  759.     if (linewidth == 0)
  760.     return;
  761.     if (op == ERASE) {
  762.     /* kludge - to speed things up we erase with thick solid lines */
  763.     set_line_stuff(linewidth + 3, SOLID_LINE, 0.0, op, color);    /* +2 or +3 ok */
  764.     zXDrawArc(tool_d, w, gccache[op], xmin, ymin, wd, ht, 0, 360 * 64);
  765.     } else {
  766.     set_line_stuff(linewidth, style, style_val, op, color);
  767.     zXDrawArc(tool_d, w, gccache[op], xmin, ymin, wd, ht, 0, 360 * 64);
  768.     }
  769. }
  770.  
  771. pw_point(w, x, y, line_width, op, color)
  772.     Window        w;
  773.     int            x, y;
  774.     int            op, line_width;
  775.     Color        color;
  776. {
  777.     /* pw_point doesn't use line_style or fill_style - maybe not needed */
  778.     /* (needs color though - hns) */
  779.     set_line_stuff(line_width, SOLID_LINE, 0.0, op, color);
  780.     zXDrawPoint(tool_d, w, gccache[op], x, y);
  781. }
  782.  
  783. pw_arcbox(w, xmin, ymin, xmax, ymax, radius, op,
  784.       line_width, line_style, style_val, fill_style, color)
  785.     Window        w;
  786.     int            xmin, ymin, xmax, ymax, radius;
  787.     int            op, line_width, line_style, fill_style;
  788.     float        style_val;
  789.     Color        color;
  790. {
  791.     GC            gc;
  792.     int            diam = 2 * radius;
  793.  
  794.     /* if it's a fill pat we know about */
  795.     if (fill_style >= 1 && fill_style <= NUMFILLPATS) {
  796.     set_fillgc(fill_style, op, color);
  797.     /* upper left */
  798.     zXFillArc(tool_d, w, fillgc, xmin, ymin, diam, diam, 90 * 64, 90 * 64);
  799.     /* lower left */
  800.     zXFillArc(tool_d, w, fillgc, xmin, ymax - diam, diam, diam,
  801.           180 * 64, 90 * 64);
  802.     /* lower right */
  803.     zXFillArc(tool_d, w, fillgc, xmax - diam, ymax - diam, diam, diam,
  804.           270 * 64, 90 * 64);
  805.     /* upper right */
  806.     zXFillArc(tool_d, w, fillgc, xmax - diam, ymin, diam, diam,
  807.           0 * 64, 90 * 64);
  808.     /* fill strip on left side between upper and lower arcs */
  809.     if (ymax - ymin - diam > 0)
  810.         zXFillRectangle(tool_d, w, fillgc, xmin, ymin + radius, radius,
  811.                 ymax - ymin - diam);
  812.     /* fill middle section */
  813.     if (xmax - xmin - diam > 0)
  814.         zXFillRectangle(tool_d, w, fillgc, xmin + radius, ymin,
  815.                 xmax - xmin - diam, ymax - ymin);
  816.     /* fill strip on right side between upper and lower arcs */
  817.     if (ymax - ymin - diam > 0)
  818.         zXFillRectangle(tool_d, w, fillgc, xmax - radius, ymin + radius,
  819.                 radius, ymax - ymin - diam);
  820.     }
  821.     if (line_width == 0)
  822.     return;
  823.  
  824.     set_line_stuff(line_width, line_style, style_val, op, color);
  825.     gc = gccache[op];
  826.     zXDrawArc(tool_d, w, gc, xmin, ymin, diam, diam, 90 * 64, 90 * 64);
  827.     zXDrawLine(tool_d, w, gc, xmin, ymin + radius, xmin, ymax - radius + 1);
  828.     zXDrawArc(tool_d, w, gc, xmin, ymax - diam, diam, diam, 180 * 64, 90 * 64);
  829.     zXDrawLine(tool_d, w, gc, xmin + radius, ymax, xmax - radius + 1, ymax);
  830.     zXDrawArc(tool_d, w, gc, xmax - diam, ymax - diam,
  831.           diam, diam, 270 * 64, 90 * 64);
  832.     zXDrawLine(tool_d, w, gc, xmax, ymax - radius, xmax, ymin + radius - 1);
  833.     zXDrawArc(tool_d, w, gc, xmax - diam, ymin, diam, diam, 0 * 64, 90 * 64);
  834.     zXDrawLine(tool_d, w, gc, xmax - radius, ymin, xmin + radius - 1, ymin);
  835. }
  836.  
  837. pw_lines(w, points, npoints, op, line_width, line_style, style_val, fill_style, color)
  838.     Window        w;
  839.     int            npoints;
  840.     XPoint       *points;
  841.     int            op, line_width, line_style, fill_style;
  842.     float        style_val;
  843.     Color        color;
  844. {
  845.     /* if it's a fill pat we know about */
  846.     if (fill_style >= 1 && fill_style <= NUMFILLPATS) {
  847.     set_fillgc(fill_style, op, color);
  848.     if (line_style == PANEL_LINE)
  849.         XFillPolygon(tool_d, w, fillgc, points, npoints,
  850.              Complex, CoordModeOrigin);
  851.     else
  852.         zXFillPolygon(tool_d, w, fillgc, points, npoints,
  853.               Complex, CoordModeOrigin);
  854.     }
  855.     if (line_width == 0)
  856.     return;
  857.     set_line_stuff(line_width, line_style, style_val, op, color);
  858.     if (line_style == PANEL_LINE)
  859.     XDrawLines(tool_d, w, gccache[op], points, npoints, CoordModeOrigin);
  860.     else
  861.     zXDrawLines(tool_d, w, gccache[op], points, npoints, CoordModeOrigin);
  862. }
  863.  
  864. set_clip_window(xmin, ymin, xmax, ymax)
  865.     int            xmin, ymin, xmax, ymax;
  866. {
  867.     clip_xmin = clip[0].x = xmin;
  868.     clip_ymin = clip[0].y = ymin;
  869.     clip_xmax = xmax;
  870.     clip_ymax = ymax;
  871.     clip_width = clip[0].width = xmax - xmin;
  872.     clip_height = clip[0].height = ymax - ymin;
  873.     XSetClipRectangles(tool_d, gccache[PAINT], 0, 0, clip, 1, YXBanded);
  874.     XSetClipRectangles(tool_d, gccache[INV_PAINT], 0, 0, clip, 1, YXBanded);
  875. }
  876.  
  877. set_zoomed_clip_window(xmin, ymin, xmax, ymax)
  878.     int            xmin, ymin, xmax, ymax;
  879. {
  880.     set_clip_window(ZOOMX(xmin), ZOOMY(ymin), ZOOMX(xmax), ZOOMY(ymax));
  881. }
  882.  
  883. reset_clip_window()
  884. {
  885.     set_clip_window(0, 0, CANVAS_WD, CANVAS_HT);
  886. }
  887.  
  888. set_fillgc(fill_style, op, color)
  889.     int            fill_style;
  890.     int            op;
  891.     Color        color;
  892. {
  893.     if (op == PAINT) {
  894.     fillgc = ((color==BLACK || 
  895.          (color==DEFAULT_COLOR && x_fg_color.pixel==appres.color[BLACK]) ||
  896.          (!all_colors_available && color!=WHITE))? 
  897.         black_fill_gc[fill_style - 1]: fill_gc[fill_style - 1]);
  898.     if (writing_bitmap)
  899.         {
  900.         if (color == WHITE)
  901.         color = 0;
  902.         else
  903.         color = 1;
  904.         XSetForeground(tool_d,fillgc,color);
  905.         }
  906.     else
  907.         set_x_color(fillgc, color);
  908.     } else
  909.     fillgc = ((color==BLACK || 
  910.          (color==DEFAULT_COLOR && x_fg_color.pixel==appres.color[BLACK]) ||
  911.          (!all_colors_available && color!=WHITE))? 
  912.         black_un_fill_gc[fill_style - 1]: un_fill_gc[fill_style - 1]);
  913.     XSetClipRectangles(tool_d, fillgc, 0, 0, clip, 1, YXBanded);
  914. }
  915.  
  916. set_line_stuff(width, style, style_val, op, color)
  917.     int            width, style, op;
  918.     float        style_val;
  919.     Color        color;
  920. {
  921.     XGCValues        gcv;
  922.     unsigned long   mask;
  923.     static unsigned char dash_list[2] = {-1, -1};
  924.  
  925.     switch (style) {
  926.     case RUBBER_LINE:
  927.     width = 0;
  928.     break;
  929.     case PANEL_LINE:
  930.     break;
  931.     default:
  932.     width = round(zoomscale * width);
  933.     break;
  934.     }
  935.  
  936.     /* user zero-width lines for speed with SOLID lines */
  937.     /* can't do this for dashed lines because server isn't */
  938.     /* required to draw dashes for zero-width lines */
  939.     if (width == 1 && style == SOLID_LINE)
  940.     width = 0;
  941.  
  942.     /* if we're drawing to the bitmap instead of the canvas
  943.        map colors white => white, all others => black */
  944.     if (writing_bitmap)
  945.     {
  946.     if (color == WHITE)
  947.         color = 0;
  948.     else
  949.         color = 1;
  950.     }
  951.     /* see if all gc stuff is already correct */
  952.  
  953.     if (width == gc_thickness[op] && style == gc_line_style[op] &&
  954.     (writing_bitmap? color == gc_color[op] : x_color(color) == gc_color[op]) &&
  955.     (style != DASH_LINE && style != DOTTED_LINE ||
  956.      dash_list[1] == (char) round(style_val * zoomscale)))
  957.     return;            /* no need to change anything */
  958.  
  959.     gcv.line_width = width;
  960.     mask = GCLineWidth | GCLineStyle | GCCapStyle;
  961.     if (op == PAINT)
  962.     mask |= GCForeground;
  963.     gcv.line_style = (style == DASH_LINE || style == DOTTED_LINE) ?
  964.     LineOnOffDash : LineSolid;
  965.     gcv.cap_style = (style == DOTTED_LINE) ? CapRound : CapButt;
  966.     gcv.foreground = (writing_bitmap? color : x_color(color));
  967.  
  968.     XChangeGC(tool_d, gccache[op], mask, &gcv);
  969.     if (style == DASH_LINE || style == DOTTED_LINE) {
  970.     if (style_val > 0.0) {    /* style_val of 0.0 causes problems */
  971.         /* length of ON/OFF pixels */
  972.         dash_list[0] = dash_list[1] = (char) round(style_val *zoomscale);
  973.         if (dash_list[0]==0)        /* take care for rounding to zero ! */
  974.         dash_list[0]=dash_list[1]=1;
  975.  
  976.         if (style == DOTTED_LINE)
  977.         dash_list[0] = 1;    /* length of ON pixels for dotted */
  978.         XSetDashes(tool_d, gccache[op], 0, (char *) dash_list, 2);
  979.     }
  980.     }
  981.     gc_thickness[op] = width;
  982.     gc_line_style[op] = style;
  983.     gc_color[op] = writing_bitmap? color : x_color(color);
  984. }
  985.