update canvas doc, primarily readpixels and writepixels

also fixed minor bookmaker bugs so canvas 
include and online docs are (bookmaker detected)
error-free

TBR=reed@google.com
Docs-Preview: https://skia.org/?cl=37840
Bug: skia:
Change-Id: Ifcec9c751105444047c37d89fd984dbd4dfd1913
Reviewed-on: https://skia-review.googlesource.com/37840
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/docs/SkCanvas_Reference.bmh b/docs/SkCanvas_Reference.bmh
index 73606a0..ca4a129 100644
--- a/docs/SkCanvas_Reference.bmh
+++ b/docs/SkCanvas_Reference.bmh
@@ -182,17 +182,18 @@
 pixels is not nullptr;
 rowBytes is zero or large enough to contain info width pixels of Image_Color_Type.
 
-pixel buffer size should be info height times rowBytes times bytes required for
-Image_Color_Type.
+Pass zero for rowBytes to compute rowBytes from info width and size of pixel. 
+If rowBytes is greater than zero, it must be equal to or greater than
+info width times bytes required for Image_Color_Type.
+
+Pixel buffer size should be info height times computed rowBytes.
 
 #Param info  width, height, Image_Color_Type, Image_Alpha_Type, Color_Space, of Raster_Surface;
              width, or height, or both, may be zero
 ##
-#Param pixels  pointer to destination pixels buffer; buffer size should be height
-               times rowBytes times four
+#Param pixels  pointer to destination pixels buffer
 ##
-#Param rowBytes  interval from one Surface row to the next; equal to or greater than
-                 info width times bytes required for Image_Color_Type
+#Param rowBytes  interval from one Surface row to the next, or zero
 ##
 
 #Return  Canvas if all parameters are valid; otherwise, nullptr ##
@@ -249,21 +250,22 @@
 
 Canvas is returned if all parameters are valid.
 Valid parameters include:
-info dimensions are zero or positive;
-info contains Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
+width and height are zero or positive;
 pixels is not nullptr;
-rowBytes is zero or large enough to contain width pixels of Image_Color_Type.
+rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
 
-pixel buffer size should be info height times rowBytes times bytes required for
-Image_Color_Type.
+Pass zero for rowBytes to compute rowBytes from fo width and size of pixel. 
+If rowBytes is greater than zero, it must be equal to or greater than
+width times bytes required for Image_Color_Type.
+
+Pixel buffer size should be height times rowBytes.
 
 #Param width  pixel column count on Raster_Surface created; must be zero or greater ##
 #Param height  pixel row count on Raster_Surface created.; must be zero or greater ##
 #Param pixels  pointer to destination pixels buffer; buffer size should be height
-               times rowBytes times four
+               times rowBytes
 ##
-#Param rowBytes  interval from one Surface row to the next; equal to or greater than
-                 width times four
+#Param rowBytes  interval from one Surface row to the next, or zero
 ##
 
 #Return  Canvas if all parameters are valid; otherwise, nullptr ##
@@ -312,8 +314,8 @@
 
 #Method SkCanvas()
 
-Creates an empty canvas with no backing device/pixels, and zero
-dimensions.
+Creates an empty canvas with no backing device or pixels, with 
+a width and height of zero.
 
 #Return  empty canvas ##
 
@@ -587,20 +589,20 @@
 scope, offscreen destructor is called. The saved layer is restored, drawing
 transparent letters.
 ##
-void draw(SkCanvas* canvas) {

-    SkBitmap bitmap;

-    bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));

-    {

-        SkCanvas offscreen(bitmap);

-        SkPaint paint;

-        paint.setTextSize(100);

-        offscreen.drawString("ABC", 20, 160, paint);

-        SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);

-        offscreen.saveLayerAlpha(&layerBounds, 128);

-        offscreen.clear(SK_ColorWHITE);

-        offscreen.drawString("DEF", 20, 160, paint);

-    }

-    canvas->drawBitmap(bitmap, 0, 0, nullptr);

+void draw(SkCanvas* canvas) {
+    SkBitmap bitmap;
+    bitmap.allocPixels(SkImageInfo::MakeN32Premul(200, 200));
+    {
+        SkCanvas offscreen(bitmap);
+        SkPaint paint;
+        paint.setTextSize(100);
+        offscreen.drawString("ABC", 20, 160, paint);
+        SkRect layerBounds = SkRect::MakeXYWH(32, 32, 192, 192);
+        offscreen.saveLayerAlpha(&layerBounds, 128);
+        offscreen.clear(SK_ColorWHITE);
+        offscreen.drawString("DEF", 20, 160, paint);
+    }
+    canvas->drawBitmap(bitmap, 0, 0, nullptr);
 }
 ##
 
@@ -612,7 +614,7 @@
 
 #Method SkMetaData& getMetaData()
 
-Associates additional data with the canvas.
+Returns storage to associate additional data with the canvas.
 The storage is freed when Canvas is deleted.
 
 #Return  storage that can be read from and written to ##
@@ -648,14 +650,14 @@
 #Return  dimensions and Image_Color_Type of Canvas ##
 
 #Example
-    SkCanvas emptyCanvas;

-    SkImageInfo canvasInfo = emptyCanvas.imageInfo();

-    SkImageInfo emptyInfo;

-    SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');

-

-    #StdOut

-        emptyInfo == canvasInfo

-    ##

+    SkCanvas emptyCanvas;
+    SkImageInfo canvasInfo = emptyCanvas.imageInfo();
+    SkImageInfo emptyInfo;
+    SkDebugf("emptyInfo %c= canvasInfo\n", emptyInfo == canvasInfo ? '=' : '!');
+
+    #StdOut
+        emptyInfo == canvasInfo
+    ##
 ##
 
 #ToDo incomplete ##
@@ -944,12 +946,12 @@
 
 Returns true if Canvas has direct access to its pixels.
 
-Pixels are readable when Device is raster. Pixels are not readable when SkCanvas
+Pixels are readable when Device is raster. Pixels are not readable when Canvas
 is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
-SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
+SkPictureRecorder::beginRecording, or Canvas is the base of a utility class
 like SkDumpCanvas.
 
-pixmap pixel address is only valid while Canvas is in scope and unchanged. Any
+pixmap is valid only while Canvas is in scope and unchanged. Any
 Canvas or Surface call may invalidate the pixmap values.
 
 #Param pixmap  storage for Canvas pixel state if Canvas pixels are readable;
@@ -975,54 +977,67 @@
 #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
                     int srcX, int srcY)
 
-Copies rectangle of pixels from Canvas into dstPixels, converting their
-Image_Color_Type and Image_Alpha_Type. Pixels are readable when Device is
-raster. Pixels are not readable when SkCanvas is returned from GPU_Surface,
-returned by SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
-or SkCanvas is the base of a utility class like SkDumpCanvas.
+Copies rectangle of pixels from Canvas into dstPixels. Matrix and Clip are
+ignored. Source rectangle corners are (srcX, srcY) and
+(this->imageInfo.width(), this->imageInfo.height()).
+Destination rectangle corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to dstInfo.colorType() and dstInfo.alphaType() if required.
 
-Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
-does not match dstInfo. Only pixels within the rectangle that intersect Canvas
-pixels are copied. dstPixels outside the rectangle intersection are unchanged.
+Pixels are readable when Device is raster, or backed by a GPU.
+Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
+returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
+class like SkDumpCanvas.
 
-#Table
-#Legend
-# source rectangle # value ##
-##
-# left # srcX ##
-# top # srcY ##
-# width # dstInfo.width() ##
-# height # dstInfo.height() ##
-##
+The destination pixel storage must be allocated by the caller.
 
