Change drawing code for square pads to use gui->fill_rect (...) as on
[geda-pcb/gde.git] / src / draw.c
blob979d9435158c7a7d7406049d1939e998f04cca07
1 /* $Id$ */
3 /*
4 * COPYRIGHT
6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996, 2003, 2004 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 /* drawing routines
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #include "global.h"
39 /*#include "clip.h"*/
40 #include "compat.h"
41 #include "crosshair.h"
42 #include "data.h"
43 #include "draw.h"
44 #include "error.h"
45 #include "mymem.h"
46 #include "misc.h"
47 #include "polygon.h"
48 #include "rotate.h"
49 #include "rtree.h"
50 #include "search.h"
51 #include "select.h"
52 #include "print.h"
54 #ifdef HAVE_LIBDMALLOC
55 #include <dmalloc.h>
56 #endif
58 RCSID ("$Id$");
60 #define SMALL_SMALL_TEXT_SIZE 0
61 #define SMALL_TEXT_SIZE 1
62 #define NORMAL_TEXT_SIZE 2
63 #define LARGE_TEXT_SIZE 3
64 #define N_TEXT_SIZES 4
67 /* ---------------------------------------------------------------------------
68 * some local types
70 typedef struct
72 double X, Y;
74 FloatPolyType, *FloatPolyTypePtr;
76 /* ---------------------------------------------------------------------------
77 * some local identifiers
79 static BoxType Block;
80 static Boolean Gathering = True;
81 static int Erasing = False;
83 static int doing_pinout = False;
84 static int doing_assy = False;
85 static const BoxType *clip_box = NULL;
87 /* ---------------------------------------------------------------------------
88 * some local prototypes
90 static void Redraw (Boolean, BoxTypePtr);
91 static void DrawEverything (BoxTypePtr);
92 static void DrawTop (const BoxType *);
93 static void DrawLayer (LayerTypePtr, BoxType *);
94 static int DrawLayerGroup (int, const BoxType *);
95 static void DrawPinOrViaLowLevel (PinTypePtr, Boolean);
96 static void ClearOnlyPin (PinTypePtr, Boolean);
97 static void DrawPlainPin (PinTypePtr, Boolean);
98 static void DrawPlainVia (PinTypePtr, Boolean);
99 static void DrawPinOrViaNameLowLevel (PinTypePtr);
100 static void DrawPadLowLevel (PadTypePtr);
101 static void DrawPadNameLowLevel (PadTypePtr);
102 static void DrawLineLowLevel (LineTypePtr, Boolean);
103 static void DrawRegularText (LayerTypePtr, TextTypePtr, int);
104 static void DrawPolygonLowLevel (PolygonTypePtr);
105 static void DrawArcLowLevel (ArcTypePtr);
106 static void DrawElementPackageLowLevel (ElementTypePtr Element, int);
107 static void DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon);
108 static void AddPart (void *);
109 static void SetPVColor (PinTypePtr, int);
110 static void DrawEMark (ElementTypePtr, LocationType, LocationType, Boolean);
111 static void ClearPad (PadTypePtr, Boolean);
112 static void DrawHole (PinTypePtr);
113 static void DrawMask (BoxType *);
114 static void DrawSilk (int, int, BoxType *);
115 static int pin_callback (const BoxType * b, void *cl);
116 static int pad_callback (const BoxType * b, void *cl);
118 /*--------------------------------------------------------------------------------------
119 * setup color for pin or via
121 static void
122 SetPVColor (PinTypePtr Pin, int Type)
124 char *color;
126 if (Type == VIA_TYPE)
128 if (!doing_pinout
129 && TEST_FLAG (WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pin))
131 if (TEST_FLAG (WARNFLAG, Pin))
132 color = PCB->WarnColor;
133 else if (TEST_FLAG (SELECTEDFLAG, Pin))
134 color = PCB->ViaSelectedColor;
135 else
136 color = PCB->ConnectedColor;
138 else
139 color = PCB->ViaColor;
141 else
143 if (!doing_pinout
144 && TEST_FLAG (WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pin))
146 if (TEST_FLAG (WARNFLAG, Pin))
147 color = PCB->WarnColor;
148 else if (TEST_FLAG (SELECTEDFLAG, Pin))
149 color = PCB->PinSelectedColor;
150 else
151 color = PCB->ConnectedColor;
153 else
154 color = PCB->PinColor;
157 gui->set_color (Output.fgGC, color);
160 /*---------------------------------------------------------------------------
161 * Adds the update rect to the update region
163 static void
164 AddPart (void *b)
166 BoxType *box = (BoxType *) b;
168 Block.X1 = MIN (Block.X1, box->X1);
169 Block.X2 = MAX (Block.X2, box->X2);
170 Block.Y1 = MIN (Block.Y1, box->Y1);
171 Block.Y2 = MAX (Block.Y2, box->Y2);
175 * force the whole output to be updated
177 void
178 UpdateAll (void)
180 gui->invalidate_all ();
184 * initiate the actual drawing to the pixmap/screen
185 * make the update block slightly larger to handle round-off
186 * caused by the TO_SCREEN operation
188 void
189 Draw (void)
192 render = True;
194 HideCrosshair (True);
196 /* clear and create event if not drawing to a pixmap
198 gui->invalidate_lr (Block.X1, Block.X2, Block.Y1, Block.Y2, 1);
200 RestoreCrosshair (True);
202 /* shrink the update block */
203 Block.X1 = Block.Y1 = Block.X2 = Block.Y2 = 0;
206 /* ---------------------------------------------------------------------------
207 * redraws the output area without clearing it
209 void
210 RedrawOutput (BoxTypePtr area)
212 Redraw (True, area);
215 /* ---------------------------------------------------------------------------
216 * redraws the output area after clearing it
218 void
219 ClearAndRedrawOutput (void)
221 render = True;
222 Gathering = False;
223 UpdateAll ();
229 /* ----------------------------------------------------------------------
230 * redraws all the data
231 * all necessary sizes are already set by the porthole widget and
232 * by the event handlers
234 static void
235 Redraw (Boolean ClearWindow, BoxTypePtr screen_area)
237 gui->invalidate_all ();
238 Gathering = True;
239 render = False;
242 static int
243 backE_callback (const BoxType * b, void *cl)
245 ElementTypePtr element = (ElementTypePtr) b;
247 if (!FRONT (element))
249 DrawElementPackage (element, 0);
251 return 1;
254 static int
255 backN_callback (const BoxType * b, void *cl)
257 TextTypePtr text = (TextTypePtr) b;
258 ElementTypePtr element = (ElementTypePtr) text->Element;
260 if (!FRONT (element) && !TEST_FLAG (HIDENAMEFLAG, element))
261 DrawElementName (element, 0);
262 return 0;
265 static int
266 backPad_callback (const BoxType * b, void *cl)
268 PadTypePtr pad = (PadTypePtr) b;
270 if (!FRONT (pad))
271 DrawPad (pad, 0);
272 return 1;
275 static int
276 frontE_callback (const BoxType * b, void *cl)
278 ElementTypePtr element = (ElementTypePtr) b;
280 if (FRONT (element))
282 DrawElementPackage (element, 0);
284 return 1;
287 static int
288 EMark_callback (const BoxType * b, void *cl)
290 ElementTypePtr element = (ElementTypePtr) b;
292 DrawEMark (element, element->MarkX, element->MarkY, !FRONT (element));
293 return 1;
296 static int
297 frontN_callback (const BoxType * b, void *cl)
299 TextTypePtr text = (TextTypePtr) b;
300 ElementTypePtr element = (ElementTypePtr) text->Element;
302 if (FRONT (element) && !TEST_FLAG (HIDENAMEFLAG, element))
303 DrawElementName (element, 0);
304 return 0;
307 static int
308 hole_callback (const BoxType * b, void *cl)
310 PinTypePtr pin = (PinTypePtr) b;
311 int plated = cl ? *(int *) cl : -1;
312 switch (plated)
314 case -1:
315 break;
316 case 0:
317 if (!TEST_FLAG (HOLEFLAG, pin))
318 return 1;
319 break;
320 case 1:
321 if (TEST_FLAG (HOLEFLAG, pin))
322 return 1;
323 break;
325 DrawHole ((PinTypePtr) b);
326 return 1;
329 typedef struct
331 int nplated;
332 int nunplated;
333 } HoleCountStruct;
335 static int
336 hole_counting_callback (const BoxType * b, void *cl)
338 PinTypePtr pin = (PinTypePtr) b;
339 HoleCountStruct *hcs = (HoleCountStruct *) cl;
340 if (TEST_FLAG (HOLEFLAG, pin))
341 hcs->nunplated++;
342 else
343 hcs->nplated++;
344 return 1;
347 static int
348 rat_callback (const BoxType * b, void *cl)
350 DrawRat ((RatTypePtr) b, 0);
351 return 1;
354 static int
355 lowvia_callback (const BoxType * b, void *cl)
357 PinTypePtr via = (PinTypePtr) b;
358 if (!via->Mask)
359 DrawPlainVia (via, False);
360 return 1;
363 /* ---------------------------------------------------------------------------
364 * prints assembly drawing.
367 static void
368 PrintAssembly (const BoxType * drawn_area, int side_group, int swap_ident)
370 int save_swap = SWAP_IDENT;
372 gui->set_draw_faded (Output.fgGC, 1);
373 SWAP_IDENT = swap_ident;
374 DrawLayerGroup (side_group, drawn_area);
375 r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, NULL);
376 DrawTop (drawn_area);
377 gui->set_draw_faded (Output.fgGC, 0);
379 /* draw package */
380 r_search (PCB->Data->element_tree, drawn_area, NULL, frontE_callback, NULL);
381 r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL,
382 frontN_callback, NULL);
383 SWAP_IDENT = save_swap;
386 /* ---------------------------------------------------------------------------
387 * initializes some identifiers for a new zoom factor and redraws whole screen
389 static void
390 DrawEverything (BoxTypePtr drawn_area)
392 int i, ngroups, side;
393 int plated;
394 int component, solder;
395 /* This is the list of layer groups we will draw. */
396 int do_group[MAX_LAYER];
397 /* This is the reverse of the order in which we draw them. */
398 int drawn_groups[MAX_LAYER];
400 PCB->Data->SILKLAYER.Color = PCB->ElementColor;
401 PCB->Data->BACKSILKLAYER.Color = PCB->InvisibleObjectsColor;
403 memset (do_group, 0, sizeof (do_group));
404 for (ngroups = 0, i = 0; i < max_layer; i++)
406 LayerType *l = LAYER_ON_STACK (i);
407 int group = GetLayerGroupNumberByNumber (LayerStack[i]);
408 if (l->On && !do_group[group])
410 do_group[group] = 1;
411 drawn_groups[ngroups++] = group;
415 component = GetLayerGroupNumberByNumber (max_layer + COMPONENT_LAYER);
416 solder = GetLayerGroupNumberByNumber (max_layer + SOLDER_LAYER);
419 * first draw all 'invisible' stuff
421 if (!TEST_FLAG (CHECKPLANESFLAG, PCB)
422 && gui->set_layer ("invisible", SL (INVISIBLE, 0)))
424 if (PCB->PinOn)
425 r_search (PCB->Data->pad_tree, drawn_area, NULL, backPad_callback,
426 NULL);
427 if (PCB->ElementOn)
429 r_search (PCB->Data->element_tree, drawn_area, NULL, backE_callback,
430 NULL);
431 r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL,
432 backN_callback, NULL);
433 DrawLayer (&(PCB->Data->BACKSILKLAYER), drawn_area);
437 /* draw all layers in layerstack order */
438 for (i = ngroups - 1; i >= 0; i--)
440 int group = drawn_groups[i];
442 if (gui->set_layer (0, group))
444 if (DrawLayerGroup (group, drawn_area) && !gui->gui)
446 int save_swap = SWAP_IDENT;
448 if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui)
449 continue;
450 r_search (PCB->Data->pin_tree, drawn_area, NULL, pin_callback,
451 NULL);
452 r_search (PCB->Data->via_tree, drawn_area, NULL, pin_callback,
453 NULL);
454 /* draw element pads */
455 if (group == component || group == solder)
457 SWAP_IDENT = (group == solder);
458 r_search (PCB->Data->pad_tree, drawn_area, NULL,
459 pad_callback, NULL);
461 SWAP_IDENT = save_swap;
464 if (!gui->gui)
466 /* draw holes */
467 plated = -1;
468 r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback,
469 &plated);
470 r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback,
471 &plated);
475 if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui)
476 return;
478 /* draw vias below silk */
479 if (PCB->ViaOn && gui->gui)
480 r_search (PCB->Data->via_tree, drawn_area, NULL, lowvia_callback, NULL);
481 /* Draw the solder mask if turned on */
482 if (gui->set_layer ("componentmask", SL (MASK, TOP)))
484 int save_swap = SWAP_IDENT;
485 SWAP_IDENT = 0;
486 DrawMask (drawn_area);
487 SWAP_IDENT = save_swap;
489 if (gui->set_layer ("soldermask", SL (MASK, BOTTOM)))
491 int save_swap = SWAP_IDENT;
492 SWAP_IDENT = 1;
493 DrawMask (drawn_area);
494 SWAP_IDENT = save_swap;
496 /* Draw pins, pads, vias below silk */
497 if (gui->gui)
498 DrawTop (drawn_area);
499 else
501 HoleCountStruct hcs;
502 hcs.nplated = hcs.nunplated = 0;
503 r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_counting_callback,
504 &hcs);
505 r_search (PCB->Data->via_tree, drawn_area, NULL, hole_counting_callback,
506 &hcs);
507 if (hcs.nplated && gui->set_layer ("plated-drill", SL (PDRILL, 0)))
509 plated = 1;
510 r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback,
511 &plated);
512 r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback,
513 &plated);
515 if (hcs.nunplated && gui->set_layer ("unplated-drill", SL (UDRILL, 0)))
517 plated = 0;
518 r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback,
519 &plated);
520 r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback,
521 &plated);
524 /* Draw top silkscreen */
525 if (gui->set_layer ("topsilk", SL (SILK, TOP)))
526 DrawSilk (0, COMPONENT_LAYER, drawn_area);
527 if (gui->set_layer ("bottomsilk", SL (SILK, BOTTOM)))
528 DrawSilk (1, SOLDER_LAYER, drawn_area);
529 if (gui->gui)
531 /* Draw element Marks */
532 if (PCB->PinOn)
533 r_search (PCB->Data->element_tree, drawn_area, NULL, EMark_callback,
534 NULL);
535 /* Draw rat lines on top */
536 if (PCB->RatOn)
537 r_search (PCB->Data->rat_tree, drawn_area, NULL, rat_callback, NULL);
540 for (side = 0; side <= 1; side++)
542 int doit;
543 Boolean NoData = True;
544 ALLPAD_LOOP (PCB->Data);
546 if ((TEST_FLAG (ONSOLDERFLAG, pad) && side == SOLDER_LAYER)
547 || (!TEST_FLAG (ONSOLDERFLAG, pad) && side == COMPONENT_LAYER))
549 NoData = False;
550 break;
553 ENDALL_LOOP;
555 /* skip empty files */
556 if (NoData)
557 continue;
559 if (side == SOLDER_LAYER)
560 doit = gui->set_layer ("bottompaste", SL (PASTE, BOTTOM));
561 else
562 doit = gui->set_layer ("toppaste", SL (PASTE, TOP));
563 if (doit)
565 gui->set_color (Output.fgGC, PCB->ElementColor);
566 ALLPAD_LOOP (PCB->Data);
568 if ((TEST_FLAG (ONSOLDERFLAG, pad) && side == SOLDER_LAYER)
569 || (!TEST_FLAG (ONSOLDERFLAG, pad)
570 && side == COMPONENT_LAYER))
571 if (!TEST_FLAG (NOPASTEFLAG, pad))
572 DrawPadLowLevel (pad);
574 ENDALL_LOOP;
578 doing_assy = True;
579 if (gui->set_layer ("topassembly", SL (ASSY, TOP)))
580 PrintAssembly (drawn_area, component, 0);
582 if (gui->set_layer ("bottomassembly", SL (ASSY, BOTTOM)))
583 PrintAssembly (drawn_area, solder, 1);
584 doing_assy = False;
586 if (gui->set_layer ("fab", SL (FAB, 0)))
587 PrintFab ();
590 static void
591 DrawEMark (ElementTypePtr e, LocationType X, LocationType Y,
592 Boolean invisible)
594 int mark_size = EMARK_SIZE;
595 if (!PCB->InvisibleObjectsOn && invisible)
596 return;
598 if (e->PinN && mark_size > e->Pin[0].Thickness / 2)
599 mark_size = e->Pin[0].Thickness / 2;
600 if (e->PadN && mark_size > e->Pad[0].Thickness / 2)
601 mark_size = e->Pad[0].Thickness / 2;
603 gui->set_color (Output.fgGC,
604 invisible ? PCB->InvisibleMarkColor : PCB->ElementColor);
605 gui->set_line_cap (Output.fgGC, Trace_Cap);
606 gui->set_line_width (Output.fgGC, 1);
607 gui->draw_line (Output.fgGC, X - mark_size, Y, X, Y - mark_size);
608 gui->draw_line (Output.fgGC, X + mark_size, Y, X, Y - mark_size);
609 gui->draw_line (Output.fgGC, X - mark_size, Y, X, Y + mark_size);
610 gui->draw_line (Output.fgGC, X + mark_size, Y, X, Y + mark_size);
613 static int
614 via_callback (const BoxType * b, void *cl)
616 PinTypePtr via = (PinTypePtr) b;
617 if (via->Mask)
618 DrawPlainVia (via, False);
619 return 1;
622 static int
623 pin_callback (const BoxType * b, void *cl)
625 DrawPlainPin ((PinTypePtr) b, False);
626 return 1;
629 static int
630 pad_callback (const BoxType * b, void *cl)
632 PadTypePtr pad = (PadTypePtr) b;
633 if (FRONT (pad))
634 DrawPad (pad, 0);
635 return 1;
638 /* ---------------------------------------------------------------------------
639 * draws pins pads and vias
641 static void
642 DrawTop (const BoxType * screen)
644 if (PCB->PinOn || doing_assy)
646 /* draw element pins */
647 r_search (PCB->Data->pin_tree, screen, NULL, pin_callback, NULL);
648 /* draw element pads */
649 r_search (PCB->Data->pad_tree, screen, NULL, pad_callback, NULL);
651 /* draw vias */
652 if (PCB->ViaOn || doing_assy)
654 r_search (PCB->Data->via_tree, screen, NULL, via_callback, NULL);
655 r_search (PCB->Data->via_tree, screen, NULL, hole_callback, NULL);
657 if (PCB->PinOn || doing_assy)
658 r_search (PCB->Data->pin_tree, screen, NULL, hole_callback, NULL);
661 struct pin_info
663 Boolean arg;
664 LayerTypePtr Layer;
667 static int
668 clearPin_callback (const BoxType * b, void *cl)
670 PinTypePtr pin = (PinTypePtr) b;
671 struct pin_info *i = (struct pin_info *) cl;
672 if (i->arg)
673 ClearOnlyPin (pin, True);
674 return 1;
676 static int
677 poly_callback (const BoxType * b, void *cl)
679 struct pin_info *i = (struct pin_info *) cl;
681 DrawPlainPolygon (i->Layer, (PolygonTypePtr) b);
682 return 1;
685 static int
686 clearPad_callback (const BoxType * b, void *cl)
688 PadTypePtr pad = (PadTypePtr) b;
689 if (!XOR (TEST_FLAG (ONSOLDERFLAG, pad), SWAP_IDENT))
690 ClearPad (pad, True);
691 return 1;
694 /* ---------------------------------------------------------------------------
695 * Draws silk layer.
698 static void
699 DrawSilk (int new_swap, int layer, BoxTypePtr drawn_area)
701 #if 0
702 /* This code is used when you want to mask silk to avoid exposed
703 pins and pads. We decided it was a bad idea to do this
704 unconditionally, but the code remains. */
705 struct pin_info info;
706 #endif
707 int save_swap = SWAP_IDENT;
708 SWAP_IDENT = new_swap;
710 #if 0
711 if (gui->poly_before)
713 gui->use_mask (HID_MASK_BEFORE);
714 #endif
715 DrawLayer (LAYER_PTR (max_layer + layer), drawn_area);
716 /* draw package */
717 r_search (PCB->Data->element_tree, drawn_area, NULL, frontE_callback,
718 NULL);
719 r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL,
720 frontN_callback, NULL);
721 #if 0
724 gui->use_mask (HID_MASK_CLEAR);
725 info.arg = True;
726 r_search (PCB->Data->pin_tree, drawn_area, NULL, clearPin_callback, &info);
727 r_search (PCB->Data->via_tree, drawn_area, NULL, clearPin_callback, &info);
728 r_search (PCB->Data->pad_tree, drawn_area, NULL, clearPad_callback, &info);
730 if (gui->poly_after)
732 gui->use_mask (HID_MASK_AFTER);
733 DrawLayer (LAYER_PTR (max_layer + layer), drawn_area);
734 /* draw package */
735 r_search (PCB->Data->element_tree, drawn_area, NULL, frontE_callback,
736 NULL);
737 r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL,
738 frontN_callback, NULL);
740 gui->use_mask (HID_MASK_OFF);
741 #endif
742 SWAP_IDENT = save_swap;
745 /* ---------------------------------------------------------------------------
746 * draws solder mask layer - this will cover nearly everything
748 static void
749 DrawMask (BoxType * screen)
751 struct pin_info info;
753 OutputType *out = &Output;
755 info.arg = True;
757 if (gui->poly_before)
759 gui->use_mask (HID_MASK_BEFORE);
760 gui->set_color (out->fgGC, PCB->MaskColor);
761 gui->fill_rect (out->fgGC, 0, 0, PCB->MaxWidth, PCB->MaxHeight);
764 gui->use_mask (HID_MASK_CLEAR);
765 r_search (PCB->Data->pin_tree, screen, NULL, clearPin_callback, &info);
766 r_search (PCB->Data->via_tree, screen, NULL, clearPin_callback, &info);
767 r_search (PCB->Data->pad_tree, screen, NULL, clearPad_callback, &info);
769 if (gui->poly_after)
771 gui->use_mask (HID_MASK_AFTER);
772 gui->set_color (out->fgGC, PCB->MaskColor);
773 gui->fill_rect (out->fgGC, 0, 0, PCB->MaxWidth, PCB->MaxHeight);
776 gui->use_mask (HID_MASK_OFF);
779 static int
780 line_callback (const BoxType * b, void *cl)
782 DrawLine ((LayerTypePtr) cl, (LineTypePtr) b, 0);
783 return 1;
786 static int
787 arc_callback (const BoxType * b, void *cl)
789 DrawArc ((LayerTypePtr) cl, (ArcTypePtr) b, 0);
790 return 1;
793 static int
794 text_callback (const BoxType * b, void *cl)
796 DrawRegularText ((LayerTypePtr) cl, (TextTypePtr) b, 0);
797 return 1;
801 /* ---------------------------------------------------------------------------
802 * draws one non-copper layer
804 static void
805 DrawLayer (LayerTypePtr Layer, BoxType * screen)
807 struct pin_info info;
809 /* print the non-clearing polys */
810 info.Layer = Layer;
811 info.arg = False;
812 clip_box = screen;
813 r_search (Layer->polygon_tree, screen, NULL, poly_callback, &info);
815 /* draw all visible lines this layer */
816 r_search (Layer->line_tree, screen, NULL, line_callback, Layer);
818 /* draw the layer arcs on screen */
819 r_search (Layer->arc_tree, screen, NULL, arc_callback, Layer);
821 /* draw the layer text on screen */
822 r_search (Layer->text_tree, screen, NULL, text_callback, Layer);
823 clip_box = NULL;
826 /* ---------------------------------------------------------------------------
827 * draws one layer group. Returns non-zero if pins and pads should be
828 * drawn with this group.
830 static int
831 DrawLayerGroup (int group, const BoxType * screen)
833 int i, rv = 1;
834 int layernum;
835 struct pin_info info;
836 LayerTypePtr Layer;
837 int n_entries = PCB->LayerGroups.Number[group];
838 Cardinal *layers = PCB->LayerGroups.Entries[group];
840 clip_box = screen;
841 for (i = n_entries - 1; i >= 0; i--)
843 layernum = layers[i];
844 Layer = PCB->Data->Layer + layers[i];
845 if (strcmp (Layer->Name, "outline") == 0
846 || strcmp (Layer->Name, "route") == 0)
847 rv = 0;
848 if (layernum < max_layer && Layer->On)
850 /* draw all polygons on this layer */
851 if (Layer->PolygonN)
853 info.Layer = Layer;
854 info.arg = True;
855 r_search (Layer->polygon_tree, screen, NULL, poly_callback,
856 &info);
857 info.arg = False;
860 if (TEST_FLAG (CHECKPLANESFLAG, PCB))
861 continue;
863 /* draw all visible lines this layer */
864 r_search (Layer->line_tree, screen, NULL, line_callback, Layer);
866 /* draw the layer arcs on screen */
867 r_search (Layer->arc_tree, screen, NULL, arc_callback, Layer);
869 /* draw the layer text on screen */
870 r_search (Layer->text_tree, screen, NULL, text_callback, Layer);
874 if (n_entries > 1)
875 rv = 1;
876 return rv;
879 /* ---------------------------------------------------------------------------
880 * draws one polygon
881 * x and y are already in display coordinates
882 * the points are numbered:
884 * 5 --- 6
885 * / \
886 * 4 7
887 * | |
888 * 3 0
889 * \ /
890 * 2 --- 1
892 static void
893 DrawSpecialPolygon (HID * hid, hidGC DrawGC,
894 LocationType X, LocationType Y, int Thickness)
896 static FloatPolyType p[8] = {
898 0.5, -TAN_22_5_DEGREE_2},
900 TAN_22_5_DEGREE_2, -0.5},
902 -TAN_22_5_DEGREE_2, -0.5},
904 -0.5, -TAN_22_5_DEGREE_2},
906 -0.5, TAN_22_5_DEGREE_2},
908 -TAN_22_5_DEGREE_2, 0.5},
910 TAN_22_5_DEGREE_2, 0.5},
912 0.5, TAN_22_5_DEGREE_2}
914 static int special_size = 0;
915 static int scaled_x[8];
916 static int scaled_y[8];
917 int polygon_x[9];
918 int polygon_y[9];
919 int i;
922 if (Thickness != special_size)
924 special_size = Thickness;
925 for (i = 0; i < 8; i++)
927 scaled_x[i] = p[i].X * special_size;
928 scaled_y[i] = p[i].Y * special_size;
931 /* add line offset */
932 for (i = 0; i < 8; i++)
934 polygon_x[i] = X + scaled_x[i];
935 polygon_y[i] = Y + scaled_y[i];
937 if (TEST_FLAG (THINDRAWFLAG, PCB))
939 int i;
940 hid->set_line_cap (Output.fgGC, Round_Cap);
941 hid->set_line_width (Output.fgGC, 1);
942 polygon_x[8] = X + scaled_x[0];
943 polygon_y[8] = Y + scaled_y[0];
944 for (i = 0; i < 8; i++)
945 hid->draw_line (DrawGC, polygon_x[i], polygon_y[i],
946 polygon_x[i + 1], polygon_y[i + 1]);
948 else
949 hid->fill_polygon (DrawGC, 8, polygon_x, polygon_y);
952 /* ---------------------------------------------------------------------------
953 * lowlevel drawing routine for pins and vias
955 static void
956 DrawPinOrViaLowLevel (PinTypePtr Ptr, Boolean drawHole)
958 if (Gathering)
960 AddPart (Ptr);
961 return;
964 if (TEST_FLAG (HOLEFLAG, Ptr))
966 if (drawHole)
968 gui->fill_circle (Output.bgGC, Ptr->X, Ptr->Y, Ptr->Thickness / 2);
969 gui->set_line_cap (Output.fgGC, Round_Cap);
970 gui->set_line_width (Output.fgGC, 1);
971 gui->draw_arc (Output.fgGC, Ptr->X, Ptr->Y,
972 Ptr->Thickness / 2, Ptr->Thickness / 2, 0, 360);
974 return;
976 if (TEST_FLAG (SQUAREFLAG, Ptr))
978 int l, r, t, b;
979 l = Ptr->X - Ptr->Thickness / 2;
980 b = Ptr->Y - Ptr->Thickness / 2;
981 r = l + Ptr->Thickness;
982 t = b + Ptr->Thickness;
983 if (TEST_FLAG (THINDRAWFLAG, PCB))
985 gui->set_line_cap (Output.fgGC, Round_Cap);
986 gui->set_line_width (Output.fgGC, 1);
987 gui->draw_line (Output.fgGC, r, t, r, b);
988 gui->draw_line (Output.fgGC, l, t, l, b);
989 gui->draw_line (Output.fgGC, r, t, l, t);
990 gui->draw_line (Output.fgGC, r, b, l, b);
992 else
994 gui->fill_rect (Output.fgGC, l, b, r, t);
997 else if (TEST_FLAG (OCTAGONFLAG, Ptr))
999 gui->set_line_cap (Output.fgGC, Round_Cap);
1000 gui->set_line_width (Output.fgGC,
1001 (Ptr->Thickness - Ptr->DrillingHole) / 2);
1003 /* transform X11 specific coord system */
1004 DrawSpecialPolygon (gui, Output.fgGC, Ptr->X, Ptr->Y, Ptr->Thickness);
1006 else
1007 { /* draw a round pin or via */
1008 if (TEST_FLAG (THINDRAWFLAG, PCB))
1010 gui->set_line_cap (Output.fgGC, Round_Cap);
1011 gui->set_line_width (Output.fgGC, 1);
1012 gui->draw_arc (Output.fgGC, Ptr->X, Ptr->Y,
1013 Ptr->Thickness / 2, Ptr->Thickness / 2, 0, 360);
1015 else
1017 gui->fill_circle (Output.fgGC, Ptr->X, Ptr->Y, Ptr->Thickness / 2);
1021 /* and the drilling hole (which is always round */
1022 if (drawHole)
1024 if (TEST_FLAG (THINDRAWFLAG, PCB))
1026 gui->set_line_cap (Output.fgGC, Round_Cap);
1027 gui->set_line_width (Output.fgGC, 1);
1028 gui->draw_arc (Output.fgGC,
1029 Ptr->X, Ptr->Y, Ptr->DrillingHole / 2,
1030 Ptr->DrillingHole / 2, 0, 360);
1032 else
1034 gui->fill_circle (Output.bgGC, Ptr->X, Ptr->Y,
1035 Ptr->DrillingHole / 2);
1040 /**************************************************************
1041 * draw pin/via hole
1043 static void
1044 DrawHole (PinTypePtr Ptr)
1046 if (TEST_FLAG (THINDRAWFLAG, PCB))
1048 if (!TEST_FLAG (HOLEFLAG, Ptr))
1050 gui->set_line_cap (Output.fgGC, Round_Cap);
1051 gui->set_line_width (Output.fgGC, 1);
1052 gui->draw_arc (Output.fgGC,
1053 Ptr->X, Ptr->Y, Ptr->DrillingHole / 2,
1054 Ptr->DrillingHole / 2, 0, 360);
1057 else
1059 gui->fill_circle (Output.bgGC, Ptr->X, Ptr->Y, Ptr->DrillingHole / 2);
1061 if (TEST_FLAG (HOLEFLAG, Ptr))
1063 if (TEST_FLAG (WARNFLAG, Ptr))
1064 gui->set_color (Output.fgGC, PCB->WarnColor);
1065 else if (TEST_FLAG (SELECTEDFLAG, Ptr))
1066 gui->set_color (Output.fgGC, PCB->ViaSelectedColor);
1067 else
1068 gui->set_color (Output.fgGC, Settings.BlackColor);
1070 gui->set_line_cap (Output.fgGC, Round_Cap);
1071 gui->set_line_width (Output.fgGC, 1);
1072 gui->draw_arc (Output.fgGC,
1073 Ptr->X, Ptr->Y, Ptr->DrillingHole / 2,
1074 Ptr->DrillingHole / 2, 0, 360);
1078 /*******************************************************************
1079 * draw clearance in pixmask around pins and vias that pierce polygons
1081 static void
1082 ClearOnlyPin (PinTypePtr Pin, Boolean mask)
1084 BDimension half =
1085 (mask ? Pin->Mask / 2 : (Pin->Thickness + Pin->Clearance) / 2);
1087 if (!mask && TEST_FLAG (HOLEFLAG, Pin))
1088 return;
1089 if (half == 0)
1090 return;
1091 if (!mask && Pin->Clearance <= 0)
1092 return;
1094 /* Clear the area around the pin */
1095 if (TEST_FLAG (SQUAREFLAG, Pin))
1097 int l, r, t, b;
1098 l = Pin->X - half;
1099 b = Pin->Y - half;
1100 r = l + half * 2;
1101 t = b + half * 2;
1102 gui->fill_rect (Output.pmGC, l, b, r, t);
1104 else if (TEST_FLAG (OCTAGONFLAG, Pin))
1106 gui->set_line_cap (Output.pmGC, Round_Cap);
1107 gui->set_line_width (Output.pmGC, (Pin->Clearance + Pin->Thickness
1108 - Pin->DrillingHole));
1110 DrawSpecialPolygon (gui, Output.pmGC, Pin->X, Pin->Y, half * 2);
1112 else
1114 gui->fill_circle (Output.pmGC, Pin->X, Pin->Y, half);
1118 /* ---------------------------------------------------------------------------
1119 * lowlevel drawing routine for pins and vias that pierce polygons
1121 void
1122 ClearPin (PinTypePtr Pin, int Type, int unused)
1124 BDimension half = (Pin->Thickness + Pin->Clearance) / 2;
1126 if (Gathering)
1128 AddPart (Pin);
1129 return;
1131 /* Clear the area around the pin */
1132 if (TEST_FLAG (SQUAREFLAG, Pin))
1134 int l, r, t, b;
1135 l = Pin->X - half;
1136 b = Pin->Y - half;
1137 r = l + half * 2;
1138 t = b + half * 2;
1139 gui->fill_rect (Output.pmGC, l, b, r, t);
1141 else if (TEST_FLAG (OCTAGONFLAG, Pin))
1143 gui->set_line_cap (Output.pmGC, Round_Cap);
1144 gui->set_line_width (Output.pmGC, (Pin->Clearance + Pin->Thickness
1145 - Pin->DrillingHole) / 2);
1147 DrawSpecialPolygon (gui, Output.pmGC, Pin->X, Pin->Y, half * 2);
1149 else
1151 gui->fill_circle (Output.pmGC, Pin->X, Pin->Y, half);
1153 if ((!TEST_FLAG (PINFLAG, Pin) && !PCB->ViaOn)
1154 || (TEST_FLAG (PINFLAG, Pin) && !PCB->PinOn))
1155 return;
1156 /* now draw the pin or via as appropriate */
1157 switch (Type)
1159 case VIA_TYPE:
1160 case PIN_TYPE:
1161 SetPVColor (Pin, Type);
1162 DrawPinOrViaLowLevel (Pin, True);
1163 break;
1164 case NO_TYPE:
1165 default:
1166 break;
1171 #if VERTICAL_TEXT
1172 /* vertical text handling provided by Martin Devera with fixes by harry eaton */
1174 /* draw vertical text; xywh is bounding, de is text's descend used for
1175 positioning */
1176 static void
1177 DrawVText (int x, int y, int w, int h, char *str)
1179 GdkPixmap *pm;
1180 GdkImage *im;
1181 GdkGCValues values;
1182 guint32 pixel;
1183 int i, j;
1185 if (!str || !*str)
1186 return;
1188 pm = gdk_pixmap_new (DrawingWindow, w, h, -1);
1190 /* draw into pixmap */
1191 gdk_draw_rectangle (pm, Output.bgGC, TRUE, 0, 0, w, h);
1193 gui_draw_string_markup (DrawingWindow, Output.font_desc, Output.fgGC,
1194 0, 0, str);
1196 im = gdk_drawable_get_image (pm, 0, 0, w, h);
1197 gdk_gc_get_values (Output.fgGC, &values);
1199 /* draw Transpose(im). TODO: Pango should be doing vertical text soon */
1200 for (i = 0; i < w; i++)
1201 for (j = 0; j < h; j++)
1203 pixel = gdk_image_get_pixel (im, i, j);
1204 if (pixel == values.foreground.pixel)
1205 gdk_draw_point (DrawingWindow, Output.fgGC, x + j, y + w - i - 1);
1207 g_object_unref (G_OBJECT (pm));
1209 #endif
1211 /* ---------------------------------------------------------------------------
1212 * lowlevel drawing routine for pin and via names
1214 static void
1215 DrawPinOrViaNameLowLevel (PinTypePtr Ptr)
1217 char *name;
1218 BoxType box;
1219 Boolean vert;
1220 TextType text;
1222 if (!Ptr->Name || !Ptr->Name[0])
1223 name = EMPTY (Ptr->Number);
1224 else
1225 name = EMPTY (TEST_FLAG (SHOWNUMBERFLAG, PCB) ? Ptr->Number : Ptr->Name);
1227 vert = TEST_FLAG (EDGE2FLAG, Ptr);
1229 if (vert)
1231 box.X1 = Ptr->X - Ptr->Thickness / 2 + Settings.PinoutTextOffsetY;
1232 box.Y1 = Ptr->Y - Ptr->DrillingHole / 2 - Settings.PinoutTextOffsetX;
1234 else
1236 box.X1 = Ptr->X + Ptr->DrillingHole / 2 + Settings.PinoutTextOffsetX;
1237 box.Y1 = Ptr->Y - Ptr->Thickness / 2 + Settings.PinoutTextOffsetY;
1239 if (Gathering)
1241 if (vert)
1243 box.X2 = box.X1;
1244 box.Y2 = box.Y1;
1246 else
1248 box.X2 = box.X1;
1249 box.Y2 = box.Y1;
1251 /*printf("AddPart: x1=%d y1=%d x2=%d y2=%d\n", box.X1, box.Y1, box.X2, box.Y2);*/
1252 AddPart (&box);
1253 return;
1255 /*printf("DrawPin(%d,%d): x=%d y=%d w=%d h=%d\n",
1256 TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y), box.X1, box.Y1, width, height);*/
1258 gui->set_color (Output.fgGC, PCB->PinNameColor);
1260 text.Flags = NoFlags ();
1261 text.Scale = Ptr->Thickness / 80;
1262 text.X = box.X1;
1263 text.Y = box.Y1;
1264 text.Direction = vert ? 1 : 0;
1265 text.TextString = name;
1267 if (gui->gui)
1268 doing_pinout++;
1269 DrawTextLowLevel (&text, 0);
1270 if (gui->gui)
1271 doing_pinout--;
1274 /* ---------------------------------------------------------------------------
1275 * lowlevel drawing routine for pads
1278 static void
1279 DrawPadLowLevel (PadTypePtr Pad)
1281 if (Gathering)
1283 AddPart (Pad);
1284 return;
1287 if (TEST_FLAG (THINDRAWFLAG, PCB))
1289 int x1, y1, x2, y2, t, t2;
1290 t = Pad->Thickness / 2;
1291 t2 = Pad->Thickness - t;
1292 x1 = Pad->Point1.X;
1293 y1 = Pad->Point1.Y;
1294 x2 = Pad->Point2.X;
1295 y2 = Pad->Point2.Y;
1296 if (x1 > x2 || y1 > y2)
1298 /* this is a silly way to swap the variables */
1299 x1 ^= x2;
1300 x2 ^= x1;
1301 x1 ^= x2;
1302 y1 ^= y2;
1303 y2 ^= y1;
1304 y1 ^= y2;
1306 gui->set_line_cap (Output.fgGC, Round_Cap);
1307 gui->set_line_width (Output.fgGC, 1);
1308 if (TEST_FLAG (SQUAREFLAG, Pad))
1310 x1 -= t;
1311 y1 -= t;
1312 x2 += t2;
1313 y2 += t2;
1314 gui->draw_line (Output.fgGC, x1, y1, x1, y2);
1315 gui->draw_line (Output.fgGC, x1, y2, x2, y2);
1316 gui->draw_line (Output.fgGC, x2, y2, x2, y1);
1317 gui->draw_line (Output.fgGC, x2, y1, x1, y1);
1319 else if (x1 == x2 && y1 == y2)
1321 gui->draw_arc (Output.fgGC, x1, y1,
1322 Pad->Thickness / 2, Pad->Thickness / 2, 0, 360);
1324 else if (x1 == x2)
1326 gui->draw_line (Output.fgGC, x1 - t, y1, x2 - t, y2);
1327 gui->draw_line (Output.fgGC, x1 + t2, y1, x2 + t2, y2);
1328 gui->draw_arc (Output.fgGC, x1, y1,
1329 Pad->Thickness / 2, Pad->Thickness / 2, 0, -180);
1330 gui->draw_arc (Output.fgGC, x2, y2,
1331 Pad->Thickness / 2, Pad->Thickness / 2, 180, -180);
1333 else
1335 gui->draw_line (Output.fgGC, x1, y1 - t, x2, y2 - t);
1336 gui->draw_line (Output.fgGC, x1, y1 + t2, x2, y2 + t2);
1337 gui->draw_arc (Output.fgGC, x1, y1,
1338 Pad->Thickness / 2, Pad->Thickness / 2, 90, -180);
1339 gui->draw_arc (Output.fgGC, x2, y2,
1340 Pad->Thickness / 2, Pad->Thickness / 2, 270, -180);
1343 else if (Pad->Point1.X == Pad->Point2.X
1344 && Pad->Point1.Y == Pad->Point2.Y)
1346 if (TEST_FLAG (SQUAREFLAG, Pad))
1348 int l, r, t, b;
1349 l = Pad->Point1.X - Pad->Thickness / 2;
1350 b = Pad->Point1.Y - Pad->Thickness / 2;
1351 r = l + Pad->Thickness;
1352 t = b + Pad->Thickness;
1353 gui->fill_rect (Output.fgGC, l, b, r, t);
1355 else
1357 gui->fill_circle (Output.fgGC,
1358 Pad->Point1.X, Pad->Point1.Y, Pad->Thickness / 2);
1361 else
1363 gui->set_line_cap (Output.fgGC,
1364 TEST_FLAG (SQUAREFLAG,
1365 Pad) ? Square_Cap : Round_Cap);
1366 gui->set_line_width (Output.fgGC, Pad->Thickness);
1368 gui->draw_line (Output.fgGC,
1369 Pad->Point1.X, Pad->Point1.Y,
1370 Pad->Point2.X, Pad->Point2.Y);
1374 /* ---------------------------------------------------------------------------
1375 * lowlevel drawing routine for pad names
1378 static void
1379 DrawPadNameLowLevel (PadTypePtr Pad)
1381 BoxType box;
1382 char *name;
1383 Boolean vert;
1384 TextType text;
1386 if (!Pad->Name || !Pad->Name[0])
1387 name = EMPTY (Pad->Number);
1388 else
1389 name = EMPTY (TEST_FLAG (SHOWNUMBERFLAG, PCB) ? Pad->Number : Pad->Name);
1391 /* should text be vertical ? */
1392 vert = (Pad->Point1.X == Pad->Point2.X);
1394 if (vert)
1396 box.X1 = Pad->Point1.X - Pad->Thickness / 2;
1397 box.Y1 = MAX (Pad->Point1.Y, Pad->Point2.Y) + Pad->Thickness / 2;
1399 else
1401 box.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - Pad->Thickness / 2;
1402 box.Y1 = Pad->Point1.Y - Pad->Thickness / 2;
1405 if (vert)
1407 box.X1 += Settings.PinoutTextOffsetY;
1408 box.Y1 -= Settings.PinoutTextOffsetX;
1410 else
1412 box.X1 += Settings.PinoutTextOffsetX;
1413 box.Y1 += Settings.PinoutTextOffsetY;
1416 if (Gathering)
1418 if (vert)
1420 box.X2 = box.X1;
1421 box.Y2 = box.Y1;
1423 else
1425 box.X2 = box.X1;
1426 box.Y2 = box.Y1;
1428 AddPart (&box);
1429 return;
1432 gui->set_color (Output.fgGC, PCB->PinNameColor);
1434 text.Flags = NoFlags ();
1435 text.Scale = Pad->Thickness / 50;
1436 text.X = box.X1;
1437 text.Y = box.Y1;
1438 text.Direction = vert ? 1 : 0;
1439 text.TextString = name;
1441 DrawTextLowLevel (&text, 0);
1445 /* ---------------------------------------------------------------------------
1446 * clearance for pads
1448 static void
1449 ClearPad (PadTypePtr Pad, Boolean mask)
1451 int w = mask ? Pad->Mask : Pad->Thickness + Pad->Clearance;
1453 if (Pad->Point1.X == Pad->Point2.X
1454 && Pad->Point1.Y == Pad->Point2.Y)
1456 if (TEST_FLAG (SQUAREFLAG, Pad))
1458 int l, r, t, b;
1459 l = Pad->Point1.X - w;
1460 b = Pad->Point1.Y - w;
1461 r = l + w * 2;
1462 t = b + w * 2;
1463 gui->fill_rect (Output.pmGC, l, b, r, t);
1465 else
1467 gui->fill_circle (Output.pmGC, Pad->Point1.X, Pad->Point1.Y, w / 2);
1470 else
1472 gui->set_line_cap (Output.pmGC,
1473 TEST_FLAG (SQUAREFLAG,
1474 Pad) ? Square_Cap : Round_Cap);
1475 gui->set_line_width (Output.pmGC, w);
1476 gui->draw_line (Output.pmGC,
1477 Pad->Point1.X, Pad->Point1.Y,
1478 Pad->Point2.X, Pad->Point2.Y);
1482 /* ---------------------------------------------------------------------------
1483 * lowlevel drawing routine for lines
1485 static void
1486 DrawLineLowLevel (LineTypePtr Line, Boolean HaveGathered)
1488 if (Gathering && !HaveGathered)
1490 AddPart (Line);
1491 return;
1494 gui->set_line_cap (Output.fgGC, Trace_Cap);
1495 if (TEST_FLAG (THINDRAWFLAG, PCB))
1496 gui->set_line_width (Output.fgGC, 1);
1497 else
1498 gui->set_line_width (Output.fgGC, Line->Thickness);
1500 gui->draw_line (Output.fgGC,
1501 Line->Point1.X, Line->Point1.Y,
1502 Line->Point2.X, Line->Point2.Y);
1505 /* ---------------------------------------------------------------------------
1506 * lowlevel drawing routine for text objects
1508 void
1509 DrawTextLowLevel (TextTypePtr Text, int min_line_width)
1511 LocationType x = 0;
1512 unsigned char *string = (unsigned char *) Text->TextString;
1513 Cardinal n;
1514 FontTypePtr font = &PCB->Font;
1516 if (Gathering)
1518 AddPart (Text);
1519 return;
1522 while (string && *string)
1524 /* draw lines if symbol is valid and data is present */
1525 if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid)
1527 LineTypePtr line = font->Symbol[*string].Line;
1528 LineType newline;
1530 for (n = font->Symbol[*string].LineN; n; n--, line++)
1532 /* create one line, scale, move, rotate and swap it */
1533 newline = *line;
1534 newline.Point1.X = (newline.Point1.X + x) * Text->Scale / 100;
1535 newline.Point1.Y = newline.Point1.Y * Text->Scale / 100;
1536 newline.Point2.X = (newline.Point2.X + x) * Text->Scale / 100;
1537 newline.Point2.Y = newline.Point2.Y * Text->Scale / 100;
1538 newline.Thickness = newline.Thickness * Text->Scale / 200;
1539 if (newline.Thickness < min_line_width)
1540 newline.Thickness = min_line_width;
1542 RotateLineLowLevel (&newline, 0, 0, Text->Direction);
1544 /* the labels of SMD objects on the bottom
1545 * side haven't been swapped yet, only their offset
1547 if (TEST_FLAG (ONSOLDERFLAG, Text))
1549 newline.Point1.X = SWAP_SIGN_X (newline.Point1.X);
1550 newline.Point1.Y = SWAP_SIGN_Y (newline.Point1.Y);
1551 newline.Point2.X = SWAP_SIGN_X (newline.Point2.X);
1552 newline.Point2.Y = SWAP_SIGN_Y (newline.Point2.Y);
1554 /* add offset and draw line */
1555 newline.Point1.X += Text->X;
1556 newline.Point1.Y += Text->Y;
1557 newline.Point2.X += Text->X;
1558 newline.Point2.Y += Text->Y;
1559 DrawLineLowLevel (&newline, True);
1562 /* move on to next cursor position */
1563 x += (font->Symbol[*string].Width + font->Symbol[*string].Delta);
1565 else
1567 /* the default symbol is a filled box */
1568 BoxType defaultsymbol = PCB->Font.DefaultSymbol;
1569 LocationType size = (defaultsymbol.X2 - defaultsymbol.X1) * 6 / 5;
1571 defaultsymbol.X1 = (defaultsymbol.X1 + x) * Text->Scale / 100;
1572 defaultsymbol.Y1 = defaultsymbol.Y1 * Text->Scale / 100;
1573 defaultsymbol.X2 = (defaultsymbol.X2 + x) * Text->Scale / 100;
1574 defaultsymbol.Y2 = defaultsymbol.Y2 * Text->Scale / 100;
1576 RotateBoxLowLevel (&defaultsymbol, 0, 0, Text->Direction);
1578 /* add offset and draw box */
1579 defaultsymbol.X1 += Text->X;
1580 defaultsymbol.Y1 += Text->Y;
1581 defaultsymbol.X2 += Text->X;
1582 defaultsymbol.Y2 += Text->Y;
1583 gui->fill_rect (Output.fgGC,
1584 defaultsymbol.X1, defaultsymbol.Y1,
1585 defaultsymbol.X2, defaultsymbol.Y2);
1587 /* move on to next cursor position */
1588 x += size;
1590 string++;
1594 /* ---------------------------------------------------------------------------
1595 * lowlevel drawing routine for polygons
1597 static void
1598 DrawPolygonLowLevel (PolygonTypePtr Polygon)
1600 int *x, *y, n, i = 0;
1601 PLINE *pl;
1602 VNODE *v;
1603 if (!Polygon->Clipped)
1604 return;
1605 if (Gathering)
1607 AddPart (Polygon);
1608 return;
1610 pl = Polygon->Clipped->contours;
1611 n = pl->Count;
1612 x = (int *) malloc (n * sizeof (int));
1613 y = (int *) malloc (n * sizeof (int));
1614 for (v = &pl->head; i < n; v = v->next)
1616 x[i] = v->point[0];
1617 y[i++] = v->point[1];
1619 if (TEST_FLAG (THINDRAWFLAG, PCB)
1620 || TEST_FLAG (THINDRAWPOLYFLAG, PCB))
1622 gui->set_line_width (Output.fgGC, 1);
1623 for (i = 0; i < n - 1; i++)
1625 gui->draw_line (Output.fgGC, x[i], y[i], x[i + 1], y[i + 1]);
1626 // gui->fill_circle (Output.fgGC, x[i], y[i], 30);
1628 gui->draw_line (Output.fgGC, x[n - 1], y[n - 1], x[0], y[0]);
1630 else
1631 gui->fill_polygon (Output.fgGC, n, x, y);
1632 free (x);
1633 free (y);
1636 /* ---------------------------------------------------------------------------
1637 * lowlevel routine to element arcs
1639 static void
1640 DrawArcLowLevel (ArcTypePtr Arc)
1642 if (!Arc->Thickness)
1643 return;
1644 if (Gathering)
1646 AddPart (Arc);
1647 return;
1650 if (TEST_FLAG (THINDRAWFLAG, PCB))
1651 gui->set_line_width (Output.fgGC, 1);
1652 else
1653 gui->set_line_width (Output.fgGC, Arc->Thickness);
1654 gui->set_line_cap (Output.fgGC, Trace_Cap);
1656 gui->draw_arc (Output.fgGC, Arc->X, Arc->Y, Arc->Width,
1657 Arc->Height, Arc->StartAngle, Arc->Delta);
1660 /* ---------------------------------------------------------------------------
1661 * draws the package of an element
1663 static void
1664 DrawElementPackageLowLevel (ElementTypePtr Element, int unused)
1666 /* draw lines, arcs, text and pins */
1667 ELEMENTLINE_LOOP (Element);
1669 DrawLineLowLevel (line, False);
1671 END_LOOP;
1672 ARC_LOOP (Element);
1674 DrawArcLowLevel (arc);
1676 END_LOOP;
1679 /* ---------------------------------------------------------------------------
1680 * draw a via object
1682 void
1683 DrawVia (PinTypePtr Via, int unused)
1685 if (!Gathering)
1686 SetPVColor (Via, VIA_TYPE);
1687 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Via) && TEST_ANY_PIPS (Via))
1688 // ClearPin (Via, VIA_TYPE, 0);
1689 //else
1690 DrawPinOrViaLowLevel (Via, True);
1691 if (!TEST_FLAG (HOLEFLAG, Via) && TEST_FLAG (DISPLAYNAMEFLAG, Via))
1692 DrawPinOrViaNameLowLevel (Via);
1695 /* ---------------------------------------------------------------------------
1696 * draw a via without dealing with polygon clearance
1698 static void
1699 DrawPlainVia (PinTypePtr Via, Boolean holeToo)
1701 if (!Gathering)
1702 SetPVColor (Via, VIA_TYPE);
1703 DrawPinOrViaLowLevel (Via, holeToo);
1704 if (!TEST_FLAG (HOLEFLAG, Via) && TEST_FLAG (DISPLAYNAMEFLAG, Via))
1705 DrawPinOrViaNameLowLevel (Via);
1708 /* ---------------------------------------------------------------------------
1709 * draws the name of a via
1711 void
1712 DrawViaName (PinTypePtr Via, int unused)
1714 if (!Gathering)
1716 if (TEST_FLAG (SELECTEDFLAG, Via))
1717 gui->set_color (Output.fgGC, PCB->ViaSelectedColor);
1718 else
1719 gui->set_color (Output.fgGC, PCB->ViaColor);
1721 DrawPinOrViaNameLowLevel (Via);
1724 /* ---------------------------------------------------------------------------
1725 * draw a pin object
1727 void
1728 DrawPin (PinTypePtr Pin, int unused)
1730 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Pin) && TEST_ANY_PIPS (Pin))
1731 // ClearPin (Pin, PIN_TYPE, 0);
1732 //else
1734 if (!Gathering)
1735 SetPVColor (Pin, PIN_TYPE);
1736 DrawPinOrViaLowLevel (Pin, True);
1738 if ((!TEST_FLAG (HOLEFLAG, Pin) && TEST_FLAG (DISPLAYNAMEFLAG, Pin))
1739 || doing_pinout)
1740 DrawPinOrViaNameLowLevel (Pin);
1743 /* ---------------------------------------------------------------------------
1744 * draw a pin without clearing around polygons
1746 static void
1747 DrawPlainPin (PinTypePtr Pin, Boolean holeToo)
1749 if (!Gathering)
1750 SetPVColor (Pin, PIN_TYPE);
1751 DrawPinOrViaLowLevel (Pin, holeToo);
1752 if (!TEST_FLAG (HOLEFLAG, Pin) && TEST_FLAG (DISPLAYNAMEFLAG, Pin))
1753 DrawPinOrViaNameLowLevel (Pin);
1756 /* ---------------------------------------------------------------------------
1757 * draws the name of a pin
1759 void
1760 DrawPinName (PinTypePtr Pin, int unused)
1762 if (!Gathering)
1764 if (TEST_FLAG (SELECTEDFLAG, Pin))
1765 gui->set_color (Output.fgGC, PCB->PinSelectedColor);
1766 else
1767 gui->set_color (Output.fgGC, PCB->PinColor);
1769 DrawPinOrViaNameLowLevel (Pin);
1772 /* ---------------------------------------------------------------------------
1773 * draw a pad object
1775 void
1776 DrawPad (PadTypePtr Pad, int unused)
1778 if (!Gathering)
1780 if (doing_pinout)
1781 gui->set_color (Output.fgGC, PCB->PinColor);
1782 else if (TEST_FLAG (WARNFLAG | SELECTEDFLAG | FOUNDFLAG, Pad))
1784 if (TEST_FLAG (WARNFLAG, Pad))
1785 gui->set_color (Output.fgGC, PCB->WarnColor);
1786 else if (TEST_FLAG (SELECTEDFLAG, Pad))
1787 gui->set_color (Output.fgGC, PCB->PinSelectedColor);
1788 else
1789 gui->set_color (Output.fgGC, PCB->ConnectedColor);
1791 else if (FRONT (Pad))
1792 gui->set_color (Output.fgGC, PCB->PinColor);
1793 else
1794 gui->set_color (Output.fgGC, PCB->InvisibleObjectsColor);
1796 DrawPadLowLevel (Pad);
1797 if (doing_pinout || TEST_FLAG (DISPLAYNAMEFLAG, Pad))
1798 DrawPadNameLowLevel (Pad);
1801 /* ---------------------------------------------------------------------------
1802 * draws the name of a pad
1804 void
1805 DrawPadName (PadTypePtr Pad, int unused)
1807 if (!Gathering)
1809 if (TEST_FLAG (SELECTEDFLAG, Pad))
1810 gui->set_color (Output.fgGC, PCB->PinSelectedColor);
1811 else if (FRONT (Pad))
1812 gui->set_color (Output.fgGC, PCB->PinColor);
1813 else
1814 gui->set_color (Output.fgGC, PCB->InvisibleObjectsColor);
1816 DrawPadNameLowLevel (Pad);
1819 /* ---------------------------------------------------------------------------
1820 * draws a line on a layer
1822 void
1823 DrawLine (LayerTypePtr Layer, LineTypePtr Line, int unused)
1825 if (!Gathering)
1827 if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Line))
1829 if (TEST_FLAG (SELECTEDFLAG, Line))
1830 gui->set_color (Output.fgGC, Layer->SelectedColor);
1831 else
1832 gui->set_color (Output.fgGC, PCB->ConnectedColor);
1834 else
1835 gui->set_color (Output.fgGC, Layer->Color);
1837 DrawLineLowLevel (Line, False);
1840 /* ---------------------------------------------------------------------------
1841 * draws a ratline
1843 void
1844 DrawRat (RatTypePtr Line, int unused)
1846 if (!Gathering)
1848 if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Line))
1850 if (TEST_FLAG (SELECTEDFLAG, Line))
1851 gui->set_color (Output.fgGC, PCB->RatSelectedColor);
1852 else
1853 gui->set_color (Output.fgGC, PCB->ConnectedColor);
1855 else
1856 gui->set_color (Output.fgGC, PCB->RatColor);
1858 if (Settings.RatThickness < 20)
1859 Line->Thickness = pixel_slop * Settings.RatThickness;
1860 DrawLineLowLevel ((LineTypePtr) Line, False);
1863 /* ---------------------------------------------------------------------------
1864 * draws an arc on a layer
1866 void
1867 DrawArc (LayerTypePtr Layer, ArcTypePtr Arc, int unused)
1869 if (!Arc->Thickness)
1870 return;
1871 if (!Gathering)
1873 if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Arc))
1875 if (TEST_FLAG (SELECTEDFLAG, Arc))
1876 gui->set_color (Output.fgGC, Layer->SelectedColor);
1877 else
1878 gui->set_color (Output.fgGC, PCB->ConnectedColor);
1880 else
1881 gui->set_color (Output.fgGC, Layer->Color);
1883 DrawArcLowLevel (Arc);
1886 /* ---------------------------------------------------------------------------
1887 * draws a text on a layer
1889 void
1890 DrawText (LayerTypePtr Layer, TextTypePtr Text, int unused)
1892 int min_silk_line;
1893 if (!Layer->On)
1894 return;
1895 if (TEST_FLAG (SELECTEDFLAG, Text))
1896 gui->set_color (Output.fgGC, Layer->SelectedColor);
1897 else
1898 gui->set_color (Output.fgGC, Layer->Color);
1899 if (Layer == & PCB->Data->SILKLAYER
1900 || Layer == & PCB->Data->BACKSILKLAYER)
1901 min_silk_line = PCB->minSlk;
1902 else
1903 min_silk_line = PCB->minWid;
1904 DrawTextLowLevel (Text, min_silk_line);
1907 /* ---------------------------------------------------------------------------
1908 * draws text on a layer
1910 static void
1911 DrawRegularText (LayerTypePtr Layer, TextTypePtr Text, int unused)
1913 int min_silk_line;
1914 if (TEST_FLAG (SELECTEDFLAG, Text))
1915 gui->set_color (Output.fgGC, Layer->SelectedColor);
1916 else
1917 gui->set_color (Output.fgGC, Layer->Color);
1918 if (Layer == & PCB->Data->SILKLAYER
1919 || Layer == & PCB->Data->BACKSILKLAYER)
1920 min_silk_line = PCB->minSlk;
1921 else
1922 min_silk_line = PCB->minWid;
1923 DrawTextLowLevel (Text, min_silk_line);
1926 static int
1927 cp_callback (const BoxType * b, void *cl)
1929 ClearPin ((PinTypePtr) b, (int) (size_t) cl, 0);
1930 return 1;
1933 /* ---------------------------------------------------------------------------
1934 * draws a polygon on a layer
1936 void
1937 DrawPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon, int unused)
1939 int layernum;
1941 if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Polygon))
1943 if (TEST_FLAG (SELECTEDFLAG, Polygon))
1944 gui->set_color (Output.fgGC, Layer->SelectedColor);
1945 else
1946 gui->set_color (Output.fgGC, PCB->ConnectedColor);
1948 else
1949 gui->set_color (Output.fgGC, Layer->Color);
1950 layernum = GetLayerNumber (PCB->Data, Layer);
1951 DrawPolygonLowLevel (Polygon);
1952 if (TEST_FLAG (CLEARPOLYFLAG, Polygon))
1954 r_search (PCB->Data->pin_tree, &Polygon->BoundingBox, NULL,
1955 cp_callback, (void *) PIN_TYPE);
1956 r_search (PCB->Data->via_tree, &Polygon->BoundingBox, NULL,
1957 cp_callback, (void *) VIA_TYPE);
1962 thin_callback (PLINE * pl, LayerTypePtr lay, PolygonTypePtr poly)
1964 int i, *x, *y;
1965 VNODE *v;
1967 i = 0;
1968 x = (int *) malloc (pl->Count * sizeof (int));
1969 y = (int *) malloc (pl->Count * sizeof (int));
1970 for (v = &pl->head; i < pl->Count; v = v->next)
1972 x[i] = v->point[0];
1973 y[i++] = v->point[1];
1975 gui->set_line_width (Output.fgGC, 1);
1976 for (i = 0; i < pl->Count - 1; i++)
1978 gui->draw_line (Output.fgGC, x[i], y[i], x[i + 1], y[i + 1]);
1979 // gui->fill_circle (Output.fgGC, x[i], y[i], 30);
1981 gui->draw_line (Output.fgGC, x[pl->Count - 1], y[pl->Count - 1], x[0],
1982 y[0]);
1983 free (x);
1984 free (y);
1985 return 0;
1989 /* ---------------------------------------------------------------------------
1990 * draws a polygon
1992 static void
1993 DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
1995 if (TEST_FLAG (SELECTEDFLAG | FOUNDFLAG, Polygon))
1997 if (TEST_FLAG (SELECTEDFLAG, Polygon))
1998 gui->set_color (Output.fgGC, Layer->SelectedColor);
1999 else
2000 gui->set_color (Output.fgGC, PCB->ConnectedColor);
2002 else
2003 gui->set_color (Output.fgGC, Layer->Color);
2004 /* if the gui has the dicer flag set then it won't accept thin draw */
2005 if ((TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG (THINDRAWPOLYFLAG, PCB))
2006 && !gui->poly_dicer)
2008 DrawPolygonLowLevel (Polygon);
2009 if (!Gathering)
2010 PolygonHoles (clip_box, Layer, Polygon, thin_callback);
2012 else if (Polygon->Clipped)
2013 NoHolesPolygonDicer (Polygon, DrawPolygonLowLevel, clip_box);
2014 /* if the gui has the dicer flag set then it won't draw missing poly outlines */
2015 if (TEST_FLAG (CHECKPLANESFLAG, PCB) && Polygon->Clipped && !Gathering
2016 && !gui->poly_dicer)
2018 POLYAREA *pg;
2020 for (pg = Polygon->Clipped->f; pg != Polygon->Clipped; pg = pg->f)
2022 VNODE *v;
2023 PLINE *pl = pg->contours;
2024 int i = 0;
2025 int n = pl->Count;
2026 int *x = (int *) malloc (n * sizeof (int));
2027 int *y = (int *) malloc (n * sizeof (int));
2028 for (v = &pl->head; i < n; v = v->next)
2030 x[i] = v->point[0];
2031 y[i++] = v->point[1];
2033 gui->set_line_width (Output.fgGC, 1);
2034 for (i = 0; i < n - 1; i++)
2036 gui->draw_line (Output.fgGC, x[i], y[i], x[i + 1], y[i + 1]);
2037 /* gui->fill_circle (Output.bgGC, x[i], y[i], 10); */
2039 gui->draw_line (Output.fgGC, x[n - 1], y[n - 1], x[0], y[0]);
2040 free (x);
2041 free (y);
2046 /* ---------------------------------------------------------------------------
2047 * draws an element
2049 void
2050 DrawElement (ElementTypePtr Element, int unused)
2052 DrawElementPackage (Element, unused);
2053 DrawElementName (Element, unused);
2054 DrawElementPinsAndPads (Element, unused);
2057 /* ---------------------------------------------------------------------------
2058 * draws the name of an element
2060 void
2061 DrawElementName (ElementTypePtr Element, int unused)
2063 if (TEST_FLAG (HIDENAMEFLAG, Element))
2064 return;
2065 if (doing_pinout || doing_assy)
2066 gui->set_color (Output.fgGC, PCB->ElementColor);
2067 else if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, Element)))
2068 gui->set_color (Output.fgGC, PCB->ElementSelectedColor);
2069 else if (FRONT (Element))
2070 gui->set_color (Output.fgGC, PCB->ElementColor);
2071 else
2072 gui->set_color (Output.fgGC, PCB->InvisibleObjectsColor);
2073 DrawTextLowLevel (&ELEMENT_TEXT (PCB, Element), PCB->minSlk);
2076 /* ---------------------------------------------------------------------------
2077 * draws the package of an element
2079 void
2080 DrawElementPackage (ElementTypePtr Element, int unused)
2082 /* set color and draw lines, arcs, text and pins */
2083 if (doing_pinout || doing_assy)
2084 gui->set_color (Output.fgGC, PCB->ElementColor);
2085 else if (TEST_FLAG (SELECTEDFLAG, Element))
2086 gui->set_color (Output.fgGC, PCB->ElementSelectedColor);
2087 else if (FRONT (Element))
2088 gui->set_color (Output.fgGC, PCB->ElementColor);
2089 else
2090 gui->set_color (Output.fgGC, PCB->InvisibleObjectsColor);
2091 DrawElementPackageLowLevel (Element, unused);
2094 /* ---------------------------------------------------------------------------
2095 * draw pins of an element
2097 void
2098 DrawElementPinsAndPads (ElementTypePtr Element, int unused)
2100 PAD_LOOP (Element);
2102 if (doing_pinout || doing_assy || FRONT (pad) || PCB->InvisibleObjectsOn)
2103 DrawPad (pad, unused);
2105 END_LOOP;
2106 PIN_LOOP (Element);
2108 DrawPin (pin, unused);
2110 END_LOOP;
2113 /* ---------------------------------------------------------------------------
2114 * erase a via
2116 void
2117 EraseVia (PinTypePtr Via)
2119 Erasing++;
2120 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2121 DrawPinOrViaLowLevel (Via, False);
2122 if (TEST_FLAG (DISPLAYNAMEFLAG, Via))
2123 DrawPinOrViaNameLowLevel (Via);
2124 Erasing--;
2127 /* ---------------------------------------------------------------------------
2128 * erase a ratline
2130 void
2131 EraseRat (RatTypePtr Rat)
2133 Erasing++;
2134 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2135 DrawLineLowLevel ((LineTypePtr) Rat, False);
2136 Erasing--;
2140 /* ---------------------------------------------------------------------------
2141 * erase a via name
2143 void
2144 EraseViaName (PinTypePtr Via)
2146 Erasing++;
2147 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2148 DrawPinOrViaNameLowLevel (Via);
2149 Erasing--;
2152 /* ---------------------------------------------------------------------------
2153 * erase a pad object
2155 void
2156 ErasePad (PadTypePtr Pad)
2158 Erasing++;
2159 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2160 DrawPadLowLevel (Pad);
2161 if (TEST_FLAG (DISPLAYNAMEFLAG, Pad))
2162 DrawPadNameLowLevel (Pad);
2163 Erasing--;
2166 /* ---------------------------------------------------------------------------
2167 * erase a pad name
2169 void
2170 ErasePadName (PadTypePtr Pad)
2172 Erasing++;
2173 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2174 DrawPadNameLowLevel (Pad);
2175 Erasing--;
2178 /* ---------------------------------------------------------------------------
2179 * erase a pin object
2181 void
2182 ErasePin (PinTypePtr Pin)
2184 Erasing++;
2185 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2186 DrawPinOrViaLowLevel (Pin, False);
2187 if (TEST_FLAG (DISPLAYNAMEFLAG, Pin))
2188 DrawPinOrViaNameLowLevel (Pin);
2189 Erasing--;
2192 /* ---------------------------------------------------------------------------
2193 * erase a pin name
2195 void
2196 ErasePinName (PinTypePtr Pin)
2198 Erasing++;
2199 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2200 DrawPinOrViaNameLowLevel (Pin);
2201 Erasing--;
2204 /* ---------------------------------------------------------------------------
2205 * erases a line on a layer
2207 void
2208 EraseLine (LineTypePtr Line)
2210 Erasing++;
2211 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2212 DrawLineLowLevel (Line, False);
2213 Erasing--;
2216 /* ---------------------------------------------------------------------------
2217 * erases an arc on a layer
2219 void
2220 EraseArc (ArcTypePtr Arc)
2222 if (!Arc->Thickness)
2223 return;
2224 Erasing++;
2225 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2226 DrawArcLowLevel (Arc);
2227 Erasing--;
2230 /* ---------------------------------------------------------------------------
2231 * erases a text on a layer
2233 void
2234 EraseText (LayerTypePtr Layer, TextTypePtr Text)
2236 int min_silk_line;
2237 Erasing++;
2238 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2239 if (Layer == & PCB->Data->SILKLAYER
2240 || Layer == & PCB->Data->BACKSILKLAYER)
2241 min_silk_line = PCB->minSlk;
2242 else
2243 min_silk_line = PCB->minWid;
2244 DrawTextLowLevel (Text, min_silk_line);
2245 Erasing--;
2248 /* ---------------------------------------------------------------------------
2249 * erases a polygon on a layer
2251 void
2252 ErasePolygon (PolygonTypePtr Polygon)
2254 Erasing++;
2255 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2256 DrawPolygonLowLevel (Polygon);
2257 Erasing--;
2260 /* ---------------------------------------------------------------------------
2261 * erases an element
2263 void
2264 EraseElement (ElementTypePtr Element)
2266 Erasing++;
2267 /* set color and draw lines, arcs, text and pins */
2268 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2269 ELEMENTLINE_LOOP (Element);
2271 DrawLineLowLevel (line, False);
2273 END_LOOP;
2274 ARC_LOOP (Element);
2276 DrawArcLowLevel (arc);
2278 END_LOOP;
2279 if (!TEST_FLAG (HIDENAMEFLAG, Element))
2280 DrawTextLowLevel (&ELEMENT_TEXT (PCB, Element), PCB->minSlk);
2281 EraseElementPinsAndPads (Element);
2282 Erasing--;
2285 /* ---------------------------------------------------------------------------
2286 * erases all pins and pads of an element
2288 void
2289 EraseElementPinsAndPads (ElementTypePtr Element)
2291 Erasing++;
2292 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2293 PIN_LOOP (Element);
2295 /* if (TEST_ANY_PIPS (pin))
2297 ClearPin (pin, NO_TYPE, 0);
2298 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2301 DrawPinOrViaLowLevel (pin, False);
2302 if (TEST_FLAG (DISPLAYNAMEFLAG, pin))
2303 DrawPinOrViaNameLowLevel (pin);
2305 END_LOOP;
2306 PAD_LOOP (Element);
2308 DrawPadLowLevel (pad);
2309 if (TEST_FLAG (DISPLAYNAMEFLAG, pad))
2310 DrawPadNameLowLevel (pad);
2312 END_LOOP;
2313 Erasing--;
2316 /* ---------------------------------------------------------------------------
2317 * erases the name of an element
2319 void
2320 EraseElementName (ElementTypePtr Element)
2322 if (TEST_FLAG (HIDENAMEFLAG, Element))
2323 return;
2324 Erasing++;
2325 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2326 DrawTextLowLevel (&ELEMENT_TEXT (PCB, Element), PCB->minSlk);
2327 Erasing--;
2331 void
2332 EraseObject (int type, void *lptr, void *ptr)
2334 switch (type)
2336 case VIA_TYPE:
2337 case PIN_TYPE:
2338 ErasePin ((PinTypePtr) ptr);
2339 break;
2340 case TEXT_TYPE:
2341 case ELEMENTNAME_TYPE:
2342 EraseText (lptr, (TextTypePtr) ptr);
2343 break;
2344 case POLYGON_TYPE:
2345 ErasePolygon ((PolygonTypePtr) ptr);
2346 break;
2347 case ELEMENT_TYPE:
2348 EraseElement ((ElementTypePtr) ptr);
2349 break;
2350 case LINE_TYPE:
2351 case ELEMENTLINE_TYPE:
2352 case RATLINE_TYPE:
2353 EraseLine ((LineTypePtr) ptr);
2354 break;
2355 case PAD_TYPE:
2356 ErasePad ((PadTypePtr) ptr);
2357 break;
2358 case ARC_TYPE:
2359 case ELEMENTARC_TYPE:
2360 EraseArc ((ArcTypePtr) ptr);
2361 break;
2362 default:
2363 Message ("hace: Internal ERROR, trying to erase an unknown type\n");
2369 void
2370 DrawObject (int type, void *ptr1, void *ptr2, int unused)
2372 switch (type)
2374 case VIA_TYPE:
2375 if (PCB->ViaOn)
2376 DrawVia ((PinTypePtr) ptr2, 0);
2377 break;
2378 case LINE_TYPE:
2379 if (((LayerTypePtr) ptr1)->On)
2380 DrawLine ((LayerTypePtr) ptr1, (LineTypePtr) ptr2, 0);
2381 break;
2382 case ARC_TYPE:
2383 if (((LayerTypePtr) ptr1)->On)
2384 DrawArc ((LayerTypePtr) ptr1, (ArcTypePtr) ptr2, 0);
2385 break;
2386 case TEXT_TYPE:
2387 if (((LayerTypePtr) ptr1)->On)
2388 DrawText ((LayerTypePtr) ptr1, (TextTypePtr) ptr2, 0);
2389 break;
2390 case POLYGON_TYPE:
2391 if (((LayerTypePtr) ptr1)->On)
2392 DrawPolygon ((LayerTypePtr) ptr1, (PolygonTypePtr) ptr2, 0);
2393 break;
2394 case ELEMENT_TYPE:
2395 if (PCB->ElementOn &&
2396 (FRONT ((ElementTypePtr) ptr2) || PCB->InvisibleObjectsOn))
2397 DrawElement ((ElementTypePtr) ptr2, 0);
2398 break;
2399 case RATLINE_TYPE:
2400 if (PCB->RatOn)
2401 DrawRat ((RatTypePtr) ptr2, 0);
2402 break;
2403 case PIN_TYPE:
2404 if (PCB->PinOn)
2405 DrawPin ((PinTypePtr) ptr2, 0);
2406 break;
2407 case PAD_TYPE:
2408 if (PCB->PinOn)
2409 DrawPad ((PadTypePtr) ptr2, 0);
2410 break;
2411 case ELEMENTNAME_TYPE:
2412 if (PCB->ElementOn &&
2413 (FRONT ((ElementTypePtr) ptr2) || PCB->InvisibleObjectsOn))
2414 DrawElementName ((ElementTypePtr) ptr1, 0);
2415 break;
2419 /* ---------------------------------------------------------------------------
2420 * HID drawing callback.
2423 void
2424 hid_expose_callback (HID * hid, BoxType * region, void *item)
2426 HID *old_gui = gui;
2427 hidGC savebg = Output.bgGC;
2428 hidGC savefg = Output.fgGC;
2429 hidGC savepm = Output.pmGC;
2431 gui = hid;
2432 Output.fgGC = gui->make_gc ();
2433 Output.bgGC = gui->make_gc ();
2434 Output.pmGC = gui->make_gc ();
2436 render = True;
2437 Gathering = False;
2439 /*printf("\033[32mhid_expose_callback, s=%p %d\033[0m\n", &(SWAP_IDENT), SWAP_IDENT); */
2441 hid->set_color (Output.pmGC, "erase");
2442 hid->set_color (Output.bgGC, "drill");
2444 if (item)
2446 doing_pinout = True;
2447 DrawElement (item, 0);
2448 doing_pinout = False;
2450 else
2451 DrawEverything (region);
2453 gui->destroy_gc (Output.fgGC);
2454 gui->destroy_gc (Output.bgGC);
2455 gui->destroy_gc (Output.pmGC);
2456 gui = old_gui;
2457 Output.fgGC = savefg;
2458 Output.bgGC = savebg;
2459 Output.pmGC = savepm;