1 /* 2 * Copyright 2011 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 #include "gm.h" 8 #include "sk_tool_utils.h" 9 #include "Resources.h" 10 #include "SkCanvas.h" 11 #include "SkStream.h" 12 #include "SkSurface.h" 13 #include "SkTypeface.h" 14 15 class DFTextGM : public skiagm::GM { 16 public: DFTextGM()17 DFTextGM() { 18 this->setBGColor(0xFFFFFFFF); 19 } 20 21 protected: onOnceBeforeDraw()22 void onOnceBeforeDraw() override { 23 fEmojiTypeface = sk_tool_utils::emoji_typeface(); 24 fEmojiText = sk_tool_utils::emoji_sample_text(); 25 } 26 onShortName()27 SkString onShortName() override { 28 SkString name("dftext"); 29 name.append(sk_tool_utils::platform_os_emoji()); 30 return name; 31 } 32 onISize()33 SkISize onISize() override { 34 return SkISize::Make(1024, 768); 35 } 36 onDraw(SkCanvas * inputCanvas)37 virtual void onDraw(SkCanvas* inputCanvas) override { 38 SkScalar textSizes[] = { 9.0f, 9.0f*2.0f, 9.0f*5.0f, 9.0f*2.0f*5.0f }; 39 SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f }; 40 41 // set up offscreen rendering with distance field text 42 #if SK_SUPPORT_GPU 43 GrContext* ctx = inputCanvas->getGrContext(); 44 SkISize size = onISize(); 45 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType, 46 inputCanvas->imageInfo().refColorSpace()); 47 SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, 48 SkSurfaceProps::kLegacyFontHost_InitType); 49 auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props)); 50 SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas; 51 // init our new canvas with the old canvas's matrix 52 canvas->setMatrix(inputCanvas->getTotalMatrix()); 53 #else 54 SkCanvas* canvas = inputCanvas; 55 #endif 56 // apply global scale to test glyph positioning 57 canvas->scale(1.05f, 1.05f); 58 canvas->clear(0xffffffff); 59 60 SkPaint paint; 61 paint.setAntiAlias(true); 62 paint.setSubpixelText(true); 63 64 sk_tool_utils::set_portable_typeface(&paint, "serif"); 65 66 const char* text = "Hamburgefons"; 67 const size_t textLen = strlen(text); 68 69 // check scaling up 70 SkScalar x = SkIntToScalar(0); 71 SkScalar y = SkIntToScalar(78); 72 for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) { 73 SkAutoCanvasRestore acr(canvas, true); 74 canvas->translate(x, y); 75 canvas->scale(scales[i], scales[i]); 76 paint.setTextSize(textSizes[i]); 77 canvas->drawText(text, textLen, 0, 0, paint); 78 y += paint.getFontMetrics(nullptr)*scales[i]; 79 } 80 81 // check rotation 82 for (size_t i = 0; i < 5; ++i) { 83 SkScalar rotX = SkIntToScalar(10); 84 SkScalar rotY = y; 85 86 SkAutoCanvasRestore acr(canvas, true); 87 canvas->translate(SkIntToScalar(10 + i * 200), -80); 88 canvas->rotate(SkIntToScalar(i * 5), rotX, rotY); 89 for (int ps = 6; ps <= 32; ps += 3) { 90 paint.setTextSize(SkIntToScalar(ps)); 91 canvas->drawText(text, textLen, rotX, rotY, paint); 92 rotY += paint.getFontMetrics(nullptr); 93 } 94 } 95 96 // check scaling down 97 paint.setLCDRenderText(true); 98 x = SkIntToScalar(680); 99 y = SkIntToScalar(20); 100 size_t arraySize = SK_ARRAY_COUNT(textSizes); 101 for (size_t i = 0; i < arraySize; ++i) { 102 SkAutoCanvasRestore acr(canvas, true); 103 canvas->translate(x, y); 104 SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]); 105 canvas->scale(scaleFactor, scaleFactor); 106 paint.setTextSize(textSizes[i]); 107 canvas->drawText(text, textLen, 0, 0, paint); 108 y += paint.getFontMetrics(nullptr)*scaleFactor; 109 } 110 111 // check pos text 112 { 113 SkAutoCanvasRestore acr(canvas, true); 114 115 canvas->scale(2.0f, 2.0f); 116 117 SkAutoTArray<SkPoint> pos(SkToInt(textLen)); 118 SkAutoTArray<SkScalar> widths(SkToInt(textLen)); 119 paint.setTextSize(textSizes[0]); 120 121 paint.getTextWidths(text, textLen, &widths[0]); 122 123 SkScalar x = SkIntToScalar(340); 124 SkScalar y = SkIntToScalar(75); 125 for (unsigned int i = 0; i < textLen; ++i) { 126 pos[i].set(x, y); 127 x += widths[i]; 128 } 129 130 canvas->drawPosText(text, textLen, &pos[0], paint); 131 } 132 133 134 // check gamma-corrected blending 135 const SkColor fg[] = { 136 0xFFFFFFFF, 137 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 138 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 139 0xFF000000, 140 }; 141 142 paint.setColor(0xFFF7F3F7); 143 SkRect r = SkRect::MakeLTRB(670, 215, 820, 397); 144 canvas->drawRect(r, paint); 145 146 x = SkIntToScalar(680); 147 y = SkIntToScalar(235); 148 paint.setTextSize(SkIntToScalar(19)); 149 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) { 150 paint.setColor(fg[i]); 151 152 canvas->drawText(text, textLen, x, y, paint); 153 y += paint.getFontMetrics(nullptr); 154 } 155 156 paint.setColor(0xFF181C18); 157 r = SkRect::MakeLTRB(820, 215, 970, 397); 158 canvas->drawRect(r, paint); 159 160 x = SkIntToScalar(830); 161 y = SkIntToScalar(235); 162 paint.setTextSize(SkIntToScalar(19)); 163 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) { 164 paint.setColor(fg[i]); 165 166 canvas->drawText(text, textLen, x, y, paint); 167 y += paint.getFontMetrics(nullptr); 168 } 169 170 // check skew 171 { 172 paint.setLCDRenderText(false); 173 SkAutoCanvasRestore acr(canvas, true); 174 canvas->skew(0.0f, 0.151515f); 175 paint.setTextSize(SkIntToScalar(32)); 176 canvas->drawText(text, textLen, 745, 70, paint); 177 } 178 { 179 paint.setLCDRenderText(true); 180 SkAutoCanvasRestore acr(canvas, true); 181 canvas->skew(0.5f, 0.0f); 182 paint.setTextSize(SkIntToScalar(32)); 183 canvas->drawText(text, textLen, 580, 125, paint); 184 } 185 186 // check color emoji 187 if (fEmojiTypeface) { 188 paint.setTypeface(fEmojiTypeface); 189 paint.setTextSize(SkIntToScalar(19)); 190 canvas->drawString(fEmojiText, 670, 90, paint); 191 } 192 #if SK_SUPPORT_GPU 193 // render offscreen buffer 194 if (surface) { 195 SkAutoCanvasRestore acr(inputCanvas, true); 196 // since we prepended this matrix already, we blit using identity 197 inputCanvas->resetMatrix(); 198 inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, nullptr); 199 } 200 #endif 201 } 202 203 private: 204 sk_sp<SkTypeface> fEmojiTypeface; 205 const char* fEmojiText; 206 207 typedef skiagm::GM INHERITED; 208 }; 209 210 DEF_GM(return new DFTextGM;) 211