1e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt/* 2e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt * Copyright 2015 Google Inc. 3e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt * 4e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt * Use of this source code is governed by a BSD-style license that can be 5e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt * found in the LICENSE file. 6e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt */ 7e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 8e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "gm.h" 933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h" 10e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 11e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "Resources.h" 12e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkBlurMask.h" 13e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkBlurMaskFilter.h" 14e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkCanvas.h" 15e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkGradientShader.h" 16e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkImage.h" 17e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkRandom.h" 18e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkStream.h" 19e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkSurface.h" 20e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkTextBlob.h" 21e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#include "SkTypeface.h" 22e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 23e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualittnamespace skiagm { 24e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualittclass TextBlobMixedSizes : public GM { 25e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualittpublic: 26e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // This gm tests that textblobs of mixed sizes with a large glyph will render properly 27e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt TextBlobMixedSizes(bool useDFT) : fUseDFT(useDFT) {} 28e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 29e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualittprotected: 30e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt void onOnceBeforeDraw() override { 31e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkTextBlobBuilder builder; 32e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 33e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // make textblob. To stress distance fields, we choose sizes appropriately 34e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkPaint paint; 35e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setAntiAlias(true); 36e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setSubpixelText(true); 37e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setLCDRenderText(true); 3853e5e7d4ce9d203fadc36b6349bcbb68862f0d22Hal Canary paint.setTypeface(MakeResourceAsTypeface("fonts/HangingS.ttf")); 39e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 4033e91f1673123d3f19b372ec0660edd611f706a0joshualitt const char* text = "Skia"; 41e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 42e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // extra large 43e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setTextSize(262); 44e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 45e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0); 46e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 47e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // large 48e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkRect bounds; 49e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.measureText(text, strlen(text), &bounds); 50e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkScalar yOffset = bounds.height(); 51e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setTextSize(162); 52e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 53e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset); 54e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 55e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // Medium 56e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.measureText(text, strlen(text), &bounds); 57e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt yOffset += bounds.height(); 58e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setTextSize(72); 59e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 60e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset); 61e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 62e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // Small 63e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.measureText(text, strlen(text), &bounds); 64e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt yOffset += bounds.height(); 65e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setTextSize(32); 66e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 67e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset); 68e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 69e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // micro (will fall out of distance field text even if distance field text is enabled) 70e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.measureText(text, strlen(text), &bounds); 71e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt yOffset += bounds.height(); 72e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setTextSize(14); 73e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 74e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset); 75e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 7668c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen // Zero size. 7768c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen paint.measureText(text, strlen(text), &bounds); 7868c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen yOffset += bounds.height(); 7968c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen paint.setTextSize(0); 8068c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen 8168c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset); 8268c63b3727f05638a95fcf5f65c5476a2fcb34d0kkinnunen 83e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // build 8437283c28aa5bea2204c18956e74f83b238d7a891fmalita fBlob = builder.make(); 85e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 86e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 87e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkString onShortName() override { 8858822d6994d33a823a29a4c6fa251ad1ce7267d6Hal Canary return SkStringPrintf("textblobmixedsizes%s%s", 8958822d6994d33a823a29a4c6fa251ad1ce7267d6Hal Canary sk_tool_utils::platform_font_manager(), 9058822d6994d33a823a29a4c6fa251ad1ce7267d6Hal Canary fUseDFT ? "_df" : ""); 91e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 92e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 93e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkISize onISize() override { 94e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt return SkISize::Make(kWidth, kHeight); 95e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 96e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 97e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt void onDraw(SkCanvas* inputCanvas) override { 98e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkCanvas* canvas = inputCanvas; 99e8f3062a36d3682f4019309a32b5b84dc9eddf8creed sk_sp<SkSurface> surface; 100e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt if (fUseDFT) { 101e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#if SK_SUPPORT_GPU 102e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // Create a new Canvas to enable DFT 103e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt GrContext* ctx = inputCanvas->getGrContext(); 10452ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman SkISize size = onISize(); 105693fdbd6b81a860657612e7604430dd55d6e721bMike Reed sk_sp<SkColorSpace> colorSpace = inputCanvas->imageInfo().refColorSpace(); 10652ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), 10752ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman kPremul_SkAlphaType, colorSpace); 1083a0dbde1cfa84b08c7dd5b597142e9f6179f2d07brianosman SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, 109e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkSurfaceProps::kLegacyFontHost_InitType); 110e8f3062a36d3682f4019309a32b5b84dc9eddf8creed surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props); 111e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas = surface.get() ? surface->getCanvas() : inputCanvas; 112e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // init our new canvas with the old canvas's matrix 113e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->setMatrix(inputCanvas->getTotalMatrix()); 114e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#endif 115e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 116e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorWHITE)); 117e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 118e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkRect bounds = fBlob->bounds(); 119e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 120dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const int kPadX = SkScalarFloorToInt(bounds.width() / 3); 121dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const int kPadY = SkScalarFloorToInt(bounds.height() / 3); 122e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 123e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt int rowCount = 0; 124e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY)); 125e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->save(); 126e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkRandom random; 127e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 128e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkPaint paint; 129e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt if (!fUseDFT) { 130e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setColor(sk_tool_utils::color_to_565(SK_ColorWHITE)); 131e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 132e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt paint.setAntiAlias(false); 133e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 134dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const SkScalar kSigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(8)); 135e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 136e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // setup blur paint 137e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkPaint blurPaint(paint); 138e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt blurPaint.setColor(sk_tool_utils::color_to_565(SK_ColorBLACK)); 139efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, kSigma)); 140dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein 141e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt for (int i = 0; i < 4; i++) { 142e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->save(); 143e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt switch (i % 2) { 144e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt case 0: 145e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->rotate(random.nextF() * 45.f); 146e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt break; 147e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt case 1: 148e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->rotate(-random.nextF() * 45.f); 149e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt break; 150e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 151e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt if (!fUseDFT) { 152e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->drawTextBlob(fBlob, 0, 0, blurPaint); 153e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 154e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 155e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->restore(); 156e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->translate(bounds.width() + SK_Scalar1 * kPadX, 0); 157e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt ++rowCount; 158e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt if ((bounds.width() + 2 * kPadX) * rowCount > kWidth) { 159e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->restore(); 160e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->translate(0, bounds.height() + SK_Scalar1 * kPadY); 161e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->save(); 162e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt rowCount = 0; 163e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 164e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 165e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt canvas->restore(); 166e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 167e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#if SK_SUPPORT_GPU 168e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // render offscreen buffer 169e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt if (surface) { 170e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt SkAutoCanvasRestore acr(inputCanvas, true); 171e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt // since we prepended this matrix already, we blit using identity 172e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt inputCanvas->resetMatrix(); 1739ce9d6772df650ceb0511f275e1a83dffa78ff72reed inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, nullptr); 174e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 175e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#endif 176e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt } 177e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 178e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualittprivate: 17937283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> fBlob; 180e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 181dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kWidth = 2100; 182dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kHeight = 1900; 183e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 184e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt bool fUseDFT; 185e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 186e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt typedef GM INHERITED; 187e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt}; 188e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 189e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt////////////////////////////////////////////////////////////////////////////// 190e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt 191385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM( return new TextBlobMixedSizes(false); ) 192e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#if SK_SUPPORT_GPU 193385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM( return new TextBlobMixedSizes(true); ) 194e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt#endif 195e46cf96ef5781ac40852bbf4f489bc47e2a2485ejoshualitt} 196