General clean up on bookmaker.

Command line runs without error for
SkBitmap, SkPath, SkRect, SkIRect,
SkPixmap, SkCanvas.

Docs-Preview: https://skia.org/?cl=57112
TBR: caryclark@google.com
Bug: skia:6898
Change-Id: I73b69ae8ffdf0a1e6bc187dc8a9dfb28f7766faa
Reviewed-on: https://skia-review.googlesource.com/57112
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/docs/SkBitmap_Reference.bmh b/docs/SkBitmap_Reference.bmh
index 35f4de6..2758023 100644
--- a/docs/SkBitmap_Reference.bmh
+++ b/docs/SkBitmap_Reference.bmh
@@ -223,6 +223,7 @@
         SkDebugf("pixel address = %p\n", bitmap.getPixels());
     }
 #StdOut
+#Volatile
 pixel address = (nil)
 pixel address = 0x560ddd0ac670
 ##
diff --git a/docs/SkCanvas_Reference.bmh b/docs/SkCanvas_Reference.bmh
index 3e73691..486fe46 100644
--- a/docs/SkCanvas_Reference.bmh
+++ b/docs/SkCanvas_Reference.bmh
@@ -6104,4 +6104,55 @@
 ##
 
 #Class SkCanvas ##
+
+#Class SkAutoCanvasRestore
+
+Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
+goes out of scope. Use this to guarantee that the canvas is restored to a known
+state.
+
+#Method SkAutoCanvasRestore(SkCanvas* canvas, bool doSave)
+
+Preserves Canvas save count. Optionally saves Canvas Clip and Matrix.
+
+#Param canvas  Canvas to guard ##
+#Param doSave  call SkCanvas::save() ##
+
+#Return utility to restore Canvas state on destructor ##
+
+#Example
+// incomplete
+##
+
+#SeeAlso SkCanvas::save SkCanvas::restore
+
+##
+
+#Method ~SkAutoCanvasRestore()
+
+Restores Canvas to saved state.
+
+#Example
+// incomplete
+##
+
+#SeeAlso SkCanvas::save SkCanvas::restore
+
+##
+
+#Method void restore()
+
+Restores Canvas to saved state immediately. Subsequent calls and class 
+destructor have no effect.
+
+#Example
+// incomplete
+##
+
+#SeeAlso SkCanvas::save SkCanvas::restore
+
+##
+
+#Class SkAutoCanvasRestore ##
+
 #Topic Canvas ##
diff --git a/docs/SkIRect_Reference.bmh b/docs/SkIRect_Reference.bmh
index 0a9ddf8..d92c087 100644
--- a/docs/SkIRect_Reference.bmh
+++ b/docs/SkIRect_Reference.bmh
@@ -23,10 +23,10 @@
 #Subtopic Operators
 #Table
 #Legend
-# description                                                # function ##
+# description                                         # function ##
 #Legend ##
-# friend bool operator!=(const SkIRect& a, const SkIRect& b) # Returns true if members are unequal. ##
-# friend bool operator==(const SkIRect& a, const SkIRect& b) # Returns true if members are equal. ##
+# bool operator!=(const SkIRect& a, const SkIRect& b) # Returns true if members are unequal. ##
+# bool operator==(const SkIRect& a, const SkIRect& b) # Returns true if members are equal. ##
 #Table ##
 #Subtopic ##
 
@@ -106,7 +106,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkIRect SK_WARN_UNUSED_RESULT MakeEmpty()
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeEmpty()
 
 Returns constructed IRect set to (0, 0, 0, 0).
 Many other rectangles are empty; if left is equal to or greater than right,
@@ -166,7 +166,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h)
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h)
 
 Returns constructed IRect set to (0, 0, w, h). Does not validate input; w or h
 may be negative.
@@ -194,7 +194,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size)
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size)
 
 Returns constructed IRect set to (0, 0, size.width(), size.height()). 
 Does not validate input; size.width() or size.height() may be negative.
@@ -221,7 +221,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
 
 Returns constructed IRect set to (l, t, r, b). Does not sort input; Rect may
 result in fLeft greater than fRight, or fTop greater than fBottom.
@@ -252,7 +252,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
+#Method static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
 
 Returns constructed IRect set to
 #Formula
@@ -266,7 +266,7 @@
 #Param w  added to x and stored in fRight ##
 #Param h  added to y and stored in fBottom ##
 
-#Return bounds (x, y, x + w, y + h) ##
+#Return bounds at (x, y) with width w and height h ##
 
 #Example
     SkIRect rect = SkIRect::MakeXYWH(5, 35, -15, 25);

@@ -627,7 +627,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method friend bool operator==(const SkIRect& a, const SkIRect& b)
+#Method bool operator==(const SkIRect& a, const SkIRect& b)
 
 Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are 
 identical to corresponding members in b.
@@ -652,7 +652,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method friend bool operator!=(const SkIRect& a, const SkIRect& b)
+#Method bool operator!=(const SkIRect& a, const SkIRect& b)
 
 Returns true if any member in a: fLeft, fTop, fRight, and fBottom; is not 
 identical to the corresponding member in b.
diff --git a/docs/SkMatrix_Reference.bmh b/docs/SkMatrix_Reference.bmh
index db7e7c3..0db0fa8 100644
--- a/docs/SkMatrix_Reference.bmh
+++ b/docs/SkMatrix_Reference.bmh
@@ -3,10 +3,13 @@
 
 #Class SkMatrix
 
-The SkMatrix class holds a 3x3 matrix for transforming coordinates.
+Matrix holds a 3x3 matrix for transforming coordinates.
+Matrix elements are in column major order.
+
 SkMatrix does not have a constructor, so it must be explicitly initialized
 using either reset() - to construct an identity matrix, or one of the set
 functions (e.g. setTranslate, setRotate, etc.).
+
 SkMatrix is not thread safe unless getType is called first.
 
 #Topic Overview
@@ -25,8 +28,10 @@
 #Legend
 # description                                                         # function ##
 #Legend ##
-# friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) # ##
-# friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b) # ##
+# friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) # Returns true if members are unequal. ##
+# friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b) # Returns true if members are equal. ##
+# SkScalar operator[](int index) const # Returns one of nine Matrix values. ##
+# SkScalar& operator[](int index) # Returns a writable reference to one of nine Matrix values. ##
 #Table ##
 #Subtopic ##
 
@@ -35,46 +40,45 @@
 #Legend
 # description            # function ##
 #Legend ##
