Configuration: FreeBSD 4.5 - XFree86 4.2.0 - ATI Radeon VE

Problem: If a polygon which is being filled with a stipple intersects a
clip region, the fill fails and paints the clipped region black.

Diagnosing:

1) rectangles do not seem to suffer from this problem
2) solid(non-stipple) fills do not seem to exhibit the problem
3) if NoAccel is turned on, the problem goes away

How to repeat:
Attached is a program which draws 8 square polygons, 4 of which are not
clipped, 4 of which are.  The rightmost polygons should all fail.  If they
don't, please let me know.

I will be happy to provide any other logs or configuration information
required as this was a real pain to hunt down.

Thanks,
-a
#include <X11/Xlib.h>

#define stipple_bitmap_width 16
#define stipple_bitmap_height 16
static unsigned char stipple_bitmap_bits[] = {
   0x33, 0x33, 0x66, 0x66, 0xcc, 0xcc, 0x99, 0x99, 0x33, 0x33, 0x66, 0x66,
   0xcc, 0xcc, 0x99, 0x99, 0x33, 0x33, 0x66, 0x66, 0xcc, 0xcc, 0x99, 0x99,
   0x33, 0x33, 0x66, 0x66, 0xcc, 0xcc, 0x99, 0x99};

Display *display;
int screen_num;

static char *progname;

int main(int argc, char **argv)
{
  Window win;
  Pixmap stippleBitmap;
  char *display_name = NULL;
  GC gc0,gc1,gc2,gc3;
  unsigned long valuemask = 0;
  XGCValues values;
  XEvent event;
  Colormap defaultColormap;
  XColor red,green,blue,black,white,junk;

  XRectangle clipRects[1] = {{400,50,400,400}};
  XPoint rb[5] = {{0,0},{100,0},{100,100},{0,100},{0,0}};



  XPoint r[8][5];
  int i,j,k;

  for(i=0; i<8; i++)
    {
      for(j=0; j<6; j++)
        {
          r[i][j].x = rb[j].x + i*100 + i*2;
          r[i][j].y = rb[j].y;
        }
    }

  progname = argv[0];

  if ((display=XOpenDisplay(display_name)) == NULL)
    {
      printf("Failed to open display\n");
      exit(-1);
    }

  win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
                            0, 0, 800, 150, 0, BlackPixel(display, screen_num),
                            WhitePixel(display, screen_num));
  screen_num = DefaultScreen(display);


  stippleBitmap = XCreateBitmapFromData(display, win, stipple_bitmap_bits,
                                        stipple_bitmap_width, stipple_bitmap_height);

  XSelectInput(display, win, ExposureMask | KeyPressMask);

  defaultColormap = DefaultColormap(display, screen_num);

  XAllocNamedColor(display, defaultColormap, "red", &red, &junk);
  XAllocNamedColor(display, defaultColormap, "green", &green, &junk);
  XAllocNamedColor(display, defaultColormap, "blue", &blue, &junk);
  XAllocNamedColor(display, defaultColormap, "black", &black, &junk);
  XAllocNamedColor(display, defaultColormap, "white", &white, &junk);
  
  values.foreground = red.pixel;
  values.background = green.pixel;
  values.fill_style = FillStippled;
  values.stipple = stippleBitmap;
  valuemask = GCForeground | GCBackground | GCFillStyle | GCStipple;
  gc0 = XCreateGC(display, win, valuemask, &values);
  
  XMapWindow(display, win);

  while(1)
    {
      XNextEvent(display, &event);

      switch (event.type)
        {
        case Expose:
          /* Draw something */
          for(i=0; i<4; i++)
            {
              XFillPolygon(display, win, gc0, r[i], 5, Convex, CoordModeOrigin);
            }
          XSetClipRectangles(display, gc0, 0, 0, clipRects, 1, Unsorted);
          for(i=4; i<8; i++)
            {
              XFillPolygon(display, win, gc0, r[i], 5, Convex, CoordModeOrigin);
            }
          break;
        case KeyPress:
          XFreeGC(display, gc0);
          XCloseDisplay(display);
          exit(-1);
          break;
        default:
          break;
        }
    }
}

Reply via email to