- #Table
-#Legend
-# canvas pixel bounds # value ##
-##
-# left # 0 ##
-# top # 0 ##
-# width # imageInfo().width() ##
-# height # imageInfo().height() ##
-##
+Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
+do not match. Only pixels within both source and destination rectangles
+are copied. dstPixels contents outside the rectangle intersection are unchanged.
+
+Pass negative values for srcX or srcY to offset pixels across or down destination.
 
 Does not copy, and returns false if:
 
 #List
-# Source rectangle and canvas pixel bounds do not intersect. ##
-# Canvas pixels could not be converted to dstInfo Image_Color_Type or dstInfo Image_Alpha_Type. ##
-# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
+# Source and destination rectangles do not intersect. ##
+# Canvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
+# Canvas pixels are not readable; for instance, Canvas is document-based. ##
 # dstRowBytes is too small to contain one row of pixels. ##
 ##
 
-#Param dstInfo  dimensions, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
-#Param dstPixels  storage for pixels, of size dstInfo.height() times dstRowBytes ##
-#Param dstRowBytes  size of one destination row, dstInfo.width() times pixel size ##
-#Param srcX  offset into readable pixels in x ##
-#Param srcY  offset into readable pixels in y ##
+#Param dstInfo  width, height, Image_Color_Type, and Image_Alpha_Type of dstPixels ##
+#Param dstPixels  storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
+#Param dstRowBytes  size of one destination row; dstInfo.width() times pixel size, or larger ##
+#Param srcX  offset into readable pixels in x; may be negative ##
+#Param srcY  offset into readable pixels in y; may be negative ##
 
 #Return  true if pixels were copied ##
 
 #Example
+#Width 64
+#Height 64
+#Description
+    A black circle drawn on a blue background provides an image to copy.
+    readPixels copies one quarter of the canvas into each of the four corners.
+    The offscreen draws over the image.
+##
+    canvas->clear(SK_ColorBLUE);
+    SkPaint paint;
+    canvas->drawCircle(32, 32, 28, paint);
+    SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
+    sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
+    sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
+    for (int x : { 32, -32 } ) {
+        for (int y : { 32, -32 } ) {
+            canvas->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
+        } 
+    }
+    sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
+    canvas->drawImage(image, 0, 0);
+##
+
+#Example
 #Description
     Canvas returned by Raster_Surface has premultiplied pixel values.
     clear() takes unpremultiplied input with Color_Alpha equal 0x80
@@ -1045,7 +1060,7 @@
     ##
 ##
 
-#ToDo incomplete ##
+#SeeAlso peekPixels writePixels drawBitmap drawImage
 
 ##
 
@@ -1053,67 +1068,61 @@
 
 #Method bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
 
-Copies rectangle of pixels from Canvas into Pixmap, converting their
-Image_Color_Type and Image_Alpha_Type. Pixels are readable when Device is raster.
-Pixels are not readable when SkCanvas is returned from GPU_Surface, returned by
-SkDocument::beginPage, returned by SkPictureRecorder::beginRecording,
-or SkCanvas is the base of a utility class like SkDumpCanvas.
+Copies rectangle of pixels from Canvas into pixmap. Matrix and Clip are
+ignored. Source rectangle corners are (srcX, srcY) and
+(this->imageInfo.width(), this->imageInfo.height()).
+Destination rectangle are (0, 0) and (pixmap.width(), pixmap.height()).
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to pixmap.colorType() and pixmap.alphaType() if required.
 
-Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
-does not match bitmap Image_Info. Only Pixmap pixels within the rectangle that
-intersect Canvas pixels are copied. Pixmap pixels outside the rectangle
-intersection are unchanged.
+Pixels are readable when Device is raster, or backed by a GPU.
+Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
+returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
+class like SkDumpCanvas.
 
-#Table
-#Legend
-# source rectangle # value ##
-##
-# left # srcX ##
-# top # srcY ##
-# width # bitmap.width() ##
-# height # bitmap.height() ##
-##
+Allocates pixel storage in pixmap if needed.
 
- #Table
-#Legend
-# canvas pixel bounds # value ##
-##
-# left # 0 ##
-# top # 0 ##
-# width # imageInfo().width() ##
-# height # imageInfo().height() ##
-##
+Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
+do not match. Only pixels within both source and destination rectangles
+are copied. pixmap pixels contents outside the rectangle intersection are unchanged.
+
+Pass negative values for srcX or srcY to offset pixels across or down pixmap.
 
 Does not copy, and returns false if:
 
 #List
-# Source rectangle and canvas pixel bounds do not intersect. ##
-# Canvas pixels could not be converted to bitmap Image_Color_Type or bitmap Image_Alpha_Type. ##
-# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
-# bitmap pixels could not be allocated. ##
-# Bitmap_Row_Bytes is too small to contain one row of pixels. ##
+# Source and destination rectangles do not intersect. ##
+# Canvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType(). ##
+# Canvas pixels are not readable; for instance, Canvas is document-based. ##
+# Pixmap pixels could not be allocated. ##
+# pixmap.rowBytes() is too small to contain one row of pixels. ##
 ##
 
 #Param pixmap  storage for pixels copied from Canvas ##
-#Param srcX    offset into readable pixels in x ##
-#Param srcY    offset into readable pixels in y ##
+#Param srcX    offset into readable pixels in x; may be negative ##
+#Param srcY    offset into readable pixels in y; may be negative ##
 
 #Return  true if pixels were copied ##
 
 #Example
-void draw(SkCanvas* canvas) {
-    canvas->clear(0x8055aaff);
-    uint32_t pixels[1] = { 0 };
-    SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
-    canvas->readPixels(pixmap, 0, 0);
-    SkDebugf("pixel = %08x\n", pixels[0]);
-}
+    #Description
+        clear() takes unpremultiplied input with Color_Alpha equal 0x80
+        and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multipled by Color_Alpha
+        to generate premultipled value 0x802B5580.
+    ##
+    void draw(SkCanvas* canvas) {
+        canvas->clear(0x8055aaff);
+        uint32_t pixels[1] = { 0 };
+        SkPixmap pixmap(SkImageInfo::MakeN32Premul(1, 1), pixels, 4);
+        canvas->readPixels(pixmap, 0, 0);
+        SkDebugf("pixel = %08x\n", pixels[0]);
+    }
     #StdOut
         pixel = 802b5580
     ##
 ##
 
-#ToDo incomplete ##
+#SeeAlso peekPixels writePixels drawBitmap drawImage
 
 ##
 
@@ -1121,45 +1130,48 @@
 
 #Method bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
 
-Copies pixels enclosed by bitmap offset to (x, y) from Canvas into bitmap,
-converting their Image_Color_Type and Image_Alpha_Type.
-Pixels are readable when Device is raster. Pixels are not readable when SkCanvas
-is returned from GPU_Surface, returned by SkDocument::beginPage, returned by
-SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
-like SkDumpCanvas. Allocates pixel storage in bitmap if needed.
+Copies rectangle of pixels from Canvas into bitmap. Matrix and Clip are
+ignored. Source rectangle corners are (srcX, srcY) and
+(this->imageInfo.width(), this->imageInfo.height()).
+Destination rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to bitmap.colorType() and bitmap.alphaType() if required.
 
-Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
-does not match bitmap Image_Info. Only pixels within the rectangle that intersect
-Canvas pixels are copied. Bitamp pixels outside the rectangle intersection are
-unchanged.
+Pixels are readable when Device is raster, or backed by a GPU.
+Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
+returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
+class like SkDumpCanvas.
 
-#Table
-#Legend
-# canvas pixel bounds # value ##
-##
-# left # 0 ##
-# top # 0 ##
-# width # imageInfo().width() ##
-# height # imageInfo().height() ##
-##
+Allocates pixel storage in bitmap if needed.
+
+Bitmap values are converted only if Image_Color_Type and Image_Alpha_Type
+do not match. Only pixels within both source and destination rectangles
+are copied. Bitmap pixels outside the rectangle intersection are unchanged.
+
+Pass negative values for srcX or srcY to offset pixels across or down bitmap.
 
 Does not copy, and returns false if:
 
 #List