-# Concat                 # ##
-# GetMapPtsProc          # ##
-# GetMapXYProc           # ##
-# I                      # ##
-# InvalidMatrix          # ##
-# MakeRectToRect         # ##
-# MakeScale              # ##
-# MakeTrans              # ##
-# SetAffineIdentity      # ##
-# [                      # ##
-# asAffine               # ##
-# cheapEqualTo           # ##
-# decomposeScale         # ##
-# dirtyMatrixTypeCache   # ##
-# dump                   # ##
-# fixedStepInX           # ##
-# get                    # ##
-# get9                   # ##
-# getMapPtsProc          # ##
-# getMapXYProc           # ##
-# getMaxScale            # ##
-# getMinMaxScales        # ##
-# getMinScale            # ##
-# getPerspX              # ##
-# getPerspY              # ##
-# getScaleX              # ##
-# getScaleY              # ##
-# getSkewX               # ##
-# getSkewY               # ##
-# getTranslateX          # ##
-# getTranslateY          # ##
-# getType                # ##
-# hasPerspective         # ##
-# invert                 # ##
-# isFinite               # ##
-# isFixedStepInX         # ##
-# isIdentity             # ##
-# isScaleTranslate       # ##
-# isSimilarity           # ##
-# isTranslate            # ##
+# Concat                 # Returns the concatenation of Matrix pair. ##
+# GetMapPtsProc          # Returns optimal function to map Point array. ##
+# GetMapXYProc           # Returns optimal function to map one Point. ##
+# I                      # Returns a reference to a const identity Matrix. ##
+# InvalidMatrix          # Returns a reference to a const invalid Matrix. ##
+# MakeRectToRect         # Constructs from source Rect to destination Rect. ##
+# MakeScale              # Constructs from scale in x and y. ##
+# MakeTrans              # Constructs from translate in x and y. ##
+# SetAffineIdentity      # Sets 2x3 array to identity. ##
+# asAffine               # Copies to 2x3 array. ##
+# cheapEqualTo           # Compares Matrix pair using memcmp(). ##
+# decomposeScale         # Separates scale if possible. ##
+# dirtyMatrixTypeCache   # Private; used by testing. ##
+# dump                   # Sends text representation using floats to standard output. ##
+# fixedStepInX           # Returns step in x for a position in y. ##
+# get                    # Returns one of nine Matrix values. ##
+# get9                   # Returns all nine Matrix values. ##
+# getMapPtsProc          # Returns optimal function to map Point array. ##
+# getMapXYProc           # Returns optimal function to map one Point. ##
+# getMaxScale            # Returns maximum scaling, if possible. ##
+# getMinMaxScales        # Returns minimum and maximum scaling, if possible. ##
+# getMinScale            # Returns minimum scaling, if possible. ##
+# getPerspX              # Returns horizontal perspective factor. ##
+# getPerspY              # Returns vertical perspective factor. ##
+# getScaleX              # Returns horizontal scale factor. ##
+# getScaleY              # Returns vertical scale factor.##
+# getSkewX               # Returns horizontal skew factor. ##
+# getSkewY               # Returns vertical skew factor. ##
+# getTranslateX          # Returns horizontal translation factor. ##
+# getTranslateY          # Returns vertical translation factor. ##
+# getType                # Returns transform complexity. ##
+# hasPerspective         # Returns if transform includes perspective. ##
+# invert                 # Returns inverse, if possible. ##
+# isFinite               # Returns if all Matrix values are not infinity, NaN. ##
+# isFixedStepInX         # Returns if transformation supports fixed step in x. ##
+# isIdentity             # Returns if matrix equals the identity Matrix .##
+# isScaleTranslate       # Returns if transform is limited to scale and translate. ##
+# isSimilarity           # Returns if transform is limited to square scale and rotation. ##
+# isTranslate            # Returns if transform is limited to translate. ##
 # mapHomogeneousPoints   # ##
 # mapPoints              # ##
 # mapPointsWithStride    # ##
diff --git a/docs/SkPath_Reference.bmh b/docs/SkPath_Reference.bmh
index 8eb0077..e38b30d 100644
--- a/docs/SkPath_Reference.bmh
+++ b/docs/SkPath_Reference.bmh
@@ -1025,7 +1025,7 @@
 #Enum Convexity
 
 #Code
-    enum Convexity {
+    enum Convexity : uint8_t {
         kUnknown_Convexity, 
         kConvex_Convexity,
         kConcave_Convexity, 
diff --git a/docs/SkRect_Reference.bmh b/docs/SkRect_Reference.bmh
index 57f3ec6..7dc1e37 100644
--- a/docs/SkRect_Reference.bmh
+++ b/docs/SkRect_Reference.bmh
@@ -28,10 +28,10 @@
 #Subtopic Operators
 #Table
 #Legend
-# description                                              # function ##
+# description                                       # function ##
 #Legend ##
-# friend bool operator!=(const SkRect& a, const SkRect& b) # Returns true if member bits are unequal. ##
-# friend bool operator==(const SkRect& a, const SkRect& b) # Returns true if member bits are equal. ##
+# bool operator!=(const SkRect& a, const SkRect& b) # Returns true if member bits are unequal. ##
+# bool operator==(const SkRect& a, const SkRect& b) # Returns true if member bits are equal. ##
 #Table ##
 #Subtopic ##
 
@@ -47,6 +47,7 @@
 # MakeIWH               # Constructs from int input returning (0, 0, width, height). ##
 # MakeLTRB              # Constructs from SkScalar left, top, right, bottom. ##
 # MakeLargest           # Constructs (SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax). ##
+# MakeLargestS32        # Constructs largest signed integers that fit in 32-bit float. ##
 # MakeSize              # Constructs from Size returning (0, 0, width, height). ##
 # MakeWH                # Constructs from SkScalar input returning (0, 0, width, height). ##
 # MakeXYWH              # Constructs from SkScalar input returning (x, y, width, height). ##
@@ -184,13 +185,42 @@
 ##

 ##
 
-#SeeAlso isLargest setLargest SkIRect::MakeLargest
+#SeeAlso MakeLargestS32 isLargest setLargest SkIRect::MakeLargest
 
 ##
 
 # ------------------------------------------------------------------------------
 
-#Method static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h)
+#Method static SkRect SK_WARN_UNUSED_RESULT MakeLargestS32()
+
+Returns constructed Rect that can be represented exactly with IRect. The left
+and top are set to the most negative integer value that fits in a 32-bit float,
+and the right and bottom are set to the most positive finite value that fits in
+a 32-bit float.
+
+These are the largest values for which round() is well defined.
+
+#Return bounds (SK_MinS32FitsInFloat, SK_MinS32FitsInFloat,
+                SK_MaxS32FitsInFloat, SK_MaxS32FitsInFloat)
+##
+
+#Example
+    SkRect f_rect = SkRect::MakeLargestS32();

+    SkIRect i_rect = f_rect.round();

+    SkRect r_rect = SkRect::Make(i_rect);

+    SkDebugf("f_rect %c= r_rect\n", f_rect == r_rect ? '=' : '!');

+#StdOut

+f_rect == r_rect

+##

+##
+
+#SeeAlso MakeLargest isLargest setLargest SkIRect::MakeLargest
+
+##
+
+# ------------------------------------------------------------------------------
+
+#Method static constexpr SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h)
 
 Returns constructed Rect set to SkScalar values (0, 0, w, h). Does not
 validate input; w or h may be negative.
@@ -253,7 +283,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size)
+#Method static constexpr SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size)
 
 Returns constructed Rect set to (0, 0, size.width(), size.height()). Does not
 validate input; size.width() or size.height() may be negative.
