I had this itch to make soldermasks translucent.  Turns out that while
Xrender is verrry sparsely documented, it is actually pretty easy to
do what I want.

After I got it working, I realized that rats should *definitely* be
translucent.  Awesome!

        http://ad7gd.net/geda/transrats.png

The included patch has some issues.  You'll need to add '-lXrender' to
your LIBS by hand, since the patch does not touch the automake stuff.
I added a fixed, implied transparency to 'mask' drawing (which catches
the soldermask of course) and then moved rat drawing to use the mask.
And finally, I think it should not affect the GTK+ hid (who cares for
a tech demo anyway) but it might break it.

The bulk of the patch is actually refactoring some duplicated code in
the lesstif hid so that the new code I added would not also be duplicated.

The basic technology is:  XRender works on 'Pictures', so you need wrapper
Pictures for your pixmaps.  Then you get both a clip-mask AND an arbitrary
mask (that bit was unobvious) so the old mask bitmap is the clip-mask and
the arbitrary mask is a 1x1 50% alpha pixel that repeats all over the
image.  Then the copy from the mask pixmap picture to the main is done
with XRenderComposite instead of XCopyArea.  The clip_mask replaces
the glip_gc and the 'mask-mask' is the alpha pixel.

(check xdpyinfo output for the RENDER extension before you bother with
the patch)

-- 
Ben Jackson AD7GD
<[EMAIL PROTECTED]>
http://www.ben.com/
Index: draw.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/draw.c,v
retrieving revision 1.84
diff -u -r1.84 draw.c
--- draw.c      25 Nov 2007 02:40:10 -0000      1.84
+++ draw.c      29 Nov 2007 06:09:05 -0000
@@ -110,6 +110,7 @@
 static void ClearPad (PadTypePtr, Boolean);
 static void DrawHole (PinTypePtr);
 static void DrawMask (BoxType *);
+static void DrawRats (BoxType *);
 static void DrawSilk (int, int, BoxType *);
 static int pin_callback (const BoxType * b, void *cl);
 static int pad_callback (const BoxType * b, void *cl);
@@ -532,7 +533,7 @@
                  NULL);
       /* Draw rat lines on top */
       if (PCB->RatOn)
-       r_search (PCB->Data->rat_tree, drawn_area, NULL, rat_callback, NULL);
+       DrawRats(drawn_area);
     }
 
   for (side = 0; side <= 1; side++)
@@ -812,6 +813,14 @@
 #endif
 }
 
+static void
+DrawRats (BoxTypePtr drawn_area)
+{
+  gui->use_mask (HID_MASK_CLEAR);
+  r_search (PCB->Data->rat_tree, drawn_area, NULL, rat_callback, NULL);
+  gui->use_mask (HID_MASK_OFF);
+}
+
 static int
 line_callback (const BoxType * b, void *cl)
 {
Index: hid/lesstif/main.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/lesstif/main.c,v
retrieving revision 1.63
diff -u -r1.63 main.c
--- hid/lesstif/main.c  25 Nov 2007 02:46:57 -0000      1.63
+++ hid/lesstif/main.c  29 Nov 2007 06:09:12 -0000
@@ -75,6 +75,12 @@
 static Pixmap mask_bitmap = 0;
 static int use_mask = 0;
 
+static int use_xrender = 0;
+static Picture main_picture;
+static Picture mask_picture;
+static Pixmap pale_pixmap;
+static Picture pale_picture;
+
 static int pixmap_w = 0, pixmap_h = 0;
 Screen *screen_s;
 int screen;
@@ -1591,6 +1597,40 @@
 }
 
 static void
+work_area_make_pixmaps (Dimension width, Dimension height)
+{
+  if (main_pixmap)
+    XFreePixmap (display, main_pixmap);
+  main_pixmap =
+    XCreatePixmap (display, window, width, height,
+                  XDefaultDepth (display, screen));
+  if (main_picture)
+    XRenderFreePicture (display, main_picture);
+  main_picture =
+    XRenderCreatePicture (display, main_pixmap,
+      XRenderFindVisualFormat(display, DefaultVisual(display, screen)), 0, 0);
+
+  if (mask_pixmap)
+    XFreePixmap (display, mask_pixmap);
+  mask_pixmap =
+    XCreatePixmap (display, window, width, height,
+                  XDefaultDepth (display, screen));
+  if (mask_picture)
+    XRenderFreePicture (display, mask_picture);
+  mask_picture =
+    XRenderCreatePicture (display, mask_pixmap,
+      XRenderFindVisualFormat(display, DefaultVisual(display, screen)), 0, 0);
+
+  if (mask_bitmap)
+    XFreePixmap (display, mask_bitmap);
+  mask_bitmap = XCreatePixmap (display, window, width, height, 1);
+
+  pixmap = use_mask ? main_pixmap : mask_pixmap;
+  pixmap_w = width;
+  pixmap_h = height;
+}
+
+static void
 work_area_resize (Widget work_area, void *me,
                  XmDrawingAreaCallbackStruct * cbs)
 {
@@ -1616,37 +1656,7 @@
   if (!window)
     return;
 
-#if 0
-  if (!pixmap || view_width > pixmap_w || view_height > pixmap_h)
-    {
-      if (pixmap_w < view_width)
-#endif
-       pixmap_w = view_width;
-#if 0
-      if (pixmap_h < view_height)
-#endif
-       pixmap_h = view_height;
-
-      if (main_pixmap)
-       XFreePixmap (display, main_pixmap);
-      main_pixmap =
-       XCreatePixmap (display, window, pixmap_w, pixmap_h,
-                      XDefaultDepth (display, screen));
-
-      if (mask_pixmap)
-       XFreePixmap (display, mask_pixmap);
-      mask_pixmap =
-       XCreatePixmap (display, window, pixmap_w, pixmap_h,
-                      XDefaultDepth (display, screen));
-
-      if (mask_bitmap)
-       XFreePixmap (display, mask_bitmap);
-      mask_bitmap = XCreatePixmap (display, window, pixmap_w, pixmap_h, 1);
-
-      pixmap = use_mask ? main_pixmap : mask_pixmap;
-#if 0
-    }
-#endif
+  work_area_make_pixmaps (view_width, view_height);
 
   zoom_by (1, 0, 0);
 }
