~ubuntu-branches/ubuntu/precise/pcb/precise

« back to all changes in this revision

Viewing changes to src/draw.c

  • Committer: Bazaar Package Importer
  • Author(s): Hamish Moffatt
  • Date: 2005-02-20 13:14:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050220131400-pfz66g5vhx0azl8f
Tags: 1.99j+20050127-2
* Improved package description: (closes: #295405)
* Fixed dependency: tk84 -> tk8.4 (closes: #295404)
* Updated README.debian (closes: #269578)
* Applied patch to src/djopt.c to allow compilation with gcc-4.0
  (closes: #294319), thanks to Andreas Jochens for the patch.
* Prevent example files from being compressed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: draw.c,v 1.41 2005/01/03 12:56:59 danmc Exp $ */
 
2
 
1
3
/*
2
4
 *                            COPYRIGHT
3
5
 *
4
6
 *  PCB, interactive printed circuit board design
5
 
 *  Copyright (C) 1994,1995,1996 Thomas Nau
 
7
 *  Copyright (C) 1994,1995,1996, 2003, 2004 Thomas Nau
6
8
 *
7
9
 *  This program is free software; you can redistribute it and/or modify
8
10
 *  it under the terms of the GNU General Public License as published by
24
26
 *
25
27
 */
26
28
 
27
 
static  char    *rcsid = "$Id: draw.c,v 1.6.1.1 1998/03/01 22:58:33 cad Exp $";
28
29
 
29
30
/* drawing routines
30
31
 */
32
33
/* ---------------------------------------------------------------------------
33
34
 * define TO_SCREEN before macro.h is included from global.h
34
35
 */
35
 
#define SWAP_IDENT              SwapOutput
36
 
#define TO_SCREEN(a)    ((ZoomValue < 0) ? (a) << -ZoomValue : (a) >> ZoomValue)
37
 
#define XORIG dxo
38
 
#define YORIG dyo
39
 
 
 
36
#define TO_SCREEN(c)  ((Position)((c)*Local_Zoom)) 
 
37
 
 
38
#ifdef HAVE_CONFIG_H
 
39
#include "config.h"
 
40
#endif
 
41
 
 
42
#include <ctype.h>
 
43
#include <math.h>
40
44
#include "global.h"
41
 
 
 
45
#include "clip.h"
 
46
#include "compat.h"
42
47
#include "crosshair.h"
43
48
#include "data.h"
44
49
#include "draw.h"
45
50
#include "error.h"
46
51
#include "mymem.h"
47
52
#include "misc.h"
 
53
#include "polygon.h"
48
54
#include "rotate.h"
 
55
#include "rtree.h"
49
56
#include "search.h"
50
57
#include "select.h"
51
58
 
 
59
#ifdef HAVE_LIBDMALLOC
 
60
#include <dmalloc.h>
 
61
#endif
 
62
 
 
63
RCSID("$Id: draw.c,v 1.41 2005/01/03 12:56:59 danmc Exp $");
 
64
 
52
65
/* ---------------------------------------------------------------------------
53
66
 * some local types
54
67
 */
55
68
typedef struct
56
69
{
57
 
        float   X,
58
 
                Y;
59
 
} FloatPolyType, *FloatPolyTypePtr;
 
70
  float X, Y;
 
71
}
 
72
FloatPolyType, *FloatPolyTypePtr;
60
73
 
61
74
/* ---------------------------------------------------------------------------
62
75
 * some local identifiers
63
76
 */
64
 
static  int             ZoomValue;      /* zoom, drawable and mirror */
65
 
static  Window          DrawingWindow;  /* flag common to all */
66
 
static  Boolean         SwapOutput;     /* all drawing routines */
67
 
static  XPoint          Outline[MAX_SIZE+1][8];
68
 
static  XRectangle      UpdateRect;
69
 
static  BoxType         Block;
70
 
static  Boolean         Gathering = True;
71
 
static  int             Erasing = False;
72
 
static  Position        dxo, dyo;
 
77
static int ZoomValue;           /* zoom for pin fonts */
 
78
static Window DrawingWindow;    /* flag common to all */
 
79
static BoxType Block;
 
80
static Boolean Gathering = True;
 
81
static int Erasing = False;
73
82
 
74
83
 
75
84
/* ---------------------------------------------------------------------------
76
85
 * some local prototypes
77
86
 */
78
 
static  void    Redraw(Boolean);
79
 
static  void    DrawEverything(void);
80
 
static  void    DrawTop(void);
81
 
static  void    DrawLayer(LayerTypePtr, int);
82
 
static  void    InitSpecialPolygon(void);
83
 
static  void    DrawSpecialPolygon(Drawable, GC, Position, Position, XPoint *);
84
 
static  void    DrawPinOrViaLowLevel(PinTypePtr, Boolean);
85
 
static  void    ClearOnlyPin(PinTypePtr);
86
 
static  void    ThermPin(LayerTypePtr, PinTypePtr);
87
 
static  void    DrawPlainPin(PinTypePtr, int);
88
 
static  void    DrawPlainVia(PinTypePtr, int);
89
 
static  void    DrawPlainElementPinsAndPads(ElementTypePtr, int);
90
 
static  void    DrawPinOrViaNameLowLevel(PinTypePtr);
91
 
static  void    DrawPadLowLevel(PadTypePtr);
92
 
static  void    DrawPadNameLowLevel(PadTypePtr);
93
 
static  void    DrawLineLowLevel(LineTypePtr, Boolean);
94
 
static  void    DrawTextLowLevel(TextTypePtr);
95
 
static  void    DrawRegularText(LayerTypePtr, TextTypePtr, int);
96
 
static  void    DrawPolygonLowLevel(PolygonTypePtr, Boolean);
97
 
static  void    DrawArcLowLevel(ArcTypePtr);
98
 
static  void    DrawElementPackageLowLevel(ElementTypePtr Element, int);
99
 
static  void    DrawPlainPolygon(LayerTypePtr Layer, PolygonTypePtr Polygon);
100
 
static  void    AddPart(void);
101
 
static  void    SetPVColor(PinTypePtr, int);
102
 
static  void    DrawGrid(void);
103
 
static  void    DrawEMark(Position, Position, Boolean); 
104
 
static  void    ClearLine(LineTypePtr);
105
 
static  void    ClearArc(ArcTypePtr);
106
 
static  void    ClearPad(PadTypePtr);
107
 
static  void    DrawHole(PinTypePtr);
 
87
static void Redraw (Boolean, BoxTypePtr);
 
88
static void DrawEverything (BoxTypePtr);
 
89
static void DrawTop (BoxType *);
 
90
static void DrawLayer (LayerTypePtr, BoxType *);
 
91
static void DrawSpecialPolygon (Drawable, GC, LocationType, LocationType, BDimension);
 
92
static void DrawPinOrViaLowLevel (PinTypePtr, Boolean);
 
93
static void ClearOnlyPin (PinTypePtr, Boolean);
 
94
static void ThermPin (LayerTypePtr, PinTypePtr);
 
95
static void DrawPlainPin (PinTypePtr, Boolean);
 
96
static void DrawPlainVia (PinTypePtr, Boolean);
 
97
static void DrawPinOrViaNameLowLevel (PinTypePtr);
 
98
static void DrawPadLowLevel (PadTypePtr);
 
99
static void DrawPadNameLowLevel (PadTypePtr);
 
100
static void DrawLineLowLevel (LineTypePtr, Boolean);
 
101
static void DrawTextLowLevel (TextTypePtr);
 
102
static void DrawRegularText (LayerTypePtr, TextTypePtr, int);
 
103
static void DrawPolygonLowLevel (PolygonTypePtr);
 
104
static void DrawArcLowLevel (ArcTypePtr);
 
105
static void DrawElementPackageLowLevel (ElementTypePtr Element, int);
 
106
static void DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon);
 
107
static void AddPart (void *, Boolean);
 
108
static void SetPVColor (PinTypePtr, int);
 
109
static void DrawGrid (void);
 
110
static void DrawEMark (LocationType, LocationType, Boolean);
 
111
static void ClearLine (LineTypePtr);
 
112
static void ClearArc (ArcTypePtr);
 
113
static void ClearPad (PadTypePtr, Boolean);
 
114
static void DrawHole (PinTypePtr);
 
115
static void DrawMask (BoxType *);
108
116
 
109
117
/*--------------------------------------------------------------------------------------
110
118
 * setup color for pin or via
111
119
 */
112
 
static  void    SetPVColor(PinTypePtr Pin, int Type)
 
120
static void
 
121
SetPVColor (PinTypePtr Pin, int Type)
113
122
{
114
 
        if (Type == VIA_TYPE)
115
 
        {
116
 
                if (TEST_FLAG(WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pin))
117
 
                        {
118
 
                                if (TEST_FLAG(WARNFLAG, Pin))
119
 
                                        XSetForeground(Dpy, Output.fgGC, PCB->WarnColor);
120
 
                                else if (TEST_FLAG(SELECTEDFLAG, Pin))
121
 
                                        XSetForeground(Dpy, Output.fgGC, PCB->ViaSelectedColor);
122
 
                                else
123
 
                                        XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
124
 
                        }
125
 
                        else
126
 
                                XSetForeground(Dpy, Output.fgGC, PCB->ViaColor);
127
 
        }
128
 
        else
129
 
        {
130
 
                if (TEST_FLAG(WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pin))
131
 
                {
132
 
                        if (TEST_FLAG(WARNFLAG, Pin))
133
 
                                XSetForeground(Dpy, Output.fgGC, PCB->WarnColor);
134
 
                        else if (TEST_FLAG(SELECTEDFLAG, Pin))
135
 
                                XSetForeground(Dpy, Output.fgGC, PCB->PinSelectedColor);
136
 
                        else
137
 
                                XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
138
 
                }
139
 
                else
140
 
                        XSetForeground(Dpy, Output.fgGC, PCB->PinColor);
141
 
        }
 
123
  if (Type == VIA_TYPE)
 
124
    {
 
125
      if (TEST_FLAG (WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pin))
 
126
        {
 
127
          if (TEST_FLAG (WARNFLAG, Pin))
 
128
            XSetForeground (Dpy, Output.fgGC, PCB->WarnColor);
 
129
          else if (TEST_FLAG (SELECTEDFLAG, Pin))
 
130
            XSetForeground (Dpy, Output.fgGC, PCB->ViaSelectedColor);
 
131
          else
 
132
            XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
 
133
        }
 
134
      else
 
135
        XSetForeground (Dpy, Output.fgGC, PCB->ViaColor);
 
136
    }
 
137
  else
 
138
    {
 
139
      if (TEST_FLAG (WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pin))
 
140
        {
 
141
          if (TEST_FLAG (WARNFLAG, Pin))
 
142
            XSetForeground (Dpy, Output.fgGC, PCB->WarnColor);
 
143
          else if (TEST_FLAG (SELECTEDFLAG, Pin))
 
144
            XSetForeground (Dpy, Output.fgGC, PCB->PinSelectedColor);
 
145
          else
 
146
            XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
 
147
        }
 
148
      else
 
149
        XSetForeground (Dpy, Output.fgGC, PCB->PinColor);
 
150
    }
142
151
}
143
152
 
144
153
/*---------------------------------------------------------------------------
145
154
 *  Adds the update rect to the update region
146
155
 */
147
 
static void AddPart()
 
156
static void
 
157
AddPart (void *b, Boolean screen_coord)
148
158
{
149
 
        Block.X1 = MIN(Block.X1, UpdateRect.x);
150
 
        Block.X2 = MAX(Block.X2, UpdateRect.x + UpdateRect.width);
151
 
        Block.Y1 = MIN(Block.Y1, UpdateRect.y);
152
 
        Block.Y2 = MAX(Block.Y2, UpdateRect.y + UpdateRect.height);
 
159
  BoxType *box = (BoxType *) b;
 
160
 
 
161
  if (screen_coord)
 
162
    {
 
163
      Block.X1 = MIN (Block.X1, box->X1);
 
164
      Block.X2 = MAX (Block.X2, box->X2);
 
165
      Block.Y1 = MIN (Block.Y1, box->Y1);
 
166
      Block.Y2 = MAX (Block.Y2, box->Y2);
 
167
    }
 
168
  else
 
169
    {
 
170
      Block.X1 = MIN (Block.X1, TO_LIMIT_X (box->X1));
 
171
      Block.X2 = MAX (Block.X2, TO_LIMIT_X (box->X2));
 
172
      Block.Y1 =
 
173
        MIN (Block.Y1, MIN (TO_LIMIT_Y (box->Y1), TO_LIMIT_Y (box->Y2)));
 
174
      Block.Y2 =
 
175
        MAX (Block.Y2, MAX (TO_LIMIT_Y (box->Y2), TO_LIMIT_Y (box->Y1)));
 
176
    }
153
177
}
154
178
 
155
179
/*
156
180
 * force the whole output to be updated
157
181
 */
158
 
void UpdateAll(void)
 
182
void
 
183
UpdateAll (void)
159
184
{
160
 
        Block.X1 = 1;
161
 
        Block.Y1 = 1;
162
 
        Block.Y2 = MAX_COORD -1;
163
 
        Block.X2 = MAX_COORD -1;
164
 
        Draw();
 
185
  Block.X1 = 1;
 
186
  Block.Y1 = 1;
 
187
  Block.Y2 = MAX_COORD / 100 - 1;
 
188
  Block.X2 = MAX_COORD / 100 - 1;
 
189
  Draw ();
165
190
}
166
191
 
167
192
/*
169
194
 * make the update block slightly larger to handle round-off
170
195
 * caused by the TO_SCREEN operation
171
196
 */
172
 
void Draw(void)
 
197
void
 
198
Draw (void)
173
199
{
174
 
        static  XExposeEvent    erased;
 
200
  static XExposeEvent erased;
175
201
 
176
 
        render = True;
177
 
        if (VALID_PIXMAP(Offscreen))
178
 
        {
179
 
                XFillRectangle(Dpy, Offscreen, Output.bgGC, Block.X1 -1,
180
 
                        Block.Y1 -1, Block.X2 - Block.X1 + 2,
181
 
                        Block.Y2 - Block.Y1 + 2);
182
 
                        /* create an update event */
183
 
                erased.type = Expose;
184
 
                erased.display = Dpy;
185
 
                erased.window = Output.OutputWindow;
186
 
                erased.x = Block.X1 -1;
187
 
                erased.y = Block.Y1 -1;
188
 
                erased.width = Block.X2 - Block.X1 + 2;
189
 
                erased.height = Block.Y2 - Block.Y1 + 2;
190
 
                erased.count = 0;
191
 
                XSendEvent(Dpy, Output.OutputWindow, False, ExposureMask, (XEvent *) &erased);
192
 
        }
193
 
        else
194
 
        {
195
 
                HideCrosshair(True);
196
 
                        /* clear and create event if not drawing to a pixmap */
197
 
                XClearArea(Dpy, Output.OutputWindow, Block.X1 -1, Block.Y1 -1,
198
 
                        Block.X2 - Block.X1 + 2, Block.Y2 - Block.Y1 + 2, True);
199
 
                RestoreCrosshair(True);
200
 
        }
 
202
  render = True;
 
203
  if (VALID_PIXMAP (Offscreen))
 
204
    {
 
205
      /* create an update event */
 
206
      erased.type = Expose;
 
207
      erased.display = Dpy;
 
208
      erased.window = Output.OutputWindow;
 
209
      erased.x = SATURATE (Block.X1 - 1);
 
210
      erased.y = SATURATE (Block.Y1 - 1);
 
211
      erased.width = SATURATE (Block.X2 - Block.X1 + 2);
 
212
      erased.height = SATURATE (Block.Y2 - Block.Y1 + 2);
 
213
      erased.count = 0;
 
214
      XFillRectangle (Dpy, Offscreen, Output.bgGC, erased.x,
 
215
                      erased.y, erased.width, erased.height);
 
216
      XSendEvent (Dpy, Output.OutputWindow, False, ExposureMask,
 
217
                  (XEvent *) & erased);
 
218
    }
 
219
  else
 
220
    {
 
221
      HideCrosshair (True);
 
222
      /* clear and create event if not drawing to a pixmap */
 
223
      XClearArea (Dpy, Output.OutputWindow, SATURATE (Block.X1 - 1),
 
224
                  SATURATE (Block.Y1 - 1), SATURATE (Block.X2 - Block.X1 + 2),
 
225
                  SATURATE (Block.Y2 - Block.Y1 + 2), True);
 
226
      RestoreCrosshair (True);
 
227
    }
 
228
  /* shrink the update block */
 
229
  Block.X1 = MAX_COORD / 100;
 
230
  Block.Y1 = MAX_COORD / 100;
 
231
  Block.X2 = Block.Y2 = 0;
201
232
}
202
233
 
203
234
/* ---------------------------------------------------------------------------
204
235
 * redraws the output area without clearing it
205
236
 */
206
 
void RedrawOutput(void)
 
237
void
 
238
RedrawOutput (BoxTypePtr area)
207
239
{
208
 
        Redraw(False);
 
240
  Redraw (True, area);
209
241
}
210
242
 
211
243
/* ---------------------------------------------------------------------------
212
244
 * redraws the output area after clearing it
213
245
 */
214
 
void ClearAndRedrawOutput(void)
215
 
{
216
 
        render = True;
217
 
        Gathering = False;
218
 
/*
219
 
        Redraw(True);
220
 
*/
221
 
        UpdateAll();
 
246
void
 
247
ClearAndRedrawOutput (void)
 
248
{
 
249
  render = True;
 
250
  Gathering = False;
 
251
  UpdateAll ();
 
252
}
 
253
 
 
254
/* ---------------------------------------------------------------------- 
 
255
 * redraws the background image
 
256
 */
 
257
 
 
258
static int bg_w, bg_h, bgi_w, bgi_h;
 
259
static Pixel **bg = 0;
 
260
static XImage *bgi = 0;
 
261
static enum {
 
262
  PT_unknown,
 
263
  PT_RGB565
 
264
} pixel_type = PT_unknown;
 
265
 
 
266
static void
 
267
LoadBackgroundFile (FILE *f, char *filename)
 
268
{
 
269
  Display *display;
 
270
  Colormap cmap;
 
271
  XVisualInfo vinfot, *vinfo;
 
272
  Visual *vis;
 
273
  int c, r, b;
 
274
  int i, nret;
 
275
  int p[3], rows, cols, maxval;
 
276
 
 
277
  if (fgetc(f) != 'P')
 
278
    {
 
279
      printf("bgimage: %s signature not P6\n", filename);
 
280
      return;
 
281
    }
 
282
  if (fgetc(f) != '6')
 
283
    {
 
284
      printf("bgimage: %s signature not P6\n", filename);
 
285
      return;
 
286
    }
 
287
  for (i=0; i<3; i++)
 
288
    {
 
289
      do {
 
290
        b = fgetc(f);
 
291
        if (feof(f))
 
292
          return;
 
293
        if (b == '#')
 
294
          while (!feof(f) && b != '\n')
 
295
            b = fgetc(f);
 
296
      } while (!isdigit(b));
 
297
      p[i] = b - '0';
 
298
      while (isdigit(b = fgetc(f)))
 
299
        p[i] = p[i]*10 + b - '0';
 
300
    }
 
301
  bg_w = cols = p[0];
 
302
  bg_h = rows = p[1];
 
303
  maxval = p[2];
 
304
 
 
305
  setbuf(stdout, 0);
 
306
  bg = (Pixel **) malloc (rows * sizeof (Pixel *));
 
307
  if (!bg)
 
308
    {
 
309
      printf("Out of memory loading %s\n", filename);
 
310
      return;
 
311
    }
 
312
  for (i=0; i<rows; i++)
 
313
    {
 
314
      bg[i] = (Pixel *) malloc (cols * sizeof (Pixel));
 
315
      if (!bg[i])
 
316
        {
 
317
          printf("Out of memory loading %s\n", filename);
 
318
          while (--i >= 0)
 
319
            free (bg[i]);
 
320
          free (bg);
 
321
          bg = 0;
 
322
          return;
 
323
        }
 
324
    }
 
325
 
 
326
  display = XtDisplay (Output.Toplevel);
 
327
  cmap = DefaultColormap (display, DefaultScreen(display));
 
328
  vis = DefaultVisual (display, DefaultScreen(display));
 
329
 
 
330
  vinfot.visualid = XVisualIDFromVisual(vis);
 
331
  vinfo = XGetVisualInfo (display, VisualIDMask, &vinfot, &nret);
 
332
 
 
333
#if 0
 
334
  /* If you want to support more visuals below, you'll probably need
 
335
     this. */
 
336
  printf("vinfo: rm %04x gm %04x bm %04x depth %d class %d\n",
 
337
         vinfo->red_mask, vinfo->green_mask, vinfo->blue_mask,
 
338
         vinfo->depth, vinfo->class);
 
339
#endif
 
340
 
 
341
  if (vinfo->class == TrueColor
 
342
      && vinfo->depth == 16
 
343
      && vinfo->red_mask == 0xf800
 
344
      && vinfo->green_mask == 0x07e0
 
345
      && vinfo->blue_mask == 0x001f)
 
346
    pixel_type = PT_RGB565;
 
347
 
 
348
  for (r=0; r<rows; r++)
 
349
    {
 
350
      for (c=0; c<cols; c++)
 
351
        {
 
352
          XColor pix;
 
353
          unsigned int pr = (unsigned)fgetc(f);
 
354
          unsigned int pg = (unsigned)fgetc(f);
 
355
          unsigned int pb = (unsigned)fgetc(f);
 
356
 
 
357
          switch (pixel_type)
 
358
            {
 
359
            case PT_unknown:
 
360
              pix.red = pr * 65535 / maxval;
 
361
              pix.green = pg * 65535 / maxval;
 
362
              pix.blue = pb * 65535 / maxval;
 
363
              pix.flags = DoRed | DoGreen | DoBlue;
 
364
              XAllocColor (display, cmap, &pix);
 
365
              bg[r][c] = pix.pixel;
 
366
              break;
 
367
            case PT_RGB565:
 
368
              bg[r][c] = (pr>>3)<<11 | (pg>>2)<<5 | (pb>>3);
 
369
              break;
 
370
            }
 
371
        }
 
372
    }
 
373
}
 
374
 
 
375
void
 
376
LoadBackgroundImage (char *filename)
 
377
{
 
378
  FILE *f = fopen(filename, "rb");
 
379
  if (!f)
 
380
    {
 
381
      if (NSTRCMP (filename, "pcb-background.ppm"))
 
382
        perror(filename);
 
383
      return;
 
384
    }
 
385
  LoadBackgroundFile (f, filename);
 
386
  fclose(f);
 
387
}
 
388
 
 
389
static void
 
390
DrawBackgroundImage ()
 
391
{
 
392
  int x, y, w, h;
 
393
  double xscale, yscale;
 
394
  int pcbwidth = TO_DRAWABS_X (PCB->MaxWidth);
 
395
  int pcbheight = TO_DRAWABS_Y (PCB->MaxHeight);
 
396
 
 
397
  if (!DrawingWindow || !bg)
 
398
    return;
 
399
 
 
400
  if (!bgi || Output.Width != bgi_w || Output.Height != bgi_h)
 
401
    {
 
402
      if (bgi)
 
403
        XDestroyImage (bgi);
 
404
      /* Cheat - get the image, which sets up the format too.  */
 
405
      bgi = XGetImage (XtDisplay(Output.Toplevel),
 
406
                       DrawingWindow,
 
407
                       0, 0, Output.Width, Output.Height,
 
408
                       -1, ZPixmap);
 
409
      bgi_w = Output.Width;
 
410
      bgi_h = Output.Height;
 
411
    }
 
412
 
 
413
  w = MIN (Output.Width, pcbwidth);
 
414
  h = MIN (Output.Height, pcbheight);
 
415
 
 
416
  xscale = (double)bg_w / PCB->MaxWidth;
 
417
  yscale = (double)bg_h / PCB->MaxHeight;
 
418
 
 
419
  for (y=0; y<h; y++)
 
420
    {
 
421
      int pr = TO_PCB_Y(y);
 
422
      int ir = pr * yscale;
 
423
      for (x=0; x<w; x++)
 
424
        {
 
425
          int pc = TO_PCB_X(x);
 
426
          int ic = pc * xscale;
 
427
          XPutPixel (bgi, x, y, bg[ir][ic]);
 
428
        }
 
429
    }
 
430
  XPutImage(XtDisplay(Output.Toplevel), DrawingWindow, Output.fgGC,
 
431
            bgi,
 
432
            0, 0, 0, 0, w, h);
222
433
}
223
434
 
224
435
/* ---------------------------------------------------------------------- 
226
437
 * all necessary sizes are already set by the porthole widget and
227
438
 * by the event handlers
228
439
 */
229
 
static void Redraw(Boolean ClearWindow)
 
440
static void
 
441
Redraw (Boolean ClearWindow, BoxTypePtr screen_area)
230
442
{
231
 
                /* make sure window exists */
232
 
        if (Output.OutputWindow && (render || ClearWindow || !VALID_PIXMAP(Offscreen)))
233
 
        {
234
 
                        /* shrink the update block */
235
 
                Block.X1 = TO_SCREEN(PCB->MaxWidth);
236
 
                Block.Y1 = TO_SCREEN(PCB->MaxHeight);
237
 
                Block.X2 = Block.Y2 = 0;
238
 
 
239
 
                        /* switch off crosshair, set up drawing window and redraw
240
 
                         * everything with Gather = False
241
 
                         */
242
 
                HideCrosshair(True);
243
 
                SwitchDrawingWindow(PCB->Zoom,
244
 
                        VALID_PIXMAP(Offscreen) ? Offscreen : Output.OutputWindow,
245
 
                        Settings.ShowSolderSide, False);
246
 
 
247
 
                        /* clear the background
248
 
                         * of the drawing area
249
 
                         */
250
 
                XFillRectangle(Dpy, DrawingWindow, Output.bgGC, 0, 0,
251
 
                        TO_DRAWABS_X(PCB->MaxWidth),
252
 
                        TO_DRAWABS_Y(PCB->MaxHeight));
253
 
                XSetForeground(Dpy, Output.fgGC, Settings.OffLimitColor);
254
 
                XFillRectangle(Dpy, DrawingWindow, Output.fgGC,
255
 
                        TO_DRAWABS_X(PCB->MaxWidth), 0, MAX_COORD, MAX_COORD);
256
 
                XFillRectangle(Dpy, DrawingWindow, Output.fgGC,
257
 
                        0, TO_DRAWABS_Y(PCB->MaxHeight), MAX_COORD, MAX_COORD);
258
 
                if (ClearWindow)
259
 
                        Crosshair.On = False;
260
 
 
261
 
                DrawEverything();
262
 
 
263
 
                RestoreCrosshair(True);
264
 
        }
265
 
        Gathering = True;
266
 
        render = False;
 
443
  BoxType draw_area;
 
444
  Dimension pcbwidth, pcbheight;
 
445
 
 
446
  /* make sure window exists */
 
447
  if (Output.OutputWindow
 
448
      && (render || ClearWindow || !VALID_PIXMAP (Offscreen)))
 
449
    {
 
450
      /* shrink the update block */
 
451
      Block.X1 = MAX_COORD / 100;
 
452
      Block.Y1 = MAX_COORD / 100;
 
453
      Block.X2 = Block.Y2 = 0;
 
454
 
 
455
      /* switch off crosshair if needed,
 
456
       * set up drawing window and redraw
 
457
       * everything with Gather = False
 
458
       */
 
459
      if (!VALID_PIXMAP (Offscreen))
 
460
        HideCrosshair (True);
 
461
      SwitchDrawingWindow (PCB->Zoom,
 
462
                           VALID_PIXMAP (Offscreen) ? Offscreen :
 
463
                           Output.OutputWindow, Settings.ShowSolderSide,
 
464
                           False);
 
465
      draw_area.X1 = TO_PCB_X (screen_area->X1);
 
466
      draw_area.X2 = TO_PCB_X (screen_area->X2);
 
467
      draw_area.Y1 =
 
468
        MIN (TO_PCB_Y (screen_area->Y1), TO_PCB_Y (screen_area->Y2));
 
469
      draw_area.Y2 =
 
470
        MAX (TO_PCB_Y (screen_area->Y1), TO_PCB_Y (screen_area->Y2));
 
471
 
 
472
      /* clear the background
 
473
       * of the drawing area
 
474
       */
 
475
      pcbwidth = TO_DRAWABS_X (PCB->MaxWidth);
 
476
      pcbheight = TO_DRAWABS_Y (PCB->MaxHeight);
 
477
      XFillRectangle (Dpy, DrawingWindow, Output.bgGC, 0, 0,
 
478
                      MIN (pcbwidth, Output.Width),
 
479
                      MIN (pcbheight, Output.Height));
 
480
      XSetForeground (Dpy, Output.fgGC, Settings.OffLimitColor);
 
481
      if (pcbwidth < Output.Width)
 
482
        XFillRectangle (Dpy, DrawingWindow, Output.fgGC,
 
483
                        pcbwidth, 0, Output.Width - pcbwidth, Output.Height);
 
484
      if (pcbheight < Output.Height)
 
485
        XFillRectangle (Dpy, DrawingWindow, Output.fgGC, 0,
 
486
                        pcbheight, Output.Width, Output.Height - pcbheight);
 
487
      if (ClearWindow && !VALID_PIXMAP (Offscreen))
 
488
        Crosshair.On = False;
 
489
 
 
490
      DrawBackgroundImage ();
 
491
      DrawEverything (&draw_area);
 
492
 
 
493
      if (!VALID_PIXMAP (Offscreen))
 
494
        RestoreCrosshair (True);
 
495
    }
 
496
  Gathering = True;
 
497
  render = False;
267
498
}
268
499
 
269
500
/* ----------------------------------------------------------------------
270
501
 * setup of zoom and output window for the next drawing operations
271
502
 */
272
 
Boolean SwitchDrawingWindow(int Zoom, Window OutputWindow, Boolean Swap, Boolean Gather)
273
 
{
274
 
        Boolean oldGather = Gathering;
275
 
 
276
 
        Gathering = Gather;
277
 
        ZoomValue = Zoom;
278
 
        DrawingWindow = OutputWindow;
279
 
        if (OutputWindow == Offscreen || OutputWindow == Output.OutputWindow)
280
 
        {
281
 
                dxo = Xorig;
282
 
                dyo = Yorig;
283
 
        }
284
 
        else
285
 
        {
286
 
                dxo = 0;
287
 
                dyo = 0;
288
 
        }
289
 
        SwapOutput = Swap;
290
 
        if (Zoom < 0)
291
 
                Zoom = 0;
292
 
        if (Zoom > 4)
293
 
                Zoom = 4;
294
 
        XSetFont(Dpy, Output.fgGC, Settings.PinoutFont[Zoom]->fid);
295
 
        XSetFont(Dpy, Output.bgGC, Settings.PinoutFont[Zoom]->fid);
296
 
        InitSpecialPolygon();
297
 
        return(oldGather);
 
503
Boolean
 
504
SwitchDrawingWindow (float Zoom, Window OutputWindow, Boolean Swap,
 
505
                     Boolean Gather)
 
506
{
 
507
  Boolean oldGather = Gathering;
 
508
 
 
509
  Gathering = Gather;
 
510
  Local_Zoom = 0.01 / expf (Zoom * LN_2_OVER_2);
 
511
  if (Zoom < 0)
 
512
    Zoom = 0;
 
513
  if (Zoom > 4)
 
514
    Zoom = 4;
 
515
  ZoomValue = (int) Zoom;
 
516
  DrawingWindow = OutputWindow;
 
517
  if (OutputWindow == Offscreen || OutputWindow == Output.OutputWindow)
 
518
    {
 
519
      dxo = Xorig;
 
520
      dyo = Yorig;
 
521
    }
 
522
  else
 
523
    {
 
524
      dxo = 0;
 
525
      dyo = 0;
 
526
    }
 
527
  SwapOutput = Swap;
 
528
  XSetFont (Dpy, Output.fgGC, Settings.PinoutFont[ZoomValue]->fid);
 
529
  XSetFont (Dpy, Output.bgGC, Settings.PinoutFont[ZoomValue]->fid);
 
530
  return (oldGather);
 
531
}
 
532
 
 
533
static int
 
534
backE_callback (const BoxType * b, void *cl)
 
535
{
 
536
  ElementTypePtr element = (ElementTypePtr) b;
 
537
 
 
538
  if (!FRONT (element))
 
539
    {
 
540
      DrawElementPackage (element, 0);
 
541
    }
 
542
  return 1;
 
543
}
 
544
 
 
545
static int
 
546
backN_callback (const BoxType * b, void *cl)
 
547
{
 
548
  TextTypePtr text = (TextTypePtr) b;
 
549
  ElementTypePtr element = (ElementTypePtr) text->Element;
 
550
 
 
551
  if (!FRONT (element) && !TEST_FLAG (HIDENAMEFLAG, element))
 
552
    DrawElementName (element, 0);
 
553
  return 0;
 
554
}
 
555
 
 
556
static int
 
557
backPad_callback (const BoxType * b, void *cl)
 
558
{
 
559
  PadTypePtr pad = (PadTypePtr) b;
 
560
 
 
561
  if (!FRONT (pad))
 
562
    DrawPad (pad, 0);
 
563
  return 1;
 
564
}
 
565
 
 
566
static int
 
567
frontE_callback (const BoxType * b, void *cl)
 
568
{
 
569
  ElementTypePtr element = (ElementTypePtr) b;
 
570
 
 
571
  if (FRONT (element))
 
572
    {
 
573
      DrawElementPackage (element, 0);
 
574
    }
 
575
  return 1;
 
576
}
 
577
 
 
578
static int
 
579
EMark_callback (const BoxType * b, void *cl)
 
580
{
 
581
  ElementTypePtr element = (ElementTypePtr) b;
 
582
 
 
583
  DrawEMark (element->MarkX, element->MarkY, !FRONT (element));
 
584
  return 1;
 
585
}
 
586
 
 
587
static int
 
588
frontN_callback (const BoxType * b, void *cl)
 
589
{
 
590
  TextTypePtr text = (TextTypePtr) b;
 
591
  ElementTypePtr element = (ElementTypePtr) text->Element;
 
592
 
 
593
  if (FRONT (element) && !TEST_FLAG (HIDENAMEFLAG, element))
 
594
    DrawElementName (element, 0);
 
595
  return 0;
 
596
}
 
597
 
 
598
static int
 
599
hole_callback (const BoxType * b, void *cl)
 
600
{
 
601
  DrawHole ((PinTypePtr) b);
 
602
  return 1;
 
603
}
 
604
 
 
605
static int
 
606
rat_callback (const BoxType * b, void *cl)
 
607
{
 
608
  DrawRat ((RatTypePtr) b, 0);
 
609
  return 1;
 
610
}
 
611
 
 
612
static int
 
613
lowvia_callback (const BoxType * b, void *cl)
 
614
{
 
615
  PinTypePtr via = (PinTypePtr) b;
 
616
  if (!via->Mask)
 
617
    DrawPlainVia (via, False);
 
618
  return 1;
298
619
}
299
620
 
300
621
/* ---------------------------------------------------------------------------
301
622
 * initializes some identifiers for a new zoom factor and redraws whole screen
302
623
 */
303
 
static void DrawEverything(void)
304
 
{
305
 
        int i;
306
 
 
307
 
                /*
308
 
                 * first draw all 'invisible' stuff
309
 
                 */
310
 
        if (PCB->InvisibleObjectsOn)
311
 
        {
312
 
                ELEMENT_LOOP(PCB->Data,
313
 
                        if (!FRONT(element))
314
 
                        {
315
 
                                if (PCB->ElementOn)
316
 
                                {
317
 
                                        if (VELEMENT(element))
318
 
                                                DrawElementPackage(element, 0);
319
 
                                        if (VELTEXT(element))
320
 
                                                DrawElementName(element, 0);
321
 
                                }
322
 
                                if (PCB->PinOn && VELEMENT(element))
323
 
                                        PAD_LOOP(element, DrawPad(pad, 0));
324
 
                        }
325
 
                );
326
 
                if (PCB->ElementOn)
327
 
                        DrawLayer(&PCB->Data->Layer[MAX_LAYER +
328
 
                                (SWAP_IDENT ? COMPONENT_LAYER : SOLDER_LAYER)], 0);
329
 
        }
330
 
                /* draw all layers in layerstack order */
331
 
        for (i = MAX_LAYER-1; i >= 0; i--)
332
 
                if ((LAYER_ON_STACK(i))->On)
333
 
                        DrawLayer(LAYER_ON_STACK(i), 0);
334
 
                /* Draw pins, pads, vias */
335
 
        DrawTop();
336
 
                /* Draw top silkscreen */
337
 
        if (PCB->ElementOn)
338
 
        {
339
 
                DrawLayer(&PCB->Data->Layer[MAX_LAYER +
340
 
                        (SWAP_IDENT ? SOLDER_LAYER : COMPONENT_LAYER)], 0);
341
 
                ELEMENT_LOOP(PCB->Data,
342
 
                        if (FRONT(element))
343
 
                        {
344
 
                                if (VELEMENT(element))
345
 
                                        DrawElementPackage(element, 0);
346
 
                                if (VELTEXT(element))
347
 
                                        DrawElementName(element, 0);
348
 
                        }
349
 
                                /* Draw pin holes */
350
 
                        if (PCB->PinOn && VELEMENT(element))
351
 
                        {
352
 
                                PIN_LOOP(element, DrawHole(pin));
353
 
                                DrawEMark(element->MarkX, element->MarkY,
354
 
                                        !FRONT(element));
355
 
                        }
356
 
                );
357
 
        }
358
 
        else if (PCB->PinOn)
359
 
                        /* Draw pin holes */
360
 
                ELEMENT_LOOP(PCB->Data,
361
 
                        if (VELEMENT(element))
362
 
                                PIN_LOOP(element, DrawHole(pin));
363
 
                );
364
 
                /* Draw via holes */
365
 
        if (PCB->ViaOn)
366
 
                VIA_LOOP(PCB->Data, if (VVIA(via)) DrawHole(via));
367
 
                /* Draw rat lines on top */
368
 
        if (PCB->RatOn)
369
 
                RAT_LOOP(PCB->Data, if (VLINE(line)) DrawRat(line, 0));
370
 
        if (Settings.DrawGrid)
371
 
                DrawGrid();
372
 
}
373
 
 
374
 
static void DrawEMark(Position X, Position Y, Boolean invisible)
375
 
{
376
 
        if (!PCB->InvisibleObjectsOn && invisible)
377
 
                return;
378
 
        XSetForeground(Dpy, Output.fgGC, invisible ? PCB->InvisibleMarkColor : PCB->ElementColor);
379
 
        XSetLineAttributes(Dpy, Output.fgGC, 1, LineSolid, CapRound, JoinRound);
380
 
        XDrawLine(Dpy, DrawingWindow, Output.fgGC, TO_DRAW_X(X - EMARK_SIZE),
381
 
                TO_DRAW_Y(Y), TO_DRAW_X(X), TO_DRAW_Y(Y - EMARK_SIZE));
382
 
        XDrawLine(Dpy, DrawingWindow, Output.fgGC, TO_DRAW_X(X + EMARK_SIZE),
383
 
                TO_DRAW_Y(Y), TO_DRAW_X(X), TO_DRAW_Y(Y - EMARK_SIZE));
384
 
        XDrawLine(Dpy, DrawingWindow, Output.fgGC, TO_DRAW_X(X - EMARK_SIZE),
385
 
                TO_DRAW_Y(Y), TO_DRAW_X(X), TO_DRAW_Y(Y + EMARK_SIZE));
386
 
        XDrawLine(Dpy, DrawingWindow, Output.fgGC, TO_DRAW_X(X + EMARK_SIZE),
387
 
                TO_DRAW_Y(Y), TO_DRAW_X(X), TO_DRAW_Y(Y + EMARK_SIZE));
 
624
static void
 
625
DrawEverything (BoxTypePtr drawn_area)
 
626
{
 
627
  int i;
 
628
 
 
629
  /*
 
630
   * first draw all 'invisible' stuff
 
631
   */
 
632
  if (PCB->InvisibleObjectsOn)
 
633
    {
 
634
      r_search (PCB->Data->pad_tree, drawn_area, NULL, backPad_callback,
 
635
                NULL);
 
636
      if (PCB->ElementOn)
 
637
        {
 
638
          r_search (PCB->Data->element_tree, drawn_area, NULL, backE_callback,
 
639
                    NULL);
 
640
          r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL,
 
641
                    backN_callback, NULL);
 
642
          DrawLayer (LAYER_PTR
 
643
                     (MAX_LAYER +
 
644
                      (SWAP_IDENT ? COMPONENT_LAYER : SOLDER_LAYER)),
 
645
                     drawn_area);
 
646
        }
 
647
    }
 
648
  /* draw all layers in layerstack order */
 
649
  for (i = MAX_LAYER - 1; i >= 0; i--)
 
650
    if ((LAYER_ON_STACK (i))->On)
 
651
      DrawLayer (LAYER_ON_STACK (i), drawn_area);
 
652
  /* draw vias below silk */
 
653
  if (PCB->ViaOn)
 
654
    r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, NULL);
 
655
  /* Draw the solder mask if turned on */
 
656
  if (TEST_FLAG (SHOWMASKFLAG, PCB))
 
657
    DrawMask (drawn_area);
 
658
  /* Draw top silkscreen */
 
659
  if (PCB->ElementOn)
 
660
    {
 
661
      DrawLayer (LAYER_PTR (MAX_LAYER + (SWAP_IDENT ? SOLDER_LAYER :
 
662
                                         COMPONENT_LAYER)), drawn_area);
 
663
 
 
664
      /* draw package */
 
665
      r_search (PCB->Data->element_tree, drawn_area, NULL, frontE_callback,
 
666
                NULL);
 
667
      r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL,
 
668
                frontN_callback, NULL);
 
669
    }
 
670
  /* Draw pins, pads, vias above silk */
 
671
  DrawTop (drawn_area);
 
672
  if (PCB->PinOn)
 
673
    /* Draw pin holes */
 
674
    r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, NULL);
 
675
  /* Draw via holes */
 
676
  if (PCB->ViaOn)
 
677
    r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, NULL);
 
678
  /* Draw element Marks */
 
679
  if (PCB->PinOn)
 
680
    r_search (PCB->Data->element_tree, drawn_area, NULL, EMark_callback, NULL);
 
681
  /* Draw rat lines on top */
 
682
  if (PCB->RatOn)
 
683
    r_search (PCB->Data->rat_tree, drawn_area, NULL, rat_callback, NULL);
 
684
  if (Settings.DrawGrid)
 
685
    DrawGrid ();
 
686
}
 
687
 
 
688
static void
 
689
DrawEMark (LocationType X, LocationType Y, Boolean invisible)
 
690
{
 
691
  if (!PCB->InvisibleObjectsOn && invisible)
 
692
    return;
 
693
  XSetForeground (Dpy, Output.fgGC,
 
694
                  invisible ? PCB->InvisibleMarkColor : PCB->ElementColor);
 
695
  XSetLineAttributes (Dpy, Output.fgGC, 1, LineSolid, CapRound, JoinRound);
 
696
  XDrawCLine (Dpy, DrawingWindow, Output.fgGC, X - EMARK_SIZE,
 
697
              Y, X, Y - EMARK_SIZE);
 
698
  XDrawCLine (Dpy, DrawingWindow, Output.fgGC, X + EMARK_SIZE,
 
699
              Y, X, Y - EMARK_SIZE);
 
700
  XDrawCLine (Dpy, DrawingWindow, Output.fgGC, X - EMARK_SIZE,
 
701
              Y, X, Y + EMARK_SIZE);
 
702
  XDrawCLine (Dpy, DrawingWindow, Output.fgGC, X + EMARK_SIZE,
 
703
              Y, X, Y + EMARK_SIZE);
 
704
}
 
705
 
 
706
static int
 
707
via_callback (const BoxType * b, void *cl)
 
708
{
 
709
  PinTypePtr via = (PinTypePtr) b;
 
710
  if (via->Mask)
 
711
    DrawPlainVia (via, False);
 
712
  return 1;
 
713
}
 
714
 
 
715
static int
 
716
pin_callback (const BoxType * b, void *cl)
 
717
{
 
718
  DrawPlainPin ((PinTypePtr) b, False);
 
719
  return 1;
 
720
}
 
721
 
 
722
static int
 
723
pad_callback (const BoxType * b, void *cl)
 
724
{
 
725
  PadTypePtr pad = (PadTypePtr) b;
 
726
  if (FRONT (pad))
 
727
    DrawPad (pad, 0);
 
728
  return 1;
388
729
}
389
730
 
390
731
/* ---------------------------------------------------------------------------
391
732
 * draws pins pads and vias
392
733
 */
393
 
static void DrawTop(void)
394
 
{
395
 
                /* draw element pins */
396
 
        if (PCB->PinOn)
397
 
                ELEMENT_LOOP(PCB->Data,
398
 
                        if (VELEMENT(element))
399
 
                                 DrawPlainElementPinsAndPads(element, 0);
400
 
        );
401
 
 
402
 
                /* draw vias */
403
 
        if (PCB->ViaOn)
404
 
                VIA_LOOP(PCB->Data, if (VVIA(via)) DrawPlainVia(via, 0););
405
 
}
 
734
static void
 
735
DrawTop (BoxType * screen)
 
736
{
 
737
  if (PCB->PinOn)
 
738
    {
 
739
      /* draw element pins */
 
740
      r_search (PCB->Data->pin_tree, screen, NULL, pin_callback, NULL);
 
741
      /* draw element pads */
 
742
      r_search (PCB->Data->pad_tree, screen, NULL, pad_callback, NULL);
 
743
    }
 
744
  /* draw vias */
 
745
  if (PCB->ViaOn)
 
746
    r_search (PCB->Data->via_tree, screen, NULL, via_callback, NULL);
 
747
}
 
748
 
 
749
struct pin_info
 
750
{
 
751
  Boolean arg;
 
752
  int PIPFlag;
 
753
  LayerTypePtr Layer;
 
754
};
 
755
 
 
756
static int
 
757
clearPin_callback (const BoxType * b, void *cl)
 
758
{
 
759
  PinTypePtr pin = (PinTypePtr) b;
 
760
  struct pin_info *i = (struct pin_info *) cl;
 
761
  if (i->arg)
 
762
    ClearOnlyPin (pin, True);
 
763
  else if (TEST_FLAG (i->PIPFlag, pin))
 
764
    ClearOnlyPin (pin, False);
 
765
  return 1;
 
766
}
 
767
 
 
768
static int
 
769
clearPad_callback (const BoxType * b, void *cl)
 
770
{
 
771
  PadTypePtr pad = (PadTypePtr) b;
 
772
  if (!XOR (TEST_FLAG (ONSOLDERFLAG, pad), SWAP_IDENT))
 
773
    ClearPad (pad, True);
 
774
  return 1;
 
775
}
 
776
 
 
777
/* ---------------------------------------------------------------------------
 
778
 * draws solder mask layer - this will cover nearly everything
 
779
 */
 
780
static void
 
781
DrawMask (BoxType * screen)
 
782
{
 
783
  struct pin_info info;
 
784
 
 
785
  info.arg = True;
 
786
  XSetFunction (Dpy, Output.pmGC, GXcopy);
 
787
  /* fill whole map first */
 
788
  XSetForeground (Dpy, Output.pmGC, AllPlanes);
 
789
  XFillRectangle (Dpy, Offmask, Output.pmGC, 0, 0, Output.Width,
 
790
                  Output.Height);
 
791
  XSetFillStyle (Dpy, Output.pmGC, FillSolid);
 
792
  /* make clearances in mask */
 
793
  XSetFunction (Dpy, Output.pmGC, GXclear);
 
794
  r_search (PCB->Data->pin_tree, screen, NULL, clearPin_callback, &info);
 
795
  r_search (PCB->Data->via_tree, screen, NULL, clearPin_callback, &info);
 
796
  r_search (PCB->Data->pad_tree, screen, NULL, clearPad_callback, &info);
 
797
  XSetClipMask (Dpy, Output.fgGC, Offmask);
 
798
  /* now draw the mask */
 
799
  XSetForeground (Dpy, Output.fgGC, PCB->MaskColor);
 
800
  XFillRectangle (Dpy, DrawingWindow, Output.fgGC, 0, 0,
 
801
                  TO_DRAWABS_X (PCB->MaxWidth),
 
802
                  TO_DRAWABS_Y (PCB->MaxHeight));
 
803
  /* restore the clip region */
 
804
  XCopyGC (Dpy, Output.bgGC, GCClipMask, Output.fgGC);
 
805
}
 
806
 
 
807
static int
 
808
clear_callback (int type, void *ptr1, void *ptr2, void *ptr3,
 
809
                LayerTypePtr lay, PolygonTypePtr poly)
 
810
{
 
811
  LineTypePtr l = (LineTypePtr) ptr2;
 
812
  ArcTypePtr a = (ArcTypePtr) ptr2;
 
813
 
 
814
  switch (type)
 
815
    {
 
816
    case LINE_TYPE:
 
817
      ClearLine (l);
 
818
      break;
 
819
    case ARC_TYPE:
 
820
      ClearArc (a);
 
821
      break;
 
822
    case PIN_TYPE:
 
823
    case VIA_TYPE:
 
824
      ClearOnlyPin ((PinTypePtr) ptr2, False);
 
825
      break;
 
826
    case PAD_TYPE:
 
827
      ClearPad ((PadTypePtr) ptr2, False);
 
828
      break;
 
829
    default:
 
830
      Message ("Bad clear callback\n");
 
831
    }
 
832
  return 0;
 
833
}
 
834
 
 
835
static int
 
836
line_callback (const BoxType * b, void *cl)
 
837
{
 
838
  DrawLine ((LayerTypePtr) cl, (LineTypePtr) b, 0);
 
839
  return 1;
 
840
}
 
841
 
 
842
static int
 
843
arc_callback (const BoxType * b, void *cl)
 
844
{
 
845
  DrawArc ((LayerTypePtr) cl, (ArcTypePtr) b, 0);
 
846
  return 1;
 
847
}
 
848
 
 
849
static int
 
850
text_callback (const BoxType * b, void *cl)
 
851
{
 
852
  DrawRegularText ((LayerTypePtr) cl, (TextTypePtr) b, 0);
 
853
  return 1;
 
854
}
 
855
 
 
856
static int
 
857
therm_callback (const BoxType * b, void *cl)
 
858
{
 
859
  PinTypePtr pin = (PinTypePtr) b;
 
860
  struct pin_info *i = (struct pin_info *) cl;
 
861
 
 
862
  if (TEST_FLAGS (i->PIPFlag, pin))
 
863
    {
 
864
      ThermPin (i->Layer, pin);
 
865
      return 1;
 
866
    }
 
867
  return 0;
 
868
}
 
869
 
406
870
 
407
871
/* ---------------------------------------------------------------------------
408
872
 * draws one layer
409
873
 */
410
 
static void DrawLayer(LayerTypePtr Layer, int unused)
 
874
static void
 
875
DrawLayer (LayerTypePtr Layer, BoxType * screen)
411
876
{
412
 
        int             layernum = GetLayerNumber(PCB->Data, Layer);
413
 
        Cardinal        group = GetLayerGroupNumberByNumber(layernum);
414
 
        Cardinal        entry;
415
 
        
416
 
        int PIPFlag = L0PIPFLAG << layernum;
 
877
  int layernum = GetLayerNumber (PCB->Data, Layer);
 
878
  Cardinal group = GetLayerGroupNumberByNumber (layernum);
 
879
  struct pin_info info;
 
880
 
 
881
  int PIPFlag = L0PIPFLAG << layernum;
 
882
  info.PIPFlag = PIPFlag;
 
883
  info.arg = False;
 
884
  info.Layer = Layer;
417
885
/* in order to render polygons with line cut-outs:
418
886
 * draw a solid (or stippled) 1-bit pixmap, then erase
419
887
 * the clearance areas.  Use that as the mask when
420
888
 * drawing the actual polygons
421
889
 */
422
 
        if (layernum < MAX_LAYER && Layer->PolygonN)
423
 
        {
424
 
                XSetFunction(Dpy, Output.pmGC, GXcopy);
425
 
                if (Settings.StipplePolygons)
426
 
                {
427
 
                        XSetBackground(Dpy, Output.pmGC, 0);
428
 
                        XSetStipple(Dpy, Output.pmGC, Stipples[layernum]);
429
 
                        XSetFillStyle(Dpy, Output.pmGC, FillOpaqueStippled);
430
 
                }
431
 
                        /* fill whole map first */
432
 
                XSetForeground(Dpy, Output.pmGC, AllPlanes);
433
 
                XFillRectangle(Dpy, Offmask, Output.pmGC, 0, 0 , Output.Width, Output.Height);
434
 
                if (Settings.StipplePolygons)
435
 
                        XSetFillStyle(Dpy, Output.pmGC, FillSolid);
436
 
                        /* make clearances around lines, arcs, pins and vias */
437
 
                XSetFunction(Dpy, Output.pmGC, GXclear);
438
 
                for (entry = 0; entry < PCB->LayerGroups.Number[group]; entry++)
439
 
                {
440
 
                        Cardinal guest = PCB->LayerGroups.Entries[group][entry];
441
 
 
442
 
                        if (guest < MAX_LAYER)
443
 
                        {
444
 
                                LayerTypePtr    guestLayer = &PCB->Data->Layer[guest];
445
 
 
446
 
                                LINE_LOOP(guestLayer,
447
 
                                        if (TEST_FLAG(CLEARLINEFLAG, line) && VLINE(line))
448
 
                                                ClearLine(line);
449
 
                                );
450
 
                                ARC_LOOP(guestLayer,
451
 
                                        if (TEST_FLAG(CLEARLINEFLAG, arc) && VARC(arc))
452
 
                                                ClearArc(arc);
453
 
                                );
454
 
                        }
455
 
                }
456
 
                ALLPIN_LOOP(PCB->Data,
457
 
                        if (TEST_FLAG(PIPFlag, pin))
458
 
                                ClearOnlyPin(pin);
459
 
                );
460
 
                VIA_LOOP(PCB->Data,
461
 
                        if (TEST_FLAG(PIPFlag, via))
462
 
                                ClearOnlyPin(via);
463
 
                );
464
 
                if (group == GetLayerGroupNumberByNumber(MAX_LAYER + SOLDER_LAYER))
465
 
                        ALLPAD_LOOP(PCB->Data,
466
 
                                if (TEST_FLAG(ONSOLDERFLAG, pad))
467
 
                                        ClearPad(pad);
468
 
                        );
469
 
                if (group == GetLayerGroupNumberByNumber(MAX_LAYER + COMPONENT_LAYER))
470
 
                        ALLPAD_LOOP(PCB->Data,
471
 
                                if (!TEST_FLAG(ONSOLDERFLAG, pad))
472
 
                                        ClearPad(pad);
473
 
                        );
474
 
                XSetClipMask(Dpy, Output.fgGC, Offmask);
475
 
        }
476
 
        if (Layer->PolygonN)
477
 
        {
478
 
                POLYGON_LOOP(Layer, if (VPOLY(polygon)) DrawPlainPolygon(Layer, polygon));
479
 
                        /* restore the clip region */
480
 
                XCopyGC(Dpy, Output.bgGC, GCClipMask, Output.fgGC);
481
 
                if (layernum < MAX_LAYER)
482
 
                {
483
 
                        PIPFlag = L0THERMFLAG << layernum;
484
 
                        ALLPIN_LOOP(PCB->Data,
485
 
                                if (TEST_FLAG(PIPFlag, pin))
486
 
                                        ThermPin(Layer, pin);
487
 
                        );
488
 
                        VIA_LOOP(PCB->Data,
489
 
                                if (TEST_FLAG(PIPFlag, via))
490
 
                                        ThermPin(Layer, via);
491
 
                        );
492
 
                }
493
 
        } 
494
 
        LINE_LOOP(Layer, if (VLINE(line)) DrawLine(Layer, line, unused));
495
 
        ARC_LOOP(Layer, if (VARC(arc)) DrawArc(Layer, arc, unused));
496
 
        TEXT_LOOP(Layer, if (VTEXT(text)) DrawRegularText(Layer, text, unused));
497
 
498
 
 
499
 
/* ---------------------------------------------------------------------------
500
 
 * initializes some zoom dependend information for pins and lines
501
 
 * just to speed up drawing a bit
502
 
 */
503
 
static void InitSpecialPolygon(void)
504
 
{
505
 
        int     i, j;
506
 
        static  FloatPolyType   p[8] = {{       0.5, -TAN_22_5_DEGREE_2},
507
 
                                        { TAN_22_5_DEGREE_2,       -0.5},
508
 
                                        {-TAN_22_5_DEGREE_2,       -0.5},
509
 
                                        {      -0.5, -TAN_22_5_DEGREE_2},
510
 
                                        {      -0.5,  TAN_22_5_DEGREE_2},
511
 
                                        {-TAN_22_5_DEGREE_2,        0.5},
512
 
                                        { TAN_22_5_DEGREE_2,        0.5},
513
 
                                        {       0.5,  TAN_22_5_DEGREE_2}};
514
 
 
515
 
 
516
 
                /* loop over maximum number of different sizes */
517
 
        for (i = MAX(MAX_PINORVIASIZE, MAX_LINESIZE); i != -1; i--)
518
 
                for (j = 0; j < 8; j++)
519
 
                {
520
 
                        Outline[i][j].x = (p[j].X * TO_SCREEN(i));
521
 
                        Outline[i][j].y = (p[j].Y * TO_SCREEN(i));
522
 
                }
 
890
  if (layernum < MAX_LAYER && Layer->PolygonN)
 
891
    {
 
892
      XSetFunction (Dpy, Output.pmGC, GXcopy);
 
893
      if (Settings.StipplePolygons)
 
894
        {
 
895
          XSetBackground (Dpy, Output.pmGC, 0);
 
896
          XSetStipple (Dpy, Output.pmGC, Stipples[layernum]);
 
897
          XSetFillStyle (Dpy, Output.pmGC, FillOpaqueStippled);
 
898
        }
 
899
      /* fill whole map first */
 
900
      XSetForeground (Dpy, Output.pmGC, AllPlanes);
 
901
      XFillRectangle (Dpy, Offmask, Output.pmGC, 0, 0, Output.Width,
 
902
                      Output.Height);
 
903
      if (Settings.StipplePolygons)
 
904
        XSetFillStyle (Dpy, Output.pmGC, FillSolid);
 
905
      /* make clearances around lines, arcs, pins and vias */
 
906
      XSetFunction (Dpy, Output.pmGC, GXclear);
 
907
      PolygonPlows (group, screen, clear_callback);
 
908
      XSetClipMask (Dpy, Output.fgGC, Offmask);
 
909
    }
 
910
  if (Layer->PolygonN)
 
911
    {
 
912
      /* print the clearing polys */
 
913
      POLYGON_LOOP (Layer);
 
914
      {
 
915
        if (VPOLY (polygon) && TEST_FLAG (CLEARPOLYFLAG, polygon))
 
916
          DrawPlainPolygon (Layer, polygon);
 
917
      }
 
918
      END_LOOP;
 
919
      /* restore the clip region */
 
920
      XCopyGC (Dpy, Output.bgGC, GCClipMask, Output.fgGC);
 
921
      /* print the non-clearing polys */
 
922
      POLYGON_LOOP (Layer);
 
923
      {
 
924
        if (VPOLY (polygon) && !TEST_FLAG (CLEARPOLYFLAG, polygon))
 
925
          DrawPlainPolygon (Layer, polygon);
 
926
      }
 
927
      END_LOOP;
 
928
      if (layernum < MAX_LAYER)
 
929
        {
 
930
          PIPFlag = (L0THERMFLAG | L0PIPFLAG) << layernum;
 
931
          info.PIPFlag = PIPFlag;
 
932
          r_search (PCB->Data->pin_tree, screen, NULL, therm_callback, &info);
 
933
          r_search (PCB->Data->via_tree, screen, NULL, therm_callback, &info);
 
934
        }
 
935
    }
 
936
  if (TEST_FLAG (CHECKPLANESFLAG, PCB))
 
937
    return;
 
938
  /* draw all visible lines this layer */
 
939
  r_search (Layer->line_tree, screen, NULL, line_callback, Layer);
 
940
  /* draw the layer arcs on screen */
 
941
  r_search (Layer->arc_tree, screen, NULL, arc_callback, Layer);
 
942
  /* draw the layer text on screen */
 
943
  r_search (Layer->text_tree, screen, NULL, text_callback, Layer);
523
944
}
524
945
 
525
946
/* ---------------------------------------------------------------------------
536
957
 *          2 --- 1
537
958
 *
538
959
 */
539
 
static void DrawSpecialPolygon(Drawable d, GC DrawGC,
540
 
        Position X, Position Y, XPoint *PolyPtr)
 
960
static void
 
961
DrawSpecialPolygon (Drawable d, GC DrawGC,
 
962
                    LocationType X, LocationType Y, BDimension Thickness)
541
963
{
542
 
        int             i;
543
 
        XPoint  polygon[8];
544
 
 
545
 
                /* add line offset */
546
 
        for (i = 0; i < 8; i++)
 
964
  static FloatPolyType p[8] = { {0.5, -TAN_22_5_DEGREE_2},
 
965
  {TAN_22_5_DEGREE_2, -0.5},
 
966
  {-TAN_22_5_DEGREE_2, -0.5},
 
967
  {-0.5, -TAN_22_5_DEGREE_2},
 
968
  {-0.5, TAN_22_5_DEGREE_2},
 
969
  {-TAN_22_5_DEGREE_2, 0.5},
 
970
  {TAN_22_5_DEGREE_2, 0.5},
 
971
  {0.5, TAN_22_5_DEGREE_2}
 
972
  };
 
973
  static Dimension special_size = 0;
 
974
  static XPoint scaled[8];
 
975
  XPoint polygon[9];
 
976
  int i;
 
977
 
 
978
 
 
979
  if (TO_SCREEN (Thickness) != special_size)
 
980
    {
 
981
      special_size = TO_SCREEN (Thickness);
 
982
      for (i = 0; i < 8; i++)
547
983
        {
548
 
                polygon[i].x = X+ PolyPtr[i].x;
549
 
                polygon[i].y = Y+ PolyPtr[i].y;
 
984
          scaled[i].x = p[i].X * special_size;
 
985
          scaled[i].y = p[i].Y * special_size;
550
986
        }
551
 
        XFillPolygon(Dpy, d, DrawGC,
552
 
                polygon, ENTRIES(polygon), Convex, CoordModeOrigin);
 
987
    }
 
988
  /* add line offset */
 
989
  for (i = 0; i < 8; i++)
 
990
    {
 
991
      polygon[i].x = X + scaled[i].x;
 
992
      polygon[i].y = Y + scaled[i].y;
 
993
    }
 
994
  if (TEST_FLAG (THINDRAWFLAG, PCB))
 
995
    {
 
996
      XSetLineAttributes (Dpy, Output.fgGC, 1,
 
997
                          LineSolid, CapRound, JoinRound);
 
998
      polygon[8].x = X + scaled[0].x;
 
999
      polygon[8].y = Y + scaled[0].y;
 
1000
      XDrawLines (Dpy, d, DrawGC, polygon, 9, CoordModeOrigin);
 
1001
    }
 
1002
  else
 
1003
    XFillPolygon (Dpy, d, DrawGC, polygon, 8, Convex, CoordModeOrigin);
553
1004
}
554
1005
 
555
1006
/* ---------------------------------------------------------------------------
556
1007
 * lowlevel drawing routine for pins and vias
557
1008
 */
558
 
static void DrawPinOrViaLowLevel(PinTypePtr Ptr, Boolean drawHole)
 
1009
static void
 
1010
DrawPinOrViaLowLevel (PinTypePtr Ptr, Boolean drawHole)
559
1011
{
560
 
        Dimension       half = Ptr->Thickness/2;
561
 
 
562
 
        UpdateRect.x = TO_DRAW_X(Ptr->X - half);
563
 
        UpdateRect.y = TO_DRAW_Y(Ptr->Y) -TO_SCREEN(half);
564
 
        UpdateRect.width = UpdateRect.height = TO_SCREEN(Ptr->Thickness);
565
 
        if (Gathering)
566
 
        {
567
 
                AddPart();
568
 
                return;
569
 
        }
570
 
 
571
 
        if (drawHole && TEST_FLAG(HOLEFLAG, Ptr))
572
 
        {
573
 
                XSetLineAttributes(Dpy, Output.bgGC, TO_SCREEN(Ptr->Thickness),
574
 
                        LineSolid, CapRound, JoinRound);
575
 
                XDrawLine(Dpy, DrawingWindow, Output.bgGC, TO_DRAW_X(Ptr->X),
576
 
                        TO_DRAW_Y(Ptr->Y), TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y));
577
 
                XSetLineAttributes(Dpy, Output.fgGC, 1, LineSolid, CapRound, JoinRound);
578
 
                XDrawArc(Dpy, DrawingWindow, Output.fgGC,
579
 
                        TO_DRAW_X(Ptr->X - half),
580
 
                        TO_DRAW_Y(Ptr->Y - TO_SCREEN_SIGN_Y(half)),
581
 
                        TO_SCREEN(Ptr->Thickness), TO_SCREEN(Ptr->Thickness),
582
 
                        0, 23040);
583
 
                return;
584
 
        }
585
 
        if (TEST_FLAG(SQUAREFLAG, Ptr))
586
 
        {
587
 
                XFillRectangle(Dpy, DrawingWindow, Output.fgGC,
588
 
                        UpdateRect.x, UpdateRect.y,
589
 
                        UpdateRect.width, UpdateRect.height);
590
 
        }
591
 
        else if (TEST_FLAG(OCTAGONFLAG, Ptr))
592
 
        {
593
 
                XSetLineAttributes(Dpy, Output.fgGC,
594
 
                        TO_SCREEN((Ptr->Thickness -Ptr->DrillingHole) /2),
595
 
                        LineSolid, CapRound, JoinRound);
596
 
 
597
 
                        /* transform X11 specific coord system */
598
 
                DrawSpecialPolygon(DrawingWindow, Output.fgGC,
599
 
                        TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y),
600
 
                        &Outline[Ptr->Thickness][0]);
601
 
        }
602
 
        else
603
 
        {               /* draw a round pin or via */
604
 
                XSetLineAttributes(Dpy, Output.fgGC, TO_SCREEN(Ptr->Thickness),
605
 
                        LineSolid, CapRound, JoinRound);
606
 
                XDrawLine(Dpy, DrawingWindow, Output.fgGC, TO_DRAW_X(Ptr->X),
607
 
                        TO_DRAW_Y(Ptr->Y), TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y));
608
 
        }
609
 
 
610
 
                /* and the drilling hole  (which is always round */
611
 
        if (drawHole)
612
 
        {
613
 
                XSetLineAttributes(Dpy, Output.bgGC, TO_SCREEN(Ptr->DrillingHole),
614
 
                        LineSolid, CapRound, JoinRound);
615
 
                XDrawLine(Dpy, DrawingWindow, Output.bgGC, TO_DRAW_X(Ptr->X),
616
 
                        TO_DRAW_Y(Ptr->Y), TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y));
617
 
        }
 
1012
  if (Gathering)
 
1013
    {
 
1014
      AddPart (Ptr, False);
 
1015
      return;
 
1016
    }
 
1017
 
 
1018
  if (TEST_FLAG (HOLEFLAG, Ptr))
 
1019
    {
 
1020
      if (drawHole)
 
1021
        {
 
1022
          XSetLineAttributes (Dpy, Output.bgGC, TO_SCREEN (Ptr->Thickness),
 
1023
                              LineSolid, CapRound, JoinRound);
 
1024
          XDrawCLine (Dpy, DrawingWindow, Output.bgGC, Ptr->X, Ptr->Y,
 
1025
                      Ptr->X, Ptr->Y);
 
1026
          XSetLineAttributes (Dpy, Output.fgGC, 1, LineSolid, CapRound,
 
1027
                              JoinRound);
 
1028
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, Ptr->X, Ptr->Y,
 
1029
                     Ptr->Thickness, Ptr->Thickness, 0, 23040);
 
1030
        }
 
1031
      return;
 
1032
    }
 
1033
  if (TEST_FLAG (SQUAREFLAG, Ptr))
 
1034
    {
 
1035
      if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1036
        {
 
1037
          XSetLineAttributes (Dpy, Output.fgGC, 1,
 
1038
                              LineSolid, CapRound, JoinRound);
 
1039
          XDrawRectangle (Dpy, DrawingWindow, Output.fgGC,
 
1040
                          TO_DRAW_X (Ptr->X - Ptr->Thickness / 2),
 
1041
                          TO_DRAW_Y (Ptr->Y -
 
1042
                                     TO_SCREEN_SIGN_Y (Ptr->Thickness / 2)),
 
1043
                          TO_SCREEN (Ptr->Thickness),
 
1044
                          TO_SCREEN (Ptr->Thickness));
 
1045
        }
 
1046
      else
 
1047
        {
 
1048
          XFillRectangle (Dpy, DrawingWindow, Output.fgGC,
 
1049
                          TO_DRAW_X (Ptr->X - Ptr->Thickness / 2),
 
1050
                          TO_DRAW_Y (Ptr->Y -
 
1051
                                     TO_SCREEN_SIGN_Y (Ptr->Thickness / 2)),
 
1052
                          TO_SCREEN (Ptr->Thickness),
 
1053
                          TO_SCREEN (Ptr->Thickness));
 
1054
        }
 
1055
    }
 
1056
  else if (TEST_FLAG (OCTAGONFLAG, Ptr))
 
1057
    {
 
1058
      XSetLineAttributes (Dpy, Output.fgGC,
 
1059
                          TO_SCREEN ((Ptr->Thickness - Ptr->DrillingHole) /
 
1060
                                     2), LineSolid, CapRound, JoinRound);
 
1061
 
 
1062
      /* transform X11 specific coord system */
 
1063
      DrawSpecialPolygon (DrawingWindow, Output.fgGC,
 
1064
                          TO_DRAW_X (Ptr->X), TO_DRAW_Y (Ptr->Y),
 
1065
                          Ptr->Thickness);
 
1066
    }
 
1067
  else
 
1068
    {                           /* draw a round pin or via */
 
1069
      if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1070
        {
 
1071
          XSetLineAttributes (Dpy, Output.fgGC, 1,
 
1072
                              LineSolid, CapRound, JoinRound);
 
1073
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, Ptr->X, Ptr->Y,
 
1074
                     Ptr->Thickness, Ptr->Thickness, 0, 360 * 64);
 
1075
        }
 
1076
      else
 
1077
        {
 
1078
          XSetLineAttributes (Dpy, Output.fgGC, TO_SCREEN (Ptr->Thickness),
 
1079
                              LineSolid, CapRound, JoinRound);
 
1080
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Ptr->X, Ptr->Y,
 
1081
                      Ptr->X, Ptr->Y);
 
1082
        }
 
1083
    }
 
1084
 
 
1085
  /* and the drilling hole  (which is always round */
 
1086
  if (drawHole)
 
1087
    {
 
1088
      if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1089
        {
 
1090
          XSetLineAttributes (Dpy, Output.fgGC, 1,
 
1091
                              LineSolid, CapRound, JoinRound);
 
1092
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC,
 
1093
                     Ptr->X, Ptr->Y, Ptr->DrillingHole,
 
1094
                     Ptr->DrillingHole, 0, 360 * 64);
 
1095
        }
 
1096
      else
 