@@ -313,7 +343,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h)
+#Method static constexpr SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h)
 
 Returns constructed Rect set to
 #Formula
@@ -327,7 +357,7 @@
 #Param w  added to x and stored in fRight ##
 #Param h  added to y and stored in fBottom ##
 
-#Return bounds (x, y, x + w, y + h) ##
+#Return bounds at (x, y) with width w and height h ##
 
 #Example
     SkRect rect = SkRect::MakeXYWH(5, 35, -15, 25);

@@ -784,7 +814,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method friend bool operator==(const SkRect& a, const SkRect& b)
+#Method bool operator==(const SkRect& a, const SkRect& b)
 
 Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are  
 equal to the corresponding members in b.
@@ -827,7 +857,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method friend bool operator!=(const SkRect& a, const SkRect& b)
+#Method bool operator!=(const SkRect& a, const SkRect& b)
 
 Returns true if any in a: fLeft, fTop, fRight, and fBottom; does not   
 equal the corresponding members in b.
@@ -1962,7 +1992,7 @@
 
 # ------------------------------------------------------------------------------
 
-#Method    bool contains(const SkRect& r) const {
+#Method    bool contains(const SkRect& r) const
 
 Returns true if Rect contains r.
 Returns false if Rect is empty or r is empty.
diff --git a/docs/undocumented.bmh b/docs/undocumented.bmh
index d6a77b9..0239034 100644
--- a/docs/undocumented.bmh
+++ b/docs/undocumented.bmh
@@ -443,6 +443,12 @@
     #Typedef SkScalar
     #Typedef ##
     ##
+    #Const SK_MinS32FitsInFloat
+    to be written
+    ##
+    #Const SK_MaxS32FitsInFloat
+    to be written
+    ##
     #Const SK_ScalarMin
     to be written
     ##
diff --git a/site/user/api/SkBitmap_Reference.md b/site/user/api/SkBitmap_Reference.md
index 076ceba..abff9ff 100644
--- a/site/user/api/SkBitmap_Reference.md
+++ b/site/user/api/SkBitmap_Reference.md
@@ -211,6 +211,7 @@
 #### Example Output
 
 ~~~~
+#Volatile
 pixel address = (nil)
 pixel address = 0x560ddd0ac670
 ~~~~
diff --git a/site/user/api/SkCanvas_Reference.md b/site/user/api/SkCanvas_Reference.md
index 1c5d804..8d39ac4 100644
--- a/site/user/api/SkCanvas_Reference.md
+++ b/site/user/api/SkCanvas_Reference.md
@@ -5245,3 +5245,77 @@
 
 ---
 
+# <a name="SkAutoCanvasRestore"></a> Class SkAutoCanvasRestore
+Stack helper class calls
+
+<a name="SkAutoCanvasRestore_SkCanvas_star"></a>
+## SkAutoCanvasRestore
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+SkAutoCanvasRestore(SkCanvas* canvas, bool doSave)
+</pre>
+
+Preserves <a href="#Canvas">Canvas</a> save count. Optionally saves <a href="#Canvas">Canvas</a> <a href="#Clip">Clip</a> and <a href="#Matrix">Matrix</a>.
+
+### Parameters
+
+<table>  <tr>    <td><a name="SkAutoCanvasRestore_SkCanvas_star_canvas"> <code><strong>canvas </strong></code> </a></td> <td>
+<a href="#Canvas">Canvas</a> to guard</td>
+  </tr>  <tr>    <td><a name="SkAutoCanvasRestore_SkCanvas_star_doSave"> <code><strong>doSave </strong></code> </a></td> <td>
+call <a href="#SkCanvas_save">SkCanvas::save()</a></td>
+  </tr>
+</table>
+
+### Return Value
+
+utility to <a href="#SkAutoCanvasRestore_restore">restore</a> <a href="#Canvas">Canvas</a> state on destructor
+
+### Example
+
+<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkCanvas_save">SkCanvas::save</a> <a href="#SkCanvas_restore">SkCanvas::restore</a>
+
+---
+
+<a name="SkAutoCanvasRestore_destructor"></a>
+## ~SkAutoCanvasRestore
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+~SkAutoCanvasRestore()
+</pre>
+
+Restores <a href="#Canvas">Canvas</a> to saved state.
+
+### Example
+
+<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkCanvas_save">SkCanvas::save</a> <a href="#SkCanvas_restore">SkCanvas::restore</a>
+
+---
+
+<a name="SkAutoCanvasRestore_restore"></a>
+## restore
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+void restore()
+</pre>
+
+Restores <a href="#Canvas">Canvas</a> to saved state immediately. Subsequent calls and class 
+destructor have no effect.
+
+### Example
+
+<div><fiddle-embed name="882e8e0103048009a25cfc20400492f7"></fiddle-embed></div>
+
+### See Also
+
+<a href="#SkCanvas_save">SkCanvas::save</a> <a href="#SkCanvas_restore">SkCanvas::restore</a>
+
+---
+
diff --git a/site/user/api/SkIRect_Reference.md b/site/user/api/SkIRect_Reference.md
index c7c6431..1982c50 100644
--- a/site/user/api/SkIRect_Reference.md
+++ b/site/user/api/SkIRect_Reference.md
@@ -21,8 +21,8 @@
 
 | description | function |
 | --- | ---  |
-| friend bool <a href="#SkIRect_not_equal_operator">operator!=(const SkIRect& a, const SkIRect& b)</a> | Returns true if members are unequal. |
-| friend bool <a href="#SkIRect_equal_operator">operator==(const SkIRect& a, const SkIRect& b)</a> | Returns true if members are equal. |
+| bool <a href="#SkIRect_not_equal_operator">operator!=(const SkIRect& a, const SkIRect& b)</a> | Returns true if members are unequal. |
+| bool <a href="#SkIRect_equal_operator">operator==(const SkIRect& a, const SkIRect& b)</a> | Returns true if members are equal. |
 
 ## <a name="Member_Functions"></a> Member Functions
 