-# Bounds formed by (x, y) and bitmap (width, height) and canvas pixel bounds do not intersect. ##
-# Canvas pixels could not be converted to bitmap Image_Color_Type or bitmap Image_Alpha_Type. ##
-# Canvas pixels are not readable; for instance, Canvas is not raster, or is document-based. ##
+# Source and destination rectangles do not intersect. ##
+# Canvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType(). ##
+# Canvas pixels are not readable; for instance, Canvas is document-based. ##
 # bitmap pixels could not be allocated. ##
-# Bitmap_Row_Bytes is too small to contain one row of pixels. ##
+# bitmap.rowBytes() is too small to contain one row of pixels. ##
 ##
 
 #Param bitmap  storage for pixels copied from Canvas ##
-#Param srcX    offset into readable pixels in x ##
-#Param srcY    offset into readable pixels in y ##
+#Param srcX    offset into readable pixels in x; may be negative ##
+#Param srcY    offset into readable pixels in y; may be negative ##
 
 #Return  true if pixels were copied ##
 
 #Example
+    #Description
+        clear() takes unpremultiplied input with Color_Alpha equal 0x80
+        and Color_RGB equal 0x55, 0xAA, 0xFF. Color_RGB is multipled by Color_Alpha
+        to generate premultipled value 0x802B5580.
+    ##
 void draw(SkCanvas* canvas) {
     canvas->clear(0x8055aaff);
     SkBitmap bitmap;
@@ -1172,7 +1184,7 @@
     ##
 ##
 
-#ToDo incomplete ##
+#SeeAlso peekPixels writePixels drawBitmap drawImage
 
 ##
 
@@ -1180,48 +1192,39 @@
 
 #Method bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y)
 
-Copies to Canvas pixels, ignoring the Matrix and Clip, converting to match
-info Image_Color_Type and info Image_Alpha_Type.
+Copies rectangle from pixels to Canvas. Matrix and Clip are ignored.
+Source rectangle corners are (0, 0) and (info.width(), info.height()).
+Destination rectangle corners are (x, y) and
+(this->imageInfo.width(), this->imageInfo.height()). Copies each readable pixel
+intersecting both rectangles, without scaling, converting to
+this->imageInfo.colorType() and this->imageInfo.alphaType() if required.
 
-Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
-does not match info. Only pixels within the source rectangle that intersect
-Canvas pixel bounds are copied. Canvas pixels outside the rectangle intersection
-are unchanged.
+Pixels are writable when Device is raster, or backed by a GPU.
+Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
+returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
+class like SkDumpCanvas.
 
-#Table
-#Legend
-# source rectangle # value ##
-##
-# left # x ##
-# top # y ##
-# width # info.width() ##
-# height # info.height() ##
-##
+Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
+do not match. Only pixels within both source and destination rectangles
+are copied. Canvas pixels outside the rectangle intersection are unchanged.
 
- #Table
-#Legend
-# canvas pixel bounds # value ##
-##
-# left # 0 ##
-# top # 0 ##
-# width # imageInfo().width() ##
-# height # imageInfo().height() ##
-##
+Pass negative values for x or y to offset pixels to the left or
+above Canvas pixels.
 
 Does not copy, and returns false if:
 
 #List
-# Source rectangle and canvas pixel bounds do not intersect. ##
-# pixels could not be converted to Canvas Image_Color_Type or Canvas Image_Alpha_Type. ##
+# Source and destination rectangles do not intersect. ##
+# pixels could not be converted to this->imageInfo.colorType() or this->imageInfo.alphaType(). ##
 # Canvas pixels are not writable; for instance, Canvas is document-based. ##
 # rowBytes is too small to contain one row of pixels. ##
 ##
 
-#Param info    dimensions, Image_Color_Type, and Image_Alpha_Type of pixels ##
-#Param pixels  pixels to copy, of size info.height() times rowBytes ##
-#Param rowBytes  offset from one row to the next, usually info.width() times pixel size ##
-#Param x  offset into Canvas writable pixels in x ##
-#Param y  offset into Canvas writable pixels in y ##
+#Param info  width, height, Image_Color_Type, and Image_Alpha_Type of pixels ##
+#Param pixels  pixels to copy, of size info.height() times rowBytes, or larger ##
+#Param rowBytes  size of one pixels row; info.width() times pixel size, or larger ##
+#Param x  offset into Canvas writable pixels in x; may be negative ##
+#Param y  offset into Canvas writable pixels in y; may be negative ##
 
 #Return  true if pixels were written to Canvas ##
 
@@ -1236,7 +1239,7 @@
     }
 ##
 
-#ToDo incomplete ##
+#SeeAlso readPixels drawBitmap drawImage
 
 ##
 
@@ -1244,47 +1247,38 @@
 
 #Method bool writePixels(const SkBitmap& bitmap, int x, int y)
 
-Writes to Canvas pixels, ignoring the Matrix and Clip, converting to match
-bitmap Image_Color_Type and bitmap Image_Alpha_Type.
+Copies rectangle from pixels to Canvas. Matrix and Clip are ignored.
+Source rectangle corners are (0, 0) and (bitmap.width(), bitmap.height()).
+Destination rectangle corners are (x, y) and
+(this->imageInfo.width(), this->imageInfo.height()). Copies each readable pixel
+intersecting both rectangles, without scaling, converting to
+this->imageInfo.colorType() and this->imageInfo.alphaType() if required.
 
-Pixel values are converted only if Canvas Image_Color_Type and Image_Alpha_Type
-does not match bitmap. Only pixels within the source rectangle that intersect
-Canvas pixel bounds are copied. Canvas pixels outside the rectangle intersection
-are unchanged.
+Pixels are writable when Device is raster, or backed by a GPU.
+Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
+returned by SkPictureRecorder::beginRecording, or Canvas is the base of a utility
+class like SkDumpCanvas.
 
-#Table
-#Legend
-# source rectangle # value ##
-##
-# left # x ##
-# top # y ##
-# width # bitmap.width() ##
-# height # bitmap.height() ##
-##
+Pixel values are converted only if Image_Color_Type and Image_Alpha_Type
+do not match. Only pixels within both source and destination rectangles
+are copied. Canvas pixels outside the rectangle intersection are unchanged.
 
- #Table
-#Legend
-# canvas pixel bounds # value ##
-##
-# left # 0 ##
-# top # 0 ##
-# width # imageInfo().width() ##
-# height # imageInfo().height() ##
-##
+Pass negative values for x or y to offset pixels to the left or
+above Canvas pixels.
 
 Does not copy, and returns false if:
 
 #List
-# Source rectangle and Canvas pixel bounds do not intersect. ##
+# Source and destination rectangles do not intersect. ##
 # bitmap does not have allocated pixels. ##
-# bitmap pixels could not be converted to Canvas Image_Color_Type or Canvas Image_Alpha_Type. ##
+# bitmap pixels could not be converted to this->imageInfo.colorType() or this->imageInfo.alphaType(). ##
 # Canvas pixels are not writable; for instance, Canvas is document-based. ##
 # bitmap pixels are inaccessible; for instance, bitmap wraps a texture. ##
 ##
 
 #Param bitmap  contains pixels copied to Canvas ##
-#Param x       offset into Canvas writable pixels in x ##
-#Param y       offset into Canvas writable pixels in y ##
+#Param x       offset into Canvas writable pixels in x; may be negative ##
+#Param y       offset into Canvas writable pixels in y; may be negative ##
 
 #Return  true if pixels were written to Canvas ##
 
@@ -1307,7 +1301,7 @@
 }
 ##
 
-#ToDo incomplete ##
+#SeeAlso readPixels drawBitmap drawImage
 
 ##
 