1097
        {
 
1098
          XSetLineAttributes (Dpy, Output.bgGC, TO_SCREEN (Ptr->DrillingHole),
 
1099
                              LineSolid, CapRound, JoinRound);
 
1100
          XDrawCLine (Dpy, DrawingWindow, Output.bgGC, Ptr->X, Ptr->Y,
 
1101
                      Ptr->X, Ptr->Y);
 
1102
        }
 
1103
    }
618
1104
}
619
1105
 
620
1106
/**************************************************************
621
1107
 * draw pin/via hole
622
1108
 */
623
 
static void DrawHole(PinTypePtr Ptr)
 
1109
static void
 
1110
DrawHole (PinTypePtr Ptr)
624
1111
{
625
 
        XSetLineAttributes(Dpy, Output.bgGC, TO_SCREEN(Ptr->DrillingHole),
626
 
                LineSolid, CapRound, JoinRound);
627
 
        XDrawLine(Dpy, DrawingWindow, Output.bgGC, TO_DRAW_X(Ptr->X),
628
 
                TO_DRAW_Y(Ptr->Y), TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y));
629
 
        if (TEST_FLAG(HOLEFLAG, Ptr))
 
1112
  if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1113
    {
 
1114
      if (!TEST_FLAG (HOLEFLAG, Ptr))
630
1115
        {
631
 
                Dimension half = Ptr->Thickness/2;
632
 
 
633
 
                if (TEST_FLAG(SELECTEDFLAG, Ptr))
634
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ViaSelectedColor);
635
 
                else
636
 
                        XSetForeground(Dpy, Output.fgGC,
637
 
                                BlackPixelOfScreen(XtScreen(Output.Output)));
638
 
                XSetLineAttributes(Dpy, Output.fgGC, 1, LineSolid, CapRound, JoinRound);
639
 
                XDrawArc(Dpy, DrawingWindow, Output.fgGC,
640
 
                        TO_DRAW_X(Ptr->X - half),
641
 
                        TO_DRAW_Y(Ptr->Y - TO_SCREEN_SIGN_Y(half)),
642
 
                        TO_SCREEN(Ptr->DrillingHole), TO_SCREEN(Ptr->DrillingHole),
643
 
                        0, 23040);
 
1116
          XSetLineAttributes (Dpy, Output.fgGC, 1,
 
1117
                              LineSolid, CapRound, JoinRound);
 
1118
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, Ptr->X, Ptr->Y,
 
1119
                     Ptr->DrillingHole, Ptr->DrillingHole, 0, 360 * 64);
644
1120
        }
 
1121
    }
 
1122
  else
 
1123
    {
 
1124
      XSetLineAttributes (Dpy, Output.bgGC, TO_SCREEN (Ptr->DrillingHole),
 
1125
                          LineSolid, CapRound, JoinRound);
 
1126
      XDrawCLine (Dpy, DrawingWindow, Output.bgGC, Ptr->X,
 
1127
                  Ptr->Y, Ptr->X, Ptr->Y);
 
1128
    }
 
1129
  if (TEST_FLAG (HOLEFLAG, Ptr))
 
1130
    {
 
1131
      if (TEST_FLAG (WARNFLAG, Ptr))
 
1132
        XSetForeground (Dpy, Output.fgGC, PCB->WarnColor);
 
1133
      else if (TEST_FLAG (SELECTEDFLAG, Ptr))
 
1134
        XSetForeground (Dpy, Output.fgGC, PCB->ViaSelectedColor);
 
1135
      else
 
1136
        XSetForeground (Dpy, Output.fgGC,
 
1137
                        BlackPixelOfScreen (XtScreen (Output.Output)));
 
1138
      XSetLineAttributes (Dpy, Output.fgGC, 1, LineSolid, CapRound,
 
1139
                          JoinRound);
 
1140
      XDrawCArc (Dpy, DrawingWindow, Output.fgGC, Ptr->X, Ptr->Y,
 
1141
                 Ptr->DrillingHole, Ptr->DrillingHole, 0, 23040);
 
1142
    }
645
1143
}
646
1144
 
647
1145
/*******************************************************************
648
1146
 * draw clearance in pixmask arround pins and vias that pierce polygons
649
1147
 */
650
 
static void ClearOnlyPin(PinTypePtr Pin)
 
1148
static void
 
1149
ClearOnlyPin (PinTypePtr Pin, Boolean mask)
651
1150
{
652
 
        Dimension       half = (Pin->Thickness + Pin->Clearance)/2;
653
 
 
654
 
        if (TEST_FLAG(HOLEFLAG, Pin))
655
 
                return;
656
 
 
657
 
           /* Clear the area around the pin */
658
 
        if (TEST_FLAG(SQUAREFLAG, Pin))
659
 
        {
660
 
                XFillRectangle(Dpy, Offmask, Output.pmGC,
661
 
                        TO_MASK_X(Pin->X - TO_SCREEN_SIGN_X(half)),
662
 
                        TO_MASK_Y(Pin->Y - TO_SCREEN_SIGN_Y(half)),
663
 
                        TO_SCREEN(Pin->Thickness + Pin->Clearance),
664
 
                        TO_SCREEN(Pin->Thickness + Pin->Clearance));
665
 
        }
666
 
        else if (TEST_FLAG(OCTAGONFLAG, Pin))
667
 
        {
668
 
                XSetLineAttributes(Dpy, Output.pmGC,
669
 
                        TO_SCREEN((Pin->Thickness + Pin->Clearance -Pin->DrillingHole) /2),
670
 
                        LineSolid, CapRound, JoinRound);
671
 
 
672
 
                        /* transform X11 specific coord system */
673
 
                DrawSpecialPolygon(Offmask, Output.pmGC,
674
 
                        TO_MASK_X(Pin->X), TO_MASK_Y(Pin->Y),
675
 
                        &Outline[Pin->Thickness + Pin->Clearance][0]);
676
 
        }
677
 
        else
678
 
        {
679
 
                XSetLineAttributes(Dpy, Output.pmGC,
680
 
                        TO_SCREEN(Pin->Thickness + Pin->Clearance),
681
 
                        LineSolid, CapRound, JoinRound);
682
 
                XDrawLine(Dpy, Offmask, Output.pmGC, TO_MASK_X(Pin->X),
683
 
                        TO_MASK_Y(Pin->Y), TO_MASK_X(Pin->X), TO_MASK_Y(Pin->Y));
684
 
        }
 
1151
  BDimension half =
 
1152
    (mask ? Pin->Mask / 2 : (Pin->Thickness + Pin->Clearance) / 2);
 
1153
 
 
1154
  if (!mask && TEST_FLAG (HOLEFLAG, Pin))
 
1155
    return;
 
1156
 
 
1157
  /* Clear the area around the pin */
 
1158
  if (TEST_FLAG (SQUAREFLAG, Pin))
 
1159
    {
 
1160
      XFillRectangle (Dpy, Offmask, Output.pmGC,
 
1161
                      TO_DRAW_X (Pin->X - TO_SCREEN_SIGN_X (half)),
 
1162
                      TO_DRAW_Y (Pin->Y - TO_SCREEN_SIGN_Y (half)),
 
1163
                      TO_SCREEN (mask ? Pin->Mask : Pin->Thickness +
 
1164
                                 Pin->Clearance),
 
1165
                      TO_SCREEN (mask ? Pin->Mask : Pin->Thickness +
 
1166
                                 Pin->Clearance));
 
1167
    }
 
1168
  else if (TEST_FLAG (OCTAGONFLAG, Pin))
 
1169
    {
 
1170
      XSetLineAttributes (Dpy, Output.pmGC,
 
1171
                          TO_SCREEN ((Pin->Thickness + Pin->Clearance -
 
1172
                                      Pin->DrillingHole) / 2), LineSolid,
 
1173
                          CapRound, JoinRound);
 
1174
 
 
1175
      /* transform X11 specific coord system */
 
1176
      DrawSpecialPolygon (Offmask, Output.pmGC,
 
1177
                          TO_DRAW_X (Pin->X), TO_DRAW_Y (Pin->Y),
 
1178
                          mask ? Pin->Mask : Pin->Thickness + Pin->Clearance);
 
1179
    }
 
1180
  else
 
1181
    {
 
1182
      XSetLineAttributes (Dpy, Output.pmGC,
 
1183
                          TO_SCREEN (mask ? Pin->Mask : Pin->Thickness +
 
1184
                                     Pin->Clearance), LineSolid, CapRound,
 
1185
                          JoinRound);
 
1186
      XDrawCLine (Dpy, Offmask, Output.pmGC, Pin->X, Pin->Y, Pin->X, Pin->Y);
 
1187
    }
685
1188
}
686
1189
 
687
1190
/**************************************************************************
688
1191
 * draw thermals on pin
689
1192
 */
690
 
static void ThermPin(LayerTypePtr layer, PinTypePtr Pin)
 
1193
static void
 
1194
ThermPin (LayerTypePtr layer, PinTypePtr Pin)
691
1195
{
692
 
        Dimension       half = (Pin->Thickness + Pin->Clearance)/2;
693
 
        Dimension       halfs = (TO_SCREEN(half) * SQRT2OVER2 + 1);
694
 
 
695
 
        if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Pin))
696
 
        {
697
 
                if (TEST_FLAG(SELECTEDFLAG, Pin))
698
 
                        XSetForeground(Dpy, Output.fgGC, layer->SelectedColor);
699
 
                else
700
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
701
 
        }
702
 
        else
703
 
                XSetForeground(Dpy, Output.fgGC, layer->Color);
704
 
 
705
 
        XSetLineAttributes(Dpy, Output.fgGC, TO_SCREEN(Pin->Clearance/2),
706
 
                LineSolid, CapRound, JoinRound);
707
 
        if (TEST_FLAG(SQUAREFLAG, Pin))
708
 
        {
709
 
                
710
 
                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
711
 
                        TO_DRAW_X(Pin->X) - TO_SCREEN(half),
712
 
                        TO_DRAW_Y(Pin->Y) - TO_SCREEN(half),
713
 
                        TO_DRAW_X(Pin->X) + TO_SCREEN(half),
714
 
                        TO_DRAW_Y(Pin->Y) + TO_SCREEN(half));
715
 
                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
716
 
                        TO_DRAW_X(Pin->X) - TO_SCREEN(half),
717
 
                        TO_DRAW_Y(Pin->Y) + TO_SCREEN(half),
718
 
                        TO_DRAW_X(Pin->X) + TO_SCREEN(half),
719
 
                        TO_DRAW_Y(Pin->Y) - TO_SCREEN(half));
720
 
        }
721
 
        else
722
 
        {
723
 
                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
724
 
                        TO_DRAW_X(Pin->X) - halfs,
725
 
                        TO_DRAW_Y(Pin->Y) - halfs,
726
 
                        TO_DRAW_X(Pin->X) + halfs,
727
 
                        TO_DRAW_Y(Pin->Y) + halfs);
728
 
                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
729
 
                        TO_DRAW_X(Pin->X) - halfs,
730
 
                        TO_DRAW_Y(Pin->Y) + halfs,
731
 
                        TO_DRAW_X(Pin->X) + halfs,
732
 
                        TO_DRAW_Y(Pin->Y) - halfs);
733
 
        }
 
1196
  BDimension half = (Pin->Thickness + Pin->Clearance) / 2;
 
1197
  BDimension finger;
 
1198
 
 
1199
  if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Pin))
 
1200
    {
 
1201
      if (TEST_FLAG (SELECTEDFLAG, Pin))
 
1202
        XSetForeground (Dpy, Output.fgGC, layer->SelectedColor);
 
1203
      else
 
1204
        XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
 
1205
    }
 
1206
  else
 
1207
    XSetForeground (Dpy, Output.fgGC, layer->Color);
 
1208
 
 
1209
  finger = (Pin->Thickness - Pin->DrillingHole) * PCB->ThermScale;
 
1210
  XSetLineAttributes (Dpy, Output.fgGC,
 
1211
                      TEST_FLAG (THINDRAWFLAG, PCB) ? 1 : TO_SCREEN (finger),
 
1212
                      LineSolid, CapRound, JoinRound);
 
1213
  if (TEST_FLAG (SQUAREFLAG, Pin))
 
1214
    {
 
1215
 
 
1216
      XDrawCLine (Dpy, DrawingWindow, Output.fgGC,
 
1217
                  Pin->X - half, Pin->Y - half, Pin->X + half, Pin->Y + half);
 
1218
      XDrawCLine (Dpy, DrawingWindow, Output.fgGC,
 
1219
                  Pin->X - half, Pin->Y + half, Pin->X + half, Pin->Y - half);
 
1220
    }
 
1221
  else
 
1222
    {
 
1223
      BDimension halfs = (half * M_SQRT1_2 + 1);
 
1224
 
 
1225
      XDrawCLine (Dpy, DrawingWindow, Output.fgGC,
 
1226
                  Pin->X - halfs, Pin->Y - halfs, Pin->X + halfs,
 
1227
                  Pin->Y + halfs);
 
1228
      XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Pin->X - halfs,
 
1229
                  Pin->Y + halfs, Pin->X + halfs, Pin->Y - halfs);
 
1230
    }
734
1231
}
735
1232
 
736
1233
/* ---------------------------------------------------------------------------
737
1234
 * lowlevel drawing routine for pins and vias that pierce polygons
738
1235
 */
739
 
void ClearPin(PinTypePtr Pin, int Type, int unused)
 
1236
void
 
1237
ClearPin (PinTypePtr Pin, int Type, int unused)
740
1238
{
741
 
        int             ThermLayerFlag;
742
 
        LayerTypePtr    layer;
743
 
        Cardinal        i;
744
 
        Dimension       half = (Pin->Thickness + Pin->Clearance)/2;
745
 
        Dimension       halfs = (TO_SCREEN(half) * SQRT2OVER2 + 1);
746
 
 
747
 
        if (Gathering)
748
 
        {
749
 
                UpdateRect.x = TO_DRAW_X(Pin->X) - TO_SCREEN(half);
750
 
                UpdateRect.y = TO_DRAW_Y(Pin->Y) - TO_SCREEN(half);
751
 
                UpdateRect.width = UpdateRect.height = TO_SCREEN(2*half);
752
 
                AddPart();
753
 
                return;
754
 
        }
755
 
           /* Clear the area around the pin */
756
 
        if (TEST_FLAG(SQUAREFLAG, Pin))
757
 
        {
758
 
                XFillRectangle(Dpy, DrawingWindow, Output.bgGC,
759
 
                        TO_DRAW_X(Pin->X - TO_SCREEN_SIGN_X(half)),
760
 
                        TO_DRAW_Y(Pin->Y - TO_SCREEN_SIGN_Y(half)),
761
 
                        TO_SCREEN(Pin->Thickness + Pin->Clearance),
762
 
                        TO_SCREEN(Pin->Thickness + Pin->Clearance));
763
 
        }
764
 
        else if (TEST_FLAG(OCTAGONFLAG, Pin))
765
 
        {
766
 
                XSetLineAttributes(Dpy, Output.bgGC,
767
 
                        TO_SCREEN((Pin->Thickness + Pin->Clearance -Pin->DrillingHole) /2),
768
 
                        LineSolid, CapRound, JoinRound);
769
 
 
770
 
                        /* transform X11 specific coord system */
771
 
                DrawSpecialPolygon(DrawingWindow, Output.bgGC,
772
 
                        TO_DRAW_X(Pin->X), TO_DRAW_Y(Pin->Y),
773
 
                        &Outline[Pin->Thickness + Pin->Clearance][0]);
774
 
        }
775
 
        else
776
 
        {
777
 
                XSetLineAttributes(Dpy, Output.bgGC,
778
 
                        TO_SCREEN(Pin->Thickness + Pin->Clearance),
779
 
                        LineSolid, CapRound, JoinRound);
780
 
                XDrawLine(Dpy, DrawingWindow, Output.bgGC, TO_DRAW_X(Pin->X),
781
 
                        TO_DRAW_Y(Pin->Y), TO_DRAW_X(Pin->X), TO_DRAW_Y(Pin->Y));
782
 
        }
783
 
           /* draw all the thermal(s) */
784
 
        for (i = MAX_LAYER; i; i--)
785
 
        {
786
 
                layer = LAYER_ON_STACK(i-1);
787
 
                if (!layer->On)
788
 
                        continue;
789
 
                ThermLayerFlag = L0THERMFLAG << GetLayerNumber(PCB->Data, layer);
790
 
                if (TEST_FLAG(ThermLayerFlag, Pin))
 
1239
  int ThermLayerFlag;
 
1240
  LayerTypePtr layer;
 
1241
  Cardinal i;
 
1242
  BDimension half = (Pin->Thickness + Pin->Clearance) / 2;
 
1243
 
 
1244
  if (Gathering)
 
1245
    {
 
1246
      AddPart (Pin, False);
 
1247
      return;
 
1248
    }
 
1249
  /* Clear the area around the pin */
 
1250
  if (TEST_FLAG (SQUAREFLAG, Pin))
 
1251
    {
 
1252
      XFillRectangle (Dpy, DrawingWindow, Output.bgGC,
 
1253
                      TO_DRAW_X (Pin->X - TO_SCREEN_SIGN_X (half)),
 
1254
                      TO_DRAW_Y (Pin->Y - TO_SCREEN_SIGN_Y (half)),
 
1255
                      TO_SCREEN (Pin->Thickness + Pin->Clearance),
 
1256
                      TO_SCREEN (Pin->Thickness + Pin->Clearance));
 
1257
    }
 
1258
  else if (TEST_FLAG (OCTAGONFLAG, Pin))
 
1259
    {
 
1260
      XSetLineAttributes (Dpy, Output.bgGC,
 
1261
                          TO_SCREEN ((Pin->Thickness + Pin->Clearance -
 
1262
                                      Pin->DrillingHole) / 2), LineSolid,
 
1263
                          CapRound, JoinRound);
 
1264
 
 
1265
      /* transform X11 specific coord system */
 
1266
      DrawSpecialPolygon (DrawingWindow, Output.bgGC,
 
1267
                          TO_DRAW_X (Pin->X), TO_DRAW_Y (Pin->Y),
 
1268
                          Pin->Thickness + Pin->Clearance);
 
1269
    }
 
1270
  else
 
1271
    {
 
1272
      XSetLineAttributes (Dpy, Output.bgGC,
 
1273
                          TO_SCREEN (Pin->Thickness + Pin->Clearance),
 
1274
                          LineSolid, CapRound, JoinRound);
 
1275
      XDrawCLine (Dpy, DrawingWindow, Output.bgGC, Pin->X,
 
1276
                  Pin->Y, Pin->X, Pin->Y);
 
1277
    }
 
1278
  /* draw all the thermal(s) */
 
1279
  for (i = MAX_LAYER; i; i--)
 
1280
    {
 
1281
      layer = LAYER_ON_STACK (i - 1);
 
1282
      if (!layer->On)
 
1283
        continue;
 
1284
      ThermLayerFlag =
 
1285
        (L0THERMFLAG | L0PIPFLAG) << GetLayerNumber (PCB->Data, layer);
 
1286
      if (TEST_FLAGS (ThermLayerFlag, Pin))
 
1287
        {
 
1288
          if (!Erasing)
 
1289
            {
 
1290
              if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Pin))
791
1291
                {
792
 
                        if (!Erasing)
793
 
                        {
794
 
                                if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Pin))
795
 
                                {
796
 
                                        if (TEST_FLAG(SELECTEDFLAG, Pin))
797
 
                                                XSetForeground(Dpy, Output.fgGC, layer->SelectedColor);
798
 
                                        else
799
 
                                                XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
800
 
                                }
801
 
                                else
802
 
                                        XSetForeground(Dpy, Output.fgGC, layer->Color);
803
 
                        }
804
 
                        if (TEST_FLAG(SQUAREFLAG, Pin))
805
 
                        {
806
 
                                XSetLineAttributes(Dpy, Output.fgGC, TO_SCREEN(Pin->Clearance/2),
807
 
                                        LineSolid, CapRound, JoinRound);
808
 
                                
809
 
                                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
810
 
                                        TO_DRAW_X(Pin->X) - TO_SCREEN(half),
811
 
                                        TO_DRAW_Y(Pin->Y) - TO_SCREEN(half),
812
 
                                        TO_DRAW_X(Pin->X) + TO_SCREEN(half),
813
 
                                        TO_DRAW_Y(Pin->Y) + TO_SCREEN(half));
814
 
                                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
815
 
                                        TO_DRAW_X(Pin->X) - TO_SCREEN(half),
816
 
                                        TO_DRAW_Y(Pin->Y) + TO_SCREEN(half),
817
 
                                        TO_DRAW_X(Pin->X) + TO_SCREEN(half),
818
 
                                        TO_DRAW_Y(Pin->Y) - TO_SCREEN(half));
819
 
                        }
820
 
                        else
821
 
                        {
822
 
                                XSetLineAttributes(Dpy, Output.fgGC, TO_SCREEN(Pin->Clearance/2),
823
 
                                        LineSolid, CapRound, JoinRound);
824
 
                                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
825
 
                                        TO_DRAW_X(Pin->X) - halfs,
826
 
                                        TO_DRAW_Y(Pin->Y) - halfs,
827
 
                                        TO_DRAW_X(Pin->X) + halfs,
828
 
                                        TO_DRAW_Y(Pin->Y) + halfs);
829
 
                                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
830
 
                                        TO_DRAW_X(Pin->X) - halfs,
831
 
                                        TO_DRAW_Y(Pin->Y) + halfs,
832
 
                                        TO_DRAW_X(Pin->X) + halfs,
833
 
                                        TO_DRAW_Y(Pin->Y) - halfs);
834
 
                        }
 
1292
                  if (TEST_FLAG (SELECTEDFLAG, Pin))
 
1293
                    XSetForeground (Dpy, Output.fgGC, layer->SelectedColor);
 
1294
                  else
 
1295
                    XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
835
1296
                }
836
 
        }
837
 
        if ((!TEST_FLAG(PINFLAG, Pin) && !PCB->ViaOn) || (TEST_FLAG(PINFLAG, Pin) && !PCB->PinOn))
838
 
                return;
839
 
                /* now draw the pin or via as appropriate */
840
 
        switch (Type)
841
 
        {
842
 
                case VIA_TYPE:
843
 
                case PIN_TYPE:
844
 
                        SetPVColor(Pin, Type);
845
 
                        DrawPinOrViaLowLevel(Pin, True);
846
 
                        break;
847
 
                case NO_TYPE:
848
 
                default:
849
 
                        break;
850
 
        }
851
 
}
 
1297
              else
 
1298
                XSetForeground (Dpy, Output.fgGC, layer->Color);
 
1299
            }
 
1300
          if (TEST_FLAG (SQUAREFLAG, Pin))
 
1301
            {
 
1302
              XSetLineAttributes (Dpy, Output.fgGC,
 
1303
                                  TEST_FLAG (THINDRAWFLAG,
 
1304
                                             PCB) ? 1 : TO_SCREEN (Pin->
 
1305
                                                                   Clearance /
 
1306
                                                                   2),
 
1307
                                  LineSolid, CapRound, JoinRound);
 
1308
 
 
1309
              XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Pin->X - half,
 
1310
                          Pin->Y - half, Pin->X + half, Pin->Y + half);
 
1311
              XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Pin->X - half,
 
1312
                          Pin->Y + half, Pin->X + half, Pin->Y - half);
 
1313
            }
 
1314
          else
 
1315
            {
 
1316
              BDimension halfs = (half * M_SQRT1_2 + 1);
 
1317
 
 
1318
              XSetLineAttributes (Dpy, Output.fgGC,
 
1319
                                  TO_SCREEN (Pin->Clearance / 2), LineSolid,
 
1320
                                  CapRound, JoinRound);
 
1321
              XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Pin->X - halfs,
 
1322
                          Pin->Y - halfs, Pin->X + halfs, Pin->Y + halfs);
 
1323
              XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Pin->X - halfs,
 
1324
                          Pin->Y + halfs, Pin->X + halfs, Pin->Y - halfs);
 
1325
            }
 
1326
        }
 
1327
    }
 
1328
  if ((!TEST_FLAG (PINFLAG, Pin) && !PCB->ViaOn)
 
1329
      || (TEST_FLAG (PINFLAG, Pin) && !PCB->PinOn))
 
1330
    return;
 
1331
  /* now draw the pin or via as appropriate */
 
1332
  switch (Type)
 
1333
    {
 
1334
    case VIA_TYPE:
 
1335
    case PIN_TYPE:
 
1336
      SetPVColor (Pin, Type);
 
1337
      DrawPinOrViaLowLevel (Pin, True);
 
1338
      break;
 
1339
    case NO_TYPE:
 
1340
    default:
 
1341
      break;
 
1342
    }
 
1343
}
 
1344
 
 
1345
/* virtical text handling provided by Martin Devera with fixes by harry eaton */
 
1346
 
 
1347
/* draw vertical text; xywh is bounding, de is text's descend used for
 
1348
   positioning */
 
1349
static void
 
1350
DrawVText (int x, int y, int w, int h, int de, char *str)
 
1351
{
 
1352
  Pixmap pm;
 
1353
  GC gc;
 
1354
  XImage *im;
 
1355
  int i, j;
 
1356
 
 
1357
  if (strlen (str) == 0)
 
1358
    return;
 
1359
 
 
1360
  pm = XCreatePixmap (Dpy, DrawingWindow, w, h, 1);
 
1361
  gc = XCreateGC (Dpy, pm, 0, 0);
 
1362
 
 
1363
  /* draw into pixmap */
 
1364
  XFillRectangle (Dpy, pm, gc, 0, 0, w, h);
 
1365
  XSetForeground (Dpy, gc, 1);
 
1366
  XSetFont (Dpy, gc, Settings.PinoutFont[ZoomValue]->fid);
 
1367
  XDrawString (Dpy, pm, gc, 0, h - de, str,
 
1368
               MIN (Settings.PinoutNameLength, strlen (str)));
 
1369
 
 
1370
  im = XGetImage (Dpy, pm, 0, 0, w, h, 1, XYPixmap);
 
1371
 
 
1372
  /* draw Transpose(im) but only dark pixels; TODO: find a faster way */
 
1373
  for (i = 0; i < w; i++)
 
1374
    for (j = 0; j < h; j++)
 
1375
      if (XGetPixel (im, i, j))
 
1376
        XDrawPoint (Dpy, DrawingWindow, Output.fgGC, x + j, y + w - i - 1);
 
1377
  XFreeGC (Dpy, gc);
 
1378
  XFreePixmap (Dpy, pm);
 
1379
}
 
1380
 
852
1381
 
853
1382
/* ---------------------------------------------------------------------------
854
1383
 * lowlevel drawing routine for pin and via names
855
1384
 */
856
 
static void DrawPinOrViaNameLowLevel(PinTypePtr Ptr)
 
1385
static void
 
1386
DrawPinOrViaNameLowLevel (PinTypePtr Ptr)
857
1387
{
858
 
        int direction, ascent, descent;
859
 
        XCharStruct overall;
860
 
 
861
 
        if (Gathering)
862
 
        {
863
 
                UpdateRect.x = TO_DRAW_X(Ptr->X -Ptr->Thickness/2 +Settings.PinoutTextOffsetX);
864
 
                UpdateRect.y = TO_DRAW_Y(Ptr->Y -Ptr->Thickness/2 +Settings.PinoutTextOffsetY);
865
 
                XTextExtents(Settings.PinoutFont[MAX(0,PCB->Zoom)], EMPTY(Ptr->Name),
866
 
                        MIN(Settings.PinoutNameLength, strlen(EMPTY(Ptr->Name))),
867
 
                        &direction, &ascent, &descent, &overall);
868
 
                UpdateRect.x += overall.lbearing;
869
 
                UpdateRect.width = overall.width;
870
 
                UpdateRect.y -= overall.ascent;
871
 
                UpdateRect.height = ascent + descent;
872
 
                AddPart();
873
 
                return;
874
 
        }
875
 
        UpdateRect.x = TO_DRAW_X(Ptr->X -Ptr->Thickness/2 +Settings.PinoutTextOffsetX);
876
 
        UpdateRect.y = TO_DRAW_Y(Ptr->Y -Ptr->Thickness/2 +Settings.PinoutTextOffsetY);
877
 
        XDrawString(Dpy, DrawingWindow, Output.fgGC,
878
 
                UpdateRect.x, UpdateRect.y, EMPTY(Ptr->Name),
879
 
                MIN(Settings.PinoutNameLength, strlen(EMPTY(Ptr->Name))));
 
1388
  int direction, ascent, descent;
 
1389
  XCharStruct overall;
 
1390
  char *name;
 
1391
  BoxType box;
 
1392
 
 
1393
  name = EMPTY (TEST_FLAG (SHOWNUMBERFLAG, PCB) ? Ptr->Number : Ptr->Name);
 
1394
  XTextExtents (Settings.PinoutFont[ZoomValue],
 
1395
                name, MIN (Settings.PinoutNameLength, strlen (name)),
 
1396
                &direction, &ascent, &descent, &overall);
 
1397
  if (TEST_FLAG (EDGE2FLAG, Ptr))
 
1398
    {
 
1399
      box.X1 = TO_DRAW_X (Ptr->X) - ascent + descent;
 
1400
      box.Y1 =
 
1401
        TO_DRAW_Y (Ptr->Y + Ptr->Thickness / 2 + Settings.PinoutTextOffsetY)
 
1402
        + overall.lbearing;
 
1403
    }
 
1404
  else
 
1405
    {
 
1406
      box.X1 =
 
1407
        TO_DRAW_X (Ptr->X + Ptr->Thickness / 2 + Settings.PinoutTextOffsetX);
 
1408
      box.Y1 = TO_DRAW_Y (Ptr->Y) + overall.ascent / 2;
 
1409
    }
 
1410
  if (Gathering)
 
1411
    {
 
1412
      if (!TEST_FLAG (EDGE2FLAG, Ptr))
 
1413
        {
 
1414
          box.X1 += overall.lbearing;
 
1415
          box.Y1 -= overall.ascent;
 
1416
          box.X2 = box.X1 + overall.width;
 
1417
          box.Y2 = box.Y1 + ascent + descent;
 
1418
        }
 
1419
      else
 
1420
        {
 
1421
          box.X2 = box.X1 + ascent + descent;;
 
1422
          box.Y2 = box.Y1 + overall.width;
 
1423
        }
 
1424
      AddPart (&box, True);
 
1425
      return;
 
1426
    }
 
1427
  if (TEST_FLAG (EDGE2FLAG, Ptr))
 
1428
    DrawVText (box.X1, box.Y1, overall.width,
 
1429
               ascent + descent, descent, name);
 
1430
  else
 
1431
    XDrawString (Dpy, DrawingWindow, Output.fgGC,
 
1432
                 box.X1, box.Y1,
 
1433
                 name, MIN (Settings.PinoutNameLength, strlen (name)));
 
1434
 
880
1435
}
881
1436
 
882
1437
/* ---------------------------------------------------------------------------
883
1438
 * lowlevel drawing routine for pads
884
1439
 */
885
 
static void DrawPadLowLevel(PadTypePtr Pad)
 
1440
 
 
1441
static void
 
1442
DrawPadLowLevel (PadTypePtr Pad)
886
1443
{
887
 
        if (Gathering)
888
 
        {
889
 
                Dimension size = Pad->Thickness + Pad->Clearance;
890
 
 
891
 
                UpdateRect.x = MIN(TO_DRAW_X(Pad->Point1.X), TO_DRAW_X(Pad->Point2.X));
892
 
                UpdateRect.x -= TO_SCREEN(size/2);
893
 
                UpdateRect.y = MIN(TO_DRAW_Y(Pad->Point1.Y), TO_DRAW_Y(Pad->Point2.Y));
894
 
                UpdateRect.y -= TO_SCREEN(size/2);
895
 
                UpdateRect.width = TO_SCREEN(abs(Pad->Point1.X - Pad->Point2.X) + size);
896
 
                UpdateRect.height = TO_SCREEN(abs(Pad->Point1.Y - Pad->Point2.Y) + size);
897
 
                AddPart();
898
 
                return;
899
 
        }
900
 
 
901
 
        XSetLineAttributes(Dpy, Output.fgGC,
902
 
                TO_SCREEN(Pad->Thickness), LineSolid, 
903
 
                          TEST_FLAG(SQUAREFLAG, Pad) ? CapProjecting : CapRound,
 
1444
  if (Gathering)
 
1445
    {
 
1446
      AddPart (Pad, False);
 
1447
      return;
 
1448
    }
 
1449
 
 
1450
  if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1451
    {
 
1452
      int x1, y1, x2, y2, t, t2;
 
1453
      t = Pad->Thickness / 2;
 
1454
      t2 = Pad->Thickness - t;
 
1455
      x1 = Pad->Point1.X;
 
1456
      y1 = Pad->Point1.Y;
 
1457
      x2 = Pad->Point2.X;
 
1458
      y2 = Pad->Point2.Y;
 
1459
      if (x1 > x2 || y1 > y2)
 
1460
        {
 
1461
          x1 ^= x2;
 
1462
          x2 ^= x1;
 
1463
          x1 ^= x2;
 
1464
          y1 ^= y2;
 
1465
          y2 ^= y1;
 
1466
          y1 ^= y2;
 
1467
        }
 
1468
      XSetLineAttributes (Dpy, Output.fgGC,
 
1469
                          1, LineSolid, CapRound, JoinRound);
 
1470
      if (TEST_FLAG (SQUAREFLAG, Pad))
 
1471
        {
 
1472
          x1 -= t;
 
1473
          y1 -= t;
 
1474
          x2 += t2;
 
1475
          y2 += t2;
 
1476
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x1, y1, x1, y2);
 
1477
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x1, y2, x2, y2);
 
1478
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x2, y2, x2, y1);
 
1479
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x2, y1, x1, y1);
 
1480
        }
 
1481
      else if (x1 == x2)
 
1482
        {
 
1483
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x1 - t, y1, x2 - t,
 
1484
                      y2);
 
1485
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x1 + t2, y1, x2 + t2,
 
1486
                      y2);
 
1487
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, x1, y1, Pad->Thickness,
 
1488
                     Pad->Thickness, 0, 180 * 64);
 
1489
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, x2, y2, Pad->Thickness,
 
1490
                     Pad->Thickness, 180 * 64, 180 * 64);
 
1491
        }
 
1492
      else
 
1493
        {
 
1494
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x1, y1 - t, x2,
 
1495
                      y2 - t);
 
1496
          XDrawCLine (Dpy, DrawingWindow, Output.fgGC, x1, y1 + t2, x2,
 
1497
                      y2 + t2);
 
1498
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, x1, y1, Pad->Thickness,
 
1499
                     Pad->Thickness, 90 * 64, 180 * 64);
 
1500
          XDrawCArc (Dpy, DrawingWindow, Output.fgGC, x2, y2, Pad->Thickness,
 
1501
                     Pad->Thickness, 270 * 64, 180 * 64);
 
1502
        }
 
1503
    }
 
1504
  else
 
1505
    {
 
1506
 
 
1507
      XSetLineAttributes (Dpy, Output.fgGC,
 
1508
                          TO_SCREEN (Pad->Thickness), LineSolid,
 
1509
                          TEST_FLAG (SQUAREFLAG,
 
1510
                                     Pad) ? CapProjecting : CapRound,
904
1511
                          JoinRound);
905
 
        XDrawLine(Dpy, DrawingWindow, Output.fgGC,
906
 
                TO_DRAW_X(Pad->Point1.X), TO_DRAW_Y(Pad->Point1.Y),
907
 
                TO_DRAW_X(Pad->Point2.X), TO_DRAW_Y(Pad->Point2.Y));
 
1512
      XDrawCLine (Dpy, DrawingWindow, Output.fgGC, Pad->Point1.X,
 
1513
                  Pad->Point1.Y, Pad->Point2.X, Pad->Point2.Y);
 
1514
    }
908
1515
}
909
1516
 
910
1517
/* ---------------------------------------------------------------------------
911
1518
 * lowlevel drawing routine for pad names
912
1519
 */
913
 
static void DrawPadNameLowLevel(PadTypePtr Pad)
 
1520
 
 
1521
static void
 
1522
DrawPadNameLowLevel (PadTypePtr Pad)
914
1523
{
915
 
        int direction, ascent, descent;
916
 
        XCharStruct overall;
917
 
 
918
 
 
919
 
        if (Gathering)
920
 
        {
921
 
                UpdateRect.x = TO_DRAW_X((Pad->Point1.X + Pad->Point2.X)/2 + Settings.PinoutTextOffsetX);
922
 
                UpdateRect.y = TO_DRAW_Y((Pad->Point1.Y + Pad->Point2.Y)/2 + Settings.PinoutTextOffsetY);
923
 
                XTextExtents(Settings.PinoutFont[MAX(0,PCB->Zoom)], EMPTY(Pad->Name),
924
 
                        MIN(Settings.PinoutNameLength, strlen(EMPTY(Pad->Name))),
925
 
                        &direction, &ascent, &descent, &overall);
926
 
                UpdateRect.x += overall.lbearing;
927
 
                UpdateRect.width = overall.width;
928
 
                UpdateRect.y -= overall.ascent;
929
 
                UpdateRect.height = ascent + descent;
930
 
                AddPart();
931
 
                return;
932
 
        }
933
 
 
934
 
        UpdateRect.x = TO_DRAW_X((Pad->Point1.X + Pad->Point2.X)/2 + Settings.PinoutTextOffsetX);
935
 
        UpdateRect.y = TO_DRAW_Y((Pad->Point1.Y + Pad->Point2.Y)/2 + Settings.PinoutTextOffsetY);
936
 
        XDrawString(Dpy, DrawingWindow, Output.fgGC,
937
 
                UpdateRect.x, UpdateRect.y,
938
 
                EMPTY(Pad->Name),
939
 
                MIN(Settings.PinoutNameLength, strlen(EMPTY(Pad->Name))));
 
1524
  int direction, ascent, descent, vert;
 
1525
  XCharStruct overall;
 
1526
  char *name;
 
1527
  BoxType box;
 
1528
 
 
1529
  name = EMPTY (TEST_FLAG (SHOWNUMBERFLAG, PCB) ? Pad->Number : Pad->Name);
 
1530
 
 
1531
  XTextExtents (Settings.PinoutFont[ZoomValue], name,
 
1532
                MIN (Settings.PinoutNameLength, strlen (name)),
 
1533
                &direction, &ascent, &descent, &overall);
 
1534
  /* should text be vertical ? */
 
1535
  vert = (Pad->Point1.X == Pad->Point2.X);
 
1536
  if (vert)
 
1537
    {
 
1538
      box.X1 = TO_DRAW_X (Pad->Point1.X) - ascent + descent;
 
1539
      box.Y1 =
 
1540
        TO_DRAW_Y (MAX (Pad->Point1.Y, Pad->Point2.Y) + Pad->Thickness / 2);
 
1541
    }
 
1542
  else
 
1543
    {
 
1544
      box.X1 =
 
1545
        TO_DRAW_X (MAX (Pad->Point1.X, Pad->Point2.X) + Pad->Thickness / 2);
 
1546
      box.Y1 = TO_DRAW_Y (Pad->Point1.Y) + overall.ascent / 2;
 
1547
    }
 
1548
 
 
1549
  if (vert)
 
1550
    box.Y1 += overall.lbearing + TO_SCREEN (Settings.PinoutTextOffsetY);
 
1551
  else
 
1552
    box.X1 += TO_SCREEN (Settings.PinoutTextOffsetX);
 
1553
 
 
1554
  if (Gathering)
 
1555
    {
 
1556
      if (vert)
 
1557
        {
 
1558
          box.X2 = box.X1 + ascent + descent;
 
1559
          box.Y2 = box.Y1 + overall.width;
 
1560
        }
 
1561
      else
 
1562
        {
 
1563
          box.X1 += overall.lbearing;
 
1564
          box.Y1 -= ascent;
 
1565
          box.X2 = box.X1 + overall.width;
 
1566
          box.Y2 = box.Y1 + ascent + descent;
 
1567
        }
 
1568
      AddPart (&box, True);
 
1569
      return;
 
1570
    }
 
1571
 
 
1572
  if (vert)
 
1573
    DrawVText (box.X1, box.Y1, overall.width,
 
1574
               ascent + descent, descent, name);
 
1575
  else
 
1576
    XDrawString (Dpy, DrawingWindow, Output.fgGC,
 
1577
                 box.X1, box.Y1,
 
1578
                 name, MIN (Settings.PinoutNameLength, strlen (name)));
940
1579
}
941
1580
 
942
1581
/* ---------------------------------------------------------------------------
943
1582
 * clearance for pads
944
1583
 */
945
 
static void ClearPad(PadTypePtr Pad)
 
1584
static void
 
1585
ClearPad (PadTypePtr Pad, Boolean mask)
946
1586
{
947
 
        XSetLineAttributes(Dpy, Output.pmGC,
948
 
                TO_SCREEN(Pad->Thickness + Pad->Clearance), LineSolid, 
949
 
                          TEST_FLAG(SQUAREFLAG, Pad) ? CapProjecting : CapRound,
950
 
                          JoinRound);
951
 
        XDrawLine(Dpy, Offmask, Output.pmGC,
952
 
                TO_MASK_X(Pad->Point1.X), TO_MASK_Y(Pad->Point1.Y),
953
 
                TO_MASK_X(Pad->Point2.X), TO_MASK_Y(Pad->Point2.Y));
 
1587
  XSetLineAttributes (Dpy, Output.pmGC,
 
1588
                      TO_SCREEN (mask ? Pad->Mask : Pad->Thickness +
 
1589
                                 Pad->Clearance), LineSolid,
 
1590
                      TEST_FLAG (SQUAREFLAG, Pad) ? CapProjecting : CapRound,
 
1591
                      JoinRound);
 
1592
  XDrawCLine (Dpy, Offmask, Output.pmGC, Pad->Point1.X, Pad->Point1.Y,
 
1593
              Pad->Point2.X, Pad->Point2.Y);
954
1594
}
955
1595
 
956
1596
/* ---------------------------------------------------------------------------
957
1597
 * clearance for lines
958
1598
 */
959
 
static void ClearLine(LineTypePtr Line)
 
1599
static void
 
1600
ClearLine (LineTypePtr Line)
960
1601
{
961
 
        XSetLineAttributes(Dpy, Output.pmGC,
962
 
                TO_SCREEN(Line->Clearance + Line->Thickness), LineSolid, CapRound, JoinRound);
963
 
        XDrawLine(Dpy, Offmask, Output.pmGC,
964
 
                TO_MASK_X(Line->Point1.X), TO_MASK_Y(Line->Point1.Y),
965
 
                TO_MASK_X(Line->Point2.X), TO_MASK_Y(Line->Point2.Y));
 
1602
  XSetLineAttributes (Dpy, Output.pmGC,
 
1603
                      TO_SCREEN (Line->Clearance + Line->Thickness),
 
1604
                      LineSolid, CapRound, JoinRound);
 
1605
  XDrawCLine (Dpy, Offmask, Output.pmGC, Line->Point1.X, Line->Point1.Y,
 
1606
              Line->Point2.X, Line->Point2.Y);
966
1607
}
967
1608
 
968
1609
/* ---------------------------------------------------------------------------
969
1610
 * clearance for arcs 
970
1611
 */
971
 
static void ClearArc(ArcTypePtr Arc)
 
1612
static void
 
1613
ClearArc (ArcTypePtr Arc)
972
1614
{
973
 
        XSetLineAttributes(Dpy, Output.pmGC,
974
 
                TO_SCREEN(Arc->Thickness + Arc->Clearance),
975
 
                        LineSolid, CapRound, JoinRound);
976
 
        XDrawArc(Dpy, Offmask, Output.pmGC,
977
 
                TO_MASK_X(Arc->X) -TO_SCREEN(Arc->Width),
978
 
                TO_MASK_Y(Arc->Y) -TO_SCREEN(Arc->Height),
979
 
                TO_SCREEN(2*Arc->Width),
980
 
                TO_SCREEN(2*Arc->Height),
981
 
                (TO_SCREEN_ANGLE(Arc->StartAngle) -180) *64,
982
 
                TO_SCREEN_DELTA(Arc->Delta) *64);
 
1615
  XSetLineAttributes (Dpy, Output.pmGC,
 
1616
                      TO_SCREEN (Arc->Thickness + Arc->Clearance),
 
1617
                      LineSolid, CapRound, JoinRound);
 
1618
  XDrawCArc (Dpy, Offmask, Output.pmGC, Arc->X, Arc->Y,
 
1619
             2 * Arc->Width, 2 * Arc->Height,
 
1620
             (Arc->StartAngle - 180) * 64, Arc->Delta * 64);
983
1621
}
984
1622
 
985
1623
/* ---------------------------------------------------------------------------
986
1624
 * lowlevel drawing routine for lines
987
1625
 */
988
 
static void DrawLineLowLevel(LineTypePtr Line, Boolean HaveGathered)
 
1626
static void
 
1627
DrawLineLowLevel (LineTypePtr Line, Boolean HaveGathered)
989
1628
{
990
 
        if (Gathering && !HaveGathered)
991
 
        {
992
 
                Dimension wide = Line->Thickness;
993
 
 
994
 
                if (TEST_FLAG(CLEARLINEFLAG, Line))
995
 
                        wide += Line->Clearance;
996
 
                UpdateRect.x = MIN(TO_DRAW_X(Line->Point1.X), TO_DRAW_X(Line->Point2.X));
997
 
                UpdateRect.x -= TO_SCREEN(wide/2);
998
 
                UpdateRect.y = MIN(TO_DRAW_Y(Line->Point1.Y), TO_DRAW_Y(Line->Point2.Y));
999
 
                UpdateRect.y -= TO_SCREEN(wide/2);
1000
 
                UpdateRect.width = TO_SCREEN(abs(Line->Point1.X - Line->Point2.X) + wide);
1001
 
                UpdateRect.height = TO_SCREEN(abs(Line->Point1.Y - Line->Point2.Y) + wide);
1002
 
                if (UpdateRect.width == 0)
1003
 
                        UpdateRect.width = 1;
1004
 
                if (UpdateRect.height == 0)
1005
 
                        UpdateRect.height = 1;
1006
 
                AddPart();
1007
 
                return;
1008
 
        }
1009
 
 
1010
 
        XSetLineAttributes(Dpy, Output.fgGC,
1011
 
                TO_SCREEN(Line->Thickness), LineSolid, CapRound, JoinRound);
1012
 
        if (TEST_FLAG(RATFLAG, Line))
1013
 
        {
1014
 
                XSetStipple(Dpy, Output.fgGC, Stipples[0]);
1015
 
                XSetFillStyle(Dpy, Output.fgGC, FillStippled);
1016
 
                XDrawLine(Dpy, DrawingWindow, Output.fgGC,
1017
 
                        TO_DRAW_X(Line->Point1.X), TO_DRAW_Y(Line->Point1.Y),
1018
 
                        TO_DRAW_X(Line->Point2.X), TO_DRAW_Y(Line->Point2.Y));
1019
 
                XSetFillStyle(Dpy, Output.fgGC, FillSolid);
1020
 
        }
1021
 
        else
1022
 
        XDrawLine(Dpy, DrawingWindow, Output.fgGC,
1023
 
                TO_DRAW_X(Line->Point1.X), TO_DRAW_Y(Line->Point1.Y),
1024
 
                TO_DRAW_X(Line->Point2.X), TO_DRAW_Y(Line->Point2.Y));
 
1629
  if (Gathering && !HaveGathered)
 
1630
    {
 
1631
      AddPart (Line, False);
 
1632
      return;
 
1633
    }
 
1634
 
 
1635
  if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1636
    XSetLineAttributes (Dpy, Output.fgGC, 1, LineSolid, CapRound, JoinRound);
 
1637
  else
 
1638
    XSetLineAttributes (Dpy, Output.fgGC,
 
1639
                        TO_SCREEN (Line->Thickness), LineSolid, CapRound,
 
1640
                        JoinRound);
 
1641
 
 
1642
  if (TEST_FLAG (RATFLAG, Line))
 
1643
    {
 
1644
      XSetStipple (Dpy, Output.fgGC, Stipples[0]);
 
1645
      XSetFillStyle (Dpy, Output.fgGC, FillStippled);
 
1646
      XDrawCLine (Dpy, DrawingWindow, Output.fgGC,
 
1647
                  Line->Point1.X, Line->Point1.Y,
 
1648
                  Line->Point2.X, Line->Point2.Y);
 
1649
      XSetFillStyle (Dpy, Output.fgGC, FillSolid);
 
1650
    }
 
1651
  else
 
1652
    XDrawCLine (Dpy, DrawingWindow, Output.fgGC,
 
1653
                Line->Point1.X, Line->Point1.Y,
 
1654
                Line->Point2.X, Line->Point2.Y);
1025
1655
}
1026
1656
 
