This is generally a bit crufty, but for your amusement, see the attached
patch. It breaks drawing the mask layer, cursor and rubber-band lines,
but is a stab at making PCB render (translucent drawing) with GL.
Its frame-rate on my complex power controller board at minimum zoom is
about 2.4 frames per second. This basically matches the frame-rate of my
similarly crufty test implementation with cairo.
Regards,
--
Peter Clifton
Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA
Tel: +44 (0)7729 980173 - (No signal in the lab!)
Index: configure.ac
===================================================================
RCS file: /cvsroot/pcb/pcb/configure.ac,v
retrieving revision 1.103
diff -U3 -p -r1.103 configure.ac
--- configure.ac 28 Apr 2008 17:10:13 -0000 1.103
+++ configure.ac 14 Jun 2008 16:58:47 -0000
@@ -494,6 +494,16 @@ Please review the following errors:
$GLIB_PKG_ERRORS])]
)
GLIB_VERSION=`$PKG_CONFIG glib-2.0 --modversion`
+
+
+# Check for GtkGLExt
+PKG_CHECK_MODULES(GTKGLEXT, gtkglext-1.0 >= 1.0.0, , [AC_MSG_ERROR([
+*** Required version of gtkglext is not installed - please install first ***
+Please review the following errors:
+$GTKGLEXT_PKG_ERRORS])]
+)
+
+GTKGLEXT_VER=`$PKG_CONFIG gtkglext-1.0 --modversion`
;;
nelma|png )
@@ -696,8 +706,8 @@ fi
AC_MSG_RESULT([no])
])
-CFLAGS="$CFLAGS $X_CFLAGS $DBUS_CFLAGS $GTK_CFLAGS"
-LIBS="$LIBS $XM_LIBS $DBUS_LIBS $X_LIBS $GTK_LIBS $DMALLOC_LIBS $GD_LIBS $INTLLIBS"
+CFLAGS="$CFLAGS $X_CFLAGS $DBUS_CFLAGS $GTK_CFLAGS $GTKGLEXT_CFLAGS"
+LIBS="$LIBS $XM_LIBS $DBUS_LIBS $X_LIBS $GTK_LIBS $GTKGLEXT_LIBS $DMALLOC_LIBS $GD_LIBS $INTLLIBS -lglut"
# if we have gcc then add -Wall
Index: src/crosshair.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/crosshair.c,v
retrieving revision 1.36
diff -U3 -p -r1.36 crosshair.c
--- src/crosshair.c 13 Apr 2008 16:06:39 -0000 1.36
+++ src/crosshair.c 14 Jun 2008 16:59:20 -0000
@@ -83,7 +83,7 @@ static void XORDrawMoveOrCopyObject (voi
static void XORDrawAttachedLine (LocationType, LocationType, LocationType,
LocationType, BDimension);
static void XORDrawAttachedArc (BDimension);
-static void DrawAttached (Boolean);
+/*static*/ void DrawAttached (Boolean);
/* ---------------------------------------------------------------------------
* creates a tmp polygon with coordinates converted to screen system
@@ -184,8 +184,7 @@ XORDrawAttachedLine (LocationType x1, Lo
{
LocationType angle = atan2 ((float) dx, (float) dy) * 57.295779;
gui->draw_line (Crosshair.GC, x1 - ox, y1 - oy, x2 - ox, y2 - oy);
- gui->draw_arc (Crosshair.GC,
- x1, y1, thick / 2, thick / 2, angle - 180, 180);
+ gui->draw_arc (Crosshair.GC, x1, y1, thick / 2, thick / 2, angle - 180, 180);
gui->draw_arc (Crosshair.GC, x2, y2, thick / 2, thick / 2, angle, 180);
}
}
@@ -575,7 +574,7 @@ XORDrawMoveOrCopyObject (void)
/* ---------------------------------------------------------------------------
* draws additional stuff that follows the crosshair
*/
-static void
+/*static*/ void
DrawAttached (Boolean BlockToo)
{
BDimension s;
@@ -746,7 +745,7 @@ HideCrosshair (Boolean BlockToo)
CrosshairStack[CrosshairStackLocation] = Crosshair.On;
CrosshairStackLocation++;
- CrosshairOff (BlockToo);
+// CrosshairOff (BlockToo);
}
/* ---------------------------------------------------------------------------
@@ -766,11 +765,11 @@ RestoreCrosshair (Boolean BlockToo)
if (CrosshairStack[CrosshairStackLocation])
{
- CrosshairOn (BlockToo);
+// CrosshairOn (BlockToo);
}
else
{
- CrosshairOff (BlockToo);
+// CrosshairOff (BlockToo);
}
}
@@ -782,6 +781,7 @@ FitCrosshairIntoGrid (LocationType X, Lo
{
LocationType x2, y2, x0, y0;
void *ptr1, *ptr2, *ptr3;
+ float nearest, sq_dist;
int ans;
x0 = 0;
@@ -791,41 +791,6 @@ FitCrosshairIntoGrid (LocationType X, Lo
Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X));
Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y));
- if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
- {
- ans =
- SearchScreen (Crosshair.X, Crosshair.Y,
- PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3);
- if (ans == NO_TYPE && !PCB->RatDraw)
- ans =
- SearchScreen (Crosshair.X, Crosshair.Y, VIA_TYPE | LINEPOINT_TYPE,
- &ptr1, &ptr2, &ptr3);
- if (ans == NO_TYPE && !PCB->RatDraw)
- ans =
- SearchScreen (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2,
- &ptr3);
- }
- else
- ans = NO_TYPE;
-
- /* avoid self-snapping */
- if (Settings.Mode == MOVE_MODE)
- {
- switch (Crosshair.AttachedObject.Type)
- {
- case ELEMENT_TYPE:
- if ((ans & (PAD_TYPE | PIN_TYPE)) &&
- ptr1 == Crosshair.AttachedObject.Ptr1)
- ans = NO_TYPE;
- break;
- case VIA_TYPE:
- /* just avoid snapping to any other vias */
- if (ans & PIN_TYPES)
- ans = NO_TYPE;
- break;
- }
- }
-
if (PCB->RatDraw)
{
x0 = -600;
@@ -875,82 +840,133 @@ FitCrosshairIntoGrid (LocationType X, Lo
}
}
+
+ nearest = -1;
+
+ if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
+ ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
+ PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3);
+ else
+ ans = NO_TYPE;
+
+ /* Avoid self-snapping when moving */
+ if (Settings.Mode == MOVE_MODE &&
+ Crosshair.AttachedObject.Type == ELEMENT_TYPE)
+ {
+ if ((ans & (PAD_TYPE | PIN_TYPE)) &&
+ ptr1 == Crosshair.AttachedObject.Ptr1)
+ ans = NO_TYPE;
+ }
+
if (ans & PAD_TYPE)
{
PadTypePtr pad = (PadTypePtr) ptr2;
LocationType px, py;
- if (SQUARE (pad->Point1.X - Crosshair.X) +
- SQUARE (pad->Point1.Y - Crosshair.Y) <
- SQUARE (pad->Point2.X - Crosshair.X) + SQUARE (pad->Point2.Y -
- Crosshair.Y))
- {
- px = pad->Point1.X;
- py = pad->Point1.Y;
- }
- else
- {
- px = pad->Point2.X;
- py = pad->Point2.Y;
- }
+ px = (pad->Point1.X + pad->Point2.X) / 2;
+ py = (pad->Point1.Y + pad->Point2.Y) / 2;
- if (!gui->shift_is_pressed()
- || (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) >
- SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y)))
- {
- x0 = px;
- y0 = py;
- }
+ sq_dist = SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y);
+
+ if (!gui->shift_is_pressed() ||
+ SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)
+ {
+ x0 = px;
+ y0 = py;
+ nearest = sq_dist;
+ }
+ }
+ else if (ans & PIN_TYPE)
+ {
+ PinTypePtr pin = (PinTypePtr) ptr2;
+ sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y);
+ if ((nearest == -1 || sq_dist < nearest) &&
+ (!gui->shift_is_pressed() ||
+ SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
+ {
+ x0 = pin->X;
+ y0 = pin->Y;
+ nearest = sq_dist;
+ }
}
- else if (ans & (PIN_TYPE | VIA_TYPE))
+ if (TEST_FLAG (SNAPPINFLAG, PCB))
+ ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
+ VIA_TYPE | LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
+ else
+ ans = NO_TYPE;
+
+ /* Avoid snapping vias to any other vias */
+ if (Settings.Mode == MOVE_MODE &&
+ Crosshair.AttachedObject.Type == VIA_TYPE)
+ {
+ if (ans & PIN_TYPES)
+ ans = NO_TYPE;
+ }
+
+ if (ans & VIA_TYPE)
{
PinTypePtr pin = (PinTypePtr) ptr2;
- if (!gui->shift_is_pressed()
- || (SQUARE (x0 - Crosshair.X) +
- SQUARE (y0 - Crosshair.Y) >
- SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y)))
- {
- x0 = pin->X;
- y0 = pin->Y;
- }
+ sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y);
+ if ((nearest == -1 || sq_dist < nearest) &&
+ (!gui->shift_is_pressed() ||
+ SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
+ {
+ x0 = pin->X;
+ y0 = pin->Y;
+ nearest = sq_dist;
+ }
}
else if (ans & LINEPOINT_TYPE)
{
PointTypePtr pnt = (PointTypePtr) ptr3;
- if (((x0 - Crosshair.X) * (x0 - Crosshair.X) +
- (y0 - Crosshair.Y) * (y0 - Crosshair.Y)) >
- ((pnt->X - Crosshair.X) * (pnt->X - Crosshair.X) +
- (pnt->Y - Crosshair.Y) * (pnt->Y - Crosshair.Y)))
- {
- x0 = pnt->X;
- y0 = pnt->Y;
- }
+ sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y);
+ if ((nearest == -1 || sq_dist < nearest) &&
+ (!gui->shift_is_pressed() ||
+ SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
+ {
+ x0 = pnt->X;
+ y0 = pnt->Y;
+ nearest = sq_dist;
+ }
}
- else if (ans & ELEMENT_TYPE)
+
+
+ if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
+ ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
+ ELEMENT_TYPE, &ptr1, &ptr2, &ptr3);
+ else
+ ans = NO_TYPE;
+
+ if (ans & ELEMENT_TYPE)
{
ElementTypePtr el = (ElementTypePtr) ptr1;
- if (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) >
- SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y))
- {
- x0 = el->MarkX;
- y0 = el->MarkY;
- }
+ sq_dist = SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y);
+ if ((nearest == -1 || sq_dist < nearest) &&
+// (!gui->shift_is_pressed() ||
+ SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)
+ {
+ x0 = el->MarkX;
+ y0 = el->MarkY;
+ nearest = sq_dist;
+ }
}
+
if (x0 >= 0 && y0 >= 0)
{
Crosshair.X = x0;
Crosshair.Y = y0;
}
+
if (Settings.Mode == ARROW_MODE)
{
- ans =
- SearchScreen (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE,
- &ptr1, &ptr2, &ptr3);
- if (ans == NO_TYPE)
- hid_action("PointCursor");
- else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
- hid_actionl("PointCursor","True", NULL);
+ ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
+ LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
+ if (ans == NO_TYPE)
+ hid_action("PointCursor");
+ else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
+ hid_actionl("PointCursor","True", NULL);
}
+
if (Settings.Mode == LINE_MODE
&& Crosshair.AttachedLine.State != STATE_FIRST
&& TEST_FLAG (AUTODRCFLAG, PCB))
Index: src/search.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/search.c,v
retrieving revision 1.36
diff -U3 -p -r1.36 search.c
--- src/search.c 23 Nov 2007 06:09:18 -0000 1.36
+++ src/search.c 14 Jun 2008 16:59:20 -0000
@@ -322,6 +322,7 @@ struct arc_info
ArcTypePtr *Arc, *Dummy;
jmp_buf env;
int locked;
+ int smallest_radius;
};
static int
@@ -329,16 +330,24 @@ arc_callback (const BoxType * box, void
{
struct arc_info *i = (struct arc_info *) cl;
ArcTypePtr a = (ArcTypePtr) box;
+ int found_radius;
if (TEST_FLAG (i->locked, a))
return 0;
if (!IsPointOnArc (PosX, PosY, SearchRadius, a))
return 0;
- *i->Arc = a;
- *i->Dummy = a;
- longjmp (i->env, 1);
- return 1; /* never reached */
+
+ found_radius = ClosestArcPoint (PosX, PosY, a);
+
+ if (i->smallest_radius == -1 || found_radius < i->smallest_radius)
+ {
+ i->smallest_radius = found_radius;
+ *i->Arc = a;
+ *i->Dummy = a;
+ }
+// longjmp (i->env, 1);
+ return 1;// /* never reached */
}
@@ -351,14 +360,18 @@ SearchArcByLocation (int locked, LayerTy
info.Arc = Arc;
info.Dummy = Dummy;
info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG;
+ info.smallest_radius = -1;
*Layer = SearchLayer;
- if (setjmp (info.env) == 0)
- {
+// if (setjmp (info.env) == 0)
+// {
r_search (SearchLayer->arc_tree, &SearchBox, NULL, arc_callback, &info);
- return False;
- }
- return (True);
+// return False;
+// }
+ if (info.smallest_radius > -1)
+ return True;
+ else
+ return False;
}
static int
@@ -492,7 +505,9 @@ SearchLinePointByLocation (int locked, L
info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG;
if (r_search
(SearchLayer->line_tree, &SearchBox, NULL, linepoint_callback, &info))
+ {
return True;
+ }
return False;
}
@@ -1001,6 +1016,11 @@ IsPointInBox (LocationType X, LocationTy
return IsPointInPad (X, Y, Radius, &pad);
}
+int ClosestArcPoint (float X, float Y, ArcTypePtr Arc)
+{
+ return 0;
+}
+
Boolean
IsPointOnArc (float X, float Y, float Radius, ArcTypePtr Arc)
{
@@ -1548,3 +1568,17 @@ SearchScreen (LocationType X, LocationTy
X, Y, SLOP * pixel_slop);
return (ans);
}
+
+/* ---------------------------------------------------------------------------
+ * searches the cursor position for the type
+ */
+int
+SearchScreenGridSlop (LocationType X, LocationType Y, int Type, void **Result1,
+ void **Result2, void **Result3)
+{
+ int ans;
+
+ ans = SearchObjectByLocation (Type, Result1, Result2, Result3,
+ X, Y, PCB->Grid / 2);
+ return (ans);
+}
Index: src/search.h
===================================================================
RCS file: /cvsroot/pcb/pcb/src/search.h,v
retrieving revision 1.12
diff -U3 -p -r1.12 search.h
--- src/search.h 23 Nov 2007 06:09:19 -0000 1.12
+++ src/search.h 14 Jun 2008 16:59:20 -0000
@@ -73,6 +73,7 @@
*/
Boolean IsPointOnLine (float, float, float, LineTypePtr);
Boolean IsPointOnPin (float, float, float, PinTypePtr);
+int ClosestArcPoint (float, float, ArcTypePtr);
Boolean IsPointOnArc (float, float, float, ArcTypePtr);
Boolean IsPointOnLineEnd (LocationType, LocationType, RatTypePtr);
Boolean IsLineInRectangle (LocationType, LocationType, LocationType,
@@ -85,6 +86,7 @@ Boolean IsPointInBox (LocationType, Loca
int SearchObjectByLocation (int, void **, void **, void **, LocationType,
LocationType, BDimension);
int SearchScreen (LocationType, LocationType, int, void **, void **, void **);
+int SearchScreenGridSlop (LocationType, LocationType, int, void **, void **, void **);
int SearchObjectByID (DataTypePtr, void **, void **, void **, int, int);
ElementTypePtr SearchElementByName (DataTypePtr, char *);
Index: src/hid/batch/batch.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/batch/batch.c,v
retrieving revision 1.11
diff -U3 -p -r1.11 batch.c
--- src/hid/batch/batch.c 13 Apr 2008 14:15:38 -0000 1.11
+++ src/hid/batch/batch.c 14 Jun 2008 16:59:23 -0000
@@ -329,6 +329,33 @@ batch_stop_timer (hidval timer)
{
}
+hidval
+batch_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data),
+ hidval user_data)
+{
+ hidval ret;
+ ret.ptr = NULL;
+ return ret;
+}
+
+void
+batch_unwatch_file (hidval data)
+{
+}
+
+static hidval
+batch_add_block_hook (void (*func) (hidval data), hidval user_data )
+{
+ hidval ret;
+ ret.ptr = NULL;
+ return ret;
+}
+
+static void
+batch_stop_block_hook (hidval mlpoll)
+{
+}
+
static void
batch_log (const char *fmt, ...)
{
@@ -454,6 +481,10 @@ HID batch_gui = {
batch_set_crosshair,
batch_add_timer,
batch_stop_timer,
+ batch_watch_file,
+ batch_unwatch_file,
+ batch_add_block_hook,
+ batch_stop_block_hook,
batch_log,
batch_logv,
batch_confirm_dialog,
Index: src/hid/common/hidinit.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/common/hidinit.c,v
retrieving revision 1.19
diff -U3 -p -r1.19 hidinit.c
--- src/hid/common/hidinit.c 20 Apr 2007 11:31:14 -0000 1.19
+++ src/hid/common/hidinit.c 14 Jun 2008 16:59:26 -0000
@@ -609,7 +609,7 @@ hid_load_settings ()
hid_load_settings_1 (Concat ("pcb.settings", NULL));
}
-#define HASH_SIZE 32
+#define HASH_SIZE 31
typedef struct ecache
{
@@ -636,7 +636,7 @@ copy_color (int set, hidval * cval, hidv
int
hid_cache_color (int set, const char *name, hidval * val, void **vcache)
{
- int hash;
+ unsigned long hash;
const char *cp;
ccache *cache;
ecache *e;
@@ -651,14 +651,22 @@ hid_cache_color (int set, const char *na
return 1;
}
+ /* djb2: this algorithm (k=33) was first reported by dan bernstein many
+ * years ago in comp.lang.c. another version of this algorithm (now favored
+ * by bernstein) uses xor: hash(i) = hash(i - 1) * 33 ^ str[i]; the magic
+ * of number 33 (why it works better than many other constants, prime or
+ * not) has never been adequately explained.
+ */
+ hash = 5381;
for (cp = name, hash = 0; *cp; cp++)
- hash += (*cp) & 0xff;
+ hash = ((hash << 5) + hash) + (*cp & 0xff); /* hash * 33 + c */
hash %= HASH_SIZE;
for (e = cache->colors[hash]; e; e = e->next)
if (strcmp (e->name, name) == 0)
{
copy_color (set, &(e->val), val);
+ cache->lru = e;
return 1;
}
if (!set)
@@ -670,6 +678,8 @@ hid_cache_color (int set, const char *na
e->name = strdup (name);
memcpy (&(e->val), val, sizeof (hidval));
+ cache->lru = e;
+
return 1;
}
Index: src/hid/gtk/gtkhid-main.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/gtk/gtkhid-main.c,v
retrieving revision 1.56
diff -U3 -p -r1.56 gtkhid-main.c
--- src/hid/gtk/gtkhid-main.c 13 Apr 2008 15:29:20 -0000 1.56
+++ src/hid/gtk/gtkhid-main.c 14 Jun 2008 16:59:29 -0000
@@ -32,6 +32,9 @@
#include <gdk/gdkx.h>
#endif
+#include <gtk/gtkgl.h>
+#include <GL/glut.h>
+
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
#endif
@@ -49,6 +52,7 @@ static void zoom_by (double factor, int
/* Sets gport->u_gc to the "right" GC to use (wrt mask or window)
*/
#define USE_GC(gc) if (!use_gc(gc)) return
+//#define USE_GC(gc)
static int cur_mask = -1;
static int mask_seq = 0;
@@ -379,7 +383,7 @@ zoom_by (double factor, int x, int y)
/* ------------------------------------------------------------ */
-static void
+/*static*/ void
draw_grid ()
{
static GdkPoint *points = 0;
@@ -387,6 +391,8 @@ draw_grid ()
int x1, y1, x2, y2, n, i;
double x, y;
+ return;
+
if (!Settings.DrawGrid)
return;
if (Vz (PCB->Grid) < MIN_GRID_DISTANCE)
@@ -474,44 +480,73 @@ ghid_invalidate_lr (int left, int right,
static void
ghid_draw_bg_image(void)
{
- static GdkPixbuf *pixbuf;
- GdkInterpType interp_type;
- gint x, y, w, h, w_src, h_src;
- static gint w_scaled, h_scaled;
-
- if (!ghidgui->bg_pixbuf)
- return;
-
- w = PCB->MaxWidth / gport->zoom;
- h = PCB->MaxHeight / gport->zoom;
- x = gport->view_x0 / gport->zoom;
- y = gport->view_y0 / gport->zoom;
-
- if (w_scaled != w || h_scaled != h)
- {
- if (pixbuf)
- g_object_unref(G_OBJECT(pixbuf));
-
- w_src = gdk_pixbuf_get_width(ghidgui->bg_pixbuf);
- h_src = gdk_pixbuf_get_height(ghidgui->bg_pixbuf);
- if (w > w_src && h > h_src)
- interp_type = GDK_INTERP_NEAREST;
- else
- interp_type = GDK_INTERP_BILINEAR;
-
- pixbuf = gdk_pixbuf_scale_simple(ghidgui->bg_pixbuf, w, h, interp_type);
- w_scaled = w;
- h_scaled = h;
- }
- if (pixbuf)
- gdk_pixbuf_render_to_drawable(pixbuf, gport->drawable, gport->bg_gc,
- x, y, 0, 0,
- w - x, h - y, GDK_RGB_DITHER_NORMAL, 0, 0);
- }
+ static GdkPixbuf *pixbuf = NULL;
+ static gint vw_scaled, vh_scaled, x_cached, y_cached;
+ GdkInterpType interp_type;
+ gint x, y, vw, vh, w, h, w_src, h_src;
+ int bits_per_sample;
+ gboolean has_alpha;
+
+ if (!ghidgui->bg_pixbuf)
+ return;
+
+ w = PCB->MaxWidth / gport->zoom;
+ h = PCB->MaxHeight / gport->zoom;
+ x = gport->view_x0 / gport->zoom;
+ y = gport->view_y0 / gport->zoom;
+ vw = gport->view_width / gport->zoom;
+ vh = gport->view_height / gport->zoom;
+
+ if (pixbuf == NULL || vw_scaled != vw || vh_scaled != vh)
+ {
+ if (pixbuf != NULL)
+ g_object_unref(G_OBJECT(pixbuf));
+
+ bits_per_sample = gdk_pixbuf_get_bits_per_sample(ghidgui->bg_pixbuf);
+ has_alpha = gdk_pixbuf_get_has_alpha (ghidgui->bg_pixbuf);
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+ has_alpha,
+ bits_per_sample,
+ vw, vh);
+ }
+
+ if (pixbuf == NULL)
+ return;
+
+ if (vw_scaled != vw || vh_scaled != vh ||
+ x_cached != x || y_cached != y)
+ {
+ w_src = gdk_pixbuf_get_width(ghidgui->bg_pixbuf);
+ h_src = gdk_pixbuf_get_height(ghidgui->bg_pixbuf);
+
+ if (w > w_src && h > h_src)
+ interp_type = GDK_INTERP_NEAREST;
+ else
+ interp_type = GDK_INTERP_BILINEAR;
+
+ gdk_pixbuf_scale(ghidgui->bg_pixbuf, pixbuf,
+ 0, 0, vw, vh,
+ (double) -x,
+ (double) -y,
+ (double) w / w_src,
+ (double) h / h_src,
+ interp_type);
+
+ x_cached = x;
+ y_cached = y;
+ vw_scaled = vw;
+ vh_scaled = vh;
+ }
+
+ if (pixbuf != NULL)
+ gdk_draw_pixbuf(gport->drawable, gport->bg_gc, pixbuf,
+ 0, 0, 0, 0, vw, vh, GDK_RGB_DITHER_NORMAL, 0, 0);
+}
void
ghid_invalidate_all ()
{
+#if 0
int eleft, eright, etop, ebottom;
BoxType region;
@@ -569,10 +604,13 @@ ghid_invalidate_all ()
hid_expose_callback (&ghid_hid, ®ion, 0);
draw_grid ();
+#endif
if (ghidgui->need_restore_crosshair)
RestoreCrosshair (FALSE);
ghidgui->need_restore_crosshair = FALSE;
- ghid_screen_update ();
+// ghid_screen_update ();
+ gdk_window_invalidate_rect (gport->drawing_area->window, NULL, 1);
+// gdk_window_process_updates (gport->drawing_area->window, FALSE);
}
@@ -583,8 +621,15 @@ ghid_set_layer (const char *name, int gr
&& group <
max_layer) ? PCB->LayerGroups.Entries[group][0] : group;
- if (idx >= 0 && idx < max_layer + 2)
+ if (idx >= 0 && idx < max_layer + 2) {
+ gport->trans_lines = TRUE;
+#if 0
+ cairo_pop_group_to_source (gport->cr);
+ cairo_paint_with_alpha (gport->cr, 0.7);
+ cairo_push_group (gport->cr);
+#endif
return /*pinout ? 1 : */ PCB->Data->Layer[idx].On;
+ }
if (idx < 0)
{
switch (SL_TYPE (idx))
@@ -596,6 +641,13 @@ ghid_set_layer (const char *name, int gr
return TEST_FLAG (SHOWMASKFLAG, PCB);
return 0;
case SL_SILK:
+ //cairo_pop_group_to_source (gport->cr);
+ //if (gport->trans_lines)
+ //cairo_paint (gport->cr);
+ //else
+ //cairo_paint_with_alpha (gport->cr, 0.7);
+ //cairo_push_group (gport->cr);
+ gport->trans_lines = FALSE;
if (SL_MYSIDE (idx) /*|| pinout */ )
return PCB->ElementOn;
return 0;
@@ -625,6 +677,9 @@ ghid_use_mask (int use_it)
{
case HID_MASK_OFF:
gport->drawable = gport->pixmap;
+ //if (gport->cr) cairo_destroy (gport->cr);
+ //gport->cr = gdk_cairo_create (gport->drawable);
+
mask_seq = 0;
break;
@@ -636,6 +691,8 @@ ghid_use_mask (int use_it)
if (!gport->mask)
gport->mask = gdk_pixmap_new (0, gport->width, gport->height, 1);
gport->drawable = gport->mask;
+ //if (gport->cr) cairo_destroy (gport->cr);
+ //gport->cr = gdk_cairo_create (gport->drawable);
mask_seq = 0;
if (!gport->mask_gc)
{
@@ -647,6 +704,7 @@ ghid_use_mask (int use_it)
gport->width, gport->height);
color.pixel = 0;
gdk_gc_set_foreground (gport->mask_gc, &color);
+ printf ("Mask clearing\n");
break;
case HID_MASK_AFTER:
@@ -656,6 +714,8 @@ ghid_use_mask (int use_it)
mask_seq = mask_seq_id;
gport->drawable = gport->pixmap;
+ //if (gport->cr) cairo_destroy (gport->cr);
+ //gport->cr = gdk_cairo_create (gport->drawable);
break;
}
@@ -674,6 +734,9 @@ typedef struct
GdkColor color;
int xor_set;
GdkColor xor_color;
+ double red;
+ double green;
+ double blue;
} ColorCache;
@@ -716,11 +779,132 @@ ghid_set_special_colors (HID_Attribute *
}
}
+static void *cache = 0;
+
+void
+ghid_cairo_set_color (hidGC gc, const char *name)
+{
+ //static void *cache = 0;
+ hidval cval;
+ ColorCache *cc;
+ double alpha_mult = 1.0;
+ double r, g, b, a;
+ a = 1.0;
+
+ if (name == NULL)
+ {
+ fprintf (stderr, "%s(): name = NULL, setting to magenta\n",
+ __FUNCTION__);
+ name = "magenta";
+ }
+
+ gc->colorname = (char *) name;
+// if (!gc->gc)
+// return;
+ if (gport->colormap == 0)
+ gport->colormap = gtk_widget_get_colormap (gport->top_window);
+#if 0
+if (1)
+#else
+ if (strcmp (name, "erase") == 0)
+ {
+// gdk_cairo_set_source_color (gport->cr, &gport->bg_color);
+ gc->erase = 1;
+ r = gport->bg_color.red / 65535.;
+ g = gport->bg_color.green / 65535.;
+ b = gport->bg_color.blue / 65535.;
+ }
+ else if (strcmp (name, "drill") == 0)
+ {
+// gdk_cairo_set_source_color (gport->cr, &gport->offlimits_color);
+ gc->erase = 0;
+ alpha_mult = 0.85;
+ r = gport->offlimits_color.red / 65535.;
+ g = gport->offlimits_color.green / 65535.;
+ b = gport->offlimits_color.blue / 65535.;
+
+ }
+ else
+#endif
+ {
+ alpha_mult = 0.7;
+ if (hid_cache_color (0, name, &cval, &cache))
+ cc = (ColorCache *) cval.ptr;
+ else
+ {
+ cc = (ColorCache *) malloc (sizeof (ColorCache));
+ memset (cc, 0, sizeof (*cc));
+ cval.ptr = cc;
+ hid_cache_color (1, name, &cval, &cache);
+ }
+
+ if (!cc->color_set)
+ {
+ if (gdk_color_parse (name, &cc->color))
+ gdk_color_alloc (gport->colormap, &cc->color);
+ else
+ gdk_color_white (gport->colormap, &cc->color);
+ cc->red = cc->color.red / 65535.;
+ cc->green = cc->color.green / 65535.;
+ cc->blue = cc->color.blue / 65535.;
+ cc->color_set = 1;
+ }
+ r = cc->red;
+ g = cc->green;
+ b = cc->blue;
+ if (gc->xor)
+ {
+ if (!cc->xor_set)
+ {
+#if 0
+ cc->xor_color.red = cc->color.red ^ gport->bg_color.red;
+ cc->xor_color.green = cc->color.green ^ gport->bg_color.green;
+ cc->xor_color.blue = cc->color.blue ^ gport->bg_color.blue;
+ gdk_color_alloc (gport->colormap, &cc->xor_color);
+ cc->red = cc->color.red / 65535.;
+ cc->green = cc->color.green / 65535.;
+ cc->blue = cc->color.blue / 65535.;
+#endif
+ cc->xor_set = 1;
+ }
+// gdk_gc_set_foreground (gc->gc, &cc->xor_color);
+// gdk_cairo_set_source_color (gport->cr, &cc->xor_color);
+// cairo_set_source_rgb (gport->cr, cc->red, cc->green, cc->blue);
+ }
+ else
+ {
+// gdk_gc_set_foreground (gc->gc, &cc->color);
+// gdk_cairo_set_source_color (gport->cr, &cc->color);
+// cairo_set_source_rgb (gport->cr, cc->red, cc->green, cc->blue);
+ }
+
+ gc->erase = 0;
+ }
+ if (1) {
+ double maxi, mult;
+// cairo_pattern_get_rgba (cairo_get_source (gport->cr), &r, &g, &b, &a);
+ if (gport->trans_lines)
+ a = a * alpha_mult;
+ maxi = r;
+ if (g > maxi) maxi = g;
+ if (b > maxi) maxi = b;
+ mult = MIN (1 / alpha_mult, 1 / maxi);
+ r = r * mult;
+ g = g * mult;
+ b = b * mult;
+// cairo_set_source_rgba (gport->cr, r, g, b, a);
+ }
+}
+
void
ghid_set_color (hidGC gc, const char *name)
{
- static void *cache = 0;
hidval cval;
+// if (gport->cr) ghid_cairo_set_color (gc, name);
+#if 0
+ return;
+#else
+ //static void *cache = 0;
if (name == NULL)
{
@@ -764,6 +948,9 @@ ghid_set_color (hidGC gc, const char *na
gdk_color_alloc (gport->colormap, &cc->color);
else
gdk_color_white (gport->colormap, &cc->color);
+ cc->red = cc->color.red / 65535.;
+ cc->green = cc->color.green / 65535.;
+ cc->blue = cc->color.blue / 65535.;
cc->color_set = 1;
}
if (gc->xor)
@@ -774,6 +961,9 @@ ghid_set_color (hidGC gc, const char *na
cc->xor_color.green = cc->color.green ^ gport->bg_color.green;
cc->xor_color.blue = cc->color.blue ^ gport->bg_color.blue;
gdk_color_alloc (gport->colormap, &cc->xor_color);
+ cc->red = cc->color.red / 65535.;
+ cc->green = cc->color.green / 65535.;
+ cc->blue = cc->color.blue / 65535.;
cc->xor_set = 1;
}
gdk_gc_set_foreground (gc->gc, &cc->xor_color);
@@ -785,12 +975,35 @@ ghid_set_color (hidGC gc, const char *na
gc->erase = 0;
}
+#endif
+}
+
+static void
+ghid_cairo_set_line_cap (hidGC gc, EndCapStyle style)
+{
+ switch (style)
+ {
+ case Trace_Cap:
+ case Round_Cap:
+ gc->cairo_cap = CAIRO_LINE_CAP_ROUND;
+ gc->cairo_join = CAIRO_LINE_JOIN_ROUND;
+ break;
+ case Square_Cap:
+ case Beveled_Cap:
+ gc->cairo_cap = CAIRO_LINE_CAP_SQUARE;
+ gc->cairo_join = CAIRO_LINE_JOIN_MITER;
+ break;
+ }
+ // GDK_LINE_SOLID,
+// cairo_set_line_cap (gport->cr, gc->cairo_cap);
+// cairo_set_line_join (gport->cr, gc->cairo_join);
}
void
ghid_set_line_cap (hidGC gc, EndCapStyle style)
{
-
+// if (gport->cr) ghid_cairo_set_line_cap (gc, style);
+#if 1
switch (style)
{
case Trace_Cap:
@@ -804,31 +1017,58 @@ ghid_set_line_cap (hidGC gc, EndCapStyle
gc->join = GDK_JOIN_MITER;
break;
}
+#endif
+#if 0
if (gc->gc)
gdk_gc_set_line_attributes (WHICH_GC (gc),
Vz (gc->width), GDK_LINE_SOLID,
gc->cap, gc->join);
+#endif
+}
+
+static void
+ghid_cairo_set_line_width (hidGC gc, int width)
+{
+ int s_width;
+ gc->width = width;
+ s_width = Vz(gc->width);
+ if (s_width == 0) s_width = 1;
+// cairo_set_line_width (gport->cr, s_width);
+ // GDK_LINE_SOLID,
+// cairo_set_line_join (gport->cr, gc->cairo_join);
+ // gc->join
+// cairo_set_line_cap (gport->cr, gc->cairo_cap);
}
void
ghid_set_line_width (hidGC gc, int width)
{
-
+// if (gport->cr) ghid_cairo_set_line_width (gc, width);
gc->width = width;
+#if 0
if (gc->gc)
gdk_gc_set_line_attributes (WHICH_GC (gc),
Vz (gc->width), GDK_LINE_SOLID,
gc->cap, gc->join);
+#endif
+}
+
+static void
+ghid_cairo_set_draw_xor (hidGC gc, int xor)
+{
+// cairo_set_operator (gport->cr, xor ? CAIRO_OPERATOR_XOR : CAIRO_OPERATOR_OVER);
+// ghid_cairo_set_color (gc, gc->colorname);
}
void
ghid_set_draw_xor (hidGC gc, int xor)
{
- gc->xor = xor;
- if (!gc->gc)
- return;
- gdk_gc_set_function (gc->gc, xor ? GDK_XOR : GDK_COPY);
- ghid_set_color (gc, gc->colorname);
+// gc->xor = xor;
+// if (gport->cr) ghid_cairo_set_draw_xor (gc, xor);
+// if (!gc->gc)
+// return;
+// gdk_gc_set_function (gc->gc, xor ? GDK_XOR : GDK_COPY);
+// ghid_set_color (gc, gc->colorname);
}
void
@@ -846,8 +1086,18 @@ ghid_set_line_cap_angle (hidGC gc, int x
static int
use_gc (hidGC gc)
{
- if (!gport->pixmap)
+ static hidGC last_gc = 0;
+
+ if (last_gc == gc) return 1;
+
+ last_gc = gc;
+#if 0
+ if (!gport->pixmap) {
+ printf ("NULL pixmap\n");
return 0;
+ }
+#endif
+#if 0
if (!gc->gc)
{
gc->gc = gdk_gc_new (gport->top_window->window);
@@ -856,6 +1106,8 @@ use_gc (hidGC gc)
ghid_set_line_cap (gc, gc->cap);
ghid_set_draw_xor (gc, gc->xor);
}
+#endif
+#if 0
if (gc->mask_seq != mask_seq)
{
if (mask_seq)
@@ -865,25 +1117,135 @@ use_gc (hidGC gc)
gc->mask_seq = mask_seq;
}
gport->u_gc = WHICH_GC (gc);
+#endif
+#if 0
+ ghid_cairo_set_color (gc, gc->colorname);
+ ghid_cairo_set_line_width (gc, gc->width);
+ ghid_cairo_set_line_cap (gc, gc->cap);
+// ghid_cairo_set_draw_xor (gc, gc->xor);
+#endif
return 1;
}
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+void CALLBACK errorCallback(GLenum errorCode)
+{
+ const GLubyte *estring;
+
+ estring = gluErrorString(errorCode);
+ fprintf(stderr, "Quadric Error: %s\n", estring);
+ exit(0);
+}
+
+
void
ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
{
double dx1, dy1, dx2, dy2;
+ GLUquadricObj *qobj;
+ double width;
- dx1 = Vx ((double)x1);
- dy1 = Vy ((double)y1);
- dx2 = Vx ((double)x2);
- dy2 = Vy ((double)y2);
+ GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
+ GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat mat_shininess[] = { 50.0 };
+ GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+ GLfloat model_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
if (! ClipLine (0, 0, gport->width, gport->height,
- &dx1, &dy1, &dx2, &dy2, gc->width / gport->zoom))
+ &dx1, &dy1, &dx2, &dy2, gc->width / gport->zoom))
return;
- USE_GC (gc);
- gdk_draw_line (gport->drawable, gport->u_gc, dx1, dy1, dx2, dy2);
+// glClearColor(0.0, 0.0, 0.0, 0.0);
+
+// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glShadeModel (GL_SMOOTH);
+
+ glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ dx1 = Vx (x1)+0.5;
+ dy1 = Vy (y1)+0.5;
+ dx2 = Vx (x2)+0.5;
+ dy2 = Vy (y2)+0.5;
+
+ width = Vz (gc->width);
+
+ if (width == 0.0)
+ width = 1.0;
+
+#if 0
+/\
+\ \
+ \ \
+ \ \
+ \ \
+ \/
+ _
+| |
+| |
+| |
+| |
+|_|
+#endif
+
+{
+ float deltax, deltay, length;
+ float wdx, wdy;
+
+ deltax = dx2 - dx1;
+ deltay = dy2 - dy1;
+
+ length = sqrt (deltax * deltax + deltay * deltay);
+
+ wdy = deltax * width / 2 / length;
+ wdx = -deltay * width / 2 / length;
+
+ glBegin (GL_QUADS);
+// glBegin (GL_LINE_LOOP);
+ glNormal3f (0.0f, 0.0f, 1.0f);
+ glVertex3f (dx1 - wdx, dy1 - wdy, 0.0f);
+ glVertex3f (dx2 - wdx, dy2 - wdy, 0.0f);
+ glVertex3f (dx2 + wdx, dy2 + wdy, 0.0f);
+ glVertex3f (dx1 + wdx, dy1 + wdy, 0.0f);
+ glEnd ();
+}
+
+#if 1
+ qobj = gluNewQuadric();
+ gluQuadricCallback(qobj, GLU_ERROR, errorCallback);
+ gluQuadricDrawStyle (qobj, GLU_FILL); /* smooth shaded */
+// gluQuadricDrawStyle (qobj, GLU_LINE); /* smooth shaded */
+ gluQuadricNormals (qobj, GLU_SMOOTH);
+
+ glPushMatrix();
+ glTranslatef (dx1, dy1, 0.0);
+ gluDisk (qobj, 0, width / 2, 50, 1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef (dx2, dy2, 0.0);
+ gluDisk (qobj, 0, width / 2, 50, 1);
+ glPopMatrix();
+#endif
+
+#if 0
+ ghid_cairo_set_color (gc, gc->colorname);
+ ghid_cairo_set_line_width (gc, gc->width);
+ ghid_cairo_set_line_cap (gc, gc->cap);
+// ghid_cairo_set_draw_xor (gc, gc->xor);
+#endif
+// USE_GC (gc);
}
void
@@ -906,7 +1268,6 @@ ghid_draw_arc (hidGC gc, int cx, int cy,
vrx = Vz (xradius);
vry = Vz (yradius);
-
/* make sure we fall in the -180 to +180 range */
start_angle = (start_angle + 360 + 180) % 360 - 180;
if (ghid_flip_x)
@@ -920,9 +1281,18 @@ ghid_draw_arc (hidGC gc, int cx, int cy,
delta_angle = - delta_angle;
}
- gdk_draw_arc (gport->drawable, gport->u_gc, 0,
- Vx (cx) - vrx, Vy (cy) - vry,
- vrx * 2, vry * 2, (start_angle + 180) * 64, delta_angle * 64);
+ //cairo_new_sub_path (gport->cr);
+
+ //cairo_save (gport->cr);
+ //cairo_translate (gport->cr, Vx(cx) + 0.5, Vy(cy) + 0.5);
+ //cairo_scale (gport->cr, vrx, vry);
+ if (delta_angle < 0) {
+ //cairo_arc (gport->cr, 0., 0., 1., (180 - start_angle) * (M_PI / 180.), (180 - start_angle - delta_angle) * (M_PI / 180.));
+ } else {
+ //cairo_arc_negative (gport->cr, 0., 0., 1., (180 - start_angle) * (M_PI / 180.), (180 - start_angle - delta_angle) * (M_PI / 180.));
+ }
+ //cairo_restore (gport->cr);
+ //cairo_stroke (gport->cr);
}
void
@@ -953,8 +1323,8 @@ ghid_draw_rect (hidGC gc, int x1, int y1
if (y1 > y2) { gint yt = y1; y1 = y2; y2 = yt; }
USE_GC (gc);
- gdk_draw_rectangle (gport->drawable, gport->u_gc, FALSE,
- x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ //cairo_rectangle (gport->cr, x1 + 0.5, y1 + 0.5, x2 - x1 + 1, y2 - y1 + 1);
+ //cairo_stroke (gport->cr);
}
@@ -973,31 +1343,26 @@ ghid_fill_circle (hidGC gc, int cx, int
USE_GC (gc);
vr = Vz (radius);
- gdk_draw_arc (gport->drawable, gport->u_gc, TRUE,
- Vx (cx) - vr, Vy (cy) - vr,
- vr * 2, vr * 2, 0, 360 * 64);
+
+ //cairo_new_sub_path (gport->cr);
+ //cairo_arc (gport->cr, Vx(cx) + 0.5, Vy(cy) + 0.5, vr, 0, 2 * M_PI);
+ //cairo_fill (gport->cr);
}
void
ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
{
- static GdkPoint *points = 0;
- static int npoints = 0;
int i;
USE_GC (gc);
- if (npoints < n_coords)
- {
- npoints = n_coords + 1;
- points = MyRealloc (points,
- npoints * sizeof (GdkPoint), (char *) __FUNCTION__);
- }
- for (i = 0; i < n_coords; i++)
+ g_assert (n_coords > 0);
+ //cairo_move_to (gport->cr, Vx (x[0]) + 0.5, Vy (y[0]) + 0.5);
+ for (i = 1; i < n_coords; i++)
{
- points[i].x = Vx (x[i]);
- points[i].y = Vy (y[i]);
+ //cairo_line_to (gport->cr, Vx (x[i]) + 0.5, Vy (y[i]) + 0.5);
}
- gdk_draw_polygon (gport->drawable, gport->u_gc, 1, points, n_coords);
+ //cairo_close_path (gport->cr);
+ //cairo_fill (gport->cr);
}
void
@@ -1036,8 +1401,8 @@ ghid_fill_rect (hidGC gc, int x1, int y1
y2 = yy;
}
USE_GC (gc);
- gdk_draw_rectangle (gport->drawable, gport->u_gc, TRUE,
- x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ //cairo_rectangle (gport->cr, x1 + 0.5, y1 + 0.5, x2 - x1 + 1, y2 - y1 + 1);
+ //cairo_fill (gport->cr);
}
void
@@ -2160,11 +2525,22 @@ Benchmark (int argc, char **argv, int x,
region.X2 = PCB->MaxWidth;
region.Y2 = PCB->MaxHeight;
+
+
gdk_display_sync (display);
time (&start);
do
{
+ gdk_window_invalidate_rect (gport->drawing_area->window, NULL, 1);
+ gdk_window_process_updates (gport->drawing_area->window, FALSE);
+
+// ghid_port_drawing_area_expose_event_cb (gport->drawing_area, NULL, gport);
+#if 0
+ cairo_push_group (gport->cr);
hid_expose_callback (&ghid_hid, ®ion, 0);
+ cairo_pop_group_to_source (gport->cr);
+ cairo_paint_with_alpha (gport->cr, 0.7);
+#endif
gdk_display_sync (display);
time (&end);
i++;
Index: src/hid/gtk/gui-output-events.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/gtk/gui-output-events.c,v
retrieving revision 1.26
diff -U3 -p -r1.26 gui-output-events.c
--- src/hid/gtk/gui-output-events.c 13 Apr 2008 16:06:39 -0000 1.26
+++ src/hid/gtk/gui-output-events.c 14 Jun 2008 16:59:29 -0000
@@ -300,12 +300,14 @@ ghid_show_crosshair (gboolean show)
static GdkGC *xor_gc;
static GdkColor cross_color;
+ return;
+
if (gport->x_crosshair < 0 || ghidgui->creating || !gport->has_entered)
return;
if (!xor_gc)
{
- xor_gc = gdk_gc_new (ghid_port.drawing_area->window);
+ xor_gc = gdk_gc_new (ghid_port.drawable);
gdk_gc_copy (xor_gc, ghid_port.drawing_area->style->white_gc);
gdk_gc_set_function (xor_gc, GDK_XOR);
/* FIXME: when CrossColor changed from config */
@@ -316,42 +318,32 @@ ghid_show_crosshair (gboolean show)
gdk_gc_set_foreground (xor_gc, &cross_color);
+#if 1
if (x_prev >= 0)
{
- gdk_draw_line (gport->drawing_area->window, xor_gc,
- x_prev, 0, x_prev, gport->height);
- gdk_draw_line (gport->drawing_area->window, xor_gc,
- 0, y_prev, gport->width, y_prev);
+ gdk_draw_line (gport->drawable, xor_gc, x_prev, 0, x_prev, gport->height);
+ gdk_draw_line (gport->drawable, xor_gc, 0, y_prev, gport->width, y_prev);
if (ghidgui->auto_pan_on && have_crosshair_attachments ())
- {
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- 0, y_prev - VCD, VCD, VCW);
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- gport->width - VCD, y_prev - VCD, VCD, VCW);
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- x_prev - VCD, 0, VCW, VCD);
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- x_prev - VCD, gport->height - VCD, VCW, VCD);
- }
+ {
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, 0, y_prev - VCD, VCD, VCW);
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, gport->width - VCD, y_prev - VCD, VCD, VCW);
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, x_prev - VCD, 0, VCW, VCD);
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, x_prev - VCD, gport->height - VCD, VCW, VCD);
+ }
}
+#endif
if (x >= 0 && show)
{
- gdk_draw_line (gport->drawing_area->window, xor_gc,
- x, 0, x, gport->height);
- gdk_draw_line (gport->drawing_area->window, xor_gc,
- 0, y, gport->width, y);
+ gdk_draw_line (gport->drawable, xor_gc, x, 0, x, gport->height);
+ gdk_draw_line (gport->drawable, xor_gc, 0, y, gport->width, y);
if (ghidgui->auto_pan_on && have_crosshair_attachments ())
- {
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- 0, y - VCD, VCD, VCW);
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- gport->width - VCD, y - VCD, VCD, VCW);
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- x - VCD, 0, VCW, VCD);
- gdk_draw_rectangle (gport->drawing_area->window, xor_gc, TRUE,
- x - VCD, gport->height - VCD, VCW, VCD);
- }
+ {
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, 0, y - VCD, VCD, VCW);
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, gport->width - VCD, y - VCD, VCD, VCW);
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, x - VCD, 0, VCW, VCD);
+ gdk_draw_rectangle (gport->drawable, xor_gc, TRUE, x - VCD, gport->height - VCD, VCW, VCD);
+ }
x_prev = x;
y_prev = y;
}
@@ -757,26 +749,238 @@ ghid_port_drawing_area_configure_event_c
return 0;
}
+static inline int
+Px (int x)
+{
+ int rv = x * gport->zoom + gport->view_x0;
+ if (ghid_flip_x)
+ rv = PCB->MaxWidth - (x * gport->zoom + gport->view_x0);
+ return rv;
+}
+
+static inline int
+Py (int y)
+{
+ int rv = y * gport->zoom + gport->view_y0;
+ if (ghid_flip_y)
+ rv = PCB->MaxHeight - (y * gport->zoom + gport->view_y0);
+ return rv;
+}
+
+static inline int
+Vx (int x)
+{
+ int rv;
+ if (ghid_flip_x)
+ rv = (PCB->MaxWidth - x - gport->view_x0) / gport->zoom + 0.5;
+ else
+ rv = (x - gport->view_x0) / gport->zoom + 0.5;
+ return rv;
+}
+
+static inline int
+Vy (int y)
+{
+ int rv;
+ if (ghid_flip_y)
+ rv = (PCB->MaxHeight - y - gport->view_y0) / gport->zoom + 0.5;
+ else
+ rv = (y - gport->view_y0) / gport->zoom + 0.5;
+ return rv;
+}
void
ghid_screen_update (void)
{
-
+#if 0
ghid_show_crosshair (FALSE);
gdk_draw_drawable (gport->drawing_area->window, gport->bg_gc, gport->pixmap,
0, 0, 0, 0, gport->width, gport->height);
ghid_show_crosshair (TRUE);
+#endif
}
+void DrawAttached (Boolean);
+void draw_grid ();
+
+#define Z_NEAR 3.0
+#define FOVY_2 20.0
gboolean
ghid_port_drawing_area_expose_event_cb (GtkWidget * widget,
GdkEventExpose * ev, GHidPort * port)
{
+ BoxType region;
+ extern HID ghid_hid;
+ GdkDrawable *save_drawable;
+ GdkGLContext* pGlContext = gtk_widget_get_gl_context (widget);
+ GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (widget);
+ GLuint auiColorBuffer;
+ cairo_surface_t *dsurf;
+ /* Should be elsewhere */
+ static guchar *surface_data;
+ /* Should be elsewhere */
+
+ save_drawable = gport->drawable;
+ gport->drawable = widget->window;
+
ghid_show_crosshair (FALSE);
- gdk_draw_drawable (widget->window, port->bg_gc, port->pixmap,
- ev->area.x, ev->area.y, ev->area.x, ev->area.y,
- ev->area.width, ev->area.height);
+
+
+ /* make GL-context "current" */
+ if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext)) {
+ printf ("FUBAR\n");
+ return FALSE;
+ }
+
+// glEnable (GL_BLEND);
+// glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+// glShadeModel (GL_FLAT);
+
+#if 0
+ glEnable (GL_TEXTURE_RECTANGLE_ARB);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri (GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri (GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR);
+#endif
+
+ glViewport (0, 0, ev->area.width, ev->area.height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+// gluPerspective (2.0f * FOVY_2, (GLfloat) ev->area.width / (GLfloat) ev->area.height, 0.0f, 50.0f);
+ glOrtho (0, ev->area.width, ev->area.height, 0, 0, 100);
+// glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+#if 0
+ gluLookAt (0.0f, 0.0f, Z_NEAR,
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f);
+#endif
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+#if 0
+// if (surface_data == NULL)
+ g_free (surface_data);
+ surface_data = g_malloc0 (4 * ev->area.width * ev->area.height);
+
+ dsurf = cairo_image_surface_create_for_data (surface_data, CAIRO_FORMAT_ARGB32,
+ ev->area.width, ev->area.height,
+ 4 * ev->area.width);
+
+ if (gport->cr) cairo_destroy (gport->cr);
+ gport->cr = cairo_create (dsurf);
+#endif
+
+ region.X1 = MIN(Px(0), Px(gport->width + 1));
+ region.Y1 = MIN(Py(0), Py(gport->height + 1));
+ region.X2 = MAX(Px(0), Px(gport->width + 1));
+ region.Y2 = MAX(Py(0), Py(gport->height + 1));
+
+// cairo_push_group (gport->cr);
+
+ hid_expose_callback (&ghid_hid, ®ion, 0);
+#if 0
+ cairo_pop_group_to_source (gport->cr);
+ cairo_paint_with_alpha (gport->cr, 0.7);
+ draw_grid ();
+
+ DrawAttached (TRUE);
ghid_show_crosshair (TRUE);
+
+ gport->drawable = save_drawable;
+
+ glGenTextures (1, &auiColorBuffer);
+
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, auiColorBuffer);
+ glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,
+ 0, GL_RGBA, ev->area.width, ev->area.height,
+ 0, GL_BGRA, GL_UNSIGNED_BYTE,
+ surface_data);
+#endif
+
+#if 0
+ {
+ float GLhwidth;
+ GLhwidth = 1.0 * (float)ev->area.width / (float)ev->area.height;
+
+ glBegin (GL_QUADS);
+ glNormal3f (0.0f, 0.0f, 1.0f);
+ glTexCoord2f ((GLfloat) ev->area.width, 0.0f);
+ glVertex3f (GLhwidth, 1.0f, 0.0f);
+ glTexCoord2f (0.0f, 0.0f);
+ glVertex3f (-GLhwidth, 1.0f, 0.0f);
+ glTexCoord2f (0.0f, (GLfloat) ev->area.height);
+ glVertex3f (-GLhwidth, -1.0f, 0.0f);
+ glTexCoord2f ((GLfloat) ev->area.width, (GLfloat) ev->area.height);
+ glVertex3f (GLhwidth, -1.0f, 0.0f);
+ glEnd ();
+ }
+#endif
+
+if (0) {
+ GLUquadricObj *qobj;
+
+ GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
+ GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat mat_shininess[] = { 50.0 };
+ GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+ GLfloat model_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
+
+// glClearColor(0.0, 0.0, 0.0, 0.0);
+
+// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glPushMatrix();
+
+ glShadeModel (GL_SMOOTH);
+// glTranslatef(-1.0, -1.0, 0.0);
+
+ glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ glTranslatef (0, 0, 0);
+
+#if 1
+ qobj = gluNewQuadric();
+
+ gluQuadricDrawStyle(qobj, GLU_FILL); /* smooth shaded */
+ gluQuadricNormals(qobj, GLU_SMOOTH);
+ gluSphere(qobj, 1, 15, 10);
+#endif
+
+// glutSolidTeapot(1.0);
+
+ glPopMatrix();
+
+ }
+
+// glPopMatrix ();
+
+ if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
+ gdk_gl_drawable_swap_buffers (pGlDrawable);
+ else
+ glFlush ();
+
+// glDeleteTextures (1, &auiColorBuffer);
+
+ /* end drawing to current GL-context */
+ gdk_gl_drawable_gl_end (pGlDrawable);
+
return FALSE;
}
@@ -789,6 +993,7 @@ ghid_port_window_motion_cb (GtkWidget *
static gint x_prev = -1, y_prev = -1;
gboolean moved;
GdkModifierType state;
+ GdkDrawable *save_drawable;
state = (GdkModifierType) (ev->state);
mk = ghid_modifier_keys_state (&state);
@@ -808,9 +1013,14 @@ ghid_port_window_motion_cb (GtkWidget *
}
x_prev = y_prev = -1;
moved = ghid_note_event_location (ev);
+
+ save_drawable = gport->drawable;
+ gport->drawable = gport->drawing_area->window;
ghid_show_crosshair (TRUE);
+ gport->drawable = save_drawable;
if (moved && have_crosshair_attachments ())
ghid_draw_area_update (gport, NULL);
+
return FALSE;
}
Index: src/hid/gtk/gui-top-window.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/gtk/gui-top-window.c,v
retrieving revision 1.54
diff -U3 -p -r1.54 gui-top-window.c
--- src/hid/gtk/gui-top-window.c 31 Jan 2008 01:23:09 -0000 1.54
+++ src/hid/gtk/gui-top-window.c 14 Jun 2008 16:59:31 -0000
@@ -2295,6 +2295,13 @@ ghid_build_pcb_top_window (void)
gtk_box_pack_start (GTK_BOX (hbox), viewport, TRUE, TRUE, 0);
gport->drawing_area = gtk_drawing_area_new ();
+#if 1
+ gtk_widget_set_gl_capability (gport->drawing_area,
+ gport->glconfig,
+ NULL,
+ TRUE,
+ GDK_GL_RGBA_TYPE);
+#endif
gtk_widget_add_events (gport->drawing_area, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
@@ -2657,11 +2664,27 @@ ghid_parse_arguments (int *argc, char **
gtk_disable_setlocale ();
gtk_init (argc, argv);
+#if 1
+ gtk_gl_init(argc, argv);
+ glutInit(argc, *argv);
+#endif
gport = &ghid_port;
gport->zoom = 300.0;
pixel_slop = 300;
+#if 1
+ /* setup GL-context */
+ gport->glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
+ GDK_GL_MODE_ALPHA |
+ GDK_GL_MODE_DEPTH |
+ GDK_GL_MODE_DOUBLE);
+ if (!gport->glconfig) {
+ printf("Could not setup GL-context!\n");
+ return; /* Should we abort? */
+ }
+#endif
+
ghid_config_files_read (argc, argv);
Settings.AutoPlace = 0;
Index: src/hid/gtk/gui.h
===================================================================
RCS file: /cvsroot/pcb/pcb/src/hid/gtk/gui.h,v
retrieving revision 1.25
diff -U3 -p -r1.25 gui.h
--- src/hid/gtk/gui.h 13 Apr 2008 14:15:38 -0000 1.25
+++ src/hid/gtk/gui.h 14 Jun 2008 16:59:31 -0000
@@ -35,6 +35,10 @@
#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
+#include <GL/glu.h>
+//#include <GL/glut.h>
+
/* Internationalization support.
*/
#if defined (ENABLE_NLS)
@@ -128,6 +132,8 @@ typedef struct hid_gc_struct
gchar *colorname;
gint width;
gint cap, join;
+ cairo_line_cap_t cairo_cap;
+ cairo_line_join_t cairo_join;
gchar xor;
gchar erase;
gint mask_seq;
@@ -197,6 +203,11 @@ typedef struct
GdkDrawable *drawable; /* Current drawable for drawing routines */
gint width, height;
+ GdkGLConfig *glconfig;
+
+ cairo_t *cr;
+ gint trans_lines;
+
GdkGC *bg_gc, *offlimits_gc, *mask_gc, *u_gc, *grid_gc;
GdkColor bg_color, offlimits_color, grid_color;
_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev