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