@@ -1658,6 +1668,8 @@
   int c;
   Dimension width, height;
   static char dashes[] = { 4, 4 };
+  XRenderPictureAttributes pa;
+  XRenderColor pale = {0, 0, 0, 0x8000};
 
   window = XtWindow (work_area);
   my_gc = XCreateGC (display, window, 0, 0);
@@ -1687,16 +1699,14 @@
   bg_gc = XCreateGC (display, window, 0, 0);
   XSetForeground (display, bg_gc, bgcolor);
 
-  main_pixmap =
-    XCreatePixmap (display, window, width, height,
-                  XDefaultDepth (display, screen));
-  mask_pixmap =
-    XCreatePixmap (display, window, width, height,
-                  XDefaultDepth (display, screen));
-  mask_bitmap = XCreatePixmap (display, window, width, height, 1);
-  pixmap = main_pixmap;
-  pixmap_w = width;
-  pixmap_h = height;
+  work_area_make_pixmaps (width, height);
+
+  pale_pixmap = XCreatePixmap (display, window, 1, 1, 8);
+  pa.repeat = True;
+  pale_picture = XRenderCreatePicture (display, pale_pixmap,
+                       XRenderFindStandardFormat(display, PictStandardA8),
+                       CPRepeat, &pa);
+  XRenderFillRectangle(display, PictOpSrc, pale_picture, &pale, 0, 0, 1, 1);
 
   clip_gc = XCreateGC (display, window, 0, 0);
   bset_gc = XCreateGC (display, mask_bitmap, 0, 0);
@@ -1971,6 +1981,7 @@
   XrmOptionDescRec *new_options;
   XtResource *new_resources;
   val_union *new_values;
+  int render_event, render_error;
 
   XtSetTypeConverter (XtRString,
                      XtRDouble,
@@ -2128,6 +2139,9 @@
   XtGetApplicationResources (appwidget, new_values, new_resources,
                             rmax, 0, 0);
 
+  use_xrender = XRenderQueryExtension (display, &render_event, &render_error) 
&&
+       XRenderFindVisualFormat (display, DefaultVisual(display, screen));
+
   rcount = 0;
   for (ha = hid_attr_nodes; ha; ha = ha->next)
     for (i = 0; i < ha->n; i++)
@@ -2896,8 +2910,10 @@
 static void
 lesstif_use_mask (int use_it)
 {
+#if 0
   if (TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG(THINDRAWPOLYFLAG, PCB))
     use_it = 0;
+#endif
   if ((use_it == 0) == (use_mask == 0))
     return;
   use_mask = use_it;
@@ -2925,10 +2941,22 @@
     }
   else
     {
-      XSetClipMask (display, clip_gc, mask_bitmap);
       pixmap = main_pixmap;
-      XCopyArea (display, mask_pixmap, main_pixmap, clip_gc,
-                0, 0, view_width, view_height, 0, 0);
+      if (use_xrender)
+       {
+         XRenderPictureAttributes pa;
+
+         pa.clip_mask = mask_bitmap;
+         XRenderChangePicture(display, main_picture, CPClipMask, &pa);
+         XRenderComposite(display, PictOpOver, mask_picture, pale_picture,
+               main_picture, 0, 0, 0, 0, 0, 0, view_width, view_height);
+       }
+      else
+       {
+         XSetClipMask (display, clip_gc, mask_bitmap);
+         XCopyArea (display, mask_pixmap, main_pixmap, clip_gc,
+                    0, 0, view_width, view_height, 0, 0);
+       }
     }
 }
 
Index: hid/lesstif/xincludes.h
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/lesstif/xincludes.h,v
retrieving revision 1.1
diff -u -r1.1 xincludes.h
--- hid/lesstif/xincludes.h     19 Apr 2006 22:36:47 -0000      1.1
+++ hid/lesstif/xincludes.h     29 Nov 2007 06:09:12 -0000
@@ -36,5 +36,7 @@
 #include <Xm/ToggleB.h>
 #include <Xm/Xm.h>
 
+#include <X11/extensions/Xrender.h>
+
 #undef Mask
 

_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev

Reply via email to