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