@@ -97,7 +97,7 @@
 ## MakeEmpty
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkIRect SK_WARN_UNUSED_RESULT MakeEmpty()
+static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeEmpty()
 </pre>
 
 Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to (0, 0, 0, 0).
@@ -169,7 +169,7 @@
 ## MakeWH
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h)
+static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h)
 </pre>
 
 Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to (0, 0, <a href="#SkIRect_MakeWH_w">w</a>, <a href="#SkIRect_MakeWH_h">h</a>). Does not validate input; <a href="#SkIRect_MakeWH_w">w</a> or <a href="#SkIRect_MakeWH_h">h</a>
@@ -210,7 +210,7 @@
 ## MakeSize
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size)
+static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size)
 </pre>
 
 Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to (0, 0, <a href="#SkIRect_size">size</a>.<a href="#SkIRect_width">width</a>, <a href="#SkIRect_size">size</a>.<a href="#SkIRect_height">height</a>). 
@@ -250,8 +250,8 @@
 ## MakeLTRB
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r,
-                                              int32_t b)
+static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t,
+                                                        int32_t r, int32_t b)
 </pre>
 
 Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to (<a href="#SkIRect_MakeLTRB_l">l</a>, <a href="#SkIRect_MakeLTRB_t">t</a>, <a href="#SkIRect_MakeLTRB_r">r</a>, <a href="#SkIRect_MakeLTRB_b">b</a>). Does not <a href="#SkIRect_sort">sort</a> input; <a href="SkRect_Reference#Rect">Rect</a> may
@@ -297,8 +297,8 @@
 ## MakeXYWH
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w,
-                                              int32_t h)
+static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y,
+                                                        int32_t w, int32_t h)
 </pre>
 
 Returns constructed <a href="#IRect">IRect</a> <a href="#SkIRect_set">set</a> to(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_MakeXYWH_w">w</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_MakeXYWH_h">h</a>). 
@@ -320,7 +320,7 @@
 
 ### Return Value
 
-bounds (<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_MakeXYWH_w">w</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_MakeXYWH_h">h</a>)
+bounds at (<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>) with <a href="#SkIRect_width">width</a> <a href="#SkIRect_MakeXYWH_w">w</a> and <a href="#SkIRect_height">height</a> <a href="#SkIRect_MakeXYWH_h">h</a>
 
 ### Example
 
@@ -783,7 +783,7 @@
 ## operator==
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-friend bool operator==(const SkIRect& a, const SkIRect& b)
+bool operator==(const SkIRect& a, const SkIRect& b)
 </pre>
 
 Returns true if all members in <a href="#SkIRect_equal_operator_a">a</a>: <a href="#SkIRect_fLeft">fLeft</a>, <a href="#SkIRect_fTop">fTop</a>, <a href="#SkIRect_fRight">fRight</a>, and <a href="#SkIRect_fBottom">fBottom</a>; are 
@@ -824,7 +824,7 @@
 ## operator!=
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-friend bool operator!=(const SkIRect& a, const SkIRect& b)
+bool operator!=(const SkIRect& a, const SkIRect& b)
 </pre>
 
 Returns true if any member in <a href="#SkIRect_not_equal_operator_a">a</a>: <a href="#SkIRect_fLeft">fLeft</a>, <a href="#SkIRect_fTop">fTop</a>, <a href="#SkIRect_fRight">fRight</a>, and <a href="#SkIRect_fBottom">fBottom</a>; is not 
@@ -1019,9 +1019,9 @@
 void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
 </pre>
 
-Sets <a href="#IRect">IRect</a> to(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + w, <a href="#SkIRect_y">y</a> + h). 
+Sets <a href="#IRect">IRect</a> to(<a href="#SkIRect_x">x</a>, <a href="#SkIRect_y">y</a>, <a href="#SkIRect_x">x</a> + <a href="#SkIRect_width">width</a>, <a href="#SkIRect_y">y</a> + <a href="#SkIRect_height">height</a>). 
 Does not validate input;
-w or h may be negative.
+<a href="#SkIRect_width">width</a> or <a href="#SkIRect_height">height</a> may be negative.
 
 ### Parameters
 
@@ -1174,7 +1174,7 @@
 
 ### Return Value
 
-<a href="SkRect_Reference#Rect">Rect</a> <a href="#SkIRect_inset">inset</a> symetrically <a href="#SkIRect_left">left</a> and <a href="#SkIRect_right">right</a>, <a href="#SkIRect_top">top</a> and <a href="#SkIRect_bottom">bottom</a>
+<a href="SkRect_Reference#Rect">Rect</a> <a href="#SkIRect_inset">inset</a> symmetrically <a href="#SkIRect_left">left</a> and <a href="#SkIRect_right">right</a>, <a href="#SkIRect_top">top</a> and <a href="#SkIRect_bottom">bottom</a>
 
 ### Example
 
@@ -1220,7 +1220,7 @@
 
 ### Return Value
 
-<a href="SkRect_Reference#Rect">Rect</a> <a href="#SkIRect_outset">outset</a> symetrically <a href="#SkIRect_left">left</a> and <a href="#SkIRect_right">right</a>, <a href="#SkIRect_top">top</a> and <a href="#SkIRect_bottom">bottom</a>
+<a href="SkRect_Reference#Rect">Rect</a> <a href="#SkIRect_outset">outset</a> symmetrically <a href="#SkIRect_left">left</a> and <a href="#SkIRect_right">right</a>, <a href="#SkIRect_top">top</a> and <a href="#SkIRect_bottom">bottom</a>
 
 ### Example
 
diff --git a/site/user/api/SkPath_Reference.md b/site/user/api/SkPath_Reference.md
index 791dc17..bb3634e 100644
--- a/site/user/api/SkPath_Reference.md
+++ b/site/user/api/SkPath_Reference.md
@@ -843,7 +843,7 @@
 ## <a name="SkPath_Convexity"></a> Enum SkPath::Convexity
 
 <pre style="padding: 1em 1em 1em 1em;width: 44em; background-color: #f0f0f0">