1027
1657
/* ---------------------------------------------------------------------------
1028
1658
 * lowlevel drawing routine for text objects
1029
1659
 */
1030
 
static void DrawTextLowLevel(TextTypePtr Text)
 
1660
static void
 
1661
DrawTextLowLevel (TextTypePtr Text)
1031
1662
{
1032
 
        Position        x = 0;
1033
 
        int             maxthick = 0;
1034
 
        unsigned char   *string = (unsigned char *) Text->TextString;
1035
 
        Cardinal        n;
1036
 
        FontTypePtr     font = &PCB->Font;
1037
 
 
1038
 
        if (Gathering)
1039
 
        {
1040
 
                while (string && *string)
1041
 
                {
1042
 
                                /* draw lines if symbol is valid and data is present */
1043
 
                        if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
1044
 
                        {
1045
 
                                LineTypePtr     line = font->Symbol[*string].Line;
1046
 
 
1047
 
                                for (n = font->Symbol[*string].LineN; n; n--, line++)
1048
 
                                        if (line->Thickness > maxthick)
1049
 
                                                maxthick = line->Thickness;
1050
 
                        }
1051
 
                        string++;
1052
 
                }
1053
 
                maxthick *= Text->Scale/100;
1054
 
                UpdateRect.x = MIN(TO_DRAW_X(Text->BoundingBox.X1), TO_DRAW_X(Text->BoundingBox.X2));
1055
 
                UpdateRect.y = MIN(TO_DRAW_Y(Text->BoundingBox.Y1), TO_DRAW_Y(Text->BoundingBox.Y2));
1056
 
                UpdateRect.x -= TO_SCREEN(maxthick);
1057
 
                UpdateRect.y -= TO_SCREEN(maxthick);
1058
 
                UpdateRect.width = TO_SCREEN(abs(Text->BoundingBox.X2 - Text->BoundingBox.X1) + 2 * maxthick);
1059
 
                UpdateRect.height = TO_SCREEN(abs(Text->BoundingBox.Y2 - Text->BoundingBox.Y1) + 2 * maxthick);
1060
 
                AddPart();
1061
 
                return;
1062
 
        }
1063
 
 
1064
 
        while (string && *string)
1065
 
        {
1066
 
                        /* draw lines if symbol is valid and data is present */
1067
 
                if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
1068
 
                {
1069
 
                        LineTypePtr     line = font->Symbol[*string].Line;
1070
 
                        LineType        newline;
1071
 
 
1072
 
                        for (n = font->Symbol[*string].LineN; n; n--, line++)
1073
 
                        {
1074
 
                                        /* create one line, scale, move, rotate and swap it */
1075
 
                                newline = *line;
1076
 
                                newline.Point1.X = (newline.Point1.X +x) *Text->Scale /100;
1077
 
                                newline.Point1.Y = newline.Point1.Y      *Text->Scale /100;
1078
 
                                newline.Point2.X = (newline.Point2.X +x) *Text->Scale /100;
1079
 
                                newline.Point2.Y = newline.Point2.Y      *Text->Scale /100;
1080
 
                                newline.Thickness = newline.Thickness *Text->Scale /100;
1081
 
                                if (newline.Thickness > maxthick)
1082
 
                                        maxthick = newline.Thickness;
1083
 
 
1084
 
                                RotateLineLowLevel(&newline, 0, 0, Text->Direction);
1085
 
 
1086
 
                                        /* the labels of SMD objects on the bottom
1087
 
                                         * side haven't been swapped yet, only their offset
1088
 
                                         */
1089
 
                                if (TEST_FLAG(ONSOLDERFLAG, Text))
1090
 
                                {
1091
 
                                        newline.Point1.X = SWAP_SIGN_X(newline.Point1.X);
1092
 
                                        newline.Point1.Y = SWAP_SIGN_Y(newline.Point1.Y);
1093
 
                                        newline.Point2.X = SWAP_SIGN_X(newline.Point2.X);
1094
 
                                        newline.Point2.Y = SWAP_SIGN_Y(newline.Point2.Y);
1095
 
                                }
1096
 
                                        /* add offset and draw line */
1097
 
                                newline.Point1.X += Text->X;
1098
 
                                newline.Point1.Y += Text->Y;
1099
 
                                newline.Point2.X += Text->X;
1100
 
                                newline.Point2.Y += Text->Y;
1101
 
                                DrawLineLowLevel(&newline, True);
1102
 
                        }
1103
 
 
1104
 
                                /* move on to next cursor position */
1105
 
                        x += (font->Symbol[*string].Width +font->Symbol[*string].Delta);
1106
 
                }
1107
 
                else
1108
 
                {
1109
 
                                /* the default symbol is a filled box */
1110
 
                        BoxType         defaultsymbol = PCB->Font.DefaultSymbol;
1111
 
                        Position        size = (defaultsymbol.X2 -defaultsymbol.X1) *6/5;
1112
 
 
1113
 
                        defaultsymbol.X1 = (defaultsymbol.X1 +x) *Text->Scale /100;
1114
 
                        defaultsymbol.Y1 = defaultsymbol.Y1      *Text->Scale /100;
1115
 
                        defaultsymbol.X2 = (defaultsymbol.X2 +x) *Text->Scale /100;
1116
 
                        defaultsymbol.Y2 = defaultsymbol.Y2      *Text->Scale /100;
1117
 
 
1118
 
                        if (TEST_FLAG(ONSOLDERFLAG, Text))
1119
 
                        {
1120
 
                                defaultsymbol.X1 = TO_SCREEN_SIGN_X(defaultsymbol.X1);
1121
 
                                defaultsymbol.Y1 = TO_SCREEN_SIGN_Y(defaultsymbol.Y1);
1122
 
                                defaultsymbol.X2 = TO_SCREEN_SIGN_X(defaultsymbol.X2);
1123
 
                                defaultsymbol.Y2 = TO_SCREEN_SIGN_Y(defaultsymbol.Y2);
1124
 
                        }
1125
 
                        RotateBoxLowLevel(&defaultsymbol, 0, 0, Text->Direction);
1126
 
 
1127
 
                                /* add offset and draw box */
1128
 
                        defaultsymbol.X1 += Text->X;
1129
 
                        defaultsymbol.Y1 += Text->Y;
1130
 
                        defaultsymbol.X2 += Text->X;
1131
 
                        defaultsymbol.Y2 += Text->Y;
1132
 
                        XFillRectangle(Dpy, DrawingWindow, Output.fgGC,
1133
 
                                TO_DRAW_X(defaultsymbol.X1),
1134
 
                                TO_DRAW_Y(SWAP_IDENT ? defaultsymbol.Y2 : defaultsymbol.Y1),
1135
 
                                TO_SCREEN(abs(defaultsymbol.X2 -defaultsymbol.X1)),
1136
 
                                TO_SCREEN(abs(defaultsymbol.Y2 -defaultsymbol.Y1)));
1137
 
 
1138
 
                                /* move on to next cursor position */
1139
 
                        x += size;
1140
 
                }
1141
 
                string++;
1142
 
        }
 
1663
  LocationType x = 0;
 
1664
  unsigned char *string = (unsigned char *) Text->TextString;
 
1665
  Cardinal n;
 
1666
  FontTypePtr font = &PCB->Font;
 
1667
 
 
1668
  if (Gathering)
 
1669
    {
 
1670
      AddPart (Text, False);
 
1671
      return;
 
1672
    }
 
1673
 
 
1674
  while (string && *string)
 
1675
    {
 
1676
      /* draw lines if symbol is valid and data is present */
 
1677
      if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
 
1678
        {
 
1679
          LineTypePtr line = font->Symbol[*string].Line;
 
1680
          LineType newline;
 
1681
 
 
1682
          for (n = font->Symbol[*string].LineN; n; n--, line++)
 
1683
            {
 
1684
              /* create one line, scale, move, rotate and swap it */
 
1685
              newline = *line;
 
1686
              newline.Point1.X = (newline.Point1.X + x) * Text->Scale / 100;
 
1687
              newline.Point1.Y = newline.Point1.Y * Text->Scale / 100;
 
1688
              newline.Point2.X = (newline.Point2.X + x) * Text->Scale / 100;
 
1689
              newline.Point2.Y = newline.Point2.Y * Text->Scale / 100;
 
1690
              newline.Thickness = newline.Thickness * Text->Scale / 200;
 
1691
              if (newline.Thickness < 800)
 
1692
                newline.Thickness = 800;
 
1693
 
 
1694
              RotateLineLowLevel (&newline, 0, 0, Text->Direction);
 
1695
 
 
1696
              /* the labels of SMD objects on the bottom
 
1697
               * side haven't been swapped yet, only their offset
 
1698
               */
 
1699
              if (TEST_FLAG (ONSOLDERFLAG, Text))
 
1700
                {
 
1701
                  newline.Point1.X = SWAP_SIGN_X (newline.Point1.X);
 
1702
                  newline.Point1.Y = SWAP_SIGN_Y (newline.Point1.Y);
 
1703
                  newline.Point2.X = SWAP_SIGN_X (newline.Point2.X);
 
1704
                  newline.Point2.Y = SWAP_SIGN_Y (newline.Point2.Y);
 
1705
                }
 
1706
              /* add offset and draw line */
 
1707
              newline.Point1.X += Text->X;
 
1708
              newline.Point1.Y += Text->Y;
 
1709
              newline.Point2.X += Text->X;
 
1710
              newline.Point2.Y += Text->Y;
 
1711
              DrawLineLowLevel (&newline, True);
 
1712
            }
 
1713
 
 
1714
          /* move on to next cursor position */
 
1715
          x += (font->Symbol[*string].Width + font->Symbol[*string].Delta);
 
1716
        }
 
1717
      else
 
1718
        {
 
1719
          /* the default symbol is a filled box */
 
1720
          BoxType defaultsymbol = PCB->Font.DefaultSymbol;
 
1721
          LocationType size = (defaultsymbol.X2 - defaultsymbol.X1) * 6 / 5;
 
1722
 
 
1723
          defaultsymbol.X1 = (defaultsymbol.X1 + x) * Text->Scale / 100;
 
1724
          defaultsymbol.Y1 = defaultsymbol.Y1 * Text->Scale / 100;
 
1725
          defaultsymbol.X2 = (defaultsymbol.X2 + x) * Text->Scale / 100;
 
1726
          defaultsymbol.Y2 = defaultsymbol.Y2 * Text->Scale / 100;
 
1727
 
 
1728
          if (TEST_FLAG (ONSOLDERFLAG, Text))
 
1729
            {
 
1730
              defaultsymbol.X1 = TO_SCREEN_SIGN_X (defaultsymbol.X1);
 
1731
              defaultsymbol.Y1 = TO_SCREEN_SIGN_Y (defaultsymbol.Y1);
 
1732
              defaultsymbol.X2 = TO_SCREEN_SIGN_X (defaultsymbol.X2);
 
1733
              defaultsymbol.Y2 = TO_SCREEN_SIGN_Y (defaultsymbol.Y2);
 
1734
            }
 
1735
          RotateBoxLowLevel (&defaultsymbol, 0, 0, Text->Direction);
 
1736
 
 
1737
          /* add offset and draw box */
 
1738
          defaultsymbol.X1 += Text->X;
 
1739
          defaultsymbol.Y1 += Text->Y;
 
1740
          defaultsymbol.X2 += Text->X;
 
1741
          defaultsymbol.Y2 += Text->Y;
 
1742
          XFillRectangle (Dpy, DrawingWindow, Output.fgGC,
 
1743
                          TO_DRAW_X (defaultsymbol.X1),
 
1744
                          TO_DRAW_Y (SWAP_IDENT ? defaultsymbol.Y2 :
 
1745
                                     defaultsymbol.Y1),
 
1746
                          TO_SCREEN (abs
 
1747
                                     (defaultsymbol.X2 - defaultsymbol.X1)),
 
1748
                          TO_SCREEN (abs
 
1749
                                     (defaultsymbol.Y2 - defaultsymbol.Y1)));
 
1750
 
 
1751
          /* move on to next cursor position */
 
1752
          x += size;
 
1753
        }
 
1754
      string++;
 
1755
    }
1143
1756
}
1144
1757
 
1145
1758
/* ---------------------------------------------------------------------------
1146
1759
 * lowlevel drawing routine for polygons
1147
1760
 */
1148
 
static void DrawPolygonLowLevel(PolygonTypePtr Polygon, Boolean OnMask)
 
1761
static void
 
1762
DrawPolygonLowLevel (PolygonTypePtr Polygon)
1149
1763
{
1150
 
        static  XPoint          *data = NULL;   /* tmp pointer */
1151
 
        static  Cardinal        max = 0;
1152
 
 
1153
 
        if (Gathering)
1154
 
        {
1155
 
                UpdateRect.x = MIN(TO_DRAW_X(Polygon->BoundingBox.X1), TO_DRAW_X(Polygon->BoundingBox.X2));
1156
 
                UpdateRect.y = MIN(TO_DRAW_Y(Polygon->BoundingBox.Y1), TO_DRAW_Y(Polygon->BoundingBox.Y2));
1157
 
                UpdateRect.width = TO_SCREEN(Polygon->BoundingBox.X2 - Polygon->BoundingBox.X1);
1158
 
                UpdateRect.height = TO_SCREEN(Polygon->BoundingBox.Y2 - Polygon->BoundingBox.Y1);
1159
 
                AddPart();
1160
 
                return;
1161
 
        }
1162
 
                /* allocate memory for data with screen coordinates */
1163
 
        if (Polygon->PointN > max)
1164
 
        {
1165
 
                max = Polygon->PointN;
1166
 
                data = (XPoint *) MyRealloc(data, max *sizeof(XPoint),
1167
 
                        "DrawPolygonLowLevel()");
1168
 
        }
1169
 
 
1170
 
                /* copy data to tmp array and convert it to screen coordinates */
1171
 
        POLYGONPOINT_LOOP(Polygon,
1172
 
                if (OnMask)
1173
 
                {
1174
 
                        data[n].x = TO_MASK_X(point->X);
1175
 
                        data[n].y = TO_MASK_Y(point->Y);
1176
 
                }
1177
 
                else
1178
 
                {
1179
 
                        data[n].x = TO_DRAW_X(point->X);
1180
 
                        data[n].y = TO_DRAW_Y(point->Y);
1181
 
                }
1182
 
        );
1183
 
        if (OnMask)
1184
 
                XFillPolygon(Dpy, Offmask, Output.pmGC,
1185
 
                        data, Polygon->PointN, Complex, CoordModeOrigin);
1186
 
        else
1187
 
                XFillPolygon(Dpy, DrawingWindow, Output.fgGC,
1188
 
                        data, Polygon->PointN, Complex, CoordModeOrigin);
 
1764
  if (Gathering)
 
1765
    {
 
1766
      AddPart (Polygon, False);
 
1767
      return;
 
1768
    }
 
1769
  DrawCPolygon (DrawingWindow, Polygon);
1189
1770
}
1190
1771
 
1191
1772
/* ---------------------------------------------------------------------------
1192
1773
 * lowlevel routine to element arcs
1193
1774
 */
1194
 
static void DrawArcLowLevel(ArcTypePtr Arc)
 
1775
static void
 
1776
DrawArcLowLevel (ArcTypePtr Arc)
1195
1777
{
1196
 
        Dimension       width = Arc->Thickness;
 
1778
  if (Gathering)
 
1779
    {
 
1780
      AddPart (Arc, False);
 
1781
      return;
 
1782
    }
 
1783
  /* angles have to be converted to X11 notation */
 
1784
  if (TEST_FLAG (THINDRAWFLAG, PCB))
 
1785
    XSetLineAttributes (Dpy, Output.fgGC, 1, LineSolid, CapRound, JoinRound);
 
1786
  else
 
1787
    XSetLineAttributes (Dpy, Output.fgGC,
 
1788
                        TO_SCREEN (Arc->Thickness), LineSolid, CapRound,
 
1789
                        JoinRound);
1197
1790
 
1198
 
        if (Gathering)
1199
 
        {
1200
 
                if (TEST_FLAG(CLEARLINEFLAG, Arc))
1201
 
                        width += Arc->Clearance;
1202
 
                UpdateRect.x = TO_DRAW_X(Arc->X) -TO_SCREEN(Arc->Width + width/2);
1203
 
                UpdateRect.y = TO_DRAW_Y(Arc->Y) -TO_SCREEN(Arc->Height + width/2);
1204
 
                UpdateRect.width = TO_SCREEN(2*Arc->Width + width);
1205
 
                UpdateRect.height = TO_SCREEN(2*Arc->Height + width);
1206
 
                AddPart();
1207
 
                return;
1208
 
        }
1209
 
                /* angles have to be converted to X11 notation */
1210
 
        XSetLineAttributes(Dpy, Output.fgGC,
1211
 
                TO_SCREEN(Arc->Thickness), LineSolid, CapRound, JoinRound);
1212
 
        XDrawArc(Dpy, DrawingWindow, Output.fgGC,
1213
 
                TO_DRAW_X(Arc->X) -TO_SCREEN(Arc->Width),
1214
 
                TO_DRAW_Y(Arc->Y) -TO_SCREEN(Arc->Height),
1215
 
                TO_SCREEN(2*Arc->Width),
1216
 
                TO_SCREEN(2*Arc->Height),
1217
 
                (TO_SCREEN_ANGLE(Arc->StartAngle) -180) *64,
1218
 
                TO_SCREEN_DELTA(Arc->Delta) *64);
 
1791
  XDrawCArc (Dpy, DrawingWindow, Output.fgGC, Arc->X, Arc->Y, 2 * Arc->Width,
 
1792
             2 * Arc->Height, (Arc->StartAngle - 180) * 64, Arc->Delta * 64);
1219
1793
}
1220
1794
 
1221
1795
/* ---------------------------------------------------------------------------
1222
1796
 * draws the package of an element
1223
1797
 */
1224
 
static void DrawElementPackageLowLevel(ElementTypePtr Element, int unused)
 
1798
static void
 
1799
DrawElementPackageLowLevel (ElementTypePtr Element, int unused)
1225
1800
{
1226
 
                /* draw lines, arcs, text and pins */
1227
 
        ELEMENTLINE_LOOP(Element, DrawLineLowLevel(line, False););
1228
 
        ARC_LOOP(Element, DrawArcLowLevel(arc););
 
1801
  /* draw lines, arcs, text and pins */
 
1802
  ELEMENTLINE_LOOP (Element);
 
1803
  {
 
1804
    DrawLineLowLevel (line, False);
 
1805
  }
 
1806
  END_LOOP;
 
1807
  ARC_LOOP (Element);
 
1808
  {
 
1809
    DrawArcLowLevel (arc);
 
1810
  }
 
1811
  END_LOOP;
1229
1812
}
1230
1813
 
1231
1814
/* ---------------------------------------------------------------------------
1232
1815
 * draw a via object
1233
1816
 */
1234
 
void DrawVia(PinTypePtr Via, int unused)
 
1817
void
 
1818
DrawVia (PinTypePtr Via, int unused)
1235
1819
{
1236
 
        if (!Gathering)
1237
 
                SetPVColor(Via, VIA_TYPE);
1238
 
        if (!TEST_FLAG(HOLEFLAG, Via) && TEST_FLAG(ALLPIPFLAGS, Via))
1239
 
                ClearPin(Via, VIA_TYPE, 0);
1240
 
        else
1241
 
                DrawPinOrViaLowLevel(Via, True);
1242
 
        if (!TEST_FLAG(HOLEFLAG, Via) && TEST_FLAG(DISPLAYNAMEFLAG, Via))
1243
 
                DrawPinOrViaNameLowLevel(Via);
 
1820
  if (!Gathering)
 
1821
    SetPVColor (Via, VIA_TYPE);
 
1822
  if (!TEST_FLAG (HOLEFLAG, Via) && TEST_FLAG (ALLPIPFLAGS, Via))
 
1823
    ClearPin (Via, VIA_TYPE, 0);
 
1824
  else
 
1825
    DrawPinOrViaLowLevel (Via, True);
 
1826
  if (!TEST_FLAG (HOLEFLAG, Via) && TEST_FLAG (DISPLAYNAMEFLAG, Via))
 
1827
    DrawPinOrViaNameLowLevel (Via);
1244
1828
}
1245
1829
 
1246
1830
/* ---------------------------------------------------------------------------
1247
1831
 * draw a via without dealing with polygon clearance 
1248
1832
 */
1249
 
static void DrawPlainVia(PinTypePtr Via, int unused)
 
1833
static void
 
1834
DrawPlainVia (PinTypePtr Via, Boolean holeToo)
1250
1835
{
1251
 
        if (!Gathering)
1252
 
                SetPVColor(Via, VIA_TYPE);
1253
 
        DrawPinOrViaLowLevel(Via, False);
1254
 
        if (!TEST_FLAG(HOLEFLAG, Via) && TEST_FLAG(DISPLAYNAMEFLAG, Via))
1255
 
                DrawPinOrViaNameLowLevel(Via);
 
1836
  if (!Gathering)
 
1837
    SetPVColor (Via, VIA_TYPE);
 
1838
  DrawPinOrViaLowLevel (Via, holeToo);
 
1839
  if (!TEST_FLAG (HOLEFLAG, Via) && TEST_FLAG (DISPLAYNAMEFLAG, Via))
 
1840
    DrawPinOrViaNameLowLevel (Via);
1256
1841
}
1257
1842
 
1258
1843
/* ---------------------------------------------------------------------------
1259
1844
 * draws the name of a via
1260
1845
 */
1261
 
void DrawViaName(PinTypePtr Via, int unused)
 
1846
void
 
1847
DrawViaName (PinTypePtr Via, int unused)
1262
1848
{
1263
 
        if (!Gathering)
1264
 
        {
1265
 
                if (TEST_FLAG(SELECTEDFLAG, Via))
1266
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ViaSelectedColor);
1267
 
                else
1268
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ViaColor);
1269
 
        }
1270
 
        DrawPinOrViaNameLowLevel(Via);
 
1849
  if (!Gathering)
 
1850
    {
 
1851
      if (TEST_FLAG (SELECTEDFLAG, Via))
 
1852
        XSetForeground (Dpy, Output.fgGC, PCB->ViaSelectedColor);
 
1853
      else
 
1854
        XSetForeground (Dpy, Output.fgGC, PCB->ViaColor);
 
1855
    }
 
1856
  DrawPinOrViaNameLowLevel (Via);
1271
1857
}
1272
1858
 
1273
1859
/* ---------------------------------------------------------------------------
1274
1860
 * draw a pin object
1275
1861
 */
1276
 
void DrawPin(PinTypePtr Pin, int unused) 
 
1862
void
 
