1523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt/* 2523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * Copyright 2015 Google Inc. 3523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * 4523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * Use of this source code is governed by a BSD-style license that can be 5523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt * found in the LICENSE file. 6523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt */ 7523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 8523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "gm.h" 933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h" 10523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 11523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "Resources.h" 12523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkCanvas.h" 13523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkGradientShader.h" 14523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkStream.h" 15523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkTextBlob.h" 16523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt#include "SkTypeface.h" 17523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 18523ed6c0c1ac9029be315542258e02ba9854365cjoshualittnamespace skiagm { 19523ed6c0c1ac9029be315542258e02ba9854365cjoshualittclass TextBlobTransforms : public GM { 20523ed6c0c1ac9029be315542258e02ba9854365cjoshualittpublic: 21523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // This gm tests that textblobs can be translated, rotated, and scaled 22523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt TextBlobTransforms() {} 23523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 24523ed6c0c1ac9029be315542258e02ba9854365cjoshualittprotected: 25523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt void onOnceBeforeDraw() override { 26523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkTextBlobBuilder builder; 27523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 28523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // make textblob. To stress distance fields, we choose sizes appropriately 29523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkPaint paint; 30523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt paint.setTextSize(162); 31523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt const char* text = "A"; 321818acb6a4b11cd9a1d44ce5dde77452502a9796caryclark sk_tool_utils::set_portable_typeface(&paint); 33523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 34523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkRect bounds; 35523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt paint.measureText(text, strlen(text), &bounds); 36567ff2f6143ecb993dbedede402a43feb71c420atfarina sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0); 37523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 38523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // Medium 39523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkScalar xOffset = bounds.width() + 5; 40523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt paint.setTextSize(72); 41523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt text = "B"; 42523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset, 0); 43523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 44523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt paint.measureText(text, strlen(text), &bounds); 45523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkScalar yOffset = bounds.height(); 46523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 47523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // Small 48523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt paint.setTextSize(32); 49523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt text = "C"; 50523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt sk_tool_utils::add_to_text_blob(&builder, text, paint, xOffset, -yOffset - 10); 51523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 52523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // build 5337283c28aa5bea2204c18956e74f83b238d7a891fmalita fBlob = builder.make(); 54523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt } 55523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 56523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkString onShortName() override { 57523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt return SkString("textblobtransforms"); 58523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt } 59523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 60523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkISize onISize() override { 61523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt return SkISize::Make(kWidth, kHeight); 62523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt } 63523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 64523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt void onDraw(SkCanvas* canvas) override { 65523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 6685693c15c8948911afb0036a1a01bda64157a0abcaryclark canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY)); 67523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 68523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkPaint paint; 69523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 70523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkRect bounds = fBlob->bounds(); 71523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(20, 20); 72523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 73523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // Colors were chosen to map to pairs of canonical colors. The GPU Backend will cache A8 74523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // Texture Blobs based on the canonical color they map to. Canonical colors are used to 75523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // create masks. For A8 there are 8 of them. 7685693c15c8948911afb0036a1a01bda64157a0abcaryclark //SkColor colors[] = {SK_ColorCYAN, sk_tool_utils::color_to_565(SK_ColorLTGRAY), SK_ColorYELLOW, SK_ColorWHITE}; 77523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 78523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkScalar xOffset = SkScalarCeilToScalar(bounds.width()); 79523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt SkScalar yOffset = SkScalarCeilToScalar(bounds.height()); 80523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // first translate 81523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 2 * yOffset); 82523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 83523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(-xOffset, 0); 84523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 85523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(2 * xOffset, 0); 86523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 87523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(-xOffset, -yOffset); 88523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 89523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(0, 2 * yOffset); 90523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 91523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 92523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // now rotate 93523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(4 * xOffset, -yOffset); 94523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(180.f); 95523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 96523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(-180.f); 97523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(0, -yOffset); 98523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(-180.f); 99523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 100523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(270.f); 101523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 102523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(-90.f); 103523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(-xOffset, yOffset); 104523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(-90.f); 105523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 106523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(90.f); 107523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 108523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // and scales 109523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(- 3 * xOffset, 3 * yOffset); 110523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(1.5f, 1.5f); 111523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 112523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 113523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(.25f, .25f); 114523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 115523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 116523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(3.f, 2.f); 117523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 118523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 119523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt // finally rotates, scales, and translates together 120523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 121523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(23.f); 122523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(.33f, .5f); 123523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 124523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 125523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(-46.f); 126523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 127523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(1.2f, 1.1f); 128523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 129523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 130523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(46.f); 131523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 132523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(1.1f, 1.2f); 133523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 134523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 135523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(46.f); 136523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 137523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(.95f, 1.1f); 138523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 139523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 140523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(46.f); 141523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 142523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(1.3f, .7f); 143523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 144523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 145523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(46.f); 146523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 147523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(.8f, 1.1f); 148523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 149523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 150523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(10.f); 151523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 152523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(1.f, 5.f); 153523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 154523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 155523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->rotate(5.f); 156523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->translate(xOffset, 0); 157523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->scale(5.f, 1.f); 158523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt canvas->drawTextBlob(fBlob, 0, 0, paint); 159523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt } 160523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 161523ed6c0c1ac9029be315542258e02ba9854365cjoshualittprivate: 16237283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> fBlob; 163523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 164dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kWidth = 1000; 165dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein static constexpr int kHeight = 1200; 166523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 167523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt typedef GM INHERITED; 168523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt}; 169523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 170523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt////////////////////////////////////////////////////////////////////////////// 171523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt 172385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_GM(return new TextBlobTransforms;) 173523ed6c0c1ac9029be315542258e02ba9854365cjoshualitt} 174