blob: 9edf83dcdbe22ddd09e3c8ad42c8ca77b97a67ff [file] [log] [blame] [view]
Andrew Top200ce4b2018-01-29 13:43:50 -08001Coding Style Guidelines
2=======================
3
4These conventions have evolved over time. Some of the earlier code in both
Xiaoming Shi73dfa202020-03-12 11:31:35 -07005projects doesn't strictly adhere to the guidelines. However, as the code evolves
Andrew Top200ce4b2018-01-29 13:43:50 -08006we hope to make the existing code conform to the guildelines.
7
8Files
9-----
10
Xiaoming Shi73dfa202020-03-12 11:31:35 -070011We use .cpp and .h as extensions for c++ source and header files.
Andrew Top200ce4b2018-01-29 13:43:50 -080012
Xiaoming Shi73dfa202020-03-12 11:31:35 -070013Headers that aren't meant for public consumption should be placed in src
14directories so that they aren't in a client's search path, or in
15include/private if they need to be used by public headers.
Andrew Top200ce4b2018-01-29 13:43:50 -080016
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).
Xiaoming Shi73dfa202020-03-12 11:31:35 -070025Most things you'd #if on tend to not yet be decided until SkTypes.h.
Andrew Top200ce4b2018-01-29 13:43:50 -080026
Xiaoming Shi73dfa202020-03-12 11:31:35 -070027We use 4 spaces, not tabs.
Andrew Top200ce4b2018-01-29 13:43:50 -080028
29We use Unix style endlines (LF).
30
31We prefer no trailing whitespace but aren't very strict about it.
32
33We wrap lines at 100 columns unless it is excessively ugly (use your judgement).
34The soft line length limit was changed from 80 to 100 columns in June 2012. Thus,
35most files still adhere to the 80 column limit. It is not necessary or worth
36significant effort to promote 80 column wrapped files to 100 columns. Please
37don't willy-nilly insert longer lines in 80 column wrapped files. Either be
38consistent with the surrounding code or, if you really feel the need, promote
39the surrounding code to 100 column wrapping.
40
41Naming
42------
43
44Both projects use a prefix to designate that they are Skia prefix for classes,
Xiaoming Shi73dfa202020-03-12 11:31:35 -070045enums, structs, typedefs etc is Sk. Ganesh's is Gr. Nested types should not be
Andrew Top200ce4b2018-01-29 13:43:50 -080046prefixed.
47
48<!--?prettify?-->
49~~~~
50class SkClass {
51public:
52 class HelperClass {
53 ...
54 };
55};
56~~~~
57
Xiaoming Shi73dfa202020-03-12 11:31:35 -070058Data fields in structs, classes, unions begin with lowercase f and are then
Andrew Top200ce4b2018-01-29 13:43:50 -080059camel capped.
60
61<!--?prettify?-->
62~~~~
63struct GrCar {
64 ...
65 float fMilesDriven;
66 ...
67};
68~~~~
69
70Globals variables are similar but prefixed with g and camel-capped
71
72<!--?prettify?-->
73~~~~
74bool gLoggingEnabled
75Local variables begin lowercases and are camel-capped.
76
77int herdCats(const Array& cats) {
78 int numCats = cats.count();
79}
80~~~~
81
82Enum values are prefixed with k. Unscoped enum values are post fixed with
83an underscore and singular name of the enum name. The enum itself should be
84singular for exclusive values or plural for a bitfield. If a count is needed it
Xiaoming Shi73dfa202020-03-12 11:31:35 -070085is `k<singular enum name>Count` and not be a member of the enum (see example),
86or a kLast member of the enum is fine too.
Andrew Top200ce4b2018-01-29 13:43:50 -080087
88<!--?prettify?-->
89~~~~
90enum class SkPancakeType {
91 kBlueberry,
92 kPlain,
93 kChocolateChip,
94};
95~~~~
96
97<!--?prettify?-->
98~~~~
99enum SkPancakeType {
100 kBlueberry_PancakeType,
101 kPlain_PancakeType,
102 kChocolateChip_PancakeType,
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700103
Andrew Top200ce4b2018-01-29 13:43:50 -0800104 kLast_PancakeType = kChocolateChip_PancakeType
105};
106
107static const SkPancakeType kPancakeTypeCount = kLast_PancakeType + 1;
108~~~~
109
110A bitfield:
111
112<!--?prettify?-->
113~~~~
114enum SkSausageIngredientBits {
115 kFennel_SuasageIngredientBit = 0x1,
116 kBeef_SausageIngredientBit = 0x2
117};
118~~~~
119
120or:
121
122<!--?prettify?-->
123~~~~
124enum SkMatrixFlags {
125 kTranslate_MatrixFlag = 0x1,
126 kRotate_MatrixFlag = 0x2
127};
128~~~~
129
130Exception: anonymous enums can be used to declare integral constants, e.g.:
131
132<!--?prettify?-->
133~~~~
134enum { kFavoriteNumber = 7 };
135~~~~
136
137Macros are all caps with underscores between words. Macros that have greater
138than file scope should be prefixed SK or GR.
139
140Static non-class functions in implementation files are lower case with
141underscores separating words:
142
143<!--?prettify?-->
144~~~~
145static inline bool tastes_like_chicken(Food food) {
146 return kIceCream_Food != food;
147}
148~~~~
149
150Externed functions or static class functions are camel-capped with an initial cap:
151
152<!--?prettify?-->
153~~~~
154bool SkIsOdd(int n);
155
156class SkFoo {
157public:
158 static int FooInstanceCount();
159};
160~~~~
161
162Macros
163------
164
165Ganesh macros that are GL-specific should be prefixed GR_GL.
166
167<!--?prettify?-->
168~~~~
169#define GR_GL_TEXTURE0 0xdeadbeef
170~~~~
171
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700172Ganesh prefers that macros are always defined and the use of `#if MACRO` rather than
173`#ifdef MACRO`.
Andrew Top200ce4b2018-01-29 13:43:50 -0800174
175<!--?prettify?-->
176~~~~
177#define GR_GO_SLOWER 0
178...
179#if GR_GO_SLOWER
180 Sleep(1000);
181#endif
182~~~~
183
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700184Skia tends to use `#ifdef SK_MACRO` for boolean flags.
Andrew Top200ce4b2018-01-29 13:43:50 -0800185
186Braces
187------
188
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700189Open braces don't get a newline. `else` and `else if` appear on same line as
Andrew Top200ce4b2018-01-29 13:43:50 -0800190opening and closing braces unless preprocessor conditional compilation
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700191interferes. Braces are always used with `if`, `else`, `while`, `for`, and `do`.
Andrew Top200ce4b2018-01-29 13:43:50 -0800192
193<!--?prettify?-->
194~~~~
195if (...) {
196 oneOrManyLines;
197}
198
199if (...) {
200 oneOrManyLines;
201} else if (...) {
202 oneOrManyLines;
203} else {
204 oneOrManyLines;
205}
206
207for (...) {
208 oneOrManyLines;
209}
210
211while (...) {
212 oneOrManyLines;
213}
214
215void function(...) {
216 oneOrManyLines;
217}
218
219if (!error) {
220 proceed_as_usual();
221}
222#if HANDLE_ERROR
223else {
224 freak_out();
225}
226#endif
227~~~~
228
229Flow Control
230------------
231
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700232There is a space between flow control words and parentheses and between
Andrew Top200ce4b2018-01-29 13:43:50 -0800233parentheses and braces:
234
235<!--?prettify?-->
236~~~~
237while (...) {
238}
239
240do {
241} while(...);
242
243switch (...) {
244...
245}
246~~~~
247
248Cases and default in switch statements are indented from the switch.
249
250<!--?prettify?-->
251~~~~
252switch (color) {
253 case kBlue:
254 ...
255 break;
256 case kGreen:
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700257 ...
Andrew Top200ce4b2018-01-29 13:43:50 -0800258 break;
259 ...
260 default:
261 ...
262 break;
263}
264~~~~
265
266Fallthrough from one case to the next is commented unless it is trivial:
267
268<!--?prettify?-->
269~~~~
270switch (recipe) {
271 ...
272 case kCheeseOmelette_Recipe:
273 ingredients |= kCheese_Ingredient;
274 // fallthrough
275 case kPlainOmelette_Recipe:
276 ingredients |= (kEgg_Ingredient | kMilk_Ingredient);
277 break;
278 ...
279}
280~~~~
281
282When a block is needed to declare variables within a case follow this pattern:
283
284<!--?prettify?-->
285~~~~
286switch (filter) {
287 ...
288 case kGaussian_Filter: {
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700289 Bitmap srcCopy = src->makeCopy();
Andrew Top200ce4b2018-01-29 13:43:50 -0800290 ...
291 break;
292 }
293 ...
294};
295~~~~
296
297Classes
298-------
299
300Unless there is a need for forward declaring something, class declarations
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700301should be ordered `public`, `protected`, `private`. Each should be preceded by a
302newline. Within each visibility section (`public`, `private`), fields should not be
303intermixed with methods. It's nice to keep all data fields together at the end.
Andrew Top200ce4b2018-01-29 13:43:50 -0800304
305<!--?prettify?-->
306~~~~
307class SkFoo {
308
309public:
310 ...
311
312protected:
Andrew Top200ce4b2018-01-29 13:43:50 -0800313 ...
314
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700315private:
Andrew Top200ce4b2018-01-29 13:43:50 -0800316 void barHelper(...);
317 ...
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700318
319 SkBar fBar;
320 ...
Andrew Top200ce4b2018-01-29 13:43:50 -0800321};
322~~~~
323
324Subclasses should have a private typedef of their super class called INHERITED:
325
326<!--?prettify?-->
327~~~~
328class GrDillPickle : public GrPickle {
329 ...
330private:
331 typedef GrPickle INHERITED;
332};
333~~~~
334
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700335Virtual functions that are overridden in derived classes should use override,
336and the virtual keyword should be omitted.
Andrew Top200ce4b2018-01-29 13:43:50 -0800337
338<!--?prettify?-->
339~~~~
340void myVirtual() override {
341}
342~~~~
343
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700344All references to base-class implementations of a virtual function
345should be explicitly qualified:
Andrew Top200ce4b2018-01-29 13:43:50 -0800346
347<!--?prettify?-->
348~~~~
349void myVirtual() override {
350 ...
351 this->INHERITED::myVirtual();
352 ...
353}
354~~~~
355
Andrew Top200ce4b2018-01-29 13:43:50 -0800356Constructor initializers should be one per line, indented, with punctuation
357placed before the initializer. This is a fairly new rule so much of the existing
358code is non-conforming. Please fix as you go!
359
360<!--?prettify?-->
361~~~~
362GrDillPickle::GrDillPickle()
363 : GrPickle()
364 , fSize(kDefaultPickleSize) {
365 ...
366}
367~~~~
368
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700369Constructors that take one argument should almost always be explicit, with
Andrew Top200ce4b2018-01-29 13:43:50 -0800370exceptions made only for the (rare) automatic compatibility class.
371
372<!--?prettify?-->
373~~~~
374class Foo {
375 explicit Foo(int x); // Good.
376 Foo(float y); // Spooky implicit conversion from float to Foo. No no no!
377 ...
378};
379~~~~
380
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700381Method calls within method calls should be prefixed with dereference of the
Andrew Top200ce4b2018-01-29 13:43:50 -0800382'this' pointer. For example:
383
384<!--?prettify?-->
385~~~~
386this->method();
387~~~~
388
Andrew Top200ce4b2018-01-29 13:43:50 -0800389Integer Types
390-------------
391
392We follow the Google C++ guide for ints and are slowly making older code conform to this
393
394(http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Integer_Types)
395
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700396Summary: Use `int` unless you have need a guarantee on the bit count, then use
397`stdint.h` types (`int32_t`, etc). Assert that counts, etc are not negative instead
398of using unsigned. Bitfields use `uint32_t` unless they have to be made shorter
Andrew Top200ce4b2018-01-29 13:43:50 -0800399for packing or performance reasons.
400
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700401`nullptr`, 0
402------------
Andrew Top200ce4b2018-01-29 13:43:50 -0800403
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700404Use `nullptr` for pointers, 0 for ints. We suggest explicit `nullptr` comparisons when
405checking for `nullptr` pointers, as documentation:
Andrew Top200ce4b2018-01-29 13:43:50 -0800406
407<!--?prettify?-->
408~~~~
409if (nullptr == x) { // slightly preferred over if (!x)
410 ...
411}
412~~~~
413
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700414When checking non-`nullptr` pointers we think implicit comparisons read better than
415an explicit comparison's double negative:
Andrew Top200ce4b2018-01-29 13:43:50 -0800416
417<!--?prettify?-->
418~~~~
419if (x) { // slightly preferred over if (nullptr != x)
420 ...
421}
422~~~~
423
Andrew Top200ce4b2018-01-29 13:43:50 -0800424Function Parameters
425-------------------
426
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700427Mandatory constant object parameters are passed to functions as const references.
428Optional constant object parameters are passed to functions as const pointers.
429Mutable object parameters are passed to functions as pointers.
430We very rarely pass anything by non-const reference.
Andrew Top200ce4b2018-01-29 13:43:50 -0800431
432<!--?prettify?-->
433~~~~
434// src and paint are optional
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700435void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
436 const SkRect& dst, const SkPaint* paint = nullptr);
437
Andrew Top200ce4b2018-01-29 13:43:50 -0800438// metrics is mutable (it is changed by the method)
439SkScalar SkPaint::getFontMetrics(FontMetric* metrics, SkScalar scale) const;
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700440
Andrew Top200ce4b2018-01-29 13:43:50 -0800441~~~~
442
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700443If function arguments or parameters do not all fit on one line, the overflowing
444parameters may be lined up with the first parameter on the next line
Andrew Top200ce4b2018-01-29 13:43:50 -0800445
446<!--?prettify?-->
447~~~~
448void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
449 const SkPaint* paint = nullptr) {
450 this->drawBitmapRectToRect(bitmap, nullptr, dst, paint,
451 kNone_DrawBitmapRectFlag);
452}
453~~~~
454
Xiaoming Shi73dfa202020-03-12 11:31:35 -0700455or all parameters placed on the next line and indented eight spaces
Andrew Top200ce4b2018-01-29 13:43:50 -0800456
457<!--?prettify?-->
458~~~~
459void drawBitmapRect(
460 const SkBitmap& bitmap, const SkRect& dst,
461 const SkPaint* paint = nullptr) {
462 this->drawBitmapRectToRect(
463 bitmap, nullptr, dst, paint, kNone_DrawBitmapRectFlag);
464}
465~~~~
466
467Python
468------
469
470Python code follows the [Google Python Style Guide](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html).
471