1 Coding Style Guidelines
2 =======================
4 These conventions have evolved over time. Some of the earlier code in both
5 projects doesn’t strictly adhere to the guidelines. However, as the code evolves
6 we hope to make the existing code conform to the guildelines.
11 We use .cpp and .h as extensions for c++ source and header files. We use
12 foo_impl.h for headers with inline definitions for class foo.
14 Headers that aren’t meant for public consumption should be placed in src
15 directories so that they aren’t in a client’s search path.
17 We prefer to minimize includes. If forward declaring a name in a header is
18 sufficient then that is preferred to an include.
20 Forward declarations and file includes should be in alphabetical order (but we
21 aren't very strict about it).
23 <span id="no-define-before-sktypes"></span>
24 Do not use #if/#ifdef before including "SkTypes.h" (directly or indirectly).
26 We use spaces not tabs (4 of them).
28 We use Unix style endlines (LF).
30 We prefer no trailing whitespace but aren't very strict about it.
32 We wrap lines at 100 columns unless it is excessively ugly (use your judgement).
33 The soft line length limit was changed from 80 to 100 columns in June 2012. Thus,
34 most files still adhere to the 80 column limit. It is not necessary or worth
35 significant effort to promote 80 column wrapped files to 100 columns. Please
36 don't willy-nilly insert longer lines in 80 column wrapped files. Either be
37 consistent with the surrounding code or, if you really feel the need, promote
38 the surrounding code to 100 column wrapping.
43 Both projects use a prefix to designate that they are Skia prefix for classes,
44 enums, structs, typedefs etc is Sk. Ganesh’s is Gr. Nested types should not be
57 Data fields in structs, classes, unions begin with lowercase f and are then
69 Globals variables are similar but prefixed with g and camel-capped
74 Local variables begin lowercases and are camel-capped.
76 int herdCats(const Array& cats) {
77 int numCats = cats.count();
81 Enum values are prefixed with k and have post fix that consists of an underscore
82 and singular name of the enum name. The enum itself should be singular for
83 exclusive values or plural for a bitfield. If a count is needed it is
84 k<singular enum name>Count and not be a member of the enum (see example):
89 kBlueberry_PancakeType,
91 kChocolateChip_PancakeType,
93 kLast_PancakeType = kChocolateChip_PancakeType
96 static const SkPancakeType kPancakeTypeCount = kLast_PancakeType + 1;
103 enum SkSausageIngredientBits {
104 kFennel_SuasageIngredientBit = 0x1,
105 kBeef_SausageIngredientBit = 0x2
114 kTranslate_MatrixFlag = 0x1,
115 kRotate_MatrixFlag = 0x2
119 Exception: anonymous enums can be used to declare integral constants, e.g.:
123 enum { kFavoriteNumber = 7 };
126 Macros are all caps with underscores between words. Macros that have greater
127 than file scope should be prefixed SK or GR.
129 Static non-class functions in implementation files are lower case with
130 underscores separating words:
134 static inline bool tastes_like_chicken(Food food) {
135 return kIceCream_Food != food;
139 Externed functions or static class functions are camel-capped with an initial cap:
147 static int FooInstanceCount();
154 Ganesh macros that are GL-specific should be prefixed GR_GL.
158 #define GR_GL_TEXTURE0 0xdeadbeef
161 Ganesh prefers that macros are always defined and the use of #if MACRO rather than
166 #define GR_GO_SLOWER 0
173 Skia tends to use #ifdef SK_MACRO for boolean flags.
178 Open braces don’t get a newline. “else” and “else if” appear on same line as
179 opening and closing braces unless preprocessor conditional compilation
180 interferes. Braces are always used with if, else, while, for, and do.
221 There is a space between flow control words and parentheses and between
222 parentheses and braces:
237 Cases and default in switch statements are indented from the switch.
255 Fallthrough from one case to the next is commented unless it is trivial:
261 case kCheeseOmelette_Recipe:
262 ingredients |= kCheese_Ingredient;
264 case kPlainOmelette_Recipe:
265 ingredients |= (kEgg_Ingredient | kMilk_Ingredient);
271 When a block is needed to declare variables within a case follow this pattern:
277 case kGaussian_Filter: {
278 Bitmap srcCopy = src->makeCopy();
289 Unless there is a need for forward declaring something, class declarations
290 should be ordered public, protected, private. Each should be preceded by a
291 newline. Within each visibility section (public, private), fields should not be
292 intermixed with methods.
313 Subclasses should have a private typedef of their super class called INHERITED:
317 class GrDillPickle : public GrPickle {
320 typedef GrPickle INHERITED;
324 Virtual functions that are overridden in derived classes should use override
325 (and not the override keyword). The virtual keyword can be omitted.
329 void myVirtual() override {
333 This should be the last element of their private section, and all references to
334 base-class implementations of a virtual function should be explicitly qualified:
338 void myVirtual() override {
340 this->INHERITED::myVirtual();
345 As in the above example, derived classes that redefine virtual functions should
346 use override to note that explicitly.
348 Constructor initializers should be one per line, indented, with punctuation
349 placed before the initializer. This is a fairly new rule so much of the existing
350 code is non-conforming. Please fix as you go!
354 GrDillPickle::GrDillPickle()
356 , fSize(kDefaultPickleSize) {
361 Constructors that take one argument should almost always be explicit, with
362 exceptions made only for the (rare) automatic compatibility class.
367 explicit Foo(int x); // Good.
368 Foo(float y); // Spooky implicit conversion from float to Foo. No no no!
373 Method calls within method calls should be prefixed with dereference of the
374 'this' pointer. For example:
382 All memory allocation should be routed through SkNEW and its variants. These are
383 #defined in SkPostConfig.h, but the correct way to get access to the config
384 system is to #include SkTypes.h, which will allow external users of the library
385 to provide a custom memory manager or other adaptations.
390 SkNEW_ARGS(type_name, args)
391 SkNEW_ARRAY(type_name, count)
392 SkNEW_PLACEMENT(buf, type_name)
393 SkNEW_PLACEMENT_ARGS(buf, type_name, args)
395 SkDELETE_ARRAY(array)
401 We prefer that equality operators between lvalues and rvalues place the lvalue
406 if (7 == luckyNumber) {
411 However, inequality operators need not follow this rule:
422 We use doxygen-style comments.
424 For grouping or separators in an implementation file we use 80 slashes
428 void SkClassA::foo() {
432 ////////////////////////////////////////////////////////////////
434 void SkClassB::bar() {
442 We follow the Google C++ guide for ints and are slowly making older code conform to this
444 (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Integer_Types)
446 Summary: Use int unless you have need a guarantee on the bit count, then use
447 stdint.h types (int32_t, etc). Assert that counts, etc are not negative instead
448 of using unsigned. Bitfields use uint32_t unless they have to be made shorter
449 for packing or performance reasons.
454 Use NULL for pointers, 0 for ints. We prefer explicit NULL comparisons when
455 checking for NULL pointers (as documentation):
459 if (NULL == x) { // slightly preferred over if (!x)
464 When checking non-NULL pointers explicit comparisons are not required because it
465 reads like a double negative:
469 if (x) { // slightly preferred over if (NULL != x)
477 If the desired behavior is for a function to return a struct, we prefer using a
478 struct as an output parameter
482 void modify_foo(SkFoo* foo) {
487 Then the function can be called as followed:
495 This way, if return value optimization cannot be used there is no performance
496 hit. It also means that modify_foo can actually return a boolean for whether the
497 call was successful. In this case, initialization of foo can potentially be
498 skipped on failure (assuming the constructor for SkFoo does no initialization).
502 bool modify_foo(SkFoo* foo) {
503 if (some_condition) {
507 // Leave foo unmodified
515 Mandatory constant object parameters are passed to functions as const references
516 if they are not retained by the receiving function. Optional constant object
517 parameters are passed to functions as const pointers. Objects that the called
518 function will retain, either directly or indirectly, are passed as pointers.
519 Variable (i.e. mutable) object parameters are passed to functions as pointers.
523 // src and paint are optional
524 void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
525 const SkRect& dst, const SkPaint* paint = NULL);
526 // metrics is mutable (it is changed by the method)
527 SkScalar SkPaint::getFontMetrics(FontMetric* metrics, SkScalar scale) const;
528 // A reference to foo is retained by SkContainer
529 void SkContainer::insert(const SkFoo* foo);
532 If function arguments or parameters do not all fit on one line, they may be
533 lined up with the first parameter on the same line
537 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
538 const SkPaint* paint = NULL) {
539 this->drawBitmapRectToRect(bitmap, NULL, dst, paint,
540 kNone_DrawBitmapRectFlag);
544 or placed on the next line indented eight spaces
549 const SkBitmap& bitmap, const SkRect& dst,
550 const SkPaint* paint = NULL) {
551 this->drawBitmapRectToRect(
552 bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
559 Python code follows the [Google Python Style Guide](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html).