diff --git a/site/user/api/SkCanvas_Reference.md b/site/user/api/SkCanvas_Reference.md
index 2f3fb59..a2b027b 100644
--- a/site/user/api/SkCanvas_Reference.md
+++ b/site/user/api/SkCanvas_Reference.md
@@ -166,8 +166,11 @@
 <a href="SkCanvas_Reference#MakeRasterDirect">pixels</a> is not nullptr;
 <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a> is zero or large enough to contain <a href="SkCanvas_Reference#MakeRasterDirect">info</a> width <a href="SkCanvas_Reference#MakeRasterDirect">pixels</a> of <a href="undocumented#Color_Type">Image Color Type</a>.
 
-pixel buffer size should be <a href="SkCanvas_Reference#MakeRasterDirect">info</a> height times <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a> times bytes required for
-<a href="undocumented#Color_Type">Image Color Type</a>.
+Pass zero for <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a> to compute <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a> from <a href="SkCanvas_Reference#MakeRasterDirect">info</a> width and size of pixel. 
+If <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a> is greater than zero, it must be equal to or greater than
+<a href="SkCanvas_Reference#MakeRasterDirect">info</a> width times bytes required for <a href="undocumented#Color_Type">Image Color Type</a>.
+
+<a href="undocumented#Pixel">Pixel</a> buffer size should be <a href="SkCanvas_Reference#MakeRasterDirect">info</a> height times computed <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a>.
 
 ### Parameters
 
@@ -175,11 +178,9 @@
 width, height, <a href="undocumented#Color_Type">Image Color Type</a>, <a href="undocumented#Alpha_Type">Image Alpha Type</a>, <a href="undocumented#Color_Space">Color Space</a>, of <a href="undocumented#Raster_Surface">Raster Surface</a>;
 width, or height, or both, may be zero</td>
   </tr>  <tr>    <td><code><strong>pixels </strong></code></td> <td>
-pointer to destination <a href="SkCanvas_Reference#MakeRasterDirect">pixels</a> buffer; buffer size should be height
-times <a href="SkCanvas_Reference#MakeRasterDirect">rowBytes</a> times four</td>
+pointer to destination <a href="SkCanvas_Reference#MakeRasterDirect">pixels</a> buffer</td>
   </tr>  <tr>    <td><code><strong>rowBytes </strong></code></td> <td>
-interval from one <a href="undocumented#Surface">Surface</a> row to the next; equal to or greater than
-<a href="SkCanvas_Reference#MakeRasterDirect">info</a> width times bytes required for <a href="undocumented#Color_Type">Image Color Type</a></td>
+interval from one <a href="undocumented#Surface">Surface</a> row to the next, or zero</td>
   </tr>
 </table>
 
@@ -225,13 +226,15 @@
 
 <a href="SkCanvas_Reference#Canvas">Canvas</a> is returned if all parameters are valid.
 Valid parameters include:
-info dimensions are zero or positive;
-info contains <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a> supported by <a href="undocumented#Raster_Surface">Raster Surface</a>;
+<a href="SkCanvas_Reference#width">width</a> and <a href="SkCanvas_Reference#height">height</a> are zero or positive;
 <a href="SkCanvas_Reference#MakeRasterDirectN32">pixels</a> is not nullptr;
-<a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> is zero or large enough to contain <a href="SkCanvas_Reference#width">width</a> <a href="SkCanvas_Reference#MakeRasterDirectN32">pixels</a> of <a href="undocumented#Color_Type">Image Color Type</a>.
+<a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> is zero or large enough to contain <a href="SkCanvas_Reference#width">width</a> <a href="SkCanvas_Reference#MakeRasterDirectN32">pixels</a> of <a href="undocumented#SkColorType">kN32 SkColorType</a>.
 
-pixel buffer size should be info <a href="SkCanvas_Reference#height">height</a> times <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> times bytes required for
-<a href="undocumented#Color_Type">Image Color Type</a>.
+Pass zero for <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> to compute <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> from fo <a href="SkCanvas_Reference#width">width</a> and size of pixel. 
+If <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> is greater than zero, it must be equal to or greater than
+<a href="SkCanvas_Reference#width">width</a> times bytes required for <a href="undocumented#Color_Type">Image Color Type</a>.
+
+<a href="undocumented#Pixel">Pixel</a> buffer size should be <a href="SkCanvas_Reference#height">height</a> times <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a>.
 
 ### Parameters
 
@@ -241,10 +244,9 @@
 pixel row count on <a href="undocumented#Raster_Surface">Raster Surface</a> created.; must be zero or greater</td>
   </tr>  <tr>    <td><code><strong>pixels </strong></code></td> <td>
 pointer to destination <a href="SkCanvas_Reference#MakeRasterDirectN32">pixels</a> buffer; buffer size should be <a href="SkCanvas_Reference#height">height</a>
-times <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a> times four</td>
+times <a href="SkCanvas_Reference#MakeRasterDirectN32">rowBytes</a></td>
   </tr>  <tr>    <td><code><strong>rowBytes </strong></code></td> <td>
-interval from one <a href="undocumented#Surface">Surface</a> row to the next; equal to or greater than
-<a href="SkCanvas_Reference#width">width</a> times four</td>
+interval from one <a href="undocumented#Surface">Surface</a> row to the next, or zero</td>
   </tr>
 </table>
 
@@ -276,8 +278,8 @@
 SkCanvas()
 </pre>
 
-Creates an empty canvas with no backing device/pixels, and zero
-dimensions.
+Creates an empty canvas with no backing device or pixels, with 
+a width and height of zero.
 
 ### Return Value
 
@@ -547,7 +549,7 @@
 SkMetaData& getMetaData()
 </pre>
 
-Associates additional data with the canvas.
+Returns storage to associate additional data with the canvas.
 The storage is freed when <a href="SkCanvas_Reference#Canvas">Canvas</a> is deleted.
 
 ### Return Value
@@ -833,12 +835,12 @@
 
 Returns true if <a href="SkCanvas_Reference#Canvas">Canvas</a> has direct access to its pixels.
 
-Pixels are readable when <a href="undocumented#Device">Device</a> is raster. Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a>
+Pixels are readable when <a href="undocumented#Device">Device</a> is raster. Pixels are not readable when <a href="SkCanvas_Reference#Canvas">Canvas</a>
 is returned from <a href="undocumented#GPU_Surface">GPU Surface</a>, returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>, returned by
-<a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is the base of a utility class
+<a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#Canvas">Canvas</a> is the base of a utility class
 like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
 
-<a href="SkCanvas_Reference#peekPixels">pixmap</a> pixel address is only valid while <a href="SkCanvas_Reference#Canvas">Canvas</a> is in scope and unchanged. Any
+<a href="SkCanvas_Reference#peekPixels">pixmap</a> is valid only while <a href="SkCanvas_Reference#Canvas">Canvas</a> is in scope and unchanged. Any
 <a href="SkCanvas_Reference#Canvas">Canvas</a> or <a href="undocumented#Surface">Surface</a> call may invalidate the <a href="SkCanvas_Reference#peekPixels">pixmap</a> values.
 
 ### Parameters
@@ -875,51 +877,47 @@
                 int srcX, int srcY)
 </pre>
 
-Copies rectangle of pixels from <a href="SkCanvas_Reference#Canvas">Canvas</a> into <a href="SkCanvas_Reference#dstPixels">dstPixels</a>, converting their
-<a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>. Pixels are readable when <a href="undocumented#Device">Device</a> is
-raster. Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned from <a href="undocumented#GPU_Surface">GPU Surface</a>,
-returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>, returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>,
-or <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is the base of a utility class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
+Copies rectangle of pixels from <a href="SkCanvas_Reference#Canvas">Canvas</a> into <a href="SkCanvas_Reference#dstPixels">dstPixels</a>. <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a> are
+ignored. Source rectangle corners are (<a href="SkCanvas_Reference#srcX">srcX</a>, <a href="SkCanvas_Reference#srcY">srcY</a>) and
+(this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width(), this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height()).
+Destination rectangle corners are (0, 0) and (<a href="SkCanvas_Reference#dstInfo">dstInfo</a>.width(), <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.height()).
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.colorType() and <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.alphaType() if required.
 
