work on skimageinfo

work on skimageinfo

Docs-Preview: https://skia.org/?cl=109081
TBR=caryclark@google.com
Bug: skia:6898
Change-Id: I4d1734647ef1fa879d08b04c64142c7f16abc858
Reviewed-on: https://skia-review.googlesource.com/109081
Commit-Queue: Cary Clark <caryclark@skia.org>
Reviewed-by: Cary Clark <caryclark@skia.org>
diff --git a/docs/SkBitmap_Reference.bmh b/docs/SkBitmap_Reference.bmh
index a11330a..39719a9 100644
--- a/docs/SkBitmap_Reference.bmh
+++ b/docs/SkBitmap_Reference.bmh
@@ -3275,7 +3275,7 @@
 Sets dst to Alpha described by pixels. Returns false if dst cannot be written to
 or dst pixels cannot be allocated.
 
-If paint is not nullptr and contains Mask_Filter, SkMaskFilter::filterMask 
+If paint is not nullptr and contains Mask_Filter, SkMaskFilter 
 generates Mask_Alpha from Bitmap. Uses HeapAllocator to reserve memory for dst
 Pixel_Ref. Sets offset to top-left position for dst for alignment with Bitmap;
 (0, 0) unless SkMaskFilter generates mask.
@@ -3322,7 +3322,7 @@
 Sets dst to Alpha described by pixels. Returns false if dst cannot be written to
 or dst pixels cannot be allocated.
 
-If paint is not nullptr and contains Mask_Filter, SkMaskFilter::filterMask 
+If paint is not nullptr and contains Mask_Filter, SkMaskFilter 
 generates Mask_Alpha from Bitmap. allocator may reference a custom allocation
 class or be set to nullptr to use HeapAllocator. Sets offset to top-left  
 position for dst for alignment with Bitmap; (0, 0) unless SkMaskFilter generates
diff --git a/docs/SkImageInfo_Reference.bmh b/docs/SkImageInfo_Reference.bmh
index 946fc84..38e5a6d 100644
--- a/docs/SkImageInfo_Reference.bmh
+++ b/docs/SkImageInfo_Reference.bmh
@@ -1,6 +1,16 @@
 #Topic Image_Info
 #Alias Image_Info_Reference
 
+Image_Info specifies the dimensions and encoding of the pixels in a Bitmap.
+The dimensions are integral width and height. The encoding is how pixel
+bits describe Color_Alpha, transparency; Color components red, blue,
+and green; and Color_Space, the range and linearity of colors.
+
+Image_Info describes an uncompressed raster pixels. In contrast, Image
+additionally describes compressed pixels like PNG, and Surface describes
+destinations on the GPU. Image and Surface may be specified by Image_Info,
+but Image and Surface may not contain Image_Info.
+
 #Subtopic Overview
     #Subtopic Subtopic
     #Populate
@@ -13,11 +23,12 @@
 
 # ------------------------------------------------------------------------------
 #Subtopic Alpha_Type
-#Line # incomplete ##
+#Line # encoding for pixel transparency ##
 #Alias Alpha_Type
 #Alias Alpha_Types
+
 #Enum SkAlphaType
-#Line # incomplete ##
+#Line # encoding for pixel transparency ##
 
 #Code
     enum SkAlphaType {
@@ -29,36 +40,157 @@
     };
 ##
 
-Describes how to interpret the alpha component of a pixel.
+Describes how to interpret the alpha component of a pixel. A pixel may
+be opaque, or Color_Alpha, describing multiple levels of transparency.
+
+In simple blending, Color_Alpha weights the draw color and the destination
+color to create a new color. If alpha describes a weight from zero to one:
+
+#Formula
+    new color = draw color * alpha + destination color * (1 - alpha)
+##
+
+In practice alpha is encoded in two or more bits, where 1.0 equals all bits set.
+
+Color_RGB may have Color_Alpha included in each component value; the stored
+value is the original Color_RGB multiplied by Color_Alpha. Premultiplied color
+components improve performance.
 
 #Const kUnknown_SkAlphaType 0
+Alpha_Type is uninitialized.
 ##
 #Const kOpaque_SkAlphaType 1
-All pixels are stored as opaque.
+Pixels are opaque. The Color_Type must have no explicit alpha
+component, or all alpha components must be set to their maximum value.
 ##
 #Const kPremul_SkAlphaType 2
-All pixels have their alpha premultiplied in their color components.
-This is the natural format for the rendering target pixels.
+Pixels have alpha premultiplied into color components.
+Surface pixels must be premultiplied.
 ##
 #Const kUnpremul_SkAlphaType 3
-All pixels have their color components stored without any regard to the
-alpha. e.g. this is the default configuration for PNG images.
-kUnpremul_SkAlphaType is supported only for input images. Rendering cannot
-generate this on output.
+Pixel color component values are independent of alpha value.
+Images generated from encoded data like PNG do not premultiply pixel color
+components. kUnpremul_SkAlphaType is supported for Image pixels, but not for
+Surface pixels.
 ##
 
