Home | History | Annotate | Download | only in docs
      1 #Topic Bitmap
      2 #Alias Bitmaps ##
      3 #Alias Bitmap_Reference ##
      4 
      5 #Class SkBitmap
      6 #Line # two-dimensional raster pixel array ##
      7 
      8 #Code
      9 #Populate
     10 ##
     11 
     12 Bitmap describes a two-dimensional raster pixel array. Bitmap is built on
     13 Image_Info, containing integer width and height, Color_Type and Alpha_Type
     14 describing the pixel format, and Color_Space describing the range of colors.
     15 Bitmap points to Pixel_Ref, which describes the physical array of pixels.
     16 Image_Info bounds may be located anywhere fully inside Pixel_Ref bounds.
     17 
     18 Bitmap can be drawn using Canvas. Bitmap can be a drawing destination for Canvas
     19 draw member functions. Bitmap flexibility as a pixel container limits some
     20 optimizations available to the target platform.
     21 
     22 If pixel array is primarily read-only, use Image for better performance.
     23 If pixel array is primarily written to, use Surface for better performance.
     24 
     25 Declaring SkBitmap const prevents altering Image_Info: the Bitmap height, width,
     26 and so on cannot change. It does not affect Pixel_Ref: a caller may write its
     27 pixels. Declaring SkBitmap const affects Bitmap configuration, not its contents.
     28 
     29 Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields,
     30 although threads may share the underlying pixel array.
     31 
     32 #Subtopic Row_Bytes
     33 #Line # interval from one row to the next ##
     34 Bitmap pixels may be contiguous, or may have a gap at the end of each row.
     35 Row_Bytes is the interval from one row to the next. Row_Bytes may be specified;
     36 sometimes passing zero will compute the Row_Bytes from the row width and the
     37 number of bytes in a pixel. Row_Bytes may be larger than the row requires. This
     38 is useful to position one or more Bitmaps within a shared pixel array.
     39 ##
     40 
     41 # ------------------------------------------------------------------------------
     42 
     43 #Class Allocator
     44 #Line # abstract subclass of HeapAllocator ##
     45 #Code
     46 #Populate
     47 ##
     48 
     49 Abstract subclass of HeapAllocator.
     50 
     51 # ------------------------------------------------------------------------------
     52 
     53 #Method virtual bool allocPixelRef(SkBitmap* bitmap) = 0
     54 #Line # allocates pixel memory ##
     55 #Populate
     56 
     57 #NoExample
     58 ##
     59 
     60 #SeeAlso HeapAllocator
     61 
     62 ##
     63 
     64 #Class Allocator ##
     65 
     66 # ------------------------------------------------------------------------------
     67 
     68 #Class HeapAllocator
     69 #Line # allocates pixel memory from heap ##
     70 
     71 #Code
     72 #Populate
     73 ##
     74 
     75 Subclass of SkBitmap::Allocator that returns a Pixel_Ref that allocates its pixel
     76 memory from the heap. This is the default SkBitmap::Allocator invoked by
     77 allocPixels.
     78 
     79 # ------------------------------------------------------------------------------
     80 
     81 #Method bool allocPixelRef(SkBitmap* bitmap) override
     82 #Line # allocates pixel memory ##
     83 #Populate
     84 
     85 #Example
     86     SkBitmap bitmap;
     87     bitmap.setInfo(SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType));
     88     SkDebugf("pixel address = %p\n", bitmap.getPixels());
     89     SkBitmap::HeapAllocator stdalloc;
     90     if (!stdalloc.allocPixelRef(&bitmap)) {
     91         SkDebugf("pixel allocation failed\n");
     92     } else {
     93         SkDebugf("pixel address = %p\n", bitmap.getPixels());
     94     }
     95 #StdOut
     96 #Volatile
     97 pixel address = (nil)
     98 pixel address = 0x560ddd0ac670
     99 ##
    100 ##
    101 
    102 #SeeAlso SkBitmap::Allocator tryAllocPixels
    103 
    104 ##
    105 
    106 #Class HeapAllocator ##
    107 
    108 # ------------------------------------------------------------------------------
    109 
    110 #Method SkBitmap()
    111 
    112 #Line # constructs with default values ##
    113 #Populate
    114 
    115 #Example
    116 void draw(SkCanvas* canvas) {
    117     const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
    118     const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    119                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
    120     SkBitmap bitmap;
    121     for (int i = 0; i < 2; ++i) {
    122        SkDebugf("width: %2d  height: %2d", bitmap.width(), bitmap.height());
    123        SkDebugf("  color: k%s_SkColorType", colors[bitmap.colorType()]);
    124        SkDebugf("  alpha: k%s_SkAlphaType\n", alphas[bitmap.alphaType()]);
    125        bitmap.setInfo(SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType),
    126                       0);
    127     }
    128 }
    129 #StdOut
    130 width:  0  height:  0  color: kUnknown_SkColorType  alpha: kUnknown_SkAlphaType
    131 width: 25  height: 35  color: kRGBA_8888_SkColorType  alpha: kOpaque_SkAlphaType
    132 ##
    133 ##
    134 
    135 #SeeAlso setInfo
    136 
    137 ##
    138 
    139 # ------------------------------------------------------------------------------
    140 
    141 #Method SkBitmap(const SkBitmap& src)
    142 
    143 #Line # shares ownership of pixels ##
    144 #Populate
    145 
    146 #Example
    147 void draw(SkCanvas* canvas) {
    148     SkBitmap original;
    149     if (original.tryAllocPixels(
    150             SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
    151         SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false");
    152         SkBitmap copy(original);
    153         SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false");
    154         SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
    155     }
    156 }
    157 #StdOut
    158 original has pixels before copy: true
    159 original has pixels after copy: true
    160 copy has pixels: true
    161 ##
    162 ##
    163 
    164 #SeeAlso setInfo setPixelRef setPixels swap
    165 
    166 ##
    167 
    168 # ------------------------------------------------------------------------------
    169 
    170 #Method SkBitmap(SkBitmap&& src)
    171 
    172 #Line # takes ownership of pixels ##
    173 #Populate
    174 
    175 #Example
    176 void draw(SkCanvas* canvas) {
    177     SkBitmap original;
    178     if (original.tryAllocPixels(
    179             SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
    180         SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false");
    181         SkBitmap copy(std::move(original));
    182         SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false");
    183         SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
    184     }
    185 }
    186 #StdOut
    187 original has pixels before move: true
    188 original has pixels after move: false
    189 copy has pixels: true
    190 ##
    191 ##
    192 
    193 #SeeAlso setInfo setPixelRef setPixels swap
    194 
    195 ##
    196 
    197 # ------------------------------------------------------------------------------
    198 
    199 #Method ~SkBitmap()
    200 
    201 #Line # releases ownership of pixels ##
    202 #Populate
    203 
    204 #NoExample
    205 ##
    206 
    207 #SeeAlso Pixel_Ref
    208 
    209 ##
    210 
    211 # ------------------------------------------------------------------------------
    212 
    213 #Method SkBitmap& operator=(const SkBitmap& src)
    214 
    215 #Line # shares ownership of pixels ##
    216 #Populate
    217 
    218 #Example
    219 void draw(SkCanvas* canvas) {
    220     SkBitmap original;
    221     if (original.tryAllocPixels(
    222             SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
    223         SkDebugf("original has pixels before copy: %s\n", original.getPixels() ? "true" : "false");
    224         SkBitmap copy = original;
    225         SkDebugf("original has pixels after copy: %s\n", original.getPixels() ? "true" : "false");
    226         SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
    227     }
    228 }
    229 #StdOut
    230 original has pixels before copy: true
    231 original has pixels after copy: true
    232 copy has pixels: true
    233 ##
    234 ##
    235 
    236 #SeeAlso setInfo setPixelRef setPixels swap
    237 
    238 ##
    239 
    240 # ------------------------------------------------------------------------------
    241 
    242 #Method SkBitmap& operator=(SkBitmap&& src)
    243 
    244 #Line # takes ownership of pixels ##
    245 #Populate
    246 
    247 #Example
    248 void draw(SkCanvas* canvas) {
    249     SkBitmap original;
    250     if (original.tryAllocPixels(
    251             SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
    252         SkDebugf("original has pixels before move: %s\n", original.getPixels() ? "true" : "false");
    253         SkBitmap copy = std::move(original);
    254         SkDebugf("original has pixels after move: %s\n", original.getPixels() ? "true" : "false");
    255         SkDebugf("copy has pixels: %s\n", copy.getPixels() ? "true" : "false");
    256     }
    257 }
    258 #StdOut
    259 original has pixels before move: true
    260 original has pixels after move: false
    261 copy has pixels: true
    262 ##
    263 ##
    264 
    265 #SeeAlso setInfo setPixelRef setPixels swap
    266 
    267 ##
    268 
    269 # ------------------------------------------------------------------------------
    270 
    271 #Method void swap(SkBitmap& other)
    272 #In Utility
    273 #Line # exchanges Bitmap pair ##
    274 #Populate
    275 
    276 #Example
    277 void draw(SkCanvas* canvas) {
    278     auto debugster = [](const char* prefix, const SkBitmap& b) -> void {
    279         const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
    280         const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    281                                 "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
    282         SkDebugf("%s width:%d height:%d colorType:k%s_SkColorType alphaType:k%s_SkAlphaType\n",
    283                  prefix, b.width(), b.height(), colors[b.colorType()], alphas[b.alphaType()]);
    284     };
    285     SkBitmap one, two;
    286     if (!one.tryAllocPixels(
    287             SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType))) {
    288         return;
    289     }
    290     if (!two.tryAllocPixels(
    291             SkImageInfo::Make(2, 2, kBGRA_8888_SkColorType, kPremul_SkAlphaType))) {
    292         return;
    293     }
    294     for (int index = 0; index < 2; ++index) {
    295        debugster("one", one);
    296        debugster("two", two);
    297        one.swap(two);
    298     }
    299 }
    300 #StdOut
    301 one width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType
    302 two width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType
    303 one width:2 height:2 colorType:kBGRA_8888_SkColorType alphaType:kPremul_SkAlphaType
    304 two width:1 height:1 colorType:kRGBA_8888_SkColorType alphaType:kOpaque_SkAlphaType
    305 ##
    306 ##
    307 
    308 #SeeAlso SkBitmap(SkBitmap&& src) operator=(SkBitmap&& src)
    309 
    310 ##
    311 
    312 # ------------------------------------------------------------------------------
    313 #Subtopic Property
    314 #Line # metrics and attributes ##
    315 ##
    316 
    317 #Method const SkPixmap& pixmap() const
    318 #In Property
    319 #Line # returns Pixmap ##
    320 #Populate
    321 
    322 #Example
    323     SkBitmap bitmap;
    324     bitmap.allocPixels(SkImageInfo::MakeN32Premul(10, 11));
    325     SkCanvas offscreen(bitmap);
    326     offscreen.clear(SK_ColorWHITE);
    327     SkPaint paint;
    328     offscreen.drawString("&", 0, 10, paint);
    329     const SkPixmap& pixmap = bitmap.pixmap();
    330     if (pixmap.addr()) {
    331         SkPMColor pmWhite = *pixmap.addr32(0, 0);
    332         for (int y = 0; y < pixmap.height(); ++y) {
    333             for (int x = 0; x < pixmap.width(); ++x) {
    334                 SkDebugf("%c", *pixmap.addr32(x, y) == pmWhite ? '-' : 'x');
    335             }
    336             SkDebugf("\n");
    337         }
    338     }
    339     #StdOut
    340 ----------
    341 ---xx-----
    342 --x--x----
    343 --x-------
    344 --xx------
    345 --x-x---x-
    346 -x---x--x-
    347 -x----xx--
    348 -xx---x---
    349 --xxxx-xx-
    350 ----------
    351     #StdOut ##
    352 
    353 ##
    354 
    355 #SeeAlso peekPixels installPixels readPixels writePixels
    356 
    357 ##
    358 
    359 # ------------------------------------------------------------------------------
    360 
    361 #Method const SkImageInfo& info() const
    362 #In Property
    363 #Line # returns Image_Info ##
    364 #Populate
    365 
    366 #Example
    367 #Image 4
    368 void draw(SkCanvas* canvas) {
    369     // SkBitmap source;  // pre-populated with soccer ball by fiddle.skia.org
    370     const SkImageInfo& info = source.info();
    371     const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
    372     const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    373                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
    374     SkDebugf("width: %d height: %d color: %s alpha: %s\n", info.width(), info.height(),
    375                 colors[info.colorType()], alphas[info.alphaType()]);
    376 #StdOut
    377 width: 56 height: 56 color: BGRA_8888 alpha: Opaque
    378 ##
    379 }
    380 ##
    381 
    382 #SeeAlso Image_Info
    383 
    384 ##
    385 
    386 # ------------------------------------------------------------------------------
    387 
    388 #Method int width() const
    389 #In Property
    390 #Line # returns pixel column count ##
    391 Returns pixel count in each row. Should be equal or less than
    392 #Formula # rowBytes() / info().bytesPerPixel() ##.
    393 
    394 May be less than pixelRef().width(). Will not exceed pixelRef().width() less
    395 pixelRefOrigin().fX.
    396 
    397 #Return  pixel width in Image_Info ##
    398 
    399 #Example
    400     SkImageInfo info = SkImageInfo::MakeA8(16, 32);
    401     SkBitmap bitmap;
    402     bitmap.setInfo(info);
    403     SkDebugf("bitmap width: %d  info width: %d\n", bitmap.width(), info.width());
    404 #StdOut
    405 bitmap width: 16  info width: 16
    406 ##
    407 ##
    408 
    409 #SeeAlso height() SkPixelRef::width() SkImageInfo::width()
    410 
    411 ##
    412 
    413 # ------------------------------------------------------------------------------
    414 
    415 #Method int height() const
    416 #In Property
    417 #Line # returns pixel row count ##
    418 #Populate
    419 
    420 #Example
    421     SkImageInfo info = SkImageInfo::MakeA8(16, 32);
    422     SkBitmap bitmap;
    423     bitmap.setInfo(info);
    424     SkDebugf("bitmap height: %d  info height: %d\n", bitmap.height(), info.height());
    425 #StdOut
    426 bitmap height: 32  info height: 32
    427 ##
    428 ##
    429 
    430 #SeeAlso width() SkPixelRef::height() SkImageInfo::height()
    431 
    432 ##
    433 
    434 # ------------------------------------------------------------------------------
    435 
    436 #Method SkColorType colorType() const
    437 #In Property
    438 #Line # returns Image_Info Color_Type ##
    439 Returns Color_Type, one of: #list_of_color_types#.
    440 
    441 #Return  Color_Type in Image_Info ##
    442 
    443 #Example
    444     const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    445                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
    446     SkBitmap bitmap;
    447     bitmap.setInfo(SkImageInfo::MakeA8(16, 32));
    448     SkDebugf("color type: k" "%s" "_SkColorType\n", colors[bitmap.colorType()]);
    449 #StdOut
    450 color type: kAlpha_8_SkColorType
    451 ##
    452 ##
    453 
    454 #SeeAlso alphaType() SkImageInfo::colorType
    455 
    456 ##
    457 
    458 # ------------------------------------------------------------------------------
    459 
    460 #Method SkAlphaType alphaType() const
    461 #In Property
    462 #Line # returns Image_Info Alpha_Type ##
    463 Returns Alpha_Type, one of: #list_of_alpha_types#.
    464 
    465 #Return  Alpha_Type in Image_Info ##
    466 
    467 #Example
    468     const char* alphas[] = {"Unknown", "Opaque", "Premul", "Unpremul"};
    469     SkPixmap pixmap(SkImageInfo::MakeA8(16, 32), nullptr, 64);
    470     SkDebugf("alpha type: k" "%s" "_SkAlphaType\n", alphas[pixmap.alphaType()]);
    471 #StdOut
    472 alpha type: kPremul_SkAlphaType
    473 ##
    474 ##
    475 
    476 #SeeAlso colorType() SkImageInfo::alphaType
    477 
    478 ##
    479 
    480 # ------------------------------------------------------------------------------
    481 
    482 #Method SkColorSpace* colorSpace() const
    483 #In Property
    484 #Line # returns Image_Info Color_Space ##
    485 #Populate
    486 
    487 #Example
    488 #Description
    489 SkColorSpace::MakeSRGBLinear creates Color_Space with linear gamma
    490 and an sRGB gamut. This Color_Space gamma is not close to sRGB gamma.
    491 ##
    492     SkBitmap bitmap;
    493     bitmap.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
    494             SkColorSpace::MakeSRGBLinear()));
    495     SkColorSpace* colorSpace = bitmap.colorSpace();
    496     SkDebugf("gammaCloseToSRGB: %s  gammaIsLinear: %s  isSRGB: %s\n",
    497             colorSpace->gammaCloseToSRGB() ? "true" : "false",
    498             colorSpace->gammaIsLinear() ? "true" : "false",
    499             colorSpace->isSRGB() ? "true" : "false");
    500 #StdOut
    501 gammaCloseToSRGB: false  gammaIsLinear: true  isSRGB: false
    502 ##
    503 ##
    504 
    505 #SeeAlso Color_Space SkImageInfo::colorSpace
    506 
    507 ##
    508 
    509 # ------------------------------------------------------------------------------
    510 
    511 #Method sk_sp<SkColorSpace> refColorSpace() const
    512 #In Property
    513 #Line # returns Image_Info Color_Space ##
    514 #Populate
    515 
    516 #Example
    517     SkBitmap bitmap1, bitmap2;
    518     bitmap1.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
    519             SkColorSpace::MakeSRGBLinear()));
    520     bitmap2.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType,
    521             bitmap1.refColorSpace()));
    522     SkColorSpace* colorSpace = bitmap2.colorSpace();
    523     SkDebugf("gammaCloseToSRGB: %s  gammaIsLinear: %s  isSRGB: %s\n",
    524             colorSpace->gammaCloseToSRGB() ? "true" : "false",
    525             colorSpace->gammaIsLinear() ? "true" : "false",
    526             colorSpace->isSRGB() ? "true" : "false");
    527 #StdOut
    528 gammaCloseToSRGB: false  gammaIsLinear: true  isSRGB: false
    529 ##
    530 ##
    531 
    532 #SeeAlso Color_Space SkImageInfo::colorSpace
    533 
    534 ##
    535 
    536 # ------------------------------------------------------------------------------
    537 
    538 #Method int bytesPerPixel() const
    539 #In Property
    540 #Line # returns number of bytes in pixel based on Color_Type ##
    541 #Populate
    542 
    543 #Example
    544     const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    545                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
    546     SkImageInfo info = SkImageInfo::MakeA8(1, 1);
    547     SkBitmap bitmap;
    548     for (SkColorType colorType : { #list_of_color_types#
    549                                  } ) {
    550         bitmap.setInfo(info.makeColorType(colorType));
    551         SkDebugf("color: k" "%s" "_SkColorType" "%*s" "bytesPerPixel: %d\n",
    552                 colors[colorType], 13 - strlen(colors[colorType]), " ",
    553                 bitmap.bytesPerPixel());
    554     }
    555 #StdOut
    556 color: kUnknown_SkColorType      bytesPerPixel: 0
    557 color: kAlpha_8_SkColorType      bytesPerPixel: 1
    558 color: kRGB_565_SkColorType      bytesPerPixel: 2
    559 color: kARGB_4444_SkColorType    bytesPerPixel: 2
    560 color: kRGBA_8888_SkColorType    bytesPerPixel: 4
    561 color: kRGB_888x_SkColorType     bytesPerPixel: 4
    562 color: kBGRA_8888_SkColorType    bytesPerPixel: 4
    563 color: kRGBA_1010102_SkColorType bytesPerPixel: 4
    564 color: kRGB_101010x_SkColorType  bytesPerPixel: 4
    565 color: kGray_8_SkColorType       bytesPerPixel: 1
    566 color: kRGBA_F16_SkColorType     bytesPerPixel: 8
    567 ##
    568 ##
    569 
    570 #SeeAlso rowBytes rowBytesAsPixels width shiftPerPixel SkImageInfo::bytesPerPixel
    571 
    572 ##
    573 
    574 # ------------------------------------------------------------------------------
    575 
    576 #Method int rowBytesAsPixels() const
    577 #In Property
    578 #Line # returns interval between rows in pixels ##
    579 #Populate
    580 
    581 #Example
    582     SkBitmap bitmap;
    583     for (int rowBytes : { 4, 5, 6, 7, 8} ) {
    584         bitmap.setInfo(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType), rowBytes);
    585         SkDebugf("rowBytes: %d rowBytesAsPixels: %d\n", rowBytes, bitmap.rowBytesAsPixels());
    586     }
    587 #StdOut
    588 rowBytes: 4 rowBytesAsPixels: 1
    589 rowBytes: 5 rowBytesAsPixels: 1
    590 rowBytes: 6 rowBytesAsPixels: 1
    591 rowBytes: 7 rowBytesAsPixels: 1
    592 rowBytes: 8 rowBytesAsPixels: 2
    593 ##
    594 ##
    595 
    596 #SeeAlso rowBytes shiftPerPixel width bytesPerPixel
    597 
    598 ##
    599 
    600 # ------------------------------------------------------------------------------
    601 
    602 #Method int shiftPerPixel() const
    603 #In Property
    604 #Line # returns bit shift from pixels to bytes ##
    605 #Populate
    606 
    607 #Example
    608     const char* colors[] = {"Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    609                             "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16"};
    610     SkImageInfo info = SkImageInfo::MakeA8(1, 1);
    611     SkBitmap bitmap;
    612     for (SkColorType colorType : { #list_of_color_types#
    613                                  } ) {
    614         bitmap.setInfo(info.makeColorType(colorType));
    615         SkDebugf("color: k" "%s" "_SkColorType" "%*s" "shiftPerPixel: %d\n",
    616                 colors[colorType], 14 - strlen(colors[colorType]), " ",
    617                 bitmap.shiftPerPixel());
    618     }
    619 #StdOut
    620 color: kUnknown_SkColorType       shiftPerPixel: 0
    621 color: kAlpha_8_SkColorType       shiftPerPixel: 0
    622 color: kRGB_565_SkColorType       shiftPerPixel: 1
    623 color: kARGB_4444_SkColorType     shiftPerPixel: 1
    624 color: kRGBA_8888_SkColorType     shiftPerPixel: 2
    625 color: kRGB_888x_SkColorType      shiftPerPixel: 2
    626 color: kBGRA_8888_SkColorType     shiftPerPixel: 2
    627 color: kRGBA_1010102_SkColorType  shiftPerPixel: 2
    628 color: kRGB_101010x_SkColorType   shiftPerPixel: 2
    629 color: kGray_8_SkColorType        shiftPerPixel: 0
    630 color: kRGBA_F16_SkColorType      shiftPerPixel: 3
    631 ##
    632 ##
    633 
    634 #SeeAlso rowBytes rowBytesAsPixels width bytesPerPixel
    635 
    636 ##
    637 
    638 # ------------------------------------------------------------------------------
    639 
    640 #Method bool empty() const
    641 #In Property
    642 #Line # returns true if Image_Info has zero width() or height() ##
    643 #Populate
    644 
    645 #Example
    646     SkBitmap bitmap;
    647     for (int width : { 0, 2 } ) {
    648         for (int height : { 0, 2 } ) {
    649              bitmap.setInfo(SkImageInfo::MakeA8(width, height));
    650              SkDebugf("width: %d height: %d empty: %s\n", width, height,
    651                       bitmap.empty() ? "true" : "false");
    652         }
    653     }
    654 #StdOut
    655 width: 0 height: 0 empty: true
    656 width: 0 height: 2 empty: true
    657 width: 2 height: 0 empty: true
    658 width: 2 height: 2 empty: false
    659 ##
    660 ##
    661 
    662 #SeeAlso height() width() drawsNothing
    663 
    664 ##
    665 
    666 # ------------------------------------------------------------------------------
    667 
    668 #Method bool isNull() const
    669 #In Property
    670 #Line # returns true if Pixel_Ref is nullptr ##
    671 #Populate
    672 
    673 #Example
    674     SkBitmap bitmap;
    675     SkDebugf("empty bitmap does %shave pixels\n", bitmap.isNull() ? "not " : "");
    676     bitmap.setInfo(SkImageInfo::MakeA8(8, 8));
    677     SkDebugf("bitmap with dimensions does %shave pixels\n", bitmap.isNull() ? "not " : "");
    678     bitmap.allocPixels();
    679     SkDebugf("allocated bitmap does %shave pixels\n", bitmap.isNull() ? "not " : "");
    680 #StdOut
    681 empty bitmap does not have pixels
    682 bitmap with dimensions does not have pixels
    683 allocated bitmap does have pixels
    684 ##
    685 ##
    686 
    687 #SeeAlso empty() drawsNothing pixelRef
    688 
    689 ##
    690 
    691 # ------------------------------------------------------------------------------
    692 
    693 #Method bool drawsNothing() const
    694 #In Property
    695 #Line # returns true if no width(), no height(), or no Pixel_Ref ##
    696 #Populate
    697 
    698 #Example
    699     SkBitmap bitmap;
    700     for (int w : { 0, 8 } ) {
    701         for (bool allocate : { false, true} ) {
    702             bitmap.setInfo(SkImageInfo::MakeA8(w, 8));
    703             allocate ? bitmap.allocPixels() : (void) 0 ;
    704             SkDebugf("empty:%s isNull:%s drawsNothing:%s\n", bitmap.empty() ? "true " : "false",
    705                      bitmap.isNull() ? "true " : "false", bitmap.drawsNothing() ? "true" : "false");
    706         }
    707     }
    708 #StdOut
    709 empty:true  isNull:true  drawsNothing:true
    710 empty:true  isNull:false drawsNothing:true
    711 empty:false isNull:true  drawsNothing:true
    712 empty:false isNull:false drawsNothing:false
    713 ##
    714 ##
    715 
    716 #SeeAlso empty() isNull pixelRef
    717 
    718 ##
    719 
    720 # ------------------------------------------------------------------------------
    721 
    722 #Method size_t rowBytes() const
    723 #In Property
    724 #Line # returns interval between rows in bytes ##
    725 Returns row bytes, the interval from one pixel row to the next. Row bytes
    726 is at least as large as: #Formula # width() * info().bytesPerPixel() ##.
    727 
    728 Returns zero if colorType is kUnknown_SkColorType, or if row bytes supplied to
    729 setInfo is not large enough to hold a row of pixels.
    730 
    731 #Return  byte length of pixel row ##
    732 
    733 #Example
    734    SkBitmap bitmap;
    735    for (int rowBytes : { 2, 8 } ) {
    736        bool result = bitmap.setInfo(SkImageInfo::MakeA8(4, 4), rowBytes);
    737        SkDebugf("setInfo returned:%s rowBytes:%d\n", result ? "true " : "false", bitmap.rowBytes());
    738     }
    739 #StdOut
    740 setInfo returned:false rowBytes:0
    741 setInfo returned:true  rowBytes:8
    742 ##
    743 ##
    744 
    745 #SeeAlso info() setInfo SkImageInfo::minRowBytes
    746 
    747 ##
    748 
    749 # ------------------------------------------------------------------------------
    750 
    751 #Method bool setAlphaType(SkAlphaType alphaType)
    752 #In Set
    753 #Line # sets Alpha_Type of shared pixels ##
    754 #Populate
    755 
    756 #Example
    757 void draw(SkCanvas* canvas) {
    758     const char* colors[] = { "Unknown", "Alpha_8", "RGB_565", "ARGB_4444", "RGBA_8888", "RGB_888x",
    759                              "BGRA_8888", "RGBA_1010102", "RGB_101010x", "Gray_8", "RGBA_F16" };
    760     const char* alphas[] = {"Unknown ", "Opaque  ", "Premul  ", "Unpremul"};
    761     SkBitmap bitmap;
    762     SkAlphaType alphaTypes[] = { #list_of_alpha_types#
    763                                };
    764     SkDebugf("%18s%15s%17s%18s%19s\n", "Canonical", "Unknown", "Opaque", "Premul", "Unpremul");
    765     for (SkColorType colorType : { #list_of_color_types#
    766                                  } ) {
    767         for (SkAlphaType canonicalAlphaType : alphaTypes) {
    768             SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType );
    769             SkDebugf("%12s %9s  ", colors[(int) colorType], alphas[(int) canonicalAlphaType ]);
    770             for (SkAlphaType alphaType : alphaTypes) {
    771                 bitmap.setInfo(SkImageInfo::Make(4, 4, colorType, canonicalAlphaType));
    772                 bool result = bitmap.setAlphaType(alphaType);
    773                 SkDebugf("%s %s    ", result ? "true " : "false", alphas[(int) bitmap.alphaType()]);
    774             }
    775             SkDebugf("\n");
    776         }
    777     }
    778 }
    779 ##
    780 
    781 #SeeAlso Alpha_Type Color_Type Image_Info setInfo
    782 
    783 ##
    784 
    785 # ------------------------------------------------------------------------------
    786 
    787 #Method void* getPixels() const
    788 #In Property
    789 #Line # returns address of pixels ##
    790 #Populate
    791 
    792 #Example
    793     SkBitmap bitmap;
    794     bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType));
    795     bitmap.allocPixels();
    796     bitmap.eraseColor(0x00000000);
    797     void* baseAddr = bitmap.getPixels();
    798     *(SkPMColor*)baseAddr = 0xFFFFFFFF;
    799     SkDebugf("bitmap.getColor(0, 1) %c= 0x00000000\n",
    800               bitmap.getColor(0, 1)  == 0x00000000 ? '=' : '!');
    801     SkDebugf("bitmap.getColor(0, 0) %c= 0xFFFFFFFF\n",
    802               bitmap.getColor(0, 0)  == 0xFFFFFFFF ? '=' : '!');
    803 #StdOut
    804 bitmap.getColor(0, 1) == 0x00000000
    805 bitmap.getColor(0, 0) == 0xFFFFFFFF
    806 ##
    807 ##
    808 
    809 #SeeAlso isNull drawsNothing
    810 
    811 ##
    812 
    813 # ------------------------------------------------------------------------------
    814 
    815 #Method size_t computeByteSize() const
    816 #In Utility
    817 #Line # returns size required for pixels ##
    818 #Populate
    819 
    820 #Example
    821     SkBitmap bitmap;
    822     for (int width : { 1, 1000, 1000000 } ) {
    823         for (int height: { 1, 1000, 1000000 } ) {
    824             SkImageInfo imageInfo = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
    825             bitmap.setInfo(imageInfo, width * 5);
    826             SkDebugf("width: %7d height: %7d computeByteSize: %13lld\n", width, height,
    827                      bitmap.computeByteSize());
    828         }
    829     }
    830 #StdOut
    831 width:       1 height:       1 computeByteSize:             4
    832 width:       1 height:    1000 computeByteSize:          4999
    833 width:       1 height: 1000000 computeByteSize:       4999999
    834 width:    1000 height:       1 computeByteSize:          4000
    835 width:    1000 height:    1000 computeByteSize:       4999000
    836 width:    1000 height: 1000000 computeByteSize:    4999999000
    837 width: 1000000 height:       1 computeByteSize:       4000000
    838 width: 1000000 height:    1000 computeByteSize:    4999000000
    839 width: 1000000 height: 1000000 computeByteSize: 4999999000000
    840 ##
    841 ##
    842 
    843 #SeeAlso SkImageInfo::computeByteSize
    844 
    845 ##
    846 
    847 # ------------------------------------------------------------------------------
    848 
    849 #Method bool isImmutable() const
    850 #In Property
    851 #Line # returns true if pixels will not change ##
    852 #Populate
    853 
    854 #Example
    855     SkBitmap original;
    856     SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
    857     if (original.tryAllocPixels(info)) {
    858         original.setImmutable();
    859         SkBitmap copy;
    860         original.extractSubset(&copy, {5, 10, 15, 20});
    861         SkDebugf("original is " "%s" "immutable\n", original.isImmutable() ? "" : "not ");
    862         SkDebugf("copy is " "%s" "immutable\n", copy.isImmutable() ? "" : "not ");
    863     }
    864 #StdOut
    865 original is immutable
    866 copy is immutable
    867 ##
    868 ##
    869 
    870 #SeeAlso setImmutable SkPixelRef::isImmutable SkImage
    871 
    872 ##
    873 
    874 # ------------------------------------------------------------------------------
    875 
    876 #Method void setImmutable()
    877 #In Set
    878 #Line # marks that pixels will not change ##
    879 #Populate
    880 
    881 #Example
    882 #Description
    883 Triggers assert if SK_DEBUG is true, runs fine otherwise.
    884 ##
    885     SkBitmap bitmap;
    886     bitmap.setInfo(SkImageInfo::MakeN32(4, 4, kPremul_SkAlphaType));
    887     bitmap.allocPixels();
    888     SkCanvas offscreen(bitmap);
    889     SkDebugf("draw white\n");
    890     offscreen.clear(SK_ColorWHITE);
    891     bitmap.setImmutable();
    892     SkDebugf("draw black\n");
    893     offscreen.clear(SK_ColorBLACK);
    894 ##
    895 
    896 #SeeAlso isImmutable SkPixelRef::setImmutable SkImage
    897 
    898 ##
    899 
    900 # ------------------------------------------------------------------------------
    901 
    902 #Method bool isOpaque() const
    903 #In Property
    904 #Line # returns true if Image_Info describes opaque pixels ##
    905 #Populate
    906 
    907 #Example
    908 #Description
    909     isOpaque ignores whether all pixels are opaque or not.
    910 ##
    911     const int height = 2;
    912     const int width = 2;
    913     SkBitmap bitmap;
    914     bitmap.setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType));
    915     for (int index = 0; index < 2; ++index) {
    916         bitmap.allocPixels();
    917         bitmap.eraseColor(0x00000000);
    918         SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false");
    919         bitmap.eraseColor(0xFFFFFFFF);
    920         SkDebugf("isOpaque: %s\n", bitmap.isOpaque() ? "true" : "false");
    921         bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType));
    922     }
    923 #StdOut
    924 isOpaque: false
    925 isOpaque: false
    926 isOpaque: true
    927 isOpaque: true
    928 ##
    929 ##
    930 
    931 #SeeAlso ComputeIsOpaque SkImageInfo::isOpaque
    932 
    933 ##
    934 
    935 # ------------------------------------------------------------------------------
    936 
    937 #Method bool isVolatile() const
    938 #In Property
    939 #Line # returns true if pixels should not be cached ##
    940 #Populate
    941 
    942 #Example
    943     SkBitmap original;
    944     SkImageInfo info = SkImageInfo::Make(25, 35, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
    945     if (original.tryAllocPixels(info)) {
    946         original.setIsVolatile(true);
    947         SkBitmap copy;
    948         original.extractSubset(&copy, {5, 10, 15, 20});
    949         SkDebugf("original is " "%s" "volatile\n", original.isVolatile() ? "" : "not ");
    950         SkDebugf("copy is " "%s" "volatile\n", copy.isImmutable() ? "" : "not ");
    951     }
    952 #StdOut
    953 original is volatile
    954 copy is not volatile
    955 ##
    956 ##
    957 
    958 #SeeAlso setIsVolatile
    959 
    960 ##
    961 
    962 # ------------------------------------------------------------------------------
    963 
    964 #Method void setIsVolatile(bool isVolatile)
    965 #In Set
    966 #Line # marks if pixels should not be cached ##
    967 #Populate
    968 
    969 #Example
    970 #Height 20
    971     SkBitmap bitmap;
    972     bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
    973     bitmap.allocPixels();
    974     bitmap.eraseColor(SK_ColorRED);
    975     canvas->scale(16, 16);
    976     canvas->drawBitmap(bitmap, 0, 0);
    977     *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE);
    978     canvas->drawBitmap(bitmap, 2, 0);
    979     bitmap.setIsVolatile(true);
    980     *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN);
    981     canvas->drawBitmap(bitmap, 4, 0);
    982 ##
    983 
    984 #SeeAlso isVolatile
    985 
    986 ##
    987 
    988 # ------------------------------------------------------------------------------
    989 
    990 #Method void reset()
    991 #In Constructors
    992 #Line # sets to default values, releases pixel ownership ##
    993 #Populate
    994 
    995 #Example
    996     SkBitmap bitmap;
    997     bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
    998     bitmap.allocPixels();
    999     SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(),
   1000              bitmap.isNull() ? "true" : "false");
   1001     bitmap.reset();
   1002     SkDebugf("width:%d height:%d isNull:%s\n", bitmap.width(), bitmap.height(),
   1003              bitmap.isNull() ? "true" : "false");
   1004 #StdOut
   1005 width:1 height:1 isNull:false
   1006 width:0 height:0 isNull:true
   1007 ##
   1008 ##
   1009 
   1010 #SeeAlso SkBitmap() SkAlphaType SkColorType
   1011 
   1012 ##
   1013 
   1014 # ------------------------------------------------------------------------------
   1015 
   1016 #Method static bool ComputeIsOpaque(const SkBitmap& bm)
   1017 #In Utility
   1018 #Line # returns true if all pixels are opaque ##
   1019 #Populate
   1020 
   1021 #Example
   1022     SkBitmap bitmap;
   1023     bitmap.setInfo(SkImageInfo::Make(2, 2, kN32_SkColorType, kPremul_SkAlphaType));
   1024     for (int index = 0; index < 2; ++index) {
   1025         bitmap.allocPixels();
   1026         bitmap.eraseColor(0x00000000);
   1027         SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false");
   1028         bitmap.eraseColor(0xFFFFFFFF);
   1029         SkDebugf("computeIsOpaque: %s\n", SkBitmap::ComputeIsOpaque(bitmap) ? "true" : "false");
   1030         bitmap.setInfo(bitmap.info().makeAlphaType(kOpaque_SkAlphaType));
   1031     }
   1032 #StdOut
   1033 computeIsOpaque: false
   1034 computeIsOpaque: true
   1035 computeIsOpaque: false
   1036 computeIsOpaque: true
   1037 ##
   1038 ##
   1039 
   1040 #SeeAlso isOpaque Color_Type Alpha
   1041 
   1042 ##
   1043 
   1044 # ------------------------------------------------------------------------------
   1045 
   1046 #Method void getBounds(SkRect* bounds) const
   1047 #In Property
   1048 #Line # returns width() and height() as Rectangle ##
   1049 #Populate
   1050 
   1051 #Example
   1052 #Height 160
   1053 #Image 3
   1054     SkRect bounds;
   1055     source.getBounds(&bounds);
   1056     bounds.offset(100, 100);
   1057     SkPaint paint;
   1058     paint.setColor(SK_ColorGRAY);
   1059     canvas->scale(.25f, .25f);
   1060     canvas->drawRect(bounds, paint);
   1061     canvas->drawBitmap(source, 40, 40);
   1062 ##
   1063 
   1064 #SeeAlso bounds()
   1065 
   1066 ##
   1067 
   1068 # ------------------------------------------------------------------------------
   1069 
   1070 #Method void getBounds(SkIRect* bounds) const
   1071 #Populate
   1072 
   1073 #Example
   1074 #Image 3
   1075     SkIRect bounds;
   1076     source.getBounds(&bounds);
   1077     bounds.inset(100, 100);
   1078     SkBitmap bitmap;
   1079     source.extractSubset(&bitmap, bounds);
   1080     canvas->scale(.5f, .5f);
   1081     canvas->drawBitmap(bitmap, 10, 10);
   1082 ##
   1083 
   1084 #SeeAlso bounds()
   1085 
   1086 ##
   1087 
   1088 # ------------------------------------------------------------------------------
   1089 
   1090 #Method SkIRect bounds() const
   1091 #In Property
   1092 #Line # returns width() and height() as Rectangle ##
   1093 #Populate
   1094 
   1095 #Example
   1096 #Height 64
   1097 #Image 4
   1098     canvas->scale(.5f, .5f);
   1099     SkIRect bounds = source.bounds();
   1100     for (int x : { 0, bounds.width() } ) {
   1101         for (int y : { 0, bounds.height() } ) {
   1102             canvas->drawBitmap(source, x, y);
   1103         }
   1104     }
   1105 ##
   1106 
   1107 #SeeAlso getBounds
   1108 
   1109 ##
   1110 
   1111 # ------------------------------------------------------------------------------
   1112 
   1113 #Method SkISize dimensions() const
   1114 #In Property
   1115 #Line # returns width() and height() ##
   1116 #Populate
   1117 
   1118 #Example
   1119     SkBitmap bitmap;
   1120     bitmap.setInfo(SkImageInfo::MakeN32(33, 55, kOpaque_SkAlphaType));
   1121     SkISize dimensions = bitmap.dimensions();
   1122     SkRect bounds;
   1123     bitmap.getBounds(&bounds);
   1124     SkRect dimensionsAsBounds = SkRect::Make(dimensions);
   1125     SkDebugf("dimensionsAsBounds %c= bounds\n", dimensionsAsBounds == bounds ? '=' : '!');
   1126 ##
   1127 
   1128 #SeeAlso height width
   1129 
   1130 ##
   1131 
   1132 # ------------------------------------------------------------------------------
   1133 
   1134 #Method SkIRect getSubset() const
   1135 #In Property
   1136 #Line # returns bounds offset by origin ##
   1137 #Populate
   1138 
   1139 #Example
   1140 #Image 3
   1141     SkIRect bounds;
   1142     source.getBounds(&bounds);
   1143     bounds.inset(100, 100);
   1144     SkBitmap subset;
   1145     source.extractSubset(&subset, bounds);
   1146     SkIRect r = source.getSubset();
   1147     SkDebugf("source: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
   1148     r = subset.getSubset();
   1149     SkDebugf("subset: %d, %d, %d, %d\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
   1150 #StdOut
   1151 source: 0, 0, 512, 512
   1152 subset: 100, 100, 412, 412
   1153 ##
   1154 ##
   1155 
   1156 #SeeAlso extractSubset getBounds
   1157 
   1158 ##
   1159 
   1160 # ------------------------------------------------------------------------------
   1161 
   1162 #Method bool setInfo(const SkImageInfo& imageInfo, size_t rowBytes = 0)
   1163 #In Set
   1164 #Line # sets height, width, Color_Type, and so on, releasing pixels ##
   1165 Sets width, height, Alpha_Type, Color_Type, Color_Space, and optional
   1166 rowBytes. Frees pixels, and returns true if successful.
   1167 
   1168 imageInfo.alphaType() may be altered to a value permitted by imageInfo.colorSpace().
   1169 If imageInfo.colorType() is kUnknown_SkColorType, imageInfo.alphaType() is
   1170 set to kUnknown_SkAlphaType.
   1171 If imageInfo.colorType() is kAlpha_8_SkColorType and imageInfo.alphaType() is
   1172 kUnpremul_SkAlphaType, imageInfo.alphaType() is replaced by kPremul_SkAlphaType.
   1173 If imageInfo.colorType() is kRGB_565_SkColorType or kGray_8_SkColorType,
   1174 imageInfo.alphaType() is set to kOpaque_SkAlphaType.
   1175 If imageInfo.colorType() is kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
   1176 kBGRA_8888_SkColorType, or kRGBA_F16_SkColorType: imageInfo.alphaType() remains
   1177 unchanged.
   1178 
   1179 rowBytes must equal or exceed imageInfo.minRowBytes(). If imageInfo.colorSpace() is
   1180 kUnknown_SkColorType, rowBytes is ignored and treated as zero; for all other
   1181 Color_Space values, rowBytes of zero is treated as imageInfo.minRowBytes().
   1182 
   1183 Calls reset() and returns false if:
   1184 #List
   1185 # rowBytes exceeds 31 bits ##
   1186 # imageInfo.width() is negative ##
   1187 # imageInfo.height() is negative ##
   1188 # rowBytes is positive and less than imageInfo.width() times imageInfo.bytesPerPixel() ##
   1189 ##
   1190 
   1191 #Param imageInfo  contains width, height, Alpha_Type, Color_Type, Color_Space ##
   1192 #Param rowBytes   imageInfo.minRowBytes() or larger; or zero ##
   1193 
   1194 #Return  true if Image_Info set successfully ##
   1195 
   1196 #Example
   1197 #Height 96
   1198 ###^
   1199 SkBitmap bitmap;
   1200 bitmap.setInfo(SkImageInfo::MakeN32(44, 16, kOpaque_SkAlphaType));
   1201 bitmap.allocPixels();
   1202 bitmap.eraseColor(SK_ColorGREEN);
   1203 SkCanvas offscreen(bitmap);
   1204 SkPaint paint;
   1205 offscreen.drawString("!@#$%", 0, 12, paint);
   1206 canvas->scale(6, 6);
   1207 canvas->drawBitmap(bitmap, 0, 0);
   1208 ^^^#
   1209 ##
   1210 
   1211 #SeeAlso Alpha_Type Color_Type Color_Space height rowBytes width
   1212 
   1213 ##
   1214 
   1215 # ------------------------------------------------------------------------------
   1216 
   1217 #Enum AllocFlags
   1218 #Line # zero pixel memory ##
   1219 #Code
   1220 #Populate
   1221 ##
   1222 
   1223 AllocFlags provides the option to zero pixel memory when allocated.
   1224 
   1225 #Const kZeroPixels_AllocFlag 1
   1226 #Line # zero pixel memory ##
   1227     Instructs tryAllocPixelsFlags and allocPixelsFlags to zero pixel memory.
   1228 ##
   1229 
   1230 #NoExample
   1231 ##
   1232 
   1233 #SeeAlso tryAllocPixelsFlags allocPixelsFlags erase eraseColor
   1234 
   1235 ##
   1236 
   1237 # ------------------------------------------------------------------------------
   1238 #Subtopic Allocate
   1239 #Line # allocates storage for pixels ##
   1240 ##
   1241 
   1242 #Method bool tryAllocPixelsFlags(const SkImageInfo& info, uint32_t flags)
   1243 #In Allocate
   1244 #Line # allocates pixels from Image_Info with options if possible ##
   1245 #Populate
   1246 
   1247 #Example
   1248     SkBitmap bitmap;
   1249     if (!bitmap.tryAllocPixelsFlags(SkImageInfo::MakeN32(10000, 10000, kOpaque_SkAlphaType),
   1250                                     SkBitmap::kZeroPixels_AllocFlag)) {
   1251         SkDebugf("bitmap allocation failed!\n");
   1252     } else {
   1253         SkDebugf("bitmap allocation succeeded!\n");
   1254     }
   1255 #StdOut
   1256 bitmap allocation succeeded!
   1257 ##
   1258 ##
   1259 
   1260 #SeeAlso allocPixelsFlags tryAllocPixels SkMallocPixelRef::MakeZeroed
   1261 
   1262 ##
   1263 
   1264 # ------------------------------------------------------------------------------
   1265 
   1266 #Method void allocPixelsFlags(const SkImageInfo& info, uint32_t flags)
   1267 #In Allocate
   1268 #Line # allocates pixels from Image_Info with options, or aborts ##
   1269 #Populate
   1270 
   1271 #Example
   1272 #Height 128
   1273 #Description
   1274 Text is drawn on a transparent background; drawing the bitmap a second time
   1275 lets the first draw show through.
   1276 ##
   1277 ###^
   1278 SkBitmap bitmap;
   1279 bitmap.allocPixelsFlags(SkImageInfo::MakeN32(44, 16, kPremul_SkAlphaType),
   1280                         SkBitmap::kZeroPixels_AllocFlag);
   1281 SkCanvas offscreen(bitmap);
   1282 SkPaint paint;
   1283 offscreen.drawString("!@#$%", 0, 12, paint);
   1284 canvas->scale(6, 6);
   1285 canvas->drawBitmap(bitmap, 0, 0);
   1286 canvas->drawBitmap(bitmap, 8, 8);
   1287 ^^^#
   1288 ##
   1289 
   1290 #SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeZeroed
   1291 
   1292 ##
   1293 
   1294 # ------------------------------------------------------------------------------
   1295 
   1296 #Method bool tryAllocPixels(const SkImageInfo& info, size_t rowBytes)
   1297 #In Allocate
   1298 #Line # allocates pixels from Image_Info if possible ##
   1299 #Populate
   1300 
   1301 #Example
   1302 #Image 3
   1303 SkBitmap bitmap;
   1304 SkImageInfo info = SkImageInfo::Make(64, 256, kGray_8_SkColorType, kOpaque_SkAlphaType);
   1305 if (bitmap.tryAllocPixels(info, 0)) {
   1306     SkCanvas offscreen(bitmap);
   1307     offscreen.scale(.5f, .5f);
   1308     for (int x : { 0, 64, 128, 192 } ) {
   1309         offscreen.drawBitmap(source, -x, 0);
   1310         canvas->drawBitmap(bitmap, x, 0);
   1311     }
   1312 }
   1313 ##
   1314 
   1315 #SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate
   1316 
   1317 ##
   1318 
   1319 # ------------------------------------------------------------------------------
   1320 
   1321 #Method void allocPixels(const SkImageInfo& info, size_t rowBytes)
   1322 #In Allocate
   1323 #Line # allocates pixels from Image_Info, or aborts ##
   1324 #Populate
   1325 
   1326 #Example
   1327 #Image 3
   1328 SkBitmap bitmap;
   1329 SkImageInfo info = SkImageInfo::Make(256, 64, kGray_8_SkColorType, kOpaque_SkAlphaType);
   1330 bitmap.allocPixels(info, info.width() * info.bytesPerPixel() + 64);
   1331 SkCanvas offscreen(bitmap);
   1332 offscreen.scale(.5f, .5f);
   1333 for (int y : { 0, 64, 128, 192 } ) {
   1334     offscreen.drawBitmap(source, 0, -y);
   1335     canvas->drawBitmap(bitmap, 0, y);
   1336 }
   1337 ##
   1338 
   1339 #SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate
   1340 
   1341 ##
   1342 
   1343 # ------------------------------------------------------------------------------
   1344 
   1345 #Method bool tryAllocPixels(const SkImageInfo& info)
   1346 #Populate
   1347 
   1348 #Example
   1349 #Image 3
   1350 SkBitmap bitmap;
   1351 if (bitmap.tryAllocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType))) {
   1352     SkCanvas offscreen(bitmap);
   1353     offscreen.scale(.25f, .5f);
   1354     for (int y : { 0, 64, 128, 192 } ) {
   1355         offscreen.drawBitmap(source, -y, -y);
   1356         canvas->drawBitmap(bitmap, y, y);
   1357     }
   1358 }
   1359 ##
   1360 
   1361 #SeeAlso tryAllocPixelsFlags allocPixels SkMallocPixelRef::MakeAllocate
   1362 
   1363 ##
   1364 
   1365 # ------------------------------------------------------------------------------
   1366 
   1367 #Method void allocPixels(const SkImageInfo& info)
   1368 #Populate
   1369 
   1370 #Example
   1371 #Image 4
   1372 SkBitmap bitmap;
   1373 bitmap.allocPixels(SkImageInfo::Make(64, 64, kGray_8_SkColorType, kOpaque_SkAlphaType));
   1374 SkCanvas offscreen(bitmap);
   1375 offscreen.scale(.5f, .5f);
   1376 for (int y : { 0, 64, 128, 192 } ) {
   1377     offscreen.drawBitmap(source, -y, -y);
   1378     canvas->drawBitmap(bitmap, y, y);
   1379 }
   1380 ##
   1381 
   1382 #SeeAlso tryAllocPixels allocPixelsFlags SkMallocPixelRef::MakeAllocate
   1383 
   1384 ##
   1385 
   1386 # ------------------------------------------------------------------------------
   1387 
   1388 #Method bool tryAllocN32Pixels(int width, int height, bool isOpaque = false)
   1389 #In Allocate
   1390 #Line # allocates compatible ARGB pixels if possible ##
   1391 #Populate
   1392 
   1393 #Example
   1394 #Height 160
   1395     SkBitmap bitmap;
   1396     if (bitmap.tryAllocN32Pixels(80, 80)) {
   1397         bitmap.eraseColor(SK_ColorTRANSPARENT);
   1398         bitmap.erase(0x7f3f7fff, SkIRect::MakeWH(50, 30));
   1399         bitmap.erase(0x3f7fff3f, SkIRect::MakeXYWH(20, 10, 50, 30));
   1400         bitmap.erase(0x5fff3f7f, SkIRect::MakeXYWH(40, 20, 50, 30));
   1401         canvas->drawBitmap(bitmap, 0, 0);
   1402         for (int x : { 0, 30, 60, 90 } ) {
   1403             canvas->drawBitmap(bitmap, x, 70);
   1404         }
   1405     }
   1406 ##
   1407 
   1408 #SeeAlso tryAllocPixels allocN32Pixels SkMallocPixelRef::MakeAllocate
   1409 
   1410 ##
   1411 
   1412 # ------------------------------------------------------------------------------
   1413 
   1414 #Method void allocN32Pixels(int width, int height, bool isOpaque = false)
   1415 #In Allocate
   1416 #Line # allocates compatible ARGB pixels, or aborts ##
   1417 #Populate
   1418 
   1419 #Example
   1420     SkRandom random;
   1421     SkBitmap bitmap;
   1422     bitmap.allocN32Pixels(64, 64);
   1423     bitmap.eraseColor(SK_ColorTRANSPARENT);
   1424     for (int y = 0; y < 256; y += 64) {
   1425         for (int x = 0; x < 256; x += 64) {
   1426             SkColor color = random.nextU();
   1427             uint32_t w = random.nextRangeU(4, 32);
   1428             uint32_t cx = random.nextRangeU(0, 64 - w);
   1429             uint32_t h = random.nextRangeU(4, 32);
   1430             uint32_t cy = random.nextRangeU(0, 64 - h);
   1431             bitmap.erase(color, SkIRect::MakeXYWH(cx, cy, w, h));
   1432             canvas->drawBitmap(bitmap, x, y);
   1433         }
   1434     }
   1435 ##
   1436 
   1437 #SeeAlso allocPixels tryAllocN32Pixels SkMallocPixelRef::MakeAllocate
   1438 
   1439 ##
   1440 
   1441 # ------------------------------------------------------------------------------
   1442 
   1443 #Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
   1444                        void (*releaseProc)(void* addr, void* context), void* context)
   1445 #In Allocate
   1446 #Line # creates Pixel_Ref, with optional release function ##
   1447 #Populate
   1448 
   1449 #Example
   1450 #Description
   1451 releaseProc is called immediately because rowBytes is too small for Pixel_Ref.
   1452 ##
   1453 #Function
   1454 static void releaseProc(void* addr, void* ) {
   1455     SkDebugf("releaseProc called\n");
   1456     delete[] (uint32_t*) addr;
   1457 }
   1458 
   1459 ##
   1460 
   1461 void draw(SkCanvas* canvas) {
   1462    SkBitmap bitmap;
   1463    void* pixels = new uint32_t[8 * 8];
   1464    SkImageInfo info = SkImageInfo::MakeN32(8, 8, kOpaque_SkAlphaType);
   1465    SkDebugf("before installPixels\n");
   1466    bool installed = bitmap.installPixels(info, pixels, 16, releaseProc, nullptr);
   1467    SkDebugf("install " "%s" "successful\n", installed ? "" : "not ");
   1468 }
   1469 #StdOut
   1470 before installPixels
   1471 releaseProc called
   1472 install not successful
   1473 ##
   1474 ##
   1475 
   1476 #SeeAlso allocPixels
   1477 
   1478 ##
   1479 
   1480 # ------------------------------------------------------------------------------
   1481 
   1482 #Method bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes)
   1483 #Populate
   1484 
   1485 #Example
   1486 #Bug 7079
   1487 #Description
   1488 GPU does not support kUnpremul_SkAlphaType, does not assert that it does not.
   1489 ##
   1490 void draw(SkCanvas* canvas) {
   1491    SkRandom random;
   1492    SkBitmap bitmap;
   1493    const int width = 8;
   1494    const int height = 8;
   1495    uint32_t pixels[width * height];
   1496    for (unsigned x = 0; x < width * height; ++x) {
   1497        pixels[x] = random.nextU();
   1498    }
   1499    SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType);
   1500    if (bitmap.installPixels(info, pixels, info.minRowBytes())) {
   1501        canvas->scale(32, 32);
   1502        canvas->drawBitmap(bitmap, 0, 0);
   1503    }
   1504 }
   1505 ##
   1506 
   1507 #SeeAlso allocPixels
   1508 
   1509 ##
   1510 
   1511 # ------------------------------------------------------------------------------
   1512 
   1513 #Method bool installPixels(const SkPixmap& pixmap)
   1514 #Populate
   1515 
   1516 #Example
   1517 #Description
   1518 Draw a five by five bitmap, and draw it again with a center white pixel.
   1519 ##
   1520 #Height 64
   1521     uint8_t storage[][5] = {{ 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 },
   1522                             { 0xAC, 0xA8, 0x89, 0x47, 0x87 },
   1523                             { 0x4B, 0x25, 0x25, 0x25, 0x46 },
   1524                             { 0x90, 0x81, 0x25, 0x41, 0x33 },
   1525                             { 0x75, 0x55, 0x44, 0x20, 0x00 }};
   1526     SkImageInfo imageInfo = SkImageInfo::Make(5, 5, kGray_8_SkColorType, kOpaque_SkAlphaType);
   1527     SkPixmap pixmap(imageInfo, storage[0], sizeof(storage) / 5);
   1528     SkBitmap bitmap;
   1529     bitmap.installPixels(pixmap);
   1530     canvas->scale(10, 10);
   1531     canvas->drawBitmap(bitmap, 0, 0);
   1532     *pixmap.writable_addr8(2, 2) = 0xFF;
   1533     bitmap.installPixels(pixmap);
   1534     canvas->drawBitmap(bitmap, 10, 0);
   1535 ##
   1536 
   1537 #SeeAlso allocPixels
   1538 
   1539 ##
   1540 
   1541 # ------------------------------------------------------------------------------
   1542 #Subtopic Pixels
   1543 #Line # read and write pixel values ##
   1544 ##
   1545 
   1546 #Method void setPixels(void* pixels)
   1547 #In Pixels
   1548 #Line # sets Pixel_Ref without an offset ##
   1549 #Populate
   1550 
   1551 #Example
   1552 #Height 50
   1553     uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
   1554     uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 };
   1555     SkBitmap bitmap;
   1556     bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
   1557     canvas->scale(10, 50);
   1558     canvas->drawBitmap(bitmap, 0, 0);
   1559     bitmap.setPixels(set2);
   1560     canvas->drawBitmap(bitmap, 10, 0);
   1561 ##
   1562 
   1563 #SeeAlso installPixels allocPixels
   1564 
   1565 ##
   1566 
   1567 # ------------------------------------------------------------------------------
   1568 
   1569 #Method bool tryAllocPixels()
   1570 #In Allocate
   1571 #Populate
   1572 
   1573 #Example
   1574 #Height 50
   1575 #Description
   1576 Bitmap hosts and draws gray values in set1. tryAllocPixels replaces Pixel_Ref
   1577 and erases it to black, but does not alter set1. setPixels replaces black
   1578 Pixel_Ref with set1.
   1579 ##
   1580     uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
   1581     SkBitmap bitmap;
   1582     bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
   1583     canvas->scale(10, 50);
   1584     canvas->drawBitmap(bitmap, 0, 0);
   1585     if (bitmap.tryAllocPixels()) {
   1586         bitmap.eraseColor(SK_ColorBLACK);
   1587         canvas->drawBitmap(bitmap, 8, 0);
   1588         bitmap.setPixels(set1);
   1589         canvas->drawBitmap(bitmap, 16, 0);
   1590     }
   1591 ##
   1592 
   1593 #SeeAlso allocPixels installPixels setPixels
   1594 
   1595 ##
   1596 
   1597 # ------------------------------------------------------------------------------
   1598 
   1599 #Method void allocPixels()
   1600 #In Allocate
   1601 #Populate
   1602 
   1603 #Example
   1604 #Height 50
   1605 #Description
   1606 Bitmap hosts and draws gray values in set1. allocPixels replaces Pixel_Ref
   1607 and erases it to black, but does not alter set1. setPixels replaces black
   1608 Pixel_Ref with set2.
   1609 ##
   1610     uint8_t set1[5] = { 0xCA, 0xDA, 0xCA, 0xC9, 0xA3 };
   1611     uint8_t set2[5] = { 0xAC, 0xA8, 0x89, 0x47, 0x87 };
   1612     SkBitmap bitmap;
   1613     bitmap.installPixels(SkImageInfo::Make(5, 1, kGray_8_SkColorType, kOpaque_SkAlphaType), set1, 5);
   1614     canvas->scale(10, 50);
   1615     canvas->drawBitmap(bitmap, 0, 0);
   1616     bitmap.allocPixels();
   1617     bitmap.eraseColor(SK_ColorBLACK);
   1618     canvas->drawBitmap(bitmap, 8, 0);
   1619     bitmap.setPixels(set2);
   1620     canvas->drawBitmap(bitmap, 16, 0);
   1621 ##
   1622 
   1623 #SeeAlso tryAllocPixels installPixels setPixels
   1624 
   1625 ##
   1626 
   1627 # ------------------------------------------------------------------------------
   1628 
   1629 #Method bool tryAllocPixels(Allocator* allocator)
   1630 #Populate
   1631 
   1632 #Example
   1633 #Height 100
   1634 #Description
   1635 HeapAllocator limits the maximum size of Bitmap to two gigabytes. Using
   1636 a custom allocator, this limitation may be relaxed. This example can be
   1637 modified to allocate an eight gigabyte Bitmap on a 64-bit platform with
   1638 sufficient memory.
   1639 ##
   1640 #Function
   1641 class LargePixelRef : public SkPixelRef {
   1642 public:
   1643     LargePixelRef(const SkImageInfo& info, char* storage, size_t rowBytes)
   1644         : SkPixelRef(info.width(), info.height(), storage, rowBytes) {
   1645     }
   1646 
   1647     ~LargePixelRef() override {
   1648         delete[] (char* ) this->pixels();
   1649     }
   1650 };
   1651 
   1652 class LargeAllocator : public SkBitmap::Allocator {
   1653 public:
   1654     bool allocPixelRef(SkBitmap* bitmap) override {
   1655         const SkImageInfo& info = bitmap->info();
   1656         uint64_t rowBytes = info.minRowBytes64();
   1657         uint64_t size = info.height() * rowBytes;
   1658         char* addr = new char[size];
   1659         if (nullptr == addr) {
   1660             return false;
   1661         }
   1662         sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(new LargePixelRef(info, addr, rowBytes));
   1663         if (!pr) {
   1664             return false;
   1665         }
   1666         bitmap->setPixelRef(std::move(pr), 0, 0);
   1667         return true;
   1668     }
   1669 };
   1670 
   1671 ##
   1672 
   1673 void draw(SkCanvas* canvas) {
   1674    LargeAllocator largeAllocator;
   1675    SkBitmap bitmap;
   1676    int width = 100; // make this 20000
   1677    int height = 100; // and this 100000 to allocate 8 gigs on a 64-bit platform
   1678    bitmap.setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType));
   1679    if (bitmap.tryAllocPixels(&largeAllocator)) {
   1680        bitmap.eraseColor(0xff55aa33);
   1681        canvas->drawBitmap(bitmap, 0, 0);
   1682    }
   1683 }
   1684 
   1685 ##
   1686 
   1687 #SeeAlso allocPixels Allocator Pixel_Ref
   1688 
   1689 ##
   1690 
   1691 # ------------------------------------------------------------------------------
   1692 
   1693 #Method void allocPixels(Allocator* allocator)
   1694 #Populate
   1695 
   1696 #Example
   1697 #Height 32
   1698 #Function
   1699 class TinyAllocator : public SkBitmap::Allocator {
   1700 public:
   1701     bool allocPixelRef(SkBitmap* bitmap) override {
   1702         const SkImageInfo& info = bitmap->info();
   1703         if (info.height() * info.minRowBytes() > sizeof(storage)) {
   1704             return false;
   1705         }
   1706         sk_sp<SkPixelRef> pr = sk_sp<SkPixelRef>(
   1707                 new SkPixelRef(info.width(), info.height(), storage, info.minRowBytes()));
   1708         bitmap->setPixelRef(std::move(pr), 0, 0);
   1709         return true;
   1710     }
   1711 
   1712     char storage[16];
   1713 };
   1714 
   1715 ##
   1716 
   1717 void draw(SkCanvas* canvas) {
   1718    TinyAllocator tinyAllocator;
   1719    SkBitmap bitmap;
   1720    bitmap.setInfo(SkImageInfo::MakeN32(2, 2, kOpaque_SkAlphaType));
   1721    if (bitmap.tryAllocPixels(&tinyAllocator)) {
   1722        bitmap.eraseColor(0xff55aa33);
   1723        bitmap.erase(0xffaa3355, SkIRect::MakeXYWH(1, 1, 1, 1));
   1724        canvas->scale(16, 16);
   1725        canvas->drawBitmap(bitmap, 0, 0);
   1726    }
   1727 }
   1728 ##
   1729 
   1730 #SeeAlso allocPixels Allocator Pixel_Ref
   1731 
   1732 ##
   1733 
   1734 # ------------------------------------------------------------------------------
   1735 
   1736 #Method SkPixelRef* pixelRef() const
   1737 #In Property
   1738 #Line # returns Pixel_Ref, or nullptr ##
   1739 #Populate
   1740 
   1741 #Example
   1742 #Image 3
   1743    SkBitmap subset;
   1744    source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256));
   1745    SkDebugf("src ref %c= sub ref\n", source.pixelRef() == subset.pixelRef() ? '=' : '!');
   1746    SkDebugf("src pixels %c= sub pixels\n", source.getPixels() == subset.getPixels() ? '=' : '!');
   1747    SkDebugf("src addr %c= sub addr\n", source.getAddr(32, 64) == subset.getAddr(0, 0) ? '=' : '!');
   1748 ##
   1749 
   1750 #SeeAlso getPixels getAddr
   1751 
   1752 ##
   1753 
   1754 # ------------------------------------------------------------------------------
   1755 
   1756 #Method SkIPoint pixelRefOrigin() const
   1757 #In Property
   1758 #Line # returns offset within Pixel_Ref ##
   1759 #Populate
   1760 
   1761 #Example
   1762 #Image 3
   1763    SkBitmap subset;
   1764    source.extractSubset(&subset, SkIRect::MakeXYWH(32, 64, 128, 256));
   1765    SkIPoint sourceOrigin = source.pixelRefOrigin();
   1766    SkIPoint subsetOrigin = subset.pixelRefOrigin();
   1767    SkDebugf("source origin: %d, %d\n", sourceOrigin.fX, sourceOrigin.fY);
   1768    SkDebugf("subset origin: %d, %d\n", subsetOrigin.fX, subsetOrigin.fY);
   1769 #StdOut
   1770 source origin: 0, 0
   1771 subset origin: 32, 64
   1772 ##
   1773 ##
   1774 
   1775 #SeeAlso SkPixelRef getSubset setPixelRef
   1776 
   1777 ##
   1778 
   1779 # ------------------------------------------------------------------------------
   1780 #Subtopic Set
   1781 #Line # updates values and attributes ##
   1782 ##
   1783 
   1784 #Method void setPixelRef(sk_sp<SkPixelRef> pixelRef, int dx, int dy)
   1785 #In Set
   1786 #Line # sets Pixel_Ref and offset ##
   1787 #Populate
   1788 
   1789 #Example
   1790 #Height 140
   1791 #Image 5
   1792 #Description
   1793 Treating 32-bit data as 8-bit data is unlikely to produce useful results.
   1794 ##
   1795     SkBitmap bitmap;
   1796     bitmap.setInfo(SkImageInfo::Make(source.width() - 5, source.height() - 5,
   1797                    kGray_8_SkColorType, kOpaque_SkAlphaType), source.rowBytes());
   1798     bitmap.setPixelRef(sk_ref_sp(source.pixelRef()), 5, 5);
   1799     canvas->drawBitmap(bitmap, 10, 10);
   1800 ##
   1801 
   1802 #SeeAlso setInfo
   1803 
   1804 ##
   1805 
   1806 # ------------------------------------------------------------------------------
   1807 
   1808 #Method bool readyToDraw() const
   1809 #In Utility
   1810 #Line # returns true if address of pixels is not nullptr ##
   1811 #Populate
   1812 
   1813 #Example
   1814 #Image 5
   1815 #Height 160
   1816     if (source.readyToDraw()) {
   1817         canvas->drawBitmap(source, 10, 10);
   1818     }
   1819 ##
   1820 
   1821 #SeeAlso getPixels drawsNothing
   1822 
   1823 ##
   1824 
   1825 # ------------------------------------------------------------------------------
   1826 
   1827 #Method uint32_t getGenerationID() const
   1828 #In Utility
   1829 #Line # returns unique ID ##
   1830 #Populate
   1831 
   1832 #Example
   1833     SkBitmap bitmap;
   1834     SkDebugf("empty id %u\n", bitmap.getGenerationID());
   1835     bitmap.allocPixels(SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType));
   1836     SkDebugf("alloc id %u\n", bitmap.getGenerationID());
   1837     bitmap.eraseColor(SK_ColorRED);
   1838     SkDebugf("erase id %u\n", bitmap.getGenerationID());
   1839 #StdOut
   1840 #Volatile
   1841 empty id 0
   1842 alloc id 4
   1843 erase id 6
   1844 ##
   1845 ##
   1846 
   1847 #SeeAlso notifyPixelsChanged Pixel_Ref
   1848 
   1849 ##
   1850 
   1851 # ------------------------------------------------------------------------------
   1852 
   1853 #Method void notifyPixelsChanged() const
   1854 #In Pixels
   1855 #Line # marks pixels as changed, altering the unique ID ##
   1856 #Populate
   1857 
   1858 #Example
   1859 #Height 20
   1860     SkBitmap bitmap;
   1861     bitmap.setInfo(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
   1862     bitmap.allocPixels();
   1863     bitmap.eraseColor(SK_ColorRED);
   1864     canvas->scale(16, 16);
   1865     canvas->drawBitmap(bitmap, 0, 0);
   1866     *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorBLUE);
   1867     canvas->drawBitmap(bitmap, 2, 0);
   1868     bitmap.notifyPixelsChanged();
   1869     *(SkPMColor*) bitmap.getPixels() = SkPreMultiplyColor(SK_ColorGREEN);
   1870     canvas->drawBitmap(bitmap, 4, 0);
   1871 ##
   1872 
   1873 #SeeAlso getGenerationID isVolatile Pixel_Ref
   1874 
   1875 ##
   1876 
   1877 # ------------------------------------------------------------------------------
   1878 #Subtopic Draw
   1879 #Line # sets pixels to Color ##
   1880 ##
   1881 
   1882 #Method void eraseColor(SkColor c) const
   1883 #In Draw
   1884 #Line # writes Color to pixels ##
   1885 #Populate
   1886 
   1887 #Example
   1888 #Height 20
   1889     SkBitmap bitmap;
   1890     bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kOpaque_SkAlphaType));
   1891     bitmap.eraseColor(SK_ColorRED);
   1892     canvas->scale(16, 16);
   1893     canvas->drawBitmap(bitmap, 0, 0);
   1894 ##
   1895 
   1896 #SeeAlso eraseARGB erase
   1897 
   1898 ##
   1899 
   1900 # ------------------------------------------------------------------------------
   1901 
   1902 #Method void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const
   1903 #In Draw
   1904 #Line # writes Color to pixels ##
   1905 #Populate
   1906 
   1907 #Example
   1908 #Height 80
   1909     SkBitmap bitmap;
   1910     bitmap.allocPixels(SkImageInfo::MakeN32(1, 1, kPremul_SkAlphaType));
   1911     bitmap.eraseARGB(0x7f, 0xff, 0x7f, 0x3f);
   1912     canvas->scale(50, 50);
   1913     canvas->drawBitmap(bitmap, 0, 0);
   1914     canvas->drawBitmap(bitmap, .5f, .5f);
   1915 ##
   1916 
   1917 #SeeAlso eraseColor erase
   1918 
   1919 ##
   1920 
   1921 # ------------------------------------------------------------------------------
   1922 
   1923 #Method void erase(SkColor c, const SkIRect& area) const
   1924 #In Draw
   1925 #Line # writes Color to rectangle of pixels ##
   1926 #Populate
   1927 
   1928 #Example
   1929 #Height 70
   1930     SkBitmap bitmap;
   1931     bitmap.allocPixels(SkImageInfo::MakeN32(2, 2, kPremul_SkAlphaType));
   1932     bitmap.erase(0x7fff7f3f, SkIRect::MakeWH(1, 1));
   1933     bitmap.erase(0x7f7f3fff, SkIRect::MakeXYWH(0, 1, 1, 1));
   1934     bitmap.erase(0x7f3fff7f, SkIRect::MakeXYWH(1, 0, 1, 1));
   1935     bitmap.erase(0x7f1fbf5f, SkIRect::MakeXYWH(1, 1, 1, 1));
   1936     canvas->scale(25, 25);
   1937     canvas->drawBitmap(bitmap, 0, 0);
   1938     canvas->drawBitmap(bitmap, .5f, .5f);
   1939 
   1940 ##
   1941 
   1942 #SeeAlso eraseColor eraseARGB SkCanvas::drawRect
   1943 
   1944 ##
   1945 
   1946 # ------------------------------------------------------------------------------
   1947 
   1948 #Method SkColor getColor(int x, int y) const
   1949 #In Property
   1950 #In Pixels
   1951 #Line # returns one pixel as Unpremultiplied Color ##
   1952 #Populate
   1953 
   1954 #Example
   1955     const int w = 4;
   1956     const int h = 4;
   1957     SkColor colors[][w] = {
   1958         { 0x00000000, 0x2a0e002a, 0x55380055, 0x7f7f007f },
   1959         { 0x2a000e2a, 0x551c1c55, 0x7f542a7f, 0xaaaa38aa },
   1960         { 0x55003855, 0x7f2a547f, 0xaa7171aa, 0xd4d48dd4 },
   1961         { 0x7f007f7f, 0xaa38aaaa, 0xd48dd4d4, 0xffffffff }
   1962     };
   1963     SkDebugf("Premultiplied:\n");
   1964     for (int y = 0; y < h; ++y) {
   1965         SkDebugf("(0, %d) ", y);
   1966         for (int x = 0; x < w; ++x) {
   1967             SkDebugf("0x%08x%c", colors[y][x], x == w - 1 ? '\n' : ' ');
   1968         }
   1969     }
   1970     SkPixmap pixmap(SkImageInfo::MakeN32(w, h, kPremul_SkAlphaType), colors, w * 4);
   1971     SkBitmap bitmap;
   1972     bitmap.installPixels(pixmap);
   1973     SkDebugf("Unpremultiplied:\n");
   1974     for (int y = 0; y < h; ++y) {
   1975         SkDebugf("(0, %d) ", y);
   1976         for (int x = 0; x < w; ++x) {
   1977             SkDebugf("0x%08x%c", bitmap.getColor(x, y), x == w - 1 ? '\n' : ' ');
   1978         }
   1979     }
   1980 #StdOut
   1981 Premultiplied:
   1982 (0, 0) 0x00000000 0x2a0e002a 0x55380055 0x7f7f007f
   1983 (0, 1) 0x2a000e2a 0x551c1c55 0x7f542a7f 0xaaaa38aa
   1984 (0, 2) 0x55003855 0x7f2a547f 0xaa7171aa 0xd4d48dd4
   1985 (0, 3) 0x7f007f7f 0xaa38aaaa 0xd48dd4d4 0xffffffff
   1986 Unpremultiplied:
   1987 (0, 0) 0x00000000 0x2a5500ff 0x55a800ff 0x7fff00ff
   1988 (0, 1) 0x2a0055ff 0x555454ff 0x7fa954ff 0xaaff54ff
   1989 (0, 2) 0x5500a8ff 0x7f54a9ff 0xaaaaaaff 0xd4ffaaff
   1990 (0, 3) 0x7f00ffff 0xaa54ffff 0xd4aaffff 0xffffffff
   1991 ##
   1992 ##
   1993 
   1994 #SeeAlso getAlphaf getAddr readPixels
   1995 
   1996 ##
   1997 
   1998 #Method float getAlphaf(int x, int y) const
   1999 #In Property
   2000 #Line # returns Alpha normalized from zero to one ##
   2001 
   2002 Looks up the pixel at (x,y) and return its alpha component, normalized to [0..1].
   2003 This is roughly equivalent to #Formula # SkGetColorA(getColor()) ##, but can be more efficient
   2004 (and more precise if the pixels store more than 8 bits per component).
   2005 
   2006 #Param x  column index, zero or greater, and less than width() ##
   2007 #Param y  row index, zero or greater, and less than height() ##
   2008 
   2009 #Return   alpha converted to normalized float ##
   2010 
   2011 #NoExample
   2012 ##
   2013 
   2014 #SeeAlso getColor
   2015 
   2016 ##
   2017 
   2018 
   2019 # ------------------------------------------------------------------------------
   2020 
   2021 #Method void* getAddr(int x, int y) const
   2022 #In Property
   2023 #Line # returns readable pixel address as void pointer ##
   2024 #Populate
   2025 
   2026 #Example
   2027 #Image 3
   2028     char* row0 = (char* ) source.getAddr(0, 0);
   2029     char* row1 = (char* ) source.getAddr(0, 1);
   2030     SkDebugf("addr interval %c= rowBytes\n",
   2031              (size_t) (row1 - row0) == source.rowBytes() ? '=' : '!');
   2032 #StdOut
   2033 addr interval == rowBytes
   2034 ##
   2035 ##
   2036 
   2037 #SeeAlso getAddr8 getAddr16 getAddr32 readPixels SkPixmap::addr
   2038 
   2039 ##
   2040 
   2041 # ------------------------------------------------------------------------------
   2042 
   2043 #Method uint32_t* getAddr32(int x, int y) const
   2044 #In Property
   2045 #Line # returns readable pixel address as 32-bit pointer ##
   2046 Returns address at (x, y).
   2047 
   2048 Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
   2049 #List
   2050 # Pixel_Ref is nullptr ##
   2051 # bytesPerPixel() is not four ##
   2052 # x is negative, or not less than width() ##
   2053 # y is negative, or not less than height() ##
   2054 ##
   2055 
   2056 #Param x  column index, zero or greater, and less than width() ##
   2057 #Param y  row index, zero or greater, and less than height() ##
   2058 
   2059 #Return  unsigned 32-bit pointer to pixel at (x, y) ##
   2060 
   2061 #Example
   2062 #Image 3
   2063     uint32_t* row0 = source.getAddr32(0, 0);
   2064     uint32_t* row1 = source.getAddr32(0, 1);
   2065     size_t interval = (row1 - row0) * source.bytesPerPixel();
   2066     SkDebugf("addr interval %c= rowBytes\n", interval == source.rowBytes() ? '=' : '!');
   2067 #StdOut
   2068 addr interval == rowBytes
   2069 ##
   2070 ##
   2071 
   2072 #SeeAlso getAddr8 getAddr16 getAddr readPixels SkPixmap::addr32
   2073 
   2074 ##
   2075 
   2076 # ------------------------------------------------------------------------------
   2077 
   2078 #Method uint16_t* getAddr16(int x, int y) const
   2079 #In Property
   2080 #Line # returns readable pixel address as 16-bit pointer ##
   2081 Returns address at (x, y).
   2082 
   2083 Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
   2084 #List
   2085 # Pixel_Ref is nullptr ##
   2086 # bytesPerPixel() is not two ##
   2087 # x is negative, or not less than width() ##
   2088 # y is negative, or not less than height() ##
   2089 ##
   2090 
   2091 #Param x  column index, zero or greater, and less than width() ##
   2092 #Param y  row index, zero or greater, and less than height() ##
   2093 
   2094 #Return  unsigned 16-bit pointer to pixel at (x, y)##
   2095 
   2096 #Example
   2097 #Image 3
   2098     SkBitmap bitmap16;
   2099     SkImageInfo dstInfo = SkImageInfo::Make(source.width(), source.height(), kARGB_4444_SkColorType,
   2100                      kPremul_SkAlphaType);
   2101     bitmap16.allocPixels(dstInfo);
   2102     if (source.readPixels(dstInfo, bitmap16.getPixels(), bitmap16.rowBytes(), 0, 0)) {
   2103         uint16_t* row0 = bitmap16.getAddr16(0, 0);
   2104         uint16_t* row1 = bitmap16.getAddr16(0, 1);
   2105         size_t interval = (row1 - row0) * bitmap16.bytesPerPixel();
   2106         SkDebugf("addr interval %c= rowBytes\n", interval == bitmap16.rowBytes() ? '=' : '!');
   2107     }
   2108 #StdOut
   2109 addr interval == rowBytes
   2110 ##
   2111 ##
   2112 
   2113 #SeeAlso getAddr8 getAddr getAddr32 readPixels SkPixmap::addr16
   2114 
   2115 ##
   2116 
   2117 # ------------------------------------------------------------------------------
   2118 
   2119 #Method uint8_t* getAddr8(int x, int y) const
   2120 #In Property
   2121 #Line # returns readable pixel address as 8-bit pointer ##
   2122 Returns address at (x, y).
   2123 
   2124 Input is not validated. Triggers an assert() if built with SK_DEBUG defined and:
   2125 #List
   2126 # Pixel_Ref is nullptr ##
   2127 # bytesPerPixel() is not one ##
   2128 # x is negative, or not less than width() ##
   2129 # y is negative, or not less than height() ##
   2130 ##
   2131 
   2132 #Param x  column index, zero or greater, and less than width() ##
   2133 #Param y  row index, zero or greater, and less than height() ##
   2134 
   2135 #Return unsigned 8-bit pointer to pixel at (x, y) ##
   2136 
   2137 #Example
   2138    SkBitmap bitmap;
   2139    const int width = 8;
   2140    const int height = 8;
   2141    uint8_t pixels[height][width];
   2142    SkImageInfo info = SkImageInfo::Make(width, height, kGray_8_SkColorType, kOpaque_SkAlphaType);
   2143    if (bitmap.installPixels(info, pixels, info.minRowBytes())) {
   2144        SkDebugf("&pixels[4][2] %c= bitmap.getAddr8(2, 4)\n",
   2145                  &pixels[4][2]  == bitmap.getAddr8(2, 4) ? '=' : '!');
   2146    }
   2147 #StdOut
   2148 &pixels[4][2] == bitmap.getAddr8(2, 4)
   2149 ##
   2150 ##
   2151 
   2152 #SeeAlso getAddr getAddr16 getAddr32 readPixels SkPixmap::addr8
   2153 
   2154 ##
   2155 
   2156 # ------------------------------------------------------------------------------
   2157 
   2158 #Method bool extractSubset(SkBitmap* dst, const SkIRect& subset) const
   2159 #In Constructors
   2160 #Line # creates Bitmap, sharing pixels if possible ##
   2161 Shares Pixel_Ref with dst. Pixels are not copied; Bitmap and dst point
   2162 to the same pixels; dst bounds() are set to the intersection of subset
   2163 and the original bounds().
   2164 
   2165 subset may be larger than bounds(). Any area outside of bounds() is ignored.
   2166 
   2167 Any contents of dst are discarded. isVolatile setting is copied to dst.
   2168 dst is set to colorType, alphaType, and colorSpace.
   2169 
   2170 Return false if:
   2171 #List
   2172 # dst is nullptr ##
   2173 # Pixel_Ref is nullptr ##
   2174 # subset does not intersect bounds() ##
   2175 ##
   2176 
   2177 #Param dst  Bitmap set to subset ##
   2178 #Param subset  rectangle of pixels to reference ##
   2179 
   2180 #Return  true if dst is replaced by subset
   2181 ##
   2182 
   2183 #Example
   2184 #Image 3
   2185     SkIRect bounds, s;
   2186     source.getBounds(&bounds);
   2187     SkDebugf("bounds: %d, %d, %d, %d\n", bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
   2188     SkBitmap subset;
   2189     for (int left: { -100, 0, 100, 1000 } ) {
   2190          for (int right: { 0, 100, 1000 } ) {
   2191              SkIRect b = SkIRect::MakeLTRB(left, 100, right, 200);
   2192              bool success = source.extractSubset(&subset, b);
   2193              SkDebugf("subset: %4d, %4d, %4d, %4d  ", b.fLeft, b.fTop, b.fRight, b.fBottom);
   2194              SkDebugf("success; %s", success ? "true" : "false");
   2195              if (success) {
   2196                  subset.getBounds(&s);
   2197                  SkDebugf("  subset: %d, %d, %d, %d", s.fLeft, s.fTop, s.fRight, s.fBottom);
   2198              }
   2199              SkDebugf("\n");
   2200          }
   2201     }
   2202 #StdOut
   2203 bounds: 0, 0, 512, 512
   2204 subset: -100,  100,    0,  200  success; false
   2205 subset: -100,  100,  100,  200  success; true  subset: 0, 0, 100, 100
   2206 subset: -100,  100, 1000,  200  success; true  subset: 0, 0, 512, 100
   2207 subset:    0,  100,    0,  200  success; false
   2208 subset:    0,  100,  100,  200  success; true  subset: 0, 0, 100, 100
   2209 subset:    0,  100, 1000,  200  success; true  subset: 0, 0, 512, 100
   2210 subset:  100,  100,    0,  200  success; false
   2211 subset:  100,  100,  100,  200  success; false
   2212 subset:  100,  100, 1000,  200  success; true  subset: 0, 0, 412, 100
   2213 subset: 1000,  100,    0,  200  success; false
   2214 subset: 1000,  100,  100,  200  success; false
   2215 subset: 1000,  100, 1000,  200  success; false
   2216 ##
   2217 ##
   2218 
   2219 #SeeAlso readPixels writePixels SkCanvas::drawBitmap
   2220 
   2221 ##
   2222 
   2223 # ------------------------------------------------------------------------------
   2224 
   2225 #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
   2226                     int srcX, int srcY) const
   2227 #In Pixels
   2228 #Line # copies and converts pixels ##
   2229 
   2230 Copies a Rect of pixels from Bitmap to dstPixels. Copy starts at (srcX, srcY),
   2231 and does not exceed Bitmap (width(), height()).
   2232 
   2233 dstInfo specifies width, height, Color_Type, Alpha_Type, and Color_Space of
   2234 destination. dstRowBytes specifics the gap from one destination row to the next.
   2235 Returns true if pixels are copied. Returns false if:
   2236 #List
   2237 # dstInfo has no address ##
   2238 # dstRowBytes is less than dstInfo.minRowBytes() ##
   2239 # Pixel_Ref is nullptr ##
   2240 ##
   2241 
   2242 Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
   2243 kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
   2244 If Bitmap colorType is kGray_8_SkColorType, dstInfo.colorSpace() must match.
   2245 If Bitmap alphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must
   2246 match. If Bitmap colorSpace is nullptr, dstInfo.colorSpace() must match. Returns
   2247 false if pixel conversion is not possible.
   2248 
   2249 srcX and srcY may be negative to copy only top or left of source. Returns
   2250 false if width() or height() is zero or negative.
   2251 Returns false if #Formula # abs(srcX) >= Bitmap width() ##, or if #Formula # abs(srcY) >= Bitmap height() ##.
   2252 
   2253 #Param dstInfo  destination width, height, Color_Type, Alpha_Type, Color_Space ##
   2254 #Param dstPixels  destination pixel storage ##
   2255 #Param dstRowBytes  destination row length ##
   2256 #Param srcX  column index whose absolute value is less than width() ##
   2257 #Param srcY  row index whose absolute value is less than height() ##
   2258 
   2259 #Return  true if pixels are copied to dstPixels ##
   2260 
   2261 #Example
   2262 #Height 128
   2263 #Description
   2264 Transferring the gradient from 8 bits per component to 4 bits per component
   2265 creates visible banding.
   2266 ##
   2267     const int width = 256;
   2268     const int height = 64;
   2269     SkImageInfo srcInfo = SkImageInfo::MakeN32Premul(width, height);
   2270     SkColor  gradColors[] = { 0xFFAA3300, 0x7F881122 };
   2271     SkPoint  gradPoints[] = { { 0, 0 }, { 256, 0 } };
   2272     SkPaint paint;
   2273     paint.setShader(SkGradientShader::MakeLinear(gradPoints, gradColors, nullptr,
   2274                     SK_ARRAY_COUNT(gradColors), SkShader::kClamp_TileMode));
   2275     SkBitmap bitmap;
   2276     bitmap.allocPixels(srcInfo);
   2277     SkCanvas srcCanvas(bitmap);
   2278     srcCanvas.drawRect(SkRect::MakeWH(width, height), paint);
   2279     canvas->drawBitmap(bitmap, 0, 0);
   2280     SkImageInfo dstInfo = srcInfo.makeColorType(kARGB_4444_SkColorType);
   2281     std::vector<int16_t> dstPixels;
   2282     dstPixels.resize(height * width);
   2283     bitmap.readPixels(dstInfo, &dstPixels.front(), width * 2, 0, 0);
   2284     SkPixmap dstPixmap(dstInfo, &dstPixels.front(), width * 2);
   2285     bitmap.installPixels(dstPixmap);
   2286     canvas->drawBitmap(bitmap, 0, 64);
   2287 ##
   2288 
   2289 #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
   2290 
   2291 ##
   2292 
   2293 # ------------------------------------------------------------------------------
   2294 
   2295 #Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) const
   2296 
   2297 Copies a Rect of pixels from Bitmap to dst. Copy starts at (srcX, srcY), and
   2298 does not exceed Bitmap (width(), height()).
   2299 
   2300 dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
   2301 and row bytes of destination. dst.rowBytes() specifics the gap from one destination
   2302 row to the next. Returns true if pixels are copied. Returns false if:
   2303 #List
   2304 # dst pixel storage equals nullptr ##
   2305 # dst.rowBytes() is less than SkImageInfo::minRowBytes() ##
   2306 # Pixel_Ref is nullptr ##
   2307 ##
   2308 
   2309 Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
   2310 kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match.
   2311 If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match.
   2312 If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must
   2313 match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns
   2314 false if pixel conversion is not possible.
   2315 
   2316 srcX and srcY may be negative to copy only top or left of source. Returns
   2317 false if width() or height() is zero or negative.
   2318 Returns false if #Formula # abs(srcX) >= Bitmap width() ##, or if #Formula # abs(srcY) >= Bitmap height() ##.
   2319 
   2320 #Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
   2321 #Param srcX  column index whose absolute value is less than width() ##
   2322 #Param srcY  row index whose absolute value is less than height() ##
   2323 
   2324 #Return  true if pixels are copied to dst ##
   2325 
   2326 #Example
   2327 #Image 3
   2328     std::vector<int32_t> srcPixels;
   2329     srcPixels.resize(source.height() * source.rowBytes());
   2330     for (int y = 0; y < 4; ++y) {
   2331         for (int x = 0; x < 4; ++x) {
   2332             SkPixmap pixmap(SkImageInfo::MakeN32Premul(source.width() / 4, source.height() / 4),
   2333                     &srcPixels.front() + x * source.height() * source.width() / 4 +
   2334                     y * source.width() / 4, source.rowBytes());
   2335             source.readPixels(pixmap, x * source.width() / 4, y * source.height() / 4);
   2336         }
   2337     }
   2338     canvas->scale(.5f, .5f);
   2339     SkBitmap bitmap;
   2340     bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width(), source.height()),
   2341                              &srcPixels.front(), source.rowBytes());
   2342     canvas->drawBitmap(bitmap, 0, 0);
   2343 ##
   2344 
   2345 #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
   2346 
   2347 ##
   2348 
   2349 # ------------------------------------------------------------------------------
   2350 
   2351 #Method bool readPixels(const SkPixmap& dst) const
   2352 
   2353 Copies a Rect of pixels from Bitmap to dst. Copy starts at (0, 0), and
   2354 does not exceed Bitmap (width(), height()).
   2355 
   2356 dst specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
   2357 and row bytes of destination. dst.rowBytes() specifics the gap from one destination
   2358 row to the next. Returns true if pixels are copied. Returns false if:
   2359 #List
   2360 # dst pixel storage equals nullptr ##
   2361 # dst.rowBytes() is less than SkImageInfo::minRowBytes() ##
   2362 # Pixel_Ref is nullptr ##
   2363 ##
   2364 
   2365 Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
   2366 kGray_8_SkColorType, or kAlpha_8_SkColorType; dst Color_Type must match.
   2367 If Bitmap colorType is kGray_8_SkColorType, dst Color_Space must match.
   2368 If Bitmap alphaType is kOpaque_SkAlphaType, dst Alpha_Type must
   2369 match. If Bitmap colorSpace is nullptr, dst Color_Space must match. Returns
   2370 false if pixel conversion is not possible.
   2371 
   2372 #Param dst  destination Pixmap: Image_Info, pixels, row bytes ##
   2373 
   2374 #Return  true if pixels are copied to dst ##
   2375 
   2376 #Example
   2377 #Height 128
   2378 #Image 3
   2379     std::vector<int32_t> srcPixels;
   2380     srcPixels.resize(source.height() * source.width() * 8);
   2381     for (int i = 0;  i < 2; ++i) {
   2382     SkPixmap pixmap(SkImageInfo::Make(source.width() * 2, source.height(),
   2383                     i ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType, kPremul_SkAlphaType),
   2384                     &srcPixels.front() + i * source.width(), source.rowBytes() * 2);
   2385         source.readPixels(pixmap);
   2386     }
   2387     canvas->scale(.25f, .25f);
   2388     SkBitmap bitmap;
   2389     bitmap.installPixels(SkImageInfo::MakeN32Premul(source.width() * 2, source.height()),
   2390                          &srcPixels.front(), source.rowBytes() * 2);
   2391     canvas->drawBitmap(bitmap, 0, 0);
   2392 ##
   2393 
   2394 #SeeAlso writePixels SkPixmap::readPixels SkCanvas::readPixels SkImage::readPixels SkSurface::readPixels
   2395 
   2396 ##
   2397 
   2398 # ------------------------------------------------------------------------------
   2399 
   2400 #Method bool writePixels(const SkPixmap& src, int dstX, int dstY)
   2401 #In Pixels
   2402 #Line # copies and converts pixels ##
   2403 Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed
   2404 (src.width(), src.height()).
   2405 
   2406 src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
   2407 and row bytes of source. src.rowBytes() specifics the gap from one source
   2408 row to the next. Returns true if pixels are copied. Returns false if:
   2409 #List
   2410 # src pixel storage equals nullptr ##
   2411 # src.rowBytes() is less than SkImageInfo::minRowBytes() ##
   2412 # Pixel_Ref is nullptr ##
   2413 ##
   2414 
   2415 Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
   2416 kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
   2417 If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
   2418 If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
   2419 match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
   2420 false if pixel conversion is not possible.
   2421 
   2422 dstX and dstY may be negative to copy only top or left of source. Returns
   2423 false if width() or height() is zero or negative.
   2424 Returns false if #Formula # abs(dstX) >= Bitmap width() ##, or if #Formula # abs(dstY) >= Bitmap height() ##.
   2425 
   2426 #Param src  source Pixmap: Image_Info, pixels, row bytes ##
   2427 #Param dstX  column index whose absolute value is less than width() ##
   2428 #Param dstY  row index whose absolute value is less than height() ##
   2429 
   2430 #Return  true if src pixels are copied to Bitmap ##
   2431 
   2432 #Example
   2433 #Image 3
   2434     std::vector<int32_t> srcPixels;
   2435     int width = image->width();
   2436     int height = image->height();
   2437     srcPixels.resize(height * width  * 4);
   2438     SkPixmap pixmap(SkImageInfo::MakeN32Premul(width, height), (const void*) &srcPixels.front(),
   2439                     width * 4);
   2440     image->readPixels(pixmap, 0, 0);
   2441     canvas->scale(.5f, .5f);
   2442     width /= 4;
   2443     height /= 4;
   2444     for (int y = 0; y < 4; ++y) {
   2445         for (int x = 0; x < 4; ++x) {
   2446             SkBitmap bitmap;
   2447             bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
   2448             bitmap.writePixels(pixmap, -y * width, -x * height);
   2449             canvas->drawBitmap(bitmap, x * width, y * height);
   2450         }
   2451     }
   2452 ##
   2453 
   2454 #SeeAlso readPixels
   2455 
   2456 ##
   2457 
   2458 # ------------------------------------------------------------------------------
   2459 
   2460 #Method bool writePixels(const SkPixmap& src)
   2461 
   2462 Copies a Rect of pixels from src. Copy starts at (0, 0), and does not exceed
   2463 (src.width(), src.height()).
   2464 
   2465 src specifies width, height, Color_Type, Alpha_Type, Color_Space, pixel storage,
   2466 and row bytes of source. src.rowBytes() specifics the gap from one source
   2467 row to the next. Returns true if pixels are copied. Returns false if:
   2468 #List
   2469 # src pixel storage equals nullptr ##
   2470 # src.rowBytes() is less than SkImageInfo::minRowBytes() ##
   2471 # Pixel_Ref is nullptr ##
   2472 ##
   2473 
   2474 Pixels are copied only if pixel conversion is possible. If Bitmap colorType is
   2475 kGray_8_SkColorType, or kAlpha_8_SkColorType; src Color_Type must match.
   2476 If Bitmap colorType is kGray_8_SkColorType, src Color_Space must match.
   2477 If Bitmap alphaType is kOpaque_SkAlphaType, src Alpha_Type must
   2478 match. If Bitmap colorSpace is nullptr, src Color_Space must match. Returns
   2479 false if pixel conversion is not possible.
   2480 
   2481 #Param src  source Pixmap: Image_Info, pixels, row bytes ##
   2482 
   2483 #Return  true if src pixels are copied to Bitmap ##
   2484 
   2485 #Example
   2486 #Height 80
   2487     SkBitmap bitmap;
   2488     bitmap.allocPixels(SkImageInfo::MakeN32Premul(2, 2));
   2489     bitmap.eraseColor(SK_ColorGREEN);
   2490     SkPMColor color = 0xFF5599BB;
   2491     SkPixmap src(SkImageInfo::MakeN32Premul(1, 1), &color, 4);
   2492     bitmap.writePixels(src);
   2493     canvas->scale(40, 40);
   2494     canvas->drawBitmap(bitmap, 0, 0);
   2495 ##
   2496 
   2497 #SeeAlso readPixels
   2498 
   2499 ##
   2500 
   2501 # ------------------------------------------------------------------------------
   2502 
   2503 #Method bool extractAlpha(SkBitmap* dst) const
   2504 #In Constructors
   2505 #Line # creates Bitmap containing Alpha of pixels ##
   2506 #Populate
   2507 
   2508 #Example
   2509 #Height 100
   2510     SkBitmap alpha, bitmap;
   2511     bitmap.allocN32Pixels(100, 100);
   2512     SkCanvas offscreen(bitmap);
   2513     offscreen.clear(0);
   2514     SkPaint paint;
   2515     paint.setAntiAlias(true);
   2516     paint.setColor(SK_ColorBLUE);
   2517     paint.setStyle(SkPaint::kStroke_Style);
   2518     paint.setStrokeWidth(20);
   2519     offscreen.drawCircle(50, 50, 39, paint);
   2520     offscreen.flush();
   2521     bitmap.extractAlpha(&alpha);
   2522     paint.setColor(SK_ColorRED);
   2523     canvas->drawBitmap(bitmap, 0, 0, &paint);
   2524     canvas->drawBitmap(alpha, 100, 0, &paint);
   2525 ##
   2526 
   2527 #SeeAlso extractSubset
   2528 
   2529 ##
   2530 
   2531 # ------------------------------------------------------------------------------
   2532 
   2533 #Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
   2534                       SkIPoint* offset) const
   2535 #Populate
   2536 
   2537 #Example
   2538 #Height 160
   2539     auto radiusToSigma = [](SkScalar radius) -> SkScalar {
   2540          static const SkScalar kBLUR_SIGMA_SCALE = 0.57735f;
   2541          return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
   2542     };
   2543     SkBitmap alpha, bitmap;
   2544     bitmap.allocN32Pixels(100, 100);
   2545     SkCanvas offscreen(bitmap);
   2546     offscreen.clear(0);
   2547     SkPaint paint;
   2548     paint.setAntiAlias(true);
   2549     paint.setColor(SK_ColorBLUE);
   2550     paint.setStyle(SkPaint::kStroke_Style);
   2551     paint.setStrokeWidth(20);
   2552     offscreen.drawCircle(50, 50, 39, paint);
   2553     offscreen.flush();
   2554     paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, radiusToSigma(25)));
   2555     SkIPoint offset;
   2556     bitmap.extractAlpha(&alpha, &paint, &offset);
   2557     paint.setColor(SK_ColorRED);
   2558     canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
   2559     canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
   2560 ##
   2561 
   2562 #SeeAlso extractSubset
   2563 
   2564 ##
   2565 
   2566 # ------------------------------------------------------------------------------
   2567 
   2568 #Method bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
   2569                       SkIPoint* offset) const
   2570 #Populate
   2571 
   2572 #Example
   2573 #Height 128
   2574     SkBitmap alpha, bitmap;
   2575     bitmap.allocN32Pixels(100, 100);
   2576     SkCanvas offscreen(bitmap);
   2577     offscreen.clear(0);
   2578     SkPaint paint;
   2579     paint.setAntiAlias(true);
   2580     paint.setColor(SK_ColorBLUE);
   2581     paint.setStyle(SkPaint::kStroke_Style);
   2582     paint.setStrokeWidth(20);
   2583     offscreen.drawCircle(50, 50, 39, paint);
   2584     offscreen.flush();
   2585     paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
   2586     SkIPoint offset;
   2587     bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
   2588     paint.setColor(SK_ColorRED);
   2589     canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
   2590     canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
   2591 ##
   2592 
   2593 #SeeAlso extractSubset
   2594 
   2595 ##
   2596 
   2597 # ------------------------------------------------------------------------------
   2598 
   2599 #Method bool peekPixels(SkPixmap* pixmap) const
   2600 #In Pixels
   2601 #Line # returns Pixmap if possible ##
   2602 #Populate
   2603 
   2604 #Example
   2605     SkBitmap bitmap;
   2606     bitmap.allocPixels(SkImageInfo::MakeN32Premul(6, 11));
   2607     SkCanvas offscreen(bitmap);
   2608     offscreen.clear(SK_ColorWHITE);
   2609     SkPaint paint;
   2610     offscreen.drawString("?", 0, 10, paint);
   2611     SkPixmap pixmap;
   2612     if (bitmap.peekPixels(&pixmap)) {
   2613         const SkPMColor* pixels = pixmap.addr32();
   2614         SkPMColor pmWhite = pixels[0];
   2615         for (int y = 0; y < bitmap.height(); ++y) {
   2616             for (int x = 0; x < bitmap.width(); ++x) {
   2617                 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
   2618             }
   2619             SkDebugf("\n");
   2620         }
   2621     }
   2622     #StdOut
   2623 ------
   2624 -xxx--
   2625 x---x-
   2626 ----x-
   2627 ---x--
   2628 --x---
   2629 --x---
   2630 ------
   2631 --x---
   2632 --x---
   2633 ------
   2634     #StdOut ##
   2635 ##
   2636 
   2637 #SeeAlso pixmap installPixels readPixels writePixels
   2638 
   2639 ##
   2640 
   2641 # ------------------------------------------------------------------------------
   2642 #Subtopic Utility
   2643 #Line # rarely called management functions ##
   2644 ##
   2645 
   2646 #Method void validate() const;
   2647 #In Utility
   2648 #Line # asserts if Bitmap is invalid (debug only) ##
   2649 #Populate
   2650 
   2651 #NoExample
   2652 ##
   2653 
   2654 #SeeAlso SkImageInfo::validate
   2655 
   2656 ##
   2657 
   2658 # ------------------------------------------------------------------------------
   2659 
   2660 #Class SkBitmap ##
   2661 
   2662 #Topic Bitmap ##
   2663