-<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
-does not match <a href="SkCanvas_Reference#dstInfo">dstInfo</a>. Only pixels within the rectangle that intersect <a href="SkCanvas_Reference#Canvas">Canvas</a>
-pixels are copied. <a href="SkCanvas_Reference#dstPixels">dstPixels</a> outside the rectangle intersection are unchanged.
+Pixels are readable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
+Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>,
+returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#Canvas">Canvas</a> is the base of a utility
+class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
 
-| source rectangle | value |
-| --- | ---  |
-| left | <a href="SkCanvas_Reference#srcX">srcX</a> |
-| top | <a href="SkCanvas_Reference#srcY">srcY</a> |
-| width | <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.width() |
-| height | <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.height() |
+The destination pixel storage must be allocated by the caller.
 
-| canvas pixel bounds | value |
-| --- | ---  |
-| left | 0 |
-| top | 0 |
-| width | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width() |
-| height | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height() |
+<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
+do not match. Only pixels within both source and destination rectangles
+are copied. <a href="SkCanvas_Reference#dstPixels">dstPixels</a> contents outside the rectangle intersection are unchanged.
+
+Pass negative values for <a href="SkCanvas_Reference#srcX">srcX</a> or <a href="SkCanvas_Reference#srcY">srcY</a> to offset pixels across or down destination.
 
 Does not copy, and returns false if:
 
 <table>  <tr>
-    <td>Source rectangle and canvas pixel bounds do not intersect.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels could not be converted to <a href="SkCanvas_Reference#dstInfo">dstInfo</a> <a href="undocumented#Color_Type">Image Color Type</a> or <a href="SkCanvas_Reference#dstInfo">dstInfo</a> <a href="undocumented#Alpha_Type">Image Alpha Type</a>.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not readable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is not raster, or is document-based.</td>  </tr>  <tr>
+    <td>Source and destination rectangles do not intersect.</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels could not be converted to <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.colorType() or <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.alphaType().</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not readable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is document-based.</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#dstRowBytes">dstRowBytes</a> is too small to contain one row of pixels.</td>  </tr>
 </table>
 
 ### Parameters
 
 <table>  <tr>    <td><code><strong>dstInfo </strong></code></td> <td>
-dimensions, <a href="undocumented#Color_Type">Image Color Type</a>, and <a href="undocumented#Alpha_Type">Image Alpha Type</a> of <a href="SkCanvas_Reference#dstPixels">dstPixels</a></td>
+width, height, <a href="undocumented#Color_Type">Image Color Type</a>, and <a href="undocumented#Alpha_Type">Image Alpha Type</a> of <a href="SkCanvas_Reference#dstPixels">dstPixels</a></td>
   </tr>  <tr>    <td><code><strong>dstPixels </strong></code></td> <td>
-storage for pixels, of size <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.height() times <a href="SkCanvas_Reference#dstRowBytes">dstRowBytes</a></td>
+storage for pixels; <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.height() times <a href="SkCanvas_Reference#dstRowBytes">dstRowBytes</a>, or larger</td>
   </tr>  <tr>    <td><code><strong>dstRowBytes </strong></code></td> <td>
-size of one destination row, <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.width() times pixel size</td>
+size of one destination row; <a href="SkCanvas_Reference#dstInfo">dstInfo</a>.width() times pixel size, or larger</td>
   </tr>  <tr>    <td><code><strong>srcX </strong></code></td> <td>
-offset into readable pixels in x</td>
+offset into readable pixels in x; may be negative</td>
   </tr>  <tr>    <td><code><strong>srcY </strong></code></td> <td>
-offset into readable pixels in y</td>
+offset into readable pixels in y; may be negative</td>
   </tr>
 </table>
 
@@ -929,6 +927,12 @@
 
 ### Example
 
+<div><fiddle-embed name="2964297993747769b0760874c19e0168"><div>A black circle drawn on a blue background provides an image to copy.
+<a href="SkCanvas_Reference#readPixels">readPixels</a> copies one quarter of the canvas into each of the four corners.
+The offscreen draws over the image.</div></fiddle-embed></div>
+
+### Example
+
 <div><fiddle-embed name="481e990e923a0ed34654f4361b94f096"><div><a href="SkCanvas_Reference#Canvas">Canvas</a> returned by <a href="undocumented#Raster_Surface">Raster Surface</a> has premultiplied pixel values.
 <a href="SkCanvas_Reference#clear">clear</a> takes unpremultiplied input with <a href="undocumented#Alpha">Color Alpha</a> equal 0x80
 and <a href="undocumented#RGB">Color RGB</a> equal 0x55, 0xAA, 0xFF. <a href="undocumented#RGB">Color RGB</a> is multipled by <a href="undocumented#Alpha">Color Alpha</a>
@@ -944,45 +948,44 @@
 
 </fiddle-embed></div>
 
+### See Also
+
+<a href="SkCanvas_Reference#peekPixels">peekPixels</a> <a href="SkCanvas_Reference#writePixels">writePixels</a> <a href="SkCanvas_Reference#drawBitmap">drawBitmap</a> <a href="SkCanvas_Reference#drawImage">drawImage</a>
+
 ---
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
 bool readPixels(const SkPixmap& pixmap, int srcX, int srcY)
 </pre>
 
-Copies rectangle of pixels from <a href="SkCanvas_Reference#Canvas">Canvas</a> into <a href="undocumented#Pixmap">Pixmap</a>, converting their
-<a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>. Pixels are readable when <a href="undocumented#Device">Device</a> is raster.
-Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned from <a href="undocumented#GPU_Surface">GPU Surface</a>, returned by
-<a href="undocumented#beginPage">SkDocument::beginPage</a>, returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>,
-or <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is the base of a utility class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
+Copies rectangle of pixels from <a href="SkCanvas_Reference#Canvas">Canvas</a> into <a href="SkCanvas_Reference#pixmap">pixmap</a>. <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a> are
+ignored. Source rectangle corners are (<a href="SkCanvas_Reference#srcX">srcX</a>, <a href="SkCanvas_Reference#srcY">srcY</a>) and
+(this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width(), this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height()).
+Destination rectangle are (0, 0) and (<a href="SkCanvas_Reference#pixmap">pixmap</a>.width(), <a href="SkCanvas_Reference#pixmap">pixmap</a>.height()).
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to <a href="SkCanvas_Reference#pixmap">pixmap</a>.colorType() and <a href="SkCanvas_Reference#pixmap">pixmap</a>.alphaType() if required.
 
-<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
-does not match bitmap <a href="undocumented#Info">Image Info</a>. Only <a href="undocumented#Pixmap">Pixmap</a> pixels within the rectangle that
-intersect <a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are copied. <a href="undocumented#Pixmap">Pixmap</a> pixels outside the rectangle
-intersection are unchanged.
+Pixels are readable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
+Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>,
+returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#Canvas">Canvas</a> is the base of a utility
+class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
 
-| source rectangle | value |
-| --- | ---  |
-| left | <a href="SkCanvas_Reference#srcX">srcX</a> |
-| top | <a href="SkCanvas_Reference#srcY">srcY</a> |
-| width | bitmap.width() |
-| height | bitmap.height() |
+Allocates pixel storage in <a href="SkCanvas_Reference#pixmap">pixmap</a> if needed.
 
