Find cubic KLM functionals directly
[platform/upstream/libSkiaSharp.git] / gm / textblobrandomfont.cpp
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"))) {
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