-#Example
-// incomplete
+#NoExample
 ##
 
-#SeeAlso incomplete
+#SeeAlso SkColorType SkColorSpace
 
 #Enum SkAlphaType ##
+
+#Subtopic Opaque
+
+Use Opaque as a hint to optimize drawing when alpha component
+of all pixel is set to its maximum value of 1.0; all alpha component bits are set.
+If Image_Info is set to Opaque but all alpha values are not 1.0, results are
+undefined.
+
+#Example
+#Height 64
+#Description
+SkPreMultiplyARGB parameter a is set to 255, its maximum value, and is interpreted
+as Color_Alpha of 1.0. kOpaque_SkAlphaType may be set to improve performance.
+If SkPreMultiplyARGB parameter a is set to a value smaller than 255, 
+kPremul_SkAlphaType must be used instead to avoid undefined results.
+The four displayed values are the original component values, though not necessarily
+in the same order.
+##
+    SkPMColor color = SkPreMultiplyARGB(255, 50, 100, 150);
+    SkString s;
+    s.printf("%u %u %u %u", SkColorGetA(color), SkColorGetR(color),
+                            SkColorGetG(color), SkColorGetB(color));
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    canvas->drawString(s, 10, 62, paint);
+    canvas->scale(50, 50);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(1, 1, kN32_SkColorType, kOpaque_SkAlphaType);
+    if (bitmap.installPixels(imageInfo, (void*) &color, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 0, 0);
+    }
+##
+
+#Subtopic Opaque ##
+
+#Subtopic Premul
+
+Use Premul when stored color components are the original color multiplied by the
+alpha component. The alpha component range of 0.0 to 1.0 is achieved by dividing
+the integer bit value by the maximum bit value.
+
+#Formula
+stored color = original color * alpha / max alpha
+##
+
+The color component must be equal to or smaller than the alpha component,
+or the results are undefined.
+
+#Example
+#Description
+SkPreMultiplyARGB parameter a is set to 150, less than its maximum value, and is
+interpreted as Color_Alpha of about 0.6. kPremul_SkAlphaType must be set, since
+SkPreMultiplyARGB parameter a is set to a value smaller than 255, 
+to avoid undefined results.
+The four displayed values reflect that the alpha component has been multiplied
+by the original color.
+##
+#Height 64
+    SkPMColor color = SkPreMultiplyARGB(150, 50, 100, 150);
+    SkString s;
+    s.printf("%u %u %u %u", SkColorGetA(color), SkColorGetR(color),
+                            SkColorGetG(color), SkColorGetB(color));
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    canvas->drawString(s, 10, 62, paint);
+    canvas->scale(50, 50);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(1, 1, kN32_SkColorType, kPremul_SkAlphaType);
+    if (bitmap.installPixels(imageInfo, (void*) &color, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 0, 0);
+    }
+##
+
+#Subtopic Premul ##
+
+#Subtopic Unpremul
+
+Use Unpremul if stored color components are not divided by the alpha component.
+Some drawing destinations may not support Unpremul.
+
+#Bug 7079
+#Example
+#Description
+SkColorSetARGB parameter a is set to 150, less than its maximum value, and is
+interpreted as Color_Alpha of about 0.6. color is not premultiplied;
+color components may have values greater than color alpha.
+The four displayed values are the original component values, though not necessarily
+in the same order.
+##
+    SkColor color = SkColorSetARGB(150, 50, 100, 255);
+    SkString s;
+    s.printf("%u %u %u %u", SkColorGetA(color), SkColorGetR(color),
+                            SkColorGetG(color), SkColorGetB(color));
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    canvas->drawString(s, 10, 62, paint);
+    canvas->scale(50, 50);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(1, 1, kN32_SkColorType, kUnpremul_SkAlphaType);
+    if (bitmap.installPixels(imageInfo, (void*) &color, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 0, 0);
+    }
+##
+
+#Subtopic Unpremul ##
+
 #Subtopic Alpha_Type ##
 
 # ------------------------------------------------------------------------------
 #Subtopic Color_Type
-#Line # incomplete ##
+#Line # encoding for pixel color ##
 #Alias Color_Type
 #Alias Color_Types
 
@@ -68,7 +200,7 @@
 ##
 
 #Enum SkColorType
-#Line # incomplete ##
+#Line # encoding for pixel color ##
 
 #Code
     enum SkColorType {
@@ -89,7 +221,8 @@
     };
 ##
 
-Describes how to interpret the components of a pixel.
+Describes how pixel bits encode color. A pixel may be an alpha mask, a
+gray level, Color_RGB, or Color_ARGB. 
 
 kN32_SkColorType selects the native 32-bit Color_ARGB format. On Little_Endian
 processors, pixels containing 8-bit Color_ARGB components pack into 32-bit
