• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Coding Style Guidelines
2=======================
3
4These conventions have evolved over time. Some of the earlier code in both
5projects doesn’t strictly adhere to the guidelines. However, as the code evolves
6we hope to make the existing code conform to the guildelines.
7
8Files
9-----
10
11We use .cpp and .h as extensions for c++ source and header files. We use
12foo_impl.h for headers with inline definitions for class foo.
13
14Headers that aren’t meant for public consumption should be placed in src
15directories so that they aren’t in a client’s search path.
16
17We prefer to minimize includes. If forward declaring a name in a header is
18sufficient then that is preferred to an include.
19
20Forward declarations and file includes should be in alphabetical order (but we
21aren't very strict about it).
22
23<span id="no-define-before-sktypes"></span>
24Do not use #if/#ifdef before including "SkTypes.h" (directly or indirectly).
25
26We use spaces not tabs (4 of them).
27
28We use Unix style endlines (LF).
29
30We prefer no trailing whitespace but aren't very strict about it.
31
32We wrap lines at 100 columns unless it is excessively ugly (use your judgement).
33The soft line length limit was changed from 80 to 100 columns in June 2012. Thus,
34most files still adhere to the 80 column limit. It is not necessary or worth
35significant effort to promote 80 column wrapped files to 100 columns. Please
36don't willy-nilly insert longer lines in 80 column wrapped files. Either be
37consistent with the surrounding code or, if you really feel the need, promote
38the surrounding code to 100 column wrapping.
39
40Naming
41------
42
43Both projects use a prefix to designate that they are Skia prefix for classes,
44enums, structs, typedefs etc is Sk. Ganesh’s is Gr. Nested types should not be
45prefixed.
46
47<!--?prettify?-->
48~~~~
49class SkClass {
50public:
51    class HelperClass {
52        ...
53    };
54};
55~~~~
56
57Data fields in structs, classes, unions begin with lowercase f and are then
58camel capped.
59
60<!--?prettify?-->
61~~~~
62struct GrCar {
63    ...
64    float fMilesDriven;
65    ...
66};
67~~~~
68
69Globals variables are similar but prefixed with g and camel-capped
70
71<!--?prettify?-->
72~~~~
73bool gLoggingEnabled
74Local variables begin lowercases and are camel-capped.
75
76int herdCats(const Array& cats) {
77    int numCats = cats.count();
78}
79~~~~
80
81Enum values are prefixed with k. Unscoped enum values are post fixed with
82an underscore and singular name of the enum name. The enum itself should be
83singular for exclusive values or plural for a bitfield. If a count is needed it
84is  k&lt;singular enum name&gt;Count and not be a member of the enum (see example):
85
86<!--?prettify?-->
87~~~~
88enum class SkPancakeType {
89     kBlueberry,
90     kPlain,
91     kChocolateChip,
92};
93~~~~
94
95<!--?prettify?-->
96~~~~
97enum SkPancakeType {
98     kBlueberry_PancakeType,
99     kPlain_PancakeType,
100     kChocolateChip_PancakeType,
101
102     kLast_PancakeType = kChocolateChip_PancakeType
103};
104
105static const SkPancakeType kPancakeTypeCount = kLast_PancakeType + 1;
106~~~~
107
108A bitfield:
109
110<!--?prettify?-->
111~~~~
112enum SkSausageIngredientBits {
113    kFennel_SuasageIngredientBit = 0x1,
114    kBeef_SausageIngredientBit   = 0x2
115};
116~~~~
117
118or:
119
120<!--?prettify?-->
121~~~~
122enum SkMatrixFlags {
123    kTranslate_MatrixFlag = 0x1,
124    kRotate_MatrixFlag    = 0x2
125};
126~~~~
127
128Exception: anonymous enums can be used to declare integral constants, e.g.:
129
130<!--?prettify?-->
131~~~~
132enum { kFavoriteNumber = 7 };
133~~~~
134
135Macros are all caps with underscores between words. Macros that have greater
136than file scope should be prefixed SK or GR.
137
138Static non-class functions in implementation files are lower case with
139underscores separating words:
140
141<!--?prettify?-->
142~~~~
143static inline bool tastes_like_chicken(Food food) {
144    return kIceCream_Food != food;
145}
146~~~~
147
148Externed functions or static class functions are camel-capped with an initial cap:
149
150<!--?prettify?-->
151~~~~
152bool SkIsOdd(int n);
153
154class SkFoo {
155public:
156    static int FooInstanceCount();
157};
158~~~~
159
160Macros
161------
162
163Ganesh macros that are GL-specific should be prefixed GR_GL.
164
165<!--?prettify?-->
166~~~~
167#define GR_GL_TEXTURE0 0xdeadbeef
168~~~~
169
170Ganesh prefers that macros are always defined and the use of #if MACRO rather than
171#ifdef MACRO.
172
173<!--?prettify?-->
174~~~~
175#define GR_GO_SLOWER 0
176...
177#if GR_GO_SLOWER
178    Sleep(1000);
179#endif
180~~~~
181
182Skia tends to use #ifdef SK_MACRO for boolean flags.
183
184Braces
185------
186
187Open braces don’t get a newline. “else” and “else if” appear on same line as
188opening and closing braces unless preprocessor conditional compilation
189interferes. Braces are always used with if, else, while, for, and do.
190
191<!--?prettify?-->
192~~~~
193if (...) {
194    oneOrManyLines;
195}
196
197if (...) {
198    oneOrManyLines;
199} else if (...) {
200    oneOrManyLines;
201} else {
202    oneOrManyLines;
203}
204
205for (...) {
206    oneOrManyLines;
207}
208
209while (...) {
210    oneOrManyLines;
211}
212
213void function(...) {
214    oneOrManyLines;
215}
216
217if (!error) {
218    proceed_as_usual();
219}
220#if HANDLE_ERROR
221else {
222    freak_out();
223}
224#endif
225~~~~
226
227Flow Control
228------------
229
230There is a space between flow control words and parentheses and between
231parentheses and braces:
232
233<!--?prettify?-->
234~~~~
235while (...) {
236}
237
238do {
239} while(...);
240
241switch (...) {
242...
243}
244~~~~
245
246Cases and default in switch statements are indented from the switch.
247
248<!--?prettify?-->
249~~~~
250switch (color) {
251    case kBlue:
252        ...
253        break;
254    case kGreen:
255        ...
256        break;
257    ...
258    default:
259       ...
260       break;
261}
262~~~~
263
264Fallthrough from one case to the next is commented unless it is trivial:
265
266<!--?prettify?-->
267~~~~
268switch (recipe) {
269    ...
270    case kCheeseOmelette_Recipe:
271        ingredients |= kCheese_Ingredient;
272        // fallthrough
273    case kPlainOmelette_Recipe:
274        ingredients |= (kEgg_Ingredient | kMilk_Ingredient);
275        break;
276    ...
277}
278~~~~
279
280When a block is needed to declare variables within a case follow this pattern:
281
282<!--?prettify?-->
283~~~~
284switch (filter) {
285    ...
286    case kGaussian_Filter: {
287        Bitmap srcCopy = src->makeCopy();
288        ...
289        break;
290    }
291    ...
292};
293~~~~
294
295Classes
296-------
297
298Unless there is a need for forward declaring something, class declarations
299should be ordered public, protected, private. Each should be preceded by a
300newline. Within each visibility section (public, private), fields should not be
301intermixed with methods.
302
303<!--?prettify?-->
304~~~~
305class SkFoo {
306
307public:
308    ...
309
310protected:
311    ...
312
313private:
314    SkBar fBar;
315    ...
316
317    void barHelper(...);
318    ...
319};
320~~~~
321
322Subclasses should have a private typedef of their super class called INHERITED:
323
324<!--?prettify?-->
325~~~~
326class GrDillPickle : public GrPickle {
327    ...
328private:
329    typedef GrPickle INHERITED;
330};
331~~~~
332
333Virtual functions that are overridden in derived classes should use override
334(and not the override keyword). The virtual keyword can be omitted.
335
336<!--?prettify?-->
337~~~~
338void myVirtual() override {
339}
340~~~~
341
342This should be the last element of their private section, and all references to
343base-class implementations of a virtual function should be explicitly qualified:
344
345<!--?prettify?-->
346~~~~
347void myVirtual() override {
348    ...
349    this->INHERITED::myVirtual();
350    ...
351}
352~~~~
353
354As in the above example, derived classes that redefine virtual functions should
355use override to note that explicitly.
356
357Constructor initializers should be one per line, indented, with punctuation
358placed before the initializer. This is a fairly new rule so much of the existing
359code is non-conforming. Please fix as you go!
360
361<!--?prettify?-->
362~~~~
363GrDillPickle::GrDillPickle()
364    : GrPickle()
365    , fSize(kDefaultPickleSize) {
366    ...
367}
368~~~~
369
370Constructors that take one argument should almost always be explicit, with
371exceptions made only for the (rare) automatic compatibility class.
372
373<!--?prettify?-->
374~~~~
375class Foo {
376    explicit Foo(int x);  // Good.
377    Foo(float y);         // Spooky implicit conversion from float to Foo.  No no no!
378    ...
379};
380~~~~
381
382Method calls within method calls should be prefixed with dereference of the
383'this' pointer. For example:
384
385<!--?prettify?-->
386~~~~
387this->method();
388Memory Management
389~~~~
390
391All memory allocation should be routed through SkNEW and its variants. These are
392#defined in SkPostConfig.h, but the correct way to get access to the config
393system is to #include SkTypes.h, which will allow external users of the library
394to provide a custom memory manager or other adaptations.
395
396<!--?prettify?-->
397~~~~
398SkNEW(type_name)
399SkNEW_ARGS(type_name, args)
400SkNEW_ARRAY(type_name, count)
401SkNEW_PLACEMENT(buf, type_name)
402SkNEW_PLACEMENT_ARGS(buf, type_name, args)
403SkDELETE(obj)
404SkDELETE_ARRAY(array)
405~~~~
406
407Comparisons
408-----------
409
410We prefer that equality operators between lvalues and rvalues place the lvalue
411on the right:
412
413<!--?prettify?-->
414~~~~
415if (7 == luckyNumber) {
416    ...
417}
418~~~~
419
420However, inequality operators need not follow this rule:
421
422<!--?prettify?-->
423~~~~
424if (count > 0) {
425    ...
426}
427~~~~
428
429Comments
430
431We use doxygen-style comments.
432
433For grouping or separators in an implementation file we use 80 slashes
434
435<!--?prettify?-->
436~~~~
437void SkClassA::foo() {
438    ...
439}
440
441////////////////////////////////////////////////////////////////
442
443void SkClassB::bar() {
444    ...
445}
446~~~~
447
448Integer Types
449-------------
450
451We follow the Google C++ guide for ints and are slowly making older code conform to this
452
453(http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Integer_Types)
454
455Summary: Use int unless you have need a guarantee on the bit count, then use
456stdint.h types (int32_t, etc). Assert that counts, etc are not negative instead
457of using unsigned. Bitfields use uint32_t unless they have to be made shorter
458for packing or performance reasons.
459
460NULL, 0
461-------
462
463Use NULL for pointers, 0 for ints. We prefer explicit NULL comparisons when
464checking for NULL pointers (as documentation):
465
466<!--?prettify?-->
467~~~~
468if (NULL == x) {  // slightly preferred over if (!x)
469   ...
470}
471~~~~
472
473When checking non-NULL pointers explicit comparisons are not required because it
474reads like a double negative:
475
476<!--?prettify?-->
477~~~~
478if (x) {  // slightly preferred over if (NULL != x)
479   ...
480}
481~~~~
482
483Returning structs
484-----------------
485
486If the desired behavior is for a function to return a struct, we prefer using a
487struct as an output parameter
488
489<!--?prettify?-->
490~~~~
491void modify_foo(SkFoo* foo) {
492    // Modify foo
493}
494~~~~
495
496Then the function can be called as followed:
497
498<!--?prettify?-->
499~~~~
500SkFoo foo;
501modify_foo(&foo);
502~~~~
503
504This way, if return value optimization cannot be used there is no performance
505hit. It also means that modify_foo can actually return a boolean for whether the
506call was successful. In this case, initialization of foo can potentially be
507skipped on failure (assuming the constructor for SkFoo does no initialization).
508
509<!--?prettify?-->
510~~~~
511bool modify_foo(SkFoo* foo) {
512    if (some_condition) {
513        // Modify foo
514        return true;
515    }
516    // Leave foo unmodified
517    return false;
518}
519~~~~
520
521Function Parameters
522-------------------
523
524Mandatory constant object parameters are passed to functions as const references
525if they are not retained by the receiving function. Optional constant object
526parameters are passed to functions as const pointers. Objects that the called
527function will retain, either directly or indirectly, are passed as pointers.
528Variable (i.e. mutable) object parameters are passed to functions as pointers.
529
530<!--?prettify?-->
531~~~~
532// src and paint are optional
533void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
534                             const SkRect& dst, const SkPaint* paint = NULL);
535// metrics is mutable (it is changed by the method)
536SkScalar SkPaint::getFontMetrics(FontMetric* metrics, SkScalar scale) const;
537// A reference to foo is retained by SkContainer
538void SkContainer::insert(const SkFoo* foo);
539~~~~
540
541If function arguments or parameters do not all fit on one line, they may be
542lined up with the first parameter on the same line
543
544<!--?prettify?-->
545~~~~
546void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
547                    const SkPaint* paint = NULL) {
548    this->drawBitmapRectToRect(bitmap, NULL, dst, paint,
549                               kNone_DrawBitmapRectFlag);
550}
551~~~~
552
553or placed on the next line indented eight spaces
554
555<!--?prettify?-->
556~~~~
557void drawBitmapRect(
558        const SkBitmap& bitmap, const SkRect& dst,
559        const SkPaint* paint = NULL) {
560    this->drawBitmapRectToRect(
561            bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
562}
563~~~~
564
565Python
566------
567
568Python code follows the [Google Python Style Guide](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html).
569
570