Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "sk_tool_utils.h"
      9 #include "SkSurface.h"
     10 #include "Resources.h"
     11 #include "gm.h"
     12 
     13 #include "SkMath.h"
     14 #include "SkColorPriv.h"
     15 
     16 static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
     17     SkBitmap copy;
     18     src.copyTo(&copy, colorType);
     19     copy.setImmutable();
     20     return copy;
     21 }
     22 
     23 #define SCALE 128
     24 
     25 // Make either A8 or gray8 bitmap.
     26 static SkBitmap make_bitmap(SkColorType ct) {
     27     SkBitmap bm;
     28     switch (ct) {
     29         case kAlpha_8_SkColorType:
     30             bm.allocPixels(SkImageInfo::MakeA8(SCALE, SCALE));
     31             break;
     32         case kGray_8_SkColorType:
     33             bm.allocPixels(
     34                     SkImageInfo::Make(SCALE, SCALE, ct, kOpaque_SkAlphaType));
     35             break;
     36         default:
     37             SkASSERT(false);
     38             return bm;
     39     }
     40     SkAutoLockPixels autoLockPixels(bm);
     41     uint8_t spectrum[256];
     42     for (int y = 0; y < 256; ++y) {
     43         spectrum[y] = y;
     44     }
     45     for (int y = 0; y < 128; ++y) {
     46         // Shift over one byte each scanline.
     47         memcpy(bm.getAddr8(0, y), &spectrum[y], 128);
     48     }
     49     bm.setImmutable();
     50     return bm;
     51 }
     52 
     53 static void draw_center_letter(char c,
     54                                SkPaint* p,
     55                                SkColor color,
     56                                SkScalar x,
     57                                SkScalar y,
     58                                SkCanvas* canvas) {
     59     SkRect bounds;
     60     p->setColor(color);
     61     p->measureText(&c, 1, &bounds);
     62     canvas->drawText(&c, 1, x - bounds.centerX(), y - bounds.centerY(), *p);
     63 }
     64 
     65 static void color_wheel_native(SkCanvas* canvas) {
     66     SkAutoCanvasRestore autoCanvasRestore(canvas, true);
     67     canvas->translate(0.5f * SCALE, 0.5f * SCALE);
     68     SkPaint p;
     69     p.setAntiAlias(false);
     70     p.setColor(SK_ColorWHITE);
     71     canvas->drawCircle(0.0f, 0.0f, SCALE * 0.5f, p);
     72 
     73     const double sqrt_3_over_2 = 0.8660254037844387;
     74     const SkScalar Z = 0.0f;
     75     const SkScalar D = 0.3f * SkIntToScalar(SCALE);
     76     const SkScalar X = SkDoubleToScalar(D * sqrt_3_over_2);
     77     const SkScalar Y = D * SK_ScalarHalf;
     78     sk_tool_utils::set_portable_typeface(&p, nullptr, SkTypeface::kBold);
     79     p.setTextSize(0.28125f * SCALE);
     80     draw_center_letter('K', &p, SK_ColorBLACK, Z, Z, canvas);
     81     draw_center_letter('R', &p, SK_ColorRED, Z, D, canvas);
     82     draw_center_letter('G', &p, SK_ColorGREEN, -X, -Y, canvas);
     83     draw_center_letter('B', &p, SK_ColorBLUE, X, -Y, canvas);
     84     draw_center_letter('C', &p, SK_ColorCYAN, Z, -D, canvas);
     85     draw_center_letter('M', &p, SK_ColorMAGENTA, X, Y, canvas);
     86     draw_center_letter('Y', &p, SK_ColorYELLOW, -X, Y, canvas);
     87 }
     88 
     89 template <typename T>
     90 int find(T* array, int N, T item) {
     91     for (int i = 0; i < N; ++i) {
     92         if (array[i] == item) {
     93             return i;
     94         }
     95     }
     96     return -1;
     97 }
     98 
     99 static SkPMColor premultiply_color(SkColor c) {
    100     return SkPremultiplyARGBInline(SkColorGetA(c), SkColorGetR(c),
    101                                    SkColorGetG(c), SkColorGetB(c));
    102 }
    103 
    104 static SkBitmap indexed_bitmap() {
    105     SkBitmap n32bitmap;
    106     n32bitmap.allocN32Pixels(SCALE, SCALE);
    107     n32bitmap.eraseColor(SK_ColorTRANSPARENT);
    108 
    109     SkCanvas canvas(n32bitmap);
    110     color_wheel_native(&canvas);
    111     const SkColor colors[] = {
    112             SK_ColorTRANSPARENT,
    113             SK_ColorWHITE,
    114             SK_ColorBLACK,
    115             SK_ColorRED,
    116             SK_ColorGREEN,
    117             SK_ColorBLUE,
    118             SK_ColorCYAN,
    119             SK_ColorMAGENTA,
    120             SK_ColorYELLOW,
    121     };
    122     SkPMColor pmColors[SK_ARRAY_COUNT(colors)];
    123     for (size_t i = 0; i < SK_ARRAY_COUNT(colors); ++i) {
    124         pmColors[i] = premultiply_color(colors[i]);
    125     }
    126     SkBitmap bm;
    127     SkAutoTUnref<SkColorTable> ctable(new SkColorTable(pmColors, SK_ARRAY_COUNT(pmColors)));
    128     SkImageInfo info = SkImageInfo::Make(SCALE, SCALE, kIndex_8_SkColorType,
    129                                          kPremul_SkAlphaType);
    130     bm.allocPixels(info, nullptr, ctable);
    131     SkAutoLockPixels autoLockPixels1(n32bitmap);
    132     SkAutoLockPixels autoLockPixels2(bm);
    133     for (int y = 0; y < SCALE; ++y) {
    134         for (int x = 0; x < SCALE; ++x) {
    135             SkPMColor c = *n32bitmap.getAddr32(x, y);
    136             int idx = find(pmColors, SK_ARRAY_COUNT(pmColors), c);
    137             *bm.getAddr8(x, y) = SkClampMax(idx, SK_ARRAY_COUNT(pmColors) - 1);
    138         }
    139     }
    140     return bm;
    141 }
    142 
    143 static void draw(SkCanvas* canvas,
    144                  const SkPaint& p,
    145                  const SkBitmap& src,
    146                  SkColorType colorType,
    147                  const char text[]) {
    148     SkASSERT(src.colorType() == colorType);
    149     canvas->drawBitmap(src, 0.0f, 0.0f);
    150     canvas->drawText(text, strlen(text), 0.0f, 12.0f, p);
    151 }
    152 
    153 DEF_SIMPLE_GM(all_bitmap_configs, canvas, SCALE, 6 * SCALE) {
    154     SkAutoCanvasRestore autoCanvasRestore(canvas, true);
    155     SkPaint p;
    156     p.setColor(SK_ColorBLACK);
    157     p.setAntiAlias(true);
    158     sk_tool_utils::set_portable_typeface(&p, nullptr);
    159 
    160     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
    161 
    162     SkBitmap bitmap;
    163     if (GetResourceAsBitmap("color_wheel.png", &bitmap)) {
    164         bitmap.setImmutable();
    165         draw(canvas, p, bitmap, kN32_SkColorType, "Native 32");
    166 
    167         canvas->translate(0.0f, SkIntToScalar(SCALE));
    168         SkBitmap copy565 = copy_bitmap(bitmap, kRGB_565_SkColorType);
    169         p.setColor(SK_ColorRED);
    170         draw(canvas, p, copy565, kRGB_565_SkColorType, "RGB 565");
    171         p.setColor(SK_ColorBLACK);
    172 
    173         canvas->translate(0.0f, SkIntToScalar(SCALE));
    174         SkBitmap copy4444 = copy_bitmap(bitmap, kARGB_4444_SkColorType);
    175         draw(canvas, p, copy4444, kARGB_4444_SkColorType, "ARGB 4444");
    176     } else {
    177         canvas->translate(0.0f, SkIntToScalar(2 * SCALE));
    178     }
    179 
    180     canvas->translate(0.0f, SkIntToScalar(SCALE));
    181     SkBitmap bitmapIndexed = indexed_bitmap();
    182     draw(canvas, p, bitmapIndexed, kIndex_8_SkColorType, "Index 8");
    183 
    184     canvas->translate(0.0f, SkIntToScalar(SCALE));
    185     SkBitmap bitmapA8 = make_bitmap(kAlpha_8_SkColorType);
    186     draw(canvas, p, bitmapA8, kAlpha_8_SkColorType, "Alpha 8");
    187 
    188     p.setColor(SK_ColorRED);
    189     canvas->translate(0.0f, SkIntToScalar(SCALE));
    190     SkBitmap bitmapG8 = make_bitmap(kGray_8_SkColorType);
    191     draw(canvas, p, bitmapG8, kGray_8_SkColorType, "Gray 8");
    192 }
    193 
    194 // Works on Ganesh, fails on Raster.
    195 SkImage* make_not_native32_color_wheel() {
    196     SkBitmap n32bitmap, notN32bitmap;
    197     n32bitmap.allocN32Pixels(SCALE, SCALE);
    198     n32bitmap.eraseColor(SK_ColorTRANSPARENT);
    199     SkCanvas n32canvas(n32bitmap);
    200     color_wheel_native(&n32canvas);
    201     n32canvas.flush();
    202     #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
    203         const SkColorType ct = kRGBA_8888_SkColorType;
    204     #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
    205         const SkColorType ct = kBGRA_8888_SkColorType;
    206     #endif
    207     static_assert(ct != kN32_SkColorType, "BRGA!=RGBA");
    208     SkAssertResult(n32bitmap.copyTo(&notN32bitmap, ct));
    209     SkASSERT(notN32bitmap.colorType() == ct);
    210     return SkImage::NewFromBitmap(notN32bitmap);
    211 }
    212 
    213 DEF_SIMPLE_GM(not_native32_bitmap_config, canvas, SCALE, SCALE) {
    214     SkAutoTUnref<SkImage> notN32image(make_not_native32_color_wheel());
    215     SkASSERT(notN32image);
    216     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
    217     canvas->drawImage(notN32image, 0.0f, 0.0f);
    218 }
    219