downsamplebitmap.cpp revision 9c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6
19c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com/* 29c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com * Copyright 2013 Google Inc. 39c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com * 49c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com * Use of this source code is governed by a BSD-style license that can be 59c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com * found in the LICENSE file. 69c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com */ 79c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 89c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com#include "gm.h" 99c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com#include "SkGradientShader.h" 109c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 119c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com#include "SkTypeface.h" 129c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com#include "SkImageDecoder.h" 139c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com#include "SkStream.h" 149c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 159c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comstatic void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) { 169c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style))); 179c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com} 189c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 199c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comclass DownsampleBitmapGM : public skiagm::GM { 209c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 219c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.compublic: 229c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkBitmap fBM; 239c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkString fName; 249c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com bool fBitmapMade; 259c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 269c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com DownsampleBitmapGM() 279c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com { 289c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com this->setBGColor(0xFFDDDDDD); 299c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBitmapMade = false; 309c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 319c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 329c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com void setName(const char name[]) { 339c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fName.set(name); 349c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 359c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 369c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comprotected: 379c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual SkString onShortName() SK_OVERRIDE { 389c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com return fName; 399c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 409c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 419c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual SkISize onISize() SK_OVERRIDE { 429c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com make_bitmap_wrapper(); 439c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com return SkISize::Make(4 * fBM.width(), fBM.height()); 449c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 459c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 469c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com void make_bitmap_wrapper() { 479c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com if (!fBitmapMade) { 489c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBitmapMade = true; 499c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com make_bitmap(); 509c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 519c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 529c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 539c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual void make_bitmap() = 0; 549c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 559c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 569c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com make_bitmap_wrapper(); 579c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 589c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int curX = 0; 599c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int curWidth; 609c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com float curScale = 1; 619c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com do { 629c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 639c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkMatrix matrix; 649c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com matrix.setScale( curScale, curScale ); 659c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 669c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkPaint paint; 679c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com paint.setFilterBitmap(true); 689c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com paint.setFlags( paint.getFlags() | SkPaint::kHighQualityFilterBitmap_Flag ); 699c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 709c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas->save(); 719c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas->translate( (SkScalar) curX, 0.f ); 729c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas->drawBitmapMatrix( fBM, matrix, &paint ); 739c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas->restore(); 749c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 759c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com curWidth = (int) (fBM.width() * curScale + 2); 769c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com curX += curWidth; 779c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com curScale *= 0.75f; 789c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } while (curX < 4*fBM.width()); 799c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 809c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 819c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comprivate: 829c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com typedef skiagm::GM INHERITED; 839c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com}; 849c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 859c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comclass DownsampleBitmapTextGM: public DownsampleBitmapGM { 869c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com public: 879c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com DownsampleBitmapTextGM(float textSize) 889c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com : fTextSize(textSize) 899c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com { 909c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com char name[1024]; 919c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com sprintf(name, "downsamplebitmap_text_%.2fpt", fTextSize); 929c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setName(name); 939c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 949c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 959c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com protected: 969c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com float fTextSize; 979c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 989c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual void make_bitmap() SK_OVERRIDE { 999c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBM.setConfig(SkBitmap::kARGB_8888_Config, int(fTextSize * 8), int(fTextSize * 6)); 1009c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBM.allocPixels(); 1019c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkCanvas canvas(fBM); 1029c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas.drawColor(SK_ColorWHITE); 1039c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1049c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkPaint paint; 1059c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com paint.setAntiAlias(true); 1069c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com paint.setSubpixelText(true); 1079c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com paint.setTextSize(fTextSize); 1089c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1099c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setTypeface(&paint, "Times", SkTypeface::kNormal); 1109c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas.drawText("Hamburgefons", 12, fTextSize/2, 1.2f*fTextSize, paint); 1119c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setTypeface(&paint, "Times", SkTypeface::kBold); 1129c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas.drawText("Hamburgefons", 12, fTextSize/2, 2.4f*fTextSize, paint); 1139c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setTypeface(&paint, "Times", SkTypeface::kItalic); 1149c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas.drawText("Hamburgefons", 12, fTextSize/2, 3.6f*fTextSize, paint); 1159c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setTypeface(&paint, "Times", SkTypeface::kBoldItalic); 1169c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com canvas.drawText("Hamburgefons", 12, fTextSize/2, 4.8f*fTextSize, paint); 1179c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1189c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com private: 1199c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com typedef DownsampleBitmapGM INHERITED; 1209c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com}; 1219c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1229c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comclass DownsampleBitmapCheckerboardGM: public DownsampleBitmapGM { 1239c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com public: 1249c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com DownsampleBitmapCheckerboardGM(int size, int numChecks) 1259c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com : fSize(size), fNumChecks(numChecks) 1269c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com { 1279c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com char name[1024]; 1289c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com sprintf(name, "downsamplebitmap_checkerboard_%d_%d", fSize, fNumChecks); 1299c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setName(name); 1309c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1319c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1329c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com protected: 1339c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int fSize; 1349c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int fNumChecks; 1359c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1369c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual void make_bitmap() SK_OVERRIDE { 1379c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBM.setConfig(SkBitmap::kARGB_8888_Config, fSize, fSize); 1389c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBM.allocPixels(); 1399c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkAutoLockPixels lock(fBM); 1409c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com for (int y = 0; y < fSize; ++y) { 1419c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com for (int x = 0; x < fSize; ++x) { 1429c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkPMColor* s = fBM.getAddr32(x, y); 1439c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int cx = (x * fNumChecks) / fSize; 1449c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int cy = (y * fNumChecks) / fSize; 1459c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com if ((cx+cy)%2) { 1469c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com *s = 0xFFFFFFFF; 1479c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } else { 1489c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com *s = 0xFF000000; 1499c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1509c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1519c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1529c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1539c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com private: 1549c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com typedef DownsampleBitmapGM INHERITED; 1559c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com}; 1569c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1579c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comclass DownsampleBitmapImageGM: public DownsampleBitmapGM { 1589c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com public: 1599c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com DownsampleBitmapImageGM(const char filename[]) 1609c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com : fFilename(filename) 1619c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com { 1629c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com char name[1024]; 1639c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com sprintf(name, "downsamplebitmap_image_%s", filename); 1649c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com setName(name); 1659c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1669c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1679c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com protected: 1689c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkString fFilename; 1699c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com int fSize; 1709c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1719c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com virtual void make_bitmap() SK_OVERRIDE { 1729c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkString path(skiagm::GM::gResourcePath); 1739c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com path.append("/"); 1749c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com path.append(fFilename); 1759c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1769c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkImageDecoder *codec = NULL; 1779c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkFILEStream stream(path.c_str()); 1789c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com if (stream.isValid()) { 1799c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com codec = SkImageDecoder::Factory(&stream); 1809c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1819c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com if (codec) { 1829c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com stream.rewind(); 1839c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com codec->decode(&stream, &fBM, SkBitmap::kARGB_8888_Config, 1849c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkImageDecoder::kDecodePixels_Mode); 1859c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com SkDELETE(codec); 1869c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } else { 1879c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBM.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); 1889c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fBM.allocPixels(); 1899c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad 1909c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1919c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com fSize = fBM.height(); 1929c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com } 1939c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com private: 1949c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com typedef DownsampleBitmapGM INHERITED; 1959c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com}; 1969c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1979c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com////////////////////////////////////////////////////////////////////////////// 1989c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com 1999c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comDEF_GM( return new DownsampleBitmapTextGM(72); ) 2009c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comDEF_GM( return new DownsampleBitmapCheckerboardGM(512,256); ) 2019c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.comDEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png"); ) 202