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