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 (strcmp (Layer
->Name
, "outline") == 0
895 || strcmp (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 (TEST_FLAG (THINDRAWFLAG
, PCB
) ||
1353 (clear
&& TEST_FLAG (THINDRAWPOLYFLAG
, PCB
)))
1355 int x1
, y1
, x2
, y2
, t
, t2
;
1362 if (x1
> x2
|| y1
> y2
)
1364 /* this is a silly way to swap the variables */
1372 gui
->set_line_cap (gc
, Round_Cap
);
1373 gui
->set_line_width (gc
, 0);
1374 if (TEST_FLAG (SQUAREFLAG
, Pad
)
1375 && (x1
== x2
|| y1
== y2
))
1381 gui
->draw_line (gc
, x1
, y1
, x1
, y2
);
1382 gui
->draw_line (gc
, x1
, y2
, x2
, y2
);
1383 gui
->draw_line (gc
, x2
, y2
, x2
, y1
);
1384 gui
->draw_line (gc
, x2
, y1
, x1
, y1
);
1386 else if (TEST_FLAG (SQUAREFLAG
, Pad
))
1388 /* slanted square pad */
1389 float tx
, ty
, theta
;
1391 theta
= atan2 (y2
-y1
, x2
-x1
);
1393 /* T is a vector half a thickness long, in the direction of
1394 one of the corners. */
1395 tx
= t
* cos (theta
+ M_PI
/4) * sqrt(2.0);
1396 ty
= t
* sin (theta
+ M_PI
/4) * sqrt(2.0);
1398 gui
->draw_line (gc
, x1
-tx
, y1
-ty
, x2
+ty
, y2
-tx
);
1399 gui
->draw_line (gc
, x2
+ty
, y2
-tx
, x2
+tx
, y2
+ty
);
1400 gui
->draw_line (gc
, x2
+tx
, y2
+ty
, x1
-ty
, y1
+tx
);
1401 gui
->draw_line (gc
, x1
-ty
, y1
+tx
, x1
-tx
, y1
-ty
);
1403 else if (x1
== x2
&& y1
== y2
)
1405 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 0, 360);
1409 gui
->draw_line (gc
, x1
- t
, y1
, x2
- t
, y2
);
1410 gui
->draw_line (gc
, x1
+ t2
, y1
, x2
+ t2
, y2
);
1411 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 0, -180);
1412 gui
->draw_arc (gc
, x2
, y2
, w
/ 2, w
/ 2, 180, -180);
1416 gui
->draw_line (gc
, x1
, y1
- t
, x2
, y2
- t
);
1417 gui
->draw_line (gc
, x1
, y1
+ t2
, x2
, y2
+ t2
);
1418 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 90, -180);
1419 gui
->draw_arc (gc
, x2
, y2
, w
/ 2, w
/ 2, 270, -180);
1423 /* Slanted round-end pads. */
1424 LocationType dx
, dy
, ox
, oy
;
1429 h
= t
/ sqrt (SQUARE (dx
) + SQUARE (dy
));
1430 ox
= dy
* h
+ 0.5 * SGN (dy
);
1431 oy
= -(dx
* h
+ 0.5 * SGN (dx
));
1433 gui
->draw_line (gc
, x1
+ ox
, y1
+ oy
, x2
+ ox
, y2
+ oy
);
1435 if (abs (ox
) >= pixel_slop
|| abs (oy
) >= pixel_slop
)
1437 LocationType angle
= atan2 ((float) dx
, (float) dy
) * 57.295779;
1438 gui
->draw_line (gc
, x1
- ox
, y1
- oy
, x2
- ox
, y2
- oy
);
1440 x1
, y1
, t
, t
, angle
- 180, 180);
1441 gui
->draw_arc (gc
, x2
, y2
, t
, t
, angle
, 180);
1445 else if (Pad
->Point1
.X
== Pad
->Point2
.X
1446 && Pad
->Point1
.Y
== Pad
->Point2
.Y
)
1448 if (TEST_FLAG (SQUAREFLAG
, Pad
))
1451 l
= Pad
->Point1
.X
- w
/ 2;
1452 b
= Pad
->Point1
.Y
- w
/ 2;
1455 gui
->fill_rect (gc
, l
, b
, r
, t
);
1459 gui
->fill_circle (gc
, Pad
->Point1
.X
, Pad
->Point1
.Y
, w
/ 2);
1464 gui
->set_line_cap (gc
,
1465 TEST_FLAG (SQUAREFLAG
,
1466 Pad
) ? Square_Cap
: Round_Cap
);
1467 gui
->set_line_width (gc
, w
);
1470 Pad
->Point1
.X
, Pad
->Point1
.Y
,
1471 Pad
->Point2
.X
, Pad
->Point2
.Y
);
1474 { /* Draw bounding box for test */
1475 BoxType
*box
= &Pad
->BoundingBox
;
1476 gui
->set_line_width (gc
, 0);
1477 gui
->draw_line (gc
, box
->X1
, box
->Y1
, box
->X1
, box
->Y2
);
1478 gui
->draw_line (gc
, box
->X1
, box
->Y2
, box
->X2
, box
->Y2
);
1479 gui
->draw_line (gc
, box
->X2
, box
->Y2
, box
->X2
, box
->Y1
);
1480 gui
->draw_line (gc
, box
->X2
, box
->Y1
, box
->X1
, box
->Y1
);
1485 /* ---------------------------------------------------------------------------
1486 * lowlevel drawing routine for pad names
1490 DrawPadNameLowLevel (PadTypePtr Pad
)
1497 if (!Pad
->Name
|| !Pad
->Name
[0])
1498 name
= EMPTY (Pad
->Number
);
1500 name
= EMPTY (TEST_FLAG (SHOWNUMBERFLAG
, PCB
) ? Pad
->Number
: Pad
->Name
);
1502 /* should text be vertical ? */
1503 vert
= (Pad
->Point1
.X
== Pad
->Point2
.X
);
1507 box
.X1
= Pad
->Point1
.X
- Pad
->Thickness
/ 2;
1508 box
.Y1
= MAX (Pad
->Point1
.Y
, Pad
->Point2
.Y
) + Pad
->Thickness
/ 2;
1512 box
.X1
= MIN (Pad
->Point1
.X
, Pad
->Point2
.X
) - Pad
->Thickness
/ 2;
1513 box
.Y1
= Pad
->Point1
.Y
- Pad
->Thickness
/ 2;
1518 box
.X1
+= Settings
.PinoutTextOffsetY
;
1519 box
.Y1
-= Settings
.PinoutTextOffsetX
;
1523 box
.X1
+= Settings
.PinoutTextOffsetX
;
1524 box
.Y1
+= Settings
.PinoutTextOffsetY
;
1543 gui
->set_color (Output
.fgGC
, PCB
->PinNameColor
);
1545 text
.Flags
= NoFlags ();
1546 text
.Scale
= Pad
->Thickness
/ 50;
1549 text
.Direction
= vert
? 1 : 0;
1550 text
.TextString
= name
;
1552 DrawTextLowLevel (&text
, 0);
1556 /* ---------------------------------------------------------------------------
1557 * clearance for pads
1560 ClearPad (PadTypePtr Pad
, Boolean mask
)
1562 DrawPadLowLevel(Output
.pmGC
, Pad
, True
, mask
);
1565 /* ---------------------------------------------------------------------------
1566 * lowlevel drawing routine for lines
1569 DrawLineLowLevel (LineTypePtr Line
, Boolean HaveGathered
)
1571 if (Gathering
&& !HaveGathered
)
1577 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
1578 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1579 gui
->set_line_width (Output
.fgGC
, 0);
1581 gui
->set_line_width (Output
.fgGC
, Line
->Thickness
);
1583 gui
->draw_line (Output
.fgGC
,
1584 Line
->Point1
.X
, Line
->Point1
.Y
,
1585 Line
->Point2
.X
, Line
->Point2
.Y
);
1588 /* ---------------------------------------------------------------------------
1589 * lowlevel drawing routine for text objects
1592 DrawTextLowLevel (TextTypePtr Text
, int min_line_width
)
1595 unsigned char *string
= (unsigned char *) Text
->TextString
;
1597 FontTypePtr font
= &PCB
->Font
;
1605 while (string
&& *string
)
1607 /* draw lines if symbol is valid and data is present */
1608 if (*string
<= MAX_FONTPOSITION
&& font
->Symbol
[*string
].Valid
)
1610 LineTypePtr line
= font
->Symbol
[*string
].Line
;
1613 for (n
= font
->Symbol
[*string
].LineN
; n
; n
--, line
++)
1615 /* create one line, scale, move, rotate and swap it */
1617 newline
.Point1
.X
= (newline
.Point1
.X
+ x
) * Text
->Scale
/ 100;
1618 newline
.Point1
.Y
= newline
.Point1
.Y
* Text
->Scale
/ 100;
1619 newline
.Point2
.X
= (newline
.Point2
.X
+ x
) * Text
->Scale
/ 100;
1620 newline
.Point2
.Y
= newline
.Point2
.Y
* Text
->Scale
/ 100;
1621 newline
.Thickness
= newline
.Thickness
* Text
->Scale
/ 200;
1622 if (newline
.Thickness
< min_line_width
)
1623 newline
.Thickness
= min_line_width
;
1625 RotateLineLowLevel (&newline
, 0, 0, Text
->Direction
);
1627 /* the labels of SMD objects on the bottom
1628 * side haven't been swapped yet, only their offset
1630 if (TEST_FLAG (ONSOLDERFLAG
, Text
))
1632 newline
.Point1
.X
= SWAP_SIGN_X (newline
.Point1
.X
);
1633 newline
.Point1
.Y
= SWAP_SIGN_Y (newline
.Point1
.Y
);
1634 newline
.Point2
.X
= SWAP_SIGN_X (newline
.Point2
.X
);
1635 newline
.Point2
.Y
= SWAP_SIGN_Y (newline
.Point2
.Y
);
1637 /* add offset and draw line */
1638 newline
.Point1
.X
+= Text
->X
;
1639 newline
.Point1
.Y
+= Text
->Y
;
1640 newline
.Point2
.X
+= Text
->X
;
1641 newline
.Point2
.Y
+= Text
->Y
;
1642 DrawLineLowLevel (&newline
, True
);
1645 /* move on to next cursor position */
1646 x
+= (font
->Symbol
[*string
].Width
+ font
->Symbol
[*string
].Delta
);
1650 /* the default symbol is a filled box */
1651 BoxType defaultsymbol
= PCB
->Font
.DefaultSymbol
;
1652 LocationType size
= (defaultsymbol
.X2
- defaultsymbol
.X1
) * 6 / 5;
1654 defaultsymbol
.X1
= (defaultsymbol
.X1
+ x
) * Text
->Scale
/ 100;
1655 defaultsymbol
.Y1
= defaultsymbol
.Y1
* Text
->Scale
/ 100;
1656 defaultsymbol
.X2
= (defaultsymbol
.X2
+ x
) * Text
->Scale
/ 100;
1657 defaultsymbol
.Y2
= defaultsymbol
.Y2
* Text
->Scale
/ 100;
1659 RotateBoxLowLevel (&defaultsymbol
, 0, 0, Text
->Direction
);
1661 /* add offset and draw box */
1662 defaultsymbol
.X1
+= Text
->X
;
1663 defaultsymbol
.Y1
+= Text
->Y
;
1664 defaultsymbol
.X2
+= Text
->X
;
1665 defaultsymbol
.Y2
+= Text
->Y
;
1666 gui
->fill_rect (Output
.fgGC
,
1667 defaultsymbol
.X1
, defaultsymbol
.Y1
,
1668 defaultsymbol
.X2
, defaultsymbol
.Y2
);
1670 /* move on to next cursor position */
1677 /* ---------------------------------------------------------------------------
1678 * lowlevel drawing routine for polygons
1681 DrawPolygonLowLevel (PolygonTypePtr Polygon
)
1683 if (!Polygon
->Clipped
)
1692 printf ("DrawPolygonLowLevel: Called without Gathering set!\n");
1695 /* ---------------------------------------------------------------------------
1696 * lowlevel routine to element arcs
1699 DrawArcLowLevel (ArcTypePtr Arc
)
1701 if (!Arc
->Thickness
)
1709 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1710 gui
->set_line_width (Output
.fgGC
, 0);
1712 gui
->set_line_width (Output
.fgGC
, Arc
->Thickness
);
1713 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
1715 gui
->draw_arc (Output
.fgGC
, Arc
->X
, Arc
->Y
, Arc
->Width
,
1716 Arc
->Height
, Arc
->StartAngle
, Arc
->Delta
);
1719 /* ---------------------------------------------------------------------------
1720 * draws the package of an element
1723 DrawElementPackageLowLevel (ElementTypePtr Element
, int unused
)
1725 /* draw lines, arcs, text and pins */
1726 ELEMENTLINE_LOOP (Element
);
1728 DrawLineLowLevel (line
, False
);
1733 DrawArcLowLevel (arc
);
1738 /* ---------------------------------------------------------------------------
1742 DrawVia (PinTypePtr Via
, int unused
)
1745 SetPVColor (Via
, VIA_TYPE
);
1746 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Via) && TEST_ANY_PIPS (Via))
1747 // ClearPin (Via, VIA_TYPE, 0);
1749 DrawPinOrViaLowLevel (Via
, True
);
1750 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
1751 DrawPinOrViaNameLowLevel (Via
);
1754 /* ---------------------------------------------------------------------------
1755 * draw a via without dealing with polygon clearance
1758 DrawPlainVia (PinTypePtr Via
, Boolean holeToo
)
1761 SetPVColor (Via
, VIA_TYPE
);
1762 DrawPinOrViaLowLevel (Via
, holeToo
);
1763 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
1764 DrawPinOrViaNameLowLevel (Via
);
1767 /* ---------------------------------------------------------------------------
1768 * draws the name of a via
1771 DrawViaName (PinTypePtr Via
, int unused
)
1775 if (TEST_FLAG (SELECTEDFLAG
, Via
))
1776 gui
->set_color (Output
.fgGC
, PCB
->ViaSelectedColor
);
1778 gui
->set_color (Output
.fgGC
, PCB
->ViaColor
);
1780 DrawPinOrViaNameLowLevel (Via
);
1783 /* ---------------------------------------------------------------------------
1787 DrawPin (PinTypePtr Pin
, int unused
)
1789 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Pin) && TEST_ANY_PIPS (Pin))
1790 // ClearPin (Pin, PIN_TYPE, 0);
1794 SetPVColor (Pin
, PIN_TYPE
);
1795 DrawPinOrViaLowLevel (Pin
, True
);
1797 if ((!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1799 DrawPinOrViaNameLowLevel (Pin
);
1802 /* ---------------------------------------------------------------------------
1803 * draw a pin without clearing around polygons
1806 DrawPlainPin (PinTypePtr Pin
, Boolean holeToo
)
1809 SetPVColor (Pin
, PIN_TYPE
);
1810 DrawPinOrViaLowLevel (Pin
, holeToo
);
1811 if (!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1812 DrawPinOrViaNameLowLevel (Pin
);
1815 /* ---------------------------------------------------------------------------
1816 * draws the name of a pin
1819 DrawPinName (PinTypePtr Pin
, int unused
)
1823 if (TEST_FLAG (SELECTEDFLAG
, Pin
))
1824 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1826 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1828 DrawPinOrViaNameLowLevel (Pin
);
1831 /* ---------------------------------------------------------------------------
1835 DrawPad (PadTypePtr Pad
, int unused
)
1840 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1841 else if (TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pad
))
1843 if (TEST_FLAG (WARNFLAG
, Pad
))
1844 gui
->set_color (Output
.fgGC
, PCB
->WarnColor
);
1845 else if (TEST_FLAG (SELECTEDFLAG
, Pad
))
1846 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1848 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1850 else if (FRONT (Pad
))
1851 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1853 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
1855 DrawPadLowLevel (Output
.fgGC
, Pad
, False
, False
);
1856 if (doing_pinout
|| TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
1857 DrawPadNameLowLevel (Pad
);
1860 /* ---------------------------------------------------------------------------
1861 * draws the name of a pad
1864 DrawPadName (PadTypePtr Pad
, int unused
)
1868 if (TEST_FLAG (SELECTEDFLAG
, Pad
))
1869 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1870 else if (FRONT (Pad
))
1871 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1873 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
1875 DrawPadNameLowLevel (Pad
);
1878 /* ---------------------------------------------------------------------------
1879 * draws a line on a layer
1882 DrawLine (LayerTypePtr Layer
, LineTypePtr Line
, int unused
)
1886 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Line
))
1888 if (TEST_FLAG (SELECTEDFLAG
, Line
))
1889 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1891 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1894 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1896 DrawLineLowLevel (Line
, False
);
1899 /* ---------------------------------------------------------------------------
1903 DrawRat (RatTypePtr Line
, int unused
)
1907 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Line
))
1909 if (TEST_FLAG (SELECTEDFLAG
, Line
))
1910 gui
->set_color (Output
.fgGC
, PCB
->RatSelectedColor
);
1912 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1915 gui
->set_color (Output
.fgGC
, PCB
->RatColor
);
1917 if (Settings
.RatThickness
< 20)
1918 Line
->Thickness
= pixel_slop
* Settings
.RatThickness
;
1919 /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */
1920 if (TEST_FLAG(VIAFLAG
, Line
))
1922 int w
= Line
->Thickness
;
1928 b
.X1
= Line
->Point1
.X
- w
* 2 - w
/ 2;
1929 b
.X2
= Line
->Point1
.X
+ w
* 2 + w
/ 2;
1930 b
.Y1
= Line
->Point1
.Y
- w
* 2 - w
/ 2;
1931 b
.Y2
= Line
->Point1
.Y
+ w
* 2 + w
/ 2;
1936 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1937 gui
->set_line_width (Output
.fgGC
, 0);
1939 gui
->set_line_width (Output
.fgGC
, w
);
1940 gui
->draw_arc (Output
.fgGC
, Line
->Point1
.X
, Line
->Point1
.Y
,
1941 w
* 2, w
* 2, 0, 360);
1945 DrawLineLowLevel ((LineTypePtr
) Line
, False
);
1948 /* ---------------------------------------------------------------------------
1949 * draws an arc on a layer
1952 DrawArc (LayerTypePtr Layer
, ArcTypePtr Arc
, int unused
)
1954 if (!Arc
->Thickness
)
1958 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Arc
))
1960 if (TEST_FLAG (SELECTEDFLAG
, Arc
))
1961 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1963 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1966 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1968 DrawArcLowLevel (Arc
);
1971 /* ---------------------------------------------------------------------------
1972 * draws a text on a layer
1975 DrawText (LayerTypePtr Layer
, TextTypePtr Text
, int unused
)
1980 if (TEST_FLAG (SELECTEDFLAG
, Text
))
1981 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1983 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1984 if (Layer
== & PCB
->Data
->SILKLAYER
1985 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
1986 min_silk_line
= PCB
->minSlk
;
1988 min_silk_line
= PCB
->minWid
;
1989 DrawTextLowLevel (Text
, min_silk_line
);
1992 /* ---------------------------------------------------------------------------
1993 * draws text on a layer
1996 DrawRegularText (LayerTypePtr Layer
, TextTypePtr Text
, int unused
)
1999 if (TEST_FLAG (SELECTEDFLAG
, Text
))
2000 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2002 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2003 if (Layer
== & PCB
->Data
->SILKLAYER
2004 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2005 min_silk_line
= PCB
->minSlk
;
2007 min_silk_line
= PCB
->minWid
;
2008 DrawTextLowLevel (Text
, min_silk_line
);
2012 cp_callback (const BoxType
* b
, void *cl
)
2014 ClearPin ((PinTypePtr
) b
, (int) (size_t) cl
, 0);
2018 /* ---------------------------------------------------------------------------
2019 * draws a polygon on a layer
2022 DrawPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
, int unused
)
2026 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Polygon
))
2028 if (TEST_FLAG (SELECTEDFLAG
, Polygon
))
2029 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2031 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
2034 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2035 layernum
= GetLayerNumber (PCB
->Data
, Layer
);
2036 DrawPolygonLowLevel (Polygon
);
2037 if (TEST_FLAG (CLEARPOLYFLAG
, Polygon
))
2039 r_search (PCB
->Data
->pin_tree
, &Polygon
->BoundingBox
, NULL
,
2040 cp_callback
, (void *) PIN_TYPE
);
2041 r_search (PCB
->Data
->via_tree
, &Polygon
->BoundingBox
, NULL
,
2042 cp_callback
, (void *) VIA_TYPE
);
2047 thin_callback (PLINE
* pl
, LayerTypePtr lay
, PolygonTypePtr poly
)
2053 x
= (int *) malloc (pl
->Count
* sizeof (int));
2054 y
= (int *) malloc (pl
->Count
* sizeof (int));
2055 for (v
= &pl
->head
; i
< pl
->Count
; v
= v
->next
)
2058 y
[i
++] = v
->point
[1];
2060 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
2061 gui
->set_line_width (Output
.fgGC
, 0);
2062 for (i
= 0; i
< pl
->Count
- 1; i
++)
2064 gui
->draw_line (Output
.fgGC
, x
[i
], y
[i
], x
[i
+ 1], y
[i
+ 1]);
2065 // gui->fill_circle (Output.fgGC, x[i], y[i], 30);
2067 gui
->draw_line (Output
.fgGC
, x
[pl
->Count
- 1], y
[pl
->Count
- 1], x
[0],
2075 /* ---------------------------------------------------------------------------
2079 DrawPlainPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
2083 if (!Polygon
->Clipped
)
2092 if (TEST_FLAG (SELECTEDFLAG
, Polygon
))
2093 color
= Layer
->SelectedColor
;
2094 else if (TEST_FLAG (FOUNDFLAG
, Polygon
))
2095 color
= PCB
->ConnectedColor
;
2097 color
= Layer
->Color
;
2098 gui
->set_color (Output
.fgGC
, color
);
2100 if (gui
->thindraw_pcb_polygon
!= NULL
&&
2101 (TEST_FLAG (THINDRAWFLAG
, PCB
) ||
2102 TEST_FLAG (THINDRAWPOLYFLAG
, PCB
)))
2103 gui
->thindraw_pcb_polygon (Output
.fgGC
, Polygon
, clip_box
);
2105 gui
->fill_pcb_polygon (Output
.fgGC
, Polygon
, clip_box
);
2107 /* If checking planes, thin-draw any pieces which have been clipped away */
2108 if (gui
->thindraw_pcb_polygon
!= NULL
&&
2109 TEST_FLAG (CHECKPLANESFLAG
, PCB
) &&
2110 !TEST_FLAG (FULLPOLYFLAG
, Polygon
))
2112 PolygonType poly
= *Polygon
;
2114 for (poly
.Clipped
= Polygon
->Clipped
->f
;
2115 poly
.Clipped
!= Polygon
->Clipped
;
2116 poly
.Clipped
= poly
.Clipped
->f
)
2117 gui
->thindraw_pcb_polygon (Output
.fgGC
, &poly
, clip_box
);
2121 /* ---------------------------------------------------------------------------
2125 DrawElement (ElementTypePtr Element
, int unused
)
2127 DrawElementPackage (Element
, unused
);
2128 DrawElementName (Element
, unused
);
2129 DrawElementPinsAndPads (Element
, unused
);
2132 /* ---------------------------------------------------------------------------
2133 * draws the name of an element
2136 DrawElementName (ElementTypePtr Element
, int unused
)
2138 if (gui
->gui
&& TEST_FLAG (HIDENAMESFLAG
, PCB
))
2140 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
2142 if (doing_pinout
|| doing_assy
)
2143 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2144 else if (TEST_FLAG (SELECTEDFLAG
, &ELEMENT_TEXT (PCB
, Element
)))
2145 gui
->set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
2146 else if (FRONT (Element
))
2147 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2149 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
2150 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2153 /* ---------------------------------------------------------------------------
2154 * draws the package of an element
2157 DrawElementPackage (ElementTypePtr Element
, int unused
)
2159 /* set color and draw lines, arcs, text and pins */
2160 if (doing_pinout
|| doing_assy
)
2161 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2162 else if (TEST_FLAG (SELECTEDFLAG
, Element
))
2163 gui
->set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
2164 else if (FRONT (Element
))
2165 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2167 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
2168 DrawElementPackageLowLevel (Element
, unused
);
2171 /* ---------------------------------------------------------------------------
2172 * draw pins of an element
2175 DrawElementPinsAndPads (ElementTypePtr Element
, int unused
)
2179 if (doing_pinout
|| doing_assy
|| FRONT (pad
) || PCB
->InvisibleObjectsOn
)
2180 DrawPad (pad
, unused
);
2185 DrawPin (pin
, unused
);
2190 /* ---------------------------------------------------------------------------
2194 EraseVia (PinTypePtr Via
)
2197 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2198 DrawPinOrViaLowLevel (Via
, False
);
2199 if (TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
2200 DrawPinOrViaNameLowLevel (Via
);
2204 /* ---------------------------------------------------------------------------
2208 EraseRat (RatTypePtr Rat
)
2211 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2212 if (TEST_FLAG(VIAFLAG
, Rat
))
2214 int w
= Rat
->Thickness
;
2216 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
2217 gui
->set_line_width (Output
.fgGC
, 0);
2219 gui
->set_line_width (Output
.fgGC
, w
);
2220 gui
->draw_arc (Output
.fgGC
, Rat
->Point1
.X
, Rat
->Point1
.Y
,
2221 w
* 2, w
* 2, 0, 360);
2224 DrawLineLowLevel ((LineTypePtr
) Rat
, False
);
2229 /* ---------------------------------------------------------------------------
2233 EraseViaName (PinTypePtr Via
)
2236 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2237 DrawPinOrViaNameLowLevel (Via
);
2241 /* ---------------------------------------------------------------------------
2242 * erase a pad object
2245 ErasePad (PadTypePtr Pad
)
2248 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2249 DrawPadLowLevel (Output
.fgGC
, Pad
, False
, False
);
2250 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
2251 DrawPadNameLowLevel (Pad
);
2255 /* ---------------------------------------------------------------------------
2259 ErasePadName (PadTypePtr Pad
)
2262 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2263 DrawPadNameLowLevel (Pad
);
2267 /* ---------------------------------------------------------------------------
2268 * erase a pin object
2271 ErasePin (PinTypePtr Pin
)
2274 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2275 DrawPinOrViaLowLevel (Pin
, False
);
2276 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
2277 DrawPinOrViaNameLowLevel (Pin
);
2281 /* ---------------------------------------------------------------------------
2285 ErasePinName (PinTypePtr Pin
)
2288 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2289 DrawPinOrViaNameLowLevel (Pin
);
2293 /* ---------------------------------------------------------------------------
2294 * erases a line on a layer
2297 EraseLine (LineTypePtr Line
)
2300 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2301 DrawLineLowLevel (Line
, False
);
2305 /* ---------------------------------------------------------------------------
2306 * erases an arc on a layer
2309 EraseArc (ArcTypePtr Arc
)
2311 if (!Arc
->Thickness
)
2314 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2315 DrawArcLowLevel (Arc
);
2319 /* ---------------------------------------------------------------------------
2320 * erases a text on a layer
2323 EraseText (LayerTypePtr Layer
, TextTypePtr Text
)
2327 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2328 if (Layer
== & PCB
->Data
->SILKLAYER
2329 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2330 min_silk_line
= PCB
->minSlk
;
2332 min_silk_line
= PCB
->minWid
;
2333 DrawTextLowLevel (Text
, min_silk_line
);
2337 /* ---------------------------------------------------------------------------
2338 * erases a polygon on a layer
2341 ErasePolygon (PolygonTypePtr Polygon
)
2344 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2345 DrawPolygonLowLevel (Polygon
);
2349 /* ---------------------------------------------------------------------------
2353 EraseElement (ElementTypePtr Element
)
2356 /* set color and draw lines, arcs, text and pins */
2357 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2358 ELEMENTLINE_LOOP (Element
);
2360 DrawLineLowLevel (line
, False
);
2365 DrawArcLowLevel (arc
);
2368 if (!TEST_FLAG (HIDENAMEFLAG
, Element
))
2369 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2370 EraseElementPinsAndPads (Element
);
2374 /* ---------------------------------------------------------------------------
2375 * erases all pins and pads of an element
2378 EraseElementPinsAndPads (ElementTypePtr Element
)
2381 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2384 /* if (TEST_ANY_PIPS (pin))
2386 ClearPin (pin, NO_TYPE, 0);
2387 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2390 DrawPinOrViaLowLevel (pin
, False
);
2391 if (TEST_FLAG (DISPLAYNAMEFLAG
, pin
))
2392 DrawPinOrViaNameLowLevel (pin
);
2397 DrawPadLowLevel (Output
.fgGC
, pad
, False
, False
);
2398 if (TEST_FLAG (DISPLAYNAMEFLAG
, pad
))
2399 DrawPadNameLowLevel (pad
);
2405 /* ---------------------------------------------------------------------------
2406 * erases the name of an element
2409 EraseElementName (ElementTypePtr Element
)
2411 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
2414 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2415 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2421 EraseObject (int type
, void *lptr
, void *ptr
)
2427 ErasePin ((PinTypePtr
) ptr
);
2430 case ELEMENTNAME_TYPE
:
2431 EraseText (lptr
, (TextTypePtr
) ptr
);
2434 ErasePolygon ((PolygonTypePtr
) ptr
);
2437 EraseElement ((ElementTypePtr
) ptr
);
2440 case ELEMENTLINE_TYPE
:
2442 EraseLine ((LineTypePtr
) ptr
);
2445 ErasePad ((PadTypePtr
) ptr
);
2448 case ELEMENTARC_TYPE
:
2449 EraseArc ((ArcTypePtr
) ptr
);
2452 Message ("hace: Internal ERROR, trying to erase an unknown type\n");
2459 DrawObject (int type
, void *ptr1
, void *ptr2
, int unused
)
2465 DrawVia ((PinTypePtr
) ptr2
, 0);
2468 if (((LayerTypePtr
) ptr1
)->On
)
2469 DrawLine ((LayerTypePtr
) ptr1
, (LineTypePtr
) ptr2
, 0);
2472 if (((LayerTypePtr
) ptr1
)->On
)
2473 DrawArc ((LayerTypePtr
) ptr1
, (ArcTypePtr
) ptr2
, 0);
2476 if (((LayerTypePtr
) ptr1
)->On
)
2477 DrawText ((LayerTypePtr
) ptr1
, (TextTypePtr
) ptr2
, 0);
2480 if (((LayerTypePtr
) ptr1
)->On
)
2481 DrawPolygon ((LayerTypePtr
) ptr1
, (PolygonTypePtr
) ptr2
, 0);
2484 if (PCB
->ElementOn
&&
2485 (FRONT ((ElementTypePtr
) ptr2
) || PCB
->InvisibleObjectsOn
))
2486 DrawElement ((ElementTypePtr
) ptr2
, 0);
2490 DrawRat ((RatTypePtr
) ptr2
, 0);
2494 DrawPin ((PinTypePtr
) ptr2
, 0);
2498 DrawPad ((PadTypePtr
) ptr2
, 0);
2500 case ELEMENTNAME_TYPE
:
2501 if (PCB
->ElementOn
&&
2502 (FRONT ((ElementTypePtr
) ptr2
) || PCB
->InvisibleObjectsOn
))
2503 DrawElementName ((ElementTypePtr
) ptr1
, 0);
2508 /* ---------------------------------------------------------------------------
2509 * HID drawing callback.
2513 hid_expose_callback (HID
* hid
, BoxType
* region
, void *item
)
2516 hidGC savebg
= Output
.bgGC
;
2517 hidGC savefg
= Output
.fgGC
;
2518 hidGC savepm
= Output
.pmGC
;
2521 Output
.fgGC
= gui
->make_gc ();
2522 Output
.bgGC
= gui
->make_gc ();
2523 Output
.pmGC
= gui
->make_gc ();
2528 /*printf("\033[32mhid_expose_callback, s=%p %d\033[0m\n", &(SWAP_IDENT), SWAP_IDENT); */
2530 hid
->set_color (Output
.pmGC
, "erase");
2531 hid
->set_color (Output
.bgGC
, "drill");
2535 doing_pinout
= True
;
2536 DrawElement (item
, 0);
2537 doing_pinout
= False
;
2540 DrawEverything (region
);
2542 gui
->destroy_gc (Output
.fgGC
);
2543 gui
->destroy_gc (Output
.bgGC
);
2544 gui
->destroy_gc (Output
.pmGC
);
2546 Output
.fgGC
= savefg
;
2547 Output
.bgGC
= savebg
;
2548 Output
.pmGC
= savepm
;