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
41 #include "crosshair.h"
53 #ifdef HAVE_LIBDMALLOC
59 #define SMALL_SMALL_TEXT_SIZE 0
60 #define SMALL_TEXT_SIZE 1
61 #define NORMAL_TEXT_SIZE 2
62 #define LARGE_TEXT_SIZE 3
63 #define N_TEXT_SIZES 4
66 /* ---------------------------------------------------------------------------
73 FloatPolyType
, *FloatPolyTypePtr
;
75 /* ---------------------------------------------------------------------------
76 * some local identifiers
79 static Boolean Gathering
= True
;
80 static int Erasing
= False
;
82 static int doing_pinout
= False
;
83 static int doing_assy
= False
;
84 static const BoxType
*clip_box
= NULL
;
86 /* ---------------------------------------------------------------------------
87 * some local prototypes
89 static void Redraw (Boolean
, BoxTypePtr
);
90 static void DrawEverything (BoxTypePtr
);
91 static void DrawTop (const BoxType
*);
92 static int DrawLayerGroup (int, const BoxType
*);
93 static void DrawPinOrViaLowLevel (PinTypePtr
, Boolean
);
94 static void ClearOnlyPin (PinTypePtr
, Boolean
);
95 static void DrawPlainPin (PinTypePtr
, Boolean
);
96 static void DrawPlainVia (PinTypePtr
, Boolean
);
97 static void DrawPinOrViaNameLowLevel (PinTypePtr
);
98 static void DrawPadLowLevel (hidGC
, PadTypePtr
, Boolean
, Boolean
);
99 static void DrawPadNameLowLevel (PadTypePtr
);
100 static void DrawLineLowLevel (LineTypePtr
, Boolean
);
101 static void DrawRegularText (LayerTypePtr
, TextTypePtr
, int);
102 static void DrawPolygonLowLevel (PolygonTypePtr
);
103 static void DrawArcLowLevel (ArcTypePtr
);
104 static void DrawElementPackageLowLevel (ElementTypePtr Element
, int);
105 static void DrawPlainPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
);
106 static void AddPart (void *);
107 static void SetPVColor (PinTypePtr
, int);
108 static void DrawEMark (ElementTypePtr
, LocationType
, LocationType
, Boolean
);
109 static void ClearPad (PadTypePtr
, Boolean
);
110 static void DrawHole (PinTypePtr
);
111 static void DrawMask (BoxType
*);
112 static void DrawRats (BoxType
*);
113 static void DrawSilk (int, int, BoxType
*);
114 static int pin_callback (const BoxType
* b
, void *cl
);
115 static int pad_callback (const BoxType
* b
, void *cl
);
117 /*--------------------------------------------------------------------------------------
118 * setup color for pin or via
121 SetPVColor (PinTypePtr Pin
, int Type
)
125 if (Type
== VIA_TYPE
)
128 && TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pin
))
130 if (TEST_FLAG (WARNFLAG
, Pin
))
131 color
= PCB
->WarnColor
;
132 else if (TEST_FLAG (SELECTEDFLAG
, Pin
))
133 color
= PCB
->ViaSelectedColor
;
135 color
= PCB
->ConnectedColor
;
138 color
= PCB
->ViaColor
;
143 && TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pin
))
145 if (TEST_FLAG (WARNFLAG
, Pin
))
146 color
= PCB
->WarnColor
;
147 else if (TEST_FLAG (SELECTEDFLAG
, Pin
))
148 color
= PCB
->PinSelectedColor
;
150 color
= PCB
->ConnectedColor
;
153 color
= PCB
->PinColor
;
156 gui
->set_color (Output
.fgGC
, color
);
159 /*---------------------------------------------------------------------------
160 * Adds the update rect to the update region
165 BoxType
*box
= (BoxType
*) b
;
167 Block
.X1
= MIN (Block
.X1
, box
->X1
);
168 Block
.X2
= MAX (Block
.X2
, box
->X2
);
169 Block
.Y1
= MIN (Block
.Y1
, box
->Y1
);
170 Block
.Y2
= MAX (Block
.Y2
, box
->Y2
);
174 * force the whole output to be updated
179 gui
->invalidate_all ();
183 * initiate the actual drawing to the pixmap/screen
184 * make the update block slightly larger to handle round-off
185 * caused by the TO_SCREEN operation
193 HideCrosshair (True
);
195 /* clear and create event if not drawing to a pixmap
197 gui
->invalidate_lr (Block
.X1
, Block
.X2
, Block
.Y1
, Block
.Y2
, 1);
199 RestoreCrosshair (True
);
201 /* shrink the update block */
202 Block
.X1
= Block
.Y1
= Block
.X2
= Block
.Y2
= 0;
205 /* ---------------------------------------------------------------------------
206 * redraws the output area without clearing it
209 RedrawOutput (BoxTypePtr area
)
214 /* ---------------------------------------------------------------------------
215 * redraws the output area after clearing it
218 ClearAndRedrawOutput (void)
228 /* ----------------------------------------------------------------------
229 * redraws all the data
230 * all necessary sizes are already set by the porthole widget and
231 * by the event handlers
234 Redraw (Boolean ClearWindow
, BoxTypePtr screen_area
)
236 gui
->invalidate_all ();
242 backE_callback (const BoxType
* b
, void *cl
)
244 ElementTypePtr element
= (ElementTypePtr
) b
;
246 if (!FRONT (element
))
248 DrawElementPackage (element
, 0);
254 backN_callback (const BoxType
* b
, void *cl
)
256 TextTypePtr text
= (TextTypePtr
) b
;
257 ElementTypePtr element
= (ElementTypePtr
) text
->Element
;
259 if (!FRONT (element
) && !TEST_FLAG (HIDENAMEFLAG
, element
))
260 DrawElementName (element
, 0);
265 backPad_callback (const BoxType
* b
, void *cl
)
267 PadTypePtr pad
= (PadTypePtr
) b
;
275 frontE_callback (const BoxType
* b
, void *cl
)
277 ElementTypePtr element
= (ElementTypePtr
) b
;
281 DrawElementPackage (element
, 0);
287 EMark_callback (const BoxType
* b
, void *cl
)
289 ElementTypePtr element
= (ElementTypePtr
) b
;
291 DrawEMark (element
, element
->MarkX
, element
->MarkY
, !FRONT (element
));
296 frontN_callback (const BoxType
* b
, void *cl
)
298 TextTypePtr text
= (TextTypePtr
) b
;
299 ElementTypePtr element
= (ElementTypePtr
) text
->Element
;
301 if (FRONT (element
) && !TEST_FLAG (HIDENAMEFLAG
, element
))
302 DrawElementName (element
, 0);
307 hole_callback (const BoxType
* b
, void *cl
)
309 PinTypePtr pin
= (PinTypePtr
) b
;
310 int plated
= cl
? *(int *) cl
: -1;
316 if (!TEST_FLAG (HOLEFLAG
, pin
))
320 if (TEST_FLAG (HOLEFLAG
, pin
))
324 DrawHole ((PinTypePtr
) b
);
335 hole_counting_callback (const BoxType
* b
, void *cl
)
337 PinTypePtr pin
= (PinTypePtr
) b
;
338 HoleCountStruct
*hcs
= (HoleCountStruct
*) cl
;
339 if (TEST_FLAG (HOLEFLAG
, pin
))
347 rat_callback (const BoxType
* b
, void *cl
)
349 DrawRat ((RatTypePtr
) b
, 0);
354 lowvia_callback (const BoxType
* b
, void *cl
)
356 PinTypePtr via
= (PinTypePtr
) b
;
358 DrawPlainVia (via
, False
);
362 /* ---------------------------------------------------------------------------
363 * prints assembly drawing.
367 PrintAssembly (const BoxType
* drawn_area
, int side_group
, int swap_ident
)
369 int save_swap
= SWAP_IDENT
;
371 gui
->set_draw_faded (Output
.fgGC
, 1);
372 SWAP_IDENT
= swap_ident
;
373 DrawLayerGroup (side_group
, drawn_area
);
374 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, lowvia_callback
, NULL
);
375 DrawTop (drawn_area
);
376 gui
->set_draw_faded (Output
.fgGC
, 0);
379 DrawSilk (swap_ident
,
380 swap_ident
? SOLDER_LAYER
: COMPONENT_LAYER
,
382 SWAP_IDENT
= save_swap
;
385 /* ---------------------------------------------------------------------------
386 * initializes some identifiers for a new zoom factor and redraws whole screen
389 DrawEverything (BoxTypePtr drawn_area
)
391 int i
, ngroups
, side
;
393 int component
, solder
;
394 /* This is the list of layer groups we will draw. */
395 int do_group
[MAX_LAYER
];
396 /* This is the reverse of the order in which we draw them. */
397 int drawn_groups
[MAX_LAYER
];
399 PCB
->Data
->SILKLAYER
.Color
= PCB
->ElementColor
;
400 PCB
->Data
->BACKSILKLAYER
.Color
= PCB
->InvisibleObjectsColor
;
402 memset (do_group
, 0, sizeof (do_group
));
403 for (ngroups
= 0, i
= 0; i
< max_layer
; i
++)
405 LayerType
*l
= LAYER_ON_STACK (i
);
406 int group
= GetLayerGroupNumberByNumber (LayerStack
[i
]);
407 if (l
->On
&& !do_group
[group
])
410 drawn_groups
[ngroups
++] = group
;
414 component
= GetLayerGroupNumberByNumber (max_layer
+ COMPONENT_LAYER
);
415 solder
= GetLayerGroupNumberByNumber (max_layer
+ SOLDER_LAYER
);
418 * first draw all 'invisible' stuff
420 if (!TEST_FLAG (CHECKPLANESFLAG
, PCB
)
421 && gui
->set_layer ("invisible", SL (INVISIBLE
, 0), 0))
423 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
, backPad_callback
,
427 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, backE_callback
,
429 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
,
430 backN_callback
, NULL
);
431 DrawLayer (&(PCB
->Data
->BACKSILKLAYER
), drawn_area
);
435 /* draw all layers in layerstack order */
436 for (i
= ngroups
- 1; i
>= 0; i
--)
438 int group
= drawn_groups
[i
];
440 if (gui
->set_layer (0, group
, 0))
442 if (DrawLayerGroup (group
, drawn_area
) && !gui
->gui
)
444 int save_swap
= SWAP_IDENT
;
446 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
) && gui
->gui
)
448 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, pin_callback
,
450 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, pin_callback
,
452 /* draw element pads */
453 if (group
== component
|| group
== solder
)
455 SWAP_IDENT
= (group
== solder
);
456 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
,
459 SWAP_IDENT
= save_swap
;
465 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_callback
,
467 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_callback
,
473 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
) && gui
->gui
)
476 /* draw vias below silk */
477 if (PCB
->ViaOn
&& gui
->gui
)
478 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, lowvia_callback
, NULL
);
479 /* Draw the solder mask if turned on */
480 if (gui
->set_layer ("componentmask", SL (MASK
, TOP
), 0))
482 int save_swap
= SWAP_IDENT
;
484 DrawMask (drawn_area
);
485 SWAP_IDENT
= save_swap
;
487 if (gui
->set_layer ("soldermask", SL (MASK
, BOTTOM
), 0))
489 int save_swap
= SWAP_IDENT
;
491 DrawMask (drawn_area
);
492 SWAP_IDENT
= save_swap
;
494 /* Draw pins, pads, vias below silk */
496 DrawTop (drawn_area
);
500 hcs
.nplated
= hcs
.nunplated
= 0;
501 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_counting_callback
,
503 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_counting_callback
,
505 if (hcs
.nplated
&& gui
->set_layer ("plated-drill", SL (PDRILL
, 0), 0))
508 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_callback
,
510 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_callback
,
513 if (hcs
.nunplated
&& gui
->set_layer ("unplated-drill", SL (UDRILL
, 0), 0))
516 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_callback
,
518 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_callback
,
522 /* Draw top silkscreen */
523 if (gui
->set_layer ("topsilk", SL (SILK
, TOP
), 0))
524 DrawSilk (0, COMPONENT_LAYER
, drawn_area
);
525 if (gui
->set_layer ("bottomsilk", SL (SILK
, BOTTOM
), 0))
526 DrawSilk (1, SOLDER_LAYER
, drawn_area
);
529 /* Draw element Marks */
531 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, EMark_callback
,
533 /* Draw rat lines on top */
535 DrawRats(drawn_area
);
538 for (side
= 0; side
<= 1; side
++)
541 Boolean NoData
= True
;
542 ALLPAD_LOOP (PCB
->Data
);
544 if ((TEST_FLAG (ONSOLDERFLAG
, pad
) && side
== SOLDER_LAYER
)
545 || (!TEST_FLAG (ONSOLDERFLAG
, pad
) && side
== COMPONENT_LAYER
))
553 if (side
== SOLDER_LAYER
)
554 doit
= gui
->set_layer ("bottompaste", SL (PASTE
, BOTTOM
), NoData
);
556 doit
= gui
->set_layer ("toppaste", SL (PASTE
, TOP
), NoData
);
559 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
560 ALLPAD_LOOP (PCB
->Data
);
562 if ((TEST_FLAG (ONSOLDERFLAG
, pad
) && side
== SOLDER_LAYER
)
563 || (!TEST_FLAG (ONSOLDERFLAG
, pad
)
564 && side
== COMPONENT_LAYER
))
565 if (!TEST_FLAG (NOPASTEFLAG
, pad
))
566 DrawPadLowLevel (Output
.fgGC
, pad
, False
, False
);
573 if (gui
->set_layer ("topassembly", SL (ASSY
, TOP
), 0))
574 PrintAssembly (drawn_area
, component
, 0);
576 if (gui
->set_layer ("bottomassembly", SL (ASSY
, BOTTOM
), 0))
577 PrintAssembly (drawn_area
, solder
, 1);
580 if (gui
->set_layer ("fab", SL (FAB
, 0), 0))
585 DrawEMark (ElementTypePtr e
, LocationType X
, LocationType Y
,
588 int mark_size
= EMARK_SIZE
;
589 if (!PCB
->InvisibleObjectsOn
&& invisible
)
592 if (e
->PinN
&& mark_size
> e
->Pin
[0].Thickness
/ 2)
593 mark_size
= e
->Pin
[0].Thickness
/ 2;
594 if (e
->PadN
&& mark_size
> e
->Pad
[0].Thickness
/ 2)
595 mark_size
= e
->Pad
[0].Thickness
/ 2;
597 gui
->set_color (Output
.fgGC
,
598 invisible
? PCB
->InvisibleMarkColor
: PCB
->ElementColor
);
599 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
600 gui
->set_line_width (Output
.fgGC
, 0);
601 gui
->draw_line (Output
.fgGC
, X
- mark_size
, Y
, X
, Y
- mark_size
);
602 gui
->draw_line (Output
.fgGC
, X
+ mark_size
, Y
, X
, Y
- mark_size
);
603 gui
->draw_line (Output
.fgGC
, X
- mark_size
, Y
, X
, Y
+ mark_size
);
604 gui
->draw_line (Output
.fgGC
, X
+ mark_size
, Y
, X
, Y
+ mark_size
);
607 * If an element is locked, place a "L" on top of the "diamond".
608 * This provides a nice visual indication that it is locked that
609 * works even for color blind users.
611 if (TEST_FLAG (LOCKFLAG
, e
) )
613 gui
->draw_line (Output
.fgGC
, X
, Y
, X
+ 2 * mark_size
, Y
);
614 gui
->draw_line (Output
.fgGC
, X
, Y
, X
, Y
- 4* mark_size
);
620 via_callback (const BoxType
* b
, void *cl
)
622 PinTypePtr via
= (PinTypePtr
) b
;
624 DrawPlainVia (via
, False
);
629 pin_callback (const BoxType
* b
, void *cl
)
631 DrawPlainPin ((PinTypePtr
) b
, False
);
636 pad_callback (const BoxType
* b
, void *cl
)
638 PadTypePtr pad
= (PadTypePtr
) b
;
644 /* ---------------------------------------------------------------------------
645 * draws pins pads and vias
648 DrawTop (const BoxType
* screen
)
650 if (PCB
->PinOn
|| doing_assy
)
652 /* draw element pins */
653 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, pin_callback
, NULL
);
654 /* draw element pads */
655 r_search (PCB
->Data
->pad_tree
, screen
, NULL
, pad_callback
, NULL
);
658 if (PCB
->ViaOn
|| doing_assy
)
660 r_search (PCB
->Data
->via_tree
, screen
, NULL
, via_callback
, NULL
);
661 r_search (PCB
->Data
->via_tree
, screen
, NULL
, hole_callback
, NULL
);
663 if (PCB
->PinOn
|| doing_assy
)
664 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, hole_callback
, NULL
);
674 clearPin_callback (const BoxType
* b
, void *cl
)
676 PinTypePtr pin
= (PinTypePtr
) b
;
677 struct pin_info
*i
= (struct pin_info
*) cl
;
679 ClearOnlyPin (pin
, True
);
683 poly_callback (const BoxType
* b
, void *cl
)
685 struct pin_info
*i
= (struct pin_info
*) cl
;
687 DrawPlainPolygon (i
->Layer
, (PolygonTypePtr
) b
);
692 clearPad_callback (const BoxType
* b
, void *cl
)
694 PadTypePtr pad
= (PadTypePtr
) b
;
695 if (!XOR (TEST_FLAG (ONSOLDERFLAG
, pad
), SWAP_IDENT
))
696 ClearPad (pad
, True
);
700 /* ---------------------------------------------------------------------------
705 DrawSilk (int new_swap
, int layer
, BoxTypePtr drawn_area
)
708 /* This code is used when you want to mask silk to avoid exposed
709 pins and pads. We decided it was a bad idea to do this
710 unconditionally, but the code remains. */
711 struct pin_info info
;
713 int save_swap
= SWAP_IDENT
;
714 SWAP_IDENT
= new_swap
;
717 if (gui
->poly_before
)
719 gui
->use_mask (HID_MASK_BEFORE
);
721 DrawLayer (LAYER_PTR (max_layer
+ layer
), drawn_area
);
723 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, frontE_callback
,
725 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
,
726 frontN_callback
, NULL
);
730 gui
->use_mask (HID_MASK_CLEAR
);
732 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, clearPin_callback
, &info
);
733 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, clearPin_callback
, &info
);
734 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
, clearPad_callback
, &info
);
738 gui
->use_mask (HID_MASK_AFTER
);
739 DrawLayer (LAYER_PTR (max_layer
+ layer
), drawn_area
);
741 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, frontE_callback
,
743 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
,
744 frontN_callback
, NULL
);
746 gui
->use_mask (HID_MASK_OFF
);
748 SWAP_IDENT
= save_swap
;
751 /* ---------------------------------------------------------------------------
752 * draws solder mask layer - this will cover nearly everything
755 DrawMask (BoxType
* screen
)
757 struct pin_info info
;
758 int thin
= TEST_FLAG(THINDRAWFLAG
, PCB
) || TEST_FLAG(THINDRAWPOLYFLAG
, PCB
);
760 OutputType
*out
= &Output
;
765 gui
->set_color (Output
.pmGC
, PCB
->MaskColor
);
768 if (gui
->poly_before
)
770 gui
->use_mask (HID_MASK_BEFORE
);
771 gui
->set_color (out
->fgGC
, PCB
->MaskColor
);
772 gui
->fill_rect (out
->fgGC
, 0, 0, PCB
->MaxWidth
, PCB
->MaxHeight
);
774 gui
->use_mask (HID_MASK_CLEAR
);
777 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, clearPin_callback
, &info
);
778 r_search (PCB
->Data
->via_tree
, screen
, NULL
, clearPin_callback
, &info
);
779 r_search (PCB
->Data
->pad_tree
, screen
, NULL
, clearPad_callback
, &info
);
782 gui
->set_color (Output
.pmGC
, "erase");
787 gui
->use_mask (HID_MASK_AFTER
);
788 gui
->set_color (out
->fgGC
, PCB
->MaskColor
);
789 gui
->fill_rect (out
->fgGC
, 0, 0, PCB
->MaxWidth
, PCB
->MaxHeight
);
791 gui
->use_mask (HID_MASK_OFF
);
795 /* Some fabs want the board outline on the solder mask layer. If
796 you need this, change the '0' above to '1', and the code below
797 will copy the outline layer to the mask layers. */
801 for (i
=PCB
->Data
->LayerN
; i
>=0; i
--)
803 LayerTypePtr Layer
= PCB
->Data
->Layer
+ i
;
804 if (strcasecmp (Layer
->Name
, "outline") == 0)
805 DrawLayer (Layer
, screen
);
812 DrawRats (BoxTypePtr drawn_area
)
815 * XXX lesstif allows positive AND negative drawing in HID_MASK_CLEAR.
816 * XXX gtk only allows negative drawing.
817 * XXX using the mask here is to get rat transparency
819 int can_mask
= strcmp(gui
->name
, "lesstif") == 0;
822 gui
->use_mask (HID_MASK_CLEAR
);
823 r_search (PCB
->Data
->rat_tree
, drawn_area
, NULL
, rat_callback
, NULL
);
825 gui
->use_mask (HID_MASK_OFF
);
829 line_callback (const BoxType
* b
, void *cl
)
831 DrawLine ((LayerTypePtr
) cl
, (LineTypePtr
) b
, 0);
836 arc_callback (const BoxType
* b
, void *cl
)
838 DrawArc ((LayerTypePtr
) cl
, (ArcTypePtr
) b
, 0);
843 text_callback (const BoxType
* b
, void *cl
)
845 DrawRegularText ((LayerTypePtr
) cl
, (TextTypePtr
) b
, 0);
850 /* ---------------------------------------------------------------------------
851 * draws one non-copper layer
854 DrawLayer (LayerTypePtr Layer
, BoxType
* screen
)
856 struct pin_info info
;
858 /* print the non-clearing polys */
862 r_search (Layer
->polygon_tree
, screen
, NULL
, poly_callback
, &info
);
864 /* draw all visible lines this layer */
865 r_search (Layer
->line_tree
, screen
, NULL
, line_callback
, Layer
);
867 /* draw the layer arcs on screen */
868 r_search (Layer
->arc_tree
, screen
, NULL
, arc_callback
, Layer
);
870 /* draw the layer text on screen */
871 r_search (Layer
->text_tree
, screen
, NULL
, text_callback
, Layer
);
875 /* ---------------------------------------------------------------------------
876 * draws one layer group. Returns non-zero if pins and pads should be
877 * drawn with this group.
880 DrawLayerGroup (int group
, const BoxType
* screen
)
884 struct pin_info info
;
886 int n_entries
= PCB
->LayerGroups
.Number
[group
];
887 Cardinal
*layers
= PCB
->LayerGroups
.Entries
[group
];
890 for (i
= n_entries
- 1; i
>= 0; i
--)
892 layernum
= layers
[i
];
893 Layer
= PCB
->Data
->Layer
+ layers
[i
];
894 if (strcasecmp (Layer
->Name
, "outline") == 0
895 || strcasecmp (Layer
->Name
, "route") == 0)
897 if (layernum
< max_layer
&& Layer
->On
)
899 /* draw all polygons on this layer */
904 r_search (Layer
->polygon_tree
, screen
, NULL
, poly_callback
,
909 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
))
912 /* draw all visible lines this layer */
913 r_search (Layer
->line_tree
, screen
, NULL
, line_callback
, Layer
);
915 /* draw the layer arcs on screen */
916 r_search (Layer
->arc_tree
, screen
, NULL
, arc_callback
, Layer
);
918 /* draw the layer text on screen */
919 r_search (Layer
->text_tree
, screen
, NULL
, text_callback
, Layer
);
928 /* ---------------------------------------------------------------------------
930 * x and y are already in display coordinates
931 * the points are numbered:
942 DrawSpecialPolygon (HID
* hid
, hidGC DrawGC
,
943 LocationType X
, LocationType Y
, int Thickness
)
945 static FloatPolyType p
[8] = {
947 0.5, -TAN_22_5_DEGREE_2
},
949 TAN_22_5_DEGREE_2
, -0.5},
951 -TAN_22_5_DEGREE_2
, -0.5},
953 -0.5, -TAN_22_5_DEGREE_2
},
955 -0.5, TAN_22_5_DEGREE_2
},
957 -TAN_22_5_DEGREE_2
, 0.5},
959 TAN_22_5_DEGREE_2
, 0.5},
961 0.5, TAN_22_5_DEGREE_2
}
963 static int special_size
= 0;
964 static int scaled_x
[8];
965 static int scaled_y
[8];
971 if (Thickness
!= special_size
)
973 special_size
= Thickness
;
974 for (i
= 0; i
< 8; i
++)
976 scaled_x
[i
] = p
[i
].X
* special_size
;
977 scaled_y
[i
] = p
[i
].Y
* special_size
;
980 /* add line offset */
981 for (i
= 0; i
< 8; i
++)
983 polygon_x
[i
] = X
+ scaled_x
[i
];
984 polygon_y
[i
] = Y
+ scaled_y
[i
];
986 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
989 hid
->set_line_cap (Output
.fgGC
, Round_Cap
);
990 hid
->set_line_width (Output
.fgGC
, 0);
991 polygon_x
[8] = X
+ scaled_x
[0];
992 polygon_y
[8] = Y
+ scaled_y
[0];
993 for (i
= 0; i
< 8; i
++)
994 hid
->draw_line (DrawGC
, polygon_x
[i
], polygon_y
[i
],
995 polygon_x
[i
+ 1], polygon_y
[i
+ 1]);
998 hid
->fill_polygon (DrawGC
, 8, polygon_x
, polygon_y
);
1001 /* ---------------------------------------------------------------------------
1002 * lowlevel drawing routine for pins and vias
1005 DrawPinOrViaLowLevel (PinTypePtr Ptr
, Boolean drawHole
)
1013 if (TEST_FLAG (HOLEFLAG
, Ptr
))
1017 gui
->fill_circle (Output
.bgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->Thickness
/ 2);
1018 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1019 gui
->set_line_width (Output
.fgGC
, 0);
1020 gui
->draw_arc (Output
.fgGC
, Ptr
->X
, Ptr
->Y
,
1021 Ptr
->Thickness
/ 2, Ptr
->Thickness
/ 2, 0, 360);
1025 if (TEST_FLAG (SQUAREFLAG
, Ptr
))
1028 l
= Ptr
->X
- Ptr
->Thickness
/ 2;
1029 b
= Ptr
->Y
- Ptr
->Thickness
/ 2;
1030 r
= l
+ Ptr
->Thickness
;
1031 t
= b
+ Ptr
->Thickness
;
1032 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1034 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1035 gui
->set_line_width (Output
.fgGC
, 0);
1036 gui
->draw_line (Output
.fgGC
, r
, t
, r
, b
);
1037 gui
->draw_line (Output
.fgGC
, l
, t
, l
, b
);
1038 gui
->draw_line (Output
.fgGC
, r
, t
, l
, t
);
1039 gui
->draw_line (Output
.fgGC
, r
, b
, l
, b
);
1043 gui
->fill_rect (Output
.fgGC
, l
, b
, r
, t
);
1046 else if (TEST_FLAG (OCTAGONFLAG
, Ptr
))
1048 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1049 gui
->set_line_width (Output
.fgGC
,
1050 (Ptr
->Thickness
- Ptr
->DrillingHole
) / 2);
1052 /* transform X11 specific coord system */
1053 DrawSpecialPolygon (gui
, Output
.fgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->Thickness
);
1056 { /* draw a round pin or via */
1057 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1059 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1060 gui
->set_line_width (Output
.fgGC
, 0);
1061 gui
->draw_arc (Output
.fgGC
, Ptr
->X
, Ptr
->Y
,
1062 Ptr
->Thickness
/ 2, Ptr
->Thickness
/ 2, 0, 360);
1066 gui
->fill_circle (Output
.fgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->Thickness
/ 2);
1070 /* and the drilling hole (which is always round */
1073 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1075 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1076 gui
->set_line_width (Output
.fgGC
, 0);
1077 gui
->draw_arc (Output
.fgGC
,
1078 Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2,
1079 Ptr
->DrillingHole
/ 2, 0, 360);
1083 gui
->fill_circle (Output
.bgGC
, Ptr
->X
, Ptr
->Y
,
1084 Ptr
->DrillingHole
/ 2);
1089 /**************************************************************
1093 DrawHole (PinTypePtr Ptr
)
1095 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1097 if (!TEST_FLAG (HOLEFLAG
, Ptr
))
1099 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1100 gui
->set_line_width (Output
.fgGC
, 0);
1101 gui
->draw_arc (Output
.fgGC
,
1102 Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2,
1103 Ptr
->DrillingHole
/ 2, 0, 360);
1108 gui
->fill_circle (Output
.bgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2);
1110 if (TEST_FLAG (HOLEFLAG
, Ptr
))
1112 if (TEST_FLAG (WARNFLAG
, Ptr
))
1113 gui
->set_color (Output
.fgGC
, PCB
->WarnColor
);
1114 else if (TEST_FLAG (SELECTEDFLAG
, Ptr
))
1115 gui
->set_color (Output
.fgGC
, PCB
->ViaSelectedColor
);
1117 gui
->set_color (Output
.fgGC
, Settings
.BlackColor
);
1119 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1120 gui
->set_line_width (Output
.fgGC
, 0);
1121 gui
->draw_arc (Output
.fgGC
,
1122 Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2,
1123 Ptr
->DrillingHole
/ 2, 0, 360);
1127 /*******************************************************************
1128 * draw clearance in pixmask around pins and vias that pierce polygons
1131 ClearOnlyPin (PinTypePtr Pin
, Boolean mask
)
1134 (mask
? Pin
->Mask
/ 2 : (Pin
->Thickness
+ Pin
->Clearance
) / 2);
1136 if (!mask
&& TEST_FLAG (HOLEFLAG
, Pin
))
1140 if (!mask
&& Pin
->Clearance
<= 0)
1143 /* Clear the area around the pin */
1144 if (TEST_FLAG (SQUAREFLAG
, Pin
))
1151 if (TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG (THINDRAWPOLYFLAG
, PCB
))
1153 gui
->set_line_cap (Output
.pmGC
, Round_Cap
);
1154 gui
->set_line_width (Output
.pmGC
, 0);
1155 gui
->draw_line (Output
.pmGC
, r
, t
, r
, b
);
1156 gui
->draw_line (Output
.pmGC
, l
, t
, l
, b
);
1157 gui
->draw_line (Output
.pmGC
, r
, t
, l
, t
);
1158 gui
->draw_line (Output
.pmGC
, r
, b
, l
, b
);
1161 gui
->fill_rect (Output
.pmGC
, l
, b
, r
, t
);
1163 else if (TEST_FLAG (OCTAGONFLAG
, Pin
))
1165 gui
->set_line_cap (Output
.pmGC
, Round_Cap
);
1166 gui
->set_line_width (Output
.pmGC
, (Pin
->Clearance
+ Pin
->Thickness
1167 - Pin
->DrillingHole
));
1169 DrawSpecialPolygon (gui
, Output
.pmGC
, Pin
->X
, Pin
->Y
, half
* 2);
1173 if (TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG (THINDRAWPOLYFLAG
, PCB
))
1174 gui
->draw_arc (Output
.pmGC
, Pin
->X
, Pin
->Y
, half
, half
, 0, 360);
1176 gui
->fill_circle (Output
.pmGC
, Pin
->X
, Pin
->Y
, half
);
1180 /* ---------------------------------------------------------------------------
1181 * lowlevel drawing routine for pins and vias that pierce polygons
1184 ClearPin (PinTypePtr Pin
, int Type
, int unused
)
1186 BDimension half
= (Pin
->Thickness
+ Pin
->Clearance
) / 2;
1193 /* Clear the area around the pin */
1194 if (TEST_FLAG (SQUAREFLAG
, Pin
))
1201 gui
->fill_rect (Output
.pmGC
, l
, b
, r
, t
);
1203 else if (TEST_FLAG (OCTAGONFLAG
, Pin
))
1205 gui
->set_line_cap (Output
.pmGC
, Round_Cap
);
1206 gui
->set_line_width (Output
.pmGC
, (Pin
->Clearance
+ Pin
->Thickness
1207 - Pin
->DrillingHole
) / 2);
1209 DrawSpecialPolygon (gui
, Output
.pmGC
, Pin
->X
, Pin
->Y
, half
* 2);
1213 gui
->fill_circle (Output
.pmGC
, Pin
->X
, Pin
->Y
, half
);
1215 if ((!TEST_FLAG (PINFLAG
, Pin
) && !PCB
->ViaOn
)
1216 || (TEST_FLAG (PINFLAG
, Pin
) && !PCB
->PinOn
))
1218 /* now draw the pin or via as appropriate */
1223 SetPVColor (Pin
, Type
);
1224 DrawPinOrViaLowLevel (Pin
, True
);
1234 /* vertical text handling provided by Martin Devera with fixes by harry eaton */
1236 /* draw vertical text; xywh is bounding, de is text's descend used for
1239 DrawVText (int x
, int y
, int w
, int h
, char *str
)
1250 pm
= gdk_pixmap_new (DrawingWindow
, w
, h
, -1);
1252 /* draw into pixmap */
1253 gdk_draw_rectangle (pm
, Output
.bgGC
, TRUE
, 0, 0, w
, h
);
1255 gui_draw_string_markup (DrawingWindow
, Output
.font_desc
, Output
.fgGC
,
1258 im
= gdk_drawable_get_image (pm
, 0, 0, w
, h
);
1259 gdk_gc_get_values (Output
.fgGC
, &values
);
1261 /* draw Transpose(im). TODO: Pango should be doing vertical text soon */
1262 for (i
= 0; i
< w
; i
++)
1263 for (j
= 0; j
< h
; j
++)
1265 pixel
= gdk_image_get_pixel (im
, i
, j
);
1266 if (pixel
== values
.foreground
.pixel
)
1267 gdk_draw_point (DrawingWindow
, Output
.fgGC
, x
+ j
, y
+ w
- i
- 1);
1269 g_object_unref (G_OBJECT (pm
));
1273 /* ---------------------------------------------------------------------------
1274 * lowlevel drawing routine for pin and via names
1277 DrawPinOrViaNameLowLevel (PinTypePtr Ptr
)
1284 if (!Ptr
->Name
|| !Ptr
->Name
[0])
1285 name
= EMPTY (Ptr
->Number
);
1287 name
= EMPTY (TEST_FLAG (SHOWNUMBERFLAG
, PCB
) ? Ptr
->Number
: Ptr
->Name
);
1289 vert
= TEST_FLAG (EDGE2FLAG
, Ptr
);
1293 box
.X1
= Ptr
->X
- Ptr
->Thickness
/ 2 + Settings
.PinoutTextOffsetY
;
1294 box
.Y1
= Ptr
->Y
- Ptr
->DrillingHole
/ 2 - Settings
.PinoutTextOffsetX
;
1298 box
.X1
= Ptr
->X
+ Ptr
->DrillingHole
/ 2 + Settings
.PinoutTextOffsetX
;
1299 box
.Y1
= Ptr
->Y
- Ptr
->Thickness
/ 2 + Settings
.PinoutTextOffsetY
;
1313 /*printf("AddPart: x1=%d y1=%d x2=%d y2=%d\n", box.X1, box.Y1, box.X2, box.Y2);*/
1317 /*printf("DrawPin(%d,%d): x=%d y=%d w=%d h=%d\n",
1318 TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y), box.X1, box.Y1, width, height);*/
1320 gui
->set_color (Output
.fgGC
, PCB
->PinNameColor
);
1322 text
.Flags
= NoFlags ();
1323 text
.Scale
= Ptr
->Thickness
/ 80;
1326 text
.Direction
= vert
? 1 : 0;
1327 text
.TextString
= name
;
1331 DrawTextLowLevel (&text
, 0);
1336 /* ---------------------------------------------------------------------------
1337 * lowlevel drawing routine for pads
1341 DrawPadLowLevel (hidGC gc
, PadTypePtr Pad
, Boolean clear
, Boolean mask
)
1343 int w
= clear
? (mask
? Pad
->Mask
: Pad
->Thickness
+ Pad
->Clearance
)
1352 if (clear
&& !mask
&& Pad
->Clearance
<= 0)
1355 if (TEST_FLAG (THINDRAWFLAG
, PCB
) ||
1356 (clear
&& TEST_FLAG (THINDRAWPOLYFLAG
, PCB
)))
1358 int x1
, y1
, x2
, y2
, t
, t2
;
1365 if (x1
> x2
|| y1
> y2
)
1367 /* this is a silly way to swap the variables */
1375 gui
->set_line_cap (gc
, Round_Cap
);
1376 gui
->set_line_width (gc
, 0);
1377 if (TEST_FLAG (SQUAREFLAG
, Pad
)
1378 && (x1
== x2
|| y1
== y2
))
1384 gui
->draw_line (gc
, x1
, y1
, x1
, y2
);
1385 gui
->draw_line (gc
, x1
, y2
, x2
, y2
);
1386 gui
->draw_line (gc
, x2
, y2
, x2
, y1
);
1387 gui
->draw_line (gc
, x2
, y1
, x1
, y1
);
1389 else if (TEST_FLAG (SQUAREFLAG
, Pad
))
1391 /* slanted square pad */
1392 float tx
, ty
, theta
;
1394 theta
= atan2 (y2
-y1
, x2
-x1
);
1396 /* T is a vector half a thickness long, in the direction of
1397 one of the corners. */
1398 tx
= t
* cos (theta
+ M_PI
/4) * sqrt(2.0);
1399 ty
= t
* sin (theta
+ M_PI
/4) * sqrt(2.0);
1401 gui
->draw_line (gc
, x1
-tx
, y1
-ty
, x2
+ty
, y2
-tx
);
1402 gui
->draw_line (gc
, x2
+ty
, y2
-tx
, x2
+tx
, y2
+ty
);
1403 gui
->draw_line (gc
, x2
+tx
, y2
+ty
, x1
-ty
, y1
+tx
);
1404 gui
->draw_line (gc
, x1
-ty
, y1
+tx
, x1
-tx
, y1
-ty
);
1406 else if (x1
== x2
&& y1
== y2
)
1408 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 0, 360);
1412 gui
->draw_line (gc
, x1
- t
, y1
, x2
- t
, y2
);
1413 gui
->draw_line (gc
, x1
+ t2
, y1
, x2
+ t2
, y2
);
1414 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 0, -180);
1415 gui
->draw_arc (gc
, x2
, y2
, w
/ 2, w
/ 2, 180, -180);
1419 gui
->draw_line (gc
, x1
, y1
- t
, x2
, y2
- t
);
1420 gui
->draw_line (gc
, x1
, y1
+ t2
, x2
, y2
+ t2
);
1421 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 90, -180);
1422 gui
->draw_arc (gc
, x2
, y2
, w
/ 2, w
/ 2, 270, -180);
1426 /* Slanted round-end pads. */
1427 LocationType dx
, dy
, ox
, oy
;
1432 h
= t
/ sqrt (SQUARE (dx
) + SQUARE (dy
));
1433 ox
= dy
* h
+ 0.5 * SGN (dy
);
1434 oy
= -(dx
* h
+ 0.5 * SGN (dx
));
1436 gui
->draw_line (gc
, x1
+ ox
, y1
+ oy
, x2
+ ox
, y2
+ oy
);
1438 if (abs (ox
) >= pixel_slop
|| abs (oy
) >= pixel_slop
)
1440 LocationType angle
= atan2 ((float) dx
, (float) dy
) * 57.295779;
1441 gui
->draw_line (gc
, x1
- ox
, y1
- oy
, x2
- ox
, y2
- oy
);
1443 x1
, y1
, t
, t
, angle
- 180, 180);
1444 gui
->draw_arc (gc
, x2
, y2
, t
, t
, angle
, 180);
1448 else if (Pad
->Point1
.X
== Pad
->Point2
.X
1449 && Pad
->Point1
.Y
== Pad
->Point2
.Y
)
1451 if (TEST_FLAG (SQUAREFLAG
, Pad
))
1454 l
= Pad
->Point1
.X
- w
/ 2;
1455 b
= Pad
->Point1
.Y
- w
/ 2;
1458 gui
->fill_rect (gc
, l
, b
, r
, t
);
1462 gui
->fill_circle (gc
, Pad
->Point1
.X
, Pad
->Point1
.Y
, w
/ 2);
1467 gui
->set_line_cap (gc
,
1468 TEST_FLAG (SQUAREFLAG
,
1469 Pad
) ? Square_Cap
: Round_Cap
);
1470 gui
->set_line_width (gc
, w
);
1473 Pad
->Point1
.X
, Pad
->Point1
.Y
,
1474 Pad
->Point2
.X
, Pad
->Point2
.Y
);
1477 { /* Draw bounding box for test */
1478 BoxType
*box
= &Pad
->BoundingBox
;
1479 gui
->set_line_width (gc
, 0);
1480 gui
->draw_line (gc
, box
->X1
, box
->Y1
, box
->X1
, box
->Y2
);
1481 gui
->draw_line (gc
, box
->X1
, box
->Y2
, box
->X2
, box
->Y2
);
1482 gui
->draw_line (gc
, box
->X2
, box
->Y2
, box
->X2
, box
->Y1
);
1483 gui
->draw_line (gc
, box
->X2
, box
->Y1
, box
->X1
, box
->Y1
);
1488 /* ---------------------------------------------------------------------------
1489 * lowlevel drawing routine for pad names
1493 DrawPadNameLowLevel (PadTypePtr Pad
)
1500 if (!Pad
->Name
|| !Pad
->Name
[0])
1501 name
= EMPTY (Pad
->Number
);
1503 name
= EMPTY (TEST_FLAG (SHOWNUMBERFLAG
, PCB
) ? Pad
->Number
: Pad
->Name
);
1505 /* should text be vertical ? */
1506 vert
= (Pad
->Point1
.X
== Pad
->Point2
.X
);
1510 box
.X1
= Pad
->Point1
.X
- Pad
->Thickness
/ 2;
1511 box
.Y1
= MAX (Pad
->Point1
.Y
, Pad
->Point2
.Y
) + Pad
->Thickness
/ 2;
1515 box
.X1
= MIN (Pad
->Point1
.X
, Pad
->Point2
.X
) - Pad
->Thickness
/ 2;
1516 box
.Y1
= Pad
->Point1
.Y
- Pad
->Thickness
/ 2;
1521 box
.X1
+= Settings
.PinoutTextOffsetY
;
1522 box
.Y1
-= Settings
.PinoutTextOffsetX
;
1526 box
.X1
+= Settings
.PinoutTextOffsetX
;
1527 box
.Y1
+= Settings
.PinoutTextOffsetY
;
1546 gui
->set_color (Output
.fgGC
, PCB
->PinNameColor
);
1548 text
.Flags
= NoFlags ();
1549 text
.Scale
= Pad
->Thickness
/ 50;
1552 text
.Direction
= vert
? 1 : 0;
1553 text
.TextString
= name
;
1555 DrawTextLowLevel (&text
, 0);
1559 /* ---------------------------------------------------------------------------
1560 * clearance for pads
1563 ClearPad (PadTypePtr Pad
, Boolean mask
)
1565 DrawPadLowLevel(Output
.pmGC
, Pad
, True
, mask
);
1568 /* ---------------------------------------------------------------------------
1569 * lowlevel drawing routine for lines
1572 DrawLineLowLevel (LineTypePtr Line
, Boolean HaveGathered
)
1574 if (Gathering
&& !HaveGathered
)
1580 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
1581 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1582 gui
->set_line_width (Output
.fgGC
, 0);
1584 gui
->set_line_width (Output
.fgGC
, Line
->Thickness
);
1586 gui
->draw_line (Output
.fgGC
,
1587 Line
->Point1
.X
, Line
->Point1
.Y
,
1588 Line
->Point2
.X
, Line
->Point2
.Y
);
1591 /* ---------------------------------------------------------------------------
1592 * lowlevel drawing routine for text objects
1595 DrawTextLowLevel (TextTypePtr Text
, int min_line_width
)
1598 unsigned char *string
= (unsigned char *) Text
->TextString
;
1600 FontTypePtr font
= &PCB
->Font
;
1608 while (string
&& *string
)
1610 /* draw lines if symbol is valid and data is present */
1611 if (*string
<= MAX_FONTPOSITION
&& font
->Symbol
[*string
].Valid
)
1613 LineTypePtr line
= font
->Symbol
[*string
].Line
;
1616 for (n
= font
->Symbol
[*string
].LineN
; n
; n
--, line
++)
1618 /* create one line, scale, move, rotate and swap it */
1620 newline
.Point1
.X
= (newline
.Point1
.X
+ x
) * Text
->Scale
/ 100;
1621 newline
.Point1
.Y
= newline
.Point1
.Y
* Text
->Scale
/ 100;
1622 newline
.Point2
.X
= (newline
.Point2
.X
+ x
) * Text
->Scale
/ 100;
1623 newline
.Point2
.Y
= newline
.Point2
.Y
* Text
->Scale
/ 100;
1624 newline
.Thickness
= newline
.Thickness
* Text
->Scale
/ 200;
1625 if (newline
.Thickness
< min_line_width
)
1626 newline
.Thickness
= min_line_width
;
1628 RotateLineLowLevel (&newline
, 0, 0, Text
->Direction
);
1630 /* the labels of SMD objects on the bottom
1631 * side haven't been swapped yet, only their offset
1633 if (TEST_FLAG (ONSOLDERFLAG
, Text
))
1635 newline
.Point1
.X
= SWAP_SIGN_X (newline
.Point1
.X
);
1636 newline
.Point1
.Y
= SWAP_SIGN_Y (newline
.Point1
.Y
);
1637 newline
.Point2
.X
= SWAP_SIGN_X (newline
.Point2
.X
);
1638 newline
.Point2
.Y
= SWAP_SIGN_Y (newline
.Point2
.Y
);
1640 /* add offset and draw line */
1641 newline
.Point1
.X
+= Text
->X
;
1642 newline
.Point1
.Y
+= Text
->Y
;
1643 newline
.Point2
.X
+= Text
->X
;
1644 newline
.Point2
.Y
+= Text
->Y
;
1645 DrawLineLowLevel (&newline
, True
);
1648 /* move on to next cursor position */
1649 x
+= (font
->Symbol
[*string
].Width
+ font
->Symbol
[*string
].Delta
);
1653 /* the default symbol is a filled box */
1654 BoxType defaultsymbol
= PCB
->Font
.DefaultSymbol
;
1655 LocationType size
= (defaultsymbol
.X2
- defaultsymbol
.X1
) * 6 / 5;
1657 defaultsymbol
.X1
= (defaultsymbol
.X1
+ x
) * Text
->Scale
/ 100;
1658 defaultsymbol
.Y1
= defaultsymbol
.Y1
* Text
->Scale
/ 100;
1659 defaultsymbol
.X2
= (defaultsymbol
.X2
+ x
) * Text
->Scale
/ 100;
1660 defaultsymbol
.Y2
= defaultsymbol
.Y2
* Text
->Scale
/ 100;
1662 RotateBoxLowLevel (&defaultsymbol
, 0, 0, Text
->Direction
);
1664 /* add offset and draw box */
1665 defaultsymbol
.X1
+= Text
->X
;
1666 defaultsymbol
.Y1
+= Text
->Y
;
1667 defaultsymbol
.X2
+= Text
->X
;
1668 defaultsymbol
.Y2
+= Text
->Y
;
1669 gui
->fill_rect (Output
.fgGC
,
1670 defaultsymbol
.X1
, defaultsymbol
.Y1
,
1671 defaultsymbol
.X2
, defaultsymbol
.Y2
);
1673 /* move on to next cursor position */
1680 /* ---------------------------------------------------------------------------
1681 * lowlevel drawing routine for polygons
1684 DrawPolygonLowLevel (PolygonTypePtr Polygon
)
1686 if (!Polygon
->Clipped
)
1695 printf ("DrawPolygonLowLevel: Called without Gathering set!\n");
1698 /* ---------------------------------------------------------------------------
1699 * lowlevel routine to element arcs
1702 DrawArcLowLevel (ArcTypePtr Arc
)
1704 if (!Arc
->Thickness
)
1712 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1713 gui
->set_line_width (Output
.fgGC
, 0);
1715 gui
->set_line_width (Output
.fgGC
, Arc
->Thickness
);
1716 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
1718 gui
->draw_arc (Output
.fgGC
, Arc
->X
, Arc
->Y
, Arc
->Width
,
1719 Arc
->Height
, Arc
->StartAngle
, Arc
->Delta
);
1722 /* ---------------------------------------------------------------------------
1723 * draws the package of an element
1726 DrawElementPackageLowLevel (ElementTypePtr Element
, int unused
)
1728 /* draw lines, arcs, text and pins */
1729 ELEMENTLINE_LOOP (Element
);
1731 DrawLineLowLevel (line
, False
);
1736 DrawArcLowLevel (arc
);
1741 /* ---------------------------------------------------------------------------
1745 DrawVia (PinTypePtr Via
, int unused
)
1748 SetPVColor (Via
, VIA_TYPE
);
1749 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Via) && TEST_ANY_PIPS (Via))
1750 // ClearPin (Via, VIA_TYPE, 0);
1752 DrawPinOrViaLowLevel (Via
, True
);
1753 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
1754 DrawPinOrViaNameLowLevel (Via
);
1757 /* ---------------------------------------------------------------------------
1758 * draw a via without dealing with polygon clearance
1761 DrawPlainVia (PinTypePtr Via
, Boolean holeToo
)
1764 SetPVColor (Via
, VIA_TYPE
);
1765 DrawPinOrViaLowLevel (Via
, holeToo
);
1766 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
1767 DrawPinOrViaNameLowLevel (Via
);
1770 /* ---------------------------------------------------------------------------
1771 * draws the name of a via
1774 DrawViaName (PinTypePtr Via
, int unused
)
1778 if (TEST_FLAG (SELECTEDFLAG
, Via
))
1779 gui
->set_color (Output
.fgGC
, PCB
->ViaSelectedColor
);
1781 gui
->set_color (Output
.fgGC
, PCB
->ViaColor
);
1783 DrawPinOrViaNameLowLevel (Via
);
1786 /* ---------------------------------------------------------------------------
1790 DrawPin (PinTypePtr Pin
, int unused
)
1792 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Pin) && TEST_ANY_PIPS (Pin))
1793 // ClearPin (Pin, PIN_TYPE, 0);
1797 SetPVColor (Pin
, PIN_TYPE
);
1798 DrawPinOrViaLowLevel (Pin
, True
);
1800 if ((!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1802 DrawPinOrViaNameLowLevel (Pin
);
1805 /* ---------------------------------------------------------------------------
1806 * draw a pin without clearing around polygons
1809 DrawPlainPin (PinTypePtr Pin
, Boolean holeToo
)
1812 SetPVColor (Pin
, PIN_TYPE
);
1813 DrawPinOrViaLowLevel (Pin
, holeToo
);
1814 if (!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1815 DrawPinOrViaNameLowLevel (Pin
);
1818 /* ---------------------------------------------------------------------------
1819 * draws the name of a pin
1822 DrawPinName (PinTypePtr Pin
, int unused
)
1826 if (TEST_FLAG (SELECTEDFLAG
, Pin
))
1827 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1829 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1831 DrawPinOrViaNameLowLevel (Pin
);
1834 /* ---------------------------------------------------------------------------
1838 DrawPad (PadTypePtr Pad
, int unused
)
1843 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1844 else if (TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pad
))
1846 if (TEST_FLAG (WARNFLAG
, Pad
))
1847 gui
->set_color (Output
.fgGC
, PCB
->WarnColor
);
1848 else if (TEST_FLAG (SELECTEDFLAG
, Pad
))
1849 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1851 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1853 else if (FRONT (Pad
))
1854 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1856 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
1858 DrawPadLowLevel (Output
.fgGC
, Pad
, False
, False
);
1859 if (doing_pinout
|| TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
1860 DrawPadNameLowLevel (Pad
);
1863 /* ---------------------------------------------------------------------------
1864 * draws the name of a pad
1867 DrawPadName (PadTypePtr Pad
, int unused
)
1871 if (TEST_FLAG (SELECTEDFLAG
, Pad
))
1872 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1873 else if (FRONT (Pad
))
1874 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1876 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
1878 DrawPadNameLowLevel (Pad
);
1881 /* ---------------------------------------------------------------------------
1882 * draws a line on a layer
1885 DrawLine (LayerTypePtr Layer
, LineTypePtr Line
, int unused
)
1889 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Line
))
1891 if (TEST_FLAG (SELECTEDFLAG
, Line
))
1892 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1894 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1897 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1899 DrawLineLowLevel (Line
, False
);
1902 /* ---------------------------------------------------------------------------
1906 DrawRat (RatTypePtr Line
, int unused
)
1910 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Line
))
1912 if (TEST_FLAG (SELECTEDFLAG
, Line
))
1913 gui
->set_color (Output
.fgGC
, PCB
->RatSelectedColor
);
1915 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1918 gui
->set_color (Output
.fgGC
, PCB
->RatColor
);
1920 if (Settings
.RatThickness
< 20)
1921 Line
->Thickness
= pixel_slop
* Settings
.RatThickness
;
1922 /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */
1923 if (TEST_FLAG(VIAFLAG
, Line
))
1925 int w
= Line
->Thickness
;
1931 b
.X1
= Line
->Point1
.X
- w
* 2 - w
/ 2;
1932 b
.X2
= Line
->Point1
.X
+ w
* 2 + w
/ 2;
1933 b
.Y1
= Line
->Point1
.Y
- w
* 2 - w
/ 2;
1934 b
.Y2
= Line
->Point1
.Y
+ w
* 2 + w
/ 2;
1939 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1940 gui
->set_line_width (Output
.fgGC
, 0);
1942 gui
->set_line_width (Output
.fgGC
, w
);
1943 gui
->draw_arc (Output
.fgGC
, Line
->Point1
.X
, Line
->Point1
.Y
,
1944 w
* 2, w
* 2, 0, 360);
1948 DrawLineLowLevel ((LineTypePtr
) Line
, False
);
1951 /* ---------------------------------------------------------------------------
1952 * draws an arc on a layer
1955 DrawArc (LayerTypePtr Layer
, ArcTypePtr Arc
, int unused
)
1957 if (!Arc
->Thickness
)
1961 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Arc
))
1963 if (TEST_FLAG (SELECTEDFLAG
, Arc
))
1964 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1966 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1969 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1971 DrawArcLowLevel (Arc
);
1974 /* ---------------------------------------------------------------------------
1975 * draws a text on a layer
1978 DrawText (LayerTypePtr Layer
, TextTypePtr Text
, int unused
)
1983 if (TEST_FLAG (SELECTEDFLAG
, Text
))
1984 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1986 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1987 if (Layer
== & PCB
->Data
->SILKLAYER
1988 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
1989 min_silk_line
= PCB
->minSlk
;
1991 min_silk_line
= PCB
->minWid
;
1992 DrawTextLowLevel (Text
, min_silk_line
);
1995 /* ---------------------------------------------------------------------------
1996 * draws text on a layer
1999 DrawRegularText (LayerTypePtr Layer
, TextTypePtr Text
, int unused
)
2002 if (TEST_FLAG (SELECTEDFLAG
, Text
))
2003 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2005 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2006 if (Layer
== & PCB
->Data
->SILKLAYER
2007 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2008 min_silk_line
= PCB
->minSlk
;
2010 min_silk_line
= PCB
->minWid
;
2011 DrawTextLowLevel (Text
, min_silk_line
);
2015 cp_callback (const BoxType
* b
, void *cl
)
2017 ClearPin ((PinTypePtr
) b
, (int) (size_t) cl
, 0);
2021 /* ---------------------------------------------------------------------------
2022 * draws a polygon on a layer
2025 DrawPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
, int unused
)
2029 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Polygon
))
2031 if (TEST_FLAG (SELECTEDFLAG
, Polygon
))
2032 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2034 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
2037 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2038 layernum
= GetLayerNumber (PCB
->Data
, Layer
);
2039 DrawPolygonLowLevel (Polygon
);
2040 if (TEST_FLAG (CLEARPOLYFLAG
, Polygon
))
2042 r_search (PCB
->Data
->pin_tree
, &Polygon
->BoundingBox
, NULL
,
2043 cp_callback
, (void *) PIN_TYPE
);
2044 r_search (PCB
->Data
->via_tree
, &Polygon
->BoundingBox
, NULL
,
2045 cp_callback
, (void *) VIA_TYPE
);
2050 thin_callback (PLINE
* pl
, LayerTypePtr lay
, PolygonTypePtr poly
)
2056 x
= (int *) malloc (pl
->Count
* sizeof (int));
2057 y
= (int *) malloc (pl
->Count
* sizeof (int));
2058 for (v
= &pl
->head
; i
< pl
->Count
; v
= v
->next
)
2061 y
[i
++] = v
->point
[1];
2063 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
2064 gui
->set_line_width (Output
.fgGC
, 0);
2065 for (i
= 0; i
< pl
->Count
- 1; i
++)
2067 gui
->draw_line (Output
.fgGC
, x
[i
], y
[i
], x
[i
+ 1], y
[i
+ 1]);
2068 // gui->fill_circle (Output.fgGC, x[i], y[i], 30);
2070 gui
->draw_line (Output
.fgGC
, x
[pl
->Count
- 1], y
[pl
->Count
- 1], x
[0],
2078 /* ---------------------------------------------------------------------------
2082 DrawPlainPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
2086 if (!Polygon
->Clipped
)
2095 if (TEST_FLAG (SELECTEDFLAG
, Polygon
))
2096 color
= Layer
->SelectedColor
;
2097 else if (TEST_FLAG (FOUNDFLAG
, Polygon
))
2098 color
= PCB
->ConnectedColor
;
2100 color
= Layer
->Color
;
2101 gui
->set_color (Output
.fgGC
, color
);
2103 if (gui
->thindraw_pcb_polygon
!= NULL
&&
2104 (TEST_FLAG (THINDRAWFLAG
, PCB
) ||
2105 TEST_FLAG (THINDRAWPOLYFLAG
, PCB
)))
2106 gui
->thindraw_pcb_polygon (Output
.fgGC
, Polygon
, clip_box
);
2108 gui
->fill_pcb_polygon (Output
.fgGC
, Polygon
, clip_box
);
2110 /* If checking planes, thin-draw any pieces which have been clipped away */
2111 if (gui
->thindraw_pcb_polygon
!= NULL
&&
2112 TEST_FLAG (CHECKPLANESFLAG
, PCB
) &&
2113 !TEST_FLAG (FULLPOLYFLAG
, Polygon
))
2115 PolygonType poly
= *Polygon
;
2117 for (poly
.Clipped
= Polygon
->Clipped
->f
;
2118 poly
.Clipped
!= Polygon
->Clipped
;
2119 poly
.Clipped
= poly
.Clipped
->f
)
2120 gui
->thindraw_pcb_polygon (Output
.fgGC
, &poly
, clip_box
);
2124 /* ---------------------------------------------------------------------------
2128 DrawElement (ElementTypePtr Element
, int unused
)
2130 DrawElementPackage (Element
, unused
);
2131 DrawElementName (Element
, unused
);
2132 DrawElementPinsAndPads (Element
, unused
);
2135 /* ---------------------------------------------------------------------------
2136 * draws the name of an element
2139 DrawElementName (ElementTypePtr Element
, int unused
)
2141 if (gui
->gui
&& TEST_FLAG (HIDENAMESFLAG
, PCB
))
2143 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
2145 if (doing_pinout
|| doing_assy
)
2146 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2147 else if (TEST_FLAG (SELECTEDFLAG
, &ELEMENT_TEXT (PCB
, Element
)))
2148 gui
->set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
2149 else if (FRONT (Element
))
2150 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2152 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
2153 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2156 /* ---------------------------------------------------------------------------
2157 * draws the package of an element
2160 DrawElementPackage (ElementTypePtr Element
, int unused
)
2162 /* set color and draw lines, arcs, text and pins */
2163 if (doing_pinout
|| doing_assy
)
2164 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2165 else if (TEST_FLAG (SELECTEDFLAG
, Element
))
2166 gui
->set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
2167 else if (FRONT (Element
))
2168 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2170 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
2171 DrawElementPackageLowLevel (Element
, unused
);
2174 /* ---------------------------------------------------------------------------
2175 * draw pins of an element
2178 DrawElementPinsAndPads (ElementTypePtr Element
, int unused
)
2182 if (doing_pinout
|| doing_assy
|| FRONT (pad
) || PCB
->InvisibleObjectsOn
)
2183 DrawPad (pad
, unused
);
2188 DrawPin (pin
, unused
);
2193 /* ---------------------------------------------------------------------------
2197 EraseVia (PinTypePtr Via
)
2200 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2201 DrawPinOrViaLowLevel (Via
, False
);
2202 if (TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
2203 DrawPinOrViaNameLowLevel (Via
);
2207 /* ---------------------------------------------------------------------------
2211 EraseRat (RatTypePtr Rat
)
2214 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2215 if (TEST_FLAG(VIAFLAG
, Rat
))
2217 int w
= Rat
->Thickness
;
2219 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
2220 gui
->set_line_width (Output
.fgGC
, 0);
2222 gui
->set_line_width (Output
.fgGC
, w
);
2223 gui
->draw_arc (Output
.fgGC
, Rat
->Point1
.X
, Rat
->Point1
.Y
,
2224 w
* 2, w
* 2, 0, 360);
2227 DrawLineLowLevel ((LineTypePtr
) Rat
, False
);
2232 /* ---------------------------------------------------------------------------
2236 EraseViaName (PinTypePtr Via
)
2239 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2240 DrawPinOrViaNameLowLevel (Via
);
2244 /* ---------------------------------------------------------------------------
2245 * erase a pad object
2248 ErasePad (PadTypePtr Pad
)
2251 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2252 DrawPadLowLevel (Output
.fgGC
, Pad
, False
, False
);
2253 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
2254 DrawPadNameLowLevel (Pad
);
2258 /* ---------------------------------------------------------------------------
2262 ErasePadName (PadTypePtr Pad
)
2265 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2266 DrawPadNameLowLevel (Pad
);
2270 /* ---------------------------------------------------------------------------
2271 * erase a pin object
2274 ErasePin (PinTypePtr Pin
)
2277 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2278 DrawPinOrViaLowLevel (Pin
, False
);
2279 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
2280 DrawPinOrViaNameLowLevel (Pin
);
2284 /* ---------------------------------------------------------------------------
2288 ErasePinName (PinTypePtr Pin
)
2291 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2292 DrawPinOrViaNameLowLevel (Pin
);
2296 /* ---------------------------------------------------------------------------
2297 * erases a line on a layer
2300 EraseLine (LineTypePtr Line
)
2303 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2304 DrawLineLowLevel (Line
, False
);
2308 /* ---------------------------------------------------------------------------
2309 * erases an arc on a layer
2312 EraseArc (ArcTypePtr Arc
)
2314 if (!Arc
->Thickness
)
2317 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2318 DrawArcLowLevel (Arc
);
2322 /* ---------------------------------------------------------------------------
2323 * erases a text on a layer
2326 EraseText (LayerTypePtr Layer
, TextTypePtr Text
)
2330 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2331 if (Layer
== & PCB
->Data
->SILKLAYER
2332 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2333 min_silk_line
= PCB
->minSlk
;
2335 min_silk_line
= PCB
->minWid
;
2336 DrawTextLowLevel (Text
, min_silk_line
);
2340 /* ---------------------------------------------------------------------------
2341 * erases a polygon on a layer
2344 ErasePolygon (PolygonTypePtr Polygon
)
2347 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2348 DrawPolygonLowLevel (Polygon
);
2352 /* ---------------------------------------------------------------------------
2356 EraseElement (ElementTypePtr Element
)
2359 /* set color and draw lines, arcs, text and pins */
2360 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2361 ELEMENTLINE_LOOP (Element
);
2363 DrawLineLowLevel (line
, False
);
2368 DrawArcLowLevel (arc
);
2371 if (!TEST_FLAG (HIDENAMEFLAG
, Element
))
2372 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2373 EraseElementPinsAndPads (Element
);
2377 /* ---------------------------------------------------------------------------
2378 * erases all pins and pads of an element
2381 EraseElementPinsAndPads (ElementTypePtr Element
)
2384 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2387 /* if (TEST_ANY_PIPS (pin))
2389 ClearPin (pin, NO_TYPE, 0);
2390 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2393 DrawPinOrViaLowLevel (pin
, False
);
2394 if (TEST_FLAG (DISPLAYNAMEFLAG
, pin
))
2395 DrawPinOrViaNameLowLevel (pin
);
2400 DrawPadLowLevel (Output
.fgGC
, pad
, False
, False
);
2401 if (TEST_FLAG (DISPLAYNAMEFLAG
, pad
))
2402 DrawPadNameLowLevel (pad
);
2408 /* ---------------------------------------------------------------------------
2409 * erases the name of an element
2412 EraseElementName (ElementTypePtr Element
)
2414 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
2417 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2418 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2424 EraseObject (int type
, void *lptr
, void *ptr
)
2430 ErasePin ((PinTypePtr
) ptr
);
2433 case ELEMENTNAME_TYPE
:
2434 EraseText (lptr
, (TextTypePtr
) ptr
);
2437 ErasePolygon ((PolygonTypePtr
) ptr
);
2440 EraseElement ((ElementTypePtr
) ptr
);
2443 case ELEMENTLINE_TYPE
:
2445 EraseLine ((LineTypePtr
) ptr
);
2448 ErasePad ((PadTypePtr
) ptr
);
2451 case ELEMENTARC_TYPE
:
2452 EraseArc ((ArcTypePtr
) ptr
);
2455 Message ("hace: Internal ERROR, trying to erase an unknown type\n");
2462 DrawObject (int type
, void *ptr1
, void *ptr2
, int unused
)
2468 DrawVia ((PinTypePtr
) ptr2
, 0);
2471 if (((LayerTypePtr
) ptr1
)->On
)
2472 DrawLine ((LayerTypePtr
) ptr1
, (LineTypePtr
) ptr2
, 0);
2475 if (((LayerTypePtr
) ptr1
)->On
)
2476 DrawArc ((LayerTypePtr
) ptr1
, (ArcTypePtr
) ptr2
, 0);
2479 if (((LayerTypePtr
) ptr1
)->On
)
2480 DrawText ((LayerTypePtr
) ptr1
, (TextTypePtr
) ptr2
, 0);
2483 if (((LayerTypePtr
) ptr1
)->On
)
2484 DrawPolygon ((LayerTypePtr
) ptr1
, (PolygonTypePtr
) ptr2
, 0);
2487 if (PCB
->ElementOn
&&
2488 (FRONT ((ElementTypePtr
) ptr2
) || PCB
->InvisibleObjectsOn
))
2489 DrawElement ((ElementTypePtr
) ptr2
, 0);
2493 DrawRat ((RatTypePtr
) ptr2
, 0);
2497 DrawPin ((PinTypePtr
) ptr2
, 0);
2501 DrawPad ((PadTypePtr
) ptr2
, 0);
2503 case ELEMENTNAME_TYPE
:
2504 if (PCB
->ElementOn
&&
2505 (FRONT ((ElementTypePtr
) ptr2
) || PCB
->InvisibleObjectsOn
))
2506 DrawElementName ((ElementTypePtr
) ptr1
, 0);
2511 /* ---------------------------------------------------------------------------
2512 * HID drawing callback.
2516 hid_expose_callback (HID
* hid
, BoxType
* region
, void *item
)
2519 hidGC savebg
= Output
.bgGC
;
2520 hidGC savefg
= Output
.fgGC
;
2521 hidGC savepm
= Output
.pmGC
;
2524 Output
.fgGC
= gui
->make_gc ();
2525 Output
.bgGC
= gui
->make_gc ();
2526 Output
.pmGC
= gui
->make_gc ();
2531 /*printf("\033[32mhid_expose_callback, s=%p %d\033[0m\n", &(SWAP_IDENT), SWAP_IDENT); */
2533 hid
->set_color (Output
.pmGC
, "erase");
2534 hid
->set_color (Output
.bgGC
, "drill");
2538 doing_pinout
= True
;
2539 DrawElement (item
, 0);
2540 doing_pinout
= False
;
2543 DrawEverything (region
);
2545 gui
->destroy_gc (Output
.fgGC
);
2546 gui
->destroy_gc (Output
.bgGC
);
2547 gui
->destroy_gc (Output
.pmGC
);
2549 Output
.fgGC
= savefg
;
2550 Output
.bgGC
= savebg
;
2551 Output
.pmGC
= savepm
;