• 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();
388~~~~
389
390Comparisons
391-----------
392
393We prefer that equality operators between lvalues and rvalues place the lvalue
394on the right:
395
396<!--?prettify?-->
397~~~~
398if (7 == luckyNumber) {
399    ...
400}
401~~~~
402
403However, inequality operators need not follow this rule:
404
405<!--?prettify?-->
406~~~~
407if (count > 0) {
408    ...
409}
410~~~~
411
412Comments
413
414We use doxygen-style comments.
415
416For grouping or separators in an implementation file we use 80 slashes
417
418<!--?prettify?-->
419~~~~
420void SkClassA::foo() {
421    ...
422}
423
424////////////////////////////////////////////////////////////////
425
426void SkClassB::bar() {
427    ...
428}
429~~~~
430
431Integer Types
432-------------
433
434We follow the Google C++ guide for ints and are slowly making older code conform to this
435
436(http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Integer_Types)
437
438Summary: Use int unless you have need a guarantee on the bit count, then use
439stdint.h types (int32_t, etc). Assert that counts, etc are not negative instead
440of using unsigned. Bitfields use uint32_t unless they have to be made shorter
441for packing or performance reasons.
442
443nullptr, 0
444-------
445
446Use nullptr for pointers, 0 for ints. We prefer explicit nullptr comparisons when
447checking for nullptr pointers (as documentation):
448
449<!--?prettify?-->
450~~~~
451if (nullptr == x) {  // slightly preferred over if (!x)
452   ...
453}
454~~~~
455
456When checking non-nullptr pointers explicit comparisons are not required because it
457reads like a double negative:
458
459<!--?prettify?-->
460~~~~
461if (x) {  // slightly preferred over if (nullptr != x)
462   ...
463}
464~~~~
465
466Returning structs
467-----------------
468
469If the desired behavior is for a function to return a struct, we prefer using a
470struct as an output parameter
471
472<!--?prettify?-->
473~~~~
474void modify_foo(SkFoo* foo) {
475    // Modify foo
476}
477~~~~
478
479Then the function can be called as followed:
480
481<!--?prettify?-->
482~~~~
483SkFoo foo;
484modify_foo(&foo);
485~~~~
486
487This way, if return value optimization cannot be used there is no performance
488hit. It also means that modify_foo can actually return a boolean for whether the
489call was successful. In this case, initialization of foo can potentially be
490skipped on failure (assuming the constructor for SkFoo does no initialization).
491
492<!--?prettify?-->
493~~~~
494bool modify_foo(SkFoo* foo) {
495    if (some_condition) {
496        // Modify foo
497        return true;
498    }
499    // Leave foo unmodified
500    return false;
501}
502~~~~
503
504Function Parameters
505-------------------
506
507Mandatory constant object parameters are passed to functions as const references
508if they are not retained by the receiving function. Optional constant object
509parameters are passed to functions as const pointers. Objects that the called
510function will retain, either directly or indirectly, are passed as pointers.
511Variable (i.e. mutable) object parameters are passed to functions as pointers.
512
513<!--?prettify?-->
514~~~~
515// src and paint are optional
516void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
517                             const SkRect& dst, const SkPaint* paint = nullptr);
518// metrics is mutable (it is changed by the method)
519SkScalar SkPaint::getFontMetrics(FontMetric* metrics, SkScalar scale) const;
520// A reference to foo is retained by SkContainer
521void SkContainer::insert(const SkFoo* foo);
522~~~~
523
524If function arguments or parameters do not all fit on one line, they may be
525lined up with the first parameter on the same line
526
527<!--?prettify?-->
528~~~~
529void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
530                    const SkPaint* paint = nullptr) {
531    this->drawBitmapRectToRect(bitmap, nullptr, dst, paint,
532                               kNone_DrawBitmapRectFlag);
533}
534~~~~
535
536or placed on the next line indented eight spaces
537
538<!--?prettify?-->
539~~~~
540void drawBitmapRect(
541        const SkBitmap& bitmap, const SkRect& dst,
542        const SkPaint* paint = nullptr) {
543    this->drawBitmapRectToRect(
544            bitmap, nullptr, dst, paint, kNone_DrawBitmapRectFlag);
545}
546~~~~
547
548Python
549------
550
551Python code follows the [Google Python Style Guide](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html).
552
553