4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996, 2003, 2004 Thomas Nau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Contact addresses for paper mail and Email:
22 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 * Thomas.Nau@rz.uni-ulm.de
40 #include "crosshair.h"
43 #include "draw_funcs.h"
53 #ifdef HAVE_LIBDMALLOC
61 #define MAXINT (((unsigned int)(~0))>>1)
64 #define SMALL_SMALL_TEXT_SIZE 0
65 #define SMALL_TEXT_SIZE 1
66 #define NORMAL_TEXT_SIZE 2
67 #define LARGE_TEXT_SIZE 3
68 #define N_TEXT_SIZES 4
71 /* ---------------------------------------------------------------------------
72 * some local identifiers
74 static BoxType Block
= {MAXINT
, MAXINT
, -MAXINT
, -MAXINT
};
76 static int doing_pinout
= 0;
77 static bool doing_assy
= false;
78 static HID_DRAW
*hid_draw
= NULL
;
80 /* ---------------------------------------------------------------------------
81 * some local prototypes
83 static void DrawEverything (const BoxType
*);
84 static void AddPart (void *);
85 /* static */ void DrawEMark (ElementType
*, Coord
, Coord
, bool);
86 /* static */ void DrawRats (HID_DRAW
*hid_draw
, const BoxType
*);
89 set_object_color (AnyObjectType
*obj
, char *warn_color
, char *selected_color
,
90 char *connected_color
, char *found_color
, char *normal_color
)
94 if (warn_color
!= NULL
&& TEST_FLAG (WARNFLAG
, obj
)) color
= warn_color
;
95 else if (selected_color
!= NULL
&& TEST_FLAG (SELECTEDFLAG
, obj
)) color
= selected_color
;
96 else if (connected_color
!= NULL
&& TEST_FLAG (CONNECTEDFLAG
, obj
)) color
= connected_color
;
97 else if (found_color
!= NULL
&& TEST_FLAG (FOUNDFLAG
, obj
)) color
= found_color
;
98 else color
= normal_color
;
100 hid_draw_set_color (Output
.fgGC
, color
);
103 /*---------------------------------------------------------------------------
104 * Adds the update rect to the update region
109 BoxType
*box
= (BoxType
*) b
;
111 Block
.X1
= MIN (Block
.X1
, box
->X1
);
112 Block
.X2
= MAX (Block
.X2
, box
->X2
);
113 Block
.Y1
= MIN (Block
.Y1
, box
->Y1
);
114 Block
.Y2
= MAX (Block
.Y2
, box
->Y2
);
118 * initiate the actual redrawing of the updated area
123 if (Block
.X1
<= Block
.X2
&& Block
.Y1
<= Block
.Y2
)
124 gui
->invalidate_lr (Block
.X1
, Block
.X2
, Block
.Y1
, Block
.Y2
);
126 /* shrink the update block */
127 Block
.X1
= Block
.Y1
= MAXINT
;
128 Block
.X2
= Block
.Y2
= -MAXINT
;
131 /* ----------------------------------------------------------------------
132 * redraws all the data by the event handlers
137 gui
->invalidate_all ();
141 pad_callback (const BoxType
* b
, void *cl
)
143 PadType
*pad
= (PadType
*) b
;
146 if (ON_SIDE (pad
, *side
))
148 set_object_color ((AnyObjectType
*)pad
, PCB
->WarnColor
,
149 PCB
->PinSelectedColor
, PCB
->ConnectedColor
, PCB
->FoundColor
,
150 FRONT (pad
) ? PCB
->PinColor
: PCB
->InvisibleObjectsColor
);
152 dapi
->draw_pad (pad
, NULL
, NULL
);
158 draw_element_name (ElementType
*element
)
160 if ((TEST_FLAG (HIDENAMESFLAG
, PCB
) && hid_draw_is_gui (hid_draw
)) ||
161 TEST_FLAG (HIDENAMEFLAG
, element
))
163 if (doing_pinout
|| doing_assy
)
164 hid_draw_set_color (Output
.fgGC
, PCB
->ElementColor
);
165 else if (TEST_FLAG (SELECTEDFLAG
, &ELEMENT_TEXT (PCB
, element
)))
166 hid_draw_set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
167 else if (FRONT (element
))
168 hid_draw_set_color (Output
.fgGC
, PCB
->ElementColor
);
170 hid_draw_set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
171 hid_draw_pcb_text (Output
.fgGC
, &ELEMENT_TEXT (PCB
, element
), PCB
->minSlk
);
175 name_callback (const BoxType
* b
, void *cl
)
177 TextType
*text
= (TextType
*) b
;
178 ElementType
*element
= (ElementType
*) text
->Element
;
181 if (TEST_FLAG (HIDENAMEFLAG
, element
))
184 if (ON_SIDE (element
, *side
))
185 draw_element_name (element
);
190 draw_element_pins_and_pads (ElementType
*element
)
194 if (doing_pinout
|| doing_assy
|| FRONT (pad
) || PCB
->InvisibleObjectsOn
)
196 set_object_color ((AnyObjectType
*)pad
, PCB
->WarnColor
,
197 PCB
->PinSelectedColor
, PCB
->ConnectedColor
, PCB
->FoundColor
,
198 FRONT (pad
) ? PCB
->PinColor
: PCB
->InvisibleObjectsColor
);
200 dapi
->draw_pad (pad
, NULL
, NULL
);
206 set_object_color ((AnyObjectType
*)pin
, PCB
->WarnColor
, PCB
->PinSelectedColor
,
207 PCB
->ConnectedColor
, PCB
->FoundColor
, PCB
->PinColor
);
209 dapi
->draw_pin (pin
, NULL
, NULL
);
211 set_object_color ((AnyObjectType
*)pin
, PCB
->WarnColor
,
212 PCB
->PinSelectedColor
, NULL
, NULL
, Settings
.BlackColor
);
214 dapi
->draw_pin_hole (pin
, NULL
, NULL
);
220 EMark_callback (const BoxType
* b
, void *cl
)
222 ElementType
*element
= (ElementType
*) b
;
224 DrawEMark (element
, element
->MarkX
, element
->MarkY
, !FRONT (element
));
229 rat_callback (const BoxType
* b
, void *cl
)
231 RatType
*rat
= (RatType
*)b
;
233 set_object_color ((AnyObjectType
*) rat
, NULL
, PCB
->RatSelectedColor
,
234 PCB
->ConnectedColor
, PCB
->FoundColor
, PCB
->RatColor
);
236 dapi
->draw_rat (rat
, NULL
, NULL
);
241 draw_element_package (ElementType
*element
)
243 /* set color and draw lines, arcs, text and pins */
244 if (doing_pinout
|| doing_assy
)
245 hid_draw_set_color (Output
.fgGC
, PCB
->ElementColor
);
246 else if (TEST_FLAG (SELECTEDFLAG
, element
))
247 hid_draw_set_color (Output
.fgGC
, PCB
->ElementSelectedColor
);
248 else if (FRONT (element
))
249 hid_draw_set_color (Output
.fgGC
, PCB
->ElementColor
);
251 hid_draw_set_color (Output
.fgGC
, PCB
->InvisibleObjectsColor
);
253 /* draw lines, arcs, text and pins */
254 ELEMENTLINE_LOOP (element
);
256 //hid_draw_pcb_line (Output.fgGC, line);
257 dapi
->draw_line (line
, NULL
, NULL
);
262 //hid_draw_pcb_arc (Output.fgGC, arc);
263 dapi
->draw_arc (arc
, NULL
, NULL
);
269 element_callback (const BoxType
* b
, void *cl
)
271 ElementType
*element
= (ElementType
*) b
;
274 if (ON_SIDE (element
, *side
))
275 draw_element_package (element
);
279 /* ---------------------------------------------------------------------------
280 * prints assembly drawing.
284 PrintAssembly (int side
, const BoxType
* drawn_area
)
286 int side_group
= GetLayerGroupNumberBySide (side
);
289 hid_draw_set_draw_faded (Output
.fgGC
, 1);
290 DrawLayerGroup (side_group
, drawn_area
);
291 hid_draw_set_draw_faded (Output
.fgGC
, 0);
294 DrawSilk (hid_draw
, side
, drawn_area
);
298 /* ---------------------------------------------------------------------------
299 * initializes some identifiers for a new zoom factor and redraws whole screen
302 DrawEverything (const BoxType
*drawn_area
)
304 int i
, ngroups
, side
;
305 int top_group
, bottom_group
;
306 /* This is the list of layer groups we will draw. */
307 int do_group
[MAX_GROUP
];
308 /* This is the reverse of the order in which we draw them. */
309 int drawn_groups
[MAX_GROUP
];
310 int plated
, unplated
;
313 PCB
->Data
->SILKLAYER
.Color
= PCB
->ElementColor
;
314 PCB
->Data
->BACKSILKLAYER
.Color
= PCB
->InvisibleObjectsColor
;
316 memset (do_group
, 0, sizeof (do_group
));
317 for (ngroups
= 0, i
= 0; i
< max_copper_layer
; i
++)
319 LayerType
*l
= LAYER_ON_STACK (i
);
320 int group
= GetLayerGroupNumberByNumber (LayerStack
[i
]);
321 if (l
->On
&& !do_group
[group
])
324 drawn_groups
[ngroups
++] = group
;
328 top_group
= GetLayerGroupNumberBySide (TOP_SIDE
);
329 bottom_group
= GetLayerGroupNumberBySide (BOTTOM_SIDE
);
332 * first draw all 'invisible' stuff
334 if (!TEST_FLAG (CHECKPLANESFLAG
, PCB
)
335 && hid_draw_set_layer (hid_draw
, "invisible", SL (INVISIBLE
, 0), 0))
337 side
= SWAP_IDENT
? TOP_SIDE
: BOTTOM_SIDE
;
340 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, element_callback
, &side
);
341 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
, name_callback
, &side
);
342 dapi
->draw_layer (&(PCB
->Data
->Layer
[max_copper_layer
+ side
]), drawn_area
, NULL
);
344 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
, pad_callback
, &side
);
345 hid_draw_end_layer (hid_draw
);
348 /* draw all layers in layerstack order */
349 for (i
= ngroups
- 1; i
>= 0; i
--)
351 int group
= drawn_groups
[i
];
353 if (hid_draw_set_layer (hid_draw
, 0, group
, 0))
355 DrawLayerGroup (group
, drawn_area
);
356 hid_draw_end_layer (hid_draw
);
360 if (TEST_FLAG (CHECKPLANESFLAG
, PCB
) && hid_draw_is_gui (hid_draw
))
363 /* Draw pins, pads, vias below silk */
364 if (hid_draw_is_gui (hid_draw
))
365 dapi
->draw_ppv (SWAP_IDENT
? bottom_group
: top_group
, drawn_area
, NULL
);
368 CountHoles (&plated
, &unplated
, drawn_area
);
370 if (plated
&& hid_draw_set_layer (hid_draw
, "plated-drill", SL (PDRILL
, 0), 0))
372 dapi
->draw_holes (1, drawn_area
, NULL
);
373 hid_draw_end_layer (hid_draw
);
376 if (unplated
&& hid_draw_set_layer (hid_draw
, "unplated-drill", SL (UDRILL
, 0), 0))
378 dapi
->draw_holes (0, drawn_area
, NULL
);
379 hid_draw_end_layer (hid_draw
);
383 /* Draw the solder mask if turned on */
384 if (hid_draw_set_layer (hid_draw
, "componentmask", SL (MASK
, TOP
), 0))
386 DrawMask (TOP_SIDE
, drawn_area
);
387 hid_draw_end_layer (hid_draw
);
390 if (hid_draw_set_layer (hid_draw
, "soldermask", SL (MASK
, BOTTOM
), 0))
392 DrawMask (BOTTOM_SIDE
, drawn_area
);
393 hid_draw_end_layer (hid_draw
);
396 if (hid_draw_set_layer (hid_draw
, "topsilk", SL (SILK
, TOP
), 0))
398 DrawSilk (hid_draw
, TOP_SIDE
, drawn_area
);
399 hid_draw_end_layer (hid_draw
);
402 if (hid_draw_set_layer (hid_draw
, "bottomsilk", SL (SILK
, BOTTOM
), 0))
404 DrawSilk (hid_draw
, BOTTOM_SIDE
, drawn_area
);
405 hid_draw_end_layer (hid_draw
);
408 if (hid_draw_is_gui (hid_draw
))
410 /* Draw element Marks */
412 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, EMark_callback
,
414 /* Draw rat lines on top */
415 if (hid_draw_set_layer (hid_draw
, "rats", SL (RATS
, 0), 0))
417 DrawRats (hid_draw
, drawn_area
);
418 hid_draw_end_layer (hid_draw
);
422 paste_empty
= IsPasteEmpty (TOP_SIDE
);
423 if (hid_draw_set_layer (hid_draw
, "toppaste", SL (PASTE
, TOP
), paste_empty
))
425 DrawPaste (TOP_SIDE
, drawn_area
);
426 hid_draw_end_layer (hid_draw
);
429 paste_empty
= IsPasteEmpty (BOTTOM_SIDE
);
430 if (hid_draw_set_layer (hid_draw
, "bottompaste", SL (PASTE
, BOTTOM
), paste_empty
))
432 DrawPaste (BOTTOM_SIDE
, drawn_area
);
433 hid_draw_end_layer (hid_draw
);
436 if (hid_draw_set_layer (hid_draw
, "topassembly", SL (ASSY
, TOP
), 0))
438 PrintAssembly (TOP_SIDE
, drawn_area
);
439 hid_draw_end_layer (hid_draw
);
442 if (hid_draw_set_layer (hid_draw
, "bottomassembly", SL (ASSY
, BOTTOM
), 0))
444 PrintAssembly (BOTTOM_SIDE
, drawn_area
);
445 hid_draw_end_layer (hid_draw
);
448 if (hid_draw_set_layer (hid_draw
, "fab", SL (FAB
, 0), 0))
450 PrintFab (Output
.fgGC
);
451 hid_draw_end_layer (hid_draw
);
456 DrawEMark (ElementType
*e
, Coord X
, Coord Y
, bool invisible
)
458 Coord mark_size
= EMARK_SIZE
;
459 if (!PCB
->InvisibleObjectsOn
&& invisible
)
464 PinType
*pin0
= e
->Pin
->data
;
465 if (TEST_FLAG (HOLEFLAG
, pin0
))
466 mark_size
= MIN (mark_size
, pin0
->DrillingHole
/ 2);
468 mark_size
= MIN (mark_size
, pin0
->Thickness
/ 2);
473 PadType
*pad0
= e
->Pad
->data
;
474 mark_size
= MIN (mark_size
, pad0
->Thickness
/ 2);
477 hid_draw_set_color (Output
.fgGC
, invisible
? PCB
->InvisibleMarkColor
: PCB
->ElementColor
);
478 hid_draw_set_line_cap (Output
.fgGC
, Trace_Cap
);
479 hid_draw_set_line_width (Output
.fgGC
, 0);
480 hid_draw_line (Output
.fgGC
, X
- mark_size
, Y
, X
, Y
- mark_size
);
481 hid_draw_line (Output
.fgGC
, X
+ mark_size
, Y
, X
, Y
- mark_size
);
482 hid_draw_line (Output
.fgGC
, X
- mark_size
, Y
, X
, Y
+ mark_size
);
483 hid_draw_line (Output
.fgGC
, X
+ mark_size
, Y
, X
, Y
+ mark_size
);
486 * If an element is locked, place a "L" on top of the "diamond".
487 * This provides a nice visual indication that it is locked that
488 * works even for color blind users.
490 if (TEST_FLAG (LOCKFLAG
, e
) )
492 hid_draw_line (Output
.fgGC
, X
, Y
, X
+ 2 * mark_size
, Y
);
493 hid_draw_line (Output
.fgGC
, X
, Y
, X
, Y
- 4* mark_size
);
498 pin_mask_callback (const BoxType
* b
, void *cl
)
500 dapi
->draw_pin_mask ((PinType
*) b
, NULL
, NULL
);
505 via_mask_callback (const BoxType
* b
, void *cl
)
507 dapi
->draw_via_mask ((PinType
*) b
, NULL
, NULL
);
512 pad_mask_callback (const BoxType
* b
, void *cl
)
514 PadType
*pad
= (PadType
*) b
;
516 if (ON_SIDE (pad
, *side
))
517 dapi
->draw_pad_mask (pad
, NULL
, NULL
);
521 /* ---------------------------------------------------------------------------
526 DrawSilk (HID_DRAW
*new_hid_draw
, int side
, const BoxType
* drawn_area
)
528 HID_DRAW
*old_hid_draw
= hid_draw
;
529 hid_draw
= new_hid_draw
;
532 /* This code is used when you want to mask silk to avoid exposed
533 pins and pads. We decided it was a bad idea to do this
534 unconditionally, but the code remains. */
538 if (hid_draw
->poly_before
)
540 hid_draw_use_mask (hid_draw
, HID_MASK_BEFORE
);
542 dapi
->draw_layer (LAYER_PTR (max_copper_layer
+ side
), drawn_area
, NULL
);
544 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, element_callback
, &side
);
545 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
, name_callback
, &side
);
549 hid_draw_use_mask (hid_draw
, HID_MASK_CLEAR
);
550 r_search (PCB
->Data
->pin_tree
, drawn_area
, NULL
, pin_mask_callback
, NULL
);
551 r_search (PCB
->Data
->via_tree
, drawn_area
, NULL
, via_mask_callback
, NULL
);
552 r_search (PCB
->Data
->pad_tree
, drawn_area
, NULL
, pad_mask_callback
, &side
);
554 if (hid_draw
->poly_after
)
556 hid_draw_use_mask (hid_draw
, HID_MASK_AFTER
);
557 dapi
->draw_layer (LAYER_PTR (max_copper_layer
+ layer
), drawn_area
, NULL
);
559 r_search (PCB
->Data
->element_tree
, drawn_area
, NULL
, element_callback
, &side
);
560 r_search (PCB
->Data
->name_tree
[NAME_INDEX (PCB
)], drawn_area
, NULL
, name_callback
, &side
);
562 hid_draw_use_mask (hid_draw
, HID_MASK_OFF
);
565 hid_draw
= old_hid_draw
;
570 DrawMaskBoardArea (int mask_type
, const BoxType
*drawn_area
)
572 /* Skip the mask drawing if the GUI doesn't want this type */
573 if ((mask_type
== HID_MASK_BEFORE
&& !hid_draw
->poly_before
) ||
574 (mask_type
== HID_MASK_AFTER
&& !hid_draw
->poly_after
))
577 hid_draw_use_mask (hid_draw
, mask_type
);
578 hid_draw_set_color (Output
.fgGC
, PCB
->MaskColor
);
579 if (drawn_area
== NULL
)
580 hid_draw_fill_rect (Output
.fgGC
, 0, 0, PCB
->MaxWidth
, PCB
->MaxHeight
);
582 hid_draw_fill_rect (Output
.fgGC
, drawn_area
->X1
, drawn_area
->Y1
,
583 drawn_area
->X2
, drawn_area
->Y2
);
587 const const BoxType
*drawn_area
;
592 mask_poly_callback (const BoxType
* b
, void *cl
)
594 struct poly_info
*i
= cl
;
595 PolygonType
*polygon
= (PolygonType
*)b
;
597 hid_draw_pcb_polygon (Output
.pmGC
, polygon
, i
->drawn_area
);
602 mask_line_callback (const BoxType
* b
, void *cl
)
604 LineType
*line
= (LineType
*)b
;
606 hid_draw_pcb_line (Output
.pmGC
, line
);
611 mask_arc_callback (const BoxType
* b
, void *cl
)
613 ArcType
*arc
= (ArcType
*)b
;
615 hid_draw_pcb_arc (Output
.pmGC
, arc
);
620 mask_text_callback (const BoxType
* b
, void *cl
)
622 LayerType
*layer
= cl
;
623 TextType
*text
= (TextType
*)b
;
626 if (layer
== &PCB
->Data
->SILKLAYER
||
627 layer
== &PCB
->Data
->BACKSILKLAYER
)
628 min_silk_line
= PCB
->minSlk
;
630 min_silk_line
= PCB
->minWid
;
631 hid_draw_pcb_text (Output
.fgGC
, text
, min_silk_line
);
635 /* ---------------------------------------------------------------------------
636 * draws solder mask layer - this will cover nearly everything
639 DrawMask (int side
, const BoxType
*screen
)
641 int thin
= TEST_FLAG(THINDRAWFLAG
, PCB
) || TEST_FLAG(THINDRAWPOLYFLAG
, PCB
);
642 LayerType
*Layer
= LAYER_PTR (side
== TOP_SIDE
? top_soldermask_layer
: bottom_soldermask_layer
);
643 struct poly_info info
;
646 hid_draw_set_color (Output
.pmGC
, PCB
->MaskColor
);
649 DrawMaskBoardArea (HID_MASK_BEFORE
, screen
);
650 hid_draw_use_mask (hid_draw
, HID_MASK_CLEAR
);
654 info
.drawn_area
= screen
;
655 r_search (Layer
->polygon_tree
, screen
, NULL
, mask_poly_callback
, &info
);
656 r_search (Layer
->line_tree
, screen
, NULL
, mask_line_callback
, Layer
);
657 r_search (Layer
->arc_tree
, screen
, NULL
, mask_arc_callback
, Layer
);
658 r_search (Layer
->text_tree
, screen
, NULL
, mask_text_callback
, Layer
);
660 r_search (PCB
->Data
->pin_tree
, screen
, NULL
, pin_mask_callback
, NULL
);
661 r_search (PCB
->Data
->via_tree
, screen
, NULL
, via_mask_callback
, NULL
);
662 r_search (PCB
->Data
->pad_tree
, screen
, NULL
, pad_mask_callback
, &side
);
665 hid_draw_set_color (Output
.pmGC
, "erase");
668 DrawMaskBoardArea (HID_MASK_AFTER
, screen
);
669 hid_draw_use_mask (hid_draw
, HID_MASK_OFF
);
673 /* ---------------------------------------------------------------------------
674 * draws solder paste layer for a given side of the board
677 DrawPaste (int side
, const BoxType
*drawn_area
)
679 hid_draw_set_color (Output
.fgGC
, PCB
->ElementColor
);
680 ALLPAD_LOOP (PCB
->Data
);
682 if (ON_SIDE (pad
, side
))
683 dapi
->draw_pad_paste (pad
, NULL
, NULL
);
689 DrawRats (HID_DRAW
*new_hid_draw
, const BoxType
*drawn_area
)
691 HID_DRAW
*old_hid_draw
= hid_draw
;
692 hid_draw
= new_hid_draw
;
695 * XXX lesstif allows positive AND negative drawing in HID_MASK_CLEAR.
696 * XXX gtk only allows negative drawing.
697 * XXX using the mask here is to get rat transparency
700 if (hid_draw_can_draw_in_mask_clear (hid_draw
))
701 hid_draw_use_mask (hid_draw
, HID_MASK_CLEAR
);
702 r_search (PCB
->Data
->rat_tree
, drawn_area
, NULL
, rat_callback
, NULL
);
703 if (hid_draw_can_draw_in_mask_clear (hid_draw
))
704 hid_draw_use_mask (hid_draw
, HID_MASK_OFF
);
706 hid_draw
= old_hid_draw
;
709 /* ---------------------------------------------------------------------------
710 * draws one layer group. If the exporter is not a GUI,
711 * also draws the pins / pads / vias in this layer group.
714 DrawLayerGroup (int group
, const BoxType
*drawn_area
)
719 int n_entries
= PCB
->LayerGroups
.Number
[group
];
720 Cardinal
*layers
= PCB
->LayerGroups
.Entries
[group
];
722 for (i
= n_entries
- 1; i
>= 0; i
--)
724 layernum
= layers
[i
];
725 Layer
= PCB
->Data
->Layer
+ layers
[i
];
726 if (strcmp (Layer
->Name
, "outline") == 0 ||
727 strcmp (Layer
->Name
, "route") == 0)
729 if (layernum
< max_copper_layer
&& Layer
->On
)
730 dapi
->draw_layer (Layer
, drawn_area
, NULL
);
735 if (rv
&& !hid_draw_is_gui (hid_draw
))
736 dapi
->draw_ppv (group
, drawn_area
, NULL
);
740 GatherPVName (PinType
*Ptr
)
743 bool vert
= TEST_FLAG (EDGE2FLAG
, Ptr
);
747 box
.X1
= Ptr
->X
- Ptr
->Thickness
/ 2 + Settings
.PinoutTextOffsetY
;
748 box
.Y1
= Ptr
->Y
- Ptr
->DrillingHole
/ 2 - Settings
.PinoutTextOffsetX
;
752 box
.X1
= Ptr
->X
+ Ptr
->DrillingHole
/ 2 + Settings
.PinoutTextOffsetX
;
753 box
.Y1
= Ptr
->Y
- Ptr
->Thickness
/ 2 + Settings
.PinoutTextOffsetY
;
770 GatherPadName (PadType
*Pad
)
775 /* should text be vertical ? */
776 vert
= (Pad
->Point1
.X
== Pad
->Point2
.X
);
780 box
.X1
= Pad
->Point1
.X
- Pad
->Thickness
/ 2;
781 box
.Y1
= MAX (Pad
->Point1
.Y
, Pad
->Point2
.Y
) + Pad
->Thickness
/ 2;
782 box
.X1
+= Settings
.PinoutTextOffsetY
;
783 box
.Y1
-= Settings
.PinoutTextOffsetX
;
789 box
.X1
= MIN (Pad
->Point1
.X
, Pad
->Point2
.X
) - Pad
->Thickness
/ 2;
790 box
.Y1
= Pad
->Point1
.Y
- Pad
->Thickness
/ 2;
791 box
.X1
+= Settings
.PinoutTextOffsetX
;
792 box
.Y1
+= Settings
.PinoutTextOffsetY
;
801 /* ---------------------------------------------------------------------------
805 DrawVia (PinType
*Via
)
808 if (!TEST_FLAG (HOLEFLAG
, Via
) && TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
812 /* ---------------------------------------------------------------------------
813 * draws the name of a via
816 DrawViaName (PinType
*Via
)
821 /* ---------------------------------------------------------------------------
825 DrawPin (PinType
*Pin
)
828 if ((!TEST_FLAG (HOLEFLAG
, Pin
) && TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
833 /* ---------------------------------------------------------------------------
834 * draws the name of a pin
837 DrawPinName (PinType
*Pin
)
842 /* ---------------------------------------------------------------------------
846 DrawPad (PadType
*Pad
)
849 if (doing_pinout
|| TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
853 /* ---------------------------------------------------------------------------
854 * draws the name of a pad
857 DrawPadName (PadType
*Pad
)
862 /* ---------------------------------------------------------------------------
863 * draws a line on a layer
866 DrawLine (LayerType
*Layer
, LineType
*Line
)
871 /* ---------------------------------------------------------------------------
875 DrawRat (RatType
*Rat
)
877 if (Settings
.RatThickness
< 100)
878 Rat
->Thickness
= pixel_slop
* Settings
.RatThickness
;
879 /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */
880 if (TEST_FLAG(VIAFLAG
, Rat
))
882 Coord w
= Rat
->Thickness
;
886 b
.X1
= Rat
->Point1
.X
- w
* 2 - w
/ 2;
887 b
.X2
= Rat
->Point1
.X
+ w
* 2 + w
/ 2;
888 b
.Y1
= Rat
->Point1
.Y
- w
* 2 - w
/ 2;
889 b
.Y2
= Rat
->Point1
.Y
+ w
* 2 + w
/ 2;
893 DrawLine (NULL
, (LineType
*)Rat
);
896 /* ---------------------------------------------------------------------------
897 * draws an arc on a layer
900 DrawArc (LayerType
*Layer
, ArcType
*Arc
)
905 /* ---------------------------------------------------------------------------
906 * draws a text on a layer
909 DrawText (LayerType
*Layer
, TextType
*Text
)
915 /* ---------------------------------------------------------------------------
916 * draws a polygon on a layer
919 DrawPolygon (LayerType
*Layer
, PolygonType
*Polygon
)
924 /* ---------------------------------------------------------------------------
928 DrawElement (ElementType
*Element
)
930 DrawElementPackage (Element
);
931 DrawElementName (Element
);
932 DrawElementPinsAndPads (Element
);
935 /* ---------------------------------------------------------------------------
936 * draws the name of an element
939 DrawElementName (ElementType
*Element
)
941 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
943 DrawText (NULL
, &ELEMENT_TEXT (PCB
, Element
));
946 /* ---------------------------------------------------------------------------
947 * draws the package of an element
950 DrawElementPackage (ElementType
*Element
)
952 ELEMENTLINE_LOOP (Element
);
954 DrawLine (NULL
, line
);
964 /* ---------------------------------------------------------------------------
965 * draw pins of an element
968 DrawElementPinsAndPads (ElementType
*Element
)
972 if (doing_pinout
|| doing_assy
|| FRONT (pad
) || PCB
->InvisibleObjectsOn
)
983 /* ---------------------------------------------------------------------------
987 EraseVia (PinType
*Via
)
990 if (TEST_FLAG (DISPLAYNAMEFLAG
, Via
))
994 /* ---------------------------------------------------------------------------
998 EraseRat (RatType
*Rat
)
1000 if (TEST_FLAG(VIAFLAG
, Rat
))
1002 Coord w
= Rat
->Thickness
;
1006 b
.X1
= Rat
->Point1
.X
- w
* 2 - w
/ 2;
1007 b
.X2
= Rat
->Point1
.X
+ w
* 2 + w
/ 2;
1008 b
.Y1
= Rat
->Point1
.Y
- w
* 2 - w
/ 2;
1009 b
.Y2
= Rat
->Point1
.Y
+ w
* 2 + w
/ 2;
1013 EraseLine ((LineType
*)Rat
);
1017 /* ---------------------------------------------------------------------------
1021 EraseViaName (PinType
*Via
)
1026 /* ---------------------------------------------------------------------------
1027 * erase a pad object
1030 ErasePad (PadType
*Pad
)
1033 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pad
))
1037 /* ---------------------------------------------------------------------------
1041 ErasePadName (PadType
*Pad
)
1043 GatherPadName (Pad
);
1046 /* ---------------------------------------------------------------------------
1047 * erase a pin object
1050 ErasePin (PinType
*Pin
)
1053 if (TEST_FLAG (DISPLAYNAMEFLAG
, Pin
))
1057 /* ---------------------------------------------------------------------------
1061 ErasePinName (PinType
*Pin
)
1066 /* ---------------------------------------------------------------------------
1067 * erases a line on a layer
1070 EraseLine (LineType
*Line
)
1075 /* ---------------------------------------------------------------------------
1076 * erases an arc on a layer
1079 EraseArc (ArcType
*Arc
)
1081 if (!Arc
->Thickness
)
1086 /* ---------------------------------------------------------------------------
1087 * erases a text on a layer
1090 EraseText (LayerType
*Layer
, TextType
*Text
)
1095 /* ---------------------------------------------------------------------------
1096 * erases a polygon on a layer
1099 ErasePolygon (PolygonType
*Polygon
)
1104 /* ---------------------------------------------------------------------------
1108 EraseElement (ElementType
*Element
)
1110 ELEMENTLINE_LOOP (Element
);
1120 EraseElementName (Element
);
1121 EraseElementPinsAndPads (Element
);
1124 /* ---------------------------------------------------------------------------
1125 * erases all pins and pads of an element
1128 EraseElementPinsAndPads (ElementType
*Element
)
1142 /* ---------------------------------------------------------------------------
1143 * erases the name of an element
1146 EraseElementName (ElementType
*Element
)
1148 if (TEST_FLAG (HIDENAMEFLAG
, Element
))
1150 DrawText (NULL
, &ELEMENT_TEXT (PCB
, Element
));
1155 EraseObject (int type
, void *lptr
, void *ptr
)
1161 ErasePin ((PinType
*) ptr
);
1164 case ELEMENTNAME_TYPE
:
1165 EraseText ((LayerType
*)lptr
, (TextType
*) ptr
);
1168 ErasePolygon ((PolygonType
*) ptr
);
1171 EraseElement ((ElementType
*) ptr
);
1174 case ELEMENTLINE_TYPE
:
1176 EraseLine ((LineType
*) ptr
);
1179 ErasePad ((PadType
*) ptr
);
1182 case ELEMENTARC_TYPE
:
1183 EraseArc ((ArcType
*) ptr
);
1186 Message ("hace: Internal ERROR, trying to erase an unknown type\n");
1193 DrawObject (int type
, void *ptr1
, void *ptr2
)
1199 DrawVia ((PinType
*) ptr2
);
1202 if (((LayerType
*) ptr1
)->On
)
1203 DrawLine ((LayerType
*) ptr1
, (LineType
*) ptr2
);
1206 if (((LayerType
*) ptr1
)->On
)
1207 DrawArc ((LayerType
*) ptr1
, (ArcType
*) ptr2
);
1210 if (((LayerType
*) ptr1
)->On
)
1211 DrawText ((LayerType
*) ptr1
, (TextType
*) ptr2
);
1214 if (((LayerType
*) ptr1
)->On
)
1215 DrawPolygon ((LayerType
*) ptr1
, (PolygonType
*) ptr2
);
1218 if (PCB
->ElementOn
&&
1219 (FRONT ((ElementType
*) ptr2
) || PCB
->InvisibleObjectsOn
))
1220 DrawElement ((ElementType
*) ptr2
);
1224 DrawRat ((RatType
*) ptr2
);
1228 DrawPin ((PinType
*) ptr2
);
1232 DrawPad ((PadType
*) ptr2
);
1234 case ELEMENTNAME_TYPE
:
1235 if (PCB
->ElementOn
&&
1236 (FRONT ((ElementType
*) ptr2
) || PCB
->InvisibleObjectsOn
))
1237 DrawElementName ((ElementType
*) ptr1
);
1243 draw_element (ElementType
*element
)
1245 draw_element_package (element
);
1246 draw_element_name (element
);
1247 draw_element_pins_and_pads (element
);
1250 /* ---------------------------------------------------------------------------
1251 * HID drawing callback.
1255 hid_expose_callback (HID_DRAW
*expose_hid_draw
, BoxType
*region
, void *item
)
1257 hid_draw
= expose_hid_draw
;
1258 Output
.fgGC
= hid_draw_make_gc (hid_draw
);
1259 Output
.bgGC
= hid_draw_make_gc (hid_draw
);
1260 Output
.pmGC
= hid_draw_make_gc (hid_draw
);
1262 hid_draw_set_color (Output
.pmGC
, "erase");
1263 hid_draw_set_color (Output
.bgGC
, "drill");
1267 doing_pinout
= true;
1268 draw_element ((ElementType
*)item
);
1269 doing_pinout
= false;
1272 DrawEverything (region
);
1274 hid_draw_destroy_gc (Output
.fgGC
);
1275 hid_draw_destroy_gc (Output
.bgGC
);
1276 hid_draw_destroy_gc (Output
.pmGC
);