-enum <a href="#Convexity">Convexity</a> {
+enum <a href="#Convexity">Convexity</a> : uint8_t {
 <a href="#SkPath_kUnknown_Convexity">kUnknown Convexity</a>, 
 <a href="#SkPath_kConvex_Convexity">kConvex Convexity</a>,
 <a href="#SkPath_kConcave_Convexity">kConcave Convexity</a>, 
diff --git a/site/user/api/SkRect_Reference.md b/site/user/api/SkRect_Reference.md
index e067bf3..4dd16b8 100644
--- a/site/user/api/SkRect_Reference.md
+++ b/site/user/api/SkRect_Reference.md
@@ -24,8 +24,8 @@
 
 | description | function |
 | --- | ---  |
-| friend bool <a href="#SkRect_not_equal_operator">operator!=(const SkRect& a, const SkRect& b)</a> | Returns true if member bits are unequal. |
-| friend bool <a href="#SkRect_equal_operator">operator==(const SkRect& a, const SkRect& b)</a> | Returns true if member bits are equal. |
+| bool <a href="#SkRect_not_equal_operator">operator!=(const SkRect& a, const SkRect& b)</a> | Returns true if member bits are unequal. |
+| bool <a href="#SkRect_equal_operator">operator==(const SkRect& a, const SkRect& b)</a> | Returns true if member bits are equal. |
 
 ## <a name="Member_Functions"></a> Member Functions
 
@@ -38,6 +38,7 @@
 | <a href="#SkRect_MakeIWH">MakeIWH</a> | Constructs from int input returning (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
 | <a href="#SkRect_MakeLTRB">MakeLTRB</a> | Constructs from <a href="undocumented#SkScalar">SkScalar</a> <a href="#SkRect_left">left</a>, <a href="#SkRect_top">top</a>, <a href="#SkRect_right">right</a>, <a href="#SkRect_bottom">bottom</a>. |
 | <a href="#SkRect_MakeLargest">MakeLargest</a> | Constructs (<a href="undocumented#SK_ScalarMin">SK ScalarMin</a>, <a href="undocumented#SK_ScalarMin">SK ScalarMin</a>, <a href="undocumented#SK_ScalarMax">SK ScalarMax</a>, <a href="undocumented#SK_ScalarMax">SK ScalarMax</a>). |
+| <a href="#SkRect_MakeLargestS32">MakeLargestS32</a> | Constructs largest signed integers that fit in 32-bit float. |
 | <a href="#SkRect_MakeSize">MakeSize</a> | Constructs from <a href="undocumented#Size">Size</a> returning (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
 | <a href="#SkRect_MakeWH">MakeWH</a> | Constructs from <a href="undocumented#SkScalar">SkScalar</a> input returning (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
 | <a href="#SkRect_MakeXYWH">MakeXYWH</a> | Constructs from <a href="undocumented#SkScalar">SkScalar</a> input returning (<a href="#SkRect_x">x</a>, <a href="#SkRect_y">y</a>, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). |
@@ -180,7 +181,44 @@
 
 ### See Also
 
-<a href="#SkRect_isLargest">isLargest</a> <a href="#SkRect_setLargest">setLargest</a> <a href="#SkIRect_MakeLargest">SkIRect::MakeLargest</a>
+<a href="#SkRect_MakeLargestS32">MakeLargestS32</a> <a href="#SkRect_isLargest">isLargest</a> <a href="#SkRect_setLargest">setLargest</a> <a href="#SkIRect_MakeLargest">SkIRect::MakeLargest</a>
+
+---
+
+<a name="SkRect_MakeLargestS32"></a>
+## MakeLargestS32
+
+<pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
+static SkRect SK_WARN_UNUSED_RESULT MakeLargestS32()
+</pre>
+
+Returns constructed <a href="#Rect">Rect</a> that can be represented exactly with <a href="SkIRect_Reference#IRect">IRect</a>. The <a href="#SkRect_left">left</a>
+and <a href="#SkRect_top">top</a> are <a href="#SkRect_set">set</a> to the most negative integer value that fits in a 32-bit float,
+and the <a href="#SkRect_right">right</a> and <a href="#SkRect_bottom">bottom</a> are <a href="#SkRect_set">set</a> to the most positive finite value that fits in
+a 32-bit float.
+
+These are the largest values for which <a href="#SkRect_round_2">round</a> is well defined.
+
+### Return Value
+
+bounds (<a href="undocumented#SK_MinS32FitsInFloat">SK MinS32FitsInFloat</a>, <a href="undocumented#SK_MinS32FitsInFloat">SK MinS32FitsInFloat</a>,
+<a href="undocumented#SK_MaxS32FitsInFloat">SK MaxS32FitsInFloat</a>, <a href="undocumented#SK_MaxS32FitsInFloat">SK MaxS32FitsInFloat</a>)
+
+### Example
+
+<div><fiddle-embed name="9dde55347ba15b60166b5a0583c55587">
+
+#### Example Output
+
+~~~~
+f_rect == r_rect
+~~~~
+
+</fiddle-embed></div>
+
+### See Also
+
+<a href="#SkRect_MakeLargest">MakeLargest</a> <a href="#SkRect_isLargest">isLargest</a> <a href="#SkRect_setLargest">setLargest</a> <a href="#SkIRect_MakeLargest">SkIRect::MakeLargest</a>
 
 ---
 
@@ -188,7 +226,7 @@
 ## MakeWH
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h)
+static constexpr SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h)
 </pre>
 
 Returns constructed <a href="#Rect">Rect</a> <a href="#SkRect_set">set</a> to <a href="undocumented#SkScalar">SkScalar</a> values (0, 0, <a href="#SkRect_MakeWH_w">w</a>, <a href="#SkRect_MakeWH_h">h</a>). Does not
@@ -277,7 +315,7 @@
 ## MakeSize
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size)
+static constexpr SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size)
 </pre>
 
 Returns constructed <a href="#Rect">Rect</a> <a href="#SkRect_set">set</a> to (0, 0, <a href="#SkRect_MakeSize_size">size</a>.<a href="#SkRect_width">width</a>, <a href="#SkRect_MakeSize_size">size</a>.<a href="#SkRect_height">height</a>). Does not
@@ -364,8 +402,8 @@
 ## MakeXYWH
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w,
-                                             SkScalar h)
+static constexpr SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y,
+                                                       SkScalar w, SkScalar h)
 </pre>
 
 Returns constructed <a href="#Rect">Rect</a> <a href="#SkRect_set">set</a> to(<a href="#SkRect_x">x</a>, <a href="#SkRect_y">y</a>, <a href="#SkRect_x">x</a> + <a href="#SkRect_MakeXYWH_w">w</a>, <a href="#SkRect_y">y</a> + <a href="#SkRect_MakeXYWH_h">h</a>). 
@@ -387,7 +425,7 @@
 
 ### Return Value
 
-bounds (<a href="#SkRect_x">x</a>, <a href="#SkRect_y">y</a>, <a href="#SkRect_x">x</a> + <a href="#SkRect_MakeXYWH_w">w</a>, <a href="#SkRect_y">y</a> + <a href="#SkRect_MakeXYWH_h">h</a>)
+bounds at (<a href="#SkRect_x">x</a>, <a href="#SkRect_y">y</a>) with <a href="#SkRect_width">width</a> <a href="#SkRect_MakeXYWH_w">w</a> and <a href="#SkRect_height">height</a> <a href="#SkRect_MakeXYWH_h">h</a>
 
 ### Example
 
