File: HACKING

package info (click to toggle)
gerbv 2.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 8,948 kB
  • ctags: 2,246
  • sloc: ansic: 22,505; sh: 12,194; lisp: 896; makefile: 384; perl: 42
file content (235 lines) | stat: -rw-r--r-- 7,999 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
=======	CODING STANDARD FOR GERBV =======

$Id$


Indentation
-----------
To hack in this code you need to set emacs (or whatever you use) to
4 indentation steps and {} at the right places (see code).
Not negotiable.

My ~/.emacs are:
(defun my-c-mode-hook ()
  (turn-on-font-lock)
  (setq c-basic-offset 4))

(add-hook 'c-mode-hook 'my-c-mode-hook)


Curly Braces
------------

if () {
    blah1();
    blah2();
} else {
    yada1();
    yada2();
}
If there is only one statement you don't need the braces.

for() {
    do_whatever1();
    do_whatever2();
}

switch() {
case foo:
    blah1();
    break;
case bar:
    blah2();
    break;
default:
    break;
}
Switch should always have a default case.


ChangeLog
---------
Minor changes (cosmetic, minor (up to 4,5 lines) not reported bugs) 
doesn't need a ChangeLog entry. A ChangeLog entry is needed when a 
reported bug is fixed (with bug report number) or when a feature is 
added. I (spe) use ChangeLog when writing release notes.


Functions
---------
The prototype should have return type on the same line as function name:
int some_function(int par1, int par2);

The function implementation should have return type on a separate line
(including eventual pointer star). The function implementation should 
have the function name in c-comments
at the closing brace.
int *
some_function(int par1, int par2)
{
    /* Implementation */
} /* some_function */

In a function there should be maximum one empty line in a row.
Between functions there should be two empty lines.


======= GERBV'S INTERNAL WORKINGS =======

Here are some rough notes about how gerbv works.  These notes were
taken during the development of version 1.1.0, so things may have 
changed since then.  The idea behind these notes is to help new 
developers understand the program flow.  Please add/modify these
notes as you work on gerbv and come to understand its workings.

----------------------------------------------------------------
Important datastructures (this list is not complete, but rather
tries to touch upon the high points of the datastructures used):

screen -- top level struct of info about all Gerber images superimposed.
  Global variable.  Individual Gerber images(layers) are accessed as
  screen.file[i]->image.  This is a global variable, invoked by 
  "extern gerbv_screen_t screen" in every fcn which uses it.
  Defined in gerbv_screen.h.

  Selected members:
  screen->drawing_area -- This is the window showing the layers (Gerbers)
  screen->pixmap
  screen->win -- various windows presented to the user.
  screen->state
  screen->file[idx] -- This holds info relating to the input 
                       layer (Gerber) files.  Defined 
                       as gerbv_fileinfo_t in gerbv_screen.h

  screen->file[idx]->color
  screen->file[idx]->name
  screen->file[idx]->isVisible
  screen->file[idx]->gerber_stats -- struct hold info about codes
                                     encountered while reading gerber files.
  screen->file[idx]->drill_stats -- struct hold info about codes
                                     encountered while reading drill files.

  screen->file[idx]->image -- Holds a parsed representation 
                     of each Gerber file in the project.  The data 
                     held in this struct is used in the drawing 
                     programs (image2pixmap) to draw the screen.
                     Each layer lives on a separate index (idx). 
                     defined as gerb_image_t in gerb_image.h

  screen->file[idx]->image->aperture -- Holds aperture info pertaining
                                        to this Gerber layer.
					Defined as gerb_aperture_t
					in gerb_image.h
  screen->file[idx]->image->format
  screen->file[idx]->image->netlist -- This holds info relating 
                                       to the elements in the
                                       layer (Gerber) files.  
                                       Defined as gerb_net_t
				       in gerb_image.h


gerb_state_t -- This variable keeps track of the state of the 
  CAM job as the Gerber file is parsed.  It is updated with
  each code read in, and is also used duing parsing to hold 
  state information which can be modified by the incoming codes.
  Its use is local to gerber.c

----------------------------------------------------------------
Important files:

Here's a summary of gerbv's file hierarchy, from top to bottom:

1. gerbv.c -- holds main() and other top level fcns.  

2. callbacks.[hc], interface.[hc] -- Hold GUI widgets (interface) and 
   callbacks (callbacks).

3. render.[hc] -- holds the top-level rendering stuff with lots of looping
   code, like redraw_pixmap,  image2pixmap, and
   render_image_to_cairo_target.  This is the place that other,
   non-GUI exporters should get called from (export_png, export_pdf,
   etc).  

4. draw.[hc], draw-gdk.[hc] -- these hold the low level utilities
   which draw objects onto screen.drawing_area.  Each is specific to
   the corresponding rendering engine.

Then on the side we have:

*  gerb_file.[hc]. gerb_image.[hc], etc -- functions related to dealing
   with the important structs in the program.  This can be expanded as we
   include gerb_stats.[hc] etc.

*  gerber.[hc]  drill.[hc]  pick_and_place.[hc]  -- files holding the
   stuff which parses and processes the respective types of CAM files.

*  Many others to be documented......

----------------------------------------------------------------
Important functions

gerber.c:parse_gerb:  Parses gerber, returns gerb_image.

gerbv.c:redraw_pixmap is the thing which actually 
draws the Gerber files on the
screen.  It is called by several callbacks to draw the screen.  It takes a
pointer to the screen widget (screen.drawing_area)

image2pixmap (gdk) or render_image_to_cairo_target (cairo) 
is the thing which actually does the drawing onto the drawing
area.  


----------------------------------------------------------------
Use cases:

====
gerbv starts.  Global variable screen is declared.
 main() called.   Sets up screen.  Handles command line flags.
Inits GTK, then goes into GTK event loop.

User does "file -> open Gerber(s)".  Callback XXXX is called.  It
calls open_image to open the Gerber file.  Then redraw_pixmap is called
to redraw the screen for the user.

open_image does this:
  1.  Calls gerb_fopen, which returns a file descriptor
  2.  Calls parse_gerb, which returns a gerb_image_t*.
  3.  Attaches new image to screen.file[idx]->image.
  4.  Stores the filename in screen.file[idx]->name
  5.  Sets the basename for the file.
  6.  Sets the colors for the image.
  7.  Return -1 upon error or 0 upon success.

parse_gerb does this:
  0.  Mallocs and creates a new state (gerb_state_t).  State is local
      to parse_gerb.
  1.  Creates a new gerb image (gerb_image_t) using new_gerb_image
  2.  Attaches new netlist using curr_net = image->netlist;
  3.  Reads chars from the opened Gerber file, and does a dispatch
      based upon which char is found.  Example: for a G code,
      parse_G_code is called.
  4.  If the found char is a *, then wrap up processing for this
      code by:
      1.  Malloc memory for a new net element in the curr_net list.
      2.  Update state and image members depending upon what this
          code has been.
  5.  Loop to next code.
  6.  Returns built up gerb image (gerb_image_t *)

parse_G_code (and parse_<*>_code) does this:
  1.  Calls gerb_fgetint to get the number of the code, then does
      a dispatch depending upon which number is found.
  2.  Depending upon the code (number), state-> is modified.
  3.  Return void.

redraw_pixmap does this:
  1.  Set up global drawing parameters
  2.  Creates a new screen.pixmap
  3.  Loops over visible files (images) in state.file_index list
  4.  Calls image2pixmap (gdk) or render_image_to_cairo_target (cairo) 
      on each image.
  5.  Redraws the top level window.
  6.  Returns TRUE or FALSE to control idle function (???)