-| canvas pixel bounds | value |
-| --- | ---  |
-| left | 0 |
-| top | 0 |
-| width | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width() |
-| height | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height() |
+<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
+do not match. Only pixels within both source and destination rectangles
+are copied. <a href="SkCanvas_Reference#pixmap">pixmap</a> pixels contents outside the rectangle intersection are unchanged.
+
+Pass negative values for <a href="SkCanvas_Reference#srcX">srcX</a> or <a href="SkCanvas_Reference#srcY">srcY</a> to offset pixels across or down <a href="SkCanvas_Reference#pixmap">pixmap</a>.
 
 Does not copy, and returns false if:
 
 <table>  <tr>
-    <td>Source rectangle and canvas pixel bounds do not intersect.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels could not be converted to bitmap <a href="undocumented#Color_Type">Image Color Type</a> or bitmap <a href="undocumented#Alpha_Type">Image Alpha Type</a>.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not readable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is not raster, or is document-based.</td>  </tr>  <tr>
-    <td>bitmap pixels could not be allocated.</td>  </tr>  <tr>
-    <td><a href="undocumented#Row_Bytes">Bitmap Row Bytes</a> is too small to contain one row of pixels.</td>  </tr>
+    <td>Source and destination rectangles do not intersect.</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels could not be converted to <a href="SkCanvas_Reference#pixmap">pixmap</a>.colorType() or <a href="SkCanvas_Reference#pixmap">pixmap</a>.alphaType().</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not readable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is document-based.</td>  </tr>  <tr>
+    <td><a href="undocumented#Pixmap">Pixmap</a> pixels could not be allocated.</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#pixmap">pixmap</a>.rowBytes() is too small to contain one row of pixels.</td>  </tr>
 </table>
 
 ### Parameters
@@ -990,9 +993,9 @@
 <table>  <tr>    <td><code><strong>pixmap </strong></code></td> <td>
 storage for pixels copied from <a href="SkCanvas_Reference#Canvas">Canvas</a></td>
   </tr>  <tr>    <td><code><strong>srcX </strong></code></td> <td>
-offset into readable pixels in x</td>
+offset into readable pixels in x; may be negative</td>
   </tr>  <tr>    <td><code><strong>srcY </strong></code></td> <td>
-offset into readable pixels in y</td>
+offset into readable pixels in y; may be negative</td>
   </tr>
 </table>
 
@@ -1002,7 +1005,9 @@
 
 ### Example
 
-<div><fiddle-embed name="85f199032943b6483722c34a91c4e20f">
+<div><fiddle-embed name="85f199032943b6483722c34a91c4e20f"><div><a href="SkCanvas_Reference#clear">clear</a> takes unpremultiplied input with <a href="undocumented#Alpha">Color Alpha</a> equal 0x80
+and <a href="undocumented#RGB">Color RGB</a> equal 0x55, 0xAA, 0xFF. <a href="undocumented#RGB">Color RGB</a> is multipled by <a href="undocumented#Alpha">Color Alpha</a>
+to generate premultipled value 0x802B5580.</div>
 
 #### Example Output
 
@@ -1012,39 +1017,44 @@
 
 </fiddle-embed></div>
 
+### See Also
+
+<a href="SkCanvas_Reference#peekPixels">peekPixels</a> <a href="SkCanvas_Reference#writePixels">writePixels</a> <a href="SkCanvas_Reference#drawBitmap">drawBitmap</a> <a href="SkCanvas_Reference#drawImage">drawImage</a>
+
 ---
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
 bool readPixels(const SkBitmap& bitmap, int srcX, int srcY)
 </pre>
 
-Copies pixels enclosed by <a href="SkCanvas_Reference#bitmap">bitmap</a> offset to (x, y) from <a href="SkCanvas_Reference#Canvas">Canvas</a> into <a href="SkCanvas_Reference#bitmap">bitmap</a>,
-converting their <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>.
-Pixels are readable when <a href="undocumented#Device">Device</a> is raster. Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a>
-is returned from <a href="undocumented#GPU_Surface">GPU Surface</a>, returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>, returned by
-<a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is the base of a utility class
-like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>. Allocates pixel storage in <a href="SkCanvas_Reference#bitmap">bitmap</a> if needed.
+Copies rectangle of pixels from <a href="SkCanvas_Reference#Canvas">Canvas</a> into <a href="SkCanvas_Reference#bitmap">bitmap</a>. <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a> are
+ignored. Source rectangle corners are (<a href="SkCanvas_Reference#srcX">srcX</a>, <a href="SkCanvas_Reference#srcY">srcY</a>) and
+(this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width(), this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height()).
+Destination rectangle corners are (0, 0) and (<a href="SkCanvas_Reference#bitmap">bitmap</a>.width(), <a href="SkCanvas_Reference#bitmap">bitmap</a>.height()).
+Copies each readable pixel intersecting both rectangles, without scaling,
+converting to <a href="SkCanvas_Reference#bitmap">bitmap</a>.colorType() and <a href="SkCanvas_Reference#bitmap">bitmap</a>.alphaType() if required.
 
-<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
-does not match <a href="SkCanvas_Reference#bitmap">bitmap</a> <a href="undocumented#Info">Image Info</a>. Only pixels within the rectangle that intersect
-<a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are copied. Bitamp pixels outside the rectangle intersection are
-unchanged.
+Pixels are readable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
+Pixels are not readable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>,
+returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#Canvas">Canvas</a> is the base of a utility
+class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
 
-| canvas pixel bounds | value |
-| --- | ---  |
-| left | 0 |
-| top | 0 |
-| width | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width() |
-| height | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height() |
+Allocates pixel storage in <a href="SkCanvas_Reference#bitmap">bitmap</a> if needed.
+
+<a href="undocumented#Bitmap">Bitmap</a> values are converted only if <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
+do not match. Only pixels within both source and destination rectangles
+are copied. <a href="undocumented#Bitmap">Bitmap</a> pixels outside the rectangle intersection are unchanged.
+
+Pass negative values for <a href="SkCanvas_Reference#srcX">srcX</a> or <a href="SkCanvas_Reference#srcY">srcY</a> to offset pixels across or down <a href="SkCanvas_Reference#bitmap">bitmap</a>.
 
 Does not copy, and returns false if:
 
 <table>  <tr>
-    <td>Bounds formed by (x, y) and <a href="SkCanvas_Reference#bitmap">bitmap</a> (width, height) and canvas pixel bounds do not intersect.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels could not be converted to <a href="SkCanvas_Reference#bitmap">bitmap</a> <a href="undocumented#Color_Type">Image Color Type</a> or <a href="SkCanvas_Reference#bitmap">bitmap</a> <a href="undocumented#Alpha_Type">Image Alpha Type</a>.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not readable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is not raster, or is document-based.</td>  </tr>  <tr>
+    <td>Source and destination rectangles do not intersect.</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels could not be converted to <a href="SkCanvas_Reference#bitmap">bitmap</a>.colorType() or <a href="SkCanvas_Reference#bitmap">bitmap</a>.alphaType().</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not readable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is document-based.</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#bitmap">bitmap</a> pixels could not be allocated.</td>  </tr>  <tr>
-    <td><a href="undocumented#Row_Bytes">Bitmap Row Bytes</a> is too small to contain one row of pixels.</td>  </tr>
+    <td><a href="SkCanvas_Reference#bitmap">bitmap</a>.rowBytes() is too small to contain one row of pixels.</td>  </tr>
 </table>
 
 ### Parameters
@@ -1052,9 +1062,9 @@
 <table>  <tr>    <td><code><strong>bitmap </strong></code></td> <td>
 storage for pixels copied from <a href="SkCanvas_Reference#Canvas">Canvas</a></td>
   </tr>  <tr>    <td><code><strong>srcX </strong></code></td> <td>
-offset into readable pixels in x</td>
+offset into readable pixels in x; may be negative</td>
   </tr>  <tr>    <td><code><strong>srcY </strong></code></td> <td>
-offset into readable pixels in y</td>
+offset into readable pixels in y; may be negative</td>
   </tr>
 </table>
 
