• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 #include "Resources.h"
11 #include "SkCanvas.h"
12 #include "SkGradientShader.h"
13 #include "SkStream.h"
14 #include "SkSurface.h"
15 #include "SkTextBlob.h"
16 #include "SkTypeface.h"
17 #include "../src/fonts/SkRandomScalerContext.h"
18 
19 #if SK_SUPPORT_GPU
20 
21 #include "GrContext.h"
22 
23 namespace skiagm {
24 class TextBlobRandomFont : public GM {
25 public:
26     // This gm tests that textblobs can be translated and scaled with a font that returns random
27     // but deterministic masks
TextBlobRandomFont()28     TextBlobRandomFont() { }
29 
30 protected:
onOnceBeforeDraw()31     void onOnceBeforeDraw() override {
32         SkTextBlobBuilder builder;
33 
34         const char* text = "The quick brown fox jumps over the lazy dog.";
35 
36         // make textbloben
37         SkPaint paint;
38         paint.setTextSize(32);
39         paint.setLCDRenderText(true);
40 
41         // Setup our random scaler context
42         SkAutoTUnref<SkTypeface> orig(sk_tool_utils::create_portable_typeface("sans-serif",
43                                                                               SkTypeface::kBold));
44         if (nullptr == orig) {
45             orig.reset(SkTypeface::RefDefault());
46         }
47         SkAutoTUnref<SkTypeface> random(new SkRandomTypeface(orig, paint, false));
48         paint.setTypeface(random);
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         SkAutoTUnref<SkTypeface> origEmoji;
70         sk_tool_utils::emoji_typeface(&origEmoji);
71         const char* osName = sk_tool_utils::platform_os_name();
72         // The mac emoji string will break us
73         if (origEmoji && (!strcmp(osName, "Android") || !strcmp(osName, "Ubuntu"))) {
74             const char* emojiText = sk_tool_utils::emoji_sample_text();
75             paint.measureText(emojiText, strlen(emojiText), &bounds);
76             offset += bounds.height();
77             SkAutoTUnref<SkTypeface> randomEmoji(new SkRandomTypeface(orig, paint, false));
78             paint.setTypeface(randomEmoji);
79             sk_tool_utils::add_to_text_blob(&builder, emojiText, paint, 0, offset);
80         }
81 
82         // build
83         fBlob.reset(builder.build());
84     }
85 
onShortName()86     SkString onShortName() override {
87         return SkString("textblobrandomfont");
88     }
89 
onISize()90     SkISize onISize() override {
91         return SkISize::Make(kWidth, kHeight);
92     }
93 
onDraw(SkCanvas * canvas)94     void onDraw(SkCanvas* canvas) override {
95         // This GM exists to test a specific feature of the GPU backend.
96         if (nullptr == canvas->getGrContext()) {
97             skiagm::GM::DrawGpuOnlyMessage(canvas);
98             return;
99         }
100 
101         canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorWHITE));
102 
103         SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
104         SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
105         SkAutoTUnref<SkSurface> surface(canvas->newSurface(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     SkAutoTUnref<const SkTextBlob> fBlob;
142 
143     static const int kWidth = 2000;
144     static const int kHeight = 1600;
145 
146     typedef GM INHERITED;
147 };
148 
149 //////////////////////////////////////////////////////////////////////////////
150 
151 DEF_GM(return new TextBlobRandomFont;)
152 }
153 #endif
154