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"
54 #ifdef HAVE_LIBDMALLOC
60 #define SMALL_SMALL_TEXT_SIZE 0
61 #define SMALL_TEXT_SIZE 1
62 #define NORMAL_TEXT_SIZE 2
63 #define LARGE_TEXT_SIZE 3
64 #define N_TEXT_SIZES 4
67 /* ---------------------------------------------------------------------------
74 FloatPolyType
, *FloatPolyTypePtr
;
76 /* ---------------------------------------------------------------------------
77 * some local identifiers
80 static Boolean Gathering
= True
;
81 static int Erasing
= False
;
83 static int doing_pinout
= False
;
84 static int doing_assy
= False
;
85 static const BoxType
*clip_box
= NULL
;
87 /* ---------------------------------------------------------------------------
88 * some local prototypes
90 static void Redraw (Boolean
, BoxTypePtr
);
91 static void DrawEverything (BoxTypePtr
);
92 static void DrawTop (const BoxType
*);
93 static int DrawLayerGroup (int, const BoxType
*);
94 static void DrawPinOrViaLowLevel (PinTypePtr
, Boolean
);
95 static void ClearOnlyPin (PinTypePtr
, Boolean
);
96 static void DrawPlainPin (PinTypePtr
, Boolean
);
97 static void DrawPlainVia (PinTypePtr
, Boolean
);
98 static void DrawPinOrViaNameLowLevel (PinTypePtr
);
99 static void DrawPadLowLevel (hidGC
, PadTypePtr
, Boolean
, Boolean
);
100 static void DrawPadNameLowLevel (PadTypePtr
);
101 static void DrawLineLowLevel (LineTypePtr
, Boolean
);
102 static void DrawRegularText (LayerTypePtr
, TextTypePtr
, int);
103 static void DrawPolygonLowLevel (PolygonTypePtr
);
104 static void DrawArcLowLevel (ArcTypePtr
);
105 static void DrawElementPackageLowLevel (ElementTypePtr Element
, int);
106 static void DrawPlainPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
);
107 static void AddPart (void *);
108 static void SetPVColor (PinTypePtr
, int);
109 static void DrawEMark (ElementTypePtr
, LocationType
, LocationType
, Boolean
);
110 static void ClearPad (PadTypePtr
, Boolean
);
111 static void DrawHole (PinTypePtr
);
112 static void DrawMask (BoxType
*);
113 static void DrawRats (BoxType
*);
114 static void DrawSilk (int, int, BoxType
*);
115 static int pin_callback (const BoxType
* b
, void *cl
);
116 static int pad_callback (const BoxType
* b
, void *cl
);
118 /*--------------------------------------------------------------------------------------
119 * setup color for pin or via
122 SetPVColor (PinTypePtr Pin
, int Type
)
126 if (Type
== VIA_TYPE
)
129 && TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pin
))
131 if (TEST_FLAG (WARNFLAG
, Pin
))
132 color
= PCB
->WarnColor
;
133 else if (TEST_FLAG (SELECTEDFLAG
, Pin
))
134 color
= PCB
->ViaSelectedColor
;
136 color
= PCB
->ConnectedColor
;
139 color
= PCB
->ViaColor
;
144 && TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pin
))
146 if (TEST_FLAG (WARNFLAG
, Pin
))
147 color
= PCB
->WarnColor
;
148 else if (TEST_FLAG (SELECTEDFLAG
, Pin
))
149 color
= PCB
->PinSelectedColor
;
151 color
= PCB
->ConnectedColor
;
154 color
= PCB
->PinColor
;
157 gui
->set_color (Output
.fgGC
, color
);
160 /*---------------------------------------------------------------------------
161 * Adds the update rect to the update region
166 BoxType
*box
= (BoxType
*) b
;
168 Block
.X1
= MIN (Block
.X1
, box
->X1
);
169 Block
.X2
= MAX (Block
.X2
, box
->X2
);
170 Block
.Y1
= MIN (Block
.Y1
, box
->Y1
);
171 Block
.Y2
= MAX (Block
.Y2
, box
->Y2
);
175 * force the whole output to be updated
180 gui
->invalidate_all ();
184 * initiate the actual drawing to the pixmap/screen
185 * make the update block slightly larger to handle round-off
186 * caused by the TO_SCREEN operation
194 HideCrosshair (True
);
196 /* clear and create event if not drawing to a pixmap
198 gui
->invalidate_lr (Block
.X1
, Block
.X2
, Block
.Y1
, Block
.Y2
, 1);
200 RestoreCrosshair (True
);
202 /* shrink the update block */
203 Block
.X1
= Block
.Y1
= Block
.X2
= Block
.Y2
= 0;
206 /* ---------------------------------------------------------------------------
207 * redraws the output area without clearing it
210 RedrawOutput (BoxTypePtr area
)
215 /* ---------------------------------------------------------------------------
216 * redraws the output area after clearing it
219 ClearAndRedrawOutput (void)
229 /* ----------------------------------------------------------------------
230 * redraws all the data
231 * all necessary sizes are already set by the porthole widget and
232 * by the event handlers
235 Redraw (Boolean ClearWindow
, BoxTypePtr screen_area
)
237 gui
->invalidate_all ();
243 backE_callback (const BoxType
* b
, void *cl
)
245 ElementTypePtr element
= (ElementTypePtr
) b
;
247 if (!FRONT (element
))
249 DrawElementPackage (element
, 0);
255 backN_callback (const BoxType
* b
, void *cl
)
257 TextTypePtr text
= (TextTypePtr
) b
;
258 ElementTypePtr element
= (ElementTypePtr
) text
->Element
;
260 if (!FRONT (element
) && !TEST_FLAG (HIDENAMEFLAG
, element
))
261 DrawElementName (element
, 0);
266 backPad_callback (const BoxType
* b
, void *cl
)
268 PadTypePtr pad
= (PadTypePtr
) b
;
276 frontE_callback (const BoxType
* b
, void *cl
)
278 ElementTypePtr element
= (ElementTypePtr
) b
;
282 DrawElementPackage (element
, 0);
288 EMark_callback (const BoxType
* b
, void *cl
)
290 ElementTypePtr element
= (ElementTypePtr
) b
;
292 DrawEMark (element
, element
->MarkX
, element
->MarkY
, !FRONT (element
));
297 frontN_callback (const BoxType
* b
, void *cl
)
299 TextTypePtr text
= (TextTypePtr
) b
;
300 ElementTypePtr element
= (ElementTypePtr
) text
->Element
;
302 if (FRONT (element
) && !TEST_FLAG (HIDENAMEFLAG
, element
))
303 DrawElementName (element
, 0);
308 hole_callback (const BoxType
* b
, void *cl
)
310 PinTypePtr pin
= (PinTypePtr
) b
;
311 int plated
= cl
? *(int *) cl
: -1;
317 if (!TEST_FLAG (HOLEFLAG
, pin
))
321 if (TEST_FLAG (HOLEFLAG
, pin
))
325 DrawHole ((PinTypePtr
) b
);
336 hole_counting_callback (const BoxType
* b
, void *cl
)
338 PinTypePtr pin
= (PinTypePtr
) b
;
339 HoleCountStruct
*hcs
= (HoleCountStruct
*) cl
;
340 if (TEST_FLAG (HOLEFLAG
, pin
))
348 rat_callback (const BoxType
* b
, void *cl
)
350 DrawRat ((RatTypePtr
) b
, 0);
355 lowvia_callback (const BoxType
* b
, void *cl
)
357 PinTypePtr via
= (PinTypePtr
) b
;
359 DrawPlainVia (via
, False
);
363 /* ---------------------------------------------------------------------------
364 * prints assembly drawing.
368 PrintAssembly (const BoxType
* drawn_area
, int side_group
, int swap_ident
)
370 int save_swap
= SWAP_IDENT
;
372 gui
->set_draw_faded (Output
.fgGC
, 1);
373 SWAP_IDENT
= swap_ident
;
374 DrawLayerGroup (side_group
, drawn_area
);
375 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, lowvia_callback
, NULL
);
376 DrawTop (drawn_area
);
377 gui
->set_draw_faded (Output
.fgGC
, 0);
380 DrawSilk (swap_ident
,
381 swap_ident
? SOLDER_LAYER
: COMPONENT_LAYER
,
383 SWAP_IDENT
= save_swap
;
386 /* ---------------------------------------------------------------------------
387 * initializes some identifiers for a new zoom factor and redraws whole screen
390 DrawEverything (BoxTypePtr drawn_area
)
392 int i
, ngroups
, side
;
394 int component
, solder
;
395 /* This is the list of layer groups we will draw. */
396 int do_group
[MAX_LAYER
];
397 /* This is the reverse of the order in which we draw them. */
398 int drawn_groups
[MAX_LAYER
];
400 PCB
->Data
->SILKLAYER
.Color
= PCB
->ElementColor
;
401 PCB
->Data
->BACKSILKLAYER
.Color
= PCB
->InvisibleObjectsColor
;
403 memset (do_group
, 0, sizeof (do_group
));
404 for (ngroups
= 0, i
= 0; i
< max_layer
; i
++)
406 LayerType
*l
= LAYER_ON_STACK (i
);
407 int group
= GetLayerGroupNumberByNumber (LayerStack
[i
]);
408 if (l
->On
&& !do_group
[group
])
411 drawn_groups
[ngroups
++] = group
;
415 component
= GetLayerGroupNumberByNumber (max_layer
+ COMPONENT_LAYER
);
416 solder
= GetLayerGroupNumberByNumber (max_layer
+ SOLDER_LAYER
);
419 * first draw all 'invisible' stuff
421 if (!TEST_FLAG (CHECKPLANESFLAG
, PCB
)
422 && gui
->set_layer ("invisible", SL (INVISIBLE
, 0), 0))
424 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
, backPad_callback
,
428 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, backE_callback
,
430 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
,
431 backN_callback
, NULL
);
432 DrawLayer (&(PCB
->Data
->BACKSILKLAYER
), drawn_area
);
436 /* draw all layers in layerstack order */
437 for (i
= ngroups
- 1; i
>= 0; i
--)
439 int group
= drawn_groups
[i
];
441 if (gui
->set_layer (0, group
, 0))
443 if (DrawLayerGroup (group
, drawn_area
) && !gui
->gui
)
445 int save_swap
= SWAP_IDENT
;
447 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
) && gui
->gui
)
449 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, pin_callback
,
451 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, pin_callback
,
453 /* draw element pads */
454 if (group
== component
|| group
== solder
)
456 SWAP_IDENT
= (group
== solder
);
457 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
,
460 SWAP_IDENT
= save_swap
;
466 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_callback
,
468 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_callback
,
474 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
) && gui
->gui
)
477 /* draw vias below silk */
478 if (PCB
->ViaOn
&& gui
->gui
)
479 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, lowvia_callback
, NULL
);
480 /* Draw the solder mask if turned on */
481 if (gui
->set_layer ("componentmask", SL (MASK
, TOP
), 0))
483 int save_swap
= SWAP_IDENT
;
485 DrawMask (drawn_area
);
486 SWAP_IDENT
= save_swap
;
488 if (gui
->set_layer ("soldermask", SL (MASK
, BOTTOM
), 0))
490 int save_swap
= SWAP_IDENT
;
492 DrawMask (drawn_area
);
493 SWAP_IDENT
= save_swap
;
495 /* Draw pins, pads, vias below silk */
497 DrawTop (drawn_area
);
501 hcs
.nplated
= hcs
.nunplated
= 0;
502 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_counting_callback
,
504 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_counting_callback
,
506 if (hcs
.nplated
&& gui
->set_layer ("plated-drill", SL (PDRILL
, 0), 0))
509 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_callback
,
511 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_callback
,
514 if (hcs
.nunplated
&& gui
->set_layer ("unplated-drill", SL (UDRILL
, 0), 0))
517 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, hole_callback
,
519 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, hole_callback
,
523 /* Draw top silkscreen */
524 if (gui
->set_layer ("topsilk", SL (SILK
, TOP
), 0))
525 DrawSilk (0, COMPONENT_LAYER
, drawn_area
);
526 if (gui
->set_layer ("bottomsilk", SL (SILK
, BOTTOM
), 0))
527 DrawSilk (1, SOLDER_LAYER
, drawn_area
);
530 /* Draw element Marks */
532 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, EMark_callback
,
534 /* Draw rat lines on top */
536 DrawRats(drawn_area
);
539 for (side
= 0; side
<= 1; side
++)
542 Boolean NoData
= True
;
543 ALLPAD_LOOP (PCB
->Data
);
545 if ((TEST_FLAG (ONSOLDERFLAG
, pad
) && side
== SOLDER_LAYER
)
546 || (!TEST_FLAG (ONSOLDERFLAG
, pad
) && side
== COMPONENT_LAYER
))
554 if (side
== SOLDER_LAYER
)
555 doit
= gui
->set_layer ("bottompaste", SL (PASTE
, BOTTOM
), NoData
);
557 doit
= gui
->set_layer ("toppaste", SL (PASTE
, TOP
), NoData
);
560 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
561 ALLPAD_LOOP (PCB
->Data
);
563 if ((TEST_FLAG (ONSOLDERFLAG
, pad
) && side
== SOLDER_LAYER
)
564 || (!TEST_FLAG (ONSOLDERFLAG
, pad
)
565 && side
== COMPONENT_LAYER
))
566 if (!TEST_FLAG (NOPASTEFLAG
, pad
))
567 DrawPadLowLevel (Output
.fgGC
, pad
, False
, False
);
574 if (gui
->set_layer ("topassembly", SL (ASSY
, TOP
), 0))
575 PrintAssembly (drawn_area
, component
, 0);
577 if (gui
->set_layer ("bottomassembly", SL (ASSY
, BOTTOM
), 0))
578 PrintAssembly (drawn_area
, solder
, 1);
581 if (gui
->set_layer ("fab", SL (FAB
, 0), 0))
586 DrawEMark (ElementTypePtr e
, LocationType X
, LocationType Y
,
589 int mark_size
= EMARK_SIZE
;
590 if (!PCB
->InvisibleObjectsOn
&& invisible
)
593 if (e
->PinN
&& mark_size
> e
->Pin
[0].Thickness
/ 2)
594 mark_size
= e
->Pin
[0].Thickness
/ 2;
595 if (e
->PadN
&& mark_size
> e
->Pad
[0].Thickness
/ 2)
596 mark_size
= e
->Pad
[0].Thickness
/ 2;
598 gui
->set_color (Output
.fgGC
,
599 invisible
? PCB
->InvisibleMarkColor
: PCB
->ElementColor
);
600 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
601 gui
->set_line_width (Output
.fgGC
, 0);
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
);
605 gui
->draw_line (Output
.fgGC
, X
+ mark_size
, Y
, X
, Y
+ mark_size
);
608 * If an element is locked, place a "L" on top of the "diamond".
609 * This provides a nice visual indication that it is locked that
610 * works even for color blind users.
612 if (TEST_FLAG (LOCKFLAG
, e
) )
614 gui
->draw_line (Output
.fgGC
, X
, Y
, X
+ 2 * mark_size
, Y
);
615 gui
->draw_line (Output
.fgGC
, X
, Y
, X
, Y
- 4* mark_size
);
621 via_callback (const BoxType
* b
, void *cl
)
623 PinTypePtr via
= (PinTypePtr
) b
;
625 DrawPlainVia (via
, False
);
630 pin_callback (const BoxType
* b
, void *cl
)
632 DrawPlainPin ((PinTypePtr
) b
, False
);
637 pad_callback (const BoxType
* b
, void *cl
)
639 PadTypePtr pad
= (PadTypePtr
) b
;
645 /* ---------------------------------------------------------------------------
646 * draws pins pads and vias
649 DrawTop (const BoxType
* screen
)
651 if (PCB
->PinOn
|| doing_assy
)
653 /* draw element pins */
654 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, pin_callback
, NULL
);
655 /* draw element pads */
656 r_search (PCB
->Data
->pad_tree
, screen
, NULL
, pad_callback
, NULL
);
659 if (PCB
->ViaOn
|| doing_assy
)
661 r_search (PCB
->Data
->via_tree
, screen
, NULL
, via_callback
, NULL
);
662 r_search (PCB
->Data
->via_tree
, screen
, NULL
, hole_callback
, NULL
);
664 if (PCB
->PinOn
|| doing_assy
)
665 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, hole_callback
, NULL
);
675 clearPin_callback (const BoxType
* b
, void *cl
)
677 PinTypePtr pin
= (PinTypePtr
) b
;
678 struct pin_info
*i
= (struct pin_info
*) cl
;
680 ClearOnlyPin (pin
, True
);
684 poly_callback (const BoxType
* b
, void *cl
)
686 struct pin_info
*i
= (struct pin_info
*) cl
;
688 DrawPlainPolygon (i
->Layer
, (PolygonTypePtr
) b
);
693 clearPad_callback (const BoxType
* b
, void *cl
)
695 PadTypePtr pad
= (PadTypePtr
) b
;
696 if (!XOR (TEST_FLAG (ONSOLDERFLAG
, pad
), SWAP_IDENT
))
697 ClearPad (pad
, True
);
701 /* ---------------------------------------------------------------------------
706 DrawSilk (int new_swap
, int layer
, BoxTypePtr drawn_area
)
709 /* This code is used when you want to mask silk to avoid exposed
710 pins and pads. We decided it was a bad idea to do this
711 unconditionally, but the code remains. */
712 struct pin_info info
;
714 int save_swap
= SWAP_IDENT
;
715 SWAP_IDENT
= new_swap
;
718 if (gui
->poly_before
)
720 gui
->use_mask (HID_MASK_BEFORE
);
722 DrawLayer (LAYER_PTR (max_layer
+ layer
), drawn_area
);
724 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, frontE_callback
,
726 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
,
727 frontN_callback
, NULL
);
731 gui
->use_mask (HID_MASK_CLEAR
);
733 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, clearPin_callback
, &info
);
734 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, clearPin_callback
, &info
);
735 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
, clearPad_callback
, &info
);
739 gui
->use_mask (HID_MASK_AFTER
);
740 DrawLayer (LAYER_PTR (max_layer
+ layer
), drawn_area
);
742 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, frontE_callback
,
744 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
,
745 frontN_callback
, NULL
);
747 gui
->use_mask (HID_MASK_OFF
);
749 SWAP_IDENT
= save_swap
;
752 /* ---------------------------------------------------------------------------
753 * draws solder mask layer - this will cover nearly everything
756 DrawMask (BoxType
* screen
)
758 struct pin_info info
;
759 int thin
= TEST_FLAG(THINDRAWFLAG
, PCB
) || TEST_FLAG(THINDRAWPOLYFLAG
, PCB
);
761 OutputType
*out
= &Output
;
766 gui
->set_color (Output
.pmGC
, PCB
->MaskColor
);
769 if (gui
->poly_before
)
771 gui
->use_mask (HID_MASK_BEFORE
);
772 gui
->set_color (out
->fgGC
, PCB
->MaskColor
);
773 gui
->fill_rect (out
->fgGC
, 0, 0, PCB
->MaxWidth
, PCB
->MaxHeight
);
775 gui
->use_mask (HID_MASK_CLEAR
);
778 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, clearPin_callback
, &info
);
779 r_search (PCB
->Data
->via_tree
, screen
, NULL
, clearPin_callback
, &info
);
780 r_search (PCB
->Data
->pad_tree
, screen
, NULL
, clearPad_callback
, &info
);
783 gui
->set_color (Output
.pmGC
, "erase");
788 gui
->use_mask (HID_MASK_AFTER
);
789 gui
->set_color (out
->fgGC
, PCB
->MaskColor
);
790 gui
->fill_rect (out
->fgGC
, 0, 0, PCB
->MaxWidth
, PCB
->MaxHeight
);
792 gui
->use_mask (HID_MASK_OFF
);
796 /* Some fabs want the board outline on the solder mask layer. If
797 you need this, change the '0' above to '1', and the code below
798 will copy the outline layer to the mask layers. */
802 for (i
=PCB
->Data
->LayerN
; i
>=0; i
--)
804 LayerTypePtr Layer
= PCB
->Data
->Layer
+ i
;
805 if (strcasecmp (Layer
->Name
, "outline") == 0)
806 DrawLayer (Layer
, screen
);
813 DrawRats (BoxTypePtr drawn_area
)
816 * XXX lesstif allows positive AND negative drawing in HID_MASK_CLEAR.
817 * XXX gtk only allows negative drawing.
818 * XXX using the mask here is to get rat transparency
820 int can_mask
= strcmp(gui
->name
, "lesstif") == 0;
823 gui
->use_mask (HID_MASK_CLEAR
);
824 r_search (PCB
->Data
->rat_tree
, drawn_area
, NULL
, rat_callback
, NULL
);
826 gui
->use_mask (HID_MASK_OFF
);
830 line_callback (const BoxType
* b
, void *cl
)
832 DrawLine ((LayerTypePtr
) cl
, (LineTypePtr
) b
, 0);
837 arc_callback (const BoxType
* b
, void *cl
)
839 DrawArc ((LayerTypePtr
) cl
, (ArcTypePtr
) b
, 0);
844 text_callback (const BoxType
* b
, void *cl
)
846 DrawRegularText ((LayerTypePtr
) cl
, (TextTypePtr
) b
, 0);
851 /* ---------------------------------------------------------------------------
852 * draws one non-copper layer
855 DrawLayer (LayerTypePtr Layer
, BoxType
* screen
)
857 struct pin_info info
;
859 /* print the non-clearing polys */
863 r_search (Layer
->polygon_tree
, screen
, NULL
, poly_callback
, &info
);
865 /* draw all visible lines this layer */
866 r_search (Layer
->line_tree
, screen
, NULL
, line_callback
, Layer
);
868 /* draw the layer arcs on screen */
869 r_search (Layer
->arc_tree
, screen
, NULL
, arc_callback
, Layer
);
871 /* draw the layer text on screen */
872 r_search (Layer
->text_tree
, screen
, NULL
, text_callback
, Layer
);
876 /* ---------------------------------------------------------------------------
877 * draws one layer group. Returns non-zero if pins and pads should be
878 * drawn with this group.
881 DrawLayerGroup (int group
, const BoxType
* screen
)
885 struct pin_info info
;
887 int n_entries
= PCB
->LayerGroups
.Number
[group
];
888 Cardinal
*layers
= PCB
->LayerGroups
.Entries
[group
];
891 for (i
= n_entries
- 1; i
>= 0; i
--)
893 layernum
= layers
[i
];
894 Layer
= PCB
->Data
->Layer
+ layers
[i
];
895 if (strcmp (Layer
->Name
, "outline") == 0
896 || strcmp (Layer
->Name
, "route") == 0)
898 if (layernum
< max_layer
&& Layer
->On
)
900 /* draw all polygons on this layer */
905 r_search (Layer
->polygon_tree
, screen
, NULL
, poly_callback
,
910 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
))
913 /* draw all visible lines this layer */
914 r_search (Layer
->line_tree
, screen
, NULL
, line_callback
, Layer
);
916 /* draw the layer arcs on screen */
917 r_search (Layer
->arc_tree
, screen
, NULL
, arc_callback
, Layer
);
919 /* draw the layer text on screen */
920 r_search (Layer
->text_tree
, screen
, NULL
, text_callback
, Layer
);
929 /* ---------------------------------------------------------------------------
931 * x and y are already in display coordinates
932 * the points are numbered:
943 DrawSpecialPolygon (HID
* hid
, hidGC DrawGC
,
944 LocationType X
, LocationType Y
, int Thickness
)
946 static FloatPolyType p
[8] = {
948 0.5, -TAN_22_5_DEGREE_2
},
950 TAN_22_5_DEGREE_2
, -0.5},
952 -TAN_22_5_DEGREE_2
, -0.5},
954 -0.5, -TAN_22_5_DEGREE_2
},
956 -0.5, TAN_22_5_DEGREE_2
},
958 -TAN_22_5_DEGREE_2
, 0.5},
960 TAN_22_5_DEGREE_2
, 0.5},
962 0.5, TAN_22_5_DEGREE_2
}
964 static int special_size
= 0;
965 static int scaled_x
[8];
966 static int scaled_y
[8];
972 if (Thickness
!= special_size
)
974 special_size
= Thickness
;
975 for (i
= 0; i
< 8; i
++)
977 scaled_x
[i
] = p
[i
].X
* special_size
;
978 scaled_y
[i
] = p
[i
].Y
* special_size
;
981 /* add line offset */
982 for (i
= 0; i
< 8; i
++)
984 polygon_x
[i
] = X
+ scaled_x
[i
];
985 polygon_y
[i
] = Y
+ scaled_y
[i
];
987 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
990 hid
->set_line_cap (Output
.fgGC
, Round_Cap
);
991 hid
->set_line_width (Output
.fgGC
, 0);
992 polygon_x
[8] = X
+ scaled_x
[0];
993 polygon_y
[8] = Y
+ scaled_y
[0];
994 for (i
= 0; i
< 8; i
++)
995 hid
->draw_line (DrawGC
, polygon_x
[i
], polygon_y
[i
],
996 polygon_x
[i
+ 1], polygon_y
[i
+ 1]);
999 hid
->fill_polygon (DrawGC
, 8, polygon_x
, polygon_y
);
1002 /* ---------------------------------------------------------------------------
1003 * lowlevel drawing routine for pins and vias
1006 DrawPinOrViaLowLevel (PinTypePtr Ptr
, Boolean drawHole
)
1014 if (TEST_FLAG (HOLEFLAG
, Ptr
))
1018 gui
->fill_circle (Output
.bgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->Thickness
/ 2);
1019 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1020 gui
->set_line_width (Output
.fgGC
, 0);
1021 gui
->draw_arc (Output
.fgGC
, Ptr
->X
, Ptr
->Y
,
1022 Ptr
->Thickness
/ 2, Ptr
->Thickness
/ 2, 0, 360);
1026 if (TEST_FLAG (SQUAREFLAG
, Ptr
))
1029 l
= Ptr
->X
- Ptr
->Thickness
/ 2;
1030 b
= Ptr
->Y
- Ptr
->Thickness
/ 2;
1031 r
= l
+ Ptr
->Thickness
;
1032 t
= b
+ Ptr
->Thickness
;
1033 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1035 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1036 gui
->set_line_width (Output
.fgGC
, 0);
1037 gui
->draw_line (Output
.fgGC
, r
, t
, r
, b
);
1038 gui
->draw_line (Output
.fgGC
, l
, t
, l
, b
);
1039 gui
->draw_line (Output
.fgGC
, r
, t
, l
, t
);
1040 gui
->draw_line (Output
.fgGC
, r
, b
, l
, b
);
1044 gui
->fill_rect (Output
.fgGC
, l
, b
, r
, t
);
1047 else if (TEST_FLAG (OCTAGONFLAG
, Ptr
))
1049 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1050 gui
->set_line_width (Output
.fgGC
,
1051 (Ptr
->Thickness
- Ptr
->DrillingHole
) / 2);
1053 /* transform X11 specific coord system */
1054 DrawSpecialPolygon (gui
, Output
.fgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->Thickness
);
1057 { /* draw a round pin or via */
1058 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1060 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1061 gui
->set_line_width (Output
.fgGC
, 0);
1062 gui
->draw_arc (Output
.fgGC
, Ptr
->X
, Ptr
->Y
,
1063 Ptr
->Thickness
/ 2, Ptr
->Thickness
/ 2, 0, 360);
1067 gui
->fill_circle (Output
.fgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->Thickness
/ 2);
1071 /* and the drilling hole (which is always round */
1074 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1076 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1077 gui
->set_line_width (Output
.fgGC
, 0);
1078 gui
->draw_arc (Output
.fgGC
,
1079 Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2,
1080 Ptr
->DrillingHole
/ 2, 0, 360);
1084 gui
->fill_circle (Output
.bgGC
, Ptr
->X
, Ptr
->Y
,
1085 Ptr
->DrillingHole
/ 2);
1090 /**************************************************************
1094 DrawHole (PinTypePtr Ptr
)
1096 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1098 if (!TEST_FLAG (HOLEFLAG
, Ptr
))
1100 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1101 gui
->set_line_width (Output
.fgGC
, 0);
1102 gui
->draw_arc (Output
.fgGC
,
1103 Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2,
1104 Ptr
->DrillingHole
/ 2, 0, 360);
1109 gui
->fill_circle (Output
.bgGC
, Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2);
1111 if (TEST_FLAG (HOLEFLAG
, Ptr
))
1113 if (TEST_FLAG (WARNFLAG
, Ptr
))
1114 gui
->set_color (Output
.fgGC
, PCB
->WarnColor
);
1115 else if (TEST_FLAG (SELECTEDFLAG
, Ptr
))
1116 gui
->set_color (Output
.fgGC
, PCB
->ViaSelectedColor
);
1118 gui
->set_color (Output
.fgGC
, Settings
.BlackColor
);
1120 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1121 gui
->set_line_width (Output
.fgGC
, 0);
1122 gui
->draw_arc (Output
.fgGC
,
1123 Ptr
->X
, Ptr
->Y
, Ptr
->DrillingHole
/ 2,
1124 Ptr
->DrillingHole
/ 2, 0, 360);
1128 /*******************************************************************
1129 * draw clearance in pixmask around pins and vias that pierce polygons
1132 ClearOnlyPin (PinTypePtr Pin
, Boolean mask
)
1135 (mask
? Pin
->Mask
/ 2 : (Pin
->Thickness
+ Pin
->Clearance
) / 2);
1137 if (!mask
&& TEST_FLAG (HOLEFLAG
, Pin
))
1141 if (!mask
&& Pin
->Clearance
<= 0)
1144 /* Clear the area around the pin */
1145 if (TEST_FLAG (SQUAREFLAG
, Pin
))
1152 if (TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG (THINDRAWPOLYFLAG
, PCB
))
1154 gui
->set_line_cap (Output
.pmGC
, Round_Cap
);
1155 gui
->set_line_width (Output
.pmGC
, 0);
1156 gui
->draw_line (Output
.pmGC
, r
, t
, r
, b
);
1157 gui
->draw_line (Output
.pmGC
, l
, t
, l
, b
);
1158 gui
->draw_line (Output
.pmGC
, r
, t
, l
, t
);
1159 gui
->draw_line (Output
.pmGC
, r
, b
, l
, b
);
1162 gui
->fill_rect (Output
.pmGC
, l
, b
, r
, t
);
1164 else if (TEST_FLAG (OCTAGONFLAG
, Pin
))
1166 gui
->set_line_cap (Output
.pmGC
, Round_Cap
);
1167 gui
->set_line_width (Output
.pmGC
, (Pin
->Clearance
+ Pin
->Thickness
1168 - Pin
->DrillingHole
));
1170 DrawSpecialPolygon (gui
, Output
.pmGC
, Pin
->X
, Pin
->Y
, half
* 2);
1174 if (TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG (THINDRAWPOLYFLAG
, PCB
))
1175 gui
->draw_arc (Output
.pmGC
, Pin
->X
, Pin
->Y
, half
, half
, 0, 360);
1177 gui
->fill_circle (Output
.pmGC
, Pin
->X
, Pin
->Y
, half
);
1181 /* ---------------------------------------------------------------------------
1182 * lowlevel drawing routine for pins and vias that pierce polygons
1185 ClearPin (PinTypePtr Pin
, int Type
, int unused
)
1187 BDimension half
= (Pin
->Thickness
+ Pin
->Clearance
) / 2;
1194 /* Clear the area around the pin */
1195 if (TEST_FLAG (SQUAREFLAG
, Pin
))
1202 gui
->fill_rect (Output
.pmGC
, l
, b
, r
, t
);
1204 else if (TEST_FLAG (OCTAGONFLAG
, Pin
))
1206 gui
->set_line_cap (Output
.pmGC
, Round_Cap
);
1207 gui
->set_line_width (Output
.pmGC
, (Pin
->Clearance
+ Pin
->Thickness
1208 - Pin
->DrillingHole
) / 2);
1210 DrawSpecialPolygon (gui
, Output
.pmGC
, Pin
->X
, Pin
->Y
, half
* 2);
1214 gui
->fill_circle (Output
.pmGC
, Pin
->X
, Pin
->Y
, half
);
1216 if ((!TEST_FLAG (PINFLAG
, Pin
) && !PCB
->ViaOn
)
1217 || (TEST_FLAG (PINFLAG
, Pin
) && !PCB
->PinOn
))
1219 /* now draw the pin or via as appropriate */
1224 SetPVColor (Pin
, Type
);
1225 DrawPinOrViaLowLevel (Pin
, True
);
1235 /* vertical text handling provided by Martin Devera with fixes by harry eaton */
1237 /* draw vertical text; xywh is bounding, de is text's descend used for
1240 DrawVText (int x
, int y
, int w
, int h
, char *str
)
1251 pm
= gdk_pixmap_new (DrawingWindow
, w
, h
, -1);
1253 /* draw into pixmap */
1254 gdk_draw_rectangle (pm
, Output
.bgGC
, TRUE
, 0, 0, w
, h
);
1256 gui_draw_string_markup (DrawingWindow
, Output
.font_desc
, Output
.fgGC
,
1259 im
= gdk_drawable_get_image (pm
, 0, 0, w
, h
);
1260 gdk_gc_get_values (Output
.fgGC
, &values
);
1262 /* draw Transpose(im). TODO: Pango should be doing vertical text soon */
1263 for (i
= 0; i
< w
; i
++)
1264 for (j
= 0; j
< h
; j
++)
1266 pixel
= gdk_image_get_pixel (im
, i
, j
);
1267 if (pixel
== values
.foreground
.pixel
)
1268 gdk_draw_point (DrawingWindow
, Output
.fgGC
, x
+ j
, y
+ w
- i
- 1);
1270 g_object_unref (G_OBJECT (pm
));
1274 /* ---------------------------------------------------------------------------
1275 * lowlevel drawing routine for pin and via names
1278 DrawPinOrViaNameLowLevel (PinTypePtr Ptr
)
1285 if (!Ptr
->Name
|| !Ptr
->Name
[0])
1286 name
= EMPTY (Ptr
->Number
);
1288 name
= EMPTY (TEST_FLAG (SHOWNUMBERFLAG
, PCB
) ? Ptr
->Number
: Ptr
->Name
);
1290 vert
= TEST_FLAG (EDGE2FLAG
, Ptr
);
1294 box
.X1
= Ptr
->X
- Ptr
->Thickness
/ 2 + Settings
.PinoutTextOffsetY
;
1295 box
.Y1
= Ptr
->Y
- Ptr
->DrillingHole
/ 2 - Settings
.PinoutTextOffsetX
;
1299 box
.X1
= Ptr
->X
+ Ptr
->DrillingHole
/ 2 + Settings
.PinoutTextOffsetX
;
1300 box
.Y1
= Ptr
->Y
- Ptr
->Thickness
/ 2 + Settings
.PinoutTextOffsetY
;
1314 /*printf("AddPart: x1=%d y1=%d x2=%d y2=%d\n", box.X1, box.Y1, box.X2, box.Y2);*/
1318 /*printf("DrawPin(%d,%d): x=%d y=%d w=%d h=%d\n",
1319 TO_DRAW_X(Ptr->X), TO_DRAW_Y(Ptr->Y), box.X1, box.Y1, width, height);*/
1321 gui
->set_color (Output
.fgGC
, PCB
->PinNameColor
);
1323 text
.Flags
= NoFlags ();
1324 text
.Scale
= Ptr
->Thickness
/ 80;
1327 text
.Direction
= vert
? 1 : 0;
1328 text
.TextString
= name
;
1332 DrawTextLowLevel (&text
, 0);
1337 /* ---------------------------------------------------------------------------
1338 * lowlevel drawing routine for pads
1342 DrawPadLowLevel (hidGC gc
, PadTypePtr Pad
, Boolean clear
, Boolean mask
)
1344 int w
= clear
? (mask
? Pad
->Mask
: Pad
->Thickness
+ Pad
->Clearance
)
1353 if (TEST_FLAG (THINDRAWFLAG
, PCB
) ||
1354 (clear
&& TEST_FLAG (THINDRAWPOLYFLAG
, PCB
)))
1356 int x1
, y1
, x2
, y2
, t
, t2
;
1363 if (x1
> x2
|| y1
> y2
)
1365 /* this is a silly way to swap the variables */
1373 gui
->set_line_cap (gc
, Round_Cap
);
1374 gui
->set_line_width (gc
, 0);
1375 if (TEST_FLAG (SQUAREFLAG
, Pad
)
1376 && (x1
== x2
|| y1
== y2
))
1382 gui
->draw_line (gc
, x1
, y1
, x1
, y2
);
1383 gui
->draw_line (gc
, x1
, y2
, x2
, y2
);
1384 gui
->draw_line (gc
, x2
, y2
, x2
, y1
);
1385 gui
->draw_line (gc
, x2
, y1
, x1
, y1
);
1387 else if (TEST_FLAG (SQUAREFLAG
, Pad
))
1389 /* slanted square pad */
1390 float tx
, ty
, theta
;
1392 theta
= atan2 (y2
-y1
, x2
-x1
);
1394 /* T is a vector half a thickness long, in the direction of
1395 one of the corners. */
1396 tx
= t
* cos (theta
+ M_PI
/4) * sqrt(2.0);
1397 ty
= t
* sin (theta
+ M_PI
/4) * sqrt(2.0);
1399 gui
->draw_line (gc
, x1
-tx
, y1
-ty
, x2
+ty
, y2
-tx
);
1400 gui
->draw_line (gc
, x2
+ty
, y2
-tx
, x2
+tx
, y2
+ty
);
1401 gui
->draw_line (gc
, x2
+tx
, y2
+ty
, x1
-ty
, y1
+tx
);
1402 gui
->draw_line (gc
, x1
-ty
, y1
+tx
, x1
-tx
, y1
-ty
);
1404 else if (x1
== x2
&& y1
== y2
)
1406 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 0, 360);
1410 gui
->draw_line (gc
, x1
- t
, y1
, x2
- t
, y2
);
1411 gui
->draw_line (gc
, x1
+ t2
, y1
, x2
+ t2
, y2
);
1412 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 0, -180);
1413 gui
->draw_arc (gc
, x2
, y2
, w
/ 2, w
/ 2, 180, -180);
1417 gui
->draw_line (gc
, x1
, y1
- t
, x2
, y2
- t
);
1418 gui
->draw_line (gc
, x1
, y1
+ t2
, x2
, y2
+ t2
);
1419 gui
->draw_arc (gc
, x1
, y1
, w
/ 2, w
/ 2, 90, -180);
1420 gui
->draw_arc (gc
, x2
, y2
, w
/ 2, w
/ 2, 270, -180);
1424 /* Slanted round-end pads. */
1425 LocationType dx
, dy
, ox
, oy
;
1430 h
= t
/ sqrt (SQUARE (dx
) + SQUARE (dy
));
1431 ox
= dy
* h
+ 0.5 * SGN (dy
);
1432 oy
= -(dx
* h
+ 0.5 * SGN (dx
));
1434 gui
->draw_line (gc
, x1
+ ox
, y1
+ oy
, x2
+ ox
, y2
+ oy
);
1436 if (abs (ox
) >= pixel_slop
|| abs (oy
) >= pixel_slop
)
1438 LocationType angle
= atan2 ((float) dx
, (float) dy
) * 57.295779;
1439 gui
->draw_line (gc
, x1
- ox
, y1
- oy
, x2
- ox
, y2
- oy
);
1441 x1
, y1
, t
, t
, angle
- 180, 180);
1442 gui
->draw_arc (gc
, x2
, y2
, t
, t
, angle
, 180);
1446 else if (Pad
->Point1
.X
== Pad
->Point2
.X
1447 && Pad
->Point1
.Y
== Pad
->Point2
.Y
)
1449 if (TEST_FLAG (SQUAREFLAG
, Pad
))
1452 l
= Pad
->Point1
.X
- w
/ 2;
1453 b
= Pad
->Point1
.Y
- w
/ 2;
1456 gui
->fill_rect (gc
, l
, b
, r
, t
);
1460 gui
->fill_circle (gc
, Pad
->Point1
.X
, Pad
->Point1
.Y
, w
/ 2);
1465 gui
->set_line_cap (gc
,
1466 TEST_FLAG (SQUAREFLAG
,
1467 Pad
) ? Square_Cap
: Round_Cap
);
1468 gui
->set_line_width (gc
, w
);
1471 Pad
->Point1
.X
, Pad
->Point1
.Y
,
1472 Pad
->Point2
.X
, Pad
->Point2
.Y
);
1475 { /* Draw bounding box for test */
1476 BoxType
*box
= &Pad
->BoundingBox
;
1477 gui
->set_line_width (gc
, 0);
1478 gui
->draw_line (gc
, box
->X1
, box
->Y1
, box
->X1
, box
->Y2
);
1479 gui
->draw_line (gc
, box
->X1
, box
->Y2
, box
->X2
, box
->Y2
);
1480 gui
->draw_line (gc
, box
->X2
, box
->Y2
, box
->X2
, box
->Y1
);
1481 gui
->draw_line (gc
, box
->X2
, box
->Y1
, box
->X1
, box
->Y1
);
1486 /* ---------------------------------------------------------------------------
1487 * lowlevel drawing routine for pad names
1491 DrawPadNameLowLevel (PadTypePtr Pad
)
1498 if (!Pad
->Name
|| !Pad
->Name
[0])
1499 name
= EMPTY (Pad
->Number
);
1501 name
= EMPTY (TEST_FLAG (SHOWNUMBERFLAG
, PCB
) ? Pad
->Number
: Pad
->Name
);
1503 /* should text be vertical ? */
1504 vert
= (Pad
->Point1
.X
== Pad
->Point2
.X
);
1508 box
.X1
= Pad
->Point1
.X
- Pad
->Thickness
/ 2;
1509 box
.Y1
= MAX (Pad
->Point1
.Y
, Pad
->Point2
.Y
) + Pad
->Thickness
/ 2;
1513 box
.X1
= MIN (Pad
->Point1
.X
, Pad
->Point2
.X
) - Pad
->Thickness
/ 2;
1514 box
.Y1
= Pad
->Point1
.Y
- Pad
->Thickness
/ 2;
1519 box
.X1
+= Settings
.PinoutTextOffsetY
;
1520 box
.Y1
-= Settings
.PinoutTextOffsetX
;
1524 box
.X1
+= Settings
.PinoutTextOffsetX
;
1525 box
.Y1
+= Settings
.PinoutTextOffsetY
;
1544 gui
->set_color (Output
.fgGC
, PCB
->PinNameColor
);
1546 text
.Flags
= NoFlags ();
1547 text
.Scale
= Pad
->Thickness
/ 50;
1550 text
.Direction
= vert
? 1 : 0;
1551 text
.TextString
= name
;
1553 DrawTextLowLevel (&text
, 0);
1557 /* ---------------------------------------------------------------------------
1558 * clearance for pads
1561 ClearPad (PadTypePtr Pad
, Boolean mask
)
1563 DrawPadLowLevel(Output
.pmGC
, Pad
, True
, mask
);
1566 /* ---------------------------------------------------------------------------
1567 * lowlevel drawing routine for lines
1570 DrawLineLowLevel (LineTypePtr Line
, Boolean HaveGathered
)
1572 if (Gathering
&& !HaveGathered
)
1578 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
1579 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1580 gui
->set_line_width (Output
.fgGC
, 0);
1582 gui
->set_line_width (Output
.fgGC
, Line
->Thickness
);
1584 gui
->draw_line (Output
.fgGC
,
1585 Line
->Point1
.X
, Line
->Point1
.Y
,
1586 Line
->Point2
.X
, Line
->Point2
.Y
);
1589 /* ---------------------------------------------------------------------------
1590 * lowlevel drawing routine for text objects
1593 DrawTextLowLevel (TextTypePtr Text
, int min_line_width
)
1596 unsigned char *string
= (unsigned char *) Text
->TextString
;
1598 FontTypePtr font
= &PCB
->Font
;
1606 while (string
&& *string
)
1608 /* draw lines if symbol is valid and data is present */
1609 if (*string
<= MAX_FONTPOSITION
&& font
->Symbol
[*string
].Valid
)
1611 LineTypePtr line
= font
->Symbol
[*string
].Line
;
1614 for (n
= font
->Symbol
[*string
].LineN
; n
; n
--, line
++)
1616 /* create one line, scale, move, rotate and swap it */
1618 newline
.Point1
.X
= (newline
.Point1
.X
+ x
) * Text
->Scale
/ 100;
1619 newline
.Point1
.Y
= newline
.Point1
.Y
* Text
->Scale
/ 100;
1620 newline
.Point2
.X
= (newline
.Point2
.X
+ x
) * Text
->Scale
/ 100;
1621 newline
.Point2
.Y
= newline
.Point2
.Y
* Text
->Scale
/ 100;
1622 newline
.Thickness
= newline
.Thickness
* Text
->Scale
/ 200;
1623 if (newline
.Thickness
< min_line_width
)
1624 newline
.Thickness
= min_line_width
;
1626 RotateLineLowLevel (&newline
, 0, 0, Text
->Direction
);
1628 /* the labels of SMD objects on the bottom
1629 * side haven't been swapped yet, only their offset
1631 if (TEST_FLAG (ONSOLDERFLAG
, Text
))
1633 newline
.Point1
.X
= SWAP_SIGN_X (newline
.Point1
.X
);
1634 newline
.Point1
.Y
= SWAP_SIGN_Y (newline
.Point1
.Y
);
1635 newline
.Point2
.X
= SWAP_SIGN_X (newline
.Point2
.X
);
1636 newline
.Point2
.Y
= SWAP_SIGN_Y (newline
.Point2
.Y
);
1638 /* add offset and draw line */
1639 newline
.Point1
.X
+= Text
->X
;
1640 newline
.Point1
.Y
+= Text
->Y
;
1641 newline
.Point2
.X
+= Text
->X
;
1642 newline
.Point2
.Y
+= Text
->Y
;
1643 DrawLineLowLevel (&newline
, True
);
1646 /* move on to next cursor position */
1647 x
+= (font
->Symbol
[*string
].Width
+ font
->Symbol
[*string
].Delta
);
1651 /* the default symbol is a filled box */
1652 BoxType defaultsymbol
= PCB
->Font
.DefaultSymbol
;
1653 LocationType size
= (defaultsymbol
.X2
- defaultsymbol
.X1
) * 6 / 5;
1655 defaultsymbol
.X1
= (defaultsymbol
.X1
+ x
) * Text
->Scale
/ 100;
1656 defaultsymbol
.Y1
= defaultsymbol
.Y1
* Text
->Scale
/ 100;
1657 defaultsymbol
.X2
= (defaultsymbol
.X2
+ x
) * Text
->Scale
/ 100;
1658 defaultsymbol
.Y2
= defaultsymbol
.Y2
* Text
->Scale
/ 100;
1660 RotateBoxLowLevel (&defaultsymbol
, 0, 0, Text
->Direction
);
1662 /* add offset and draw box */
1663 defaultsymbol
.X1
+= Text
->X
;
1664 defaultsymbol
.Y1
+= Text
->Y
;
1665 defaultsymbol
.X2
+= Text
->X
;
1666 defaultsymbol
.Y2
+= Text
->Y
;
1667 gui
->fill_rect (Output
.fgGC
,
1668 defaultsymbol
.X1
, defaultsymbol
.Y1
,
1669 defaultsymbol
.X2
, defaultsymbol
.Y2
);
1671 /* move on to next cursor position */
1678 /* ---------------------------------------------------------------------------
1679 * lowlevel drawing routine for polygons
1682 DrawPolygonLowLevel (PolygonTypePtr Polygon
)
1684 int *x
, *y
, n
, i
= 0;
1687 if (!Polygon
->Clipped
)
1694 pl
= Polygon
->Clipped
->contours
;
1696 x
= (int *) malloc (n
* sizeof (int));
1697 y
= (int *) malloc (n
* sizeof (int));
1698 for (v
= &pl
->head
; i
< n
; v
= v
->next
)
1701 y
[i
++] = v
->point
[1];
1703 if (TEST_FLAG (THINDRAWFLAG
, PCB
)
1704 || TEST_FLAG (THINDRAWPOLYFLAG
, PCB
))
1706 gui
->set_line_width (Output
.fgGC
, 0);
1707 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
1708 for (i
= 0; i
< n
- 1; i
++)
1710 gui
->draw_line (Output
.fgGC
, x
[i
], y
[i
], x
[i
+ 1], y
[i
+ 1]);
1711 // gui->fill_circle (Output.fgGC, x[i], y[i], 30);
1713 gui
->draw_line (Output
.fgGC
, x
[n
- 1], y
[n
- 1], x
[0], y
[0]);
1716 gui
->fill_polygon (Output
.fgGC
, n
, x
, y
);
1721 /* ---------------------------------------------------------------------------
1722 * lowlevel routine to element arcs
1725 DrawArcLowLevel (ArcTypePtr Arc
)
1727 if (!Arc
->Thickness
)
1735 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1736 gui
->set_line_width (Output
.fgGC
, 0);
1738 gui
->set_line_width (Output
.fgGC
, Arc
->Thickness
);
1739 gui
->set_line_cap (Output
.fgGC
, Trace_Cap
);
1741 gui
->draw_arc (Output
.fgGC
, Arc
->X
, Arc
->Y
, Arc
->Width
,
1742 Arc
->Height
, Arc
->StartAngle
, Arc
->Delta
);
1745 /* ---------------------------------------------------------------------------
1746 * draws the package of an element
1749 DrawElementPackageLowLevel (ElementTypePtr Element
, int unused
)
1751 /* draw lines, arcs, text and pins */
1752 ELEMENTLINE_LOOP (Element
);
1754 DrawLineLowLevel (line
, False
);
1759 DrawArcLowLevel (arc
);
1764 /* ---------------------------------------------------------------------------
1768 DrawVia (PinTypePtr Via
, int unused
)
1771 SetPVColor (Via
, VIA_TYPE
);
1772 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Via) && TEST_ANY_PIPS (Via))
1773 // ClearPin (Via, VIA_TYPE, 0);
1775 DrawPinOrViaLowLevel (Via
, True
);
1776 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
1777 DrawPinOrViaNameLowLevel (Via
);
1780 /* ---------------------------------------------------------------------------
1781 * draw a via without dealing with polygon clearance
1784 DrawPlainVia (PinTypePtr Via
, Boolean holeToo
)
1787 SetPVColor (Via
, VIA_TYPE
);
1788 DrawPinOrViaLowLevel (Via
, holeToo
);
1789 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
1790 DrawPinOrViaNameLowLevel (Via
);
1793 /* ---------------------------------------------------------------------------
1794 * draws the name of a via
1797 DrawViaName (PinTypePtr Via
, int unused
)
1801 if (TEST_FLAG (SELECTEDFLAG
, Via
))
1802 gui
->set_color (Output
.fgGC
, PCB
->ViaSelectedColor
);
1804 gui
->set_color (Output
.fgGC
, PCB
->ViaColor
);
1806 DrawPinOrViaNameLowLevel (Via
);
1809 /* ---------------------------------------------------------------------------
1813 DrawPin (PinTypePtr Pin
, int unused
)
1815 //if (!doing_pinout && !TEST_FLAG (HOLEFLAG, Pin) && TEST_ANY_PIPS (Pin))
1816 // ClearPin (Pin, PIN_TYPE, 0);
1820 SetPVColor (Pin
, PIN_TYPE
);
1821 DrawPinOrViaLowLevel (Pin
, True
);
1823 if ((!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1825 DrawPinOrViaNameLowLevel (Pin
);
1828 /* ---------------------------------------------------------------------------
1829 * draw a pin without clearing around polygons
1832 DrawPlainPin (PinTypePtr Pin
, Boolean holeToo
)
1835 SetPVColor (Pin
, PIN_TYPE
);
1836 DrawPinOrViaLowLevel (Pin
, holeToo
);
1837 if (!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1838 DrawPinOrViaNameLowLevel (Pin
);
1841 /* ---------------------------------------------------------------------------
1842 * draws the name of a pin
1845 DrawPinName (PinTypePtr Pin
, int unused
)
1849 if (TEST_FLAG (SELECTEDFLAG
, Pin
))
1850 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1852 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1854 DrawPinOrViaNameLowLevel (Pin
);
1857 /* ---------------------------------------------------------------------------
1861 DrawPad (PadTypePtr Pad
, int unused
)
1866 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1867 else if (TEST_FLAG (WARNFLAG
| SELECTEDFLAG
| FOUNDFLAG
, Pad
))
1869 if (TEST_FLAG (WARNFLAG
, Pad
))
1870 gui
->set_color (Output
.fgGC
, PCB
->WarnColor
);
1871 else if (TEST_FLAG (SELECTEDFLAG
, Pad
))
1872 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1874 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1876 else if (FRONT (Pad
))
1877 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1879 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
1881 DrawPadLowLevel (Output
.fgGC
, Pad
, False
, False
);
1882 if (doing_pinout
|| TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
1883 DrawPadNameLowLevel (Pad
);
1886 /* ---------------------------------------------------------------------------
1887 * draws the name of a pad
1890 DrawPadName (PadTypePtr Pad
, int unused
)
1894 if (TEST_FLAG (SELECTEDFLAG
, Pad
))
1895 gui
->set_color (Output
.fgGC
, PCB
->PinSelectedColor
);
1896 else if (FRONT (Pad
))
1897 gui
->set_color (Output
.fgGC
, PCB
->PinColor
);
1899 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
1901 DrawPadNameLowLevel (Pad
);
1904 /* ---------------------------------------------------------------------------
1905 * draws a line on a layer
1908 DrawLine (LayerTypePtr Layer
, LineTypePtr Line
, int unused
)
1912 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Line
))
1914 if (TEST_FLAG (SELECTEDFLAG
, Line
))
1915 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1917 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1920 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1922 DrawLineLowLevel (Line
, False
);
1925 /* ---------------------------------------------------------------------------
1929 DrawRat (RatTypePtr Line
, int unused
)
1933 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Line
))
1935 if (TEST_FLAG (SELECTEDFLAG
, Line
))
1936 gui
->set_color (Output
.fgGC
, PCB
->RatSelectedColor
);
1938 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1941 gui
->set_color (Output
.fgGC
, PCB
->RatColor
);
1943 if (Settings
.RatThickness
< 20)
1944 Line
->Thickness
= pixel_slop
* Settings
.RatThickness
;
1945 /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */
1946 if (TEST_FLAG(VIAFLAG
, Line
))
1948 int w
= Line
->Thickness
;
1954 b
.X1
= Line
->Point1
.X
- w
* 2 - w
/ 2;
1955 b
.X2
= Line
->Point1
.X
+ w
* 2 + w
/ 2;
1956 b
.Y1
= Line
->Point1
.Y
- w
* 2 - w
/ 2;
1957 b
.Y2
= Line
->Point1
.Y
+ w
* 2 + w
/ 2;
1962 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
1963 gui
->set_line_width (Output
.fgGC
, 0);
1965 gui
->set_line_width (Output
.fgGC
, w
);
1966 gui
->draw_arc (Output
.fgGC
, Line
->Point1
.X
, Line
->Point1
.Y
,
1967 w
* 2, w
* 2, 0, 360);
1971 DrawLineLowLevel ((LineTypePtr
) Line
, False
);
1974 /* ---------------------------------------------------------------------------
1975 * draws an arc on a layer
1978 DrawArc (LayerTypePtr Layer
, ArcTypePtr Arc
, int unused
)
1980 if (!Arc
->Thickness
)
1984 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Arc
))
1986 if (TEST_FLAG (SELECTEDFLAG
, Arc
))
1987 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
1989 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
1992 gui
->set_color (Output
.fgGC
, Layer
->Color
);
1994 DrawArcLowLevel (Arc
);
1997 /* ---------------------------------------------------------------------------
1998 * draws a text on a layer
2001 DrawText (LayerTypePtr Layer
, TextTypePtr Text
, int unused
)
2006 if (TEST_FLAG (SELECTEDFLAG
, Text
))
2007 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2009 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2010 if (Layer
== & PCB
->Data
->SILKLAYER
2011 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2012 min_silk_line
= PCB
->minSlk
;
2014 min_silk_line
= PCB
->minWid
;
2015 DrawTextLowLevel (Text
, min_silk_line
);
2018 /* ---------------------------------------------------------------------------
2019 * draws text on a layer
2022 DrawRegularText (LayerTypePtr Layer
, TextTypePtr Text
, int unused
)
2025 if (TEST_FLAG (SELECTEDFLAG
, Text
))
2026 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2028 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2029 if (Layer
== & PCB
->Data
->SILKLAYER
2030 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2031 min_silk_line
= PCB
->minSlk
;
2033 min_silk_line
= PCB
->minWid
;
2034 DrawTextLowLevel (Text
, min_silk_line
);
2038 cp_callback (const BoxType
* b
, void *cl
)
2040 ClearPin ((PinTypePtr
) b
, (int) (size_t) cl
, 0);
2044 /* ---------------------------------------------------------------------------
2045 * draws a polygon on a layer
2048 DrawPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
, int unused
)
2052 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Polygon
))
2054 if (TEST_FLAG (SELECTEDFLAG
, Polygon
))
2055 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2057 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
2060 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2061 layernum
= GetLayerNumber (PCB
->Data
, Layer
);
2062 DrawPolygonLowLevel (Polygon
);
2063 if (TEST_FLAG (CLEARPOLYFLAG
, Polygon
))
2065 r_search (PCB
->Data
->pin_tree
, &Polygon
->BoundingBox
, NULL
,
2066 cp_callback
, (void *) PIN_TYPE
);
2067 r_search (PCB
->Data
->via_tree
, &Polygon
->BoundingBox
, NULL
,
2068 cp_callback
, (void *) VIA_TYPE
);
2073 thin_callback (PLINE
* pl
, LayerTypePtr lay
, PolygonTypePtr poly
)
2079 x
= (int *) malloc (pl
->Count
* sizeof (int));
2080 y
= (int *) malloc (pl
->Count
* sizeof (int));
2081 for (v
= &pl
->head
; i
< pl
->Count
; v
= v
->next
)
2084 y
[i
++] = v
->point
[1];
2086 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
2087 gui
->set_line_width (Output
.fgGC
, 0);
2088 for (i
= 0; i
< pl
->Count
- 1; i
++)
2090 gui
->draw_line (Output
.fgGC
, x
[i
], y
[i
], x
[i
+ 1], y
[i
+ 1]);
2091 // gui->fill_circle (Output.fgGC, x[i], y[i], 30);
2093 gui
->draw_line (Output
.fgGC
, x
[pl
->Count
- 1], y
[pl
->Count
- 1], x
[0],
2101 /* ---------------------------------------------------------------------------
2105 DrawPlainPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
2107 if (TEST_FLAG (SELECTEDFLAG
| FOUNDFLAG
, Polygon
))
2109 if (TEST_FLAG (SELECTEDFLAG
, Polygon
))
2110 gui
->set_color (Output
.fgGC
, Layer
->SelectedColor
);
2112 gui
->set_color (Output
.fgGC
, PCB
->ConnectedColor
);
2115 gui
->set_color (Output
.fgGC
, Layer
->Color
);
2116 /* if the gui has the dicer flag set then it won't accept thin draw */
2117 if ((TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG (THINDRAWPOLYFLAG
, PCB
))
2118 && !gui
->poly_dicer
)
2120 DrawPolygonLowLevel (Polygon
);
2122 PolygonHoles (clip_box
, Layer
, Polygon
, thin_callback
);
2124 else if (Polygon
->Clipped
)
2126 NoHolesPolygonDicer (Polygon
, clip_box
, DrawPolygonLowLevel
, NULL
);
2127 /* draw other parts of the polygon if fullpoly flag is set */
2128 if (TEST_FLAG (FULLPOLYFLAG
, Polygon
))
2131 for (pg
= Polygon
->Clipped
->f
; pg
!= Polygon
->Clipped
; pg
= pg
->f
)
2135 NoHolesPolygonDicer (&poly
, clip_box
, DrawPolygonLowLevel
, NULL
);
2139 /* if the gui has the dicer flag set then it won't draw missing poly outlines */
2140 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
) && Polygon
->Clipped
&& !Gathering
2141 && !gui
->poly_dicer
)
2145 for (pg
= Polygon
->Clipped
->f
; pg
!= Polygon
->Clipped
; pg
= pg
->f
)
2148 PLINE
*pl
= pg
->contours
;
2151 int *x
= (int *) malloc (n
* sizeof (int));
2152 int *y
= (int *) malloc (n
* sizeof (int));
2153 for (v
= &pl
->head
; i
< n
; v
= v
->next
)
2156 y
[i
++] = v
->point
[1];
2158 gui
->set_line_width (Output
.fgGC
, 0);
2159 gui
->set_line_cap (Output
.fgGC
, Round_Cap
);
2160 for (i
= 0; i
< n
- 1; i
++)
2162 gui
->draw_line (Output
.fgGC
, x
[i
], y
[i
], x
[i
+ 1], y
[i
+ 1]);
2163 /* gui->fill_circle (Output.bgGC, x[i], y[i], 10); */
2165 gui
->draw_line (Output
.fgGC
, x
[n
- 1], y
[n
- 1], x
[0], y
[0]);
2172 /* ---------------------------------------------------------------------------
2176 DrawElement (ElementTypePtr Element
, int unused
)
2178 DrawElementPackage (Element
, unused
);
2179 DrawElementName (Element
, unused
);
2180 DrawElementPinsAndPads (Element
, unused
);
2183 /* ---------------------------------------------------------------------------
2184 * draws the name of an element
2187 DrawElementName (ElementTypePtr Element
, int unused
)
2189 if (gui
->gui
&& TEST_FLAG (HIDENAMESFLAG
, PCB
))
2191 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
2193 if (doing_pinout
|| doing_assy
)
2194 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2195 else if (TEST_FLAG (SELECTEDFLAG
, &ELEMENT_TEXT (PCB
, Element
)))
2196 gui
->set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
2197 else if (FRONT (Element
))
2198 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2200 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
2201 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2204 /* ---------------------------------------------------------------------------
2205 * draws the package of an element
2208 DrawElementPackage (ElementTypePtr Element
, int unused
)
2210 /* set color and draw lines, arcs, text and pins */
2211 if (doing_pinout
|| doing_assy
)
2212 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2213 else if (TEST_FLAG (SELECTEDFLAG
, Element
))
2214 gui
->set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
2215 else if (FRONT (Element
))
2216 gui
->set_color (Output
.fgGC
, PCB
->ElementColor
);
2218 gui
->set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
2219 DrawElementPackageLowLevel (Element
, unused
);
2222 /* ---------------------------------------------------------------------------
2223 * draw pins of an element
2226 DrawElementPinsAndPads (ElementTypePtr Element
, int unused
)
2230 if (doing_pinout
|| doing_assy
|| FRONT (pad
) || PCB
->InvisibleObjectsOn
)
2231 DrawPad (pad
, unused
);
2236 DrawPin (pin
, unused
);
2241 /* ---------------------------------------------------------------------------
2245 EraseVia (PinTypePtr Via
)
2248 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2249 DrawPinOrViaLowLevel (Via
, False
);
2250 if (TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
2251 DrawPinOrViaNameLowLevel (Via
);
2255 /* ---------------------------------------------------------------------------
2259 EraseRat (RatTypePtr Rat
)
2262 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2263 if (TEST_FLAG(VIAFLAG
, Rat
))
2265 int w
= Rat
->Thickness
;
2267 if (TEST_FLAG (THINDRAWFLAG
, PCB
))
2268 gui
->set_line_width (Output
.fgGC
, 0);
2270 gui
->set_line_width (Output
.fgGC
, w
);
2271 gui
->draw_arc (Output
.fgGC
, Rat
->Point1
.X
, Rat
->Point1
.Y
,
2272 w
* 2, w
* 2, 0, 360);
2275 DrawLineLowLevel ((LineTypePtr
) Rat
, False
);
2280 /* ---------------------------------------------------------------------------
2284 EraseViaName (PinTypePtr Via
)
2287 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2288 DrawPinOrViaNameLowLevel (Via
);
2292 /* ---------------------------------------------------------------------------
2293 * erase a pad object
2296 ErasePad (PadTypePtr Pad
)
2299 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2300 DrawPadLowLevel (Output
.fgGC
, Pad
, False
, False
);
2301 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
2302 DrawPadNameLowLevel (Pad
);
2306 /* ---------------------------------------------------------------------------
2310 ErasePadName (PadTypePtr Pad
)
2313 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2314 DrawPadNameLowLevel (Pad
);
2318 /* ---------------------------------------------------------------------------
2319 * erase a pin object
2322 ErasePin (PinTypePtr Pin
)
2325 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2326 DrawPinOrViaLowLevel (Pin
, False
);
2327 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
2328 DrawPinOrViaNameLowLevel (Pin
);
2332 /* ---------------------------------------------------------------------------
2336 ErasePinName (PinTypePtr Pin
)
2339 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2340 DrawPinOrViaNameLowLevel (Pin
);
2344 /* ---------------------------------------------------------------------------
2345 * erases a line on a layer
2348 EraseLine (LineTypePtr Line
)
2351 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2352 DrawLineLowLevel (Line
, False
);
2356 /* ---------------------------------------------------------------------------
2357 * erases an arc on a layer
2360 EraseArc (ArcTypePtr Arc
)
2362 if (!Arc
->Thickness
)
2365 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2366 DrawArcLowLevel (Arc
);
2370 /* ---------------------------------------------------------------------------
2371 * erases a text on a layer
2374 EraseText (LayerTypePtr Layer
, TextTypePtr Text
)
2378 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2379 if (Layer
== & PCB
->Data
->SILKLAYER
2380 || Layer
== & PCB
->Data
->BACKSILKLAYER
)
2381 min_silk_line
= PCB
->minSlk
;
2383 min_silk_line
= PCB
->minWid
;
2384 DrawTextLowLevel (Text
, min_silk_line
);
2388 /* ---------------------------------------------------------------------------
2389 * erases a polygon on a layer
2392 ErasePolygon (PolygonTypePtr Polygon
)
2395 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2396 DrawPolygonLowLevel (Polygon
);
2400 /* ---------------------------------------------------------------------------
2404 EraseElement (ElementTypePtr Element
)
2407 /* set color and draw lines, arcs, text and pins */
2408 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2409 ELEMENTLINE_LOOP (Element
);
2411 DrawLineLowLevel (line
, False
);
2416 DrawArcLowLevel (arc
);
2419 if (!TEST_FLAG (HIDENAMEFLAG
, Element
))
2420 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2421 EraseElementPinsAndPads (Element
);
2425 /* ---------------------------------------------------------------------------
2426 * erases all pins and pads of an element
2429 EraseElementPinsAndPads (ElementTypePtr Element
)
2432 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2435 /* if (TEST_ANY_PIPS (pin))
2437 ClearPin (pin, NO_TYPE, 0);
2438 gui->set_color (Output.fgGC, Settings.BackgroundColor);
2441 DrawPinOrViaLowLevel (pin
, False
);
2442 if (TEST_FLAG (DISPLAYNAMEFLAG
, pin
))
2443 DrawPinOrViaNameLowLevel (pin
);
2448 DrawPadLowLevel (Output
.fgGC
, pad
, False
, False
);
2449 if (TEST_FLAG (DISPLAYNAMEFLAG
, pad
))
2450 DrawPadNameLowLevel (pad
);
2456 /* ---------------------------------------------------------------------------
2457 * erases the name of an element
2460 EraseElementName (ElementTypePtr Element
)
2462 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
2465 gui
->set_color (Output
.fgGC
, Settings
.BackgroundColor
);
2466 DrawTextLowLevel (&ELEMENT_TEXT (PCB
, Element
), PCB
->minSlk
);
2472 EraseObject (int type
, void *lptr
, void *ptr
)
2478 ErasePin ((PinTypePtr
) ptr
);
2481 case ELEMENTNAME_TYPE
:
2482 EraseText (lptr
, (TextTypePtr
) ptr
);
2485 ErasePolygon ((PolygonTypePtr
) ptr
);
2488 EraseElement ((ElementTypePtr
) ptr
);
2491 case ELEMENTLINE_TYPE
:
2493 EraseLine ((LineTypePtr
) ptr
);
2496 ErasePad ((PadTypePtr
) ptr
);
2499 case ELEMENTARC_TYPE
:
2500 EraseArc ((ArcTypePtr
) ptr
);
2503 Message ("hace: Internal ERROR, trying to erase an unknown type\n");
2510 DrawObject (int type
, void *ptr1
, void *ptr2
, int unused
)
2516 DrawVia ((PinTypePtr
) ptr2
, 0);
2519 if (((LayerTypePtr
) ptr1
)->On
)
2520 DrawLine ((LayerTypePtr
) ptr1
, (LineTypePtr
) ptr2
, 0);
2523 if (((LayerTypePtr
) ptr1
)->On
)
2524 DrawArc ((LayerTypePtr
) ptr1
, (ArcTypePtr
) ptr2
, 0);
2527 if (((LayerTypePtr
) ptr1
)->On
)
2528 DrawText ((LayerTypePtr
) ptr1
, (TextTypePtr
) ptr2
, 0);
2531 if (((LayerTypePtr
) ptr1
)->On
)
2532 DrawPolygon ((LayerTypePtr
) ptr1
, (PolygonTypePtr
) ptr2
, 0);
2535 if (PCB
->ElementOn
&&
2536 (FRONT ((ElementTypePtr
) ptr2
) || PCB
->InvisibleObjectsOn
))
2537 DrawElement ((ElementTypePtr
) ptr2
, 0);
2541 DrawRat ((RatTypePtr
) ptr2
, 0);
2545 DrawPin ((PinTypePtr
) ptr2
, 0);
2549 DrawPad ((PadTypePtr
) ptr2
, 0);
2551 case ELEMENTNAME_TYPE
:
2552 if (PCB
->ElementOn
&&
2553 (FRONT ((ElementTypePtr
) ptr2
) || PCB
->InvisibleObjectsOn
))
2554 DrawElementName ((ElementTypePtr
) ptr1
, 0);
2559 /* ---------------------------------------------------------------------------
2560 * HID drawing callback.
2564 hid_expose_callback (HID
* hid
, BoxType
* region
, void *item
)
2567 hidGC savebg
= Output
.bgGC
;
2568 hidGC savefg
= Output
.fgGC
;
2569 hidGC savepm
= Output
.pmGC
;
2572 Output
.fgGC
= gui
->make_gc ();
2573 Output
.bgGC
= gui
->make_gc ();
2574 Output
.pmGC
= gui
->make_gc ();
2579 /*printf("\033[32mhid_expose_callback, s=%p %d\033[0m\n", &(SWAP_IDENT), SWAP_IDENT); */
2581 hid
->set_color (Output
.pmGC
, "erase");
2582 hid
->set_color (Output
.bgGC
, "drill");
2586 doing_pinout
= True
;
2587 DrawElement (item
, 0);
2588 doing_pinout
= False
;
2591 DrawEverything (region
);
2593 gui
->destroy_gc (Output
.fgGC
);
2594 gui
->destroy_gc (Output
.bgGC
);
2595 gui
->destroy_gc (Output
.pmGC
);
2597 Output
.fgGC
= savefg
;
2598 Output
.bgGC
= savebg
;
2599 Output
.pmGC
= savepm
;