@@ -1064,7 +1074,9 @@
 
 ### Example
 
-<div><fiddle-embed name="af6dec8ef974aa67bf102f29915bcd6a">
+<div><fiddle-embed name="af6dec8ef974aa67bf102f29915bcd6a"><div><a href="SkCanvas_Reference#clear">clear</a> takes unpremultiplied input with <a href="undocumented#Alpha">Color Alpha</a> equal 0x80
+and <a href="undocumented#RGB">Color RGB</a> equal 0x55, 0xAA, 0xFF. <a href="undocumented#RGB">Color RGB</a> is multipled by <a href="undocumented#Alpha">Color Alpha</a>
+to generate premultipled value 0x802B5580.</div>
 
 #### Example Output
 
@@ -1074,6 +1086,10 @@
 
 </fiddle-embed></div>
 
+### See Also
+
+<a href="SkCanvas_Reference#peekPixels">peekPixels</a> <a href="SkCanvas_Reference#writePixels">writePixels</a> <a href="SkCanvas_Reference#drawBitmap">drawBitmap</a> <a href="SkCanvas_Reference#drawImage">drawImage</a>
+
 ---
 
 <a name="writePixels"></a>
@@ -1084,33 +1100,30 @@
                  int x, int y)
 </pre>
 
-Copies to <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="SkCanvas_Reference#pixels">pixels</a>, ignoring the <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a>, converting to match
-<a href="SkCanvas_Reference#info">info</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="SkCanvas_Reference#info">info</a> <a href="undocumented#Alpha_Type">Image Alpha Type</a>.
+Copies rectangle from <a href="SkCanvas_Reference#pixels">pixels</a> to <a href="SkCanvas_Reference#Canvas">Canvas</a>. <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a> are ignored.
+Source rectangle corners are (0, 0) and (<a href="SkCanvas_Reference#info">info</a>.width(), <a href="SkCanvas_Reference#info">info</a>.height()).
+Destination rectangle corners are (<a href="SkCanvas_Reference#x">x</a>, <a href="SkCanvas_Reference#y">y</a>) and
+(this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width(), this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height()). Copies each readable pixel
+intersecting both rectangles, without scaling, converting to
+this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.colorType() and this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.alphaType() if required.
 
-<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
-does not match <a href="SkCanvas_Reference#info">info</a>. Only <a href="SkCanvas_Reference#pixels">pixels</a> within the source rectangle that intersect
-<a href="SkCanvas_Reference#Canvas">Canvas</a> pixel bounds are copied. <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="SkCanvas_Reference#pixels">pixels</a> outside the rectangle intersection
-are unchanged.
+Pixels are writable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
+Pixels are not writable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>,
+returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#Canvas">Canvas</a> is the base of a utility
+class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
 
-| source rectangle | value |
-| --- | ---  |
-| left | <a href="SkCanvas_Reference#x">x</a> |
-| top | <a href="SkCanvas_Reference#y">y</a> |
-| width | <a href="SkCanvas_Reference#info">info</a>.width() |
-| height | <a href="SkCanvas_Reference#info">info</a>.height() |
+<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
+do not match. Only <a href="SkCanvas_Reference#pixels">pixels</a> within both source and destination rectangles
+are copied. <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="SkCanvas_Reference#pixels">pixels</a> outside the rectangle intersection are unchanged.
 
-| canvas pixel bounds | value |
-| --- | ---  |
-| left | 0 |
-| top | 0 |
-| width | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width() |
-| height | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height() |
+Pass negative values for <a href="SkCanvas_Reference#x">x</a> or <a href="SkCanvas_Reference#y">y</a> to offset <a href="SkCanvas_Reference#pixels">pixels</a> to the left or
+above <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="SkCanvas_Reference#pixels">pixels</a>.
 
 Does not copy, and returns false if:
 
 <table>  <tr>
-    <td>Source rectangle and canvas pixel bounds do not intersect.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#pixels">pixels</a> could not be converted to <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> or <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Alpha_Type">Image Alpha Type</a>.</td>  </tr>  <tr>
+    <td>Source and destination rectangles do not intersect.</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#pixels">pixels</a> could not be converted to this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.colorType() or this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.alphaType().</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="SkCanvas_Reference#pixels">pixels</a> are not writable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is document-based.</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#rowBytes">rowBytes</a> is too small to contain one row of <a href="SkCanvas_Reference#pixels">pixels</a>.</td>  </tr>
 </table>
@@ -1118,15 +1131,15 @@
 ### Parameters
 
 <table>  <tr>    <td><code><strong>info </strong></code></td> <td>
-dimensions, <a href="undocumented#Color_Type">Image Color Type</a>, and <a href="undocumented#Alpha_Type">Image Alpha Type</a> of <a href="SkCanvas_Reference#pixels">pixels</a></td>
+width, height, <a href="undocumented#Color_Type">Image Color Type</a>, and <a href="undocumented#Alpha_Type">Image Alpha Type</a> of <a href="SkCanvas_Reference#pixels">pixels</a></td>
   </tr>  <tr>    <td><code><strong>pixels </strong></code></td> <td>
-<a href="SkCanvas_Reference#pixels">pixels</a> to copy, of size <a href="SkCanvas_Reference#info">info</a>.height() times <a href="SkCanvas_Reference#rowBytes">rowBytes</a></td>
+<a href="SkCanvas_Reference#pixels">pixels</a> to copy, of size <a href="SkCanvas_Reference#info">info</a>.height() times <a href="SkCanvas_Reference#rowBytes">rowBytes</a>, or larger</td>
   </tr>  <tr>    <td><code><strong>rowBytes </strong></code></td> <td>
-offset from one row to the next, usually <a href="SkCanvas_Reference#info">info</a>.width() times pixel size</td>
+size of one <a href="SkCanvas_Reference#pixels">pixels</a> row; <a href="SkCanvas_Reference#info">info</a>.width() times pixel size, or larger</td>
   </tr>  <tr>    <td><code><strong>x </strong></code></td> <td>
-offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable <a href="SkCanvas_Reference#pixels">pixels</a> in <a href="SkCanvas_Reference#x">x</a></td>
+offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable <a href="SkCanvas_Reference#pixels">pixels</a> in <a href="SkCanvas_Reference#x">x</a>; may be negative</td>
   </tr>  <tr>    <td><code><strong>y </strong></code></td> <td>
-offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable <a href="SkCanvas_Reference#pixels">pixels</a> in <a href="SkCanvas_Reference#y">y</a></td>
+offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable <a href="SkCanvas_Reference#pixels">pixels</a> in <a href="SkCanvas_Reference#y">y</a>; may be negative</td>
   </tr>
 </table>
 
@@ -1138,40 +1151,41 @@
 
 <div><fiddle-embed name="29b98ebf58aa9fd1edfaabf9f4490b3a"></fiddle-embed></div>
 
+### See Also
+
+<a href="SkCanvas_Reference#readPixels">readPixels</a> <a href="SkCanvas_Reference#drawBitmap">drawBitmap</a> <a href="SkCanvas_Reference#drawImage">drawImage</a>
+
 ---
 
 <pre style="padding: 1em 1em 1em 1em;width: 50em; background-color: #f0f0f0">
 bool writePixels(const SkBitmap& bitmap, int x, int y)
 </pre>
 
-Writes to <a href="SkCanvas_Reference#Canvas">Canvas</a> pixels, ignoring the <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a>, converting to match
-<a href="SkCanvas_Reference#bitmap">bitmap</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="SkCanvas_Reference#bitmap">bitmap</a> <a href="undocumented#Alpha_Type">Image Alpha Type</a>.
+Copies rectangle from pixels to <a href="SkCanvas_Reference#Canvas">Canvas</a>. <a href="SkCanvas_Reference#Matrix">Matrix</a> and <a href="SkCanvas_Reference#Clip">Clip</a> are ignored.
+Source rectangle corners are (0, 0) and (<a href="SkCanvas_Reference#bitmap">bitmap</a>.width(), <a href="SkCanvas_Reference#bitmap">bitmap</a>.height()).
+Destination rectangle corners are (<a href="SkCanvas_Reference#x">x</a>, <a href="SkCanvas_Reference#y">y</a>) and
+(this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width(), this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height()). Copies each readable pixel
+intersecting both rectangles, without scaling, converting to
+this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.colorType() and this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.alphaType() if required.
 