@@ -978,7 +1016,7 @@
 ## operator==
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-friend bool operator==(const SkRect& a, const SkRect& b)
+bool operator==(const SkRect& a, const SkRect& b)
 </pre>
 
 Returns true if all members in <a href="#SkRect_equal_operator_a">a</a>: <a href="#SkRect_fLeft">fLeft</a>, <a href="#SkRect_fTop">fTop</a>, <a href="#SkRect_fRight">fRight</a>, and <a href="#SkRect_fBottom">fBottom</a>; are  
@@ -1025,7 +1063,7 @@
 ## operator!=
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-friend bool operator!=(const SkRect& a, const SkRect& b)
+bool operator!=(const SkRect& a, const SkRect& b)
 </pre>
 
 Returns true if any in <a href="#SkRect_not_equal_operator_a">a</a>: <a href="#SkRect_fLeft">fLeft</a>, <a href="#SkRect_fTop">fTop</a>, <a href="#SkRect_fRight">fRight</a>, and <a href="#SkRect_fBottom">fBottom</a>; does not   
@@ -1502,9 +1540,9 @@
 void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height)
 </pre>
 
-Sets <a href="#Rect">Rect</a> to(<a href="#SkRect_x">x</a>, <a href="#SkRect_y">y</a>, <a href="#SkRect_x">x</a> + w, <a href="#SkRect_y">y</a> + h). 
+Sets <a href="#Rect">Rect</a> to(<a href="#SkRect_x">x</a>, <a href="#SkRect_y">y</a>, <a href="#SkRect_x">x</a> + <a href="#SkRect_width">width</a>, <a href="#SkRect_y">y</a> + <a href="#SkRect_height">height</a>). 
 Does not validate input;
-w or h may be negative.
+<a href="#SkRect_width">width</a> or <a href="#SkRect_height">height</a> may be negative.
 
 ### Parameters
 
@@ -1545,8 +1583,8 @@
 void setWH(SkScalar width, SkScalar height)
 </pre>
 
-Sets <a href="#Rect">Rect</a> to (0, 0, w, h). Does not validate input;
-w or h may be negative.
+Sets <a href="#Rect">Rect</a> to (0, 0, <a href="#SkRect_width">width</a>, <a href="#SkRect_height">height</a>). Does not validate input;
+<a href="#SkRect_width">width</a> or <a href="#SkRect_height">height</a> may be negative.
 
 ### Parameters
 
@@ -1711,7 +1749,7 @@
 
 ### Return Value
 
-<a href="#Rect">Rect</a> <a href="#SkRect_inset">inset</a> symetrically <a href="#SkRect_left">left</a> and <a href="#SkRect_right">right</a>, <a href="#SkRect_top">top</a> and <a href="#SkRect_bottom">bottom</a>
+<a href="#Rect">Rect</a> <a href="#SkRect_inset">inset</a> symmetrically <a href="#SkRect_left">left</a> and <a href="#SkRect_right">right</a>, <a href="#SkRect_top">top</a> and <a href="#SkRect_bottom">bottom</a>
 
 ### Example
 
@@ -1757,7 +1795,7 @@
 
 ### Return Value
 
-<a href="#Rect">Rect</a> <a href="#SkRect_outset">outset</a> symetrically <a href="#SkRect_left">left</a> and <a href="#SkRect_right">right</a>, <a href="#SkRect_top">top</a> and <a href="#SkRect_bottom">bottom</a>
+<a href="#Rect">Rect</a> <a href="#SkRect_outset">outset</a> symmetrically <a href="#SkRect_left">left</a> and <a href="#SkRect_right">right</a>, <a href="#SkRect_top">top</a> and <a href="#SkRect_bottom">bottom</a>
 
 ### Example
 
@@ -2330,7 +2368,7 @@
 Sets <a href="#Rect">Rect</a> to the union of itself and <a href="#SkRect_joinNonEmptyArg_r">r</a>.
 
 Asserts if <a href="#SkRect_joinNonEmptyArg_r">r</a> is empty and <a href="undocumented#SK_DEBUG">SK DEBUG</a> is defined.
-If <a href="#Rect">Rect</a> is empty, sets rect to <a href="#SkRect_joinNonEmptyArg_r">r</a>.
+If <a href="#Rect">Rect</a> is empty, sets <a href="#Rect">Rect</a> to <a href="#SkRect_joinNonEmptyArg_r">r</a>.
 
 May produce incorrect results if <a href="#SkRect_joinNonEmptyArg_r">r</a> is empty.
 
@@ -2343,7 +2381,7 @@
 
 ### Example
 
-<div><fiddle-embed name="88439de2aa0911262c60c0eb506396cb"><div>Since rect is not sorted, first result is copy of toJoin.</div>
+<div><fiddle-embed name="88439de2aa0911262c60c0eb506396cb"><div>Since <a href="#Rect">Rect</a> is not sorted, first result is copy of toJoin.</div>
 
 #### Example Output
 
@@ -2380,7 +2418,7 @@
 
 ### Example
 
-<div><fiddle-embed name="a476548d0001296afd8e58c1eba1b70b"><div>Since rect is not sorted, first result is not useful.</div>
+<div><fiddle-embed name="a476548d0001296afd8e58c1eba1b70b"><div>Since <a href="#Rect">Rect</a> is not sorted, first result is not useful.</div>
 
 #### Example Output
 