@@ -97,38 +230,467 @@
 kRGBA_8888_SkColorType.
 
 #Const kUnknown_SkColorType 0
+
 ##
 #Const kAlpha_8_SkColorType 1
+    Encodes Color_Alpha as Alpha_8 pixel in an 8-bit byte.
 ##
 #Const kRGB_565_SkColorType 2
+    Encodes Color_RGB as BGR_565 pixel in a 16-bit word.
 ##
 #Const kARGB_4444_SkColorType 3
+    Encodes Color_ARGB as ABGR_4444 pixel in a 16-bit word.
 ##
 #Const kRGBA_8888_SkColorType 4
+    Encodes Color_ARGB as RGBA_8888 pixel in a 32-bit word.
 ##
 #Const kRGB_888x_SkColorType 5
+    Encodes Color_RGB as RGB_888x pixel in a 32-bit word.
 ##
 #Const kBGRA_8888_SkColorType 6
+    Encodes Color_ARGB as BGRA_8888 pixel in a 32-bit word.
 ##
 #Const kRGBA_1010102_SkColorType 7
+    Encodes Color_ARGB as RGBA_1010102 pixel in a 32-bit word.
 ##
 #Const kRGB_101010x_SkColorType 8
+    Encodes Color_RGB as RGB_101010x pixel in a 32-bit word.
 ##
 #Const kGray_8_SkColorType 9
+    Encodes Color_Gray as Gray_8 in an 8-bit byte.
 ##
 #Const kRGBA_F16_SkColorType 10
+    Encodes Color_ARGB as RGBA_F16 in a 64-bit word.
 ##
+
 #ToDo  can be 4 or 6; how to document? ##
 #Const kN32_SkColorType 4
