downsamplebitmap.cpp revision 36352bf5e38f45a70ee4f4fc132a38048d38206d
1/* 2 * Copyright 2013 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 "gm.h" 9 10#include "Resources.h" 11#include "SkGradientShader.h" 12#include "SkTypeface.h" 13#include "SkImageDecoder.h" 14#include "SkStream.h" 15#include "SkPaint.h" 16 17static void make_checker(SkBitmap* bm, int size, int numChecks) { 18 bm->allocN32Pixels(size, size); 19 for (int y = 0; y < size; ++y) { 20 for (int x = 0; x < size; ++x) { 21 SkPMColor* s = bm->getAddr32(x, y); 22 int cx = (x * numChecks) / size; 23 int cy = (y * numChecks) / size; 24 if ((cx+cy)%2) { 25 *s = 0xFFFFFFFF; 26 } else { 27 *s = 0xFF000000; 28 } 29 } 30 } 31} 32 33static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) { 34 sk_tool_utils::set_portable_typeface(paint, name, style); 35} 36 37class DownsampleBitmapGM : public skiagm::GM { 38public: 39 SkBitmap fBM; 40 SkString fName; 41 bool fBitmapMade; 42 SkFilterQuality fFilterQuality; 43 44 DownsampleBitmapGM(SkFilterQuality filterQuality) 45 : fFilterQuality(filterQuality) 46 { 47 this->setBGColor(0xFFDDDDDD); 48 fBitmapMade = false; 49 } 50 51 const char* filterQualityToString() { 52 static const char *filterQualityNames[] = { 53 "none", "low", "medium", "high" 54 }; 55 return filterQualityNames[fFilterQuality]; 56 } 57 58protected: 59 60 SkString onShortName() override { 61 return fName; 62 } 63 64 SkISize onISize() override { 65 make_bitmap_wrapper(); 66 return SkISize::Make(fBM.width(), 4 * fBM.height()); 67 } 68 69 void make_bitmap_wrapper() { 70 if (!fBitmapMade) { 71 fBitmapMade = true; 72 make_bitmap(); 73 } 74 } 75 76 virtual void make_bitmap() = 0; 77 78 void onDraw(SkCanvas* canvas) override { 79 make_bitmap_wrapper(); 80 81 int curY = 0; 82 int curHeight; 83 float curScale = 1; 84 do { 85 86 SkMatrix matrix; 87 matrix.setScale( curScale, curScale ); 88 89 SkPaint paint; 90 paint.setFilterQuality(fFilterQuality); 91 92 canvas->save(); 93 canvas->translate(0, (SkScalar)curY); 94 canvas->concat(matrix); 95 canvas->drawBitmap(fBM, 0, 0, &paint); 96 canvas->restore(); 97 98 curHeight = (int) (fBM.height() * curScale + 2); 99 curY += curHeight; 100 curScale *= 0.75f; 101 } while (curHeight >= 2 && curY < 4*fBM.height()); 102 } 103 104private: 105 typedef skiagm::GM INHERITED; 106}; 107 108class DownsampleBitmapTextGM: public DownsampleBitmapGM { 109 public: 110 DownsampleBitmapTextGM(float textSize, SkFilterQuality filterQuality) 111 : INHERITED(filterQuality), fTextSize(textSize) 112 { 113 fName.printf("downsamplebitmap_text_%s_%.2fpt", this->filterQualityToString(), fTextSize); 114 } 115 116 protected: 117 float fTextSize; 118 119 void make_bitmap() override { 120 fBM.allocN32Pixels(int(fTextSize * 8), int(fTextSize * 6)); 121 SkCanvas canvas(fBM); 122 canvas.drawColor(SK_ColorWHITE); 123 124 SkPaint paint; 125 paint.setAntiAlias(true); 126 paint.setSubpixelText(true); 127 paint.setTextSize(fTextSize); 128 129 setTypeface(&paint, "Times", SkTypeface::kNormal); 130 canvas.drawText("Hamburgefons", 12, fTextSize/2, 1.2f*fTextSize, paint); 131 setTypeface(&paint, "Times", SkTypeface::kBold); 132 canvas.drawText("Hamburgefons", 12, fTextSize/2, 2.4f*fTextSize, paint); 133 setTypeface(&paint, "Times", SkTypeface::kItalic); 134 canvas.drawText("Hamburgefons", 12, fTextSize/2, 3.6f*fTextSize, paint); 135 setTypeface(&paint, "Times", SkTypeface::kBoldItalic); 136 canvas.drawText("Hamburgefons", 12, fTextSize/2, 4.8f*fTextSize, paint); 137 } 138 private: 139 typedef DownsampleBitmapGM INHERITED; 140}; 141 142class DownsampleBitmapCheckerboardGM: public DownsampleBitmapGM { 143 public: 144 DownsampleBitmapCheckerboardGM(int size, int numChecks, SkFilterQuality filterQuality) 145 : INHERITED(filterQuality), fSize(size), fNumChecks(numChecks) 146 { 147 fName.printf("downsamplebitmap_checkerboard_%s_%d_%d", this->filterQualityToString(), fSize, fNumChecks); 148 } 149 150 protected: 151 int fSize; 152 int fNumChecks; 153 154 void make_bitmap() override { 155 make_checker(&fBM, fSize, fNumChecks); 156 } 157 private: 158 typedef DownsampleBitmapGM INHERITED; 159}; 160 161class DownsampleBitmapImageGM: public DownsampleBitmapGM { 162 public: 163 DownsampleBitmapImageGM(const char filename[], SkFilterQuality filterQuality) 164 : INHERITED(filterQuality), fFilename(filename) 165 { 166 fName.printf("downsamplebitmap_image_%s_%s", this->filterQualityToString(), filename); 167 } 168 169 protected: 170 SkString fFilename; 171 int fSize; 172 173 void make_bitmap() override { 174 SkImageDecoder* codec = NULL; 175 SkString resourcePath = GetResourcePath(fFilename.c_str()); 176 SkFILEStream stream(resourcePath.c_str()); 177 if (stream.isValid()) { 178 codec = SkImageDecoder::Factory(&stream); 179 } 180 if (codec) { 181 stream.rewind(); 182 codec->decode(&stream, &fBM, kN32_SkColorType, SkImageDecoder::kDecodePixels_Mode); 183 SkDELETE(codec); 184 } else { 185 fBM.allocN32Pixels(1, 1); 186 *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad 187 } 188 fSize = fBM.height(); 189 } 190 private: 191 typedef DownsampleBitmapGM INHERITED; 192}; 193 194#include "SkMipMap.h" 195 196static void release_mipmap(void*, void* context) { 197 ((SkMipMap*)context)->unref(); 198} 199 200class ShowMipLevels : public skiagm::GM { 201public: 202 SkBitmap fBM; 203 204 ShowMipLevels() { 205 this->setBGColor(0xFFDDDDDD); 206 make_checker(&fBM, 512, 256); 207 } 208 209protected: 210 211 SkString onShortName() override { 212 return SkString("showmiplevels"); 213 } 214 215 SkISize onISize() override { 216 return SkISize::Make(fBM.width() + 8, 2 * fBM.height() + 80); 217 } 218 219 void onDraw(SkCanvas* canvas) override { 220 SkScalar x = 4; 221 SkScalar y = 4; 222 canvas->drawBitmap(fBM, x, y, NULL); 223 y += fBM.height() + 4; 224 225 SkAutoTUnref<SkMipMap> mm(SkMipMap::Build(fBM, NULL)); 226 227 SkMipMap::Level level; 228 SkScalar scale = 0.5f; 229 while (mm->extractLevel(scale, &level)) { 230 SkImageInfo info = SkImageInfo::MakeN32Premul(level.fWidth, level.fHeight); 231 SkBitmap bm; 232 bm.installPixels(info, level.fPixels, level.fRowBytes, NULL, 233 &release_mipmap, (void*)(SkRef(mm.get()))); 234 bm.setImmutable(); 235 canvas->drawBitmap(bm, x, y, NULL); 236 y += bm.height() + 4; 237 scale /= 2; 238 if (info.width() == 1 || info.height() == 1) { 239 break; 240 } 241 } 242 } 243 244private: 245 typedef skiagm::GM INHERITED; 246}; 247DEF_GM( return new ShowMipLevels; ) 248 249////////////////////////////////////////////////////////////////////////////// 250 251DEF_GM( return new DownsampleBitmapTextGM(72, kHigh_SkFilterQuality); ) 252DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kHigh_SkFilterQuality); ) 253DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kHigh_SkFilterQuality); ) 254DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc", 255 kHigh_SkFilterQuality); ) 256 257DEF_GM( return new DownsampleBitmapTextGM(72, kMedium_SkFilterQuality); ) 258DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kMedium_SkFilterQuality); ) 259DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kMedium_SkFilterQuality); ) 260DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc", 261 kMedium_SkFilterQuality); ) 262 263DEF_GM( return new DownsampleBitmapTextGM(72, kLow_SkFilterQuality); ) 264DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kLow_SkFilterQuality); ) 265DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kLow_SkFilterQuality); ) 266DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc", 267 kLow_SkFilterQuality); ) 268 269DEF_GM( return new DownsampleBitmapTextGM(72, kNone_SkFilterQuality); ) 270DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kNone_SkFilterQuality); ) 271DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kNone_SkFilterQuality); ) 272DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc", 273 kNone_SkFilterQuality); ) 274