Home | History | Annotate | Download | only in gm
      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:
     17     DFTextGM() {
     18         this->setBGColor(0xFFFFFFFF);
     19     }
     20 
     21 protected:
     22     void onOnceBeforeDraw() override {
     23         fEmojiTypeface = sk_tool_utils::emoji_typeface();
     24         fEmojiText = sk_tool_utils::emoji_sample_text();
     25     }
     26 
     27     SkString onShortName() override {
     28         SkString name("dftext");
     29         name.append(sk_tool_utils::platform_font_manager());
     30         return name;
     31     }
     32 
     33     SkISize onISize() override {
     34         return SkISize::Make(1024, 768);
     35     }
     36 
     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