On Sun, 2008-06-15 at 19:00 +0200, Bert Timmerman wrote:
> Hi Peter,
>
> http://www.xs4all.nl/~ljh4timm/downloads/pcb-OpenGL-screenshot4.png
>
> Gives a better view (the other side of the board.
>
> Silk is indeed on top of mask as it should be.
I fixed the mask drawing to work vaguely correctly now. Try the attached
patch. It also features cross-hairs, and construction / rubber-band
lines.
Bling :)
--
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 15 Jun 2008 21:36:44 -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 15 Jun 2008 21:36:46 -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/draw.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/draw.c,v
retrieving revision 1.87
diff -U3 -p -r1.87 draw.c
--- src/draw.c 10 Dec 2007 03:29:55 -0000 1.87
+++ src/draw.c 15 Jun 2008 21:36:47 -0000
@@ -355,7 +355,7 @@ static int
lowvia_callback (const BoxType * b, void *cl)
{
PinTypePtr via = (PinTypePtr) b;
- if (!via->Mask)
+// if (!via->Mask)
DrawPlainVia (via, False);
return 1;
}
@@ -473,25 +473,9 @@ DrawEverything (BoxTypePtr drawn_area)
}
if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui)
return;
-
/* draw vias below silk */
if (PCB->ViaOn && gui->gui)
r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, NULL);
- /* Draw the solder mask if turned on */
- if (gui->set_layer ("componentmask", SL (MASK, TOP)))
- {
- int save_swap = SWAP_IDENT;
- SWAP_IDENT = 0;
- DrawMask (drawn_area);
- SWAP_IDENT = save_swap;
- }
- if (gui->set_layer ("soldermask", SL (MASK, BOTTOM)))
- {
- int save_swap = SWAP_IDENT;
- SWAP_IDENT = 1;
- DrawMask (drawn_area);
- SWAP_IDENT = save_swap;
- }
/* Draw pins, pads, vias below silk */
if (gui->gui)
DrawTop (drawn_area);
@@ -520,6 +504,21 @@ DrawEverything (BoxTypePtr drawn_area)
&plated);
}
}
+ /* Draw the solder mask if turned on */
+ if (gui->set_layer ("componentmask", SL (MASK, TOP)))
+ {
+ int save_swap = SWAP_IDENT;
+ SWAP_IDENT = 0;
+ DrawMask (drawn_area);
+ SWAP_IDENT = save_swap;
+ }
+ if (gui->set_layer ("soldermask", SL (MASK, BOTTOM)))
+ {
+ int save_swap = SWAP_IDENT;
+ SWAP_IDENT = 1;
+ DrawMask (drawn_area);
+ SWAP_IDENT = save_swap;
+ }
/* Draw top silkscreen */
if (gui->set_layer ("topsilk", SL (SILK, TOP)))
DrawSilk (0, COMPONENT_LAYER, drawn_area);
@@ -625,7 +624,7 @@ static int
via_callback (const BoxType * b, void *cl)
{
PinTypePtr via = (PinTypePtr) b;
- if (via->Mask)
+// if (via->Mask)
DrawPlainVia (via, False);
return 1;
}
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 15 Jun 2008 21:36:47 -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 15 Jun 2008 21:36:47 -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/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 15 Jun 2008 21:36:47 -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 15 Jun 2008 21:36:48 -0000
@@ -32,10 +32,14 @@
#include <gdk/gdkx.h>
#endif
+#include <gtk/gtkgl.h>
+#include <GL/glut.h>
+
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
#endif
+#define PIXELS_PER_CIRCLINE 5.
RCSID ("$Id: gtkhid-main.c,v 1.56 2008/04/13 15:29:20 petercjclifton Exp $");
@@ -48,7 +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,105 +480,76 @@ 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;
-void
-ghid_invalidate_all ()
-{
- int eleft, eright, etop, ebottom;
- BoxType region;
+ if (!ghidgui->bg_pixbuf)
+ return;
- if (!gport->pixmap)
+ 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;
- 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));
-
- eleft = Vx (0);
- eright = Vx (PCB->MaxWidth);
- etop = Vy (0);
- ebottom = Vy (PCB->MaxHeight);
- if (eleft > eright)
- {
- int tmp = eleft;
- eleft = eright;
- eright = tmp;
- }
- if (etop > ebottom)
- {
- int tmp = etop;
- etop = ebottom;
- ebottom = tmp;
- }
-
- if (eleft > 0)
- gdk_draw_rectangle (gport->drawable, gport->offlimits_gc,
- 1, 0, 0, eleft, gport->height);
- else
- eleft = 0;
- if (eright < gport->width)
- gdk_draw_rectangle (gport->drawable, gport->offlimits_gc,
- 1, eright, 0, gport->width - eright, gport->height);
- else
- eright = gport->width;
- if (etop > 0)
- gdk_draw_rectangle (gport->drawable, gport->offlimits_gc,
- 1, eleft, 0, eright - eleft + 1, etop);
- else
- etop = 0;
- if (ebottom < gport->height)
- gdk_draw_rectangle (gport->drawable, gport->offlimits_gc,
- 1, eleft, ebottom, eright - eleft + 1,
- gport->height - ebottom);
- else
- ebottom = gport->height;
+ 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);
- gdk_draw_rectangle (gport->drawable, gport->bg_gc, 1,
- eleft, etop, eright - eleft + 1, ebottom - etop + 1);
+ if (w > w_src && h > h_src)
+ interp_type = GDK_INTERP_NEAREST;
+ else
+ interp_type = GDK_INTERP_BILINEAR;
- ghid_draw_bg_image();
+ 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);
+}
- hid_expose_callback (&ghid_hid, ®ion, 0);
- draw_grid ();
+void
+ghid_invalidate_all ()
+{
if (ghidgui->need_restore_crosshair)
RestoreCrosshair (FALSE);
ghidgui->need_restore_crosshair = FALSE;
- ghid_screen_update ();
+ gdk_window_invalidate_rect (gport->drawing_area->window, NULL, 1);
}
@@ -583,8 +560,10 @@ 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;
return /*pinout ? 1 : */ PCB->Data->Layer[idx].On;
+ }
if (idx < 0)
{
switch (SL_TYPE (idx))
@@ -596,6 +575,7 @@ ghid_set_layer (const char *name, int gr
return TEST_FLAG (SHOWMASKFLAG, PCB);
return 0;
case SL_SILK:
+ gport->trans_lines = FALSE;
if (SL_MYSIDE (idx) /*|| pinout */ )
return PCB->ElementOn;
return 0;
@@ -609,55 +589,39 @@ ghid_set_layer (const char *name, int gr
return 0;
}
-#define WHICH_GC(gc) (cur_mask == HID_MASK_CLEAR ? gport->mask_gc : (gc)->gc)
-
void
ghid_use_mask (int use_it)
{
- static int mask_seq_id = 0;
- GdkColor color;
-
- if (!gport->pixmap)
- return;
if (use_it == cur_mask)
return;
+
switch (use_it)
{
- case HID_MASK_OFF:
- gport->drawable = gport->pixmap;
- mask_seq = 0;
- break;
-
case HID_MASK_BEFORE:
- printf ("gtk doesn't support mask_before!\n");
- abort ();
+ /* Write '1' to the stencil buffer where the solder-mask is drawn. */
+ glColorMask (0, 0, 0, 0); // Disable writting in color buffer
+ glEnable (GL_STENCIL_TEST); // Enable Stencil test
+ glStencilFunc (GL_ALWAYS, 1, 1); // Test always passes, value written 1
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); // Stencil pass => replace stencil value (with 1)
+ break;
case HID_MASK_CLEAR:
- if (!gport->mask)
- gport->mask = gdk_pixmap_new (0, gport->width, gport->height, 1);
- gport->drawable = gport->mask;
- mask_seq = 0;
- if (!gport->mask_gc)
- {
- gport->mask_gc = gdk_gc_new (gport->drawable);
- }
- color.pixel = 1;
- gdk_gc_set_foreground (gport->mask_gc, &color);
- gdk_draw_rectangle (gport->drawable, gport->mask_gc, TRUE, 0, 0,
- gport->width, gport->height);
- color.pixel = 0;
- gdk_gc_set_foreground (gport->mask_gc, &color);
+ /* Drawing operations clear the stencil buffer to '0' */
+ glStencilFunc (GL_ALWAYS, 0, 1); // Test always passes, value written 0
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); // Stencil pass => replace stencil value (with 0)
break;
case HID_MASK_AFTER:
- mask_seq_id++;
- if (!mask_seq_id)
- mask_seq_id = 1;
- mask_seq = mask_seq_id;
-
- gport->drawable = gport->pixmap;
+ /* Drawing operations as masked to areas where the stencil buffer is '1' */
+ glColorMask (1, 1, 1, 1); // Enable drawing of r, g, b & a
+ glStencilFunc (GL_EQUAL, 1, 1); // Draw only where stencil buffer is 1
+ glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); // Stencil buffer read only
break;
+ case HID_MASK_OFF:
+ /* Disable stenciling */
+ glDisable (GL_STENCIL_TEST); // Disable Stencil test
+ break;
}
cur_mask = use_it;
}
@@ -674,6 +638,9 @@ typedef struct
GdkColor color;
int xor_set;
GdkColor xor_color;
+ double red;
+ double green;
+ double blue;
} ColorCache;
@@ -716,11 +683,103 @@ ghid_set_special_colors (HID_Attribute *
}
}
+static void *cache = 0;
+
+void
+ghid_gl_set_color (hidGC gc, const char *name)
+{
+ 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 (gport->colormap == 0)
+ gport->colormap = gtk_widget_get_colormap (gport->top_window);
+ if (strcmp (name, "erase") == 0)
+ {
+ 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)
+ {
+ 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
+ {
+ 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)
+ {
+ cc->xor_set = 1;
+ }
+ }
+
+ gc->erase = 0;
+ }
+ if (1) {
+ double maxi, mult;
+ 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);
+#if 1
+ r = r * mult;
+ g = g * mult;
+ b = b * mult;
+#endif
+ }
+ glColor4d (r, g, b, a);
+}
+
void
ghid_set_color (hidGC gc, const char *name)
{
- static void *cache = 0;
hidval cval;
+ ghid_gl_set_color (gc, name);
if (name == NULL)
{
@@ -764,6 +823,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 +836,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);
@@ -790,7 +855,6 @@ ghid_set_color (hidGC gc, const char *na
void
ghid_set_line_cap (hidGC gc, EndCapStyle style)
{
-
switch (style)
{
case Trace_Cap:
@@ -804,31 +868,18 @@ ghid_set_line_cap (hidGC gc, EndCapStyle
gc->join = GDK_JOIN_MITER;
break;
}
- if (gc->gc)
- gdk_gc_set_line_attributes (WHICH_GC (gc),
- Vz (gc->width), GDK_LINE_SOLID,
- gc->cap, gc->join);
}
void
ghid_set_line_width (hidGC gc, int width)
{
-
gc->width = width;
- if (gc->gc)
- gdk_gc_set_line_attributes (WHICH_GC (gc),
- Vz (gc->width), GDK_LINE_SOLID,
- gc->cap, gc->join);
}
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);
+ /* NOT IMPLEMENTED */
}
void
@@ -843,56 +894,127 @@ ghid_set_line_cap_angle (hidGC gc, int x
printf ("ghid_set_line_cap_angle() -- not implemented\n");
}
-static int
-use_gc (hidGC gc)
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+void CALLBACK errorCallback(GLenum errorCode)
{
- if (!gport->pixmap)
- return 0;
- if (!gc->gc)
- {
- gc->gc = gdk_gc_new (gport->top_window->window);
- ghid_set_color (gc, gc->colorname);
- ghid_set_line_width (gc, gc->width);
- ghid_set_line_cap (gc, gc->cap);
- ghid_set_draw_xor (gc, gc->xor);
- }
- if (gc->mask_seq != mask_seq)
- {
- if (mask_seq)
- gdk_gc_set_clip_mask (gc->gc, gport->mask);
- else
- gdk_gc_set_clip_mask (gc->gc, NULL);
- gc->mask_seq = mask_seq;
- }
- gport->u_gc = WHICH_GC (gc);
- return 1;
+ 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;
+ double width, angle;
+ float deltax, deltay, length;
+ float wdx, wdy;
+ int slices;
+ int circular_caps = 0;
+ GLUquadricObj *qobj;
- dx1 = Vx ((double)x1);
- dy1 = Vy ((double)y1);
- dx2 = Vx ((double)x2);
- dy2 = Vy ((double)y2);
-
+#if 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;
+#endif
- USE_GC (gc);
- gdk_draw_line (gport->drawable, gport->u_gc, dx1, dy1, dx2, dy2);
+ dx1 = Vx (x1);
+ dy1 = Vy (y1);
+ dx2 = Vx (x2);
+ dy2 = Vy (y2);
+
+ width = Vz (gc->width);
+
+ if (width == 0.0)
+ width = 1.0;
+
+ deltax = dx2 - dx1;
+ deltay = dy2 - dy1;
+
+ length = sqrt (deltax * deltax + deltay * deltay);
+
+ wdy = deltax * width / 2 / length;
+ wdx = -deltay * width / 2 / length;
+
+ if (deltay == 0.)
+ angle = (deltax < 0) ? 270. : 90.;
+ else
+ angle = 180. / M_PI * atanl (deltax / deltay);
+
+ if (deltay < 0)
+ angle += 180.;
+
+ slices = M_PI * width / PIXELS_PER_CIRCLINE;
+
+ if (slices < 2)
+ slices = 2;
+
+ switch (gc->cap) {
+ case Trace_Cap:
+ case Round_Cap:
+ circular_caps = 1;
+ break;
+
+ case Square_Cap:
+ case Beveled_Cap:
+ dx1 -= deltax * width / 2 / length;
+ dy1 -= deltay * width / 2 / length;
+ dx2 += deltax * width / 2 / length;
+ dy2 += deltay * width / 2 / length;
+ break;
+ }
+
+ 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 (circular_caps) {
+ 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);
+ gluPartialDisk (qobj, 0, width / 2, slices, 1, angle + 90., 180);
+ glPopMatrix ();
+
+ glPushMatrix ();
+ glTranslatef (dx2, dy2, 0.0);
+ gluPartialDisk (qobj, 0, width / 2, slices, 1, angle + 270., 180);
+ glPopMatrix ();
+
+ gluDeleteQuadric (qobj);
+ }
}
void
ghid_draw_arc (hidGC gc, int cx, int cy,
- int xradius, int yradius, int start_angle, int delta_angle)
+ int xradius, int yradius, int start_angle, int delta_angle)
{
gint vrx, vry;
- gint w, h, radius;
-
+ gint w, h, radius, slices;
+ double width;
+ GLUquadricObj *qobj;
+
+ width = Vz (gc->width);
+
+ if (width == 0.0)
+ width = 1.0;
+
w = gport->width * gport->zoom;
h = gport->height * gport->zoom;
radius = (xradius > yradius) ? xradius : yradius;
@@ -901,12 +1023,11 @@ ghid_draw_arc (hidGC gc, int cx, int cy,
|| SIDE_Y (cy) < gport->view_y0 - radius
|| SIDE_Y (cy) > gport->view_y0 + h + radius)
return;
-
+
USE_GC (gc);
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)
@@ -917,12 +1038,48 @@ ghid_draw_arc (hidGC gc, int cx, int cy,
if (ghid_flip_y)
{
start_angle = - start_angle;
- delta_angle = - delta_angle;
+ 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);
+ if (delta_angle < 0) {
+ start_angle += delta_angle;
+ delta_angle = - delta_angle;
+ }
+
+ slices = M_PI * (vrx + width / 2.) / PIXELS_PER_CIRCLINE;
+
+ if (slices < 2)
+ slices = 2;
+
+ 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 (Vx (cx), Vy (cy), 0.0);
+ gluPartialDisk (qobj, vrx - width / 2, vrx + width / 2, slices, 1, 270 + start_angle, delta_angle);
+ glPopMatrix ();
+
+ slices = M_PI * width / PIXELS_PER_CIRCLINE;
+
+ if (slices < 2)
+ slices = 2;
+
+ glPushMatrix ();
+ glTranslatef (Vx (cx) + vrx * -cos (M_PI / 180. * start_angle),
+ Vy (cy) + vrx * sin (M_PI / 180. * start_angle), 0.0);
+ gluPartialDisk (qobj, 0, width / 2, slices, 1, start_angle + 90., 180);
+ glPopMatrix ();
+
+ glPushMatrix ();
+ glTranslatef (Vx (cx) + vrx * -cos (M_PI / 180. * (start_angle + delta_angle)),
+ Vy (cy) + vrx * sin (M_PI / 180. * (start_angle + delta_angle)), 0.0);
+ gluPartialDisk (qobj, 0, width / 2, slices, 1, start_angle + delta_angle + 270., 180);
+ glPopMatrix ();
+
+ gluDeleteQuadric (qobj);
}
void
@@ -949,20 +1106,23 @@ ghid_draw_rect (hidGC gc, int x1, int y1
x2 = Vx (x2);
y2 = Vy (y2);
- if (x1 > x2) { gint xt = x1; x1 = x2; x2 = xt; }
- 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);
+
+ glBegin (GL_LINE_LOOP);
+ glNormal3f (0.0f, 0.0f, 1.0f);
+ glVertex3f (x1, y1, 0.0f);
+ glVertex3f (x1, y2, 0.0f);
+ glVertex3f (x2, y2, 0.0f);
+ glVertex3f (x2, y1, 0.0f);
+ glEnd ();
}
void
ghid_fill_circle (hidGC gc, int cx, int cy, int radius)
{
- gint w, h, vr;
-
+ gint w, h, vr, slices;
+ GLUquadricObj *qobj;
w = gport->width * gport->zoom;
h = gport->height * gport->zoom;
if (SIDE_X (cx) < gport->view_x0 - radius
@@ -973,37 +1133,98 @@ 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);
+
+ slices = M_PI * 2 * radius / PIXELS_PER_CIRCLINE;
+
+ if (slices < 2)
+ slices = 2;
+
+ 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 (Vx(cx), Vy(cy), 0.0);
+ gluDisk (qobj, 0, vr, slices, 1);
+ glPopMatrix ();
+
+ gluDeleteQuadric (qobj);
+}
+
+void
+myError (GLenum errno)
+{
+ printf ("gluTess error: %s\n", gluErrorString (errno));
+}
+
+/* TODO: Structure for storing pointers for combined memory,
+ * so we can free it.
+ */
+
+void
+myFreeCombined ()
+{
+
+}
+
+void
+myCombine ( GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **dataOut )
+{
+ GLdouble *new_vertex;
+
+ new_vertex = malloc (3 * sizeof (GLdouble));
+ new_vertex[0] = coords[0];
+ new_vertex[1] = coords[1];
+ new_vertex[2] = coords[2];
+
+ *dataOut = new_vertex;
}
void
ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
{
- static GdkPoint *points = 0;
- static int npoints = 0;
int i;
+ GLUtesselator *tobj;
+ GLdouble *vertices;
+
USE_GC (gc);
- if (npoints < n_coords)
- {
- npoints = n_coords + 1;
- points = MyRealloc (points,
- npoints * sizeof (GdkPoint), (char *) __FUNCTION__);
- }
+ g_assert (n_coords > 0);
+
+ vertices = malloc (sizeof(GLdouble) * n_coords * 3);
+
+ tobj = gluNewTess ();
+ gluTessCallback(tobj, GLU_TESS_BEGIN, glBegin);
+ gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv);
+ gluTessCallback(tobj, GLU_TESS_END, glEnd);
+ gluTessCallback(tobj, GLU_TESS_COMBINE, myCombine);
+ gluTessCallback(tobj, GLU_TESS_ERROR, myError);
+
+ gluTessBeginPolygon (tobj, NULL);
+ gluTessBeginContour (tobj);
+
for (i = 0; i < n_coords; i++)
{
- points[i].x = Vx (x[i]);
- points[i].y = Vy (y[i]);
+ vertices [0 + i * 3] = Vx (x[i]);
+ vertices [1 + i * 3] = Vy (y[i]);
+ vertices [2 + i * 3] = 0.;
+ gluTessVertex (tobj, &vertices [i * 3], &vertices [i * 3]);
}
- gdk_draw_polygon (gport->drawable, gport->u_gc, 1, points, n_coords);
+
+ gluTessEndContour (tobj);
+ gluTessEndPolygon (tobj);
+ gluDeleteTess (tobj);
+
+ myFreeCombined ();
+ free (vertices);
}
void
ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
{
- gint w, h, lw, xx, yy;
+ gint w, h, lw;
lw = gc->width;
w = gport->width * gport->zoom;
@@ -1023,21 +1244,15 @@ ghid_fill_rect (hidGC gc, int x1, int y1
y1 = Vy (y1);
x2 = Vx (x2);
y2 = Vy (y2);
- if (x2 < x1)
- {
- xx = x1;
- x1 = x2;
- x2 = xx;
- }
- if (y2 < y1)
- {
- yy = y1;
- y1 = y2;
- y2 = yy;
- }
+
USE_GC (gc);
- gdk_draw_rectangle (gport->drawable, gport->u_gc, TRUE,
- x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ glBegin (GL_QUADS);
+ glNormal3f (0.0f, 0.0f, 1.0f);
+ glVertex3f (x1, y1, 0.0f);
+ glVertex3f (x1, y2, 0.0f);
+ glVertex3f (x2, y2, 0.0f);
+ glVertex3f (x2, y1, 0.0f);
+ glEnd ();
}
void
@@ -1527,7 +1742,7 @@ HID ghid_hid = {
1, /* gui */
0, /* printer */
0, /* exporter */
- 0, /* poly before */
+ 1, /* poly before */
1, /* poly after */
0, /* poly dicer */
@@ -2160,11 +2375,14 @@ Benchmark (int argc, char **argv, int x,
region.X2 = PCB->MaxWidth;
region.Y2 = PCB->MaxHeight;
+
+
gdk_display_sync (display);
time (&start);
do
{
- hid_expose_callback (&ghid_hid, ®ion, 0);
+ gdk_window_invalidate_rect (gport->drawing_area->window, NULL, 1);
+ gdk_window_process_updates (gport->drawing_area->window, FALSE);
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 15 Jun 2008 21:36:48 -0000
@@ -300,63 +300,103 @@ ghid_show_crosshair (gboolean show)
static GdkGC *xor_gc;
static GdkColor cross_color;
- if (gport->x_crosshair < 0 || ghidgui->creating || !gport->has_entered)
+ if (gport->x_crosshair < 0 || ghidgui->creating) {// || !gport->has_entered) {
+ printf ("Returning\n");
return;
+ }
if (!xor_gc)
{
- xor_gc = gdk_gc_new (ghid_port.drawing_area->window);
- gdk_gc_copy (xor_gc, ghid_port.drawing_area->style->white_gc);
- gdk_gc_set_function (xor_gc, GDK_XOR);
+ xor_gc = (GdkGC *)1;
/* FIXME: when CrossColor changed from config */
ghid_map_color_string (Settings.CrossColor, &cross_color);
}
x = DRAW_X (gport->x_crosshair);
y = DRAW_Y (gport->y_crosshair);
- gdk_gc_set_foreground (xor_gc, &cross_color);
+ glEnable (GL_COLOR_LOGIC_OP);
+ glLogicOp (GL_XOR);
+
+ glColor3f (cross_color.red / 65535.,
+ cross_color.green / 65535.,
+ cross_color.blue / 65535.);
+
+ glBegin (GL_LINES);
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);
- 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);
- }
+ glVertex2i (x_prev, 0);
+ glVertex2i (x_prev, gport->height);
+ glVertex2i (0, y_prev);
+ glVertex2i (gport->width, y_prev);
+ }
+
+ if (x >= 0 && show)
+ {
+ glVertex2i (x, 0);
+ glVertex2i (x, gport->height);
+ glVertex2i (0, y);
+ glVertex2i (gport->width, y);
+ }
+
+ glEnd ();
+
+ if (ghidgui->auto_pan_on && have_crosshair_attachments ())
+ {
+ glBegin (GL_QUADS);
+
+ if (x_prev >= 0)
+ {
+ glVertex2i (0, y_prev - VCD);
+ glVertex2i (0, y_prev - VCD + VCW);
+ glVertex2i (VCD, y_prev - VCD + VCW);
+ glVertex2i (VCD, y_prev - VCD);
+ glVertex2i (gport->width, y_prev - VCD);
+ glVertex2i (gport->width, y_prev - VCD + VCW);
+ glVertex2i (gport->width - VCD, y_prev - VCD + VCW);
+ glVertex2i (gport->width - VCD, y_prev - VCD);
+ glVertex2i (x_prev - VCD, 0);
+ glVertex2i (x_prev - VCD, VCD);
+ glVertex2i (x_prev - VCD + VCW, VCD);
+ glVertex2i (x_prev - VCD + VCW, 0);
+ glVertex2i (x_prev - VCD, gport->height - VCD);
+ glVertex2i (x_prev - VCD, gport->height);
+ glVertex2i (x_prev - VCD + VCW, gport->height);
+ glVertex2i (x_prev - VCD + VCW, gport->height - VCD);
+ }
+
+ if (x >= 0 && show)
+ {
+ glVertex2i (0, y - VCD);
+ glVertex2i (0, y - VCD + VCW);
+ glVertex2i (VCD, y - VCD + VCW);
+ glVertex2i (VCD, y - VCD);
+ glVertex2i (gport->width, y - VCD);
+ glVertex2i (gport->width, y - VCD + VCW);
+ glVertex2i (gport->width - VCD, y - VCD + VCW);
+ glVertex2i (gport->width - VCD, y - VCD);
+ glVertex2i (x - VCD, 0);
+ glVertex2i (x - VCD, VCD);
+ glVertex2i (x - VCD + VCW, VCD);
+ glVertex2i (x - VCD + VCW, 0);
+ glVertex2i (x - VCD, gport->height - VCD);
+ glVertex2i (x - VCD, gport->height);
+ glVertex2i (x - VCD + VCW, gport->height);
+ glVertex2i (x - VCD + VCW, gport->height - VCD);
+ }
+
+ glEnd ();
}
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);
- 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);
- }
x_prev = x;
y_prev = y;
}
else
x_prev = y_prev = -1;
+
+ glDisable (GL_COLOR_LOGIC_OP);
}
static gboolean
@@ -746,37 +786,127 @@ ghid_port_drawing_area_configure_event_c
first_time_done = TRUE;
PCBChanged (0, NULL, 0, 0);
}
- if (gport->mask)
- {
- gdk_pixmap_unref (gport->mask);
- gport->mask = gdk_pixmap_new (0, gport->width, gport->height, 1);
- }
+// if (gport->mask)
+// {
+// gdk_pixmap_unref (gport->mask);
+// gport->mask = gdk_pixmap_new (0, gport->width, gport->height, 1);
+// }
ghid_port_ranges_scale (FALSE);
ghid_invalidate_all ();
RestoreCrosshair (TRUE);
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;
+ GdkGLContext* pGlContext = gtk_widget_get_gl_context (widget);
+ GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (widget);
+
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)) {
+ return FALSE;
+ }
+
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport (0, 0, ev->area.width, ev->area.height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, ev->area.width, ev->area.height, 0, 0, 100);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ glClearColor (gport->bg_color.red / 65535.,
+ gport->bg_color.green / 65535.,
+ gport->bg_color.blue / 65535.,
+ 1.);
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);// | GL_DEPTH_BUFFER_BIT);
+
+ 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));
+
+ hid_expose_callback (&ghid_hid, ®ion, 0);
+
+ draw_grid ();
+ DrawAttached (TRUE);
ghid_show_crosshair (TRUE);
+
+ if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
+ gdk_gl_drawable_swap_buffers (pGlDrawable);
+ else
+ glFlush ();
+
+ /* end drawing to current GL-context */
+ gdk_gl_drawable_gl_end (pGlDrawable);
+
return FALSE;
}
@@ -789,6 +919,13 @@ ghid_port_window_motion_cb (GtkWidget *
static gint x_prev = -1, y_prev = -1;
gboolean moved;
GdkModifierType state;
+ GdkGLContext* pGlContext = gtk_widget_get_gl_context (widget);
+ GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (widget);
+
+ /* make GL-context "current" */
+ if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext)) {
+ return FALSE;
+ }
state = (GdkModifierType) (ev->state);
mk = ghid_modifier_keys_state (&state);
@@ -808,9 +945,18 @@ ghid_port_window_motion_cb (GtkWidget *
}
x_prev = y_prev = -1;
moved = ghid_note_event_location (ev);
+
ghid_show_crosshair (TRUE);
if (moved && have_crosshair_attachments ())
ghid_draw_area_update (gport, NULL);
+
+ if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
+ gdk_gl_drawable_swap_buffers (pGlDrawable);
+ else
+ glFlush ();
+
+ /* end drawing to current GL-context */
+ gdk_gl_drawable_gl_end (pGlDrawable);
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 15 Jun 2008 21:36:51 -0000
@@ -2295,6 +2295,11 @@ ghid_build_pcb_top_window (void)
gtk_box_pack_start (GTK_BOX (hbox), viewport, TRUE, TRUE, 0);
gport->drawing_area = gtk_drawing_area_new ();
+ gtk_widget_set_gl_capability (gport->drawing_area,
+ gport->glconfig,
+ NULL,
+ TRUE,
+ GDK_GL_RGBA_TYPE);
gtk_widget_add_events (gport->drawing_area, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK
@@ -2657,11 +2662,23 @@ ghid_parse_arguments (int *argc, char **
gtk_disable_setlocale ();
gtk_init (argc, argv);
+ gtk_gl_init(argc, argv);
gport = &ghid_port;
gport->zoom = 300.0;
pixel_slop = 300;
+ /* setup GL-context */
+ gport->glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
+ GDK_GL_MODE_ALPHA |
+ GDK_GL_MODE_STENCIL |
+// GDK_GL_MODE_DEPTH |
+ GDK_GL_MODE_DOUBLE);
+ if (!gport->glconfig) {
+ printf("Could not setup GL-context!\n");
+ return; /* Should we abort? */
+ }
+
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 15 Jun 2008 21:36:52 -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)
@@ -197,6 +201,10 @@ typedef struct
GdkDrawable *drawable; /* Current drawable for drawing routines */
gint width, height;
+ GdkGLConfig *glconfig;
+
+ 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