+    Encodes Color_ARGB as either RGBA_8888 or BGRA_8888, whichever
+    is native to the platform.
+##
+
+#NoExample
+##
+
+#SeeAlso SkAlphaType SkColorSpace
+
+#Enum SkColorType ##
+
+#Subtopic Alpha_8
+
+Alpha_8 is an 8-bit byte pixel encoding that represents transparency. A value of zero is
+completely transparent; a value of 255 is completely opaque. Bitmap with Alpha_8
+pixels does not visibly draw, because its pixels have no color information.
+The paired SkAlphaType is ignored.
+
+#Example
+#Description
+Alpha_8 pixels can modify another draw. orangePaint fills the bounds of bitmap,
+with its transparency set to alpha8 pixel value.
+##
+#Height 64
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kAlpha_8_SkColorType, kOpaque_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    SkPaint orangePaint;
+    orangePaint.setARGB(0xFF, 0xFF, 0xA5, 0x00);
+    canvas->drawBitmap(bitmap, 0, 0, &orangePaint);
+    uint8_t alpha8[] = { 0xFF, 0xBB, 0x77, 0x33 };
+    SkPixmap alphaPixmap(imageInfo, &alpha8, imageInfo.minRowBytes());
+    if (bitmap.writePixels(alphaPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2, &orangePaint);
+    }
+##
+##
+
+#Subtopic BGR_565
+
+BGR_565 is a 16-bit word pixel encoding that contains five bits of blue,
+six bits of green, and five bits of red. BGR_565 is fully opaque as if its
+Color_Alpha was set to one, and should always be paired with kOpaque_SkAlphaType.
+
+#Illustration
+
+#Example
+#Height 96
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGB_565_SkColorType, kOpaque_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack565 = [](unsigned r, unsigned g, unsigned b) -> uint16_t {
+        return (b << 0) | (g << 5) | (r << 11);
+    };
+    uint16_t red565[] =  { pack565(0x1F, 0x00, 0x00), pack565(0x17, 0x00, 0x00), 
+                           pack565(0x0F, 0x00, 0x00), pack565(0x07, 0x00, 0x00) };
+    uint16_t blue565[] = { pack565(0x00, 0x00, 0x1F), pack565(0x00, 0x00, 0x17),
+                           pack565(0x00, 0x00, 0x0F), pack565(0x00, 0x00, 0x07) };
+    SkPixmap redPixmap(imageInfo, &red565, imageInfo.minRowBytes());
+    if (bitmap.writePixels(redPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, &blue565, imageInfo.minRowBytes());
+    if (bitmap.writePixels(bluePixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic ABGR_4444
+
+ABGR_4444 is a 16-bit word pixel encoding that contains four bits of alpha,
+four bits of blue, four bits of green, and four bits of red. 
+
+#Illustration
+
+If paired with kPremul_SkAlphaType: blue, green, and red components are
+premultiplied by the alpha value. If blue, green, or red is greater than alpha,
+the drawn result is undefined.
+
+If paired with kUnpremul_SkAlphaType: alpha, blue, green, and red components
+may have any value. There may be a performance penalty with unpremultipled
+pixels.
+
+If paired with kOpaque_SkAlphaType: all alpha component values are at the maximum;
+blue, green, and red components are fully opaque. If any alpha component is
+less than 15, the drawn result is undefined.
+
+#Bug 7648
+
+#Example
+#Height 96
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kARGB_4444_SkColorType, kPremul_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack4444 = [](unsigned a, unsigned r, unsigned g, unsigned b) -> uint16_t {
+        return (a << 0) | (b << 4) | (g << 8) | (r << 12);
+    };
+    uint16_t red4444[] =  { pack4444(0xF, 0xF, 0x0, 0x0), pack4444(0xF, 0xb, 0x0, 0x0), 
+                            pack4444(0xF, 0x7, 0x0, 0x0), pack4444(0xF, 0x3, 0x0, 0x0) };
+    uint16_t blue4444[] = { pack4444(0xF, 0x0, 0x0, 0xF), pack4444(0xF, 0x0, 0x0, 0xb),
+                            pack4444(0xF, 0x0, 0x0, 0x7), pack4444(0xF, 0x0, 0x0, 0x3) };
+    SkPixmap redPixmap(imageInfo, &red4444, imageInfo.minRowBytes());
+    if (bitmap.writePixels(redPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, &blue4444, imageInfo.minRowBytes());
+    if (bitmap.writePixels(bluePixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic RGBA_8888
+
+RGBA_8888 is a 32-bit word pixel encoding that contains eight bits of red,
+eight bits of green, eight bits of blue, and eight bits of alpha. 
+
+#Illustration
+
+If paired with kPremul_SkAlphaType: red, green, and blue components are
+premultiplied by the alpha value. If red, green, or blue is greater than alpha,
+the drawn result is undefined.
+
+If paired with kUnpremul_SkAlphaType: alpha, red, green, and blue components
+may have any value. There may be a performance penalty with unpremultipled
+pixels.
+
+If paired with kOpaque_SkAlphaType: all alpha component values are at the maximum; 
+red, green, and blue components are fully opaque. If any alpha component is
+less than 255, the drawn result is undefined.
+
+On Big_Endian platforms, RGBA_8888 is the native Color_Type, and will have
+the best performance. Use kN32_SkColorType to choose the best Color_Type for
+the platform at compile time.
+
+#Example
+#Height 96
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack8888 = [](unsigned a, unsigned r, unsigned g, unsigned b) -> uint32_t {
+        return (r << 0) | (g << 8) | (b << 16) | (a << 24);
+    };
+    uint32_t red8888[] = { pack8888(0xFF, 0xFF, 0x0, 0x0), pack8888(0xFF, 0xbb, 0x0, 0x0), 
+                           pack8888(0xFF, 0x77, 0x0, 0x0), pack8888(0xFF, 0x33, 0x0, 0x0) };
+    uint32_t blue8888[] = { pack8888(0xFF, 0x0, 0x0, 0x0FF), pack8888(0xFF, 0x0, 0x0, 0x0bb),
+                            pack8888(0xFF, 0x0, 0x0, 0x077), pack8888(0xFF, 0x0, 0x0, 0x033) };
+    SkPixmap redPixmap(imageInfo, &red8888, imageInfo.minRowBytes());
+    if (bitmap.writePixels(redPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, &blue8888, imageInfo.minRowBytes());
+    if (bitmap.writePixels(bluePixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic RGB_888x
+
+RGB_888x is a 32-bit word pixel encoding that contains eight bits of red,
+eight bits of green, eight bits of blue, and eight unused bits. RGB_888x is fully 
+opaque as if its Color_Alpha was set to one, and should always be paired with
+kOpaque_SkAlphaType.
+
+#Illustration
+
+#Example
+#Bug 7645
+#Height 96
+#Platform cpu
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGB_888x_SkColorType, kOpaque_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack888 = [](unsigned r, unsigned g, unsigned b) -> uint32_t {
+        return (r << 0) | (g << 8) | (b << 16);
+    };
+    uint32_t red888[] =  { pack888(0xFF, 0x00, 0x00), pack888(0xbb, 0x00, 0x00), 
+        pack888(0x77, 0x00, 0x00), pack888(0x33, 0x00, 0x00) };
+    uint32_t blue888[] = { pack888(0x00, 0x00, 0xFF), pack888(0x00, 0x00, 0xbb),
+        pack888(0x00, 0x00, 0x77), pack888(0x00, 0x00, 0x33) };
+    if (bitmap.installPixels(imageInfo, (void*) red888, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    if (bitmap.installPixels(imageInfo, (void*) blue888, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic BGRA_8888
+
+BGRA_8888 is a 32-bit word pixel encoding that contains eight bits of blue,
+eight bits of green, eight bits of red, and eight bits of alpha. 
+
+#Illustration
+
+If paired with kPremul_SkAlphaType: blue, green, and red components are
+premultiplied by the alpha value. If blue, green, or red is greater than alpha,
+the drawn result is undefined.
+
+If paired with kUnpremul_SkAlphaType: blue, green, red, and alpha components
+may have any value. There may be a performance penalty with unpremultipled
+pixels.
+
+If paired with kOpaque_SkAlphaType: all alpha component values are at the maximum; 
+blue, green, and red components are fully opaque. If any alpha component is
+less than 255, the drawn result is undefined.
+
+On Little_Endian platforms, BGRA_8888 is the native Color_Type, and will have
+the best performance. Use kN32_SkColorType to choose the best Color_Type for
+the platform at compile time.
+
+#Example
+#Height 96
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack8888 = [](unsigned a, unsigned r, unsigned g, unsigned b) -> uint32_t {
+        return (b << 0) | (g << 8) | (r << 16) | (a << 24);
+    };
+    uint32_t red8888[] = { pack8888(0xFF, 0xFF, 0x0, 0x0), pack8888(0xFF, 0xbb, 0x0, 0x0), 
+                           pack8888(0xFF, 0x99, 0x0, 0x0), pack8888(0xFF, 0x55, 0x0, 0x0) };
+    uint32_t blue8888[] = { pack8888(0xFF, 0x0, 0x0, 0x0FF), pack8888(0xFF, 0x0, 0x0, 0x0bb),
+                            pack8888(0xFF, 0x0, 0x0, 0x099), pack8888(0xFF, 0x0, 0x0, 0x055) };
+    SkPixmap redPixmap(imageInfo, &red8888, imageInfo.minRowBytes());
+    if (bitmap.writePixels(redPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, &blue8888, imageInfo.minRowBytes());
+    if (bitmap.writePixels(bluePixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic RGBA_1010102
+
+RGBA_1010102 is a 32-bit word pixel encoding that contains ten bits of red,
+ten bits of green, ten bits of blue, and two bits of alpha. Possible alpha
+values are zero: fully transparent; one: 33% opaque; two: 67% opaque;
+three: fully opaque. 
+
+#Illustration
+
+If paired with kPremul_SkAlphaType: red, green, and blue components are
+premultiplied by the alpha value. If red, green, or blue is greater than the
+alpha replicated to ten bits, the drawn result is undefined.
+
+If paired with kUnpremul_SkAlphaType: alpha, red, green, and blue components
+may have any value. There may be a performance penalty with unpremultipled
+pixels.
+
+If paired with kOpaque_SkAlphaType: all alpha component values are at the maximum; 
+red, green, and blue components are fully opaque. If any alpha component is
+less than 3, the drawn result is undefined.
+
+#Example
+#Bug 7645
+#Height 96
+#Platform cpu
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGBA_1010102_SkColorType, kOpaque_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack1010102 = [](unsigned r, unsigned g, unsigned b, unsigned a) -> uint32_t {
+        return (r << 0) | (g << 10) | (b << 20) | (a << 30);
+    };
+    uint32_t redBits[] =  { pack1010102(0x3FF, 0x000, 0x000, 0x3), 
+                            pack1010102(0x2ff, 0x000, 0x000, 0x3), 
+                            pack1010102(0x1ff, 0x000, 0x000, 0x3), 
+                            pack1010102(0x0ff, 0x000, 0x000, 0x3) };
+    uint32_t blueBits[] = { pack1010102(0x000, 0x000, 0x3FF, 0x3), 
+                            pack1010102(0x000, 0x000, 0x2ff, 0x3),
+                            pack1010102(0x000, 0x000, 0x1ff, 0x3), 
+                            pack1010102(0x000, 0x000, 0x0ff, 0x3) };
+    if (bitmap.installPixels(imageInfo, (void*) redBits, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, &blueBits, imageInfo.minRowBytes());
+    if (bitmap.installPixels(imageInfo, (void*) blueBits, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic RGB_101010x
+
+#Illustration
+
+#Example
+#Bug 7645
+#Height 96
+#Platform cpu
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGB_101010x_SkColorType, kOpaque_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto pack101010x = [](unsigned r, unsigned g, unsigned b) -> uint32_t {
+        return (r << 0) | (g << 10) | (b << 20);
+    };
+    uint32_t redBits[] =  { pack101010x(0x3FF, 0x000, 0x000), pack101010x(0x2ff, 0x000, 0x000), 
+    pack101010x(0x1ff, 0x000, 0x000), pack101010x(0x0ff, 0x000, 0x000) };
+    uint32_t blueBits[] = { pack101010x(0x000, 0x000, 0x3FF), pack101010x(0x000, 0x000, 0x2ff),
+    pack101010x(0x000, 0x000, 0x1ff), pack101010x(0x000, 0x000, 0x0ff) };
+    if (bitmap.installPixels(imageInfo, (void*) redBits, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, &blueBits, imageInfo.minRowBytes());
+    if (bitmap.installPixels(imageInfo, (void*) blueBits, imageInfo.minRowBytes())) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+##
+##
+
+#Subtopic Gray_8
+
+#Example
+#Height 64
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kGray_8_SkColorType, kOpaque_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    uint8_t gray8[] = { 0xFF, 0xBB, 0x77, 0x33 };
+    SkPixmap grayPixmap(imageInfo, &gray8, imageInfo.minRowBytes());
+    if (bitmap.writePixels(grayPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+##
+##
+
+#Subtopic RGBA_F16
+
+#Illustration
+
+#ToDo
+FloatToHalf should be replaced with SkFloatToHalf if/when that's made public
 ##
 
 #Example
-// incomplete
+#Height 96
+#Function
+union FloatUIntUnion {
+    uint32_t fUInt;
+    float    fFloat;
+};
+
+uint16_t FloatToHalf(float f) {
+    static const FloatUIntUnion magic = { 15 << 23 };
+    static const uint32_t round_mask = ~0xfffu;
+    FloatUIntUnion floatUnion;
+    floatUnion.fFloat = f;
+    uint32_t sign = floatUnion.fUInt & 0x80000000u;
+    floatUnion.fUInt ^= sign;
+    floatUnion.fUInt &= round_mask;
+    floatUnion.fFloat *= magic.fFloat;
+    floatUnion.fUInt -= round_mask;
+    return (floatUnion.fUInt >> 13) | (sign >> 16);
+}
 ##
 
-#SeeAlso incomplete
+void draw(SkCanvas* canvas) {    
+    canvas->scale(16, 16);
+    SkBitmap bitmap;
+    SkImageInfo imageInfo = SkImageInfo::Make(2, 2, kRGBA_F16_SkColorType, kPremul_SkAlphaType);
+    bitmap.allocPixels(imageInfo);
+    SkCanvas offscreen(bitmap);
+    offscreen.clear(SK_ColorGREEN);
+    canvas->drawBitmap(bitmap, 0, 0);
+    auto H = [](float c) -> uint16_t {
+        return FloatToHalf(c);
+    };
+                             //     R        G        B        A
+    uint16_t red_f16[][4] =  { { H(1.0f), H(0.0f), H(0.0f), H(1.0f) },
+                               { H(.75f), H(0.0f), H(0.0f), H(1.0f) }, 
+                               { H(.50f), H(0.0f), H(0.0f), H(1.0f) },
+                               { H(.25f), H(0.0f), H(0.0f), H(1.0f) } };
+    uint16_t blue_f16[][4] = { { H(0.0f), H(0.0f), H(1.0f), H(1.0f) },
+                               { H(0.0f), H(0.0f), H(.75f), H(1.0f) }, 
+                               { H(0.0f), H(0.0f), H(.50f), H(1.0f) },
+                               { H(0.0f), H(0.0f), H(.25f), H(1.0f) } };
+    SkPixmap redPixmap(imageInfo, red_f16, imageInfo.minRowBytes());
+    if (bitmap.writePixels(redPixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 2, 2);
+    }
+    SkPixmap bluePixmap(imageInfo, blue_f16, imageInfo.minRowBytes());
+    if (bitmap.writePixels(bluePixmap, 0, 0)) {
+        canvas->drawBitmap(bitmap, 4, 4);
+    }
+}
+##
+##
 
-#Enum SkColorType ##
 #Subtopic Color_Type ##
 
 # ------------------------------------------------------------------------------
diff --git a/docs/SkImage_Reference.bmh b/docs/SkImage_Reference.bmh
index fa08509..7f5832f 100644
--- a/docs/SkImage_Reference.bmh
+++ b/docs/SkImage_Reference.bmh
@@ -381,7 +381,8 @@
                                           SkColorType colorType,
                                           SkAlphaType alphaType,
                                           sk_sp<SkColorSpace> colorSpace)
-
+#In Constructor
+#Line # creates Image from GPU_Texture ##
 Creates Image from GPU_Texture associated with context. Caller is responsible for
 managing the lifetime of GPU_Texture.
 
diff --git a/docs/SkPaint_Reference.bmh b/docs/SkPaint_Reference.bmh
index b92fa4b..6a40f75 100644
--- a/docs/SkPaint_Reference.bmh
+++ b/docs/SkPaint_Reference.bmh
@@ -814,7 +814,7 @@
 
 ##
 
-#Subtopic Antialias ##
+#Subtopic Anti-alias ##
 # ------------------------------------------------------------------------------
 #Subtopic Dither
 #Line # distributing color error ##
diff --git a/docs/illustrations.bmh b/docs/illustrations.bmh
new file mode 100644
index 0000000..a7b5068
--- /dev/null
+++ b/docs/illustrations.bmh
@@ -0,0 +1,452 @@
+#Topic Illustrations

+

+#Subtopic Image_Info_Color_Type_BGR_565

+#Example

+#Width 415

+#Height 250

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("16-bit word", 5 + 20 * 8, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 1.5f, 137, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 6.5f, 187, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 5, 11, 16, 

+                         0, 3, 8,

+                         0, 5, 8 };

+    const char* labels[] = { "red", "green", "blue" };

+    drawBoxText(&edges[0], &labels[0], 3, 15, 45);

+    drawBoxText(&edges[4], &labels[1], 2, 7, 110);

+    drawBoxText(&edges[7], &labels[0], 2, 7, 160);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_ABGR_4444

+#Example

+#Width 415

+#Height 250

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("16-bit word", 5 + 20 * 8, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 4, 8, 12, 16 };

+    const char* labels[] = { "red", "green", "blue", "alpha" };

+    drawBoxText(&edges[0], &labels[0], 4, 15, 45);

+    drawBoxText(&edges[0], &labels[2], 2, 7, 110);

+    drawBoxText(&edges[0], &labels[0], 2, 7, 160);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_RGBA_8888

+#Example

+#Width 812

+#Height 365

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 8, 16, 24, 32 };

+    const char* labels[] = { "alpha", "blue", "green", "red" };

+    drawBoxText(edges, &labels[0], 4, 31, 45);

+    drawBoxText(edges, &labels[3], 1, 7, 110);

+    drawBoxText(edges, &labels[2], 1, 7, 160);

+    drawBoxText(edges, &labels[1], 1, 7, 210);

+    drawBoxText(edges, &labels[0], 1, 7, 260);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_RGB_888x

+#Example

+#Width 812

+#Height 365

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 8, 16, 24, 32 };

+    const char* labels[] = { "(unused)", "blue", "green", "red" };

+    drawBoxText(edges, &labels[0], 4, 31, 45);

+    drawBoxText(edges, &labels[3], 1, 7, 110);

+    drawBoxText(edges, &labels[2], 1, 7, 160);

+    drawBoxText(edges, &labels[1], 1, 7, 210);

+    drawBoxText(edges, &labels[0], 1, 7, 260);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_BGRA_8888

+#Example

+#Width 812

+#Height 365

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 8, 16, 24, 32 };

+    const char* labels[] = { "alpha", "red", "green", "blue" };

+    drawBoxText(edges, &labels[0], 4, 31, 45);

+    drawBoxText(edges, &labels[3], 1, 7, 110);

+    drawBoxText(edges, &labels[2], 1, 7, 160);

+    drawBoxText(edges, &labels[1], 1, 7, 210);

+    drawBoxText(edges, &labels[0], 1, 7, 260);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_RGBA_1010102

+#Example

+#Width 812

+#Height 380

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 4, 137, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 3, 187, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 7, 187, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 2, 237, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 6, 237, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 5, 287, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 2, 12, 22, 32,

+                         0, 8,

+                         0, 6, 8,

+                         0, 4, 8,

+                         0, 2, 8

+                        };

+    const char* labels[] = { "alpha", "blue", "green", "red" };

+    drawBoxText(&edges[0], &labels[0], 4, 31, 45);

+    drawBoxText(&edges[5], &labels[3], 1, 7, 110);

+    drawBoxText(&edges[7], &labels[2], 2, 7, 160);

+    drawBoxText(&edges[10], &labels[1], 2, 7, 210);

+    drawBoxText(&edges[13], &labels[0], 2, 7, 260);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_RGB_101010x

+#Example

+#Width 812

+#Height 380

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("32-bit word", 5 + 20 * 16, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 85, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 4, 137, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 3, 187, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 7, 187, paint);

+    canvas->drawString("(low bits)", 5 + 20 * 2, 237, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 6, 237, paint);

+    canvas->drawString("(high bits)", 5 + 20 * 5, 287, paint);

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 2, 12, 22, 32,

+                         0, 8,

+                         0, 6, 8,

+                         0, 4, 8,

+                         0, 2, 8

+                        };

+    const char* labels[] = { "unused", "blue", "green", "red" };

+    drawBoxText(&edges[0], &labels[0], 4, 31, 45);

+    drawBoxText(&edges[5], &labels[3], 1, 7, 110);

+    drawBoxText(&edges[7], &labels[2], 2, 7, 160);

+    drawBoxText(&edges[10], &labels[1], 2, 7, 210);

+    drawBoxText(&edges[13], &labels[0], 2, 7, 260);

+}

+##

+##

+

+#Subtopic Image_Info_Color_Type_RGBA_F16

+#Example

+#Width 812

+#Height 685

+void draw(SkCanvas* canvas) {

+    canvas->scale(1.25f, 1.25f);

+    SkPaint paint;

+    paint.setAntiAlias(true);

+    paint.setTextSize(10);

+    paint.setTextAlign(SkPaint::kCenter_Align);

+    canvas->drawString("64-bit word", 5 + 20 * 16, 20, paint);

+    canvas->drawString("little endian byte order", 5 + 20 * 4, 135, paint);

+    for (int i = 0; i < 4; ++i) {

+        canvas->drawString("(low bits)", 5 + 20 * 4, 187 + i * 100, paint);

+        canvas->drawString("(high bits)", 5 + 20 * 4, 237 + i * 100, paint);

+    }

+    auto drawBoxText = [=](SkScalar e[], const char* s[], int count, int n, SkScalar yPos) -> void {

+        SkPaint p(paint);

+        p.setColor(SK_ColorRED);

+        SkScalar xPos = 15;

+        int width = n % 32 + 1;

+        int lastN = n > 32 ? 32 : 0;

+        for (; n >= lastN; --n) {

+            for (int i = 0; i <= count; ++i) {

+                int a = width - e[i];

+                if (a == n || a == n + 1 || a == n - 32 || a == n - 31) {

+                    char num[3] = {(char) ('0' + n / 10), (char) ('0' + n % 10), '\0'};

+                    canvas->drawString(n >= 10 ? num : &num[1], xPos, yPos - 5, p);

+                    break;

+                }

+            }

+            xPos += 20;

+        }

+        p.setColor(SK_ColorBLACK);

+        for (int i = 0; i < count; ++i) {

+            canvas->drawString(s[i], 5 + (e[i] + e[i + 1]) * 10, yPos + 10, p);

+        }

+        p.setStyle(SkPaint::kStroke_Style);

+        for (int i = 0; i <= count; ++i) {

+            canvas->drawLine(5 + e[i] * 20, yPos, 5 + e[i] * 20, yPos + 15, p);

+        }

+        for (int i = 0; i < 2; ++i) {

+            canvas->drawLine(5 + e[0] * 20, yPos + i * 15, 5 + e[count] * 20, yPos + i * 15, p);

+        }

+    };

+    SkScalar edges[] = { 0, 16, 32,

+                         0, 8

+                       };

+    const char* labels[] = { "alpha", "blue", "green", "red" };

+    drawBoxText(&edges[0], &labels[0], 2, 63, 45);

+    drawBoxText(&edges[0], &labels[2], 2, 31, 95);

+    drawBoxText(&edges[3], &labels[3], 1, 7, 160);

+    drawBoxText(&edges[3], &labels[3], 1, 7, 210);

+    drawBoxText(&edges[3], &labels[2], 1, 7, 260);

+    drawBoxText(&edges[3], &labels[2], 1, 7, 310);

+    drawBoxText(&edges[3], &labels[1], 1, 7, 360);

+    drawBoxText(&edges[3], &labels[1], 1, 7, 410);

+    drawBoxText(&edges[3], &labels[0], 1, 7, 460);

+    drawBoxText(&edges[3], &labels[0], 1, 7, 510);

+}

+##

+##

+

+#Topic Illustrations ##

diff --git a/docs/status.json b/docs/status.json
index 7b8b7f7..a888802 100644
--- a/docs/status.json
+++ b/docs/status.json
@@ -29,6 +29,7 @@
             "SkMatrix_Reference.bmh",

             "SkPixmap_Reference.bmh",

             "SkSurface_Reference.bmh",

+            "illustrations.bmh",

             "undocumented.bmh"

         ]

     },

diff --git a/docs/undocumented.bmh b/docs/undocumented.bmh
index 5f0d2fa..70a26de 100644
--- a/docs/undocumented.bmh
+++ b/docs/undocumented.bmh
@@ -111,6 +111,8 @@
     ##
     #Method int SkColorSetARGB(a, r, g, b)
     ##
+    #Method SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
+    ##
 
     #Const SK_ColorBLACK 0xFF000000 
     ##
@@ -149,6 +151,9 @@
     #Substitute RGB-565
     #Alias Color_RGB-565 # quit changing - to _ !
     #Subtopic ##
+
+    #Subtopic Gray
+    ##
 #Topic ##
 
 #Topic Color_Filter
@@ -377,31 +382,11 @@
 ##
 ##
 
-#Topic Mask
-#Class SkMask
-    #Enum Format
-        #Const kBW_Format 0
-        ##
-        #Const kA8_Format 1
-        ##
-        #Const k3D_Format 2
-        ##
-        #Const kARGB32_Format 3
-        ##
-        k#Const LCD16_Format 4
-        ##
-    ##
-##
-#Topic ##
-
 #Topic Mask_Alpha
 #Topic ##
 
 #Topic Mask_Filter
 #Class SkMaskFilter
-#Method virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
-                            SkIPoint* margin) const
-##
 #Method void toString(SkString* str) const 
 ##
 #Class ##