Home | History | Annotate | Download | only in gm
      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.h"
      9 #include "sk_tool_utils.h"
     10 
     11 #include "Resources.h"
     12 #include "SkCanvas.h"
     13 #include "SkGradientShader.h"
     14 #include "SkStream.h"
     15 #include "SkSurface.h"
     16 #include "SkTextBlob.h"
     17 #include "SkTypeface.h"
     18 #include "../src/fonts/SkRandomScalerContext.h"
     19 
     20 #if SK_SUPPORT_GPU
     21 
     22 #include "GrContext.h"
     23 
     24 namespace skiagm {
     25 class TextBlobRandomFont : public GM {
     26 public:
     27     // This gm tests that textblobs can be translated and scaled with a font that returns random
     28     // but deterministic masks
     29     TextBlobRandomFont() { }
     30 
     31 protected:
     32     void onOnceBeforeDraw() override {
     33         SkTextBlobBuilder builder;
     34 
     35         const char* text = "The quick brown fox jumps over the lazy dog.";
     36 
     37         // make textbloben
     38         SkPaint paint;
     39         paint.setTextSize(32);
     40         paint.setLCDRenderText(true);
     41 
     42         // Setup our random scaler context
     43         sk_sp<SkTypeface> orig(sk_tool_utils::create_portable_typeface(
     44                                    "sans-serif", SkFontStyle::FromOldStyle(SkTypeface::kBold)));
     45         if (nullptr == orig) {
     46             orig = SkTypeface::MakeDefault();
     47         }
     48         paint.setTypeface(sk_make_sp<SkRandomTypeface>(orig, paint, false));
     49 
     50         SkRect bounds;
     51         paint.measureText(text, strlen(text), &bounds);
     52         sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0);
     53 
     54         // A8
     55         const char* bigtext1 = "The quick brown fox";
     56         const char* bigtext2 = "jumps over the lazy dog.";
     57         paint.setTextSize(160);
     58         paint.setSubpixelText(false);
     59         paint.setLCDRenderText(false);
     60         paint.measureText(bigtext1, strlen(bigtext1), &bounds);
     61         SkScalar offset = bounds.height();
     62         sk_tool_utils::add_to_text_blob(&builder, bigtext1, paint, 0, offset);
     63 
     64         paint.measureText(bigtext2, strlen(bigtext2), &bounds);
     65         offset += bounds.height();
     66         sk_tool_utils::add_to_text_blob(&builder, bigtext2, paint, 0, offset);
     67 
     68         // color emoji
     69         sk_sp<SkTypeface> origEmoji = sk_tool_utils::emoji_typeface();
     70         const char* osName = sk_tool_utils::platform_os_name();
     71         // The mac emoji string will break us
     72         if (origEmoji && (!strcmp(osName, "Android") || !strcmp(osName, "Ubuntu") || !strcmp(osName, "Debian"))) {
     73             const char* emojiText = sk_tool_utils::emoji_sample_text();
     74             paint.measureText(emojiText, strlen(emojiText), &bounds);
     75             offset += bounds.height();
     76             paint.setTypeface(sk_make_sp<SkRandomTypeface>(orig, paint, false));
     77             sk_tool_utils::add_to_text_blob(&builder, emojiText, paint, 0, offset);
     78         }
     79 
     80         // build
     81         fBlob = builder.make();
     82     }
     83 
     84     SkString onShortName() override {
     85         return SkString("textblobrandomfont");
     86     }
     87 
     88     SkISize onISize() override {
     89         return SkISize::Make(kWidth, kHeight);
     90     }
     91 
     92     void onDraw(SkCanvas* canvas) override {
     93         // This GM exists to test a specific feature of the GPU backend.
     94         if (nullptr == canvas->getGrContext()) {
     95             skiagm::GM::DrawGpuOnlyMessage(canvas);
     96             return;
     97         }
     98 
     99         canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorWHITE));
    100 
    101         SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, canvas->imageInfo().colorType(),
    102                                              kPremul_SkAlphaType,
    103                                              canvas->imageInfo().refColorSpace());
    104         SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
    105         auto surface(canvas->makeSurface(info, &props));
    106         if (surface) {
    107             SkPaint paint;
    108             paint.setAntiAlias(true);
    109 
    110             SkCanvas* c = surface->getCanvas();
    111 
    112             int stride = SkScalarCeilToInt(fBlob->bounds().height());
    113             int yOffset = stride / 8;
    114             for (int i = 0; i < 1; i++) {
    115                 // fiddle the canvas to force regen of textblobs
    116                 canvas->rotate(i % 2 ? 0.0f : -0.05f);
    117                 canvas->drawTextBlob(fBlob, 10.0f, SkIntToScalar(yOffset), paint);
    118                 yOffset += stride;
    119 
    120                 // This will draw as black boxes
    121                 c->drawTextBlob(fBlob, 10, SkIntToScalar(yOffset), paint);
    122                 surface->draw(canvas, 0, 0, nullptr);
    123 
    124                 // free gpu resources and verify
    125                 yOffset += stride;
    126                 canvas->getGrContext()->freeGpuResources();
    127                 canvas->drawTextBlob(fBlob, 10, SkIntToScalar(yOffset), paint);
    128 
    129                 yOffset += stride;
    130             }
    131 
    132         } else {
    133             const char* text = "This test requires a surface";
    134             size_t len = strlen(text);
    135             SkPaint paint;
    136             canvas->drawText(text, len, 10, 100, paint);
    137         }
    138     }
    139 
    140 private:
    141     sk_sp<SkTextBlob> fBlob;
    142 
    143     static constexpr int kWidth = 2000;
    144     static constexpr int kHeight = 1600;
    145 
    146     typedef GM INHERITED;
    147 };
    148 
    149 //////////////////////////////////////////////////////////////////////////////
    150 
    151 DEF_GM(return new TextBlobRandomFont;)
    152 }
    153 #endif
    154