1863
DrawPin (PinTypePtr Pin, int unused)
1277
1864
{
1278
 
        if (!TEST_FLAG(HOLEFLAG, Pin) && TEST_FLAG(ALLPIPFLAGS, Pin))
1279
 
                ClearPin(Pin, PIN_TYPE, 0);
1280
 
        else
1281
 
        {
1282
 
                if (!Gathering)
1283
 
                        SetPVColor(Pin, PIN_TYPE);
1284
 
                DrawPinOrViaLowLevel(Pin, True);
1285
 
        }
1286
 
        if (!TEST_FLAG(HOLEFLAG, Pin) && TEST_FLAG(DISPLAYNAMEFLAG, Pin))
1287
 
                DrawPinOrViaNameLowLevel(Pin);
 
1865
  if (!TEST_FLAG (HOLEFLAG, Pin) && TEST_FLAG (ALLPIPFLAGS, Pin))
 
1866
    ClearPin (Pin, PIN_TYPE, 0);
 
1867
  else
 
1868
    {
 
1869
      if (!Gathering)
 
1870
        SetPVColor (Pin, PIN_TYPE);
 
1871
      DrawPinOrViaLowLevel (Pin, True);
 
1872
    }
 
1873
  if (!TEST_FLAG (HOLEFLAG, Pin) && TEST_FLAG (DISPLAYNAMEFLAG, Pin))
 
1874
    DrawPinOrViaNameLowLevel (Pin);
1288
1875
}
1289
1876
 
1290
1877
/* ---------------------------------------------------------------------------
1291
1878
 * draw a pin without clearing around polygons 
1292
1879
 */
1293
 
static void DrawPlainPin(PinTypePtr Pin, int unused)
 
1880
static void
 
1881
DrawPlainPin (PinTypePtr Pin, Boolean holeToo)
1294
1882
{
1295
 
        if (!Gathering)
1296
 
                SetPVColor(Pin, PIN_TYPE);
1297
 
        DrawPinOrViaLowLevel(Pin, False);
1298
 
        if (!TEST_FLAG(HOLEFLAG, Pin) && TEST_FLAG(DISPLAYNAMEFLAG, Pin))
1299
 
                DrawPinOrViaNameLowLevel(Pin);
 
1883
  if (!Gathering)
 
1884
    SetPVColor (Pin, PIN_TYPE);
 
1885
  DrawPinOrViaLowLevel (Pin, holeToo);
 
1886
  if (!TEST_FLAG (HOLEFLAG, Pin) && TEST_FLAG (DISPLAYNAMEFLAG, Pin))
 
1887
    DrawPinOrViaNameLowLevel (Pin);
1300
1888
}
1301
1889
 
1302
1890
/* ---------------------------------------------------------------------------
1303
1891
 * draws the name of a pin
1304
1892
 */
1305
 
void DrawPinName(PinTypePtr Pin, int unused)
 
1893
void
 
1894
DrawPinName (PinTypePtr Pin, int unused)
1306
1895
{
1307
 
        if (!Gathering)
1308
 
        {
1309
 
                if (TEST_FLAG(SELECTEDFLAG, Pin))
1310
 
                        XSetForeground(Dpy, Output.fgGC, PCB->PinSelectedColor);
1311
 
                else
1312
 
                        XSetForeground(Dpy, Output.fgGC, PCB->PinColor);
1313
 
        }
1314
 
        DrawPinOrViaNameLowLevel(Pin);
 
1896
  if (!Gathering)
 
1897
    {
 
1898
      if (TEST_FLAG (SELECTEDFLAG, Pin))
 
1899
        XSetForeground (Dpy, Output.fgGC, PCB->PinSelectedColor);
 
1900
      else
 
1901
        XSetForeground (Dpy, Output.fgGC, PCB->PinColor);
 
1902
    }
 
1903
  DrawPinOrViaNameLowLevel (Pin);
1315
1904
}
1316
1905
 
1317
1906
/* ---------------------------------------------------------------------------
1318
1907
 * draw a pad object
1319
1908
 */
1320
 
void DrawPad(PadTypePtr Pad, int unused)
 
1909
void
 
1910
DrawPad (PadTypePtr Pad, int unused)
1321
1911
{
1322
 
        if (!Gathering)
 
1912
  if (!Gathering)
 
1913
    {
 
1914
      if (TEST_FLAG (WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pad))
1323
1915
        {
1324
 
                if (TEST_FLAG(WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pad))
1325
 
                {
1326
 
                        if (TEST_FLAG(WARNFLAG, Pad))
1327
 
                                XSetForeground(Dpy, Output.fgGC, PCB->WarnColor);
1328
 
                        else if (TEST_FLAG(SELECTEDFLAG, Pad))
1329
 
                                XSetForeground(Dpy, Output.fgGC, PCB->PinSelectedColor);
1330
 
                        else
1331
 
                                XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
1332
 
                }
1333
 
                else if (FRONT(Pad))
1334
 
                        XSetForeground(Dpy, Output.fgGC, PCB->PinColor);
1335
 
                else
1336
 
                        XSetForeground(Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
 
1916
          if (TEST_FLAG (WARNFLAG, Pad))
 
1917
            XSetForeground (Dpy, Output.fgGC, PCB->WarnColor);
 
1918
          else if (TEST_FLAG (SELECTEDFLAG, Pad))
 
1919
            XSetForeground (Dpy, Output.fgGC, PCB->PinSelectedColor);
 
1920
          else
 
1921
            XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
1337
1922
        }
1338
 
        DrawPadLowLevel(Pad);
1339
 
        if (TEST_FLAG(DISPLAYNAMEFLAG, Pad))
1340
 
                DrawPadNameLowLevel(Pad);
 
1923
      else if (FRONT (Pad))
 
1924
        XSetForeground (Dpy, Output.fgGC, PCB->PinColor);
 
1925
      else
 
1926
        XSetForeground (Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
 
1927
    }
 
1928
  DrawPadLowLevel (Pad);
 
1929
  if (TEST_FLAG (DISPLAYNAMEFLAG, Pad))
 
1930
    DrawPadNameLowLevel (Pad);
1341
1931
}
1342
1932
 
1343
1933
/* ---------------------------------------------------------------------------
1344
1934
 * draws the name of a pad
1345
1935
 */
1346
 
void DrawPadName(PadTypePtr Pad, int unused)
 
1936
void
 
1937
DrawPadName (PadTypePtr Pad, int unused)
1347
1938
{
1348
 
        if (!Gathering)
1349
 
        {
1350
 
                if (TEST_FLAG(SELECTEDFLAG, Pad))
1351
 
                        XSetForeground(Dpy, Output.fgGC, PCB->PinSelectedColor);
1352
 
                else if (FRONT(Pad))
1353
 
                        XSetForeground(Dpy, Output.fgGC, PCB->PinColor);
1354
 
                else
1355
 
                        XSetForeground(Dpy,Output.fgGC, PCB->InvisibleObjectsColor);
1356
 
        }
1357
 
        DrawPadNameLowLevel(Pad);
 
1939
  if (!Gathering)
 
1940
    {
 
1941
      if (TEST_FLAG (SELECTEDFLAG, Pad))
 
1942
        XSetForeground (Dpy, Output.fgGC, PCB->PinSelectedColor);
 
1943
      else if (FRONT (Pad))
 
1944
        XSetForeground (Dpy, Output.fgGC, PCB->PinColor);
 
1945
      else
 
1946
        XSetForeground (Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
 
1947
    }
 
1948
  DrawPadNameLowLevel (Pad);
1358
1949
}
1359
1950
 
1360
1951
/* ---------------------------------------------------------------------------
1361
1952
 * draws a line on a layer
1362
1953
 */
1363
 
void DrawLine(LayerTypePtr Layer, LineTypePtr Line, int unused)
 
1954
void
 
1955
DrawLine (LayerTypePtr Layer, LineTypePtr Line, int unused)
1364
1956
{
1365
 
        if (!Gathering)
 
1957
  if (!Gathering)
 
1958
    {
 
1959
      if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Line))
1366
1960
        {
1367
 
                if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Line))
1368
 
                {
1369
 
                        if (TEST_FLAG(SELECTEDFLAG, Line))
1370
 
                                XSetForeground(Dpy, Output.fgGC, Layer->SelectedColor);
1371
 
                        else
1372
 
                                XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
1373
 
                }
1374
 
                else
1375
 
                        XSetForeground(Dpy, Output.fgGC, Layer->Color);
 
1961
          if (TEST_FLAG (SELECTEDFLAG, Line))
 
1962
            XSetForeground (Dpy, Output.fgGC, Layer->SelectedColor);
 
1963
          else
 
1964
            XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
1376
1965
        }
1377
 
        DrawLineLowLevel(Line, False);
 
1966
      else
 
1967
        XSetForeground (Dpy, Output.fgGC, Layer->Color);
 
1968
    }
 
1969
  DrawLineLowLevel (Line, False);
1378
1970
}
1379
1971
 
1380
1972
/* ---------------------------------------------------------------------------
1381
1973
 * draws a ratline
1382
1974
 */
1383
 
void DrawRat(RatTypePtr Line, int unused)
 
1975
void
 
1976
DrawRat (RatTypePtr Line, int unused)
1384
1977
{
1385
 
        if (!Gathering)
 
1978
  if (!Gathering)
 
1979
    {
 
1980
      if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Line))
1386
1981
        {
1387
 
                if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Line))
1388
 
                {
1389
 
                        if (TEST_FLAG(SELECTEDFLAG, Line))
1390
 
                                XSetForeground(Dpy, Output.fgGC, PCB->RatSelectedColor);
1391
 
                        else
1392
 
                                XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
1393
 
                }
1394
 
                else
1395
 
                        XSetForeground(Dpy, Output.fgGC, PCB->RatColor);
 
1982
          if (TEST_FLAG (SELECTEDFLAG, Line))
 
1983
            XSetForeground (Dpy, Output.fgGC, PCB->RatSelectedColor);
 
1984
          else
 
1985
            XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
1396
1986
        }
1397
 
        DrawLineLowLevel((LineTypePtr) Line, False);
 
1987
      else
 
1988
        XSetForeground (Dpy, Output.fgGC, PCB->RatColor);
 
1989
    }
 
1990
  DrawLineLowLevel ((LineTypePtr) Line, False);
1398
1991
}
1399
1992
 
1400
1993
/* ---------------------------------------------------------------------------
1401
1994
 * draws an arc on a layer
1402
1995
 */
1403
 
void DrawArc(LayerTypePtr Layer, ArcTypePtr Arc, int unused)
 
1996
void
 
1997
DrawArc (LayerTypePtr Layer, ArcTypePtr Arc, int unused)
1404
1998
{
1405
 
        if (!Gathering)
 
1999
  if (!Gathering)
 
2000
    {
 
2001
      if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Arc))
1406
2002
        {
1407
 
                if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Arc))
1408
 
                {
1409
 
                        if (TEST_FLAG(SELECTEDFLAG, Arc))
1410
 
                                XSetForeground(Dpy, Output.fgGC, Layer->SelectedColor);
1411
 
                        else
1412
 
                                XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
1413
 
                }
1414
 
                else
1415
 
                        XSetForeground(Dpy, Output.fgGC, Layer->Color);
 
2003
          if (TEST_FLAG (SELECTEDFLAG, Arc))
 
2004
            XSetForeground (Dpy, Output.fgGC, Layer->SelectedColor);
 
2005
          else
 
2006
            XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
1416
2007
        }
1417
 
        DrawArcLowLevel(Arc);
 
2008
      else
 
2009
        XSetForeground (Dpy, Output.fgGC, Layer->Color);
 
2010
    }
 
2011
  DrawArcLowLevel (Arc);
1418
2012
}
1419
2013
 
1420
2014
/* ---------------------------------------------------------------------------
1421
2015
 * draws a text on a layer
1422
2016
 */
1423
 
void DrawText(LayerTypePtr Layer, TextTypePtr Text, int unused)
 
2017
void
 
2018
DrawText (LayerTypePtr Layer, TextTypePtr Text, int unused)
1424
2019
{
1425
 
        if (!Layer->On)
1426
 
                return;
1427
 
        if (TEST_FLAG(SELECTEDFLAG, Text))
1428
 
                XSetForeground(Dpy, Output.fgGC, Layer->SelectedColor);
1429
 
        else    
1430
 
                        XSetForeground(Dpy, Output.fgGC, Layer->Color);
1431
 
        DrawTextLowLevel(Text);
1432
 
}     
 
2020
  if (!Layer->On)
 
2021
    return;
 
2022
  if (TEST_FLAG (SELECTEDFLAG, Text))
 
2023
    XSetForeground (Dpy, Output.fgGC, Layer->SelectedColor);
 
2024
  else
 
2025
    XSetForeground (Dpy, Output.fgGC, Layer->Color);
 
2026
  DrawTextLowLevel (Text);
 
2027
}
1433
2028
 
1434
2029
/* ---------------------------------------------------------------------------
1435
2030
 * draws text on a layer - assumes it's not on silkscreen
1436
2031
 */
1437
 
static void DrawRegularText(LayerTypePtr Layer, TextTypePtr Text, int unused)
1438
 
{
1439
 
        if (TEST_FLAG(SELECTEDFLAG, Text))
1440
 
                XSetForeground(Dpy, Output.fgGC, Layer->SelectedColor);
1441
 
        else
1442
 
                XSetForeground(Dpy, Output.fgGC, Layer->Color);
1443
 
        DrawTextLowLevel(Text);
1444
 
}     
 
2032
static void
 
2033
DrawRegularText (LayerTypePtr Layer, TextTypePtr Text, int unused)
 
2034
{
 
2035
  if (TEST_FLAG (SELECTEDFLAG, Text))
 
2036
    XSetForeground (Dpy, Output.fgGC, Layer->SelectedColor);
 
2037
  else
 
2038
    XSetForeground (Dpy, Output.fgGC, Layer->Color);
 
2039
  DrawTextLowLevel (Text);
 
2040
}
 
2041
 
 
2042
static int
 
2043
cp_callback (const BoxType * b, void *cl)
 
2044
{
 
2045
  ClearPin ((PinTypePtr) b, (int) cl, 0);
 
2046
  return 1;
 
2047
}
1445
2048
 
1446
2049
/* ---------------------------------------------------------------------------
1447
2050
 * draws a polygon on a layer
1448
2051
 */
1449
 
void DrawPolygon(LayerTypePtr Layer, PolygonTypePtr Polygon, int unused)
 
2052
void
 
2053
DrawPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon, int unused)
1450
2054
{
1451
 
      int     Myflag, layernum;
1452
 
   
1453
 
      if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Polygon))
1454
 
      {
1455
 
              if (TEST_FLAG(SELECTEDFLAG, Polygon))
1456
 
                      XSetForeground(Dpy, Output.fgGC, Layer->SelectedColor);
1457
 
              else
1458
 
                      XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
1459
 
      }
 
2055
  int layernum;
 
2056
 
 
2057
  if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Polygon))
 
2058
    {
 
2059
      if (TEST_FLAG (SELECTEDFLAG, Polygon))
 
2060
        XSetForeground (Dpy, Output.fgGC, Layer->SelectedColor);
1460
2061
      else
1461
 
              XSetForeground(Dpy, Output.fgGC, Layer->Color);
1462
 
      layernum = GetLayerNumber(PCB->Data, Layer);
1463
 
      if (Settings.StipplePolygons)
1464
 
      {
1465
 
              XSetStipple(Dpy, Output.fgGC, Stipples[layernum]);
1466
 
              XSetFillStyle(Dpy, Output.fgGC, FillStippled);
1467
 
      }
1468
 
      DrawPolygonLowLevel(Polygon, False);
1469
 
      if (Settings.StipplePolygons)
1470
 
              XSetFillStyle(Dpy, Output.fgGC, FillSolid);
1471
 
      Myflag = L0THERMFLAG << GetLayerNumber(PCB->Data, Layer);
1472
 
      if (TEST_FLAG(CLEARPOLYFLAG, Polygon))
1473
 
      {
1474
 
              ALLPIN_LOOP(PCB->Data,
1475
 
                      if (IsPointInPolygon(pin->X, pin->Y,
1476
 
                          0, Polygon))
1477
 
                              {
1478
 
                                      ClearPin(pin, PIN_TYPE, 0);
1479
 
                              }
1480
 
              );  
1481
 
              VIA_LOOP(PCB->Data,
1482
 
                      if (IsPointInPolygon(via->X, via->Y,
1483
 
                          0, Polygon))
1484
 
                              {
1485
 
                                      ClearPin(via, VIA_TYPE, 0);
1486
 
                              }
1487
 
              );
1488
 
      }       
 
2062
        XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
 
2063
    }
 
2064
  else
 
2065
    XSetForeground (Dpy, Output.fgGC, Layer->Color);
 
2066
  layernum = GetLayerNumber (PCB->Data, Layer);
 
2067
  if (Settings.StipplePolygons)
 
2068
    {
 
2069
      XSetStipple (Dpy, Output.fgGC, Stipples[layernum]);
 
2070
      XSetFillStyle (Dpy, Output.fgGC, FillStippled);
 
2071
    }
 
2072
  DrawPolygonLowLevel (Polygon);
 
2073
  if (Settings.StipplePolygons)
 
2074
    XSetFillStyle (Dpy, Output.fgGC, FillSolid);
 
2075
  if (TEST_FLAG (CLEARPOLYFLAG, Polygon))
 
2076
    {
 
2077
      r_search (PCB->Data->pin_tree, &Polygon->BoundingBox, NULL,
 
2078
                cp_callback, (void *) PIN_TYPE);
 
2079
      r_search (PCB->Data->via_tree, &Polygon->BoundingBox, NULL,
 
2080
                cp_callback, (void *) VIA_TYPE);
 
2081
    }
1489
2082
}
1490
2083
 
1491
2084
/* ---------------------------------------------------------------------------
1492
2085
 * draws a polygon without cutting away the pin/via clearances
1493
2086
 */
1494
 
static void DrawPlainPolygon(LayerTypePtr Layer, PolygonTypePtr Polygon)
1495
 
{     
1496
 
        if (TEST_FLAG(SELECTEDFLAG | FOUNDFLAG, Polygon))
1497
 
        {
1498
 
                if (TEST_FLAG(SELECTEDFLAG, Polygon))
1499
 
                        XSetForeground(Dpy, Output.fgGC, Layer->SelectedColor);
1500
 
                else
1501
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ConnectedColor);
1502
 
        }
1503
 
        else
1504
 
                XSetForeground(Dpy, Output.fgGC, Layer->Color);
1505
 
        DrawPolygonLowLevel(Polygon, False);
 
2087
static void
 
2088
DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
 
2089
{
 
2090
  if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Polygon))
 
2091
    {
 
2092
      if (TEST_FLAG (SELECTEDFLAG, Polygon))
 
2093
        XSetForeground (Dpy, Output.fgGC, Layer->SelectedColor);
 
2094
      else
 
2095
        XSetForeground (Dpy, Output.fgGC, PCB->ConnectedColor);
 
2096
    }
 
2097
  else
 
2098
    XSetForeground (Dpy, Output.fgGC, Layer->Color);
 
2099
  DrawPolygonLowLevel (Polygon);
1506
2100
}
1507
2101
 
1508
2102
/* ---------------------------------------------------------------------------
1509
2103
 * draws an element
1510
2104
 */
1511
 
void DrawElement(ElementTypePtr Element, int unused)
 
2105
void
 
2106
DrawElement (ElementTypePtr Element, int unused)
1512
2107
{
1513
 
        DrawElementPackage(Element, unused);
1514
 
        DrawElementName(Element, unused);
1515
 
        DrawElementPinsAndPads(Element, unused);
1516
 
 
2108
  DrawElementPackage (Element, unused);
 
2109
  DrawElementName (Element, unused);
 
2110
  DrawElementPinsAndPads (Element, unused);
 
2111
}
1517
2112
 
1518
2113
/* ---------------------------------------------------------------------------
1519
2114
 * draws the name of an element
1520
2115
 */
1521
 
void DrawElementName(ElementTypePtr Element, int unused)
 
2116
void
 
2117
DrawElementName (ElementTypePtr Element, int unused)
1522
2118
{
1523
 
        if (TEST_FLAG(HIDENAMEFLAG, Element))
1524
 
                return;
1525
 
        if (TEST_FLAG(SELECTEDFLAG, &ELEMENT_TEXT(PCB, Element)))
1526
 
                XSetForeground(Dpy, Output.fgGC, PCB->ElementSelectedColor);
1527
 
        else
1528
 
                if (FRONT(Element))
1529
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ElementColor);
1530
 
                else
1531
 
                        XSetForeground(Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
1532
 
        DrawTextLowLevel(&ELEMENT_TEXT(PCB, Element));
 
2119
  if (TEST_FLAG (HIDENAMEFLAG, Element))
 
2120
    return;
 
2121
  if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, Element)))
 
2122
    XSetForeground (Dpy, Output.fgGC, PCB->ElementSelectedColor);
 
2123
  else if (FRONT (Element))
 
2124
    XSetForeground (Dpy, Output.fgGC, PCB->ElementColor);
 
2125
  else
 
2126
    XSetForeground (Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
 
2127
  DrawTextLowLevel (&ELEMENT_TEXT (PCB, Element));
1533
2128
}
1534
2129
 
1535
2130
/* ---------------------------------------------------------------------------
1536
2131
 * draws the package of an element
1537
2132
 */
1538
 
void DrawElementPackage(ElementTypePtr Element, int unused)
 
2133
void
 
