11dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita/* 21dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita * Copyright 2015 Google Inc. 31dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita * 41dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita * Use of this source code is governed by a BSD-style license that can be 51dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita * found in the LICENSE file. 61dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita */ 71dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 81dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "gm.h" 933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h" 101dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkBitmap.h" 111dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkCanvas.h" 121dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkGradientShader.h" 131dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkImageGenerator.h" 141dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkPaint.h" 151dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkPathOps.h" 161dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkPicture.h" 171dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita#include "SkPictureRecorder.h" 181dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 191dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalitastatic void draw_vector_logo(SkCanvas* canvas, const SkRect& viewBox) { 20dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein constexpr char kSkiaStr[] = "SKIA"; 21dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein constexpr SkScalar kGradientPad = .1f; 22dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein constexpr SkScalar kVerticalSpacing = 0.25f; 23dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein constexpr SkScalar kAccentScale = 1.20f; 241dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 251dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkPaint paint; 261dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint.setAntiAlias(true); 271dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint.setSubpixelText(true); 281dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint.setFakeBoldText(true); 291dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita sk_tool_utils::set_portable_typeface(&paint); 301dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 311dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkPath path; 321dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkRect iBox, skiBox, skiaBox; 331dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint.getTextPath("SKI", 3, 0, 0, &path); 341dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita TightBounds(path, &skiBox); 351dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint.getTextPath("I", 1, 0, 0, &path); 361dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita TightBounds(path, &iBox); 371dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita iBox.offsetTo(skiBox.fRight - iBox.width(), iBox.fTop); 381dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 391dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const size_t textLen = strlen(kSkiaStr); 401dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint.getTextPath(kSkiaStr, textLen, 0, 0, &path); 411dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita TightBounds(path, &skiaBox); 421dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita skiaBox.outset(0, 2 * iBox.width() * (kVerticalSpacing + 1)); 431dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 441dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar accentSize = iBox.width() * kAccentScale; 451dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar underlineY = iBox.bottom() + 461dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita (kVerticalSpacing + SkScalarSqrt(3) / 2) * accentSize; 471dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkMatrix m; 481dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita m.setRectToRect(skiaBox, viewBox, SkMatrix::kFill_ScaleToFit); 491dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkAutoCanvasRestore acr(canvas, true); 501dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->concat(m); 511dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 521dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->drawCircle(iBox.centerX(), 531dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita iBox.y() - (0.5f + kVerticalSpacing) * accentSize, 541dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita accentSize / 2, 551dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita paint); 561dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 571dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita path.reset(); 581dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita path.moveTo(iBox.centerX() - accentSize / 2, iBox.bottom() + kVerticalSpacing * accentSize); 591dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita path.rLineTo(accentSize, 0); 601dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita path.lineTo(iBox.centerX(), underlineY); 611dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->drawPath(path, paint); 621dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 631dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkRect underlineRect = SkRect::MakeLTRB(iBox.centerX() - iBox.width() * accentSize * 3, 641dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita underlineY, 651dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita iBox.centerX(), 661dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita underlineY + accentSize / 10); 671dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkPoint pts1[] = { SkPoint::Make(underlineRect.x(), 0), 681dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkPoint::Make(iBox.centerX(), 0) }; 691dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar pos1[] = { 0, 0.75f }; 701dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkColor colors1[] = { SK_ColorTRANSPARENT, SK_ColorBLACK }; 711dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkASSERT(SK_ARRAY_COUNT(pos1) == SK_ARRAY_COUNT(colors1)); 721a9b9640843a64af8d9d90337ec3b3fea663196areed paint.setShader(SkGradientShader::MakeLinear(pts1, colors1, pos1, SK_ARRAY_COUNT(pos1), 731a9b9640843a64af8d9d90337ec3b3fea663196areed SkShader::kClamp_TileMode)); 741dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->drawRect(underlineRect, paint); 751dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 761dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkPoint pts2[] = { SkPoint::Make(iBox.x() - iBox.width() * kGradientPad, 0), 771dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkPoint::Make(iBox.right() + iBox.width() * kGradientPad, 0) }; 781dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar pos2[] = { 0, .01f, 1.0f/3, 1.0f/3, 2.0f/3, 2.0f/3, .99f, 1 }; 791dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkColor colors2[] = { 801dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SK_ColorBLACK, 811dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 0xffca5139, 821dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 0xffca5139, 831dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 0xff8dbd53, 841dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 0xff8dbd53, 851dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 0xff5460a5, 861dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 0xff5460a5, 871dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SK_ColorBLACK 881dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita }; 891dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkASSERT(SK_ARRAY_COUNT(pos2) == SK_ARRAY_COUNT(colors2)); 901a9b9640843a64af8d9d90337ec3b3fea663196areed paint.setShader(SkGradientShader::MakeLinear(pts2, colors2, pos2, SK_ARRAY_COUNT(pos2), 911a9b9640843a64af8d9d90337ec3b3fea663196areed SkShader::kClamp_TileMode)); 921dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->drawText(kSkiaStr, textLen, 0, 0, paint); 931dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita} 941dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 951dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita// This GM exercises SkPictureImageGenerator features 961dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita// (in particular its matrix vs. bounds semantics). 971dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalitaclass PictureGeneratorGM : public skiagm::GM { 981dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalitaprotected: 991dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkString onShortName() override { 1001dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita return SkString("pictureimagegenerator"); 1011dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 1021dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1031dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkISize onISize() override { 1041dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita return SkISize::Make(1160, 860); 1051dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 1061dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1071dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita void onOnceBeforeDraw() override { 1081dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkRect rect = SkRect::MakeWH(kPictureWidth, kPictureHeight); 1091dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkPictureRecorder recorder; 1101dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkCanvas* canvas = recorder.beginRecording(rect); 1111dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita draw_vector_logo(canvas, rect); 112ca2622ba051829fed5f30facd74c5b41cd4b931creed fPicture = recorder.finishRecordingAsPicture(); 1131dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 1141dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1151dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita void onDraw(SkCanvas* canvas) override { 1161dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const struct { 1171dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkISize size; 1181dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkScalar scaleX, scaleY; 1191dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkScalar opacity; 1201dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } configs[] = { 1211dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 100), 1, 1, 1 }, 1221dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 1, 1, 1 }, 1231dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 1, 2, 1 }, 1241dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(400, 200), 2, 2, 1 }, 1251dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1261dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 100), 1, 1, 0.9f }, 1271dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 1, 1, 0.75f }, 1281dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 1, 2, 0.5f }, 1291dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(400, 200), 2, 2, 0.25f }, 1301dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1311dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 0.5f, 1, 1 }, 1321dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 1, 0.5f, 1 }, 1331dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 0.5f, 0.5f, 1 }, 1341dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 200), 2, 2, 1 }, 1351dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1361dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 100), -1, 1, 1 }, 1371dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 100), 1, -1, 1 }, 1381dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 100), -1, -1, 1 }, 1391dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita { SkISize::Make(200, 100), -1, -1, 0.5f }, 1401dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita }; 1411dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 14277a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett auto srgbColorSpace = SkColorSpace::MakeSRGB(); 1431dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const unsigned kDrawsPerRow = 4; 1441dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar kDrawSize = 250; 1451dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1461dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita for (size_t i = 0; i < SK_ARRAY_COUNT(configs); ++i) { 1471dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkPaint p; 1481dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita p.setAlpha(SkScalarRoundToInt(255 * configs[i].opacity)); 1491dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1501dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkMatrix m = SkMatrix::MakeScale(configs[i].scaleX, configs[i].scaleY); 1511dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita if (configs[i].scaleX < 0) { 1521dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita m.postTranslate(SkIntToScalar(configs[i].size.width()), 0); 1531dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 1541dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita if (configs[i].scaleY < 0) { 1551dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita m.postTranslate(0, SkIntToScalar(configs[i].size.height())); 1561dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 157185130c643f0f6b20dcf14c200074748be282a7eMike Reed std::unique_ptr<SkImageGenerator> gen = 158185130c643f0f6b20dcf14c200074748be282a7eMike Reed SkImageGenerator::MakeFromPicture(configs[i].size, fPicture, &m, 159138ea97c1acaed4b968540220724dd5bf671e8dbBrian Osman p.getAlpha() != 255 ? &p : nullptr, 160185130c643f0f6b20dcf14c200074748be282a7eMike Reed SkImage::BitDepth::kU8, srgbColorSpace); 161138ea97c1acaed4b968540220724dd5bf671e8dbBrian Osman 162693fdbd6b81a860657612e7604430dd55d6e721bMike Reed SkImageInfo bmInfo = gen->getInfo().makeColorSpace(canvas->imageInfo().refColorSpace()); 163138ea97c1acaed4b968540220724dd5bf671e8dbBrian Osman 1641dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkBitmap bm; 165138ea97c1acaed4b968540220724dd5bf671e8dbBrian Osman SkAssertResult(gen->tryGenerateBitmap(&bm, bmInfo, nullptr)); 1661dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1671dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar x = kDrawSize * (i % kDrawsPerRow); 1681dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar y = kDrawSize * (i / kDrawsPerRow); 1691dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1701dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita p.setColor(0xfff0f0f0); 1711dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita p.setAlpha(255); 1721dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->drawRect(SkRect::MakeXYWH(x, y, 1731dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkIntToScalar(bm.width()), 1741dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita SkIntToScalar(bm.height())), p); 1751dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita canvas->drawBitmap(bm, x, y); 1761dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 1771dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita } 1781dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1791dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalitaprivate: 180ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> fPicture; 1811dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1821dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar kPictureWidth = 200; 1831dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita const SkScalar kPictureHeight = 100; 1841dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 1851dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita typedef skiagm::GM INHERITED; 1861dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita}; 1871dedc3d2c00468d9b4d0f0a8e69cb56acd08698ffmalita 188385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new PictureGeneratorGM;) 189