@@ -2521,7 +2559,7 @@
 ## contains
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
-bool contains(const SkRect& r) const {
+bool contains(const SkRect& r) const
 </pre>
 
 Returns true if <a href="#Rect">Rect</a> <a href="#SkRect_contains">contains</a> <a href="#SkRect_contains_r">r</a>.
diff --git a/site/user/api/undocumented.md b/site/user/api/undocumented.md
index 721283c..cd6cb5f 100644
--- a/site/user/api/undocumented.md
+++ b/site/user/api/undocumented.md
@@ -737,6 +737,12 @@
 
 <table>
   <tr>
+    <td><a name="SK_MinS32FitsInFloat"> <code><strong>SK_MinS32FitsInFloat </strong></code> </a></td><td>to be written</td><td></td>
+  </tr>
+  <tr>
+    <td><a name="SK_MaxS32FitsInFloat"> <code><strong>SK_MaxS32FitsInFloat </strong></code> </a></td><td>to be written</td><td></td>
+  </tr>
+  <tr>
     <td><a name="SK_ScalarMin"> <code><strong>SK_ScalarMin </strong></code> </a></td><td>to be written</td><td></td>
   </tr>
   <tr>
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index 33feda5..cc45498 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -21,7 +21,7 @@
 DEFINE_string2(spellcheck, s, "", "Spell-check [once, all, mispelling]. (Requires -b)");
 DEFINE_string2(tokens, t, "", "Directory to write bmh from include. (Requires -i)");
 DEFINE_bool2(crosscheck, x, false, "Check bmh against includes. (Requires -b -i)");
-DEFINE_bool2(skip, z, false, "Skip missing example error.");
+DEFINE_bool2(skip, z, false, "Skip degenerate missed in legacy preprocessor.");
 
 /*  recipe for generating timestamps for existing doxygen comments
 find include/core -type f -name '*.h' -print -exec git blame {} \; > ~/all.blame.txt
@@ -390,9 +390,6 @@
         string paramName;
         methodParser.fChar = nextEnd + 1;
         methodParser.skipSpace();
-        if (1494 == methodParser.fLineCount) {
-            SkDebugf("");
-        }
         if (!this->nextMethodParam(&methodParser, &nextEnd, &paramName)) {
             continue;
         }
@@ -823,11 +820,12 @@
     for (auto& leaf : fLeaves) {
         if (!leaf.second.fVisited) {
             // TODO: parse embedded struct in includeParser phase, then remove this condition
-            size_t firstColon = leaf.first.find("::");
-            size_t lastColon = leaf.first.rfind("::");
-            if (firstColon != lastColon) {  // struct, two sets
-                allStructElementsFound = false;
-                continue;
+            if (FLAGS_skip) {
+                const Definition& def = leaf.second;
+                if (def.fChildren.size() > 0 &&
+                        MarkType::kDeprecated == def.fChildren[0]->fMarkType) {
+                    continue;
+                }
             }
             SkDebugf("defined in bmh but missing in include: %s\n", leaf.first.c_str());
         }
@@ -1120,9 +1118,7 @@
                     if (definition->fChildren.size() == 0) {
                         TextParser emptyCheck(definition);
                         if (emptyCheck.eof() || !emptyCheck.skipWhiteSpace()) {
-                            if (!FLAGS_skip) {
-                                return this->reportError<bool>("missing example body");
-                            }
+                            return this->reportError<bool>("missing example body");
                         }
                     }
                 }
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 3954c6e..857caf4 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -1099,9 +1099,6 @@
         }
         writePending();
         if (fDebugOut) {
-            if (!strncmp("SK_SUPPORT", data, 10)) {
-                SkDebugf("");
-            }
             string check(data, size);
             SkDebugf("%s", check.c_str());
         }
@@ -1874,7 +1871,7 @@
     Definition* structMemberOut(const Definition* memberStart, const Definition& child);
     void structOut(const Definition* root, const Definition& child,
             const char* commentStart, const char* commentEnd);
-    void structSizeMembers(Definition& child);
+    void structSizeMembers(const Definition& child);
 
 private:
     BmhParser* fBmhParser;
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 1e055db..4ad83d8 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -199,16 +199,48 @@
     return result;
 }
 
+#include <sstream>
+#include <iostream>
+
 bool IncludeParser::crossCheck(BmhParser& bmhParser) {
-    string className = this->className();
-    string classPrefix = className + "::";
-    RootDefinition* root = &bmhParser.fClassMap[className];
-    root->clearVisited();
     for (auto& classMapper : fIClassMap) {
-        if (className != classMapper.first
-                && classPrefix != classMapper.first.substr(0, classPrefix.length())) {
+        string className = classMapper.first;
+        auto finder = bmhParser.fClassMap.find(className);
+        if (bmhParser.fClassMap.end() == finder) {
+            SkASSERT(string::npos != className.find("::"));
             continue;
         }
+        RootDefinition* root = &finder->second;
+        root->clearVisited();
+    }
+    for (auto& classMapper : fIClassMap) {
+        string className = classMapper.first;
+        std::istringstream iss(className);
+        string classStr;
+        string classBase;
+        RootDefinition* root = nullptr;
+        while (std::getline(iss, classStr, ':')) {
+            if (root) {
+                if (!classStr.length()) {
+                    continue;
+                }
+                classBase += "::" + classStr;
+                auto finder = root->fBranches.find(classBase);
+                if (root->fBranches.end() != finder) {
+                    root = finder->second;
+                } else {
+                    SkASSERT(0);
+                }
+            } else {
+                classBase = classStr;
+                auto finder = bmhParser.fClassMap.find(classBase);
+                if (bmhParser.fClassMap.end() != finder) {
+                    root = &finder->second;
+                } else {
+                    SkASSERT(0);
+                }
+            }
+        }
         auto& classMap = classMapper.second;
         auto& tokens = classMap.fTokens;
         for (const auto& token : tokens) {
@@ -399,10 +431,18 @@
             }
         }
     }
-    if (!root->dumpUnVisited()) {
-        SkDebugf("some struct elements not found; struct finding in includeParser is missing\n");
+    for (auto& classMapper : fIClassMap) {
+        string className = classMapper.first;
+        auto finder = bmhParser.fClassMap.find(className);
+        if (bmhParser.fClassMap.end() == finder) {
+            continue;
+        }
+        RootDefinition* root = &finder->second;
+        if (!root->dumpUnVisited()) {
+            SkDebugf("some struct elements not found; struct finding in includeParser is missing\n");
+        }
+        SkDebugf("cross-checked %s\n", className.c_str());
     }
-    SkDebugf("cross-checked %s\n", className.c_str());
     bmhParser.fWroteOut = true;
     return true;
 }
@@ -1044,32 +1084,45 @@
         (*childIter)->fPrivate = true;
         childIter = std::next(childIter);
     }
-    int lastPublic = publicIndex;
+    int keyIndex = publicIndex;
+    KeyWord currentKey = KeyWord::kPublic;
+    const char* publicName = kKeyWords[(int) KeyWord::kPublic].fName;
+    size_t publicLen = strlen(publicName);
     const char* protectedName = kKeyWords[(int) KeyWord::kProtected].fName;
     size_t protectedLen = strlen(protectedName);
     const char* privateName = kKeyWords[(int) KeyWord::kPrivate].fName;
     size_t privateLen = strlen(privateName);
-    while (iter != includeDef->fTokens.end()
-            && (protectedLen != (size_t) (iter->fContentEnd - iter->fStart)
-            || strncmp(iter->fStart, protectedName, protectedLen))
-            && (privateLen != (size_t) (iter->fContentEnd - iter->fStart)
-            || strncmp(iter->fStart, privateName, privateLen))) {
-        iter = std::next(iter);
-        ++lastPublic;
-    }
-    fLastObject = nullptr;
-    while (childIter != includeDef->fChildren.end() && (*childIter)->fParentIndex < lastPublic) {
+    while (childIter != includeDef->fChildren.end()) {
         Definition* child = *childIter;
-        if (!this->parseObject(child, markupDef)) {
-            return false;
+        while (child->fParentIndex > keyIndex && iter != includeDef->fTokens.end()) {
+            const char* testStart = iter->fStart;
+            size_t testLen = (size_t) (iter->fContentEnd - testStart);
+            iter = std::next(iter);
+            ++keyIndex;
+            if (publicLen == testLen && !strncmp(testStart, publicName, testLen)) {
+                currentKey = KeyWord::kPublic;
+                break;
+            }
+            if (protectedLen == testLen && !strncmp(testStart, protectedName, testLen)) {
+                currentKey = KeyWord::kProtected;
+                break;
+            }
+            if (privateLen == testLen && !strncmp(testStart, privateName, testLen)) {
+                currentKey = KeyWord::kPrivate;
+                break;
+            }
+        }
+        fLastObject = nullptr;
+        if (KeyWord::kPublic == currentKey) {
+            if (!this->parseObject(child, markupDef)) {
+                return false;
+            }
+        } else {
+            child->fPrivate = true;
         }
         fLastObject = child;
         childIter = std::next(childIter);
     }
-    while (childIter != includeDef->fChildren.end()) {
-        (*childIter)->fPrivate = true;
-        childIter = std::next(childIter);
-    }
     SkASSERT(fParent->fParent);
     fParent = fParent->fParent;
     return true;
@@ -1242,6 +1295,23 @@
         }
         markupChild->fChildren.push_back(member);
     } while (true);
+    for (auto count : child->fChildren) {
+        if (Definition::Type::kBracket == count->fType) {
+            continue;
+        }
+        SkASSERT(Definition::Type::kKeyWord == count->fType);
+        if (KeyWord::kClass == count->fKeyWord) {
+            continue;
+        }
+        SkASSERT(KeyWord::kStatic == count->fKeyWord);
+        markupChild->fTokens.emplace_back(MarkType::kMember, count->fContentStart,
+                count->fContentEnd, count->fLineCount, markupChild);
+        Definition* member = &markupChild->fTokens.back();
+        member->fName = count->fName;
+        // FIXME: ? add comment as well ?
+        markupChild->fChildren.push_back(member);
+        break;
+    }
     IClassDefinition& classDef = fIClassMap[markupDef->fName];
     SkASSERT(classDef.fStart);
     string uniqueName = this->uniqueName(classDef.fEnums, nameStr);
@@ -1320,9 +1390,6 @@
     std::advance(tokenIter, child->fParentIndex);
     tokenIter = std::prev(tokenIter);
     string nameStr(tokenIter->fStart, tokenIter->fContentEnd - tokenIter->fStart);
-    if (0 == nameStr.find("SK_ATTR_DEPRECATED")) {
-        SkDebugf("");
-    }
     while (tokenIter != child->fParent->fTokens.begin()) {
         auto testIter = std::prev(tokenIter);
         switch (testIter->fType) {
@@ -1355,9 +1422,14 @@
     }
     tokenIter->fName = nameStr;
     tokenIter->fMarkType = MarkType::kMethod;
+    tokenIter->fPrivate = string::npos != nameStr.find("::");
     auto testIter = child->fParent->fTokens.begin();
     SkASSERT(child->fParentIndex > 0);
     std::advance(testIter, child->fParentIndex - 1);
+    if (tokenIter->fParent && KeyWord::kIfdef == tokenIter->fParent->fKeyWord &&
+            0 == tokenIter->fParentIndex) {
+        tokenIter = std::next(tokenIter);
+    }
     const char* start = tokenIter->fContentStart;
     const char* end = tokenIter->fContentEnd;
     const char kDebugCodeStr[] = "SkDEBUGCODE";
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index 3821361..ff7c0e3 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -673,7 +673,7 @@
     return valueEnd;
 }
 
-void IncludeWriter::structSizeMembers(Definition& child) {
+void IncludeWriter::structSizeMembers(const Definition& child) {
     int longestType = 0;
     Definition* typeStart = nullptr;
     int longestName = 0;
@@ -815,6 +815,7 @@
     fContinuation = nullptr;
     bool inStruct = false;
     bool inConstructor = false;
+    bool inInline = false;
     for (auto& child : def->fTokens) {
         if (memberEnd) {
             if (memberEnd != &child) {
@@ -824,8 +825,34 @@
             memberEnd = nullptr;
         }
         if (child.fPrivate) {
+            if (MarkType::kMethod == child.fMarkType) {
+                inInline = true;
+            }
             continue;
         }
+        if (inInline) {
+            if (Definition::Type::kKeyWord == child.fType) {
+                SkASSERT(MarkType::kMethod != child.fMarkType);
+                continue;
+            }
+            if (Definition::Type::kPunctuation == child.fType) {
+                if (Punctuation::kLeftBrace == child.fPunctuation) {
+                    inInline = false;
+                } else {
+                    SkASSERT(Punctuation::kAsterisk == child.fPunctuation);
+                }
+                continue;
+            }
+            if (Definition::Type::kWord == child.fType) {
+                string name(child.fContentStart, child.fContentEnd - child.fContentStart);
+                SkASSERT(string::npos != name.find("::"));
+                continue;
+            }
+            if (Definition::Type::kBracket == child.fType) {
+                SkASSERT(Bracket::kParen == child.fBracket);
+                continue;
+            }
+        }
         if (fContinuation) {
             if (Definition::Type::kKeyWord == child.fType) {
                 if (KeyWord::kFriend == child.fKeyWord ||
@@ -1131,6 +1158,16 @@
         }
         if (Definition::Type::kWord == child.fType) {
             if (MarkType::kMember == child.fMarkType) {
+                if (!memberStart) {
+                    auto iter = def->fTokens.begin();
+                    std::advance(iter, child.fParentIndex - 1);
+                    memberStart = &*iter;
+                    if (!fStructDef) {
+                        SkASSERT(KeyWord::kStruct == def->fParent->fKeyWord);
+                        fStructDef = def->fParent;
+                        this->structSizeMembers(*fStructDef);
+                    }
+                }
                 memberEnd = this->structMemberOut(memberStart, child);
                 fStart = child.fContentEnd + 1;
                 fDeferComment = nullptr;
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp
index b209164..3a32f37 100644
--- a/tools/bookmaker/spellCheck.cpp
+++ b/tools/bookmaker/spellCheck.cpp
@@ -595,7 +595,6 @@
             sawSpecial = true;
             continue;
         }
-        SkDebugf("");
         SkASSERT(0);
     }
     if (sawSpecial && !hasParen) {