2134
DrawElementPackage (ElementTypePtr Element, int unused)
1539
2135
{
1540
 
                /* set color and draw lines, arcs, text and pins */
1541
 
        if (TEST_FLAG(SELECTEDFLAG, Element))
1542
 
                XSetForeground(Dpy, Output.fgGC, PCB->ElementSelectedColor);
1543
 
        else
1544
 
                if (FRONT(Element))
1545
 
                        XSetForeground(Dpy, Output.fgGC, PCB->ElementColor);
1546
 
                else
1547
 
                        XSetForeground(Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
1548
 
        DrawElementPackageLowLevel(Element, unused);
 
2136
  /* set color and draw lines, arcs, text and pins */
 
2137
  if (TEST_FLAG (SELECTEDFLAG, Element))
 
2138
    XSetForeground (Dpy, Output.fgGC, PCB->ElementSelectedColor);
 
2139
  else if (FRONT (Element))
 
2140
    XSetForeground (Dpy, Output.fgGC, PCB->ElementColor);
 
2141
  else
 
2142
    XSetForeground (Dpy, Output.fgGC, PCB->InvisibleObjectsColor);
 
2143
  DrawElementPackageLowLevel (Element, unused);
1549
2144
}
1550
2145
 
1551
2146
/* ---------------------------------------------------------------------------
1552
2147
 * draw pins of an element
1553
2148
 */
1554
 
void DrawElementPinsAndPads(ElementTypePtr Element, int unused)
1555
 
{
1556
 
        PAD_LOOP(Element,
1557
 
                if (FRONT(pad) || PCB->InvisibleObjectsOn)
1558
 
                        DrawPad(pad, unused);
1559
 
        );
1560
 
        PIN_LOOP(Element,
1561
 
                DrawPin(pin, unused);
1562
 
        );
1563
 
}
1564
 
 
1565
 
/* ---------------------------------------------------------------------------
1566
 
 * draw pins of an element without clearing around polygons
1567
 
 */
1568
 
static void DrawPlainElementPinsAndPads(ElementTypePtr Element, int unused)
1569
 
{
1570
 
                /* don't draw invisible pads, they're already handled */
1571
 
        PAD_LOOP(Element,
1572
 
                if (FRONT(pad)) 
1573
 
                        DrawPad(pad, unused);
1574
 
        );
1575
 
        PIN_LOOP(Element,
1576
 
                DrawPlainPin(pin, unused);
1577
 
        );
 
2149
void
 
2150
DrawElementPinsAndPads (ElementTypePtr Element, int unused)
 
2151
{
 
2152
  PAD_LOOP (Element);
 
2153
  {
 
2154
    if (FRONT (pad) || PCB->InvisibleObjectsOn)
 
2155
      DrawPad (pad, unused);
 
2156
  }
 
2157
  END_LOOP;
 
2158
  PIN_LOOP (Element);
 
2159
  {
 
2160
    DrawPin (pin, unused);
 
2161
  }
 
2162
  END_LOOP;
1578
2163
}
1579
2164
 
1580
2165
/* ---------------------------------------------------------------------------
1581
2166
 * erase a via
1582
2167
 */
1583
 
void EraseVia(PinTypePtr Via)
 
2168
void
 
2169
EraseVia (PinTypePtr Via)
1584
2170
{
1585
 
        Erasing++;
1586
 
        if (TEST_FLAG(ALLPIPFLAGS, Via))
1587
 
                ClearPin(Via, NO_TYPE, 0);
1588
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1589
 
        DrawPinOrViaLowLevel(Via, False);
1590
 
        if (TEST_FLAG(DISPLAYNAMEFLAG, Via))
1591
 
                DrawPinOrViaNameLowLevel(Via);
1592
 
        Erasing--;
 
2171
  Erasing++;
 
2172
  if (TEST_FLAG (ALLPIPFLAGS, Via))
 
2173
    ClearPin (Via, NO_TYPE, 0);
 
2174
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2175
  DrawPinOrViaLowLevel (Via, False);
 
2176
  if (TEST_FLAG (DISPLAYNAMEFLAG, Via))
 
2177
    DrawPinOrViaNameLowLevel (Via);
 
2178
  Erasing--;
1593
2179
}
1594
2180
 
1595
2181
/* ---------------------------------------------------------------------------
1596
2182
 * erase a ratline
1597
2183
 */
1598
 
void EraseRat(RatTypePtr Rat)
 
2184
void
 
2185
EraseRat (RatTypePtr Rat)
1599
2186
{
1600
 
        Erasing++;
1601
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1602
 
        DrawLineLowLevel((LineTypePtr) Rat, False);
1603
 
        Erasing--;
 
2187
  Erasing++;
 
2188
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2189
  DrawLineLowLevel ((LineTypePtr) Rat, False);
 
2190
  Erasing--;
1604
2191
}
1605
2192
 
1606
2193
 
1607
2194
/* ---------------------------------------------------------------------------
1608
2195
 * erase a via name
1609
2196
 */
1610
 
void EraseViaName(PinTypePtr Via)
 
2197
void
 
2198
EraseViaName (PinTypePtr Via)
1611
2199
{
1612
 
        Erasing++;
1613
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1614
 
        DrawPinOrViaNameLowLevel(Via);
1615
 
        Erasing--;
 
2200
  Erasing++;
 
2201
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2202
  DrawPinOrViaNameLowLevel (Via);
 
2203
  Erasing--;
1616
2204
}
1617
2205
 
1618
2206
/* ---------------------------------------------------------------------------
1619
2207
 * erase a pad object
1620
2208
 */
1621
 
void ErasePad(PadTypePtr Pad)
 
2209
void
 
2210
ErasePad (PadTypePtr Pad)
1622
2211
{
1623
 
        Erasing++;
1624
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1625
 
        DrawPadLowLevel(Pad);
1626
 
        if (TEST_FLAG(DISPLAYNAMEFLAG, Pad))
1627
 
                DrawPadNameLowLevel(Pad);
1628
 
        Erasing--;
 
2212
  Erasing++;
 
2213
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2214
  DrawPadLowLevel (Pad);
 
2215
  if (TEST_FLAG (DISPLAYNAMEFLAG, Pad))
 
2216
    DrawPadNameLowLevel (Pad);
 
2217
  Erasing--;
1629
2218
}
1630
2219
 
1631
2220
/* ---------------------------------------------------------------------------
1632
2221
 * erase a pad name
1633
2222
 */
1634
 
void ErasePadName(PadTypePtr Pad)
 
2223
void
 
2224
ErasePadName (PadTypePtr Pad)
1635
2225
{
1636
 
        Erasing++;
1637
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1638
 
        DrawPadNameLowLevel(Pad);
1639
 
        Erasing--;
 
2226
  Erasing++;
 
2227
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2228
  DrawPadNameLowLevel (Pad);
 
2229
  Erasing--;
1640
2230
}
1641
2231
 
1642
2232
/* ---------------------------------------------------------------------------
1643
2233
 * erase a pin object
1644
2234
 */
1645
 
void ErasePin(PinTypePtr Pin)
 
2235
void
 
2236
ErasePin (PinTypePtr Pin)
1646
2237
{
1647
 
        Erasing++;
1648
 
        if (TEST_FLAG(ALLPIPFLAGS, Pin))
1649
 
                ClearPin(Pin, NO_TYPE, 0);
1650
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1651
 
        DrawPinOrViaLowLevel(Pin, False);
1652
 
        if (TEST_FLAG(DISPLAYNAMEFLAG, Pin))
1653
 
                DrawPinOrViaNameLowLevel(Pin);
1654
 
        Erasing--;
 
2238
  Erasing++;
 
2239
  if (TEST_FLAG (ALLPIPFLAGS, Pin))
 
2240
    ClearPin (Pin, NO_TYPE, 0);
 
2241
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2242
  DrawPinOrViaLowLevel (Pin, False);
 
2243
  if (TEST_FLAG (DISPLAYNAMEFLAG, Pin))
 
2244
    DrawPinOrViaNameLowLevel (Pin);
 
2245
  Erasing--;
1655
2246
}
1656
2247
 
1657
2248
/* ---------------------------------------------------------------------------
1658
2249
 * erase a pin name
1659
2250
 */
1660
 
void ErasePinName(PinTypePtr Pin)
 
2251
void
 
2252
ErasePinName (PinTypePtr Pin)
1661
2253
{
1662
 
        Erasing++;
1663
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1664
 
        DrawPinOrViaNameLowLevel(Pin);
1665
 
        Erasing--;
 
2254
  Erasing++;
 
2255
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2256
  DrawPinOrViaNameLowLevel (Pin);
 
2257
  Erasing--;
1666
2258
}
1667
2259
 
1668
2260
/* ---------------------------------------------------------------------------
1669
2261
 * erases a line on a layer
1670
2262
 */
1671
 
void EraseLine(LineTypePtr Line)
 
2263
void
 
2264
EraseLine (LineTypePtr Line)
1672
2265
{
1673
 
        Erasing++;
1674
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1675
 
        DrawLineLowLevel(Line, False);
1676
 
        Erasing--;
 
2266
  Erasing++;
 
2267
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2268
  DrawLineLowLevel (Line, False);
 
2269
  Erasing--;
1677
2270
}
1678
2271
 
1679
2272
/* ---------------------------------------------------------------------------
1680
2273
 * erases an arc on a layer
1681
2274
 */
1682
 
void EraseArc(ArcTypePtr Arc)
 
2275
void
 
2276
EraseArc (ArcTypePtr Arc)
1683
2277
{
1684
 
        Erasing++;
1685
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1686
 
        DrawArcLowLevel(Arc);
1687
 
        Erasing--;
 
2278
  Erasing++;
 
2279
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2280
  DrawArcLowLevel (Arc);
 
2281
  Erasing--;
1688
2282
}
1689
2283
 
1690
2284
/* ---------------------------------------------------------------------------
1691
2285
 * erases a text on a layer
1692
2286
 */
1693
 
void EraseText(TextTypePtr Text)
 
2287
void
 
2288
EraseText (TextTypePtr Text)
1694
2289
{
1695
 
        Erasing++;
1696
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1697
 
        DrawTextLowLevel(Text);
1698
 
        Erasing--;
 
2290
  Erasing++;
 
2291
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2292
  DrawTextLowLevel (Text);
 
2293
  Erasing--;
1699
2294
}
1700
2295
 
1701
2296
/* ---------------------------------------------------------------------------
1702
2297
 * erases a polygon on a layer
1703
2298
 */
1704
 
void ErasePolygon(PolygonTypePtr Polygon)
 
2299
void
 
2300
ErasePolygon (PolygonTypePtr Polygon)
1705
2301
{
1706
 
        Erasing++;
1707
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1708
 
        DrawPolygonLowLevel(Polygon, False);
1709
 
        Erasing--;
 
2302
  Erasing++;
 
2303
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2304
  DrawPolygonLowLevel (Polygon);
 
2305
  Erasing--;
1710
2306
}
1711
2307
 
1712
2308
/* ---------------------------------------------------------------------------
1713
2309
 * erases an element
1714
2310
 */
1715
 
void EraseElement(ElementTypePtr Element)
 
2311
void
 
2312
EraseElement (ElementTypePtr Element)
1716
2313
{
1717
 
        Erasing++;
1718
 
                /* set color and draw lines, arcs, text and pins */
1719
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1720
 
        ELEMENTLINE_LOOP(Element, DrawLineLowLevel(line, False););
1721
 
        ARC_LOOP(Element, DrawArcLowLevel(arc););
1722
 
        if (!TEST_FLAG(HIDENAMEFLAG, Element))
1723
 
                DrawTextLowLevel(&ELEMENT_TEXT(PCB, Element));
1724
 
        EraseElementPinsAndPads(Element);
1725
 
        Erasing--;
1726
 
 
2314
  Erasing++;
 
2315
  /* set color and draw lines, arcs, text and pins */
 
2316
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2317
  ELEMENTLINE_LOOP (Element);
 
2318
  {
 
2319
    DrawLineLowLevel (line, False);
 
2320
  }
 
2321
  END_LOOP;
 
2322
  ARC_LOOP (Element);
 
2323
  {
 
2324
    DrawArcLowLevel (arc);
 
2325
  }
 
2326
  END_LOOP;
 
2327
  if (!TEST_FLAG (HIDENAMEFLAG, Element))
 
2328
    DrawTextLowLevel (&ELEMENT_TEXT (PCB, Element));
 
2329
  EraseElementPinsAndPads (Element);
 
2330
  Erasing--;
 
2331
}
1727
2332
 
1728
2333
/* ---------------------------------------------------------------------------
1729
2334
 * erases all pins and pads of an element
1730
2335
 */
1731
 
void EraseElementPinsAndPads(ElementTypePtr Element)
 
2336
void
 
2337
EraseElementPinsAndPads (ElementTypePtr Element)
1732
2338
{
1733
 
        Erasing++;
1734
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1735
 
        PIN_LOOP(Element,
1736
 
                if (TEST_FLAG(ALLPIPFLAGS, pin))
1737
 
                {
1738
 
                        ClearPin(pin, NO_TYPE, 0);
1739
 
                        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1740
 
                }
1741
 
                DrawPinOrViaLowLevel(pin, False);
1742
 
                if (TEST_FLAG(DISPLAYNAMEFLAG, pin))
1743
 
                        DrawPinOrViaNameLowLevel(pin);
1744
 
        );
1745
 
        PAD_LOOP(Element,
1746
 
                DrawPadLowLevel(pad);
1747
 
                if (TEST_FLAG(DISPLAYNAMEFLAG, pad))
1748
 
                        DrawPadNameLowLevel(pad);
1749
 
        );
1750
 
        Erasing--;
 
2339
  Erasing++;
 
2340
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2341
  PIN_LOOP (Element);
 
2342
  {
 
2343
    if (TEST_FLAG (ALLPIPFLAGS, pin))
 
2344
      {
 
2345
        ClearPin (pin, NO_TYPE, 0);
 
2346
        XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2347
      }
 
2348
    DrawPinOrViaLowLevel (pin, False);
 
2349
    if (TEST_FLAG (DISPLAYNAMEFLAG, pin))
 
2350
      DrawPinOrViaNameLowLevel (pin);
 
2351
  }
 
2352
  END_LOOP;
 
2353
  PAD_LOOP (Element);
 
2354
  {
 
2355
    DrawPadLowLevel (pad);
 
2356
    if (TEST_FLAG (DISPLAYNAMEFLAG, pad))
 
2357
      DrawPadNameLowLevel (pad);
 
2358
  }
 
2359
  END_LOOP;
 
2360
  Erasing--;
1751
2361
}
1752
2362
 
1753
2363
/* ---------------------------------------------------------------------------
1754
2364
 * erases the name of an element
1755
2365
 */
1756
 
void EraseElementName(ElementTypePtr Element)
 
2366
void
 
2367
EraseElementName (ElementTypePtr Element)
1757
2368
{
1758
 
        if (TEST_FLAG(HIDENAMEFLAG, Element))
1759
 
                return;
1760
 
        Erasing++;
1761
 
        XSetForeground(Dpy, Output.fgGC, Settings.bgColor);
1762
 
        DrawTextLowLevel(&ELEMENT_TEXT(PCB, Element));
1763
 
        Erasing--;
 
2369
  if (TEST_FLAG (HIDENAMEFLAG, Element))
 
2370
    return;
 
2371
  Erasing++;
 
2372
  XSetForeground (Dpy, Output.fgGC, Settings.bgColor);
 
2373
  DrawTextLowLevel (&ELEMENT_TEXT (PCB, Element));
 
2374
  Erasing--;
1764
2375
}
1765
2376
 
1766
2377
/* ---------------------------------------------------------------------------
1767
2378
 * draws grid points if the distance is >= MIN_GRID_DISTANCE
1768
2379
 */
1769
 
static void DrawGrid()
1770
 
{
1771
 
        Position        minx, miny,
1772
 
                        maxx, maxy,
1773
 
                        x, y, temp,
1774
 
                        delta;
1775
 
        
1776
 
        delta = GetGridFactor() *PCB->Grid;
1777
 
        if (TO_SCREEN(delta) >= MIN_GRID_DISTANCE)
1778
 
        {
1779
 
                minx = TO_PCB_X(0);
1780
 
                miny = TO_PCB_Y(0);
1781
 
                maxx = TO_PCB_X(Output.Width);
1782
 
                maxy = TO_PCB_Y(Output.Height);
1783
 
                if (miny > maxy)
1784
 
                {
1785
 
                        temp = maxy;
1786
 
                        maxy = miny;
1787
 
                        miny = temp;
1788
 
                }
1789
 
                minx -= delta;
1790
 
                miny -= delta;
1791
 
                maxx += delta;
1792
 
                maxy += delta;
1793
 
                maxx = MIN((Dimension) maxx, PCB->MaxWidth);
1794
 
                maxy = MIN((Dimension) maxy, PCB->MaxHeight);
1795
 
                miny = MAX(0, miny);
1796
 
                for (y = miny; y <= maxy; y += delta)
1797
 
                        for (x = minx; x <= maxx; x += delta)
1798
 
                                XDrawPoint(Dpy, DrawingWindow,
1799
 
                                        Output.GridGC, TO_DRAW_X(GRIDFIT_X(x, delta)),
1800
 
                                        TO_DRAW_Y(GRIDFIT_Y(y, delta)));
1801
 
        }
1802
 
}
1803
 
 
1804
 
void EraseObject(int type, void *ptr)
1805
 
{
1806
 
        switch(type)
1807
 
        {
1808
 
                case VIA_TYPE:
1809
 
                case PIN_TYPE:
1810
 
                        ErasePin((PinTypePtr) ptr);
1811
 
                        break;
1812
 
                case TEXT_TYPE:
1813
 
                case ELEMENTNAME_TYPE:
1814
 
                        EraseText((TextTypePtr) ptr);
1815
 
                        break;
1816
 
                case POLYGON_TYPE:
1817
 
                        ErasePolygon((PolygonTypePtr) ptr);
1818
 
                        break;
1819
 
                case ELEMENT_TYPE:
1820
 
                        EraseElement((ElementTypePtr) ptr);
1821
 
                        break;
1822
 
                case LINE_TYPE:
1823
 
                case RATLINE_TYPE:
1824
 
                        EraseLine((LineTypePtr) ptr);
1825
 
                        break;
1826
 
                case PAD_TYPE:
1827
 
                        ErasePad((PadTypePtr) ptr);
1828
 
                        break;
1829
 
                case ARC_TYPE:
1830
 
                        EraseArc((ArcTypePtr) ptr);
1831
 
                        break;
1832
 
                default:
1833
 
                        Message("hace: Internal ERROR, trying to erase an unknown type\n");
1834
 
        }
1835
 
}
1836
 
 
1837
 
 
1838
 
 
1839
 
void DrawObject(int type, void *ptr1, void *ptr2, int unused)
1840
 
{
1841
 
        switch(type)
1842
 
        {
1843
 
                case VIA_TYPE:
1844
 
                        if (PCB->ViaOn)
1845
 
                                DrawVia((PinTypePtr) ptr2, 0);
1846
 
                        break;
1847
 
                case LINE_TYPE:
1848
 
                        if (((LayerTypePtr) ptr1)->On)
1849
 
                                DrawLine((LayerTypePtr) ptr1, (LineTypePtr) ptr2, 0);
1850
 
                        break;
1851
 
                case ARC_TYPE:
1852
 
                        if (((LayerTypePtr) ptr1)->On)
1853
 
                                DrawArc((LayerTypePtr) ptr1, (ArcTypePtr) ptr2, 0);
1854
 
                        break;
1855
 
                case TEXT_TYPE:
1856
 
                        if (((LayerTypePtr) ptr1)->On)
1857
 
                                DrawText((LayerTypePtr) ptr1, (TextTypePtr) ptr2, 0);
1858
 
                        break;
1859
 
                case POLYGON_TYPE:
1860
 
                        if (((LayerTypePtr) ptr1)->On)
1861
 
                                DrawPolygon((LayerTypePtr) ptr1, (PolygonTypePtr) ptr2, 0);
1862
 
                        break;
1863
 
                case ELEMENT_TYPE:
1864
 
                        if (PCB->ElementOn &&
1865
 
                            (FRONT((ElementTypePtr) ptr2) || PCB->InvisibleObjectsOn))
1866
 
                                DrawElement((ElementTypePtr) ptr2, 0);
1867
 
                        break;
1868
 
                case RATLINE_TYPE:
1869
 
                        if (PCB->RatOn)
1870
 
                                DrawRat((RatTypePtr) ptr2, 0);
1871
 
                        break;
1872
 
                case PIN_TYPE:
1873
 
                        if (PCB->PinOn)
1874
 
                                DrawPin((PinTypePtr) ptr2, 0);
1875
 
                        break;
1876
 
                case PAD_TYPE:
1877
 
                        if (PCB->PinOn)
1878
 
                                DrawPad((PadTypePtr) ptr2, 0);
1879
 
                        break;
1880
 
                case ELEMENTNAME_TYPE:
1881
 
                        if (PCB->ElementOn &&
1882
 
                           (FRONT((ElementTypePtr) ptr2) || PCB->InvisibleObjectsOn))
1883
 
                                DrawElementName((ElementTypePtr) ptr1, 0);
1884
 
                        break;
1885
 
        }
 
2380
static void
 
2381
DrawGrid ()
 
2382
{
 
2383
  LocationType minx, miny, maxx, maxy, temp;
 
2384
  float x, y, delta;
 
2385
 
 
2386
  delta = GetGridFactor () * PCB->Grid;
 
2387
  if (TO_SCREEN ((int) delta) >= MIN_GRID_DISTANCE)
 
2388
    {
 
2389
      minx = TO_PCB_X (0);
 
2390
      miny = TO_PCB_Y (0);
 
2391
      maxx = TO_PCB_X (Output.Width);
 
2392
      maxy = TO_PCB_Y (Output.Height);
 
2393
      if (miny > maxy)
 
2394
        {
 
2395
          temp = maxy;
 
2396
          maxy = miny;
 
2397
          miny = temp;
 
2398
        }
 
2399
      minx -= delta;
 
2400
      miny -= delta;
 
2401
#if 0
 
2402
      maxx += delta;
 
2403
      maxy += delta;
 
2404
#else
 
2405
      minx -= delta;
 
2406
      miny -= delta;
 
2407
#endif
 
2408
      maxx = MIN ((BDimension) maxx, PCB->MaxWidth);
 
2409
      maxy = MIN ((BDimension) maxy, PCB->MaxHeight);
 
2410
      miny = MAX (0, miny);
 
2411
      minx = MAX (0, minx);
 
2412
      for (y = miny; y <= maxy; y += delta)
 
2413
        for (x = minx; x <= maxx; x += delta)
 
2414
          XDrawPoint (Dpy, DrawingWindow,
 
2415
                      Output.GridGC, TO_DRAW_X (GRIDFIT_X (x, delta)),
 
2416
                      TO_DRAW_Y (GRIDFIT_Y (y, delta)));
 
2417
    }
 
2418
}
 
2419
 
 
2420
void
 
2421
EraseObject (int type, void *ptr)
 
2422
{
 
2423
  switch (type)
 
2424
    {
 
2425
    case VIA_TYPE:
 
2426
    case PIN_TYPE:
 
2427
      ErasePin ((PinTypePtr) ptr);
 
2428
      break;
 
2429
    case TEXT_TYPE:
 
2430
    case ELEMENTNAME_TYPE:
 
2431
      EraseText ((TextTypePtr) ptr);
 
2432
      break;
 
2433
    case POLYGON_TYPE:
 
2434
      ErasePolygon ((PolygonTypePtr) ptr);
 
2435
      break;
 
2436
    case ELEMENT_TYPE:
 
2437
      EraseElement ((ElementTypePtr) ptr);
 
2438
      break;
 
2439
    case LINE_TYPE:
 
2440
    case ELEMENTLINE_TYPE:
 
2441
    case RATLINE_TYPE:
 
2442
      EraseLine ((LineTypePtr) ptr);
 
2443
      break;
 
2444
    case PAD_TYPE:
 
2445
      ErasePad ((PadTypePtr) ptr);
 
2446
      break;
 
2447
    case ARC_TYPE:
 
2448
    case ELEMENTARC_TYPE:
 
2449
      EraseArc ((ArcTypePtr) ptr);
 
2450
      break;
 
2451
    default:
 
2452
      Message ("hace: Internal ERROR, trying to erase an unknown type\n");
 
2453
    }
 
2454
}
 
2455
 
 
2456
 
 
2457
 
 
2458
void
 
2459
DrawObject (int type, void *ptr1, void *ptr2, int unused)
 
2460
{
 
2461
  switch (type)
 
2462
    {
 
2463
    case VIA_TYPE:
 
2464
      if (PCB->ViaOn)
 
2465
        DrawVia ((PinTypePtr) ptr2, 0);
 
2466
      break;
 
2467
    case LINE_TYPE:
 
2468
      if (((LayerTypePtr) ptr1)->On)
 
2469
        DrawLine ((LayerTypePtr) ptr1, (LineTypePtr) ptr2, 0);
 
2470
      break;
 
2471
    case ARC_TYPE:
 
2472
      if (((LayerTypePtr) ptr1)->On)
 
2473
        DrawArc ((LayerTypePtr) ptr1, (ArcTypePtr) ptr2, 0);
 
2474
      break;
 
2475
    case TEXT_TYPE:
 
2476
      if (((LayerTypePtr) ptr1)->On)
 
2477
        DrawText ((LayerTypePtr) ptr1, (TextTypePtr) ptr2, 0);
 
2478
      break;
 
2479
    case POLYGON_TYPE:
 
2480
      if (((LayerTypePtr) ptr1)->On)
 
2481
        DrawPolygon ((LayerTypePtr) ptr1, (PolygonTypePtr) ptr2, 0);
 
2482
      break;
 
2483
    case ELEMENT_TYPE:
 
2484
      if (PCB->ElementOn &&
 
2485
          (FRONT ((ElementTypePtr) ptr2) || PCB->InvisibleObjectsOn))
 
2486
        DrawElement ((ElementTypePtr) ptr2, 0);
 
2487
      break;
 
2488
    case RATLINE_TYPE:
 
2489
      if (PCB->RatOn)
 
2490
        DrawRat ((RatTypePtr) ptr2, 0);
 
2491
      break;
 
2492
    case PIN_TYPE:
 
2493
      if (PCB->PinOn)
 
2494
        DrawPin ((PinTypePtr) ptr2, 0);
 
2495
      break;
 
2496
    case PAD_TYPE:
 
2497
      if (PCB->PinOn)
 
2498
        DrawPad ((PadTypePtr) ptr2, 0);
 
2499
      break;
 
2500
    case ELEMENTNAME_TYPE:
 
2501
      if (PCB->ElementOn &&
 
2502
          (FRONT ((ElementTypePtr) ptr2) || PCB->InvisibleObjectsOn))
 
2503
        DrawElementName ((ElementTypePtr) ptr1, 0);
 
2504
      break;
 
2505
    }
1886
2506
}