1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontTypes.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h" 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker #include <string.h> 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker namespace skiagm { 27*c8dee2aaSAndroid Build Coastguard Worker class TextBlobTransforms : public GM { 28*c8dee2aaSAndroid Build Coastguard Worker public: 29*c8dee2aaSAndroid Build Coastguard Worker // This gm tests that textblobs can be translated, rotated, and scaled TextBlobTransforms()30*c8dee2aaSAndroid Build Coastguard Worker TextBlobTransforms() {} 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker protected: onOnceBeforeDraw()33*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 34*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder builder; 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker // make textblob. To stress distance fields, we choose sizes appropriately 37*c8dee2aaSAndroid Build Coastguard Worker SkFont font(ToolUtils::DefaultPortableTypeface(), 162); 38*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kAlias); 39*c8dee2aaSAndroid Build Coastguard Worker const char* text = "A"; 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds; 42*c8dee2aaSAndroid Build Coastguard Worker font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds); 43*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder, text, font, 0, 0); 44*c8dee2aaSAndroid Build Coastguard Worker 45*c8dee2aaSAndroid Build Coastguard Worker // Medium 46*c8dee2aaSAndroid Build Coastguard Worker SkScalar xOffset = bounds.width() + 5; 47*c8dee2aaSAndroid Build Coastguard Worker font.setSize(72); 48*c8dee2aaSAndroid Build Coastguard Worker text = "B"; 49*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder, text, font, xOffset, 0); 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds); 52*c8dee2aaSAndroid Build Coastguard Worker SkScalar yOffset = bounds.height(); 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker // Small 55*c8dee2aaSAndroid Build Coastguard Worker font.setSize(32); 56*c8dee2aaSAndroid Build Coastguard Worker text = "C"; 57*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder, text, font, xOffset, -yOffset - 10); 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker // build 60*c8dee2aaSAndroid Build Coastguard Worker fBlob = builder.make(); 61*c8dee2aaSAndroid Build Coastguard Worker } 62*c8dee2aaSAndroid Build Coastguard Worker getName() const63*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("textblobtransforms"); } 64*c8dee2aaSAndroid Build Coastguard Worker getISize()65*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(kWidth, kHeight); } 66*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)67*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 68*c8dee2aaSAndroid Build Coastguard Worker 69*c8dee2aaSAndroid Build Coastguard Worker canvas->drawColor(SK_ColorGRAY); 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = fBlob->bounds(); 74*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(20, 20); 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker // Colors were chosen to map to pairs of canonical colors. The GPU Backend will cache A8 77*c8dee2aaSAndroid Build Coastguard Worker // Texture Blobs based on the canonical color they map to. Canonical colors are used to 78*c8dee2aaSAndroid Build Coastguard Worker // create masks. For A8 there are 8 of them. 79*c8dee2aaSAndroid Build Coastguard Worker //SkColor colors[] = {SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorYELLOW, SK_ColorWHITE}; 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker SkScalar xOffset = SkScalarCeilToScalar(bounds.width()); 82*c8dee2aaSAndroid Build Coastguard Worker SkScalar yOffset = SkScalarCeilToScalar(bounds.height()); 83*c8dee2aaSAndroid Build Coastguard Worker // first translate 84*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 2 * yOffset); 85*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 86*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(-xOffset, 0); 87*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 88*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(2 * xOffset, 0); 89*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 90*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(-xOffset, -yOffset); 91*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 92*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, 2 * yOffset); 93*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker // now rotate 96*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(4 * xOffset, -yOffset); 97*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(180.f); 98*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 99*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(-180.f); 100*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, -yOffset); 101*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(-180.f); 102*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 103*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(270.f); 104*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 105*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(-90.f); 106*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(-xOffset, yOffset); 107*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(-90.f); 108*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 109*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(90.f); 110*c8dee2aaSAndroid Build Coastguard Worker 111*c8dee2aaSAndroid Build Coastguard Worker // and scales 112*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(- 3 * xOffset, 3 * yOffset); 113*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(1.5f, 1.5f); 114*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 115*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 116*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(.25f, .25f); 117*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 118*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 119*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(3.f, 2.f); 120*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 121*c8dee2aaSAndroid Build Coastguard Worker 122*c8dee2aaSAndroid Build Coastguard Worker // finally rotates, scales, and translates together 123*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 124*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(23.f); 125*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(.33f, .5f); 126*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(-46.f); 129*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 130*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(1.2f, 1.1f); 131*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 132*c8dee2aaSAndroid Build Coastguard Worker 133*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(46.f); 134*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 135*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(1.1f, 1.2f); 136*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 137*c8dee2aaSAndroid Build Coastguard Worker 138*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(46.f); 139*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 140*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(.95f, 1.1f); 141*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 142*c8dee2aaSAndroid Build Coastguard Worker 143*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(46.f); 144*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 145*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(1.3f, .7f); 146*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 147*c8dee2aaSAndroid Build Coastguard Worker 148*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(46.f); 149*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 150*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(.8f, 1.1f); 151*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 152*c8dee2aaSAndroid Build Coastguard Worker 153*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(10.f); 154*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 155*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(1.f, 5.f); 156*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 157*c8dee2aaSAndroid Build Coastguard Worker 158*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(5.f); 159*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(xOffset, 0); 160*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(5.f, 1.f); 161*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(fBlob, 0, 0, paint); 162*c8dee2aaSAndroid Build Coastguard Worker } 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker private: 165*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> fBlob; 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kWidth = 1000; 168*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kHeight = 1200; 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM; 171*c8dee2aaSAndroid Build Coastguard Worker }; 172*c8dee2aaSAndroid Build Coastguard Worker 173*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////// 174*c8dee2aaSAndroid Build Coastguard Worker 175*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new TextBlobTransforms;) 176*c8dee2aaSAndroid Build Coastguard Worker } // namespace skiagm 177