-<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
-does not match <a href="SkCanvas_Reference#bitmap">bitmap</a>. Only pixels within the source rectangle that intersect
-<a href="SkCanvas_Reference#Canvas">Canvas</a> pixel bounds are copied. <a href="SkCanvas_Reference#Canvas">Canvas</a> pixels outside the rectangle intersection
-are unchanged.
+Pixels are writable when <a href="undocumented#Device">Device</a> is raster, or backed by a <a href="undocumented#GPU">GPU</a>.
+Pixels are not writable when <a href="SkCanvas_Reference#SkCanvas">SkCanvas</a> is returned by <a href="undocumented#beginPage">SkDocument::beginPage</a>,
+returned by <a href="undocumented#beginRecording">SkPictureRecorder::beginRecording</a>, or <a href="SkCanvas_Reference#Canvas">Canvas</a> is the base of a utility
+class like <a href="undocumented#SkDumpCanvas">SkDumpCanvas</a>.
 
-| source rectangle | value |
-| --- | ---  |
-| left | <a href="SkCanvas_Reference#x">x</a> |
-| top | <a href="SkCanvas_Reference#y">y</a> |
-| width | <a href="SkCanvas_Reference#bitmap">bitmap</a>.width() |
-| height | <a href="SkCanvas_Reference#bitmap">bitmap</a>.height() |
+<a href="undocumented#Pixel">Pixel</a> values are converted only if <a href="undocumented#Color_Type">Image Color Type</a> and <a href="undocumented#Alpha_Type">Image Alpha Type</a>
+do not match. Only pixels within both source and destination rectangles
+are copied. <a href="SkCanvas_Reference#Canvas">Canvas</a> pixels outside the rectangle intersection are unchanged.
 
-| canvas pixel bounds | value |
-| --- | ---  |
-| left | 0 |
-| top | 0 |
-| width | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.width() |
-| height | <a href="SkCanvas_Reference#imageInfo">imageInfo</a>.height() |
+Pass negative values for <a href="SkCanvas_Reference#x">x</a> or <a href="SkCanvas_Reference#y">y</a> to offset pixels to the left or
+above <a href="SkCanvas_Reference#Canvas">Canvas</a> pixels.
 
 Does not copy, and returns false if:
 
 <table>  <tr>
-    <td>Source rectangle and <a href="SkCanvas_Reference#Canvas">Canvas</a> pixel bounds do not intersect.</td>  </tr>  <tr>
+    <td>Source and destination rectangles do not intersect.</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#bitmap">bitmap</a> does not have allocated pixels.</td>  </tr>  <tr>
-    <td><a href="SkCanvas_Reference#bitmap">bitmap</a> pixels could not be converted to <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Color_Type">Image Color Type</a> or <a href="SkCanvas_Reference#Canvas">Canvas</a> <a href="undocumented#Alpha_Type">Image Alpha Type</a>.</td>  </tr>  <tr>
+    <td><a href="SkCanvas_Reference#bitmap">bitmap</a> pixels could not be converted to this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.colorType() or this-><a href="SkCanvas_Reference#imageInfo">imageInfo</a>.alphaType().</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#Canvas">Canvas</a> pixels are not writable; for instance, <a href="SkCanvas_Reference#Canvas">Canvas</a> is document-based.</td>  </tr>  <tr>
     <td><a href="SkCanvas_Reference#bitmap">bitmap</a> pixels are inaccessible; for instance, <a href="SkCanvas_Reference#bitmap">bitmap</a> wraps a texture.</td>  </tr>
 </table>
@@ -1181,9 +1195,9 @@
 <table>  <tr>    <td><code><strong>bitmap </strong></code></td> <td>
 contains pixels copied to <a href="SkCanvas_Reference#Canvas">Canvas</a></td>
   </tr>  <tr>    <td><code><strong>x </strong></code></td> <td>
-offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable pixels in <a href="SkCanvas_Reference#x">x</a></td>
+offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable pixels in <a href="SkCanvas_Reference#x">x</a>; may be negative</td>
   </tr>  <tr>    <td><code><strong>y </strong></code></td> <td>
-offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable pixels in <a href="SkCanvas_Reference#y">y</a></td>
+offset into <a href="SkCanvas_Reference#Canvas">Canvas</a> writable pixels in <a href="SkCanvas_Reference#y">y</a>; may be negative</td>
   </tr>
 </table>
 
@@ -1195,6 +1209,10 @@
 
 <div><fiddle-embed name="8b128e067881f9251357653692fa28da"></fiddle-embed></div>
 
+### See Also
+
+<a href="SkCanvas_Reference#readPixels">readPixels</a> <a href="SkCanvas_Reference#drawBitmap">drawBitmap</a> <a href="SkCanvas_Reference#drawImage">drawImage</a>
+
 ---
 
 # <a name="State_Stack"></a> State Stack
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index 939519e..cbb34a2 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -430,17 +430,24 @@
                 }
             } else if (!incEof && '#' == inc.peek() && (defEof || '#' != def.peek())) {
                 inc.next();
-                SkASSERT(inc.startsWith("if"));
-                inc.skipToEndBracket("#");
-                SkASSERT(inc.startsWith("#endif"));
-                inc.skipToEndBracket("\n");
+                if (inc.startsWith("if")) {
+                    inc.skipToEndBracket("\n");
+                } else if (inc.startsWith("endif")) {
+                    inc.skipToEndBracket("\n");
+                } else {
+                    SkASSERT(0); // incomplete
+                    return false;
+                }
             } else {
                 break;
             }
             inc.next();
         } while (true);
         if (defEof || incEof) {
-            return defEof == incEof || (!defEof && ';' == def.peek());
+            if (defEof == incEof || (!defEof && ';' == def.peek())) {
+                return true;
+            }
+            return false;  // allow setting breakpoint on failure
         }
         char defCh;
         do {
@@ -1960,7 +1967,7 @@
 
 DEFINE_string2(bmh, b, "", "A path to a *.bmh file or a directory.");
 DEFINE_string2(examples, e, "", "File of fiddlecli input, usually fiddle.json (For now, disables -r -f -s)");
-DEFINE_string2(fiddle, f, "fiddleout.json", "File of fiddlecli output.");
+DEFINE_string2(fiddle, f, "", "File of fiddlecli output, usually fiddleout.json.");
 DEFINE_string2(include, i, "", "A path to a *.h file or a directory.");
 DEFINE_bool2(hack, k, false, "Do a find/replace hack to update all *.bmh files. (Requires -b)");
 DEFINE_bool2(populate, p, false, "Populate include from bmh. (Requires -b -i)");
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 826c321..6aed937 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -315,6 +315,7 @@
                 } break;
                 case MarkType::kComment:
                     break;
+                case MarkType::kEnumClass:
                 case MarkType::kEnum: {
                     if (!def) {
                         // work backwards from first word to deduce #Enum name
@@ -366,7 +367,9 @@
                        SkDebugf("enum differs from bmh: %s\n", def->fName.c_str());
                     }
                     for (auto& child : token.fChildren) {
-                        string constName = className + "::" + child->fName;
+                        string constName = MarkType::kEnumClass == token.fMarkType ?
+                                fullName : className;
+                        constName += "::" + child->fName;
                         def = root->find(constName);
                         if (!def) {
                             string innerName = classMapper.first + "::" + child->fName;