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 "SkSurface.h" 9 #include "SkTypeface.h" 10 11 namespace skiagm { 12 13 class DFTextGM : public GM { 14 public: 15 DFTextGM() { 16 this->setBGColor(0xFFFFFFFF); 17 } 18 19 virtual ~DFTextGM() { 20 } 21 22 protected: 23 virtual uint32_t onGetFlags() const SK_OVERRIDE { 24 return kGPUOnly_Flag; 25 } 26 27 virtual SkString onShortName() { 28 return SkString("dftext"); 29 } 30 31 virtual SkISize onISize() { 32 return SkISize::Make(1024, 768); 33 } 34 35 static void rotate_about(SkCanvas* canvas, 36 SkScalar degrees, 37 SkScalar px, SkScalar py) { 38 canvas->translate(px, py); 39 canvas->rotate(degrees); 40 canvas->translate(-px, -py); 41 } 42 43 virtual void onDraw(SkCanvas* inputCanvas) { 44 SkScalar textSizes[] = { 11.0f, 11.0f*2.0f, 11.0f*5.0f, 11.0f*2.0f*5.0f }; 45 SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f }; 46 47 // set up offscreen rendering with distance field text 48 #if SK_SUPPORT_GPU 49 GrContext* ctx = inputCanvas->getGrContext(); 50 SkImageInfo info = SkImageInfo::MakeN32Premul(onISize()); 51 SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag, 52 SkSurfaceProps::kLegacyFontHost_InitType); 53 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, info, 0, &props)); 54 SkCanvas* canvas = surface.get() ? surface->getCanvas() : inputCanvas; 55 #else 56 SkCanvas* canvas = inputCanvas; 57 #endif 58 59 // apply global scale to test glyph positioning 60 canvas->scale(1.05f, 1.05f); 61 canvas->clear(0xffffffff); 62 63 SkPaint paint; 64 paint.setAntiAlias(true); 65 paint.setSubpixelText(true); 66 #if !SK_SUPPORT_GPU 67 paint.setDistanceFieldTextTEMP(true); 68 #endif 69 sk_tool_utils::set_portable_typeface(&paint, "Times New Roman", SkTypeface::kNormal); 70 71 const char* text = "Hamburgefons"; 72 const size_t textLen = strlen(text); 73 74 // check scaling up 75 SkScalar x = SkIntToScalar(0); 76 SkScalar y = SkIntToScalar(78); 77 for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) { 78 SkAutoCanvasRestore acr(canvas, true); 79 canvas->translate(x, y); 80 canvas->scale(scales[i], scales[i]); 81 paint.setTextSize(textSizes[i]); 82 canvas->drawText(text, textLen, 0, 0, paint); 83 y += paint.getFontMetrics(NULL)*scales[i]; 84 } 85 86 // check rotation 87 for (size_t i = 0; i < 5; ++i) { 88 SkScalar rotX = SkIntToScalar(10); 89 SkScalar rotY = y; 90 91 SkAutoCanvasRestore acr(canvas, true); 92 canvas->translate(SkIntToScalar(10 + i * 200), -80); 93 rotate_about(canvas, SkIntToScalar(i * 5), rotX, rotY); 94 for (int ps = 6; ps <= 32; ps += 3) { 95 paint.setTextSize(SkIntToScalar(ps)); 96 canvas->drawText(text, textLen, rotX, rotY, paint); 97 rotY += paint.getFontMetrics(NULL); 98 } 99 } 100 101 // check scaling down 102 paint.setLCDRenderText(true); 103 x = SkIntToScalar(680); 104 y = SkIntToScalar(20); 105 size_t arraySize = SK_ARRAY_COUNT(textSizes); 106 for (size_t i = 0; i < arraySize; ++i) { 107 SkAutoCanvasRestore acr(canvas, true); 108 canvas->translate(x, y); 109 SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]); 110 canvas->scale(scaleFactor, scaleFactor); 111 paint.setTextSize(textSizes[i]); 112 canvas->drawText(text, textLen, 0, 0, paint); 113 y += paint.getFontMetrics(NULL)*scaleFactor; 114 } 115 116 // check pos text 117 { 118 SkAutoCanvasRestore acr(canvas, true); 119 120 canvas->scale(2.0f, 2.0f); 121 122 SkAutoTArray<SkPoint> pos(textLen); 123 SkAutoTArray<SkScalar> widths(textLen); 124 paint.setTextSize(textSizes[0]); 125 126 paint.getTextWidths(text, textLen, &widths[0]); 127 128 SkScalar x = SkIntToScalar(340); 129 SkScalar y = SkIntToScalar(75); 130 for (unsigned int i = 0; i < textLen; ++i) { 131 pos[i].set(x, y); 132 x += widths[i]; 133 } 134 135 canvas->drawPosText(text, textLen, &pos[0], paint); 136 } 137 138 139 // check gamma-corrected blending 140 const SkColor fg[] = { 141 0xFFFFFFFF, 142 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 143 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 144 0xFF000000, 145 }; 146 147 paint.setColor(0xFFF1F1F1); 148 SkRect r = SkRect::MakeLTRB(670, 250, 820, 460); 149 canvas->drawRect(r, paint); 150 151 x = SkIntToScalar(680); 152 y = SkIntToScalar(270); 153 paint.setTextSize(SkIntToScalar(22)); 154 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) { 155 paint.setColor(fg[i]); 156 157 canvas->drawText(text, textLen, x, y, paint); 158 y += paint.getFontMetrics(NULL); 159 } 160 161 paint.setColor(0xFF1F1F1F); 162 r = SkRect::MakeLTRB(820, 250, 970, 460); 163 canvas->drawRect(r, paint); 164 165 x = SkIntToScalar(830); 166 y = SkIntToScalar(270); 167 paint.setTextSize(SkIntToScalar(22)); 168 for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) { 169 paint.setColor(fg[i]); 170 171 canvas->drawText(text, textLen, x, y, paint); 172 y += paint.getFontMetrics(NULL); 173 } 174 175 #if SK_SUPPORT_GPU 176 // render offscreen buffer 177 if (surface) { 178 SkImage* image = surface->newImageSnapshot(); 179 inputCanvas->drawImage(image, 0, 0, NULL); 180 image->unref(); 181 } 182 #endif 183 } 184 185 private: 186 typedef GM INHERITED; 187 }; 188 189 ////////////////////////////////////////////////////////////////////////////// 190 191 static GM* MyFactory(void*) { return new DFTextGM; } 192 static GMRegistry reg(MyFactory); 193 194 } 195